diff --git a/ChangeLog b/ChangeLog index c32d65fad2..df4e2b1159 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +2325. [bug] razvan + Fixed a bug which was causing address allocation counters to be + negative when client released leases and the server has lease + affinity and lease reclamation enabled. + (Gitlab #1336) + 2324. [func] razvan It is not necessary to restart the server to apply changes in the TLS configuration. Running the "config-reload" command is diff --git a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc index 4f0361648b..10ef724bbd 100644 --- a/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc +++ b/src/bin/dhcp4/tests/dhcp4_srv_unittest.cc @@ -238,7 +238,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) { resp->setHops(req->getHops()); // This function never throws. - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Now the destination address should be relay's address. EXPECT_EQ("192.0.1.1", resp->getRemoteAddr().toText()); @@ -265,19 +265,19 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelay) { resp->setRemoteAddr(IOAddress("0.0.0.0")); // Set the client and server ports. - srv_.client_port_ = 1234; - srv_.server_port_ = 2345; + srv_->client_port_ = 1234; + srv_->server_port_ = 2345; - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Response should be sent back to the relay address. EXPECT_EQ("192.0.1.50", resp->getRemoteAddr().toText()); // Remote port was enforced to the client port. - EXPECT_EQ(srv_.client_port_, resp->getRemotePort()); + EXPECT_EQ(srv_->client_port_, resp->getRemotePort()); // Local port was enforced to the server port. - EXPECT_EQ(srv_.server_port_, resp->getLocalPort()); + EXPECT_EQ(srv_->server_port_, resp->getLocalPort()); } // This test verifies that the remote port is adjusted when @@ -330,7 +330,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRelayPort) { resp->setRemotePort(67); // This function never throws. - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Now the destination address should be relay's address. EXPECT_EQ("192.0.1.1", resp->getRemoteAddr().toText()); @@ -395,7 +395,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataUseRouting) { resp->setHops(req->getHops()); // This function never throws. - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Now the destination address should be relay's address. EXPECT_EQ("192.0.1.1", resp->getRemoteAddr().toText()); @@ -423,7 +423,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataUseRouting) { cfg_iface->setOutboundIface(CfgIface::SAME_AS_INBOUND); CfgMgr::instance().commit(); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); EXPECT_EQ("192.0.2.5", resp->getLocalAddr().toText()); EXPECT_EQ("eth1", resp->getIface()); @@ -470,10 +470,10 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressRelaySendToSourceTestingModeEnabled) { resp->setHops(req->getHops()); // Set the testing mode. - srv_.setSendResponsesToSource(true); + srv_->setSendResponsesToSource(true); // This function never throws. - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Now the destination address should be source address. EXPECT_EQ("192.0.2.1", resp->getRemoteAddr().toText()); @@ -527,7 +527,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataRenew) { // Copy hops value from the query. resp->setHops(req->getHops()); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Check that server responds to ciaddr EXPECT_EQ("192.0.1.15", resp->getRemoteAddr().toText()); @@ -594,9 +594,9 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressRenewSendToSourceTestingModeEnabled) { resp->setHops(req->getHops()); // Set the testing mode. - srv_.setSendResponsesToSource(true); + srv_->setSendResponsesToSource(true); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Check that server responds to source address. EXPECT_EQ("192.0.2.1", resp->getRemoteAddr().toText()); @@ -657,7 +657,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataSelect) { // are zero and client has just got new lease, the assigned address is // carried in yiaddr. In order to send this address to the client, // server must broadcast its response. - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Check that the response is sent to broadcast address as the // server doesn't have capability to respond directly. @@ -686,7 +686,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataSelect) { // Now we expect that the server will send its response to the // address assigned for the client. - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); EXPECT_EQ("192.0.1.13", resp->getRemoteAddr().toText()); } @@ -735,9 +735,9 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressSelectSendToSourceTestingModeEnabled) { test_config.setDirectResponse(false); // Set the testing mode. - srv_.setSendResponsesToSource(true); + srv_->setSendResponsesToSource(true); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Check that server responds to source address. EXPECT_EQ("192.0.2.1", resp->getRemoteAddr().toText()); @@ -748,7 +748,7 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressSelectSendToSourceTestingModeEnabled) { // Clear the remote address. resp->setRemoteAddr(IOAddress("0.0.0.0")); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Check that server still responds to source address. EXPECT_EQ("192.0.2.1", resp->getRemoteAddr().toText()); @@ -791,7 +791,7 @@ TEST_F(Dhcpv4SrvTest, adjustIfaceDataBroadcast) { // Clear the remote address. resp->setRemoteAddr(IOAddress("0.0.0.0")); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Server must respond to broadcast address when client desired that // by setting the broadcast flag in its request. @@ -849,9 +849,9 @@ TEST_F(Dhcpv4SrvTest, adjustRemoteAddressBroadcastSendToSourceTestingModeEnabled resp->setRemoteAddr(IOAddress("0.0.0.0")); // Set the testing mode. - srv_.setSendResponsesToSource(true); + srv_->setSendResponsesToSource(true); - ASSERT_NO_THROW(srv_.adjustIfaceData(ex)); + ASSERT_NO_THROW(srv_->adjustIfaceData(ex)); // Check that server responds to source address. EXPECT_EQ("192.0.2.1", resp->getRemoteAddr().toText()); @@ -3896,21 +3896,21 @@ TEST_F(Dhcpv4SrvTest, clientClassify) { // This discover does not belong to foo class, so it will not // be serviced bool drop = false; - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Let's add the packet to bar class and try again. dis->addClass("bar"); // Still not supported, because it belongs to wrong class. - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Let's add it to matching class. dis->addClass("foo"); // This time it should work - EXPECT_TRUE(srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); } @@ -4232,7 +4232,7 @@ TEST_F(Dhcpv4SrvTest, prlPersistency) { query->addOption(hostname); // Let the server process it. - Pkt4Ptr response = srv_.processDiscover(query); + Pkt4Ptr response = srv_->processDiscover(query); // Processing should add an ip-forwarding option ASSERT_TRUE(response->getOption(DHO_IP_FORWARDING)); @@ -4247,7 +4247,7 @@ TEST_F(Dhcpv4SrvTest, prlPersistency) { query->addOption(prl); // Let the server process it again. - response = srv_.processDiscover(query); + response = srv_->processDiscover(query); // Processing should add an ip-forwarding option ASSERT_TRUE(response->getOption(DHO_IP_FORWARDING)); @@ -4285,7 +4285,7 @@ TEST_F(Dhcpv4SrvTest, neverSend) { query->addOption(hostname); // Let the server process it. - Pkt4Ptr response = srv_.processDiscover(query); + Pkt4Ptr response = srv_->processDiscover(query); // Processing should not add an ip-forwarding option ASSERT_FALSE(response->getOption(DHO_IP_FORWARDING)); @@ -4300,7 +4300,7 @@ TEST_F(Dhcpv4SrvTest, neverSend) { query->addOption(prl); // Let the server process it again. - response = srv_.processDiscover(query); + response = srv_->processDiscover(query); // Processing should not add an ip-forwarding option ASSERT_FALSE(response->getOption(DHO_IP_FORWARDING)); @@ -4366,28 +4366,28 @@ TEST_F(Dhcpv4SrvTest, relayOverride) { // belongs to the first subnet, so it is selected dis->setGiaddr(IOAddress("192.0.2.1")); bool drop = false; - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Relay belongs to the second subnet, so it should be selected. dis->setGiaddr(IOAddress("192.0.3.1")); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Now let's check if the relay override for the first subnets works dis->setGiaddr(IOAddress("192.0.5.1")); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // The same check for the second subnet... dis->setGiaddr(IOAddress("192.0.5.2")); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // And finally, let's check if mis-matched relay address will end up // in not selecting a subnet at all dis->setGiaddr(IOAddress("192.0.5.3")); - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Finally, check that the relay override works only with relay address @@ -4395,7 +4395,7 @@ TEST_F(Dhcpv4SrvTest, relayOverride) { dis->setGiaddr(IOAddress("0.0.0.0")); dis->setHops(0); dis->setCiaddr(IOAddress("192.0.5.1")); - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); } @@ -4456,13 +4456,13 @@ TEST_F(Dhcpv4SrvTest, relayOverrideAndClientClass) { // subnet[1], because the subnet matches and there are no class // requirements. bool drop = false; - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Now let's add this packet to class foo and recheck. This time it should // be accepted in the first subnet, because both class and relay-ip match. dis->addClass("foo"); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); } @@ -4535,18 +4535,18 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) { // belongs to the second subnet, so it is selected dis->setGiaddr(IOAddress("192.0.3.1")); bool drop = false; - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Setup a relay override for the first subnet as it has a high precedence dis->setGiaddr(IOAddress("192.0.5.1")); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Put a RAI to select back the second subnet as it has // the highest precedence dis->addOption(rai); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Subnet select option has a lower precedence @@ -4555,7 +4555,7 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) { ASSERT_TRUE(sbnsel); sbnsel->writeAddress(IOAddress("192.0.2.3")); dis->addOption(sbnsel); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // But, when RAI exists without the link selection option, we should @@ -4564,7 +4564,7 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) { dis->delOption(DHO_DHCP_AGENT_OPTIONS); dis->addOption(rai); dis->setGiaddr(IOAddress("192.0.4.1")); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Check client-classification still applies @@ -4577,11 +4577,11 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) { dis->addOption(rai); // Note it shall fail (vs. try the next criterion). - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Add the packet to the class and check again: now it shall succeed dis->addClass("foo"); - EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet3 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Check it fails with a bad address in the sub-option @@ -4592,7 +4592,7 @@ TEST_F(Dhcpv4SrvTest, relayLinkSelect) { dis->delOption(DHO_DHCP_AGENT_OPTIONS); rai->addOption(ols); dis->addOption(rai); - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); } @@ -4666,19 +4666,19 @@ TEST_F(Dhcpv4SrvTest, relayIgnoreLinkSelect) { // belongs to the second subnet, so it is selected dis->setGiaddr(IOAddress("192.0.3.1")); bool drop = false; - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Setup a relay override for the first subnet as it has a high precedence dis->setGiaddr(IOAddress("192.0.5.1")); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Put a RAI to select back the second subnet as it has // the highest precedence, but it should be ignored due // to the ignore-rai-link-selection compatibility config dis->addOption(rai); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Subnet select option has a lower precedence, but will succeed @@ -4688,7 +4688,7 @@ TEST_F(Dhcpv4SrvTest, relayIgnoreLinkSelect) { ASSERT_TRUE(sbnsel); sbnsel->writeAddress(IOAddress("192.0.2.3")); dis->addOption(sbnsel); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // But, when RAI exists without the link selection option, we should @@ -4697,7 +4697,7 @@ TEST_F(Dhcpv4SrvTest, relayIgnoreLinkSelect) { dis->delOption(DHO_DHCP_AGENT_OPTIONS); dis->addOption(rai); dis->setGiaddr(IOAddress("192.0.4.1")); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Check client-classification still applies @@ -4710,11 +4710,11 @@ TEST_F(Dhcpv4SrvTest, relayIgnoreLinkSelect) { dis->addOption(rai); // Note it shall fail (vs. try the next criterion). - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Add the packet to the class and check again: now it shall succeed dis->addClass("foo"); - EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet3 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Check it succeeds even with a bad address in the sub-option @@ -4725,7 +4725,7 @@ TEST_F(Dhcpv4SrvTest, relayIgnoreLinkSelect) { dis->delOption(DHO_DHCP_AGENT_OPTIONS); rai->addOption(ols); dis->addOption(rai); - EXPECT_TRUE(srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); } @@ -4793,33 +4793,33 @@ TEST_F(Dhcpv4SrvTest, subnetSelect) { // belongs to the second subnet, so it is selected dis->setGiaddr(IOAddress("192.0.3.1")); bool drop = false; - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Setup a relay override for the first subnet as it has a high precedence dis->setGiaddr(IOAddress("192.0.5.1")); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Put a subnet select option to select back the second subnet as // it has the second highest precedence dis->addOption(sbnsel); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Check client-classification still applies sbnsel->writeAddress(IOAddress("192.0.4.2")); // Note it shall fail (vs. try the next criterion). - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Add the packet to the class and check again: now it shall succeed dis->addClass("foo"); - EXPECT_TRUE(subnet3 == srv_.selectSubnet(dis, drop)); + EXPECT_TRUE(subnet3 == srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); // Check it fails with a bad address in the sub-option sbnsel->writeAddress(IOAddress("10.0.0.1")); - EXPECT_FALSE(srv_.selectSubnet(dis, drop)); + EXPECT_FALSE(srv_->selectSubnet(dis, drop)); EXPECT_FALSE(drop); } @@ -6476,7 +6476,7 @@ TEST_F(StashAgentOptionTest, basic) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); ASSERT_TRUE(rai_query); EXPECT_EQ(rai_query->toHexString(true), rai_->toHexString(true)); @@ -6494,7 +6494,7 @@ TEST_F(StashAgentOptionTest, clientId) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); ASSERT_TRUE(rai_query); EXPECT_EQ(rai_query->toHexString(true), rai_->toHexString(true)); @@ -6511,7 +6511,7 @@ TEST_F(StashAgentOptionTest, hardwareAddress) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); ASSERT_TRUE(rai_query); EXPECT_EQ(rai_query->toHexString(true), rai_->toHexString(true)); @@ -6526,7 +6526,7 @@ TEST_F(StashAgentOptionTest, oldExtendedInfo) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); ASSERT_TRUE(rai_query); EXPECT_EQ(rai_query->toHexString(true), rai_->toHexString(true)); @@ -6543,7 +6543,7 @@ TEST_F(StashAgentOptionTest, emptyRelayAgentInfo) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); ASSERT_TRUE(rai_query); EXPECT_FALSE(rai_query->getOptions().empty()); @@ -6559,7 +6559,7 @@ TEST_F(StashAgentOptionTest, clientAddress) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6573,14 +6573,14 @@ TEST_F(StashAgentOptionTest, gatewayAddress) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); // Even broadcast is not accepted. query_->setGiaddr(IOAddress::IPV4_BCAST_ADDRESS()); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6592,7 +6592,7 @@ TEST_F(StashAgentOptionTest, stashAgentOption) { EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6610,7 +6610,7 @@ TEST_F(StashAgentOptionTest, request) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6624,7 +6624,7 @@ TEST_F(StashAgentOptionTest, notEmptyRelayAgentInfo) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); } @@ -6636,7 +6636,7 @@ TEST_F(StashAgentOptionTest, inClass) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_TRUE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6647,7 +6647,7 @@ TEST_F(StashAgentOptionTest, lease) { CfgMgr::instance().commit(); // Not add the lease. - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6663,7 +6663,7 @@ TEST_F(StashAgentOptionTest, expired) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6677,7 +6677,7 @@ TEST_F(StashAgentOptionTest, userContext) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6696,7 +6696,7 @@ TEST_F(StashAgentOptionTest, iscEntry) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6715,7 +6715,7 @@ TEST_F(StashAgentOptionTest, relayAgentInfoEntry) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6730,7 +6730,7 @@ TEST_F(StashAgentOptionTest, badRelayAgentInfoEntry) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6746,7 +6746,7 @@ TEST_F(StashAgentOptionTest, subOptionsEntry) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6761,7 +6761,7 @@ TEST_F(StashAgentOptionTest, badSubOptionsEntry) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6776,7 +6776,7 @@ TEST_F(StashAgentOptionTest, emptySubOptionsEntry) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6791,7 +6791,7 @@ TEST_F(StashAgentOptionTest, hexString) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_THROW(srv_.recoverStashedAgentOption(query_), BadValue); + EXPECT_THROW(srv_->recoverStashedAgentOption(query_), BadValue); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); } @@ -6807,7 +6807,7 @@ TEST_F(StashAgentOptionTest, badRelayAgentInfo) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6821,7 +6821,7 @@ TEST_F(StashAgentOptionTest, badRelayAgentInfo) { sub_options_ = Element::create(content); relay_agent_info_->set("sub-options", sub_options_); - EXPECT_THROW(srv_.recoverStashedAgentOption(query_), OptionParseError); + EXPECT_THROW(srv_->recoverStashedAgentOption(query_), OptionParseError); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); } @@ -6834,7 +6834,7 @@ TEST_F(StashAgentOptionTest, badClientId) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); @@ -6855,7 +6855,7 @@ TEST_F(StashAgentOptionTest, badHwareAddress) { CfgMgr::instance().commit(); EXPECT_NO_THROW(LeaseMgrFactory::instance().addLease(lease_)); - EXPECT_NO_THROW(srv_.recoverStashedAgentOption(query_)); + EXPECT_NO_THROW(srv_->recoverStashedAgentOption(query_)); OptionPtr rai_query = query_->getOption(DHO_DHCP_AGENT_OPTIONS); EXPECT_FALSE(rai_query); EXPECT_FALSE(query_->inClass("STASH_AGENT_OPTIONS")); diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.cc b/src/bin/dhcp4/tests/dhcp4_test_utils.cc index a4c4772311..4fe44e2571 100644 --- a/src/bin/dhcp4/tests/dhcp4_test_utils.cc +++ b/src/bin/dhcp4/tests/dhcp4_test_utils.cc @@ -58,7 +58,7 @@ BaseServerTest::~BaseServerTest() { } Dhcpv4SrvTest::Dhcpv4SrvTest() - : rcode_(-1), srv_(0), multi_threading_(false), start_time_(PktEvent::now()) { + : rcode_(-1), srv_(new NakedDhcpv4Srv(0)), multi_threading_(false), start_time_(PktEvent::now()) { // Wipe any existing statistics isc::stats::StatsMgr::instance().removeAll(); @@ -795,7 +795,7 @@ Dhcpv4SrvTest::buildCfgOptionTest(IOAddress expected_server_id, query->addOption(makeServerIdOption(server_id)); Pkt4Ptr response; - ASSERT_NO_THROW(response = srv_.processRequest(query)); + ASSERT_NO_THROW(response = srv_->processRequest(query)); checkServerIdOption(response, expected_server_id); @@ -811,7 +811,7 @@ Dhcpv4SrvTest::configure(const std::string& config, const bool create_managers, const bool test, const LeaseAffinity lease_affinity) { - configure(config, srv_, commit, open_sockets, create_managers, test, + configure(config, *srv_, commit, open_sockets, create_managers, test, lease_affinity); } @@ -941,11 +941,11 @@ Dhcpv4SrvTest::configureWithStatus(const std::string& config, NakedDhcpv4Srv& sr Dhcpv4Exchange Dhcpv4SrvTest::createExchange(const Pkt4Ptr& query) { bool drop = false; - ConstSubnet4Ptr subnet = srv_.selectSubnet(query, drop); + ConstSubnet4Ptr subnet = srv_->selectSubnet(query, drop); EXPECT_FALSE(drop); AllocEngine::ClientContext4Ptr context(new AllocEngine::ClientContext4()); - EXPECT_TRUE(srv_.earlyGHRLookup(query, context)); - Dhcpv4Exchange ex(srv_.alloc_engine_, query, context, subnet, drop); + EXPECT_TRUE(srv_->earlyGHRLookup(query, context)); + Dhcpv4Exchange ex(srv_->alloc_engine_, query, context, subnet, drop); EXPECT_FALSE(context); EXPECT_FALSE(drop); return (ex); diff --git a/src/bin/dhcp4/tests/dhcp4_test_utils.h b/src/bin/dhcp4/tests/dhcp4_test_utils.h index 8fb05776cc..dafc2a4518 100644 --- a/src/bin/dhcp4/tests/dhcp4_test_utils.h +++ b/src/bin/dhcp4/tests/dhcp4_test_utils.h @@ -23,7 +23,7 @@ #include #include #include -#include +#include #include #include #include @@ -93,7 +93,7 @@ typedef boost::shared_ptr PktFilterTestPtr; class Dhcp4Client; /// @brief "Naked" DHCPv4 server, exposes internal fields -class NakedDhcpv4Srv: public Dhcpv4Srv { +class NakedDhcpv4Srv: public ControlledDhcpv4Srv { public: /// @brief Constructor. @@ -122,7 +122,7 @@ public: /// @param port port number to listen on; the default value 0 indicates /// that sockets should not be opened. NakedDhcpv4Srv(uint16_t port = 0) - : Dhcpv4Srv(port, false, false) { + : ControlledDhcpv4Srv(port) { // Create a default lease database backend. std::string dbconfig = "type=memfile universe=4 persist=false"; isc::dhcp::LeaseMgrFactory::create(dbconfig); @@ -744,7 +744,7 @@ public: isc::data::ConstElementPtr comment_; /// @brief Server object under test. - NakedDhcpv4Srv srv_; + boost::shared_ptr srv_; /// @brief The multi-threading flag. bool multi_threading_; diff --git a/src/bin/dhcp4/tests/direct_client_unittest.cc b/src/bin/dhcp4/tests/direct_client_unittest.cc index e85a6fc598..78326ab40a 100644 --- a/src/bin/dhcp4/tests/direct_client_unittest.cc +++ b/src/bin/dhcp4/tests/direct_client_unittest.cc @@ -240,26 +240,26 @@ DirectClientTest::twoSubnets() { ASSERT_NO_FATAL_FAILURE(configureTwoSubnets("192.0.2.0", "10.0.0.0")); // Create Discover and simulate reception of this message through eth0. Pkt4Ptr dis = createClientMessage(DHCPDISCOVER, "eth0", ETH0_INDEX); - srv_.fakeReceive(dis); + srv_->fakeReceive(dis); // Create Request and simulate reception of this message through eth1. Pkt4Ptr req = createClientMessage(DHCPREQUEST, "eth1", ETH1_INDEX); - srv_.fakeReceive(req); + srv_->fakeReceive(req); // Process clients' messages. - srv_.run(); + srv_->run(); // Check that the server did send responses. - ASSERT_EQ(2, srv_.fake_sent_.size()); + ASSERT_EQ(2, srv_->fake_sent_.size()); // In multi-threading responses can be received out of order. Pkt4Ptr offer; Pkt4Ptr ack; - while (srv_.fake_sent_.size()) { + while (srv_->fake_sent_.size()) { // Make sure that we received a response. - Pkt4Ptr response = srv_.fake_sent_.front(); + Pkt4Ptr response = srv_->fake_sent_.front(); ASSERT_TRUE(response); - srv_.fake_sent_.pop_front(); + srv_->fake_sent_.pop_front(); if (response->getType() == DHCPOFFER) { offer = response; @@ -310,23 +310,23 @@ DirectClientTest::oneSubnet() { ASSERT_NO_FATAL_FAILURE(configureSubnet("10.0.0.0")); // Create Discover and simulate reception of this message through eth0. Pkt4Ptr dis = createClientMessage(DHCPDISCOVER, "eth0", ETH0_INDEX); - srv_.fakeReceive(dis); + srv_->fakeReceive(dis); // Create Request and simulate reception of this message through eth1. Pkt4Ptr req = createClientMessage(DHCPDISCOVER, "eth1", ETH1_INDEX); - srv_.fakeReceive(req); + srv_->fakeReceive(req); // Process clients' messages. - srv_.run(); + srv_->run(); // Check that the server sent one response for the message received // through eth0. The other client's message should be discarded. - ASSERT_EQ(1, srv_.fake_sent_.size()); + ASSERT_EQ(1, srv_->fake_sent_.size()); // Check the response. The first Discover was sent via eth0 for which // the subnet has been configured. - Pkt4Ptr response = srv_.fake_sent_.front(); + Pkt4Ptr response = srv_->fake_sent_.front(); ASSERT_TRUE(response); - srv_.fake_sent_.pop_front(); + srv_->fake_sent_.pop_front(); // Since Discover has been received through the interface for which // the subnet has been configured, the server should respond with diff --git a/src/bin/dhcp4/tests/release_unittest.cc b/src/bin/dhcp4/tests/release_unittest.cc index 8e5038aaa5..d0a3d748ea 100644 --- a/src/bin/dhcp4/tests/release_unittest.cc +++ b/src/bin/dhcp4/tests/release_unittest.cc @@ -417,4 +417,96 @@ TEST_F(ReleaseTest, releaseNoDeleteNoSubnet) { EXPECT_EQ(lease->valid_lft_, 0); } +// This test verifies that an incoming RELEASE for an address within +// a subnet can be reclaimed and does not cause counters to decrease below 0. +TEST_F(ReleaseTest, releaseAndReclaim) { + Dhcp4Client client(srv_, Dhcp4Client::SELECTING); + // Configure DHCP server. + const char* RELEASE_CONFIG = { + // Configuration 0 + "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"valid-lifetime\": 1," + "\"subnet4\": [ { " + " \"subnet\": \"10.0.0.0/24\", " + " \"id\": 1," + " \"pools\": [ { \"pool\": \"10.0.0.10-10.0.0.100\" } ]," + " \"option-data\": [ {" + " \"name\": \"routers\"," + " \"data\": \"10.0.0.200,10.0.0.201\"" + " } ]" + " } ]," + " \"expired-leases-processing\": {" + " \"flush-reclaimed-timer-wait-time\": 3," + " \"hold-reclaimed-time\": 1," + " \"max-reclaim-leases\": 100," + " \"max-reclaim-time\": 250," + " \"reclaim-timer-wait-time\": 1," + " \"unwarned-reclaim-cycles\": 5" + "}," + "\"multi-threading\": { \"enable-multi-threading\": false }" + "}" + }; + + setenv("KEA_LFC_EXECUTABLE", KEA_LFC_EXECUTABLE, 1); + ConstElementPtr json; + try { + json = parseJSON(RELEASE_CONFIG); + } catch (const std::exception& ex) { + // Fatal failure on parsing error + FAIL() << "parsing failure:" + << "config:" << RELEASE_CONFIG << std::endl + << "error: " << ex.what(); + } + + disableIfacesReDetect(json); + + client.getServer()->processConfig(json); + + CfgMgr::instance().commit(); + + // Perform 4-way exchange to obtain a new lease. + acquireLease(client); + + std::stringstream name; + + // Let's get the subnet-id and generate statistics name out of it + const Subnet4Collection* subnets = + CfgMgr::instance().getCurrentCfg()->getCfgSubnets4()->getAll(); + ASSERT_EQ(1, subnets->size()); + name << "subnet[" << (*subnets->begin())->getID() << "].assigned-addresses"; + + ObservationPtr assigned_cnt = StatsMgr::instance().getObservation(name.str()); + ASSERT_TRUE(assigned_cnt); + uint64_t before = assigned_cnt->getInteger().first; + + // Remember the acquired address. + IOAddress leased_address = client.config_.lease_.addr_; + + // Release is as it was relayed + client.useRelay(true); + + // Send the release + ASSERT_NO_THROW(client.doRelease()); + + // Check that the lease was not removed + Lease4Ptr lease = LeaseMgrFactory::instance().getLease4(leased_address); + ASSERT_TRUE(lease); + + // Check That the lease has been expired + EXPECT_EQ(lease->valid_lft_, 0); + + assigned_cnt = StatsMgr::instance().getObservation(name.str()); + ASSERT_TRUE(assigned_cnt); + uint64_t after = assigned_cnt->getInteger().first; + ASSERT_EQ(after, before - 1); + sleep(1); + client.getServer()->getIOService()->poll(); + assigned_cnt = StatsMgr::instance().getObservation(name.str()); + ASSERT_TRUE(assigned_cnt); + uint64_t count = assigned_cnt->getInteger().first; + ASSERT_EQ(count, after); +} + } // end of anonymous namespace diff --git a/src/bin/dhcp6/tests/addr_reg_unittest.cc b/src/bin/dhcp6/tests/addr_reg_unittest.cc index ec774eee9e..8fc8c5ffa0 100644 --- a/src/bin/dhcp6/tests/addr_reg_unittest.cc +++ b/src/bin/dhcp6/tests/addr_reg_unittest.cc @@ -306,16 +306,16 @@ string AddrRegTest::cumulative_registered_nas_name_ = TEST_F(AddrRegTest, sanityCheck) { // A message with no client-id should fail Pkt6Ptr addr_reg_inf = Pkt6Ptr(new Pkt6(DHCPV6_ADDR_REG_INFORM, 1234)); - EXPECT_FALSE(srv_.sanityCheck(addr_reg_inf)); + EXPECT_FALSE(srv_->sanityCheck(addr_reg_inf)); // A message with a single client-id should succeed OptionPtr clientid = generateClientId(); addr_reg_inf->addOption(clientid); - EXPECT_TRUE(srv_.sanityCheck(addr_reg_inf)); + EXPECT_TRUE(srv_->sanityCheck(addr_reg_inf)); // A message with server-id present should fail - addr_reg_inf->addOption(srv_.getServerID()); - EXPECT_FALSE(srv_.sanityCheck(addr_reg_inf)); + addr_reg_inf->addOption(srv_->getServerID()); + EXPECT_FALSE(srv_->sanityCheck(addr_reg_inf)); } // Test that more than one client-id are forbidden for Addr-reg-inform messages @@ -326,7 +326,7 @@ TEST_F(AddrRegTest, sanityCheck2) { OptionPtr clientid = generateClientId(); addr_reg_inf->addOption(clientid); addr_reg_inf->addOption(clientid); - EXPECT_FALSE(srv_.sanityCheck(addr_reg_inf)); + EXPECT_FALSE(srv_->sanityCheck(addr_reg_inf)); } // Test that subnet selection must return a subnet for processAddrRegInform. @@ -338,16 +338,16 @@ TEST_F(AddrRegTest, noSubnet) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_FALSE(ctx.subnet_); // No server: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); // The query is silently rejected so no log to check. } @@ -367,16 +367,16 @@ TEST_F(AddrRegTest, noIA_NA) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // No IA_NA: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::abcd: "; @@ -401,16 +401,16 @@ TEST_F(AddrRegTest, twoIA_NAs) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // 2 IA_NA options: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::abcd: "; @@ -434,16 +434,16 @@ TEST_F(AddrRegTest, noIA_NAsub) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // No IA_NA sub-options: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::abcd: "; @@ -470,16 +470,16 @@ TEST_F(AddrRegTest, twoIA_NAsub) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Two IA_NA sub-options: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::abcd: "; @@ -505,16 +505,16 @@ TEST_F(AddrRegTest, noAddrMatch) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Address mismatch: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::abcd: "; @@ -547,16 +547,16 @@ TEST_F(AddrRegTest, noAddrMatchRelay) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Address mismatch: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::ef01: "; @@ -595,16 +595,16 @@ TEST_F(AddrRegTest, noAddrMatch2Relays) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Address mismatch: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client fe80::2345: "; @@ -631,16 +631,16 @@ TEST_F(AddrRegTest, noInSubnet) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Not in subnet: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client 2001:db8::1: "; @@ -667,16 +667,16 @@ TEST_F(AddrRegTest, reserved) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Reserved address: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client 2001:db8:1::10: "; @@ -710,16 +710,16 @@ AddrRegTest::testAddressInUse(const uint32_t state) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Address in use: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); string expected = "DHCP6_ADDR_REG_INFORM_FAIL "; expected += "error on ADDR-REG-INFORM from client 2001:db8:1::1: "; @@ -774,16 +774,16 @@ AddrRegTest::testBasic() { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf_, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf_, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf_, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf_, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); EXPECT_EQ(DHCPV6_ADDR_REG_REPLY, response->getType()); @@ -851,16 +851,16 @@ TEST_F(AddrRegTest, relayed) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); EXPECT_EQ(DHCPV6_ADDR_REG_REPLY, response->getType()); @@ -918,16 +918,16 @@ AddrRegTest::testRenew() { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf_, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf_, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf_, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf_, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); // Verify the updated lease. @@ -981,16 +981,16 @@ AddrRegTest::testAnotherClient() { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf_, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf_, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf_, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf_, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); // Verify the updated lease. @@ -1048,16 +1048,16 @@ AddrRegTest::testAnotherSubnet() { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf_, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf_, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf_, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf_, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); // Verify the updated lease. @@ -1093,7 +1093,7 @@ TEST_F(AddrRegTest, fqdn) { IfaceMgrTestConfig test_config(true); ASSERT_NO_THROW(configure(config_)); - ASSERT_NO_THROW(srv_.startD2()); + ASSERT_NO_THROW(srv_->startD2()); IOAddress addr("2001:db8:1::1"); Pkt6Ptr addr_reg_inf = Pkt6Ptr(new Pkt6(DHCPV6_ADDR_REG_INFORM, 1234)); @@ -1114,16 +1114,16 @@ TEST_F(AddrRegTest, fqdn) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); EXPECT_EQ(DHCPV6_ADDR_REG_REPLY, response->getType()); @@ -1162,7 +1162,7 @@ TEST_F(AddrRegTest, renewDdns) { IfaceMgrTestConfig test_config(true); ASSERT_NO_THROW(configure(config_)); - ASSERT_NO_THROW(srv_.startD2()); + ASSERT_NO_THROW(srv_->startD2()); IOAddress addr("2001:db8:1::1"); Pkt6Ptr addr_reg_inf = Pkt6Ptr(new Pkt6(DHCPV6_ADDR_REG_INFORM, 1234)); @@ -1183,16 +1183,16 @@ TEST_F(AddrRegTest, renewDdns) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); // There should be one name change request generated. @@ -1205,15 +1205,15 @@ TEST_F(AddrRegTest, renewDdns) { // Process it a second time. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx2); + drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx2.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx2.subnet_); - response = srv_.processAddrRegInform(ctx2); + response = srv_->processAddrRegInform(ctx2); ASSERT_TRUE(response); // DDNS is skipped when ddns-update-on-renew is false (default). @@ -1237,7 +1237,7 @@ TEST_F(AddrRegTest, renewDdnsUpdateOnRenew) { CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getSubnet(1); ASSERT_TRUE(subnet); ASSERT_NO_THROW(subnet->setDdnsUpdateOnRenew(true)); - ASSERT_NO_THROW(srv_.startD2()); + ASSERT_NO_THROW(srv_->startD2()); IOAddress addr("2001:db8:1::1"); Pkt6Ptr addr_reg_inf = Pkt6Ptr(new Pkt6(DHCPV6_ADDR_REG_INFORM, 1234)); @@ -1258,16 +1258,16 @@ TEST_F(AddrRegTest, renewDdnsUpdateOnRenew) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); // There should be one name change request generated. @@ -1280,15 +1280,15 @@ TEST_F(AddrRegTest, renewDdnsUpdateOnRenew) { // Process it a second time. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx2); + drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx2.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx2.subnet_); - response = srv_.processAddrRegInform(ctx2); + response = srv_->processAddrRegInform(ctx2); ASSERT_TRUE(response); // DDNS is not skipped when ddns-update-on-renew is true. @@ -1309,7 +1309,7 @@ TEST_F(AddrRegTest, renewDdnsHostname) { IfaceMgrTestConfig test_config(true); ASSERT_NO_THROW(configure(config_)); - ASSERT_NO_THROW(srv_.startD2()); + ASSERT_NO_THROW(srv_->startD2()); IOAddress addr("2001:db8:1::1"); Pkt6Ptr addr_reg_inf = Pkt6Ptr(new Pkt6(DHCPV6_ADDR_REG_INFORM, 1234)); @@ -1330,16 +1330,16 @@ TEST_F(AddrRegTest, renewDdnsHostname) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); // There should be one name change request generated. @@ -1359,15 +1359,15 @@ TEST_F(AddrRegTest, renewDdnsHostname) { // Process it a second time. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx2); + drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx2.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx2.subnet_); - response = srv_.processAddrRegInform(ctx2); + response = srv_->processAddrRegInform(ctx2); ASSERT_TRUE(response); // DDNS is not skipped when the hostname changed. @@ -1407,16 +1407,16 @@ TEST_F(AddrRegTest, oro) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); EXPECT_EQ(DHCPV6_ADDR_REG_REPLY, response->getType()); @@ -1541,16 +1541,16 @@ TEST_F(AddrRegTest, calloutSkip) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf_, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf_, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf_, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf_, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Verify the response. - Pkt6Ptr response = srv_.processAddrRegInform(ctx); + Pkt6Ptr response = srv_->processAddrRegInform(ctx); ASSERT_TRUE(response); EXPECT_TRUE(callout_errmsg_.empty()) << callout_errmsg_; checkCalloutHandleReset(); @@ -1596,16 +1596,16 @@ TEST_F(AddrRegTest, calloutDrop) { // Pass it to the server. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(addr_reg_inf_, ctx); + bool drop = !srv_->earlyGHRLookup(addr_reg_inf_, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(addr_reg_inf_, drop); + ctx.subnet_ = srv_->selectSubnet(addr_reg_inf_, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); ASSERT_TRUE(ctx.subnet_); // Callout set the status to drop: no response. - EXPECT_FALSE(srv_.processAddrRegInform(ctx)); + EXPECT_FALSE(srv_->processAddrRegInform(ctx)); EXPECT_TRUE(callout_errmsg_.empty()) << callout_errmsg_; checkCalloutHandleReset(); diff --git a/src/bin/dhcp6/tests/classify_unittest.cc b/src/bin/dhcp6/tests/classify_unittest.cc index 46f561bd56..673d71cbc3 100644 --- a/src/bin/dhcp6/tests/classify_unittest.cc +++ b/src/bin/dhcp6/tests/classify_unittest.cc @@ -534,7 +534,7 @@ public: AllocEngine::ClientContext6 ctx; bool drop = !srv.earlyGHRLookup(query, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(query, drop); + ctx.subnet_ = srv_->selectSubnet(query, drop); ASSERT_FALSE(drop); srv.initContext(ctx, drop); ASSERT_FALSE(drop); @@ -671,7 +671,7 @@ TEST_F(ClassifyTest, matchClassification) { AllocEngine::ClientContext6 ctx1; bool drop = !srv.earlyGHRLookup(query1, ctx1); ASSERT_FALSE(drop); - ctx1.subnet_ = srv_.selectSubnet(query1, drop); + ctx1.subnet_ = srv_->selectSubnet(query1, drop); ASSERT_FALSE(drop); srv.initContext(ctx1, drop); ASSERT_FALSE(drop); @@ -679,7 +679,7 @@ TEST_F(ClassifyTest, matchClassification) { AllocEngine::ClientContext6 ctx2; drop = !srv.earlyGHRLookup(query2, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(query2, drop); + ctx2.subnet_ = srv_->selectSubnet(query2, drop); ASSERT_FALSE(drop); srv.initContext(ctx2, drop); ASSERT_FALSE(drop); @@ -687,7 +687,7 @@ TEST_F(ClassifyTest, matchClassification) { AllocEngine::ClientContext6 ctx3; drop = !srv.earlyGHRLookup(query3, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(query3, drop); + ctx3.subnet_ = srv_->selectSubnet(query3, drop); ASSERT_FALSE(drop); srv.initContext(ctx3, drop); ASSERT_FALSE(drop); @@ -789,7 +789,7 @@ TEST_F(ClassifyTest, additional) { AllocEngine::ClientContext6 ctx1; bool drop = !srv.earlyGHRLookup(query1, ctx1); ASSERT_FALSE(drop); - ctx1.subnet_ = srv_.selectSubnet(query1, drop); + ctx1.subnet_ = srv_->selectSubnet(query1, drop); ASSERT_FALSE(drop); srv.initContext(ctx1, drop); ASSERT_FALSE(drop); @@ -797,7 +797,7 @@ TEST_F(ClassifyTest, additional) { AllocEngine::ClientContext6 ctx2; drop = !srv.earlyGHRLookup(query2, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(query2, drop); + ctx2.subnet_ = srv_->selectSubnet(query2, drop); ASSERT_FALSE(drop); srv.initContext(ctx2, drop); ASSERT_FALSE(drop); @@ -805,7 +805,7 @@ TEST_F(ClassifyTest, additional) { AllocEngine::ClientContext6 ctx3; drop = !srv.earlyGHRLookup(query3, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(query3, drop); + ctx3.subnet_ = srv_->selectSubnet(query3, drop); ASSERT_FALSE(drop); srv.initContext(ctx3, drop); ASSERT_FALSE(drop); @@ -904,7 +904,7 @@ TEST_F(ClassifyTest, additionalClassification) { AllocEngine::ClientContext6 ctx1; bool drop = !srv.earlyGHRLookup(query1, ctx1); ASSERT_FALSE(drop); - ctx1.subnet_ = srv_.selectSubnet(query1, drop); + ctx1.subnet_ = srv_->selectSubnet(query1, drop); ASSERT_FALSE(drop); srv.initContext(ctx1, drop); ASSERT_FALSE(drop); @@ -912,7 +912,7 @@ TEST_F(ClassifyTest, additionalClassification) { AllocEngine::ClientContext6 ctx2; drop = !srv.earlyGHRLookup(query2, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(query2, drop); + ctx2.subnet_ = srv_->selectSubnet(query2, drop); ASSERT_FALSE(drop); srv.initContext(ctx2, drop); ASSERT_FALSE(drop); @@ -920,7 +920,7 @@ TEST_F(ClassifyTest, additionalClassification) { AllocEngine::ClientContext6 ctx3; drop = !srv.earlyGHRLookup(query3, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(query3, drop); + ctx3.subnet_ = srv_->selectSubnet(query3, drop); ASSERT_FALSE(drop); srv.initContext(ctx3, drop); ASSERT_FALSE(drop); @@ -1002,7 +1002,7 @@ TEST_F(ClassifyTest, subnetClassPriority) { AllocEngine::ClientContext6 ctx; bool drop = !srv.earlyGHRLookup(query, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(query, drop); + ctx.subnet_ = srv_->selectSubnet(query, drop); ASSERT_FALSE(drop); srv.initContext(ctx, drop); ASSERT_FALSE(drop); @@ -1071,7 +1071,7 @@ TEST_F(ClassifyTest, subnetGlobalPriority) { AllocEngine::ClientContext6 ctx; bool drop = !srv.earlyGHRLookup(query, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(query, drop); + ctx.subnet_ = srv_->selectSubnet(query, drop); ASSERT_FALSE(drop); srv.initContext(ctx, drop); ASSERT_FALSE(drop); @@ -1149,7 +1149,7 @@ TEST_F(ClassifyTest, classGlobalPriority) { AllocEngine::ClientContext6 ctx; bool drop = !srv.earlyGHRLookup(query, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(query, drop); + ctx.subnet_ = srv_->selectSubnet(query, drop); ASSERT_FALSE(drop); srv.initContext(ctx, drop); ASSERT_FALSE(drop); @@ -1222,7 +1222,7 @@ TEST_F(ClassifyTest, classGlobalPersistency) { AllocEngine::ClientContext6 ctx; bool drop = !srv.earlyGHRLookup(query, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(query, drop); + ctx.subnet_ = srv_->selectSubnet(query, drop); ASSERT_FALSE(drop); srv.initContext(ctx, drop); ASSERT_FALSE(drop); @@ -1294,7 +1294,7 @@ TEST_F(ClassifyTest, classNeverSend) { AllocEngine::ClientContext6 ctx; bool drop = !srv.earlyGHRLookup(query, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(query, drop); + ctx.subnet_ = srv_->selectSubnet(query, drop); ASSERT_FALSE(drop); srv.initContext(ctx, drop); ASSERT_FALSE(drop); @@ -1345,21 +1345,21 @@ TEST_F(ClassifyTest, clientClassifySubnet) { // This discover does not belong to foo class, so it will not // be serviced bool drop = false; - EXPECT_FALSE(srv_.selectSubnet(sol, drop)); + EXPECT_FALSE(srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Let's add the packet to bar class and try again. sol->addClass("bar"); // Still not supported, because it belongs to wrong class. - EXPECT_FALSE(srv_.selectSubnet(sol, drop)); + EXPECT_FALSE(srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Let's add it to matching class. sol->addClass("foo"); // This time it should work - EXPECT_TRUE(srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); } @@ -1416,7 +1416,7 @@ TEST_F(ClassifyTest, clientClassifyPool) { AllocEngine::ClientContext6 ctx1; bool drop = !srv.earlyGHRLookup(query1, ctx1); ASSERT_FALSE(drop); - ctx1.subnet_ = srv_.selectSubnet(query1, drop); + ctx1.subnet_ = srv_->selectSubnet(query1, drop); ASSERT_FALSE(drop); srv.initContext(ctx1, drop); ASSERT_FALSE(drop); @@ -1434,7 +1434,7 @@ TEST_F(ClassifyTest, clientClassifyPool) { AllocEngine::ClientContext6 ctx2; drop = !srv.earlyGHRLookup(query2, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(query2, drop); + ctx2.subnet_ = srv_->selectSubnet(query2, drop); ASSERT_FALSE(drop); srv.initContext(ctx2, drop); ASSERT_FALSE(drop); @@ -1452,7 +1452,7 @@ TEST_F(ClassifyTest, clientClassifyPool) { AllocEngine::ClientContext6 ctx3; drop = !srv.earlyGHRLookup(query3, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(query3, drop); + ctx3.subnet_ = srv_->selectSubnet(query3, drop); ASSERT_FALSE(drop); srv.initContext(ctx3, drop); ASSERT_FALSE(drop); @@ -1512,7 +1512,7 @@ TEST_F(ClassifyTest, clientClassifyPoolKnown) { AllocEngine::ClientContext6 ctx1; bool drop = !srv.earlyGHRLookup(query1, ctx1); ASSERT_FALSE(drop); - ctx1.subnet_ = srv_.selectSubnet(query1, drop); + ctx1.subnet_ = srv_->selectSubnet(query1, drop); ASSERT_FALSE(drop); srv.initContext(ctx1, drop); ASSERT_FALSE(drop); @@ -1544,7 +1544,7 @@ TEST_F(ClassifyTest, clientClassifyPoolKnown) { AllocEngine::ClientContext6 ctx2; drop = !srv.earlyGHRLookup(query2, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(query2, drop); + ctx2.subnet_ = srv_->selectSubnet(query2, drop); ASSERT_FALSE(drop); srv.initContext(ctx2, drop); ASSERT_FALSE(drop); @@ -1650,13 +1650,13 @@ TEST_F(ClassifyTest, relayOverrideAndClientClass) { // subnet[1], because the subnet matches and there are no class // requirements. bool drop = false; - EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Now let's add this packet to class foo and recheck. This time it should // be accepted in the first subnet, because both class and relay-ip match. sol->addClass("foo"); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); } @@ -1847,7 +1847,7 @@ TEST_F(ClassifyTest, member) { AllocEngine::ClientContext6 ctx1; bool drop = !srv.earlyGHRLookup(query1, ctx1); ASSERT_FALSE(drop); - ctx1.subnet_ = srv_.selectSubnet(query1, drop); + ctx1.subnet_ = srv_->selectSubnet(query1, drop); ASSERT_FALSE(drop); srv.initContext(ctx1, drop); ASSERT_FALSE(drop); @@ -1855,7 +1855,7 @@ TEST_F(ClassifyTest, member) { AllocEngine::ClientContext6 ctx2; drop = !srv.earlyGHRLookup(query2, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(query2, drop); + ctx2.subnet_ = srv_->selectSubnet(query2, drop); ASSERT_FALSE(drop); srv.initContext(ctx2, drop); ASSERT_FALSE(drop); @@ -1863,7 +1863,7 @@ TEST_F(ClassifyTest, member) { AllocEngine::ClientContext6 ctx3; drop = !srv.earlyGHRLookup(query3, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(query3, drop); + ctx3.subnet_ = srv_->selectSubnet(query3, drop); ASSERT_FALSE(drop); srv.initContext(ctx3, drop); ASSERT_FALSE(drop); diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 12d4a8a0a6..31449bcb82 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -698,13 +698,13 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) { // Pass it to the server and get an advertise AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr adv = srv_.processSolicit(ctx); + Pkt6Ptr adv = srv_->processSolicit(ctx); // check if we get response at all ASSERT_TRUE(adv); @@ -729,13 +729,13 @@ TEST_F(Dhcpv6SrvTest, advertiseOptions) { // Need to process SOLICIT again after requesting new option. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(sol, ctx2); + drop = !srv_->earlyGHRLookup(sol, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(sol, drop); + ctx2.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); - adv = srv_.processSolicit(ctx2); + adv = srv_->processSolicit(ctx2); ASSERT_TRUE(adv); OptionPtr tmp = adv->getOption(D6O_NAME_SERVERS); @@ -2176,6 +2176,12 @@ TEST_F(Dhcpv6SrvTest, ReleaseBasic) { IOAddress("2001:db8:1:1::cafe:babe"), LEASE_AFFINITY_DISABLED); } +// This test verifies that an incoming RELEASE for an address within +// a subnet can be reclaimed and does not cause counters to decrease below 0. +TEST_F(Dhcpv6SrvTest, ReleaseAndReclaim) { + testReleaseAndReclaim(Lease::TYPE_NA); +} + // This test verifies that incoming (positive) RELEASE with address can be // handled properly, that a REPLY is generated, that the response has status // code and that the lease is expired and not removed from the database. @@ -2234,6 +2240,12 @@ TEST_F(Dhcpv6SrvTest, pdReleaseBasic) { IOAddress("2001:db8:1:2::"), LEASE_AFFINITY_DISABLED); } +// This test verifies that an incoming RELEASE for an address within +// a subnet can be reclaimed and does not cause counters to decrease below 0. +TEST_F(Dhcpv6SrvTest, pdReleaseAndReclaim) { + testReleaseAndReclaim(Lease::TYPE_PD); +} + // This test verifies that incoming (positive) RELEASE with prefix can be // handled properly, that a REPLY is generated, that the response has // status code and that the lease is expired and not removed from the database. @@ -3117,13 +3129,13 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) { // Let the server process it and generate a response. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr response = srv_.processSolicit(ctx); + Pkt6Ptr response = srv_->processSolicit(ctx); // The server should add a subscriber-id option ASSERT_TRUE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -3140,13 +3152,13 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) { // Let the server process it again. This time the name-servers // option should be present. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(sol, ctx2); + drop = !srv_->earlyGHRLookup(sol, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(sol, drop); + ctx2.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); - response = srv_.processSolicit(ctx2); + response = srv_->processSolicit(ctx2); // Processing should add a subscriber-id option ASSERT_TRUE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -3164,13 +3176,13 @@ TEST_F(Dhcpv6SrvTest, prlPersistency) { // Let the server process it again. AllocEngine::ClientContext6 ctx3; - drop = !srv_.earlyGHRLookup(sol, ctx3); + drop = !srv_->earlyGHRLookup(sol, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(sol, drop); + ctx3.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx3, drop); + srv_->initContext(ctx3, drop); ASSERT_FALSE(drop); - response = srv_.processSolicit(ctx3); + response = srv_->processSolicit(ctx3); // The subscriber-id option should be present but only once despite // it is both requested and has always-send. @@ -3206,13 +3218,13 @@ TEST_F(Dhcpv6SrvTest, neverSend) { // Let the server process it and generate a response. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr response = srv_.processSolicit(ctx); + Pkt6Ptr response = srv_->processSolicit(ctx); // The server should not add a subscriber-id option ASSERT_FALSE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -3229,13 +3241,13 @@ TEST_F(Dhcpv6SrvTest, neverSend) { // Let the server process it again. This time the name-servers // option should be present. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(sol, ctx2); + drop = !srv_->earlyGHRLookup(sol, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(sol, drop); + ctx2.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); - response = srv_.processSolicit(ctx2); + response = srv_->processSolicit(ctx2); // Processing should not add a subscriber-id option ASSERT_FALSE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -3253,13 +3265,13 @@ TEST_F(Dhcpv6SrvTest, neverSend) { // Let the server process it again. AllocEngine::ClientContext6 ctx3; - drop = !srv_.earlyGHRLookup(sol, ctx3); + drop = !srv_->earlyGHRLookup(sol, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(sol, drop); + ctx3.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx3, drop); + srv_->initContext(ctx3, drop); ASSERT_FALSE(drop); - response = srv_.processSolicit(ctx3); + response = srv_->processSolicit(ctx3); // The subscriber-id option should still not be present. ASSERT_FALSE(response->getOption(D6O_SUBSCRIBER_ID)); @@ -3354,28 +3366,28 @@ TEST_F(Dhcpv6SrvTest, relayOverride) { // This is just a sanity check, we're using regular method: the relay // belongs to the first (2001:db8:1::/64) subnet, so it's an easy decision. bool drop = false; - EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Relay belongs to the second subnet, so it should be selected. sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:2::1"); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Now let's check if the relay override for the first subnets works sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:3::1"); - EXPECT_TRUE(subnet1 == srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(subnet1 == srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Now repeat that for relay matching the second subnet. sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:3::2"); - EXPECT_TRUE(subnet2 == srv_.selectSubnet(sol, drop)); + EXPECT_TRUE(subnet2 == srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); // Finally, let's check that completely mismatched relay will not get us // anything sol->relay_info_.back().linkaddr_ = IOAddress("2001:db8:1234::1"); - EXPECT_FALSE(srv_.selectSubnet(sol, drop)); + EXPECT_FALSE(srv_->selectSubnet(sol, drop)); EXPECT_FALSE(drop); } diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index fed2be0d61..c22969f150 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -10,6 +10,7 @@ #include #include #include +#include #include #include #include @@ -56,7 +57,7 @@ BaseServerTest::~BaseServerTest() { } Dhcpv6SrvTest::Dhcpv6SrvTest() - : NakedDhcpv6SrvTest(), srv_(0), multi_threading_(false) { + : NakedDhcpv6SrvTest(), srv_(new NakedDhcpv6Srv(0)), multi_threading_(false) { subnet_ = Subnet6::create(isc::asiolink::IOAddress("2001:db8:1::"), 48, 1000, 2000, 3000, 4000, SubnetID(1)); subnet_->setIface("eth0"); @@ -676,6 +677,163 @@ Dhcpv6SrvTest::testReleaseBasic(Lease::Type type, const IOAddress& existing, } } +void +Dhcpv6SrvTest::testReleaseAndReclaim(Lease::Type type) { + IfaceMgrTestConfig iface_mgr_test_config_(true); + + Dhcp6Client client(srv_); + client.setInterface("eth0"); + + // Configure DHCP server. + const char* RELEASE_CONFIG = { + // Configuration 0 + "{ \"interfaces-config\": {" + " \"interfaces\": [ \"*\" ]" + "}," + "\"preferred-lifetime\": 3," + "\"rebind-timer\": 2, " + "\"renew-timer\": 1, " + "\"subnet6\": [ { " + " \"id\": 1, " + " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," + " \"pd-pools\": [ { \"prefix\": \"2001:db8:2::\", \"delegated-len\": 64, \"prefix-len\": 48 } ]," + " \"subnet\": \"2001:db8::/32\", " + " \"interface-id\": \"\"," + " \"interface\": \"eth0\"" + " } ]," + "\"valid-lifetime\": 4," + " \"expired-leases-processing\": {" + " \"flush-reclaimed-timer-wait-time\": 3," + " \"hold-reclaimed-time\": 1," + " \"max-reclaim-leases\": 100," + " \"max-reclaim-time\": 250," + " \"reclaim-timer-wait-time\": 1," + " \"unwarned-reclaim-cycles\": 5" + "}," + "\"multi-threading\": { \"enable-multi-threading\": false }" + "}" + }; + + isc::dhcp::CfgMgr::instance().clear(); + CfgMgr::instance().setFamily(AF_INET6); + + setenv("KEA_LFC_EXECUTABLE", KEA_LFC_EXECUTABLE, 1); + ConstElementPtr json; + try { + json = parseJSON(RELEASE_CONFIG); + } catch (const std::exception& ex) { + // Fatal failure on parsing error + FAIL() << "parsing failure:" + << "config:" << RELEASE_CONFIG << std::endl + << "error: " << ex.what(); + } + + disableIfacesReDetect(json); + + client.getServer()->processConfig(json); + + CfgMgr::instance().commit(); + + const uint32_t iaid = 234; + + uint32_t code; // option code of the container (IA_NA or IA_PD) + uint8_t prefix_len; + if (type == Lease::TYPE_NA) { + code = D6O_IA_NA; + prefix_len = 128; + client.requestAddress(iaid); + } else if (type == Lease::TYPE_PD) { + code = D6O_IA_PD; + prefix_len = pd_pool_->getLength(); + client.requestPrefix(iaid); + } else { + isc_throw(BadValue, "Invalid lease type"); + } + + // Let's get the subnet-id and generate statistics name out of it + const Subnet6Collection* subnets = + CfgMgr::instance().getCurrentCfg()->getCfgSubnets6()->getAll(); + ASSERT_EQ(1, subnets->size()); + + // And prepopulate the stats counter + std::string name = StatsMgr::generateName("subnet", (*subnets->begin())->getID(), + type == Lease::TYPE_NA ? "assigned-nas" : + "assigned-pds"); + + // Perform 4-way exchange. + ASSERT_NO_THROW(client.doSARR()); + + ObservationPtr stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + uint64_t before = stat->getInteger().first; + + // Make sure that the client has acquired NA lease. + std::vector leases = client.getLeasesByType(type); + ASSERT_EQ(1, leases.size()); + EXPECT_EQ(STATUS_Success, client.getStatusCode(iaid)); + + // Let's create a RELEASE + Pkt6Ptr rel = createMessage(DHCPV6_RELEASE, type, leases[0].addr_, prefix_len, + iaid); + rel->addOption(client.getClientId()); + rel->addOption(srv_->getServerID()); + + // Pass it to the server and hope for a REPLY + Pkt6Ptr reply = srv_->processRelease(rel); + + // Check if we get response at all + checkResponse(reply, DHCPV6_REPLY, 1234); + + OptionPtr tmp = reply->getOption(code); + ASSERT_TRUE(tmp); + + // Check that IA_NA was returned and that there's an address included + boost::shared_ptr ia = boost::dynamic_pointer_cast(tmp); + checkIA_NAStatusCode(ia, STATUS_Success, 0, 0); + checkMsgStatusCode(reply, STATUS_Success); + + // There should be no address returned in RELEASE (see RFC 8415, 18.3.7) + // There should be no prefix + EXPECT_FALSE(tmp->getOption(D6O_IAADDR)); + EXPECT_FALSE(tmp->getOption(D6O_IAPREFIX)); + + // Check DUIDs + checkServerId(reply, srv_->getServerID()); + checkClientId(reply, client.getClientId()); + + Lease6Ptr l = LeaseMgrFactory::instance().getLease6(type, leases[0].addr_); + ASSERT_TRUE(l); + + EXPECT_EQ(l->valid_lft_, 0); + EXPECT_EQ(l->preferred_lft_, 0); + + EXPECT_EQ(Lease6::STATE_RELEASED, l->state_); + + stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + uint64_t after = stat->getInteger().first; + ASSERT_EQ(after, before - 1); + sleep(1); + client.getServer()->getIOService()->poll(); + + /* + // get lease by subnetid/duid/iaid combination + l = LeaseMgrFactory::instance().getLease6(type, *duid_, iaid, + (*subnets->begin())->getID()); + ASSERT_TRUE(l); + + EXPECT_EQ(l->valid_lft_, 0); + EXPECT_EQ(l->preferred_lft_, 0); + EXPECT_EQ(Lease::STATE_DEFAULT, lease->state_); + */ + + + stat = StatsMgr::instance().getObservation(name); + ASSERT_TRUE(stat); + uint64_t count = stat->getInteger().first; + ASSERT_EQ(count, after); +} + void Dhcpv6SrvTest::testReleaseNoDelete(Lease::Type type, const IOAddress& addr, uint8_t qtype) { @@ -975,7 +1133,7 @@ Dhcpv6SrvTest::configure(const std::string& config, const bool create_managers, const bool test, const LeaseAffinity lease_affinity) { - configure(config, srv_, commit, open_sockets, create_managers, test, + configure(config, *srv_, commit, open_sockets, create_managers, test, lease_affinity); } diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index 5cdddaec4a..a1ab910a98 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -14,7 +14,7 @@ #include #include -#include +#include #include #include #include @@ -133,9 +133,9 @@ private: }; /// @brief "naked" Dhcpv6Srv class that exposes internal members -class NakedDhcpv6Srv: public isc::dhcp::Dhcpv6Srv { +class NakedDhcpv6Srv: public ControlledDhcpv6Srv { public: - NakedDhcpv6Srv(uint16_t port) : isc::dhcp::Dhcpv6Srv(port) { + NakedDhcpv6Srv(uint16_t port) : ControlledDhcpv6Srv(port) { // Open the "memfile" database for leases std::string memfile = "type=memfile universe=6 persist=false"; isc::dhcp::LeaseMgrFactory::create(memfile); @@ -936,6 +936,15 @@ public: const isc::asiolink::IOAddress& release_addr, const LeaseAffinity lease_affinity); + /// @brief Performs RELEASE test for an address within a subnet + /// and does not cause counters to decrease below 0. + /// + /// This method does not throw, but uses gtest macros to signify failures. + /// + /// @param type type (TYPE_NA or TYPE_PD) + void + testReleaseAndReclaim(isc::dhcp::Lease::Type type); + /// @brief Checks that reassignment of a released-expired lease /// does not lead to zero lifetimes. /// @@ -992,7 +1001,7 @@ public: isc::dhcp::Pool6Ptr pd_pool_; /// @brief Server object under test. - NakedDhcpv6Srv srv_; + boost::shared_ptr srv_; /// @brief The multi-threading flag. bool multi_threading_; diff --git a/src/bin/dhcp6/tests/vendor_opts_unittest.cc b/src/bin/dhcp6/tests/vendor_opts_unittest.cc index 4bdb5b9bcb..30df2331fe 100644 --- a/src/bin/dhcp6/tests/vendor_opts_unittest.cc +++ b/src/bin/dhcp6/tests/vendor_opts_unittest.cc @@ -176,13 +176,13 @@ public: // Pass it to the server and get an advertise. AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr adv = srv_.processSolicit(ctx); + Pkt6Ptr adv = srv_->processSolicit(ctx); // Check if we get a response at all. ASSERT_TRUE(adv); @@ -206,13 +206,13 @@ public: // Need to process SOLICIT again after requesting new option. AllocEngine::ClientContext6 ctx2; - drop = !srv_.earlyGHRLookup(sol, ctx2); + drop = !srv_->earlyGHRLookup(sol, ctx2); ASSERT_FALSE(drop); - ctx2.subnet_ = srv_.selectSubnet(sol, drop); + ctx2.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx2, drop); + srv_->initContext(ctx2, drop); ASSERT_FALSE(drop); - adv = srv_.processSolicit(ctx2); + adv = srv_->processSolicit(ctx2); ASSERT_TRUE(adv); // Check if there is a vendor option in the response, if the Cable Labs @@ -446,13 +446,13 @@ public: // Pass it to the server and get an advertise AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr adv = srv_.processSolicit(ctx); + Pkt6Ptr adv = srv_->processSolicit(ctx); // check if we get response at all ASSERT_TRUE(adv); @@ -684,13 +684,13 @@ public: // Pass it to the server and get an advertise AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr adv = srv_.processSolicit(ctx); + Pkt6Ptr adv = srv_->processSolicit(ctx); // check if we get response at all ASSERT_TRUE(adv); @@ -1389,13 +1389,13 @@ TEST_F(VendorOptsTest, vendorNeverSend) { // Pass it to the server and get an advertise AllocEngine::ClientContext6 ctx; - bool drop = !srv_.earlyGHRLookup(sol, ctx); + bool drop = !srv_->earlyGHRLookup(sol, ctx); ASSERT_FALSE(drop); - ctx.subnet_ = srv_.selectSubnet(sol, drop); + ctx.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx, drop); + srv_->initContext(ctx, drop); ASSERT_FALSE(drop); - Pkt6Ptr adv = srv_.processSolicit(ctx); + Pkt6Ptr adv = srv_->processSolicit(ctx); // check if we get response at all ASSERT_TRUE(adv); @@ -1415,13 +1415,13 @@ TEST_F(VendorOptsTest, vendorNeverSend) { // Need to process SOLICIT again after requesting new option. AllocEngine::ClientContext6 ctx3; - drop = !srv_.earlyGHRLookup(sol, ctx3); + drop = !srv_->earlyGHRLookup(sol, ctx3); ASSERT_FALSE(drop); - ctx3.subnet_ = srv_.selectSubnet(sol, drop); + ctx3.subnet_ = srv_->selectSubnet(sol, drop); ASSERT_FALSE(drop); - srv_.initContext(ctx3, drop); + srv_->initContext(ctx3, drop); ASSERT_FALSE(drop); - adv = srv_.processSolicit(ctx3); + adv = srv_->processSolicit(ctx3); ASSERT_TRUE(adv); // Check if there is vendor option response