2
0
mirror of https://gitlab.isc.org/isc-projects/kea synced 2025-08-22 01:49:48 +00:00

[#1336] added unittests

This commit is contained in:
Razvan Becheriu 2025-03-11 21:53:01 +02:00
parent f44b0ba95c
commit 2890e4e08c
12 changed files with 593 additions and 316 deletions

View File

@ -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

View File

@ -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"));

View File

@ -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);

View File

@ -23,7 +23,7 @@
#include <dhcpsrv/subnet.h>
#include <dhcpsrv/lease.h>
#include <dhcpsrv/lease_mgr_factory.h>
#include <dhcp4/dhcp4_srv.h>
#include <dhcp4/ctrl_dhcp4_srv.h>
#include <dhcp4/parser_context.h>
#include <asiolink/io_address.h>
#include <cc/command_interpreter.h>
@ -93,7 +93,7 @@ typedef boost::shared_ptr<PktFilterTest> 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<NakedDhcpv4Srv> srv_;
/// @brief The multi-threading flag.
bool multi_threading_;

View File

@ -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

View File

@ -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

View File

@ -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();

View File

@ -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);

View File

@ -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);
}

View File

@ -10,6 +10,7 @@
#include <dhcp/option6_status_code.h>
#include <dhcp/testutils/pkt_captures.h>
#include <dhcpsrv/cfg_multi_threading.h>
#include <dhcp6/tests/dhcp6_client.h>
#include <dhcp6/tests/dhcp6_test_utils.h>
#include <dhcp6/json_config_parser.h>
#include <log/logger_support.h>
@ -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<Lease6> 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<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(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);
}

View File

@ -14,7 +14,7 @@
#include <gtest/gtest.h>
#include <asiolink/process_spawn.h>
#include <dhcp6/dhcp6_srv.h>
#include <dhcp6/ctrl_dhcp6_srv.h>
#include <dhcp6/parser_context.h>
#include <dhcp/pkt6.h>
#include <dhcp/option6_ia.h>
@ -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<NakedDhcpv6Srv> srv_;
/// @brief The multi-threading flag.
bool multi_threading_;

View File

@ -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