From: Tomek Mrugalski Date: Wed, 12 Sep 2012 15:09:40 +0000 (+0200) Subject: [2140] DUID is now a separate class in separate files X-Git-Tag: trac2402_base~17^2~11^2~6 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=5ff43d80fb8eaae5ac2621a5a754cf94204149de;p=thirdparty%2Fkea.git [2140] DUID is now a separate class in separate files --- diff --git a/src/lib/dhcp/Makefile.am b/src/lib/dhcp/Makefile.am index 9f52690e40..b656e831b7 100644 --- a/src/lib/dhcp/Makefile.am +++ b/src/lib/dhcp/Makefile.am @@ -29,6 +29,7 @@ libb10_dhcp___la_SOURCES += option4_addrlst.cc option4_addrlst.h libb10_dhcp___la_SOURCES += dhcp6.h dhcp4.h libb10_dhcp___la_SOURCES += pkt6.cc pkt6.h libb10_dhcp___la_SOURCES += pkt4.cc pkt4.h +libb10_dhcp___la_SOURCES += duid.cc duid.h EXTRA_DIST = README #EXTRA_DIST += log_messages.mes diff --git a/src/lib/dhcp/duid.cc b/src/lib/dhcp/duid.cc new file mode 100644 index 0000000000..950e32d0de --- /dev/null +++ b/src/lib/dhcp/duid.cc @@ -0,0 +1,63 @@ +// Copyright (C) 2012 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. + +#include +#include +#include + +namespace isc { +namespace dhcp { + +DUID::DUID(const std::vector& duid) { + if (duid.size() > MAX_DUID_LEN) { + isc_throw(OutOfRange, "DUID too large"); + } else { + duid_ = duid; + } +} + +DUID::DUID(const uint8_t * data, size_t len) { + if (len > MAX_DUID_LEN) { + isc_throw(OutOfRange, "DUID too large"); + } + + duid_ = std::vector(data, data + len); +} + +const std::vector& DUID::getDuid() const { + return duid_; +} + +DUID::DUIDType DUID::getType() const { + if (duid_.size() < 2) { + return (DUID_UNKNOWN); + } + uint16_t type = (duid_[0] << 8) + duid_[1]; + if (type < DUID_MAX) { + return (static_cast(type)); + } else { + return (DUID_UNKNOWN); + } +} + +bool DUID::operator == (const DUID& other) const { + return (this->duid_ == other.duid_); +} + +bool DUID::operator != (const DUID& other) const { + return (this->duid_ != other.duid_); +} + +}; // end of isc::dhcp namespace +}; // end of isc namespace diff --git a/src/lib/dhcp/duid.h b/src/lib/dhcp/duid.h new file mode 100644 index 0000000000..d980561a91 --- /dev/null +++ b/src/lib/dhcp/duid.h @@ -0,0 +1,69 @@ +// Copyright (C) 2012 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. + +#include +#include +#include + +namespace isc { +namespace dhcp { + +/// @brief Holds DUID (DHCPv6 Unique Identifier) +/// +/// This class holds DUID, that is used in client-id, server-id and +/// several other options. It is used to identify DHCPv6 entity. +class DUID { + public: + /// @brief maximum duid size + /// As defined in RFC3315, section 9.1 + static const size_t MAX_DUID_LEN = 128; + + /// @brief specifies DUID type + typedef enum { + DUID_UNKNOWN = 0, ///< invalid/unknown type + DUID_LLT = 1, ///< link-layer + time, see RFC3315, section 9.2 + DUID_EN = 2, ///< enterprise-id, see RFC3315, section 9.3 + DUID_LL = 3, ///< link-layer, see RFC3315, section 9.4 + DUID_UUID = 4, ///< UUID, see RFC6355 + DUID_MAX ///< not a real type, just maximum defined value + 1 + } DUIDType; + + /// @brief creates a DUID + DUID(const std::vector& duid); + + /// @brief creates a DUID + DUID(const uint8_t *duid, size_t len); + + /// @brief returns a const reference to the actual DUID value + /// + /// Note: This reference is only valid as long as the DUID + /// that returned it. + const std::vector& getDuid() const; + + /// @brief returns DUID type + DUIDType getType() const; + + // compares two DUIDs + bool operator == (const DUID& other) const; + + // compares two DUIDs + bool operator != (const DUID& other) const; + + protected: + /// the actual content of the DUID + std::vector duid_; +}; + +}; // end of isc::dhcp namespace +}; // end of isc namespace diff --git a/src/lib/dhcp/lease_mgr.h b/src/lib/dhcp/lease_mgr.h index 63c166ce4b..4e6ef53995 100644 --- a/src/lib/dhcp/lease_mgr.h +++ b/src/lib/dhcp/lease_mgr.h @@ -18,6 +18,8 @@ #include #include #include +#include +#include namespace isc { namespace dhcp { @@ -35,31 +37,6 @@ class ClientId { std::vector clientid_; }; -/// @brief Holds DUID (DHCPv6 Unique Identifier) -/// -/// This class holds DUID, that is used in client-id, server-id and -/// several other options. It is used to identify DHCPv6 entity. -class DUID { - - /// @brief specifies DUID type - typedef enum { - DUID_UNKNOWN = 0, // invalid/unknown type - DUID_LLT = 1, // link-layer + time, see RFC3315, section 9.2 - DUID_EN = 2, // enterprise-id, see RFC3315, section 9.3 - DUID_LL = 3, // link-layer, see RFC3315, section 9.4 - DUID_UUID = 4, // UUID, see RFC6355 - } DUIDType; - - public: - DUID(const std::vector& duid); - DUID(const char *duid, size_t len); - const std::vector getDuid() const; - DUIDType getType(); - bool operator == (const DUID& other); - protected: - std::vector duid_; -}; - /// @brief Structure that holds a lease for IPv4 address /// /// For performance reasons it is a simple structure, not a class. If we chose @@ -79,13 +56,15 @@ struct Lease4 { uint32_t ext_; /// address extension /// @brief hardware address - std::vector hwaddr; + std::vector hwaddr_; /// @brief client identifier - std::vector client_id; + std::vector client_id_; - /// valid lifetime timestamp - uint32_t valid_lft; + /// @brief valid lifetime + /// + /// Expressed as number of seconds since cltt + uint32_t valid_lft_; /// @brief Recycle timer /// @@ -93,44 +72,45 @@ struct Lease4 { /// or expired. This timer specifies number of seconds that it should be kept /// after release or expiration, in case the client returns. This feature is not /// currently used and this value is set to 0. - uint32_t recycle_time; + uint32_t recycle_time_; /// @brief client last transmission time /// /// Specifies a timestamp, when last transmission from a client was received. - time_t cltt; + time_t cltt_; /// @brief Pool identifier /// /// Specifies pool-id of the pool that the lease belongs to - uint32_t pool_id; + uint32_t pool_id_; /// @brief Is this a fixed lease? /// /// Fixed leases are kept after they are released/expired. - bool fixed; + bool fixed_; /// @brief client hostname /// /// This field may be empty - std::string hostname; + std::string hostname_; /// @brief did we update AAAA record for this lease? - bool fqdn_fwd; + bool fqdn_fwd_; - /// @brief did we update PTR record for this lease? - bool fqdn_rev; + /// @brief did we update PTR record for this lease? + bool fqdn_rev_; /// @brief additional options stored with this lease /// - /// Currently not used. - std::string options; + /// This field is currently not used. + /// @todo We need a way to store options in the databased. + Option::OptionCollection options_; /// @brief Lease comments. /// /// Currently not used. It may be used for keeping comments made by the /// system administrator. - std::string comments; + std::string comments_; }; /// @brief Pointer to a Lease4 structure. @@ -209,7 +189,7 @@ struct Lease6 { /// or expired. This timer specifies number of seconds that it should be kept /// after release or expiration, in case the client returns. This feature is not /// currently used and this value is set to 0. - uint32_t recycle_time; + uint32_t recycle_time; /// @brief client last transmission time /// @@ -234,7 +214,7 @@ struct Lease6 { /// @brief did we update AAAA record for this lease? bool fqdn_fwd; - /// @brief did we update PTR record for this lease? + /// @brief did we update PTR record for this lease? bool fqdn_rev; /// @brief additional options stored with this lease @@ -242,12 +222,12 @@ struct Lease6 { /// That field is currently not used. We may keep extra options assigned /// for leasequery and possibly other purposes. /// @todo: Define this as a container of options - std::string options; + std::string options; /// @brief /// comments on that lease /// /// (currently not used) - std::string comments; + std::string comments; }; /// @brief Pointer to a Lease6 structure. diff --git a/src/lib/dhcp/tests/Makefile.am b/src/lib/dhcp/tests/Makefile.am index 05faee8704..68e2e00bcc 100644 --- a/src/lib/dhcp/tests/Makefile.am +++ b/src/lib/dhcp/tests/Makefile.am @@ -39,6 +39,7 @@ libdhcp___unittests_SOURCES += ../option4_addrlst.cc ../option4_addrlst.h option libdhcp___unittests_SOURCES += ../option.h ../option.cc option_unittest.cc libdhcp___unittests_SOURCES += ../pkt6.h ../pkt6.cc pkt6_unittest.cc libdhcp___unittests_SOURCES += ../pkt4.h ../pkt4.cc pkt4_unittest.cc +libdhcp___unittests_SOURCES += ../duid.h ../duid.cc duid_unittest.cc libdhcp___unittests_CPPFLAGS = $(AM_CPPFLAGS) $(GTEST_INCLUDES) $(LOG4CPLUS_INCLUDES) libdhcp___unittests_LDFLAGS = $(AM_LDFLAGS) $(GTEST_LDFLAGS) diff --git a/src/lib/dhcp/tests/duid_unittest.cc b/src/lib/dhcp/tests/duid_unittest.cc new file mode 100644 index 0000000000..4c1c422b75 --- /dev/null +++ b/src/lib/dhcp/tests/duid_unittest.cc @@ -0,0 +1,121 @@ +// Copyright (C) 2011 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. + +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace std; +using namespace isc; +using namespace isc::dhcp; + +// don't import the entire boost namespace. It will unexpectedly hide uint8_t +// for some systems. +using boost::scoped_ptr; + +namespace { + +TEST(DuidTest, constructor) { + + uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6}; + + vector data2(data1, data1 + sizeof(data1)); + + scoped_ptr duid1(new DUID(data1, sizeof(data1))); + scoped_ptr duid2(new DUID(data2)); + + vector vecdata = duid1->getDuid(); + EXPECT_EQ(data2, vecdata); + EXPECT_EQ(DUID::DUID_LLT, duid1->getType()); + + vecdata = duid2->getDuid(); + EXPECT_EQ(data2, vecdata); + + EXPECT_EQ(DUID::DUID_LLT, duid2->getType()); +} + +TEST(DuidTest, size) { + const int MAX_DUID_SIZE = 128; + uint8_t data[MAX_DUID_SIZE + 1]; + vector data2; + for (uint8_t i = 0; i < MAX_DUID_SIZE + 1; ++i) { + data[i] = i; + if (i < MAX_DUID_SIZE) + data2.push_back(i); + } + ASSERT_EQ(data2.size(), MAX_DUID_SIZE); + + scoped_ptr duidmaxsize1(new DUID(data, MAX_DUID_SIZE)); + scoped_ptr duidmaxsize2(new DUID(data2)); + + EXPECT_THROW( + scoped_ptr toolarge1(new DUID(data, MAX_DUID_SIZE + 1)), + OutOfRange); + + // that's one too much + data2.push_back(128); + + EXPECT_THROW( + scoped_ptr toolarge2(new DUID(data2)), + OutOfRange); +} + +TEST(DuidTest, getType) { + uint8_t llt[] = {0, 1, 2, 3, 4, 5, 6}; + uint8_t en[] = {0, 2, 2, 3, 4, 5, 6}; + uint8_t ll[] = {0, 3, 2, 3, 4, 5, 6}; + uint8_t uuid[] = {0, 4, 2, 3, 4, 5, 6}; + uint8_t invalid[] = {0,55, 2, 3, 4, 5, 6}; + + scoped_ptr duid_llt(new DUID(llt, sizeof(llt))); + scoped_ptr duid_en(new DUID(en, sizeof(en))); + scoped_ptr duid_ll(new DUID(ll, sizeof(ll))); + scoped_ptr duid_uuid(new DUID(uuid, sizeof(uuid))); + scoped_ptr duid_invalid(new DUID(invalid, sizeof(invalid))); + + EXPECT_EQ(DUID::DUID_LLT, duid_llt->getType()); + EXPECT_EQ(DUID::DUID_EN, duid_en->getType()); + EXPECT_EQ(DUID::DUID_LL, duid_ll->getType()); + EXPECT_EQ(DUID::DUID_UUID, duid_uuid->getType()); + EXPECT_EQ(DUID::DUID_UNKNOWN, duid_invalid->getType()); +} + +TEST(DuidTest, operators) { + uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6}; + uint8_t data2[] = {0, 1, 2, 3, 4}; + uint8_t data3[] = {0, 1, 2, 3, 4, 5, 7}; // last digit different + uint8_t data4[] = {0, 1, 2, 3, 4, 5, 6}; // the same as 1 + + scoped_ptr duid1(new DUID(data1, sizeof(data1))); + scoped_ptr duid2(new DUID(data2, sizeof(data2))); + scoped_ptr duid3(new DUID(data3, sizeof(data3))); + scoped_ptr duid4(new DUID(data4, sizeof(data4))); + + EXPECT_TRUE(*duid1 == *duid4); + EXPECT_FALSE(*duid1 == *duid2); + EXPECT_FALSE(*duid1 == *duid3); + + EXPECT_FALSE(*duid1 != *duid4); + EXPECT_TRUE(*duid1 != *duid2); + EXPECT_TRUE(*duid1 != *duid3); +} + + + +} // end of anonymous namespace