From: Tomek Mrugalski Date: Wed, 12 Sep 2012 18:39:07 +0000 (+0200) Subject: [2140] ClientId class implemented and tested. X-Git-Tag: trac2402_base~17^2~11^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=01eb4277b933cb0537204d98b9200550ee3eb641;p=thirdparty%2Fkea.git [2140] ClientId class implemented and tested. --- diff --git a/src/lib/dhcp/duid.cc b/src/lib/dhcp/duid.cc index 950e32d0de..912fc4835a 100644 --- a/src/lib/dhcp/duid.cc +++ b/src/lib/dhcp/duid.cc @@ -14,6 +14,8 @@ #include #include +#include +#include #include namespace isc { @@ -59,5 +61,51 @@ bool DUID::operator != (const DUID& other) const { return (this->duid_ != other.duid_); } +/// constructor based on vector +ClientId::ClientId(const std::vector& clientid) + :DUID(clientid) { +} + +/// constructor based on C-style data +ClientId::ClientId(const uint8_t *clientid, size_t len) + :DUID(clientid, len) { +} + +/// constructor based on IOAddress +ClientId::ClientId(const isc::asiolink::IOAddress& addr) + :DUID(std::vector(4, 0)) { + if (addr.getFamily() != AF_INET) { + isc_throw(BadValue, "Client-id supports only IPv4 addresses"); + } + isc::util::writeUint32(addr, &duid_[0]); +} + +/// @brief returns reference to the client-id data +const std::vector ClientId::getClientId() const { + return duid_; +} + +isc::asiolink::IOAddress ClientId::getAddress() const { + if (duid_.size() != sizeof(uint32_t)) { + isc_throw(BadValue, "This client-id is not an IPv4 address"); + } + + return isc::asiolink::IOAddress( isc::util::readUint32(&duid_[0]) ); +} + +bool ClientId::isAddress() const { + return (duid_.size() == sizeof(uint32_t)); +} + +// compares two client-ids +bool ClientId::operator == (const ClientId& other) const { + return (this->duid_ == other.duid_); +} + +// compares two client-ids +bool ClientId::operator != (const ClientId& 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 index d980561a91..132d1d7e88 100644 --- a/src/lib/dhcp/duid.h +++ b/src/lib/dhcp/duid.h @@ -15,6 +15,8 @@ #include #include #include +#include + namespace isc { namespace dhcp { @@ -65,5 +67,44 @@ class DUID { std::vector duid_; }; +/// @brief Holds Client identifier or client IPv4 address +/// +/// This class is intended to be a generic IPv4 client identifier. It can hold +/// a client-id +class ClientId : DUID { + public: + + /// constructor based on vector + ClientId(const std::vector& clientid); + + /// constructor based on C-style data + ClientId(const uint8_t *clientid, size_t len); + + /// constructor based on IOAddress + /// + /// @throw BadValue if specified address is not IPv4 + ClientId(const isc::asiolink::IOAddress& addr); + + /// @brief returns reference to the client-id data + /// + /// This reference is only valid as long as the object + /// that returned it. + const std::vector getClientId() const; + + /// @brief return an IPv4 address represented by this client-id + /// + /// @throw BadValue if this client-id is not an IPv4 address + isc::asiolink::IOAddress getAddress() const; + + /// @brief returns if client-id is an address + bool isAddress() const; + + // compares two client-ids + bool operator == (const ClientId& other) const; + + // compares two client-ids + bool operator != (const ClientId& other) const; +}; + }; // 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 4e6ef53995..1f33af9a88 100644 --- a/src/lib/dhcp/lease_mgr.h +++ b/src/lib/dhcp/lease_mgr.h @@ -24,19 +24,6 @@ namespace isc { namespace dhcp { -/// @brief Holds Client identifier -class ClientId { - public: - ClientId(const std::vector& duid); - ClientId(const char *duid, size_t len); - ClientId(uint32_t id); - ClientId(const isc::asiolink::IOAddress& addr); - const std::vector getClientId() const; - bool operator == (const ClientId& other); - protected: - std::vector clientid_; -}; - /// @brief Structure that holds a lease for IPv4 address /// /// For performance reasons it is a simple structure, not a class. If we chose diff --git a/src/lib/dhcp/tests/duid_unittest.cc b/src/lib/dhcp/tests/duid_unittest.cc index 4c1c422b75..d3da6e8997 100644 --- a/src/lib/dhcp/tests/duid_unittest.cc +++ b/src/lib/dhcp/tests/duid_unittest.cc @@ -19,11 +19,13 @@ #include #include #include +#include #include using namespace std; using namespace isc; using namespace isc::dhcp; +using namespace isc::asiolink; // don't import the entire boost namespace. It will unexpectedly hide uint8_t // for some systems. @@ -116,6 +118,56 @@ TEST(DuidTest, operators) { EXPECT_TRUE(*duid1 != *duid3); } +TEST(ClientIdTest, constructor) { + IOAddress addr2("192.0.2.1"); + IOAddress addr3("2001:db8:1::1"); + uint8_t data1[] = {0, 1, 2, 3, 4, 5, 6}; + vector data2(data1, data1 + sizeof(data1)); + uint8_t data3[] = {192, 0 , 2, 1 }; + + // checks for C-style construtor (uint8_t * + len) + scoped_ptr id1(new ClientId(data1, sizeof(data1))); + vector vecdata = id1->getClientId(); + EXPECT_EQ(data2, vecdata); + EXPECT_FALSE(id1->isAddress()); + EXPECT_THROW(id1->getAddress(), BadValue); + + // checks for vector-based constructor + scoped_ptr id2(new ClientId(data2)); + vecdata = id2->getClientId(); + EXPECT_EQ(data2, vecdata); + EXPECT_FALSE(id1->isAddress()); + EXPECT_THROW(id1->getAddress(), BadValue); + + // checks for IOAddress based constructor + scoped_ptr id3(new ClientId(addr2)); + vecdata = id3->getClientId(); + EXPECT_TRUE(vecdata == vector(data3, data3 + 4)); + EXPECT_EQ("192.0.2.1", id3->getAddress().toText()); + + // should support v4 address only, v6 is a wrong address here + EXPECT_THROW(new ClientId(addr3), BadValue); +} + +TEST(ClientIdTest, 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 id1(new ClientId(data1, sizeof(data1))); + scoped_ptr id2(new ClientId(data2, sizeof(data2))); + scoped_ptr id3(new ClientId(data3, sizeof(data3))); + scoped_ptr id4(new ClientId(data4, sizeof(data4))); + + EXPECT_TRUE(*id1 == *id4); + EXPECT_FALSE(*id1 == *id2); + EXPECT_FALSE(*id1 == *id3); + + EXPECT_FALSE(*id1 != *id4); + EXPECT_TRUE(*id1 != *id2); + EXPECT_TRUE(*id1 != *id3); +} } // end of anonymous namespace