From: Marcin Siodelski Date: Fri, 17 Jun 2016 16:17:02 +0000 (+0200) Subject: [4321] Implemented unit test for conflict resolution with reservations. X-Git-Tag: trac4551_base~29^2~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5c3023baababf00b97a41dd27fdf7734e51d595f;p=thirdparty%2Fkea.git [4321] Implemented unit test for conflict resolution with reservations. --- diff --git a/src/bin/dhcp6/tests/host_unittest.cc b/src/bin/dhcp6/tests/host_unittest.cc index e406b971d3..563b1baf30 100644 --- a/src/bin/dhcp6/tests/host_unittest.cc +++ b/src/bin/dhcp6/tests/host_unittest.cc @@ -1259,5 +1259,117 @@ TEST_F(HostTest, insertReservationDuringRenew) { EXPECT_TRUE(client_.hasLeaseWithZeroLifetimeForPrefix(dynamic_prefix_lease, 64)); } +// In this test there are two clients. One client obtains two leases: one +// for a prefix, another one for an address. The server is reconfigured +// to make 4 reservations to a different client. Two of those reservations +// are for the prefix and the address assigned to the first client. The +// second client performs 4-way exchange and the server detects that two +// reserved leases are not available because they are in use by another +// client. The server assigns available address and prefix and an address +// and prefix from dynamic pool. The first client renews and the server +// detects that the renewed leases are reserved for another client. As +// a result, the client obtains an address and prefix from the dynamic +// pools. The second client renews and it obtains all reserved +// addresses and prefixes. +TEST_F(HostTest, multipleIAsConflict) { + Dhcp6Client client; + client.setDUID("01:02:03:05"); + + // Create configuration without any reservations. + std::string c = configString(*client_.getDuid()); + + ASSERT_NO_THROW(configure(c, *client_.getServer())); + + // First client performs 4-way exchange and obtains an address and + // prefix indicated in hints. + requestIA(client, Hint(IAID(1), "2001:db8:1::1")); + requestIA(client, Hint(IAID(2), "3001:0:0:10::/64")); + + ASSERT_NO_THROW(client.doSARR()); + + // Make sure the client has obtained requested leases. + ASSERT_TRUE(client.hasLeaseForAddress(IOAddress("2001:db8:1::1"), IAID(1))); + ASSERT_TRUE(client.hasLeaseForPrefix(IOAddress("3001:0:0:10::"), 64, + IAID(2))); + + // Reconfigure the server to make reservations for the second client. + // The reservations include a prefix and address acquired by the + // first client in the previous transaction. + c = configString(*client_.getDuid(), + Reservation("2001:db8:1::1"), + Reservation("2001:db8:1::2"), + Reservation("3001:0:0:9::/64"), + Reservation("3001:0:0:10::/64")); + + ASSERT_NO_THROW(configure(c, *client_.getServer())); + + // Configure the second client to send two IA_NAs and two IA_PDs with + // IAIDs from 1 to 4. + client_.requestAddress(1); + client_.requestAddress(2); + client_.requestPrefix(3); + client_.requestPrefix(4); + + // Perform 4-way exchange. + ASSERT_NO_THROW(do_solicit_request_()); + + // The client should have obtained 4 leases: two prefixes and two addresses. + ASSERT_EQ(4, client_.getLeaseNum()); + + // The address "2001:db8:1::2" is reserved and available so the + // server should have assigned it. + ASSERT_TRUE(client_.hasLeaseForAddress(IOAddress("2001:db8:1::2"), + IAID(1))); + // The address "2001:db8:1::1" was hijacked by another client so it + // must not be assigned to thsi client. + ASSERT_FALSE(client_.hasLeaseForAddress(IOAddress("2001:db8:1::1"))); + // This client should have got an address from the dynamic pool excluding + // two addresses already assigned, i.e. excluding "2001:db8:1::1" and + // "2001:db8:1::2". + ASSERT_TRUE(client_.hasLeaseForAddressRange(IOAddress("2001:db8:1::3"), + IOAddress("2001:db8:1::10"))); + + // Same story with prefixes. + ASSERT_TRUE(client_.hasLeaseForPrefix(IOAddress("3001:0:0:9::"), 64, + IAID(3))); + ASSERT_FALSE(client_.hasLeaseForPrefix(IOAddress("3001:0:0:10::"), 64)); + + + // Now that the reservations have been made, the first client should get + // non-reserved leases upon renewal. The server detects that the leases + // are reserved for someone else. + ASSERT_NO_THROW(client.doRenew()); + + // For those leases, the first client should get 0 lifetimes. + ASSERT_TRUE(client.hasLeaseWithZeroLifetimeForAddress(IOAddress("2001:db8:1::1"))); + ASSERT_TRUE(client.hasLeaseWithZeroLifetimeForPrefix(IOAddress("3001:0:0:10::"), 64)); + + // The total number of leases should be 4 - two leases with zero lifetimes + // and two leases with address and prefix from the dynamic pools, which + // replace previously assigned leases. We don't care too much what those + // leases are, though. + EXPECT_EQ(4, client.getLeaseNum()); + + // The second client renews and the server should be now able to assign + // all reserved leases to this client. + ASSERT_NO_THROW(client_.doRenew()); + + // Client requests 4 leases, but there are additional two with zero + // lifetimes to indicate that the client should not use the address + // and prefix from the dynamic pools anymore. + ASSERT_EQ(6, client_.getLeaseNum()); + + // Check that the client has all reserved leases. + EXPECT_TRUE(client_.hasLeaseForAddress(IOAddress("2001:db8:1::2"), + IAID(1))); + EXPECT_TRUE(client_.hasLeaseForAddress(IOAddress("2001:db8:1::1"), + IAID(2))); + + EXPECT_TRUE(client_.hasLeaseForPrefix(IOAddress("3001:0:0:9::"), 64, + IAID(3))); + EXPECT_TRUE(client_.hasLeaseForPrefix(IOAddress("3001:0:0:10::"), 64, + IAID(4))); +} + } // end of anonymous namespace