diff options
author | Marcin Siodelski <marcin@isc.org> | 2015-07-30 14:49:21 +0200 |
---|---|---|
committer | Marcin Siodelski <marcin@isc.org> | 2015-07-30 14:49:21 +0200 |
commit | ddb442f78b4363db266b1cb4c8ce31ca0657eef9 (patch) | |
tree | 73ce45b7d6536523e4a0499b4ea96b8cf39cff29 | |
parent | [3947] Added missing unit tests for the NoBinding cases in Renew/Rebind. (diff) | |
download | kea-ddb442f78b4363db266b1cb4c8ce31ca0657eef9.tar.xz kea-ddb442f78b4363db266b1cb4c8ce31ca0657eef9.zip |
[3947] Removed the new-leases-on-renew config parameter.
This change removes ability to disable allocation new leases new
Renew/Rebind, specified in RFC7550. The behavior specified in this
RFC is the only supported behavior.
-rw-r--r-- | src/bin/dhcp6/dhcp6.spec | 6 | ||||
-rw-r--r-- | src/bin/dhcp6/dhcp6_messages.mes | 18 | ||||
-rw-r--r-- | src/bin/dhcp6/dhcp6_srv.cc | 83 | ||||
-rw-r--r-- | src/bin/dhcp6/json_config_parser.cc | 9 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/config_parser_unittest.cc | 80 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_client.cc | 16 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_client.h | 13 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_srv_unittest.cc | 17 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_test_utils.cc | 143 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/dhcp6_test_utils.h | 13 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/rebind_unittest.cc | 392 | ||||
-rw-r--r-- | src/bin/dhcp6/tests/renew_unittest.cc | 189 | ||||
-rw-r--r-- | src/lib/dhcpsrv/alloc_engine.cc | 19 | ||||
-rw-r--r-- | src/lib/dhcpsrv/alloc_engine.h | 12 | ||||
-rw-r--r-- | src/lib/dhcpsrv/alloc_engine_messages.mes | 9 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/alloc_engine_utils.cc | 2 | ||||
-rw-r--r-- | src/lib/dhcpsrv/tests/alloc_engine_utils.h | 3 |
17 files changed, 156 insertions, 868 deletions
diff --git a/src/bin/dhcp6/dhcp6.spec b/src/bin/dhcp6/dhcp6.spec index e577e889f3..e0fa45be45 100644 --- a/src/bin/dhcp6/dhcp6.spec +++ b/src/bin/dhcp6/dhcp6.spec @@ -62,12 +62,6 @@ "item_default": 4000 }, - { "item_name": "new-leases-on-renew", - "item_type": "boolean", - "item_optional": true, - "item_default": true - }, - { "item_name": "option-def", "item_type": "list", "item_optional": false, diff --git a/src/bin/dhcp6/dhcp6_messages.mes b/src/bin/dhcp6/dhcp6_messages.mes index d0d7aa15ec..acdc88884f 100644 --- a/src/bin/dhcp6/dhcp6_messages.mes +++ b/src/bin/dhcp6/dhcp6_messages.mes @@ -224,24 +224,6 @@ as a result of receiving SIGHUP signal. This is an error message logged when the dynamic reconfiguration of the DHCP server failed. -% DHCP6_EXTEND_NA_UNKNOWN %1: received unknown IA_NA with iaid=%2 in subnet %3 -This warning message is printed when client attempts to extend the lease -for the address (in the IA_NA option) but no such lease is known by the server. -It typically means that client has attempted to use its lease past its -lifetime: causes of this include a adjustment of the client's date/time -setting or poor support on the client for sleep/recovery. A properly -implemented client will recover from such a situation by restarting the -lease allocation process after receiving a negative reply from the server. -The first argument includes the client and the transaction identification -information. The second argument holds IAID. The third argument holds the -subnet information. - -An alternative cause could be that the server has lost its database -recently and does not recognize its well-behaving clients. This is more -probable if you see many such messages. Clients will recover from this, -but they will most likely get a different IP addresses and experience -a brief service interruption. - % DHCP6_HOOKS_LIBS_RELOAD_FAIL reload of hooks libraries failed A "libreload" command was issued to reload the hooks libraries but for some reason the reload failed. Other error messages issued from the diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 2f214ee09a..82cb272ebb 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -1721,7 +1721,6 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer, ctx.ia_rsp_ = ia_rsp; ctx.hwaddr_ = orig_ctx.hwaddr_; ctx.host_ = orig_ctx.host_; - ctx.allow_new_leases_in_renewals_ = subnet->getAllocLeasesOnRenew(); // Extract the addresses that the client is trying to obtain. OptionCollection addrs = ia->getOptions(); @@ -1802,34 +1801,12 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer, // All is left is to insert the status code. if (leases.empty()) { - // We did not assign any address to the client. Depending on whether the - // server is configured to allocate new leases during the Renew or - // Rebind we will have to send a different status code. If the server - // is configured to allocate new leases for the Renew and Rebind, the - // status code will be NoAddressAvail. If the server is not configured - // to allocate prefixes for the renewing client, the status code will - // be NoBinding, or perhaps the message will be dropped if this is the - // Rebind case. - if (!subnet->getAllocLeasesOnRenew()) { - ia_rsp->addOption(createStatusCode(*query, *ia_rsp, - STATUS_NoBinding, - "Sorry, no known NA leases for" - " this duid/iaid/subnet.")); - LOG_DEBUG(lease_logger, DBG_DHCP6_DETAIL, DHCP6_EXTEND_NA_UNKNOWN) - .arg(query->getLabel()) - .arg(ia->getIAID()) - .arg(subnet->toText()); - - - } else { - // The server is configured to allocate new leases for the - // renewing client, but it could not allocate anything at this - // time. The status code should be NoAddrsAvail, per RFC7550. - ia_rsp->addOption(createStatusCode(*query, *ia_rsp, - STATUS_NoAddrsAvail, - "Sorry, no addresses could be" - " assigned at this time.")); - } + // The server wasn't able allocate new lease and renew an exising + // lease. In that case, the server sends NoAddrsAvail per RFC7550. + ia_rsp->addOption(createStatusCode(*query, *ia_rsp, + STATUS_NoAddrsAvail, + "Sorry, no addresses could be" + " assigned at this time.")); } return (ia_rsp); @@ -1894,7 +1871,6 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query, ctx.ia_rsp_ = ia_rsp; ctx.hwaddr_ = orig_ctx.hwaddr_; ctx.host_ = orig_ctx.host_; - ctx.allow_new_leases_in_renewals_ = subnet->getAllocLeasesOnRenew(); // Extract prefixes that the client is trying to renew. OptionCollection addrs = ia->getOptions(); @@ -1963,47 +1939,12 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query, // All is left is to insert the status code. if (leases.empty()) { - // We did not assign any prefix to the client. Depending on whether the - // server is configured to allocate new leases during the Renew or - // Rebind we will have to send a different status code. If the server - // is configured to allocate new leases for the Renew and Rebind, the - // status code will be NoPrefixAvail. If the server is not configured - // to allocate prefixes for the renewing client, the status code will - // be NoBinding, or perhaps the message will be dropped if this is the - // Rebind case. - if (!subnet->getAllocLeasesOnRenew()) { - // The server is not configured to allocate new leases, so return - // the NoBinding for the Renew, and drop the message for the - // Rebind. There is also a detailed comment for the Rebind case - // further on. - if (query->getType() == DHCPV6_RENEW) { - ia_rsp->addOption(createStatusCode(*query, *ia_rsp, - STATUS_NoBinding, - "Sorry, no known PD leases for" - " this duid/iaid/subnet.")); - } else { - // Per RFC3633, section 12.2, if there is no binding and we are - // processing Rebind, the message has to be discarded (assuming that - // the server doesn't know if the prefix in the IA_PD option is - // appropriate for the client's link). The exception being thrown - // here should propagate to the main loop and cause the message to - // be discarded. - isc_throw(DHCPv6DiscardMessageError, "no binding found for the" - " DUID=" << duid->toText() << ", IAID=" - << ia->getIAID() << ", subnet=" - << subnet->toText() << " when processing a Rebind" - " message with IA_PD option"); - } - - } else { - // The server is configured to allocate new leases for the - // renewing client, but it could not allocate anything at this - // time. The status code should be NoPrefixAvail, per RFC7550. - ia_rsp->addOption(createStatusCode(*query, *ia_rsp, - STATUS_NoPrefixAvail, - "Sorry, no prefixes could be" - " assigned at this time.")); - } + // The server wasn't able allocate new lease and renew an exising + // lease. In that case, the server sends NoPrefixAvail per RFC7550. + ia_rsp->addOption(createStatusCode(*query, *ia_rsp, + STATUS_NoPrefixAvail, + "Sorry, no prefixes could be" + " assigned at this time.")); } return (ia_rsp); diff --git a/src/bin/dhcp6/json_config_parser.cc b/src/bin/dhcp6/json_config_parser.cc index f7c4efdc60..29f64f19de 100644 --- a/src/bin/dhcp6/json_config_parser.cc +++ b/src/bin/dhcp6/json_config_parser.cc @@ -475,16 +475,13 @@ protected: // Gather boolean parameters values. bool rapid_commit = boolean_values_->getOptionalParam("rapid-commit", false); - bool alloc_leases_on_renew = globalContext()-> - boolean_values_->getOptionalParam("new-leases-on-renew", true); std::ostringstream output; output << addr << "/" << static_cast<int>(len) << " with params t1=" << t1 << ", t2=" << t2 << ", preferred-lifetime=" << pref << ", valid-lifetime=" << valid - << ", rapid-commit is " << (rapid_commit ? "enabled" : "disabled") - << ", new-leases-on-renew is " << (alloc_leases_on_renew ? "enabled" : "disabled"); + << ", rapid-commit is " << (rapid_commit ? "enabled" : "disabled"); LOG_INFO(dhcp6_logger, DHCP6_CONFIG_NEW_SUBNET).arg(output.str()); @@ -502,8 +499,6 @@ protected: // Enable or disable Rapid Commit option support for the subnet. subnet6->setRapidCommit(rapid_commit); - // Enable or disable allocation of the new leases for the Renew or/and Rebind message. - subnet6->setAllocLeasesOnRenew(alloc_leases_on_renew); // Try setting up client class (if specified) try { @@ -700,8 +695,6 @@ namespace dhcp { parser = new RSOOListConfigParser(config_id); } else if (config_id.compare("control-socket") == 0) { parser = new ControlSocketParser(config_id); - } else if (config_id.compare("new-leases-on-renew") == 0) { - parser = new BooleanParser(config_id, globalContext()->boolean_values_); } else { isc_throw(DhcpConfigError, "unsupported global configuration parameter: " diff --git a/src/bin/dhcp6/tests/config_parser_unittest.cc b/src/bin/dhcp6/tests/config_parser_unittest.cc index 5b905c2d10..46f6d91601 100644 --- a/src/bin/dhcp6/tests/config_parser_unittest.cc +++ b/src/bin/dhcp6/tests/config_parser_unittest.cc @@ -531,37 +531,6 @@ public: CfgMgr::instance().clear(); } - /// @brief Test the 'new-leases-on-renew' configuration flag. - /// - /// @param config Server configuration, possibly including the - /// 'new-leases-on-renew' parameter. - /// @param exp_alloc_leases_on_renew Expected value of the flag - void testAllocLeasesOnRenew(const std::string& config, - const bool exp_alloc_leases_on_renew) { - // Clear any existing configuration. - CfgMgr::instance().clear(); - - // Configure the server. - ElementPtr json = Element::fromJSON(config); - - // Make sure that the configuration was successful. - ConstElementPtr status; - EXPECT_NO_THROW(status = configureDhcp6Server(srv_, json)); - checkResult(status, 0); - - // Get the subnet. - Subnet6Ptr subnet = CfgMgr::instance().getStagingCfg()->getCfgSubnets6()-> - selectSubnet(IOAddress("2001:db8:1::5"), classify_); - ASSERT_TRUE(subnet); - - // Check the flag against the expected value. - EXPECT_EQ(exp_alloc_leases_on_renew, subnet->getAllocLeasesOnRenew()); - - // Clear any existing configuration. - CfgMgr::instance().clear(); - } - - int rcode_; ///< Return code (see @ref isc::config::parseAnswer) Dhcpv6Srv srv_; ///< Instance of the Dhcp6Srv used during tests ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer) @@ -1203,55 +1172,6 @@ TEST_F(Dhcp6ParserTest, subnetRapidCommit) { } } -// This test checks the configuration of the Rapid Commit option -// support for the subnet. -TEST_F(Dhcp6ParserTest, subnetAllocLeasesOnRenew) { - { - // new-leases-on-renew implicitly set to false. - SCOPED_TRACE("Default setting for new-leases-on-renew"); - testAllocLeasesOnRenew("{ \"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::1 - " - "2001:db8:1::ffff\" } ]," - " \"subnet\": \"2001:db8:1::/64\" } ]," - "\"valid-lifetime\": 4000 }", - true); - } - - { - // new-leases-on-renew explicitly set to true. - SCOPED_TRACE("Enable new-leases-on-renew"); - testAllocLeasesOnRenew("{ \"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": True," - - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::1 - " - "2001:db8:1::ffff\" } ]," - " \"subnet\": \"2001:db8:1::/64\" } ]," - "\"valid-lifetime\": 4000 }", - true); - } - - { - // new-leases-on-renew explicitly set to false. - SCOPED_TRACE("Disable new-leases-on-renew"); - testAllocLeasesOnRenew("{ \"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::1 - " - "2001:db8:1::ffff\" } ]," - " \"subnet\": \"2001:db8:1::/64\" } ]," - "\"valid-lifetime\": 4000 }", - false); - } -} - // This test checks that multiple pools can be defined and handled properly. // The test defines 2 subnets, each with 2 pools. TEST_F(Dhcp6ParserTest, multiplePools) { diff --git a/src/bin/dhcp6/tests/dhcp6_client.cc b/src/bin/dhcp6/tests/dhcp6_client.cc index 442689ded6..503f973b3d 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.cc +++ b/src/bin/dhcp6/tests/dhcp6_client.cc @@ -94,7 +94,9 @@ Dhcp6Client::Dhcp6Client() : use_rapid_commit_(false), address_hint_(), prefix_hint_(), - fqdn_() { + fqdn_(), + na_iaid_(1234), + pd_iaid_(5678) { } Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) : @@ -113,7 +115,9 @@ Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) : use_rapid_commit_(false), address_hint_(), prefix_hint_(), - fqdn_() { + fqdn_(), + na_iaid_(1234), + pd_iaid_(5678) { } void @@ -243,11 +247,11 @@ Dhcp6Client::appendFQDN() { void Dhcp6Client::appendRequestedIAs(const Pkt6Ptr& query) const { if (use_na_) { - conditionallyAppendRequestedIA(query, D6O_IA_NA, 1234); + conditionallyAppendRequestedIA(query, D6O_IA_NA, na_iaid_); } if (use_pd_) { - conditionallyAppendRequestedIA(query, D6O_IA_PD, 5678); + conditionallyAppendRequestedIA(query, D6O_IA_PD, pd_iaid_); } } @@ -445,9 +449,9 @@ Dhcp6Client::doInfRequest() { // IA_NA, IA_TA and IA_PD options are not allowed in INF-REQUEST, // but hey! Let's test it. if (use_na_) { - // Insert IA_NA option with iaid=1234. + // Insert IA_NA option. context_.query_->addOption(Option6IAPtr(new Option6IA(D6O_IA_NA, - 1234))); + na_iaid_))); } // IA-PD is also not allowed. So it may be useful in testing, too. diff --git a/src/bin/dhcp6/tests/dhcp6_client.h b/src/bin/dhcp6/tests/dhcp6_client.h index 68dffe0dec..ffcee8b673 100644 --- a/src/bin/dhcp6/tests/dhcp6_client.h +++ b/src/bin/dhcp6/tests/dhcp6_client.h @@ -439,8 +439,10 @@ public: /// /// @param use Parameter which 'true' value indicates that client should /// request address assignment. - void useNA(const bool use = true) { + /// @param iaid IAID to be used in the IA_NA. + void useNA(const bool use = true, const uint32_t iaid = 1234) { use_na_ = use; + na_iaid_ = iaid; } /// @brief Place IA_PD options to request prefix assignment. @@ -450,8 +452,10 @@ public: /// /// @param use Parameter which 'true' value indicates that client should /// request prefix assignment. - void usePD(const bool use = true) { + /// @param iaid IAID to be used in the IA_NA. + void usePD(const bool use = true, const uint32_t iaid = 5678) { use_pd_ = use; + pd_iaid_ = iaid; } /// @brief Simulate sending messages through a relay. @@ -706,6 +710,11 @@ private: /// @brief FQDN requested by the client. Option6ClientFqdnPtr fqdn_; + + /// @bref IAID used by the client when requesting address assignment. + uint32_t na_iaid_; + /// @brief IAID used by the client when requesting prefix delegation. + uint32_t pd_iaid_; }; } // end of namespace isc::dhcp::test diff --git a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc index 2013b28918..4fa269b0bc 100644 --- a/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc +++ b/src/bin/dhcp6/tests/dhcp6_srv_unittest.cc @@ -939,23 +939,6 @@ TEST_F(Dhcpv6SrvTest, RenewSomeoneElesesLease) { testRenewSomeoneElsesLease(Lease::TYPE_NA, IOAddress("2001:db8::1")); } -// This test verifies that incoming (invalid) RENEW with a prefix -// can be handled properly. -// -// This test checks 3 scenarios: -// 1. there is no such lease at all -// 2. there is such a lease, but it is assigned to a different IAID -// 3. there is such a lease, but it belongs to a different client -// -// expected: -// - returned REPLY message has copy of client-id -// - returned REPLY message has server-id -// - returned REPLY message has IA_PD that includes STATUS-CODE -// - No lease in LeaseMgr -TEST_F(Dhcpv6SrvTest, pdRenewReject) { - testRenewReject(Lease::TYPE_PD, IOAddress("2001:db8:1:2::")); -} - // 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 indeed removed from the database. diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.cc b/src/bin/dhcp6/tests/dhcp6_test_utils.cc index 138144a560..7f716e5977 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.cc +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.cc @@ -421,149 +421,6 @@ Dhcpv6SrvTest::testRenewSomeoneElsesLease(Lease::Type type, const IOAddress& add } void -Dhcpv6SrvTest::testRenewReject(Lease::Type type, const IOAddress& addr) { - - NakedDhcpv6Srv srv(0); - - const uint32_t transid = 1234; - const uint32_t valid_iaid = 234; - const uint32_t bogus_iaid = 456; - - uint32_t code; - uint8_t prefix_len; - if (type == Lease::TYPE_NA) { - code = D6O_IA_NA; - prefix_len = 128; - } else if (type == Lease::TYPE_PD) { - code = D6O_IA_PD; - prefix_len = pd_pool_->getLength(); - } else { - isc_throw(BadValue, "Invalid lease type"); - } - - // Quick sanity check that the address we're about to use is ok - ASSERT_TRUE(subnet_->inPool(type, addr)); - - // Do not allocate leases as a result of Renew/Rebind. - subnet_->setAllocLeasesOnRenew(false); - - // GenerateClientId() also sets duid_ - OptionPtr clientid = generateClientId(); - - // Check that the lease is NOT in the database - Lease6Ptr l = LeaseMgrFactory::instance().getLease6(type, addr); - ASSERT_FALSE(l); - - // Let's create a RENEW - Pkt6Ptr req = createMessage(DHCPV6_RENEW, type, IOAddress(addr), prefix_len, - bogus_iaid); - req->addOption(clientid); - req->addOption(srv.getServerID()); - - // Case 1: No lease known to server - - // Pass it to the server and hope for a REPLY - Pkt6Ptr reply = srv.processRenew(req); - - // Check if we get response at all - checkResponse(reply, DHCPV6_REPLY, transid); - OptionPtr tmp = reply->getOption(code); - ASSERT_TRUE(tmp); - - // Check that IA_?? was returned and that there's proper status code - boost::shared_ptr<Option6IA> ia = boost::dynamic_pointer_cast<Option6IA>(tmp); - ASSERT_TRUE(ia); - - if (type == Lease::TYPE_PD) { - // For PD, the check is easy. NoBinding and no prefixes - checkIA_NAStatusCode(ia, STATUS_NoBinding, subnet_->getT1(), subnet_->getT2()); - } else { - // For IA, it's more involved, as the server will reject the address - // (and send it with 0 lifetimes), but will also assign a new address. - - // First, check that the requested address is rejected. - bool found = false; - - dhcp::OptionCollection options = ia->getOptions(); - for (isc::dhcp::OptionCollection::iterator opt = options.begin(); - opt != options.end(); ++opt) { - if (opt->second->getType() != D6O_IAADDR) { - continue; - } - - dhcp::Option6IAAddrPtr opt_addr = - boost::dynamic_pointer_cast<isc::dhcp::Option6IAAddr>(opt->second); - ASSERT_TRUE(opt_addr); - - if (opt_addr->getAddress() != addr) { - // There may be other addresses, e.g. the newly assigned one - continue; - } - - found = true; - EXPECT_NE(0, opt_addr->getPreferred()); - EXPECT_NE(0, opt_addr->getValid()); - } - - EXPECT_TRUE(found) << "Expected address " << addr.toText() - << " with zero lifetimes not found."; - } - - // Check that there is no lease added - l = LeaseMgrFactory::instance().getLease6(type, addr); - ASSERT_FALSE(l); - - // CASE 2: Lease is known and belongs to this client, but to a different IAID - - // Note that preferred, valid, T1 and T2 timers and CLTT are set to invalid - // value on purpose. They should be updated during RENEW. - Lease6Ptr lease(new Lease6(type, addr, duid_, valid_iaid, - 501, 502, 503, 504, subnet_->getID(), - HWAddrPtr(), prefix_len)); - lease->cltt_ = 123; // Let's use it as an indicator that the lease - // was NOT updated. - ASSERT_TRUE(LeaseMgrFactory::instance().addLease(lease)); - - // Pass it to the server and hope for a REPLY - reply = srv.processRenew(req); - checkResponse(reply, DHCPV6_REPLY, transid); - tmp = reply->getOption(code); - ASSERT_TRUE(tmp); - - // Check that IA_?? was returned and that there's proper status code - ia = boost::dynamic_pointer_cast<Option6IA>(tmp); - ASSERT_TRUE(ia); - checkIA_NAStatusCode(ia, STATUS_NoBinding, subnet_->getT1(), subnet_->getT2()); - - // There is a iaid mis-match, so server should respond that there is - // no such address to renew. - - // CASE 3: Lease belongs to a client with different client-id - req->delOption(D6O_CLIENTID); - ia = boost::dynamic_pointer_cast<Option6IA>(req->getOption(code)); - ia->setIAID(valid_iaid); // Now iaid in renew matches that in leasemgr - req->addOption(generateClientId(13)); // generate different DUID - // (with length 13) - - reply = srv.processRenew(req); - checkResponse(reply, DHCPV6_REPLY, transid); - tmp = reply->getOption(code); - ASSERT_TRUE(tmp); - - // Check that IA_?? was returned and that there's proper status code - ia = boost::dynamic_pointer_cast<Option6IA>(tmp); - ASSERT_TRUE(ia); - checkIA_NAStatusCode(ia, STATUS_NoBinding, subnet_->getT1(), subnet_->getT2()); - - lease = LeaseMgrFactory::instance().getLease6(type, addr); - ASSERT_TRUE(lease); - // Verify that the lease was not updated. - EXPECT_EQ(123, lease->cltt_); - - EXPECT_TRUE(LeaseMgrFactory::instance().deleteLease(addr)); -} - -void Dhcpv6SrvTest::testReleaseBasic(Lease::Type type, const IOAddress& existing, const IOAddress& release_addr) { NakedDhcpv6Srv srv(0); diff --git a/src/bin/dhcp6/tests/dhcp6_test_utils.h b/src/bin/dhcp6/tests/dhcp6_test_utils.h index d4e48319c6..6bc1334fcf 100644 --- a/src/bin/dhcp6/tests/dhcp6_test_utils.h +++ b/src/bin/dhcp6/tests/dhcp6_test_utils.h @@ -468,19 +468,6 @@ public: testRenewSomeoneElsesLease(isc::dhcp::Lease::Type type, const asiolink::IOAddress& addr); - /// @brief Performs negative RENEW test - /// - /// See renewReject and pdRenewReject tests for detailed explanation. - /// In essence the test attempts to perform couple failed RENEW scenarios. - /// - /// This method does not throw, but uses gtest macros to signify failures. - /// - /// @param type type (TYPE_NA or TYPE_PD) - /// @param addr address being sent in RENEW - void - testRenewReject(isc::dhcp::Lease::Type type, - const isc::asiolink::IOAddress& addr); - /// @brief Performs basic (positive) RELEASE test /// /// See releaseBasic and pdReleaseBasic tests for detailed explanation. diff --git a/src/bin/dhcp6/tests/rebind_unittest.cc b/src/bin/dhcp6/tests/rebind_unittest.cc index d06f30c49e..2176a8b7d5 100644 --- a/src/bin/dhcp6/tests/rebind_unittest.cc +++ b/src/bin/dhcp6/tests/rebind_unittest.cc @@ -64,26 +64,9 @@ namespace { /// - this specific configuration is used by tests which don't use relays /// /// - Configuration 6: -/// - only addresses (no prefixes) -/// - 1 subnet with the 2001:db8:1::/64 prefix -/// - 'new-leases-on-renew' enabled -/// -/// - Configuration 7: -/// - only prefixes (no addresses) -/// - 1 subnet with the 3000::/72 -/// - 'new-leases-on-rebew' enabled -/// -/// - Configuration 8: /// - addresses and prefixes /// - address pool: 2001:db8:1::/64 /// - prefix pool: 3000::/72 -/// - 'new-leases-on-renew' enabled -/// -/// - Configuration 9: -/// - addresses and prefixes -/// - address pool: 2001:db8:1::/64 -/// - prefix pool: 3000::/72 -/// - 'new-leases-on-renew' disabled /// const char* REBIND_CONFIGS[] = { // Configuration 0 @@ -93,7 +76,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," " \"subnet\": \"2001:db8:1::/48\", " @@ -115,7 +97,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ]," " \"subnet\": \"2001:db8:3::/48\", " @@ -137,7 +118,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"3000:1::/64\" } ]," " \"subnet\": \"3000:1::/48\", " @@ -159,7 +139,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"3000:3::/64\" } ]," " \"subnet\": \"3000:3::/48\", " @@ -181,7 +160,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pd-pools\": [" " { \"prefix\": \"3000::\", " @@ -211,7 +189,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pd-pools\": [" " { \"prefix\": \"2001:db8:3:01::\", " @@ -241,64 +218,6 @@ const char* REBIND_CONFIGS[] = { "\"preferred-lifetime\": 3000," "\"rebind-timer\": 2000, " "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": True," - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," - "\"valid-lifetime\": 4000 }", - -// Configuration 7 - "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": True," - "\"subnet6\": [ { " - " \"pd-pools\": [" - " { \"prefix\": \"3000::\", " - " \"prefix-len\": 72, " - " \"delegated-len\": 80" - " } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," - "\"valid-lifetime\": 4000 }", - -// Configuration 8 - "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": True," - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," - " \"pd-pools\": [" - " { \"prefix\": \"3000::\", " - " \"prefix-len\": 72, " - " \"delegated-len\": 80" - " } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," - "\"valid-lifetime\": 4000 }", - -// Configuration 9 - "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," "\"subnet6\": [ { " " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," " \"pd-pools\": [" @@ -311,8 +230,6 @@ const char* REBIND_CONFIGS[] = { " \"interface\": \"eth0\"" " } ]," "\"valid-lifetime\": 4000 }" - - }; /// @brief Test fixture class for testing Rebind. @@ -354,8 +271,10 @@ TEST_F(RebindTest, directClient) { EXPECT_TRUE(lease_server2); } -// Test that server doesn't extend the lease when the configuration has changed -// such that the existing subnet is replaced with a different subnet. +// Test that server allocates a lease from a new subnet when the server +// is reconfigured such that the previous subnet is replaced with a +// new subnet. The client should get the new lease and an old lease +// with zero lifetimes in the Reply. TEST_F(RebindTest, directClientChangingSubnet) { Dhcp6Client client; // Configure client to request IA_NA. @@ -373,29 +292,26 @@ TEST_F(RebindTest, directClientChangingSubnet) { ASSERT_NO_THROW(client.doRebind()); - // We are expecting that the server didn't extend the lease because - // the address that client is using doesn't match the new subnet. - // But, the client still has an old lease. - ASSERT_EQ(1, client.getLeaseNum()); - Lease6 lease_client2 = client.getLease(0); + // We are expecting that the server has allocated a lease from the new + // subnet and sent zero lifetimes for a previous lease. + + std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime(); + ASSERT_EQ(1, old_leases.size()); + EXPECT_EQ(lease_client.addr_, old_leases[0].addr_); - // The current lease should be exactly the same as old lease, - // because server shouldn't have extended. - EXPECT_TRUE(lease_client.addr_ == lease_client2.addr_); - EXPECT_EQ(0, lease_client2.preferred_lft_); - EXPECT_EQ(0, lease_client2.valid_lft_); + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); // Make sure, that the lease that client has, is matching the lease // in the lease database. - Lease6Ptr lease_server2 = checkLease(lease_client2); + Lease6Ptr lease_server2 = checkLease(new_leases[0]); EXPECT_TRUE(lease_server2); - // Client should have received NoBinding status code. - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); - + // Client should have received Success status code. + EXPECT_EQ(STATUS_Success, client.getStatusCode(1234)); } -// Check that the server doesn't extend the lease for the client when the -// client sends IAID which doesn't belong to the lease that client has. +// Check that the server allocates a new lease when the client sends IA_NA +// with a new IAID. TEST_F(RebindTest, directClientChangingIAID) { Dhcp6Client client; // Configure client to request IA_NA. @@ -406,23 +322,29 @@ TEST_F(RebindTest, directClientChangingIAID) { Lease6 lease_client = client.getLease(0); // Modify the IAID of the lease record that client stores. By adding // one to IAID we guarantee that the IAID will change. - ++client.config_.leases_[0].iaid_; - // Try to Rebind. Note that client will use a different IAID (which - // is not matching IAID that server retains for the client). Server - // should not find the lease that client is trying to extend and - // should return NoBinding. + client.config_.leases_[0].iaid_ = 1235; + client.useNA(true, 1235); + + // Try to Rebind. The server should allocate new lease for this IAID. ASSERT_NO_THROW(client.doRebind()); - // The lease obtained in 4-way exchange should not change after the Rebind - // attempt. - Lease6Ptr lease_server2 = checkLease(lease_client); - EXPECT_TRUE(lease_server2); - // The Status code returned to the client, should be NoBinding. - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1235)); + // The old lease should be returned with 0 lifetimes. + std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime(); + ASSERT_EQ(1, old_leases.size()); + EXPECT_EQ(lease_client.addr_, old_leases[0].addr_); + + // The new lease should be allocated. + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); + + Lease6Ptr lease_server2 = checkLease(new_leases[0]); + EXPECT_TRUE(lease_server2); + // The Status code returned to the client, should be Success. + EXPECT_EQ(STATUS_Success, client.getStatusCode(1235)); } -// Check that server sends NoBinding when the lease has been lost from -// the database and client is trying to Rebind it. +// Check that the server allocates a requested lease for the client when +// this lease has been lost from the database. TEST_F(RebindTest, directClientLostLease) { Dhcp6Client client; // Configure client to request IA_NA. @@ -434,11 +356,15 @@ TEST_F(RebindTest, directClientLostLease) { // The lease has been acquired. Now, let's explicitly remove it from the // lease database. LeaseMgrFactory::instance().deleteLease(lease_client.addr_); - // An attempt to Rebind should fail. The lease should not be found by - // the server and the server should return NoBinding status code. + // Send Rebind. ASSERT_NO_THROW(client.doRebind()); - ASSERT_EQ(1, client.getLeaseNum()); - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); + + // The server should re-allocate this lease to the client. + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); + EXPECT_EQ(lease_client.addr_, new_leases[0].addr_); + // Status code should be Success. + EXPECT_EQ(STATUS_Success, client.getStatusCode(1234)); } /// @todo Extend tests for direct client changing address. @@ -520,25 +446,32 @@ TEST_F(RebindTest, relayedClientChangingIAID) { ASSERT_NO_FATAL_FAILURE(requestLease(REBIND_CONFIGS[2], 2, client)); // Keep the client's lease for future reference. Lease6 lease_client = client.getLease(0); + // Modify the IAID of the lease record that client stores. By adding // one to IAID we guarantee that the IAID will change. - ++client.config_.leases_[0].iaid_; - // Try to Rebind. Note that client will use a different IAID (which - // is not matching IAID that server retains for the client). Server - // should not find the lease that client is trying to extend and - // should return NoBinding. + client.config_.leases_[0].iaid_ = 1235; + client.useNA(true, 1235); + + // Try to Rebind. The server should allocate new lease for this IAID. ASSERT_NO_THROW(client.doRebind()); - // The lease obtained in 4-way exchange should not change after the Rebind - // attempt. - Lease6Ptr lease_server2 = checkLease(lease_client); - EXPECT_TRUE(lease_server2); - // The Status code returned to the client, should be NoBinding. - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1235)); + // The old lease should be returned with 0 lifetimes. + std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime(); + ASSERT_EQ(1, old_leases.size()); + EXPECT_EQ(lease_client.addr_, old_leases[0].addr_); + + // The new lease should be allocated. + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); + + Lease6Ptr lease_server2 = checkLease(new_leases[0]); + EXPECT_TRUE(lease_server2); + // The Status code returned to the client, should be Success. + EXPECT_EQ(STATUS_Success, client.getStatusCode(1235)); } -// Check that the relayed client receives NoBinding when the lease that he -// is Rebinding has been lost from the database. +// Check that the server allocates a requested lease for the client when +// this lease has been lost from the database. TEST_F(RebindTest, relayedClientLostLease) { Dhcp6Client client; // Configure client to request IA_NA. @@ -554,11 +487,16 @@ TEST_F(RebindTest, relayedClientLostLease) { // The lease has been acquired. Now, let's explicitly remove it from the // lease database. LeaseMgrFactory::instance().deleteLease(lease_client.addr_); - // An attempt to Rebind should fail. The lease should not be found by - // the server and the server should return NoBinding status code. + + // Send Rebind. ASSERT_NO_THROW(client.doRebind()); - ASSERT_EQ(1, client.getLeaseNum()); - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); + + // The server should re-allocate this lease to the client. + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); + EXPECT_EQ(lease_client.addr_, new_leases[0].addr_); + // Status code should be Success. + EXPECT_EQ(STATUS_Success, client.getStatusCode(1234)); } // Check that relayed client receives the IA with lifetimes of 0, when @@ -642,9 +580,10 @@ TEST_F(RebindTest, directClientPD) { EXPECT_TRUE(lease_server2); } -// Check that the prefix lifetime is not extended for the client in case -// the configuration has been changed such, that the subnet he is using -// doesn't exist anymore. +// Test that server allocates a lease from a new subnet when the server +// is reconfigured such that the previous subnet is replaced with a +// new subnet. The client should get the new lease and an old lease +// with zero lifetimes in the Reply. TEST_F(RebindTest, directClientPDChangingSubnet) { Dhcp6Client client; // Configure client to request IA_PD. @@ -657,31 +596,31 @@ TEST_F(RebindTest, directClientPDChangingSubnet) { // client's interface. Note that there will also be a new subnet // id assigned to the subnet on this interface. configure(REBIND_CONFIGS[5], *client.getServer()); - // Try to rebind, using the address that the client had acquired using + + // Try to rebind, using the prefix that the client had acquired using // previous server configuration. - ASSERT_NO_THROW(client.doRebind()); - // Make sure that the server has discarded client's message. In such case, - // the message sent back to the client should be NULL. - EXPECT_FALSE(client.getContext().response_) - << "The server responded to the Rebind message, while it should have" - " discarded it because there is no binding for the client."; - // We are expecting that the server didn't extend the lease because - // the address that client is using doesn't match the new subnet. - // But, the client still has an old lease. - ASSERT_EQ(1, client.getLeaseNum()); - Lease6 lease_client2 = client.getLease(0); - // The current lease should be exactly the same as old lease, - // because server shouldn't have extended. - EXPECT_TRUE(lease_client == lease_client2); + client.doRebind(); + + // We are expecting that the server has allocated a lease from the new + // subnet and sent zero lifetimes for a previous lease. + + std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime(); + ASSERT_EQ(1, old_leases.size()); + EXPECT_EQ(lease_client.addr_, old_leases[0].addr_); + + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); + // Make sure, that the lease that client has, is matching the lease // in the lease database. - Lease6Ptr lease_server2 = checkLease(lease_client2); + Lease6Ptr lease_server2 = checkLease(new_leases[0]); EXPECT_TRUE(lease_server2); + // Client should have received Success status code. + EXPECT_EQ(STATUS_Success, client.getStatusCode(5678)); } -// Check that the prefix lifetime is not extended for the client when the -// IAID used in the Rebind is not matching the one recorded by the server -// for the particular client. +// Check that the server allocates a new lease when the client sends IA_PD +// with a new IAID. TEST_F(RebindTest, directClientPDChangingIAID) { Dhcp6Client client; // Configure client to request IA_PD. @@ -690,24 +629,28 @@ TEST_F(RebindTest, directClientPDChangingIAID) { ASSERT_NO_FATAL_FAILURE(requestLease(REBIND_CONFIGS[4], 2, client)); // Keep the client's lease for future reference. Lease6 lease_client = client.getLease(0); + // Modify the IAID of the lease record that client stores. By adding // one to IAID we guarantee that the IAID will change. - ++client.config_.leases_[0].iaid_; - // Try to Rebind. Note that client will use a different IAID (which - // is not matching IAID that server retains for the client). This is - // a condition described in RFC3633, section 12.2 as the server finds - // no binding for the client. It is an indication that some other - // server has probably allocated the lease for the client. Hence, our - // server should discard the message. + client.config_.leases_[0].iaid_ = 5679; + client.usePD(true, 5679); + + // Try to Rebind. The server should allocate new lease for this IAID. ASSERT_NO_THROW(client.doRebind()); - // Make sure that the server has discarded client's message. In such case, - // the message sent back to the client should be NULL. - EXPECT_FALSE(client.getContext().response_) - << "The server responded to the Rebind message, while it should have" - " discarded it because there is no binding for the client."; - // Check that server still has the same lease. - Lease6Ptr lease_server = checkLease(lease_client); - EXPECT_TRUE(lease_server); + + // The old lease should be returned with 0 lifetimes. + std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime(); + ASSERT_EQ(1, old_leases.size()); + EXPECT_EQ(lease_client.addr_, old_leases[0].addr_); + + // The new lease should be allocated. + std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime(); + ASSERT_EQ(1, new_leases.size()); + + Lease6Ptr lease_server2 = checkLease(new_leases[0]); + EXPECT_TRUE(lease_server2); + // The Status code returned to the client, should be Success. + EXPECT_EQ(STATUS_Success, client.getStatusCode(5679)); } // Check that the prefix lifetime is not extended for the client when the @@ -839,7 +782,7 @@ TEST_F(RebindTest, requestPrefixInRebind) { client.usePD(); // Configure the server with NA pools only. - ASSERT_NO_THROW(configure(REBIND_CONFIGS[6], *client.getServer())); + ASSERT_NO_THROW(configure(REBIND_CONFIGS[0], *client.getServer())); // Perform 4-way exchange. ASSERT_NO_THROW(client.doSARR()); @@ -864,7 +807,7 @@ TEST_F(RebindTest, requestPrefixInRebind) { ASSERT_EQ(STATUS_NoPrefixAvail, client.getStatusCode(5678)); // Reconfigure the server to use both NA and PD pools. - configure(REBIND_CONFIGS[8], *client.getServer()); + configure(REBIND_CONFIGS[6], *client.getServer()); // Send Rebind message to the server, including IA_NA and requesting IA_PD. ASSERT_NO_THROW(client.doRebind()); @@ -894,7 +837,7 @@ TEST_F(RebindTest, requestAddressInRebind) { client.usePD(); // Configure the server with PD pools only. - ASSERT_NO_THROW(configure(REBIND_CONFIGS[7], *client.getServer())); + ASSERT_NO_THROW(configure(REBIND_CONFIGS[4], *client.getServer())); // Perform 4-way exchange. ASSERT_NO_THROW(client.doSARR()); @@ -921,7 +864,7 @@ TEST_F(RebindTest, requestAddressInRebind) { ASSERT_EQ(STATUS_NoAddrsAvail, client.getStatusCode(1234)); // Reconfigure the server to use both NA and PD pools. - configure(REBIND_CONFIGS[8], *client.getServer()); + configure(REBIND_CONFIGS[6], *client.getServer()); // Send Rebind message to the server, including IA_PD and requesting IA_NA. ASSERT_NO_THROW(client.doRebind()); @@ -939,102 +882,5 @@ TEST_F(RebindTest, requestAddressInRebind) { EXPECT_EQ(STATUS_Success, client.getStatusCode(1234)); } -// This test verifies that when the client requests the prefix delegation -// while it is renewing an address lease its message is dropped. -TEST_F(RebindTest, requestPrefixInRebindNotAllowed) { - Dhcp6Client client; - - // Configure client to request IA_NA and IA_PD. - client.useNA(); - client.usePD(); - - // Configure the server with NA pools only. - ASSERT_NO_THROW(configure(REBIND_CONFIGS[0], *client.getServer())); - - // Perform 4-way exchange. - ASSERT_NO_THROW(client.doSARR()); - - // Simulate aging of leases. - client.fastFwdTime(1000); - - // Make sure that the client has acquired NA lease. - std::vector<Lease6> leases_client_na = client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(1, leases_client_na.size()); - - // The client should not acquire a PD lease. - std::vector<Lease6> leases_client_pd = client.getLeasesByType(Lease::TYPE_PD); - ASSERT_TRUE(leases_client_pd.empty()); - ASSERT_EQ(STATUS_NoPrefixAvail, client.getStatusCode(5678)); - - // Send Rebind message to the server, including IA_NA and requesting IA_PD. - ASSERT_NO_THROW(client.doRebind()); - EXPECT_FALSE(client.getContext().response_); - - // Reconfigure the server to use both NA and PD pools. - configure(REBIND_CONFIGS[9], *client.getServer()); - - // Send Rebind message to the server, including IA_NA and requesting IA_PD. - ASSERT_NO_THROW(client.doRebind()); - EXPECT_FALSE(client.getContext().response_); -} - -// This test verifies that when the client requests an address assignment -// while it is renewing a prefix lease it is returned NoBinding, when -// the server is not configured to allocate new leases during Renew. -TEST_F(RebindTest, requestAddressInRebindNotAllowed) { - Dhcp6Client client; - - // Configure client to request IA_NA and IA_PD. - client.useNA(); - client.usePD(); - - // Configure the server with PD pools only. - ASSERT_NO_THROW(configure(REBIND_CONFIGS[4], *client.getServer())); - - // Perform 4-way exchange. - ASSERT_NO_THROW(client.doSARR()); - - // Simulate aging of leases. - client.fastFwdTime(1000); - - // Make sure that the client has acquired PD lease. - std::vector<Lease6> leases_client_pd = client.getLeasesByType(Lease::TYPE_PD); - ASSERT_EQ(1, leases_client_pd.size()); - EXPECT_EQ(STATUS_Success, client.getStatusCode(5678)); - - // The client should not acquire a NA lease. - std::vector<Lease6> leases_client_na = - client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(0, leases_client_na.size()); - ASSERT_EQ(STATUS_NoAddrsAvail, client.getStatusCode(1234)); - - // Send Rebind message to the server, including IA_PD and requesting IA_NA. - // The server should return NoBinding status code in this case. - ASSERT_NO_THROW(client.doRebind()); - leases_client_na = client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(0, leases_client_na.size()); - ASSERT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); - - // Reconfigure the server to use both NA and PD pools. - configure(REBIND_CONFIGS[9], *client.getServer()); - - // Send Rebind message to the server, including IA_PD and requesting IA_NA. - ASSERT_NO_THROW(client.doRebind()); - - // Make sure that the client has renewed PD lease. - std::vector<Lease6> leases_client_pd_renewed = - client.getLeasesByType(Lease::TYPE_PD); - ASSERT_EQ(1, leases_client_pd_renewed.size()); - EXPECT_EQ(STATUS_Success, client.getStatusCode(5678)); - EXPECT_GE(leases_client_pd_renewed[0].cltt_ - leases_client_pd[0].cltt_, 1000); - - // The server should not allocate an address to the client, as this has been - // explicitly disabled in the configuration. Instead, it should send - // NoBinding status code. - leases_client_na = client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(0, leases_client_na.size()); - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); -} - } // end of anonymous namespace diff --git a/src/bin/dhcp6/tests/renew_unittest.cc b/src/bin/dhcp6/tests/renew_unittest.cc index 497a355472..cef2b7ef2c 100644 --- a/src/bin/dhcp6/tests/renew_unittest.cc +++ b/src/bin/dhcp6/tests/renew_unittest.cc @@ -44,23 +44,6 @@ namespace { /// - address pool: 2001:db8:1::/64 /// - prefix pool: 3000::/72 /// -/// - Configuration 3: -/// - only addresses (no prefixes) -/// - 1 subnet with 2001:db8:1::/64 pool -/// - 'new-leases-on-renew' disabled -/// -/// - Configuration 4: -/// - only prefixes (no addresses) -/// - prefix pool: 3000::/72 -/// - 'new-leases-on-renew' disabled -/// -/// - Configuration 5: -/// - addresses and prefixes -/// - 1 subnet with one address pool and one prefix pool -/// - address pool: 2001:db8:1::/64 -/// - prefix pool: 3000::/72 -/// - 'new-leases-on-renew' disabled -/// const char* RENEW_CONFIGS[] = { // Configuration 0 "{ \"interfaces-config\": {" @@ -114,63 +97,6 @@ const char* RENEW_CONFIGS[] = { " \"interface-id\": \"\"," " \"interface\": \"eth0\"" " } ]," - "\"valid-lifetime\": 4000 }", - -// Configuration 3 - "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," - "\"valid-lifetime\": 4000 }", - -// Configuration 4 - "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," - "\"subnet6\": [ { " - " \"pd-pools\": [" - " { \"prefix\": \"3000::\", " - " \"prefix-len\": 72, " - " \"delegated-len\": 80" - " } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," - "\"valid-lifetime\": 4000 }", - -// Configuration 5 - "{ \"interfaces-config\": {" - " \"interfaces\": [ \"*\" ]" - "}," - "\"preferred-lifetime\": 3000," - "\"rebind-timer\": 2000, " - "\"renew-timer\": 1000, " - "\"new-leases-on-renew\": False," - "\"subnet6\": [ { " - " \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ]," - " \"pd-pools\": [" - " { \"prefix\": \"3000::\", " - " \"prefix-len\": 72, " - " \"delegated-len\": 80" - " } ]," - " \"subnet\": \"2001:db8:1::/48\", " - " \"interface-id\": \"\"," - " \"interface\": \"eth0\"" - " } ]," "\"valid-lifetime\": 4000 }" }; @@ -427,120 +353,5 @@ TEST_F(RenewTest, requestAddressInRenewHint) { EXPECT_EQ(STATUS_Success, client.getStatusCode(1234)); } -// This test verifies that when the client requests the prefix delegation -// while it is renewing an address lease it is returned NoBinding, when -// the server is not configured to allocate new leases during Renew. -TEST_F(RenewTest, requestPrefixInRenewNotAllowed) { - Dhcp6Client client; - - // Configure client to request IA_NA and IA_PD. - client.useNA(); - client.usePD(); - - // Configure the server with NA pools only. - ASSERT_NO_THROW(configure(RENEW_CONFIGS[3], *client.getServer())); - - // Perform 4-way exchange. - ASSERT_NO_THROW(client.doSARR()); - - // Simulate aging of leases. - client.fastFwdTime(1000); - - // Make sure that the client has acquired NA lease. - std::vector<Lease6> leases_client_na = client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(1, leases_client_na.size()); - - // The client should not acquire a PD lease. - std::vector<Lease6> leases_client_pd = client.getLeasesByType(Lease::TYPE_PD); - ASSERT_TRUE(leases_client_pd.empty()); - ASSERT_EQ(STATUS_NoPrefixAvail, client.getStatusCode(5678)); - - // Send Renew message to the server, including IA_NA and requesting IA_PD. - ASSERT_NO_THROW(client.doRenew()); - leases_client_pd = client.getLeasesByType(Lease::TYPE_PD); - ASSERT_TRUE(leases_client_pd.empty()); - ASSERT_EQ(STATUS_NoBinding, client.getStatusCode(5678)); - - // Reconfigure the server to use both NA and PD pools. - configure(RENEW_CONFIGS[5], *client.getServer()); - - // Send Renew message to the server, including IA_NA and requesting IA_PD. - ASSERT_NO_THROW(client.doRenew()); - - // Make sure that the client has acquired NA lease. - std::vector<Lease6> leases_client_na_renewed = - client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(1, leases_client_na_renewed.size()); - EXPECT_EQ(STATUS_Success, client.getStatusCode(1234)); - - // The lease should have been renewed. - EXPECT_EQ(1000, leases_client_na_renewed[0].cltt_ - leases_client_na[0].cltt_); - - // The server should not delegate a prefix to the client, as this has been - // explicitly disabled in the configuration. Instead, it should send - // NoBinding status code. - leases_client_pd = client.getLeasesByType(Lease::TYPE_PD); - ASSERT_EQ(0, leases_client_pd.size()); - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(5678)); -} - -// This test verifies that when the client requests an address assignment -// while it is renewing a prefix lease it is returned NoBinding, when -// the server is not configured to allocate new leases during Renew. -TEST_F(RenewTest, requestAddressInRenewNotAllowed) { - Dhcp6Client client; - - // Configure client to request IA_NA and IA_PD. - client.useNA(); - client.usePD(); - - // Configure the server with PD pools only. - ASSERT_NO_THROW(configure(RENEW_CONFIGS[4], *client.getServer())); - - // Perform 4-way exchange. - ASSERT_NO_THROW(client.doSARR()); - - // Simulate aging of leases. - client.fastFwdTime(1000); - - // Make sure that the client has acquired PD lease. - std::vector<Lease6> leases_client_pd = client.getLeasesByType(Lease::TYPE_PD); - ASSERT_EQ(1, leases_client_pd.size()); - EXPECT_EQ(STATUS_Success, client.getStatusCode(5678)); - - // The client should not acquire a NA lease. - std::vector<Lease6> leases_client_na = - client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(0, leases_client_na.size()); - ASSERT_EQ(STATUS_NoAddrsAvail, client.getStatusCode(1234)); - - // Send Renew message to the server, including IA_PD and requesting IA_NA. - // The server should return NoBinding status code in this case. - ASSERT_NO_THROW(client.doRenew()); - leases_client_na = client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(0, leases_client_na.size()); - ASSERT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); - - // Reconfigure the server to use both NA and PD pools. - configure(RENEW_CONFIGS[5], *client.getServer()); - - // Send Renew message to the server, including IA_PD and requesting IA_NA. - ASSERT_NO_THROW(client.doRenew()); - - // Make sure that the client has renewed PD lease. - std::vector<Lease6> leases_client_pd_renewed = - client.getLeasesByType(Lease::TYPE_PD); - ASSERT_EQ(1, leases_client_pd_renewed.size()); - EXPECT_EQ(STATUS_Success, client.getStatusCode(5678)); - EXPECT_GE(leases_client_pd_renewed[0].cltt_ - leases_client_pd[0].cltt_, 1000); - - // The server should not allocate an address to the client, as this has been - // explicitly disabled in the configuration. Instead, it should send - // NoBinding status code. - leases_client_na = client.getLeasesByType(Lease::TYPE_NA); - ASSERT_EQ(0, leases_client_na.size()); - EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1234)); -} - } // end of anonymous namespace diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index f3e0a742b7..0ccef1e2dc 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -297,7 +297,7 @@ AllocEngine::ClientContext6::ClientContext6() : subnet_(), duid_(), iaid_(0), type_(Lease::TYPE_NA), hwaddr_(), hints_(), fwd_dns_update_(false), rev_dns_update_(false), hostname_(""), callout_handle_(), fake_allocation_(false), old_leases_(), host_(), - query_(), ia_rsp_(), allow_new_leases_in_renewals_(false) { + query_(), ia_rsp_() { } AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const DuidPtr& duid, @@ -310,8 +310,7 @@ AllocEngine::ClientContext6::ClientContext6(const Subnet6Ptr& subnet, const Duid subnet_(subnet), duid_(duid), iaid_(iaid), type_(type), hwaddr_(), hints_(), fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns), hostname_(hostname), fake_allocation_(fake_allocation), - old_leases_(), host_(), query_(), ia_rsp_(), - allow_new_leases_in_renewals_(false) { + old_leases_(), host_(), query_(), ia_rsp_() { static asiolink::IOAddress any("::"); @@ -1093,18 +1092,6 @@ AllocEngine::renewLeases6(ClientContext6& ctx) { Lease6Collection leases = LeaseMgrFactory::instance() .getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_, ctx.subnet_->getID()); - // If this client has no leases and we do not allow allocation of - // new leases in renewals, return now to indicate NoBinding. - if (leases.empty() && !ctx.allow_new_leases_in_renewals_) { - LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE, - ALLOC_ENGINE_V6_NO_BINDING) - .arg(ctx.query_->getLabel()) - .arg(Lease::typeToText(ctx.type_)) - .arg(ctx.iaid_) - .arg(ctx.subnet_->getID()); - return (Lease6Collection()); - } - if (!leases.empty()) { LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE, ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED) @@ -1135,7 +1122,7 @@ AllocEngine::renewLeases6(ClientContext6& ctx) { // Depending on the configuration, we may enable or disable granting // new leases during renewals. This is controlled with the // allow_new_leases_in_renewals_ field. - if (leases.empty() && ctx.allow_new_leases_in_renewals_) { + if (leases.empty()) { LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE, ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED) diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h index 408e4dc91e..487312fa1d 100644 --- a/src/lib/dhcpsrv/alloc_engine.h +++ b/src/lib/dhcpsrv/alloc_engine.h @@ -357,18 +357,6 @@ public: /// @brief A pointer to the IA_NA/IA_PD option to be sent in response Option6IAPtr ia_rsp_; - - /// @brief Specifies whether new leases in Renew/Rebind are allowed - /// - /// This field controls what to do when renewing or rebinding client - /// does not have any leases. RFC3315 and the stateful-issues draft do - /// not specify it and it is left up to the server configuration policy. - /// False (the default) means that the client will not get any new - /// unreserved leases if his existing leases are no longer suitable. - /// True means that the allocation engine will do its best to assign - /// something. - bool allow_new_leases_in_renewals_; - /// @brief Default constructor. ClientContext6(); diff --git a/src/lib/dhcpsrv/alloc_engine_messages.mes b/src/lib/dhcpsrv/alloc_engine_messages.mes index 60893718bc..8488c9f69a 100644 --- a/src/lib/dhcpsrv/alloc_engine_messages.mes +++ b/src/lib/dhcpsrv/alloc_engine_messages.mes @@ -246,15 +246,6 @@ reserved for it. This informational message signals that the specified client was assigned the prefix reserved for it. -% ALLOC_ENGINE_V6_NO_BINDING %1: client requesting renew/rebind has no binding for lease type %2, IAID %3 and subnet id %4 -This debug message is issued when the allocation engine determines that the renewing -client has no binding for the given lease type, IAID and subnet id. The server is -configured to not allocate new bindings during the Renew/Rebind. Hence the -server doesn't allocate new leases and returns NoBinding status code or -ignores the message. The first argument contains the client and the -transaction identification information. The remaining arguments hold -the lease type, IAID and subnet id respectively. - % ALLOC_ENGINE_V6_RENEW_HR allocating leases reserved for the client %1 as a result of Renew This debug message is issued when the allocation engine tries to allocate reserved leases for the client sending a Renew message. diff --git a/src/lib/dhcpsrv/tests/alloc_engine_utils.cc b/src/lib/dhcpsrv/tests/alloc_engine_utils.cc index d5894d92cc..53227c773d 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_utils.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine_utils.cc @@ -233,7 +233,6 @@ AllocEngine6Test::simpleAlloc6Test(const Pool6Ptr& pool, const IOAddress& hint, Lease6Collection AllocEngine6Test::renewTest(AllocEngine& engine, const Pool6Ptr& pool, AllocEngine::HintContainer& hints, - bool allow_new_leases_in_renewal, bool in_pool) { Lease::Type type = pool->getType(); @@ -243,7 +242,6 @@ AllocEngine6Test::renewTest(AllocEngine& engine, const Pool6Ptr& pool, type, false, false, "", false); ctx.hints_ = hints; ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 123)); - ctx.allow_new_leases_in_renewals_ = allow_new_leases_in_renewal; ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 1234)); findReservation(engine, ctx); diff --git a/src/lib/dhcpsrv/tests/alloc_engine_utils.h b/src/lib/dhcpsrv/tests/alloc_engine_utils.h index bc0728aa57..128c5060d7 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_utils.h +++ b/src/lib/dhcpsrv/tests/alloc_engine_utils.h @@ -246,13 +246,10 @@ public: /// @param engine a reference to Allocation Engine /// @param pool pool from which the lease will be allocated from /// @param hints address to be used as a hint - /// @param allow_new_leases_in_renewal - specifies how to set the - /// allow_new_leases_in_renewal flag in ClientContext6 /// @param in_pool specifies whether the lease is expected to be in pool /// @return allocated lease(s) (may be empty) Lease6Collection renewTest(AllocEngine& engine, const Pool6Ptr& pool, AllocEngine::HintContainer& hints, - bool allow_new_leases_in_renewal, bool in_pool = true); /// @brief Checks if the address allocation with a hint that is in range, |