From: Marcin Siodelski Date: Tue, 14 Oct 2014 09:43:41 +0000 (+0200) Subject: [3560] Added methods to add classes to the Host object. X-Git-Tag: trac3162a_base~3^2~5 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=da9288ba1d6d07ee12c5dc4d13470e93252adc8d;p=thirdparty%2Fkea.git [3560] Added methods to add classes to the Host object. --- diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc index 29dcd09514..49cafea0ae 100644 --- a/src/lib/dhcpsrv/host.cc +++ b/src/lib/dhcpsrv/host.cc @@ -13,6 +13,7 @@ // PERFORMANCE OF THIS SOFTWARE. #include +#include #include namespace isc { @@ -34,10 +35,13 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len, const IdentifierType& identifier_type, const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id, const asiolink::IOAddress& ipv4_reservation, - const std::string& hostname) + const std::string& hostname, + const std::string& dhcp4_client_classes, + const std::string& dhcp6_client_classes) : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id), ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation), - hostname_(hostname), dhcp4_client_classes_(), dhcp6_client_classes_() { + hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes), + dhcp6_client_classes_(dhcp6_client_classes) { // Initialize HWAddr or DUID setIdentifier(identifier, identifier_len, identifier_type); @@ -46,10 +50,13 @@ Host::Host(const uint8_t* identifier, const size_t identifier_len, Host::Host(const std::string& identifier, const std::string& identifier_name, const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id, const asiolink::IOAddress& ipv4_reservation, - const std::string& hostname) + const std::string& hostname, + const std::string& dhcp4_client_classes, + const std::string& dhcp6_client_classes) : hw_address_(), duid_(), ipv4_subnet_id_(ipv4_subnet_id), ipv6_subnet_id_(ipv6_subnet_id), ipv4_reservation_(ipv4_reservation), - hostname_(hostname), dhcp4_client_classes_(), dhcp6_client_classes_() { + hostname_(hostname), dhcp4_client_classes_(dhcp4_client_classes), + dhcp6_client_classes_(dhcp6_client_classes) { // Initialize HWAddr or DUID setIdentifier(identifier, identifier_name); @@ -99,6 +106,14 @@ Host::getIPv6Reservations(const IPv6Resrv::Type& type) const { return (ipv6_reservations_.equal_range(type)); } +void +Host::addClientClassInternal(ClientClasses& classes, + const std::string& class_name) { + std::string trimmed = util::str::trim(class_name); + if (!class_name.empty()) { + classes.insert(ClientClass(class_name)); + } +} } // end of namespace isc::dhcp } // end of namespace isc diff --git a/src/lib/dhcpsrv/host.h b/src/lib/dhcpsrv/host.h index 64b2934147..ebff21c071 100644 --- a/src/lib/dhcpsrv/host.h +++ b/src/lib/dhcpsrv/host.h @@ -178,6 +178,10 @@ public: /// this address is set to 0, there is no reservation. /// @param hostname Hostname to be allocated to both DHCPv4 and DHCPv6 /// clients. This is empty string if hostname is not allocated. + /// @param dhcp4_client_classes A string holding DHCPv4 client class names + /// separated by commas. The names get trimmed by this constructor. + /// @param dhcp6_client_classes A string holding DHCPv6 client class names + /// separated by commas. The names get trimmed by this constructor. /// /// @throw BadValue if the provided values are invalid. In particular, /// if the identifier is invalid. @@ -185,7 +189,9 @@ public: const IdentifierType& identifier_type, const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id, const asiolink::IOAddress& ipv4_reservation, - const std::string& hostname = ""); + const std::string& hostname = "", + const std::string& dhcp4_client_classes = "", + const std::string& dhcp6_client_classes = ""); /// @brief Constructor. /// @@ -206,13 +212,19 @@ public: /// this address is set to 0, there is no reservation. /// @param hostname Hostname to be allocated to both DHCPv4 and DHCPv6 /// clients. This is empty string if hostname is not allocated. + /// @param dhcp4_client_classes A string holding DHCPv4 client class names + /// separated by commas. The names get trimmed by this constructor. + /// @param dhcp6_client_classes A string holding DHCPv6 client class names + /// separated by commas. The names get trimmed by this constructor. /// /// @throw BadValue if the provided values are invalid. In particular, /// if the identifier is invalid. Host(const std::string& identifier, const std::string& identifier_name, const SubnetID ipv4_subnet_id, const SubnetID ipv6_subnet_id, const asiolink::IOAddress& ipv4_reservation, - const std::string& hostname = ""); + const std::string& hostname = "", + const std::string& dhcp4_client_classes = "", + const std::string& dhcp6_client_classes = ""); /// @brief Replaces currently used identifier with a new identifier. /// @@ -325,11 +337,25 @@ public: return (hostname_); } + /// @brief Adds new client class for DHCPv4. + /// + /// @param class_name Class name. + void addClientClass4(const std::string& class_name) { + addClientClassInternal(dhcp4_client_classes_, class_name); + } + /// @brief Returns classes which DHCPv4 client is associated with. const ClientClasses& getClientClasses4() const { return (dhcp4_client_classes_); } + /// @brief Adds new client class for DHCPv6. + /// + /// @param class_name Class name. + void addClientClass6(const std::string& class_name) { + addClientClassInternal(dhcp6_client_classes_, class_name); + } + /// @brief Returns classes which DHCPv6 client is associated with. const ClientClasses& getClientClasses6() const { return (dhcp6_client_classes_); @@ -337,6 +363,19 @@ public: private: + /// @brief Adds new client class for DHCPv4 or DHCPv6. + /// + /// This method is called internally by the @c addClientClass4 and + /// @c addClientClass6 functions. It adds the class of the specified name + /// to the supplied class set. The class names are trimmed before they are + /// added. Empty class names are ignored. + /// + /// @param [out] classes Set of classes to which the new class should be + /// inserted. + /// @param class_name Class name. + void addClientClassInternal(ClientClasses& classes, + const std::string& class_name); + /// @brief Pointer to the hardware address associated with the reservations /// for the host. HWAddrPtr hw_address_; diff --git a/src/lib/dhcpsrv/tests/host_unittest.cc b/src/lib/dhcpsrv/tests/host_unittest.cc index 60d301437e..eee372a076 100644 --- a/src/lib/dhcpsrv/tests/host_unittest.cc +++ b/src/lib/dhcpsrv/tests/host_unittest.cc @@ -146,12 +146,6 @@ TEST(HostTest, createFromDUIDString) { isc::BadValue); // Empty DUID is also not allowed. - try { - Host("", "duid", SubnetID(1), SubnetID(2), - IOAddress("192.0.2.3"), "somehost.example.org"); - } catch (const std::exception& ex) { - std::cout << ex.what() << std::endl; - } EXPECT_THROW(Host("", "duid", SubnetID(1), SubnetID(2), IOAddress("192.0.2.3"), "somehost.example.org"), isc::BadValue); @@ -362,4 +356,72 @@ TEST(HostTest, setValues) { EXPECT_EQ("10.0.0.1", host->getIPv4Reservation().toText()); } +// Test that Host constructors initialize client classes from string. +TEST(HostTest, clientClassesFromConstructor) { + boost::scoped_ptr host; + // Prepare the hardware address in binary format. + const uint8_t hwaddr_data[] = { + 0xaa, 0xab, 0xca, 0xda, 0xbb, 0xee + }; + + // Try the "from binary" constructor. + ASSERT_NO_THROW(host.reset(new Host(hwaddr_data, + sizeof(hwaddr_data), + Host::IDENT_HWADDR, + SubnetID(1), SubnetID(2), + IOAddress("192.0.2.3"), + "somehost.example.org", + "alpha, , beta", + "gamma"))); + + EXPECT_TRUE(host->getClientClasses4().contains("alpha")); + EXPECT_TRUE(host->getClientClasses4().contains("beta")); + EXPECT_FALSE(host->getClientClasses4().contains("gamma")); + EXPECT_TRUE(host->getClientClasses6().contains("gamma")); + EXPECT_FALSE(host->getClientClasses6().contains("alpha")); + EXPECT_FALSE(host->getClientClasses6().contains("beta")); + + // Try the "from string" constructor. + ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address", + SubnetID(1), SubnetID(2), + IOAddress("192.0.2.3"), + "somehost.example.org", + "alpha, beta, gamma", + "beta, gamma"))); + + EXPECT_TRUE(host->getClientClasses4().contains("alpha")); + EXPECT_TRUE(host->getClientClasses4().contains("beta")); + EXPECT_TRUE(host->getClientClasses4().contains("gamma")); + EXPECT_FALSE(host->getClientClasses6().contains("alpha")); + EXPECT_TRUE(host->getClientClasses6().contains("beta")); + EXPECT_TRUE(host->getClientClasses6().contains("gamma")); +} + +// Test that new client classes can be added for the Host. +TEST(HostTest, addClientClasses) { + boost::scoped_ptr host; + ASSERT_NO_THROW(host.reset(new Host("01:02:03:04:05:06", "hw-address", + SubnetID(1), SubnetID(2), + IOAddress("192.0.2.3")))); + + EXPECT_FALSE(host->getClientClasses4().contains("foo")); + EXPECT_FALSE(host->getClientClasses6().contains("foo")); + EXPECT_FALSE(host->getClientClasses4().contains("bar")); + EXPECT_FALSE(host->getClientClasses6().contains("bar")); + + host->addClientClass4("foo"); + host->addClientClass6("bar"); + EXPECT_TRUE(host->getClientClasses4().contains("foo")); + EXPECT_FALSE(host->getClientClasses6().contains("foo")); + EXPECT_FALSE(host->getClientClasses4().contains("bar")); + EXPECT_TRUE(host->getClientClasses6().contains("bar")); + + host->addClientClass4("bar"); + host->addClientClass6("foo"); + EXPECT_TRUE(host->getClientClasses4().contains("foo")); + EXPECT_TRUE(host->getClientClasses6().contains("foo")); + EXPECT_TRUE(host->getClientClasses4().contains("bar")); + EXPECT_TRUE(host->getClientClasses6().contains("bar")); +} + } // end of anonymous namespace