Browse Source

[2140] DUID is now a separate class in separate files

Tomek Mrugalski 12 years ago
parent
commit
5ff43d80fb

+ 1 - 0
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

+ 63 - 0
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 <vector>
+#include <exceptions/exceptions.h>
+#include <dhcp/duid.h>
+
+namespace isc {
+namespace dhcp {
+
+DUID::DUID(const std::vector<uint8_t>& 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<uint8_t>(data, data + len);
+}
+
+const std::vector<uint8_t>& 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<DUID::DUIDType>(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

+ 69 - 0
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 <stdint.h>
+#include <unistd.h>
+#include <vector>
+
+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<uint8_t>& 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<uint8_t>& 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<uint8_t> duid_;
+};
+
+}; // end of isc::dhcp namespace
+}; // end of isc namespace

+ 24 - 44
src/lib/dhcp/lease_mgr.h

@@ -18,6 +18,8 @@
 #include <map>
 #include <asiolink/io_address.h>
 #include <boost/shared_ptr.hpp>
+#include <dhcp/option.h>
+#include <dhcp/duid.h>
 
 namespace isc {
 namespace dhcp {
@@ -35,31 +37,6 @@ class ClientId {
     std::vector<uint8_t> 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<uint8_t>& duid);
-    DUID(const char *duid, size_t len);
-    const std::vector<uint8_t> getDuid() const;
-    DUIDType getType();
-    bool operator == (const DUID& other);
- protected:
-    std::vector<uint8_t> 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<uint8_t> hwaddr;
+    std::vector<uint8_t> hwaddr_;
 
     /// @brief client identifier
-    std::vector<uint8_t> client_id; 
+    std::vector<uint8_t> 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.

+ 1 - 0
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)

+ 121 - 0
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 <config.h>
+#include <iostream>
+#include <sstream>
+#include <arpa/inet.h>
+#include <gtest/gtest.h>
+#include <exceptions/exceptions.h>
+#include <boost/scoped_ptr.hpp>
+#include <dhcp/duid.h>
+
+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<uint8_t> data2(data1, data1 + sizeof(data1));
+
+    scoped_ptr<DUID> duid1(new DUID(data1, sizeof(data1)));
+    scoped_ptr<DUID> duid2(new DUID(data2));
+
+    vector<uint8_t> 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<uint8_t> 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<DUID> duidmaxsize1(new DUID(data, MAX_DUID_SIZE));
+    scoped_ptr<DUID> duidmaxsize2(new DUID(data2));
+
+    EXPECT_THROW(
+        scoped_ptr<DUID> toolarge1(new DUID(data, MAX_DUID_SIZE + 1)),
+        OutOfRange);
+
+    // that's one too much
+    data2.push_back(128);
+
+    EXPECT_THROW(
+        scoped_ptr<DUID> 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> duid_llt(new DUID(llt, sizeof(llt)));
+    scoped_ptr<DUID> duid_en(new DUID(en, sizeof(en)));
+    scoped_ptr<DUID> duid_ll(new DUID(ll, sizeof(ll)));
+    scoped_ptr<DUID> duid_uuid(new DUID(uuid, sizeof(uuid)));
+    scoped_ptr<DUID> 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<DUID> duid1(new DUID(data1, sizeof(data1)));
+    scoped_ptr<DUID> duid2(new DUID(data2, sizeof(data2)));
+    scoped_ptr<DUID> duid3(new DUID(data3, sizeof(data3)));
+    scoped_ptr<DUID> 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