Commit 023e14f9 authored by JINMEI Tatuya's avatar JINMEI Tatuya
Browse files

added RRTTL class


git-svn-id: svn://bind10.isc.org/svn/bind10/branches/jinmei-dnsrrparams@449 e5f2f494-b856-4b98-b285-d166d9295462
parent bc46e20a
......@@ -3,7 +3,7 @@ AM_CPPFLAGS = $(BOOST_INCLUDES)
lib_LTLIBRARIES = libdns.la
libdns_la_SOURCES = buffer.h name.cc name.h messagerenderer.h messagerenderer.cc
libdns_la_SOURCES += rrparamregistry.h rrparamregistry.cc
libdns_la_SOURCES += rrclass.h rrclass.cc rrtype.h rrtype.cc
libdns_la_SOURCES += rrclass.h rrclass.cc rrtype.h rrtype.cc rrttl.h rrttl.cc
libdns_la_SOURCES += exceptions.h exceptions.cc
TESTS =
......@@ -13,6 +13,7 @@ run_unittests_SOURCES = unittest_util.h unittest_util.cc
run_unittests_SOURCES += buffer_unittest.cc name_unittest.cc
run_unittests_SOURCES += messagerenderer_unittest.cc exceptions_unittest.cc
run_unittests_SOURCES += rrclass_unittest.cc rrtype_unittest.cc
run_unittests_SOURCES += rrttl_unittest.cc
run_unittests_SOURCES += run_unittests.cc
run_unittests_CPPFLAGS = $(GTEST_INCLUDES)
run_unittests_LDFLAGS = $(GTEST_LDFLAGS)
......
......@@ -162,6 +162,12 @@ MessageRenderer::writeUint16(uint16_t data)
impl_->buffer_.writeUint16(data);
}
void
MessageRenderer::writeUint32(uint32_t data)
{
impl_->buffer_.writeUint32(data);
}
const void*
MessageRenderer::getData() const
{
......
......@@ -102,7 +102,7 @@ public:
//@}
///
/// \name Methods for writing data into the buffer.
/// \name Methods for writing data into the internal buffer.
///
//@{
/// \brief Write an unsigned 16-bit integer in host byte order into the
......@@ -110,6 +110,11 @@ public:
///
/// \param data The 16-bit integer to be written into the buffer.
void writeUint16(uint16_t data);
/// \brief Write an unsigned 32-bit integer in host byte order into the
/// internal buffer in network byte order.
///
/// \param data The 32-bit integer to be written into the buffer.
void writeUint32(uint32_t data);
//@}
///
......
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <sstream>
#include "buffer.h"
#include "messagerenderer.h"
#include "rrttl.h"
using namespace std;
using namespace isc::dns;
namespace isc {
namespace dns {
RRTTL::RRTTL(const string& ttlstr)
{
uint32_t val;
istringstream iss(ttlstr);
iss >> dec >> val;
if (iss.rdstate() == ios::eofbit) {
ttlval_ = val;
} else {
dns_throw(InvalidRRTTL, "invalid TTL");
}
}
RRTTL::RRTTL(InputBuffer& buffer)
{
if (buffer.getLength() - buffer.getPosition() < sizeof(uint32_t)) {
dns_throw(IncompleteRRTTL, "incomplete wire-format TTL value");
}
ttlval_ = buffer.readUint32();
}
const string
RRTTL::toText() const
{
ostringstream oss;
oss << ttlval_;
return (oss.str());
}
void
RRTTL::toWire(OutputBuffer& buffer) const
{
buffer.writeUint32(ttlval_);
}
void
RRTTL::toWire(MessageRenderer& renderer) const
{
renderer.writeUint32(ttlval_);
}
ostream&
operator<<(ostream& os, const RRTTL& rrttl)
{
os << rrttl.toText();
return (os);
}
}
}
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#ifndef __RRTTL_H
#define __RRTTL_H 1
#include "exceptions.h"
namespace isc {
namespace dns {
// forward declarations
class InputBuffer;
class OutputBuffer;
class MessageRenderer;
///
/// \brief TBD
///
class InvalidRRTTL : public Exception {
public:
InvalidRRTTL(const char* file, size_t line, const char* what) :
isc::dns::Exception(file, line, what) {}
};
///
/// \brief A standard DNS module exception that is thrown if an RRTTL object
/// is being constructed from a incomplete (too short) wire-format data.
///
class IncompleteRRTTL : public Exception {
public:
IncompleteRRTTL(const char* file, size_t line, const char* what) :
isc::dns::Exception(file, line, what) {}
};
class RRTTL {
public:
///
/// \name Constructors and Destructor
///
//@{
explicit RRTTL(uint32_t ttlval) : ttlval_(ttlval) {}
///
/// TODO: this version only accepts decimal TTL values. We'll extend
/// it so that we can accept more convenient ones such as "2H" or "1D".
explicit RRTTL(const std::string& ttlstr);
/// Constructor from wire-format data.
///
/// The \c buffer parameter normally stores a complete DNS message
/// containing the RRTTL to be constructed. The current read position of
/// the buffer points to the head of the type.
///
/// If the given data does not large enough to contain a 16-bit integer,
/// an exception of class \c IncompleteRRTTL will be thrown.
///
/// \param buffer A buffer storing the wire format data.
explicit RRTTL(InputBuffer& buffer);
///
/// We use the default copy constructor intentionally.
//@}
/// We use the default copy assignment operator intentionally.
///
const std::string toText() const;
void toWire(OutputBuffer& buffer) const;
void toWire(MessageRenderer& renderer) const;
uint32_t getValue() const { return (ttlval_); }
///
/// \name Comparison methods
///
//@{
bool equals(const RRTTL& other) const
{ return (ttlval_ == other.ttlval_); }
bool operator==(const RRTTL& other) const
{ return (ttlval_ == other.ttlval_); }
bool nequals(const RRTTL& other) const
{ return (ttlval_ != other.ttlval_); }
bool operator!=(const RRTTL& other) const
{ return (ttlval_ != other.ttlval_); }
bool leq(const RRTTL& other) const
{ return (ttlval_ <= other.ttlval_); }
bool geq(const RRTTL& other) const
{ return (ttlval_ >= other.ttlval_); }
bool operator>=(const RRTTL& other) const
{ return (ttlval_ >= other.ttlval_); }
bool operator<=(const RRTTL& other) const
{ return (ttlval_ <= other.ttlval_); }
bool lthan(const RRTTL& other) const
{ return (ttlval_ < other.ttlval_); }
bool operator<(const RRTTL& other) const
{ return (ttlval_ < other.ttlval_); }
bool gthan(const RRTTL& other) const
{ return (ttlval_ > other.ttlval_); }
bool operator>(const RRTTL& other) const
{ return (ttlval_ > other.ttlval_); }
//@}
private:
uint32_t ttlval_;
};
std::ostream&
operator<<(std::ostream& os, const RRTTL& rrtype);
}
}
#endif // __RRTTL_H
// Local Variables:
// mode: c++
// End:
// Copyright (C) 2010 Internet Systems Consortium, Inc. ("ISC")
//
// Permission to use, copy, modify, and/or distribute this software for any
// purpose with or without fee is hereby granted, provided that the above
// copyright notice and this permission notice appear in all copies.
//
// THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
// REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
// AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
// INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
// LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
// OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
// PERFORMANCE OF THIS SOFTWARE.
// $Id$
#include <gtest/gtest.h>
#include "buffer.h"
#include "messagerenderer.h"
#include "rrttl.h"
#include "unittest_util.h"
using namespace std;
using namespace isc;
using namespace isc::dns;
namespace {
class RRTTLTest : public ::testing::Test {
protected:
RRTTLTest() : obuffer(0), renderer(obuffer) {}
OutputBuffer obuffer;
MessageRenderer renderer;
static RRTTL rrttlFactoryFromWire(const char* datafile);
static const RRTTL ttl_0, ttl_1h, ttl_1d, ttl_32bit, ttl_max;
static const RRTTL ttl_small, ttl_large;
static const uint8_t wiredata[20];
};
const RRTTL RRTTLTest::ttl_0(0);
const RRTTL RRTTLTest::ttl_1h(3600);
const RRTTL RRTTLTest::ttl_1d(86400);
const RRTTL RRTTLTest::ttl_32bit(0x12345678);
const RRTTL RRTTLTest::ttl_max(0xffffffff);
const RRTTL RRTTLTest::ttl_small(1);
const RRTTL RRTTLTest::ttl_large(0x80000001);
// This is wire-format data for the above sample RRTTLs rendered in the
// appearing order.
const uint8_t RRTTLTest::wiredata[20] = { 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x0e, 0x10,
0x00, 0x01, 0x51, 0x80,
0x12, 0x34, 0x56, 0x78,
0xff, 0xff, 0xff, 0xff };
RRTTL
RRTTLTest::rrttlFactoryFromWire(const char* datafile)
{
std::vector<unsigned char> data;
UnitTestUtil::readWireData(datafile, data);
InputBuffer buffer(&data[0], data.size());
return (RRTTL(buffer));
}
TEST_F(RRTTLTest, fromText)
{
EXPECT_EQ(0, ttl_0.getValue());
EXPECT_EQ(3600, ttl_1h.getValue());
EXPECT_EQ(86400, ttl_1d.getValue());
EXPECT_EQ(0x12345678, ttl_32bit.getValue());
EXPECT_EQ(0xffffffff, ttl_max.getValue());
EXPECT_THROW(RRTTL("1D"), InvalidRRTTL); // we don't support this form yet
EXPECT_THROW(RRTTL("0xdeadbeef"), InvalidRRTTL); // must be decimal
EXPECT_THROW(RRTTL("-1"), InvalidRRTTL); // must be positive
EXPECT_THROW(RRTTL("1.1"), InvalidRRTTL); // must be integer
EXPECT_THROW(RRTTL("4294967296"), InvalidRRTTL); // must be 32-bit
}
TEST_F(RRTTLTest, fromWire)
{
EXPECT_EQ(0x12345678,
rrttlFactoryFromWire("testdata/rrcode32_fromWire1").getValue());
EXPECT_THROW(rrttlFactoryFromWire("testdata/rrcode32_fromWire2"),
IncompleteRRTTL);
}
TEST_F(RRTTLTest, toText)
{
EXPECT_EQ("0", ttl_0.toText());
EXPECT_EQ("3600", ttl_1h.toText());
EXPECT_EQ("86400", ttl_1d.toText());
EXPECT_EQ("305419896", ttl_32bit.toText());
EXPECT_EQ("4294967295", ttl_max.toText());
}
TEST_F(RRTTLTest, toWireBuffer)
{
ttl_0.toWire(obuffer);
ttl_1h.toWire(obuffer);
ttl_1d.toWire(obuffer);
ttl_32bit.toWire(obuffer);
ttl_max.toWire(obuffer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
obuffer.getData(), obuffer.getLength(),
wiredata, sizeof(wiredata));
}
TEST_F(RRTTLTest, toWireRenderer)
{
ttl_0.toWire(renderer);
ttl_1h.toWire(renderer);
ttl_1d.toWire(renderer);
ttl_32bit.toWire(renderer);
ttl_max.toWire(renderer);
EXPECT_PRED_FORMAT4(UnitTestUtil::matchWireData,
obuffer.getData(), obuffer.getLength(),
wiredata, sizeof(wiredata));
}
TEST_F(RRTTLTest, equal)
{
EXPECT_TRUE(RRTTL("3600") == ttl_1h);
EXPECT_TRUE(RRTTL("86400").equals(ttl_1d));
EXPECT_TRUE(ttl_1d != ttl_1h);
EXPECT_TRUE(ttl_1d.nequals(ttl_max));
}
//
// The following set of tests confirm the result of <=, <, >=, >
// The test logic is simple, and all tests are just straightforward variations
// of the first one.
//
TEST_F(RRTTLTest, leq)
{
// small <= large is true
EXPECT_TRUE(ttl_small.leq(ttl_large));
EXPECT_TRUE(ttl_small <= ttl_large);
// small <= small is true
EXPECT_TRUE(ttl_small.leq(ttl_small));
EXPECT_TRUE(ttl_small <= ttl_small);
// large <= small is false
EXPECT_FALSE(ttl_large.leq(ttl_small));
EXPECT_FALSE(ttl_large <= ttl_small);
}
TEST_F(RRTTLTest, geq)
{
EXPECT_TRUE(ttl_large.geq(ttl_small));
EXPECT_TRUE(ttl_large >= ttl_small);
EXPECT_TRUE(ttl_large.geq(ttl_large));
EXPECT_TRUE(ttl_large >= ttl_large);
EXPECT_FALSE(ttl_small.geq(ttl_large));
EXPECT_FALSE(ttl_small >= ttl_large);
}
TEST_F(RRTTLTest, lthan)
{
EXPECT_TRUE(ttl_small.lthan(ttl_large));
EXPECT_TRUE(ttl_small < ttl_large);
EXPECT_FALSE(ttl_small.lthan(ttl_small));
EXPECT_FALSE(ttl_small < ttl_small);
EXPECT_FALSE(ttl_large.lthan(ttl_small));
EXPECT_FALSE(ttl_large < ttl_small);
}
TEST_F(RRTTLTest, gthan)
{
EXPECT_TRUE(ttl_large.gthan(ttl_small));
EXPECT_TRUE(ttl_large > ttl_small);
EXPECT_FALSE(ttl_large.gthan(ttl_large));
EXPECT_FALSE(ttl_large > ttl_large);
EXPECT_FALSE(ttl_small.gthan(ttl_large));
EXPECT_FALSE(ttl_small > ttl_large);
}
// test operator<<. We simply confirm it appends the result of toText().
TEST_F(RRTTLTest, LeftShiftOperator)
{
ostringstream oss;
oss << ttl_1h;
EXPECT_EQ(ttl_1h.toText(), oss.str());
}
}
#
# a 32 bit wire-format data (network byte order)
#
12345678
#
# an incomplete segment for a 32 bit wire-format data
#
123456
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment