]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[master] Merge branch 'trac5458a'
authorMarcin Siodelski <marcin@isc.org>
Wed, 2 May 2018 12:41:40 +0000 (14:41 +0200)
committerMarcin Siodelski <marcin@isc.org>
Wed, 2 May 2018 13:14:44 +0000 (15:14 +0200)
1  2 
src/bin/dhcp6/tests/hooks_unittest.cc

index be61642d1f3fbd8eddef155e42098819668680d0,2b81a88754a86abc313fd708a914232ced33e1db..3b8d52d0dcb94224b3f2680024172a57d8229aa8
@@@ -1642,6 -1728,383 +1728,383 @@@ TEST_F(HooksDhcpv6SrvTest, subnet6Selec
      ASSERT_EQ(0, srv_->fake_sent_.size());
  }
  
 -    
+ // This test verifies that the leases6_committed hook point is not triggered
+ // for the SOLICIT.
+ TEST_F(HooksDhcpv6SrvTest, leases6CommittedSolicit) {
+     IfaceMgrTestConfig test_config(true);
+     string config = "{ \"interfaces-config\": {"
+         "  \"interfaces\": [ \"*\" ]"
+         "},"
+         "\"preferred-lifetime\": 3000,"
+         "\"rebind-timer\": 2000, "
+         "\"renew-timer\": 1000, "
+         "\"subnet6\": [ { "
+         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
+         "    \"subnet\": \"2001:db8:1::/48\", "
+         "    \"interface\": \"eth1\" "
+         " } ],"
+         "\"valid-lifetime\": 4000 }";
+     Dhcp6Client client;
+     client.setInterface("eth1");
+     ASSERT_NO_THROW(configure(config, *client.getServer()));
+     // Install leases6_committed callout
+     ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                     "leases6_committed", leases6_committed_callout));
+     ASSERT_NO_THROW(client.doSolicit());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Make sure that the callout wasn't called.
+     EXPECT_TRUE(callback_name_.empty());
+ }
+ //// Add a positive (vs this negative one) test with Solicit and rapid commit
+ //// Looks for the same with park
+ // This test verifies that the leases6_committed hook point is not triggered
+ // for the CONFIRM.
+ TEST_F(HooksDhcpv6SrvTest, leases6CommittedConfirm) {
+     IfaceMgrTestConfig test_config(true);
+     string config = "{ \"interfaces-config\": {"
+         "  \"interfaces\": [ \"*\" ]"
+         "},"
+         "\"preferred-lifetime\": 3000,"
+         "\"rebind-timer\": 2000, "
+         "\"renew-timer\": 1000, "
+         "\"subnet6\": [ { "
+         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
+         "    \"subnet\": \"2001:db8:1::/48\", "
+         "    \"interface\": \"eth1\" "
+         " } ],"
+         "\"valid-lifetime\": 4000 }";
+     Dhcp6Client client;
+     client.setInterface("eth1");
+     client.requestAddress(0xabca, IOAddress("2001:db8:1::28"));
+     ASSERT_NO_THROW(configure(config, *client.getServer()));
 -    
++
+     // Get a lease for the client.
+     ASSERT_NO_THROW(client.doSARR());
++
+     // Install leases6_committed callout
+     ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                     "leases6_committed", leases6_committed_callout));
+     ASSERT_NO_THROW(client.doConfirm());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Make sure that the callout wasn't called.
+     EXPECT_TRUE(callback_name_.empty());
+ }
+ // This test verifies that the leases6_committed hook point is not triggered
+ // for the INFREQUEST.
+ TEST_F(HooksDhcpv6SrvTest, leases6CommittedInfRequest) {
+     IfaceMgrTestConfig test_config(true);
+     string config = "{ \"interfaces-config\": {"
+         "  \"interfaces\": [ \"*\" ]"
+         "},"
+         "\"preferred-lifetime\": 3000,"
+         "\"rebind-timer\": 2000, "
+         "\"renew-timer\": 1000, "
+         "\"subnet6\": [ { "
+         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
+         "    \"subnet\": \"2001:db8:1::/48\", "
+         "    \"interface\": \"eth1\" "
+         " } ],"
+         "\"valid-lifetime\": 4000 }";
+     Dhcp6Client client;
+     client.useRelay();
+     ASSERT_NO_THROW(configure(config, *client.getServer()));
+     ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                     "leases6_committed", leases6_committed_callout));
+     ASSERT_NO_THROW(client.doInfRequest());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Make sure that the callout wasn't called.
+     EXPECT_TRUE(callback_name_.empty());
+ }
+ // This test verifies that the callout installed on the leases6_committed hook
+ // point is executed as a result of REQUEST message sent to allocate new
+ // lease or renew an existing lease.
+ TEST_F(HooksDhcpv6SrvTest, leases6CommittedRequest) {
+     IfaceMgrTestConfig test_config(true);
+     string config = "{ \"interfaces-config\": {"
+         "  \"interfaces\": [ \"*\" ]"
+         "},"
+         "\"preferred-lifetime\": 3000,"
+         "\"rebind-timer\": 2000, "
+         "\"renew-timer\": 1000, "
+         "\"subnet6\": [ { "
+         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
+         "    \"subnet\": \"2001:db8:1::/48\", "
+         "    \"interface\": \"eth1\" "
+         " } ],"
+         "\"valid-lifetime\": 4000 }";
+     Dhcp6Client client;
+     client.setInterface("eth1");
+     client.requestAddress(0xabca, IOAddress("2001:db8:1::28"));
+     ASSERT_NO_THROW(configure(config, *client.getServer()));
+     ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                     "leases6_committed", leases6_committed_callout));
+     ASSERT_NO_THROW(client.doSARR());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Check that the callback called is indeed the one we installed
+     EXPECT_EQ("leases6_committed", callback_name_);
+     // Check if all expected parameters were really received
+     vector<string> expected_argument_names;
+     expected_argument_names.push_back("query6");
+     expected_argument_names.push_back("deleted_leases6");
+     expected_argument_names.push_back("leases6");
+     sort(expected_argument_names.begin(), expected_argument_names.end());
+     EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
+     // Newly allocated lease should be returned.
+     ASSERT_TRUE(callback_new_leases6_);
+     ASSERT_EQ(1, callback_new_leases6_->size());
+     Lease6Ptr lease = callback_new_leases6_->at(0);
+     ASSERT_TRUE(lease);
+     EXPECT_EQ("2001:db8:1::28", lease->addr_.toText());
+     // Deleted lease must not be present, because it is a new allocation.
+     ASSERT_TRUE(callback_deleted_leases6_);
+     EXPECT_TRUE(callback_deleted_leases6_->empty());
+     // Pkt passed to a callout must be configured to copy retrieved options.
+     EXPECT_TRUE(callback_qry_options_copy_);
+     resetCalloutBuffers();
+     // Request the lease and make sure that the callout has been executed.
+     ASSERT_NO_THROW(client.doRequest());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Check that the callback called is indeed the one we installed
+     EXPECT_EQ("leases6_committed", callback_name_);
+     // Requested lease should be returned.
+     ASSERT_TRUE(callback_new_leases6_);
+     ASSERT_EQ(1, callback_new_leases6_->size());
+     lease = callback_new_leases6_->at(0);
+     ASSERT_TRUE(lease);
+     EXPECT_EQ("2001:db8:1::28", lease->addr_.toText());
+     // Deleted lease must not be present, because it is a new allocation.
+     ASSERT_TRUE(callback_deleted_leases6_);
+     EXPECT_TRUE(callback_deleted_leases6_->empty());
+     // Pkt passed to a callout must be configured to copy retrieved options.
+     EXPECT_TRUE(callback_qry_options_copy_);
+     resetCalloutBuffers();
+     // Let's try to request again but force the client to request a different
+     // address with a different IAID.
+     client.requestAddress(0x2233, IOAddress("2001:db8:1::29"));
+     ASSERT_NO_THROW(client.doRequest());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Check that the callback called is indeed the one we installed
+     EXPECT_EQ("leases6_committed", callback_name_);
+     // New lease should be returned.
+     ASSERT_TRUE(callback_new_leases6_);
+     ASSERT_EQ(2, callback_new_leases6_->size());
+     lease = callback_new_leases6_->at(1);
+     ASSERT_TRUE(lease);
+     EXPECT_EQ("2001:db8:1::29", lease->addr_.toText());
+     // The old lease is kept.
+     ASSERT_TRUE(callback_deleted_leases6_);
+     ASSERT_TRUE(callback_deleted_leases6_->empty());
+     // Pkt passed to a callout must be configured to copy retrieved options.
+     EXPECT_TRUE(callback_qry_options_copy_);
+     resetCalloutBuffers();
+     // The requested address is just a hint.
+     client.requestAddress(0x5577, IOAddress("4000::2"));
+     ASSERT_NO_THROW(client.doRequest());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Check that the callback called is indeed the one we installed
+     EXPECT_EQ("leases6_committed", callback_name_);
+     ASSERT_TRUE(callback_new_leases6_);
+     EXPECT_EQ(3, callback_new_leases6_->size());
+     lease = callback_new_leases6_->at(2);
+     ASSERT_TRUE(lease);
+     EXPECT_EQ("2001:db8:1::", lease->addr_.toText());
+     ASSERT_TRUE(callback_deleted_leases6_);
+     EXPECT_TRUE(callback_deleted_leases6_->empty());
+     // Pkt passed to a callout must be configured to copy retrieved options.
+     EXPECT_TRUE(callback_qry_options_copy_);
+     resetCalloutBuffers();
+     // Request a prefix: this should lead to an error as no prefix pool
+     // is configured.
+     client.requestPrefix(0x1122, 64, IOAddress("2001:db8:1000::"));
+     ASSERT_NO_THROW(client.doRequest());
+     // Make sure that we received a response
+     ASSERT_TRUE(client.getContext().response_);
+     // Check the error.
+     EXPECT_EQ(STATUS_NoPrefixAvail, client.getStatusCode(0x1122));
+     // Check that the callback called is indeed the one we installed
+     EXPECT_EQ("leases6_committed", callback_name_);
+     ASSERT_TRUE(callback_new_leases6_);
+     EXPECT_EQ(3, callback_new_leases6_->size());
+     ASSERT_TRUE(callback_deleted_leases6_);
+     EXPECT_TRUE(callback_deleted_leases6_->empty());
+ }
+ //// same with prefix
+ // This test verifies that it is possible to park a packet as a result of
+ // the leases6_committed callouts.
+ TEST_F(HooksDhcpv6SrvTest, leases6CommittedParkRequests) {
+     IfaceMgrTestConfig test_config(true);
+     string config = "{ \"interfaces-config\": {"
+         "  \"interfaces\": [ \"*\" ]"
+         "},"
+         "\"preferred-lifetime\": 3000,"
+         "\"rebind-timer\": 2000, "
+         "\"renew-timer\": 1000, "
+         "\"subnet6\": [ { "
+         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
+         "    \"subnet\": \"2001:db8:1::/48\", "
+         "    \"interface\": \"eth1\" "
+         " } ],"
+         "\"valid-lifetime\": 4000 }";
+     // Create first client and perform SARR.
+     Dhcp6Client client1;
+     client1.setInterface("eth1");
+     client1.requestAddress(0xabca, IOAddress("2001:db8:1::28"));
+     ASSERT_NO_THROW(configure(config, *client1.getServer()));
+     // This callout uses provided IO service object to post a function
+     // that unparks the packet. The packet is parked and can be unparked
+     // by simply calling IOService::poll.
+     ASSERT_NO_THROW(HooksManager::preCalloutsLibraryHandle().registerCallout(
+                     "leases6_committed", leases6_committed_park_callout));
+     ASSERT_NO_THROW(client1.doSARR());
+     // We should be offered an address but the REPLY should not arrive
+     // at this point, because the packet is parked.
+     ASSERT_FALSE(client1.getContext().response_);
+     // Check that the callback called is indeed the one we installed
+     EXPECT_EQ("leases6_committed", callback_name_);
+     // Check if all expected parameters were really received
+     vector<string> expected_argument_names;
+     expected_argument_names.push_back("query6");
+     expected_argument_names.push_back("deleted_leases6");
+     expected_argument_names.push_back("leases6");
+     sort(expected_argument_names.begin(), expected_argument_names.end());
+     EXPECT_TRUE(callback_argument_names_ == expected_argument_names);
+     // Newly allocated lease should be passed to the callout.
+     ASSERT_TRUE(callback_new_leases6_);
+     ASSERT_EQ(1, callback_new_leases6_->size());
+     Lease6Ptr lease = callback_new_leases6_->at(0);
+     ASSERT_TRUE(lease);
+     EXPECT_EQ("2001:db8:1::28", lease->addr_.toText());
+     // Deleted lease must not be present, because it is a new allocation.
+     ASSERT_TRUE(callback_deleted_leases6_);
+     EXPECT_TRUE(callback_deleted_leases6_->empty());
+     // Pkt passed to a callout must be configured to copy retrieved options.
+     EXPECT_TRUE(callback_qry_options_copy_);
+     // Reset all indicators because we'll be now creating a second client.
+     resetCalloutBuffers();
+     // Create the second client to test that it may communicate with the
+     // server while the previous packet is parked.
+     Dhcp6Client client2;
+     client2.setInterface("eth1");
+     client2.requestAddress(0xabca, IOAddress("2001:db8:1::29"));
+     ASSERT_NO_THROW(client2.doSARR());
+     // The ADVERTISE should have been returned but not REPLAY, as this
+     // packet got parked too.
+     ASSERT_FALSE(client2.getContext().response_);
+     // Check that the callback called is indeed the one we installed.
+     EXPECT_EQ("leases6_committed", callback_name_);
+     // There should be now two actions scheduled on our IO service
+     // by the invoked callouts. They unpark both REPLY messages.
+     ASSERT_NO_THROW(io_service_->poll());
+     // Receive and check the first response.
+     ASSERT_NO_THROW(client1.receiveResponse());
+     ASSERT_TRUE(client1.getContext().response_);
+     Pkt6Ptr rsp = client1.getContext().response_;
+     EXPECT_EQ(DHCPV6_REPLY, rsp->getType());
+     EXPECT_TRUE(client1.hasLeaseForAddress(IOAddress("2001:db8:1::28")));
+     // Receive and check the second response.
+     ASSERT_NO_THROW(client2.receiveResponse());
+     ASSERT_TRUE(client2.getContext().response_);
+     rsp = client2.getContext().response_;
+     EXPECT_EQ(DHCPV6_REPLY, rsp->getType());
+     EXPECT_TRUE(client2.hasLeaseForAddress(IOAddress("2001:db8:1::29")));
+ }
+ //// same with prefix
  // This test verifies that incoming (positive) RENEW can be handled properly,
  // and the lease6_renew callouts are triggered.
  TEST_F(HooksDhcpv6SrvTest, basicLease6Renew) {