From: Marcin Siodelski Date: Tue, 29 Mar 2016 14:26:18 +0000 (+0200) Subject: [4302] Use new functions to retrieve reservations by any identifier. X-Git-Tag: trac4106_update_base~60^2~4 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=497a2545121bfc10ef66f07cce94f5af1772a6a7;p=thirdparty%2Fkea.git [4302] Use new functions to retrieve reservations by any identifier. --- diff --git a/src/lib/dhcpsrv/cfg_hosts.cc b/src/lib/dhcpsrv/cfg_hosts.cc index 26815095a3..7d37d2bdfa 100644 --- a/src/lib/dhcpsrv/cfg_hosts.cc +++ b/src/lib/dhcpsrv/cfg_hosts.cc @@ -227,7 +227,6 @@ CfgHosts::getAllInternal6(const IOAddress& address, Storage& storage) const { .arg(storage.size()); } - ConstHostPtr CfgHosts::get4(const SubnetID& subnet_id, const HWAddrPtr& hwaddr, const DuidPtr& duid) const { @@ -367,14 +366,13 @@ CfgHosts::get6(const SubnetID& subnet_id, } ConstHostPtr -CfgHosts::get6(const IOAddress&, const uint8_t) const { - isc_throw(isc::NotImplemented, - "get6(prefix, len) const is not implemented"); +CfgHosts::get6(const IOAddress& prefix, const uint8_t prefix_len) const { + return (getHostInternal6(prefix, prefix_len)); } HostPtr -CfgHosts::get6(const IOAddress&, const uint8_t) { - isc_throw(isc::NotImplemented, "get6(prefix, len) is not implemented"); +CfgHosts::get6(const IOAddress& prefix, const uint8_t prefix_len) { + return (getHostInternal6(prefix, prefix_len)); } ConstHostPtr @@ -425,6 +423,36 @@ CfgHosts::getHostInternal6(const SubnetID& subnet_id, } +template +ReturnType +CfgHosts::getHostInternal6(const asiolink::IOAddress& prefix, + const uint8_t prefix_len) const { + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_PREFIX) + .arg(prefix.toText()).arg(static_cast(prefix_len)); + + // Let's get all reservations that match subnet_id, address. + const HostContainer6Index0& idx = hosts6_.get<0>(); + HostContainer6Index0Range r = make_pair(idx.lower_bound(prefix), + idx.upper_bound(prefix)); + for (HostContainer6Index0::iterator resrv = r.first; resrv != r.second; + ++resrv) { + if (resrv->resrv_.getPrefixLen() == prefix_len) { + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE_DETAIL_DATA, + HOSTS_CFG_GET_ONE_PREFIX_HOST) + .arg(prefix.toText()) + .arg(static_cast(prefix_len)) + .arg(resrv->host_->toText()); + return (resrv->host_); + } + } + + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE_DETAIL_DATA, + HOSTS_CFG_GET_ONE_PREFIX_NULL) + .arg(prefix.toText()) + .arg(static_cast(prefix_len)); + return (ReturnType()); +} + template void CfgHosts::getAllInternal6(const SubnetID& subnet_id, @@ -453,7 +481,7 @@ CfgHosts::getAllInternal6(const SubnetID& subnet_id, HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6_HOST) .arg(subnet_id) .arg(address.toText()) - .arg(resrv->host_); + .arg(resrv->host_->toText()); storage.push_back(resrv->host_); } @@ -470,11 +498,10 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6, const uint8_t* identifier, const size_t identifier_len) const { -/* LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID) + LOG_DEBUG(hosts_logger, HOSTS_DBG_TRACE, HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER) .arg(subnet6 ? "IPv6" : "IPv4") .arg(subnet_id) - .arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)") - .arg(duid ? duid->toText() : "(no-duid)"); */ + .arg(Host::getIdentifierAsText(identifier_type, identifier, identifier_len)); // Get all hosts for a specified identifier. This may return multiple hosts // for different subnets, but the number of hosts returned should be low @@ -506,30 +533,30 @@ CfgHosts::getHostInternal(const SubnetID& subnet_id, const bool subnet6, } else { isc_throw(DuplicateHost, "more than one reservation found" " for the host belonging to the subnet with id '" - << subnet_id << "' and using the HW address '" -// << (hwaddr ? hwaddr->toText(false) : "(null)") -// << "' and DUID '" -// << (duid ? duid->toText() : "(null)") + << subnet_id << "' and using the identifier '" + << Host::getIdentifierAsText(identifier_type, + identifier, + identifier_len) << "'"); } } } -/* if (host) { + if (host) { LOG_DEBUG(hosts_logger, HOSTS_DBG_RESULTS, - HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID) + HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER_HOST) .arg(subnet_id) - .arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)") - .arg(duid ? duid->toText() : "(no-duid)") + .arg(Host::getIdentifierAsText(identifier_type, identifier, + identifier_len)) .arg(host->toText()); } else { LOG_DEBUG(hosts_logger, HOSTS_DBG_RESULTS, - HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID_NULL) + HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER_NULL) .arg(subnet_id) - .arg(hwaddr ? hwaddr->toText() : "(no-hwaddr)") - .arg(duid ? duid->toText() : "(no-duid)"); - } */ + .arg(Host::getIdentifierAsText(identifier_type, identifier, + identifier_len)); + } return (host); } diff --git a/src/lib/dhcpsrv/cfg_hosts.h b/src/lib/dhcpsrv/cfg_hosts.h index 700d901193..85902f969c 100644 --- a/src/lib/dhcpsrv/cfg_hosts.h +++ b/src/lib/dhcpsrv/cfg_hosts.h @@ -276,7 +276,7 @@ public: /// @param prefix IPv6 prefix for which the @c Host object is searched. /// @param prefix_len IPv6 prefix length. /// - /// @throw isc::NotImplemented + /// @return Const @c Host object for which specified prefix is reserved. virtual ConstHostPtr get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len) const; @@ -285,7 +285,8 @@ public: /// @param prefix IPv6 prefix for which the @c Host object is searched. /// @param prefix_len IPv6 prefix length. /// - /// @throw isc::NotImplemented + /// @return Non-const @c Host object for which specified prefix is + /// reserved. virtual HostPtr get6(const asiolink::IOAddress& prefix, const uint8_t prefix_len); @@ -449,6 +450,10 @@ private: ReturnType getHostInternal6(const SubnetID& subnet_id, const asiolink::IOAddress& adddress) const; + template + ReturnType getHostInternal6(const asiolink::IOAddress& prefix, + const uint8_t prefix_len) const; + /// @brief Adds a new host to the v4 collection. /// /// This is an internal method called by public @ref add. diff --git a/src/lib/dhcpsrv/host.cc b/src/lib/dhcpsrv/host.cc index 38aa8aa593..d13c86681f 100644 --- a/src/lib/dhcpsrv/host.cc +++ b/src/lib/dhcpsrv/host.cc @@ -6,6 +6,7 @@ #include #include +#include #include #include #include @@ -137,20 +138,47 @@ std::string Host::getIdentifierAsText() const { std::string txt; if (hw_address_) { - txt = "hwaddr=" + hw_address_->toText(false); + txt = getIdentifierAsText(IDENT_HWADDR, &hw_address_->hwaddr_[0], + hw_address_->hwaddr_.size()); + } else if (duid_) { + txt = getIdentifierAsText(IDENT_DUID, &duid_->getDuid()[0], + duid_->getDuid().size()); } else { - txt = "duid="; - if (duid_) { - txt += duid_->toText(); - } else { - txt += "(none)"; - } + txt = "(none)"; } return (txt); } +std::string +Host::getIdentifierAsText(const IdentifierType& type, const uint8_t* value, + const size_t length) { + // Length 0 doesn't make sense. + if (length == 0) { + isc_throw(BadValue, "invalid length 0 of the host identifier while" + " converting the identifier to a textual form"); + } + + // Convert identifier into = form. + std::ostringstream s; + switch (type) { + case IDENT_HWADDR: + s << "hwaddr"; + break; + case IDENT_DUID: + s << "duid"; + break; + default: + isc_throw(BadValue, "requested conversion of the unsupported" + " identifier into textual form"); + } + std::vector vec(value, value + length); + s << "=" << util::encode::encodeHex(vec); + return (s.str()); +} + + void Host::setIdentifier(const uint8_t* identifier, const size_t len, const IdentifierType& type) { diff --git a/src/lib/dhcpsrv/host.h b/src/lib/dhcpsrv/host.h index 93cd4816fe..16a71caad7 100644 --- a/src/lib/dhcpsrv/host.h +++ b/src/lib/dhcpsrv/host.h @@ -307,6 +307,16 @@ public: /// @return text form of the identifier, including (duid= or mac=). std::string getIdentifierAsText() const; + /// @brief Returns host identifier in textual form. + /// + /// @param type Identifier type. + /// @param value Pointer to a buffer holding identifier. + /// @param length Length of the identifier. + /// @return Identifier in the form of =. + static std::string getIdentifierAsText(const IdentifierType& type, + const uint8_t* value, + const size_t length); + /// @brief Sets new IPv4 subnet identifier. /// /// @param ipv4_subnet_id New subnet identifier. diff --git a/src/lib/dhcpsrv/hosts_messages.mes b/src/lib/dhcpsrv/hosts_messages.mes index f7f2924a89..0e08b97af1 100644 --- a/src/lib/dhcpsrv/hosts_messages.mes +++ b/src/lib/dhcpsrv/hosts_messages.mes @@ -1,4 +1,4 @@ -# Copyright (C) 2015 Internet Systems Consortium, Inc. ("ISC") +# Copyright (C) 2015-2016 Internet Systems Consortium, Inc. ("ISC") # # This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this @@ -76,10 +76,24 @@ subnet id and address. The arguments specify subnet id, address and found host details respectively. % HOSTS_CFG_GET_ALL_SUBNET_ID_ADDRESS6_HOST using subnet id %1 and address %2, found host: %3 -This debug message include the details of the host found using the +This debug message includes the details of the host found using the subnet id and address. The arguments specify subnet id, address and found host details respectively. +% HOSTS_CFG_GET_ONE_PREFIX get one host with reservation for prefix %1/%2 +This debug message is issued when starting to retrieve a host having a +reservation for a specified prefix. The arguments specify a prefix and +prefix length. + +% HOSTS_CFG_GET_ONE_PREFIX_HOST using prefix %1/%2, found host: %3 +This debug message includes the details of the host found using the +specific prefix/prefix length. The arguments specify prefix, prefix +length and host details respectively. + +% HOSTS_CFG_GET_ONE_PREFIX_NULL host not found using prefix %1/%2 +This debug messsage is issued when no host was found for a specified +prefix and prefix length. + % HOSTS_CFG_GET_ONE_SUBNET_ID_ADDRESS4 get one host with reservation for subnet id %1 and IPv4 address %2 This debug message is issued when starting to retrieve a host connected to the specific subnet and having the specific IPv4 address reserved. The @@ -106,19 +120,19 @@ subnet id and IPv6 address. This debug message is issued when no host was found using the specified subnet if and IPv6 address. -% HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID get one host with %1 reservation for subnet id %2, HWADDR %3, DUID %4 -This debug message is issued when starting to retrieve the host holding IPv4 or -IPv6 reservations, which is connected to the specific subnet and is -identified by the specific HW address or DUID. The first argument +% HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER get one host with %1 reservation for subnet id %2, identified by %3 +This debug message is issued when starting to retrieve a host holding +IPv4 or IPv6 reservations, which is connected to a specific subnet and +is identified by a specific unique identifier. The first argument identifies if the IPv4 or IPv6 reservation is desired. -% HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID_HOST using subnet id %1, HWADDR %2 and DUID %3, found host: %4 -This debug message includes the details of the host found using the -subnet id, HW address and/or DUID. +% HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER_HOST using subnet id %1 and identifier %2, found host: %3 +This debug message includes the details of a host found using a +subnet id and specific host identifier. -% HOSTS_CFG_GET_ONE_SUBNET_ID_HWADDR_DUID_NULL host not found using subnet id %1, HW address %2 and DUID %3 +% HOSTS_CFG_GET_ONE_SUBNET_ID_IDENTIFIER_NULL host not found using subnet id %1 and identifier %2 This debug message is issued when no host was found using the specified -subnet id, HW address and DUID. +subnet id and host identifier. % HOSTS_MGR_ALTERNATE_GET4_SUBNET_ID_ADDRESS4 trying alternate source for host using subnet id %1 and address %2 This debug message is issued when the Host Manager doesn't find the diff --git a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc index 80ac5934cd..b15712456c 100644 --- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.cc @@ -105,17 +105,17 @@ HostPtr GenericHostDataSourceTest::initializeHost4(std::string address, } HostPtr GenericHostDataSourceTest::initializeHost6(std::string address, - BaseHostDataSource::IdType identifier, + Host::IdentifierType identifier, bool prefix) { string ident; string ident_type; switch (identifier) { - case BaseHostDataSource::ID_HWADDR: + case Host::IDENT_HWADDR: ident = generateHWAddr(); ident_type = "hw-address"; break; - case BaseHostDataSource::ID_DUID: + case Host::IDENT_DUID: ident = generateDuid(); ident_type = "duid"; break; @@ -416,8 +416,14 @@ void GenericHostDataSourceTest::testGet4ByHWAddr() { SubnetID subnet1 = host1->getIPv4SubnetID(); SubnetID subnet2 = host2->getIPv4SubnetID(); - ConstHostPtr from_hds1 = hdsptr_->get4(subnet1, host1->getHWAddress()); - ConstHostPtr from_hds2 = hdsptr_->get4(subnet2, host2->getHWAddress()); + ConstHostPtr from_hds1 = hdsptr_->get4(subnet1, + Host::IDENT_HWADDR, + &host1->getIdentifier()[0], + host1->getIdentifier().size()); + ConstHostPtr from_hds2 = hdsptr_->get4(subnet2, + Host::IDENT_HWADDR, + &host2->getIdentifier()[0], + host2->getIdentifier().size()); // Now let's check if we got what we expected. ASSERT_TRUE(from_hds1); @@ -445,8 +451,15 @@ void GenericHostDataSourceTest::testGet4ByClientId() { SubnetID subnet1 = host1->getIPv4SubnetID(); SubnetID subnet2 = host2->getIPv4SubnetID(); - ConstHostPtr from_hds1 = hdsptr_->get4(subnet1, HWAddrPtr(), host1->getDuid()); - ConstHostPtr from_hds2 = hdsptr_->get4(subnet2, HWAddrPtr(), host2->getDuid()); + ConstHostPtr from_hds1 = hdsptr_->get4(subnet1, + Host::IDENT_DUID, + &host1->getIdentifier()[0], + host1->getIdentifier().size()); + + ConstHostPtr from_hds2 = hdsptr_->get4(subnet2, + Host::IDENT_DUID, + &host2->getIdentifier()[0], + host2->getIdentifier().size()); // Now let's check if we got what we expected. ASSERT_TRUE(from_hds1); @@ -472,10 +485,14 @@ void GenericHostDataSourceTest::testHWAddrNotClientId() { DuidPtr duid = HWAddrToDuid(host->getHWAddress()); // Get the host by HW address (should succeed) - ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, host->getHWAddress(), DuidPtr()); + ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR, + &host->getIdentifier()[0], + host->getIdentifier().size()); // Get the host by DUID (should fail) - ConstHostPtr by_duid = hdsptr_->get4(subnet, HWAddrPtr(), duid); + ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID, + &host->getIdentifier()[0], + host->getIdentifier().size()); // Now let's check if we got what we expected. EXPECT_TRUE(by_hwaddr); @@ -499,10 +516,15 @@ void GenericHostDataSourceTest::testClientIdNotHWAddr() { HWAddrPtr hwaddr = DuidToHWAddr(host->getDuid()); // Get the host by DUID (should succeed) - ConstHostPtr by_duid = hdsptr_->get4(subnet, HWAddrPtr(), host->getDuid()); + ConstHostPtr by_duid = hdsptr_->get4(subnet, Host::IDENT_DUID, + &host->getIdentifier()[0], + host->getIdentifier().size()); + // Get the host by HW address (should fail) - ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, hwaddr, DuidPtr()); + ConstHostPtr by_hwaddr = hdsptr_->get4(subnet, Host::IDENT_HWADDR, + &host->getIdentifier()[0], + host->getIdentifier().size()); // Now let's check if we got what we expected. EXPECT_TRUE(by_duid); @@ -588,7 +610,10 @@ GenericHostDataSourceTest::testMultipleSubnets(int subnets, bool hwaddr) { EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID()); // Try to retrieve the host by either HW address of client-id - from_hds = hdsptr_->get4(i + 1000, host->getHWAddress(), host->getDuid()); + from_hds = hdsptr_->get4(i + 1000, + hwaddr ? Host::IDENT_HWADDR : Host::IDENT_DUID, + &host->getIdentifier()[0], + host->getIdentifier().size()); ASSERT_TRUE(from_hds); EXPECT_EQ(i + 1000, from_hds->getIPv4SubnetID()); } @@ -606,8 +631,10 @@ GenericHostDataSourceTest::testMultipleSubnets(int subnets, bool hwaddr) { } // Finally, check that the hosts can be retrived by HW address or DUID - ConstHostCollection all_by_id = hdsptr_->getAll(host->getHWAddress(), - host->getDuid()); + ConstHostCollection all_by_id = + hdsptr_->getAll(hwaddr ? Host::IDENT_HWADDR : Host::IDENT_DUID, + &host->getIdentifier()[0], + host->getIdentifier().size()); ASSERT_EQ(subnets, all_by_id.size()); // Check that the returned values are as expected. @@ -624,8 +651,8 @@ void GenericHostDataSourceTest::testGet6ByHWAddr() { ASSERT_TRUE(hdsptr_); // Create a host reservations. - HostPtr host1 = initializeHost6("2001:db8::1", BaseHostDataSource::ID_HWADDR, true); - HostPtr host2 = initializeHost6("2001:db8::2", BaseHostDataSource::ID_HWADDR, true); + HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, true); + HostPtr host2 = initializeHost6("2001:db8::2", Host::IDENT_HWADDR, true); // Sanity check: make sure the hosts have different HW addresses. ASSERT_TRUE(host1->getHWAddress()); @@ -640,8 +667,13 @@ void GenericHostDataSourceTest::testGet6ByHWAddr() { SubnetID subnet1 = host1->getIPv6SubnetID(); SubnetID subnet2 = host2->getIPv6SubnetID(); - ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, DuidPtr(), host1->getHWAddress()); - ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, DuidPtr(), host2->getHWAddress()); + ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_HWADDR, + &host1->getIdentifier()[0], + host1->getIdentifier().size()); + + ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_HWADDR, + &host2->getIdentifier()[0], + host2->getIdentifier().size()); // Now let's check if we got what we expected. ASSERT_TRUE(from_hds1); @@ -655,8 +687,8 @@ void GenericHostDataSourceTest::testGet6ByClientId() { ASSERT_TRUE(hdsptr_); // Create a host reservations. - HostPtr host1 = initializeHost6("2001:db8::1", BaseHostDataSource::ID_DUID, true); - HostPtr host2 = initializeHost6("2001:db8::2", BaseHostDataSource::ID_DUID, true); + HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, true); + HostPtr host2 = initializeHost6("2001:db8::2", Host::IDENT_DUID, true); // Sanity check: make sure the hosts have different HW addresses. ASSERT_TRUE(host1->getDuid()); @@ -671,8 +703,13 @@ void GenericHostDataSourceTest::testGet6ByClientId() { SubnetID subnet1 = host1->getIPv6SubnetID(); SubnetID subnet2 = host2->getIPv6SubnetID(); - ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, host1->getDuid(), HWAddrPtr()); - ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, host2->getDuid(), HWAddrPtr()); + ConstHostPtr from_hds1 = hdsptr_->get6(subnet1, Host::IDENT_DUID, + &host1->getIdentifier()[0], + host1->getIdentifier().size()); + + ConstHostPtr from_hds2 = hdsptr_->get6(subnet2, Host::IDENT_DUID, + &host2->getIdentifier()[0], + host2->getIdentifier().size()); // Now let's check if we got what we expected. ASSERT_TRUE(from_hds1); @@ -682,7 +719,7 @@ void GenericHostDataSourceTest::testGet6ByClientId() { } void -GenericHostDataSourceTest::testSubnetId6(int subnets, BaseHostDataSource::IdType id) { +GenericHostDataSourceTest::testSubnetId6(int subnets, Host::IdentifierType id) { // Make sure we have a pointer to the host data source. ASSERT_TRUE(hdsptr_); @@ -709,8 +746,8 @@ GenericHostDataSourceTest::testSubnetId6(int subnets, BaseHostDataSource::IdType } // Check that the hosts can all be retrived by HW address or DUID - ConstHostCollection all_by_id = hdsptr_->getAll(host->getHWAddress(), - host->getDuid()); + ConstHostCollection all_by_id = hdsptr_->getAll(id, &host->getIdentifier()[0], + host->getIdentifier().size()); ASSERT_EQ(subnets, all_by_id.size()); // Check that the returned values are as expected. @@ -722,7 +759,7 @@ GenericHostDataSourceTest::testSubnetId6(int subnets, BaseHostDataSource::IdType } } -void GenericHostDataSourceTest::testGetByIPv6(BaseHostDataSource::IdType id, +void GenericHostDataSourceTest::testGetByIPv6(Host::IdentifierType id, bool prefix) { // Make sure we have a pointer to the host data source. ASSERT_TRUE(hdsptr_); @@ -770,7 +807,7 @@ void GenericHostDataSourceTest::testAddDuplicate6WithSameDUID() { ASSERT_TRUE(hdsptr_); // Create a host reservations. - HostPtr host = initializeHost6("2001:db8::1", BaseHostDataSource::ID_DUID, true); + HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, true); // Add this reservation once. ASSERT_NO_THROW(hdsptr_->add(host)); @@ -784,7 +821,7 @@ void GenericHostDataSourceTest::testAddDuplicate6WithSameHWAddr() { ASSERT_TRUE(hdsptr_); // Create a host reservations. - HostPtr host = initializeHost6("2001:db8::1", BaseHostDataSource::ID_HWADDR, true); + HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_HWADDR, true); // Add this reservation once. ASSERT_NO_THROW(hdsptr_->add(host)); @@ -812,7 +849,7 @@ void GenericHostDataSourceTest::testAddr6AndPrefix(){ ASSERT_TRUE(hdsptr_); // Create a host reservations with prefix reservation (prefix = true) - HostPtr host = initializeHost6("2001:db8::1", BaseHostDataSource::ID_DUID, true); + HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, true); // Create IPv6 reservation (for an address) and add it to the host IPv6Resrv resv(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::2"), 128); @@ -822,13 +859,17 @@ void GenericHostDataSourceTest::testAddr6AndPrefix(){ ASSERT_NO_THROW(hdsptr_->add(host)); // Get this host by DUID - ConstHostPtr from_hds = hdsptr_->get6(host->getIPv6SubnetID(), host->getDuid(), HWAddrPtr()); + ConstHostPtr from_hds = hdsptr_->get6(host->getIPv6SubnetID(), + Host::IDENT_DUID, + &host->getIdentifier()[0], + host->getIdentifier().size()); // Make sure we got something back ASSERT_TRUE(from_hds); // Check if reservations are the same - compareReservations6(host->getIPv6Reservations(), from_hds->getIPv6Reservations()); + compareReservations6(host->getIPv6Reservations(), + from_hds->getIPv6Reservations()); } void GenericHostDataSourceTest::testMultipleReservations(){ @@ -836,7 +877,7 @@ void GenericHostDataSourceTest::testMultipleReservations(){ ASSERT_TRUE(hdsptr_); uint8_t len = 128; - HostPtr host = initializeHost6("2001:db8::1", BaseHostDataSource::ID_DUID, false); + HostPtr host = initializeHost6("2001:db8::1", Host::IDENT_DUID, false); // Add some reservations IPv6Resrv resv1(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::6"), len); @@ -866,8 +907,8 @@ void GenericHostDataSourceTest::testMultipleReservationsDifferentOrder(){ ASSERT_TRUE(hdsptr_); uint8_t len = 128; - HostPtr host1 = initializeHost6("2001:db8::1", BaseHostDataSource::ID_DUID, false); - HostPtr host2 = initializeHost6("2001:db8::1", BaseHostDataSource::ID_DUID, false); + HostPtr host1 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false); + HostPtr host2 = initializeHost6("2001:db8::1", Host::IDENT_DUID, false); // Add some reservations IPv6Resrv resv1(IPv6Resrv::TYPE_NA, IOAddress("2001:db8::6"), len); diff --git a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h index c40b29a00a..1e9259bfa5 100644 --- a/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h +++ b/src/lib/dhcpsrv/tests/generic_host_data_source_unittest.h @@ -8,6 +8,7 @@ #define GENERIC_HOST_DATA_SOURCE_UNITTEST_H #include +#include #include #include #include @@ -46,11 +47,11 @@ public: /// @brief Creates a host reservation for specified IPv6 address. /// /// @param address IPv6 address to be reserved - /// @param id type of identifier (ID_DUID or ID_HWADDR are supported) + /// @param id type of identifier (IDENT_DUID or IDENT_HWADDR are supported) /// @param prefix reservation type (true = prefix, false = address) /// /// @return generated Host object - HostPtr initializeHost6(std::string address, BaseHostDataSource::IdType id, + HostPtr initializeHost6(std::string address, Host::IdentifierType id, bool prefix); /// @brief Generates a hardware address in text version. @@ -183,9 +184,9 @@ public: /// checks that they can be retrieved properly. /// /// Uses gtest macros to report failures. - /// @param id type of the identifier to be used (HWAddr or DUID) + /// @param id type of the identifier to be used (IDENT_HWADDR or IDENT_DUID) /// @param prefix true - reserve IPv6 prefix, false - reserve IPv6 address - void testGetByIPv6(BaseHostDataSource::IdType id, bool prefix); + void testGetByIPv6(Host::IdentifierType id, bool prefix); /// @brief Test that hosts can be retrieved by hardware address. /// @@ -216,8 +217,8 @@ public: /// Uses gtest macros to report failures. /// /// @param subnets number of subnets to test - /// @param id identifier type (ID_HWADDR or ID_DUID) - void testSubnetId6(int subnets, BaseHostDataSource::IdType id); + /// @param id identifier type (IDENT_HWADDR or IDENT_DUID) + void testSubnetId6(int subnets, Host::IdentifierType id); /// @brief Test if the duplicate host with same DUID can't be inserted. /// diff --git a/src/lib/dhcpsrv/tests/host_mgr_unittest.cc b/src/lib/dhcpsrv/tests/host_mgr_unittest.cc index 24b3a2b9c5..2abad6c444 100644 --- a/src/lib/dhcpsrv/tests/host_mgr_unittest.cc +++ b/src/lib/dhcpsrv/tests/host_mgr_unittest.cc @@ -216,17 +216,42 @@ TEST_F(HostMgrTest, get6ByPrefix) { ConstHostPtr host = HostMgr::instance().get6(IOAddress("2001:db8:1::"), 64); ASSERT_FALSE(host); + // Add a host with a reservation for a prefix 2001:db8:1::/64. HostPtr new_host(new Host(duids_[0]->toText(), "duid", SubnetID(1), SubnetID(2), IOAddress("0.0.0.0"))); new_host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 64)); getCfgHosts()->add(new_host); + + // Add another host having a reservation for prefix 2001:db8:1:0:6::/72. + new_host.reset(new Host(duids_[1]->toText(), "duid", SubnetID(2), + SubnetID(3), IOAddress::IPV4_ZERO_ADDRESS())); + new_host->addReservation(IPv6Resrv(IPv6Resrv::TYPE_PD, + IOAddress("2001:db8:1:0:6::"), 72)); + getCfgHosts()->add(new_host); CfgMgr::instance().commit(); + // Retrieve first reservation. host = HostMgr::instance().get6(IOAddress("2001:db8:1::"), 64); ASSERT_TRUE(host); EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD, IOAddress("2001:db8:1::"), 64))); + + // Make sure the first reservation is not retrieved when the prefix + // length is incorrect. + host = HostMgr::instance().get6(IOAddress("2001:db8:1::"), 72); + EXPECT_FALSE(host); + + // Retrieve second reservation. + host = HostMgr::instance().get6(IOAddress("2001:db8:1:0:6::"), 72); + ASSERT_TRUE(host); + EXPECT_TRUE(host->hasReservation(IPv6Resrv(IPv6Resrv::TYPE_PD, + IOAddress("2001:db8:1:0:6::"), 72))); + + // Make sure the second reservation is not retrieved when the prefix + // length is incorrect. + host = HostMgr::instance().get6(IOAddress("2001:db8:1:0:6::"), 64); + EXPECT_FALSE(host); } } // end of anonymous namespace diff --git a/src/lib/dhcpsrv/tests/host_unittest.cc b/src/lib/dhcpsrv/tests/host_unittest.cc index 7a84d8be9e..51a50dd5a0 100644 --- a/src/lib/dhcpsrv/tests/host_unittest.cc +++ b/src/lib/dhcpsrv/tests/host_unittest.cc @@ -631,16 +631,18 @@ TEST(HostTest, addOptions6) { EXPECT_TRUE(options->empty()); } +// This test verifies that it is possible to retrieve a textual +// representation of the host identifier. TEST(HostTest, getIdentifierAsText) { Host host1("01:02:03:04:05:06", "hw-address", SubnetID(1), SubnetID(2), IOAddress("192.0.2.3")); - EXPECT_EQ("hwaddr=01:02:03:04:05:06", host1.getIdentifierAsText()); + EXPECT_EQ("hwaddr=010203040506", host1.getIdentifierAsText()); Host host2("0a:0b:0c:0d:0e:0f:ab:cd:ef", "duid", SubnetID(1), SubnetID(2), IOAddress("192.0.2.3")); - EXPECT_EQ("duid=0a:0b:0c:0d:0e:0f:ab:cd:ef", + EXPECT_EQ("duid=0A0B0C0D0E0FABCDEF", host2.getIdentifierAsText()); } @@ -666,7 +668,7 @@ TEST(HostTest, toText) { ); // Make sure that the output is correct, - EXPECT_EQ("hwaddr=01:02:03:04:05:06 ipv4_subnet_id=1 ipv6_subnet_id=2" + EXPECT_EQ("hwaddr=010203040506 ipv4_subnet_id=1 ipv6_subnet_id=2" " hostname=myhost.example.com" " ipv4_reservation=192.0.2.3" " ipv6_reservation0=2001:db8:1::cafe" @@ -680,7 +682,7 @@ TEST(HostTest, toText) { host->removeIPv4Reservation(); host->setIPv4SubnetID(0); - EXPECT_EQ("hwaddr=01:02:03:04:05:06 ipv6_subnet_id=2" + EXPECT_EQ("hwaddr=010203040506 ipv6_subnet_id=2" " hostname=(empty) ipv4_reservation=(no)" " ipv6_reservation0=2001:db8:1::cafe" " ipv6_reservation1=2001:db8:1::1" @@ -695,14 +697,14 @@ TEST(HostTest, toText) { IOAddress::IPV4_ZERO_ADDRESS(), "myhost"))); - EXPECT_EQ("duid=11:12:13:14:15 hostname=myhost ipv4_reservation=(no)" + EXPECT_EQ("duid=1112131415 hostname=myhost ipv4_reservation=(no)" " ipv6_reservations=(none)", host->toText()); // Add some classes. host->addClientClass4("modem"); host->addClientClass4("router"); - EXPECT_EQ("duid=11:12:13:14:15 hostname=myhost ipv4_reservation=(no)" + EXPECT_EQ("duid=1112131415 hostname=myhost ipv4_reservation=(no)" " ipv6_reservations=(none)" " dhcp4_class0=modem dhcp4_class1=router", host->toText()); @@ -710,7 +712,7 @@ TEST(HostTest, toText) { host->addClientClass6("hub"); host->addClientClass6("device"); - EXPECT_EQ("duid=11:12:13:14:15 hostname=myhost ipv4_reservation=(no)" + EXPECT_EQ("duid=1112131415 hostname=myhost ipv4_reservation=(no)" " ipv6_reservations=(none)" " dhcp4_class0=modem dhcp4_class1=router" " dhcp6_class0=device dhcp6_class1=hub", diff --git a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc index 560b3d48ea..d3a0c3af92 100644 --- a/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc +++ b/src/lib/dhcpsrv/tests/mysql_host_data_source_unittest.cc @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -272,25 +273,25 @@ TEST_F(MySqlHostDataSourceTest, DISABLED_hwaddrOrClientId2) { // Test verifies that host with IPv6 address and DUID can be added and // later retrieved by IPv6 address. TEST_F(MySqlHostDataSourceTest, get6AddrWithDuid) { - testGetByIPv6(BaseHostDataSource::ID_DUID, false); + testGetByIPv6(Host::IDENT_DUID, false); } // Test verifies that host with IPv6 address and HWAddr can be added and // later retrieved by IPv6 address. TEST_F(MySqlHostDataSourceTest, get6AddrWithHWAddr) { - testGetByIPv6(BaseHostDataSource::ID_HWADDR, false); + testGetByIPv6(Host::IDENT_HWADDR, false); } // Test verifies that host with IPv6 prefix and DUID can be added and // later retrieved by IPv6 prefix. TEST_F(MySqlHostDataSourceTest, get6PrefixWithDuid) { - testGetByIPv6(BaseHostDataSource::ID_DUID, true); + testGetByIPv6(Host::IDENT_DUID, true); } // Test verifies that host with IPv6 prefix and HWAddr can be added and // later retrieved by IPv6 prefix. TEST_F(MySqlHostDataSourceTest, get6PrefixWithHWaddr) { - testGetByIPv6(BaseHostDataSource::ID_HWADDR, true); + testGetByIPv6(Host::IDENT_HWADDR, true); } // Test verifies if a host reservation can be added and later retrieved by @@ -373,7 +374,7 @@ TEST_F(MySqlHostDataSourceTest, multipleSubnetsClientId) { // Insert 10 host reservations for different subnets. Make sure that // get6(subnet-id, ...) calls return correct reservation. TEST_F(MySqlHostDataSourceTest, subnetId6) { - testSubnetId6(10, BaseHostDataSource::ID_HWADDR); + testSubnetId6(10, Host::IDENT_HWADDR); } // Test if the duplicate host instances can't be inserted. The test logic is as