Browse Source

[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.
Marcin Siodelski 9 years ago
parent
commit
ddb442f78b

+ 0 - 6
src/bin/dhcp6/dhcp6.spec

@@ -62,12 +62,6 @@
         "item_default": 4000
         "item_default": 4000
       },
       },
 
 
-      { "item_name": "new-leases-on-renew",
-        "item_type": "boolean",
-        "item_optional": true,
-        "item_default": true
-      },
-
       { "item_name": "option-def",
       { "item_name": "option-def",
         "item_type": "list",
         "item_type": "list",
         "item_optional": false,
         "item_optional": false,

+ 0 - 18
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
 This is an error message logged when the dynamic reconfiguration of the
 DHCP server failed.
 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
 % DHCP6_HOOKS_LIBS_RELOAD_FAIL reload of hooks libraries failed
 A "libreload" command was issued to reload the hooks libraries but for
 A "libreload" command was issued to reload the hooks libraries but for
 some reason the reload failed.  Other error messages issued from the
 some reason the reload failed.  Other error messages issued from the

+ 12 - 71
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.ia_rsp_ = ia_rsp;
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.host_ = orig_ctx.host_;
     ctx.host_ = orig_ctx.host_;
-    ctx.allow_new_leases_in_renewals_ = subnet->getAllocLeasesOnRenew();
 
 
     // Extract the addresses that the client is trying to obtain.
     // Extract the addresses that the client is trying to obtain.
     OptionCollection addrs = ia->getOptions();
     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.
     // All is left is to insert the status code.
     if (leases.empty()) {
     if (leases.empty()) {
 
 
-        // We did not assign any address to the client. Depending on whether the
+        // The server wasn't able allocate new lease and renew an exising
-        // server is configured to allocate new leases during the Renew or
+        // lease. In that case, the server sends NoAddrsAvail per RFC7550.
-        // Rebind we will have to send a different status code. If the server
+        ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
-        // is configured to allocate new leases for the Renew and Rebind, the
+                                           STATUS_NoAddrsAvail,
-        // status code will be NoAddressAvail. If the server is not configured
+                                           "Sorry, no addresses could be"
-        // to allocate prefixes for the renewing client, the status code will
+                                           " assigned at this time."));
-        // 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."));
-        }
     }
     }
 
 
     return (ia_rsp);
     return (ia_rsp);
@@ -1894,7 +1871,6 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
     ctx.ia_rsp_ = ia_rsp;
     ctx.ia_rsp_ = ia_rsp;
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.hwaddr_ = orig_ctx.hwaddr_;
     ctx.host_ = orig_ctx.host_;
     ctx.host_ = orig_ctx.host_;
-    ctx.allow_new_leases_in_renewals_ = subnet->getAllocLeasesOnRenew();
 
 
     // Extract prefixes that the client is trying to renew.
     // Extract prefixes that the client is trying to renew.
     OptionCollection addrs = ia->getOptions();
     OptionCollection addrs = ia->getOptions();
@@ -1963,47 +1939,12 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query,
     // All is left is to insert the status code.
     // All is left is to insert the status code.
     if (leases.empty()) {
     if (leases.empty()) {
 
 
-        // We did not assign any prefix to the client. Depending on whether the
+        // The server wasn't able allocate new lease and renew an exising
-        // server is configured to allocate new leases during the Renew or
+        // lease. In that case, the server sends NoPrefixAvail per RFC7550.
-        // Rebind we will have to send a different status code. If the server
+        ia_rsp->addOption(createStatusCode(*query, *ia_rsp,
-        // is configured to allocate new leases for the Renew and Rebind, the
+                                           STATUS_NoPrefixAvail,
-        // status code will be NoPrefixAvail. If the server is not configured
+                                           "Sorry, no prefixes could be"
-        // to allocate prefixes for the renewing client, the status code will
+                                           " assigned at this time."));
-        // 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."));
-        }
     }
     }
 
 
     return (ia_rsp);
     return (ia_rsp);

+ 1 - 8
src/bin/dhcp6/json_config_parser.cc

@@ -475,16 +475,13 @@ protected:
 
 
         // Gather boolean parameters values.
         // Gather boolean parameters values.
         bool rapid_commit = boolean_values_->getOptionalParam("rapid-commit", false);
         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;
         std::ostringstream output;
         output << addr << "/" << static_cast<int>(len)
         output << addr << "/" << static_cast<int>(len)
                << " with params t1=" << t1 << ", t2="
                << " with params t1=" << t1 << ", t2="
                << t2 << ", preferred-lifetime=" << pref
                << t2 << ", preferred-lifetime=" << pref
                << ", valid-lifetime=" << valid
                << ", valid-lifetime=" << valid
-               << ", rapid-commit is " << (rapid_commit ? "enabled" : "disabled")
+               << ", rapid-commit is " << (rapid_commit ? "enabled" : "disabled");
-               << ", new-leases-on-renew is " << (alloc_leases_on_renew ? "enabled" : "disabled");
 
 
 
 
         LOG_INFO(dhcp6_logger, DHCP6_CONFIG_NEW_SUBNET).arg(output.str());
         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.
         // Enable or disable Rapid Commit option support for the subnet.
         subnet6->setRapidCommit(rapid_commit);
         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 setting up client class (if specified)
         try {
         try {
@@ -700,8 +695,6 @@ namespace dhcp {
         parser = new RSOOListConfigParser(config_id);
         parser = new RSOOListConfigParser(config_id);
     } else if (config_id.compare("control-socket") == 0) {
     } else if (config_id.compare("control-socket") == 0) {
         parser = new ControlSocketParser(config_id);
         parser = new ControlSocketParser(config_id);
-    } else if (config_id.compare("new-leases-on-renew") == 0) {
-        parser = new BooleanParser(config_id, globalContext()->boolean_values_);
     } else {
     } else {
         isc_throw(DhcpConfigError,
         isc_throw(DhcpConfigError,
                 "unsupported global configuration parameter: "
                 "unsupported global configuration parameter: "

+ 0 - 80
src/bin/dhcp6/tests/config_parser_unittest.cc

@@ -531,37 +531,6 @@ public:
         CfgMgr::instance().clear();
         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)
     int rcode_;          ///< Return code (see @ref isc::config::parseAnswer)
     Dhcpv6Srv srv_;      ///< Instance of the Dhcp6Srv used during tests
     Dhcpv6Srv srv_;      ///< Instance of the Dhcp6Srv used during tests
     ConstElementPtr comment_; ///< Comment (see @ref isc::config::parseAnswer)
     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.
 // This test checks that multiple pools can be defined and handled properly.
 // The test defines 2 subnets, each with 2 pools.
 // The test defines 2 subnets, each with 2 pools.
 TEST_F(Dhcp6ParserTest, multiplePools) {
 TEST_F(Dhcp6ParserTest, multiplePools) {

+ 10 - 6
src/bin/dhcp6/tests/dhcp6_client.cc

@@ -94,7 +94,9 @@ Dhcp6Client::Dhcp6Client() :
     use_rapid_commit_(false),
     use_rapid_commit_(false),
     address_hint_(),
     address_hint_(),
     prefix_hint_(),
     prefix_hint_(),
-    fqdn_() {
+    fqdn_(),
+    na_iaid_(1234),
+    pd_iaid_(5678) {
 }
 }
 
 
 Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
 Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
@@ -113,7 +115,9 @@ Dhcp6Client::Dhcp6Client(boost::shared_ptr<NakedDhcpv6Srv>& srv) :
     use_rapid_commit_(false),
     use_rapid_commit_(false),
     address_hint_(),
     address_hint_(),
     prefix_hint_(),
     prefix_hint_(),
-    fqdn_() {
+    fqdn_(),
+    na_iaid_(1234),
+    pd_iaid_(5678) {
 }
 }
 
 
 void
 void
@@ -243,11 +247,11 @@ Dhcp6Client::appendFQDN() {
 void
 void
 Dhcp6Client::appendRequestedIAs(const Pkt6Ptr& query) const {
 Dhcp6Client::appendRequestedIAs(const Pkt6Ptr& query) const {
     if (use_na_) {
     if (use_na_) {
-        conditionallyAppendRequestedIA(query, D6O_IA_NA, 1234);
+        conditionallyAppendRequestedIA(query, D6O_IA_NA, na_iaid_);
     }
     }
 
 
     if (use_pd_) {
     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,
     // IA_NA, IA_TA and IA_PD options are not allowed in INF-REQUEST,
     // but hey! Let's test it.
     // but hey! Let's test it.
     if (use_na_) {
     if (use_na_) {
-        // Insert IA_NA option with iaid=1234.
+        // Insert IA_NA option.
         context_.query_->addOption(Option6IAPtr(new Option6IA(D6O_IA_NA,
         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.
     // IA-PD is also not allowed. So it may be useful in testing, too.

+ 11 - 2
src/bin/dhcp6/tests/dhcp6_client.h

@@ -439,8 +439,10 @@ public:
     ///
     ///
     /// @param use Parameter which 'true' value indicates that client should
     /// @param use Parameter which 'true' value indicates that client should
     /// request address assignment.
     /// 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;
         use_na_ = use;
+        na_iaid_ = iaid;
     }
     }
 
 
     /// @brief Place IA_PD options to request prefix assignment.
     /// @brief Place IA_PD options to request prefix assignment.
@@ -450,8 +452,10 @@ public:
     ///
     ///
     /// @param use Parameter which 'true' value indicates that client should
     /// @param use Parameter which 'true' value indicates that client should
     /// request prefix assignment.
     /// 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;
         use_pd_ = use;
+        pd_iaid_ = iaid;
     }
     }
 
 
     /// @brief Simulate sending messages through a relay.
     /// @brief Simulate sending messages through a relay.
@@ -706,6 +710,11 @@ private:
 
 
     /// @brief FQDN requested by the client.
     /// @brief FQDN requested by the client.
     Option6ClientFqdnPtr fqdn_;
     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
 } // end of namespace isc::dhcp::test

+ 0 - 17
src/bin/dhcp6/tests/dhcp6_srv_unittest.cc

@@ -939,23 +939,6 @@ TEST_F(Dhcpv6SrvTest, RenewSomeoneElesesLease) {
     testRenewSomeoneElsesLease(Lease::TYPE_NA, IOAddress("2001:db8::1"));
     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
 // This test verifies that incoming (positive) RELEASE with address can be
 // handled properly, that a REPLY is generated, that the response has status
 // handled properly, that a REPLY is generated, that the response has status
 // code and that the lease is indeed removed from the database.
 // code and that the lease is indeed removed from the database.

+ 0 - 143
src/bin/dhcp6/tests/dhcp6_test_utils.cc

@@ -421,149 +421,6 @@ Dhcpv6SrvTest::testRenewSomeoneElsesLease(Lease::Type type, const IOAddress& add
 }
 }
 
 
 void
 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,
 Dhcpv6SrvTest::testReleaseBasic(Lease::Type type, const IOAddress& existing,
                                 const IOAddress& release_addr) {
                                 const IOAddress& release_addr) {
     NakedDhcpv6Srv srv(0);
     NakedDhcpv6Srv srv(0);

+ 0 - 13
src/bin/dhcp6/tests/dhcp6_test_utils.h

@@ -468,19 +468,6 @@ public:
     testRenewSomeoneElsesLease(isc::dhcp::Lease::Type type,
     testRenewSomeoneElsesLease(isc::dhcp::Lease::Type type,
                                const asiolink::IOAddress& addr);
                                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
     /// @brief Performs basic (positive) RELEASE test
     ///
     ///
     /// See releaseBasic and pdReleaseBasic tests for detailed explanation.
     /// See releaseBasic and pdReleaseBasic tests for detailed explanation.

+ 119 - 273
src/bin/dhcp6/tests/rebind_unittest.cc

@@ -64,26 +64,9 @@ namespace {
 ///   - this specific configuration is used by tests which don't use relays
 ///   - this specific configuration is used by tests which don't use relays
 ///
 ///
 /// - Configuration 6:
 /// - 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
 ///   - addresses and prefixes
 ///   - address pool: 2001:db8:1::/64
 ///   - address pool: 2001:db8:1::/64
 ///   - prefix pool: 3000::/72
 ///   - 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[] = {
 const char* REBIND_CONFIGS[] = {
 // Configuration 0
 // Configuration 0
@@ -93,7 +76,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
-        "\"new-leases-on-renew\": False,"
         "\"subnet6\": [ { "
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
         "    \"subnet\": \"2001:db8:1::/48\", "
         "    \"subnet\": \"2001:db8:1::/48\", "
@@ -115,7 +97,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
-        "\"new-leases-on-renew\": False,"
         "\"subnet6\": [ { "
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ],"
         "    \"pools\": [ { \"pool\": \"2001:db8:3::/64\" } ],"
         "    \"subnet\": \"2001:db8:3::/48\", "
         "    \"subnet\": \"2001:db8:3::/48\", "
@@ -137,7 +118,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
-        "\"new-leases-on-renew\": False,"
         "\"subnet6\": [ { "
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"3000:1::/64\" } ],"
         "    \"pools\": [ { \"pool\": \"3000:1::/64\" } ],"
         "    \"subnet\": \"3000:1::/48\", "
         "    \"subnet\": \"3000:1::/48\", "
@@ -159,7 +139,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
-        "\"new-leases-on-renew\": False,"
         "\"subnet6\": [ { "
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"3000:3::/64\" } ],"
         "    \"pools\": [ { \"pool\": \"3000:3::/64\" } ],"
         "    \"subnet\": \"3000:3::/48\", "
         "    \"subnet\": \"3000:3::/48\", "
@@ -181,7 +160,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
-        "\"new-leases-on-renew\": False,"
         "\"subnet6\": [ { "
         "\"subnet6\": [ { "
         "    \"pd-pools\": ["
         "    \"pd-pools\": ["
         "        { \"prefix\": \"3000::\", "
         "        { \"prefix\": \"3000::\", "
@@ -211,7 +189,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"renew-timer\": 1000, "
-        "\"new-leases-on-renew\": False,"
         "\"subnet6\": [ { "
         "\"subnet6\": [ { "
         "    \"pd-pools\": ["
         "    \"pd-pools\": ["
         "        { \"prefix\": \"2001:db8:3:01::\", "
         "        { \"prefix\": \"2001:db8:3:01::\", "
@@ -241,64 +218,6 @@ const char* REBIND_CONFIGS[] = {
         "\"preferred-lifetime\": 3000,"
         "\"preferred-lifetime\": 3000,"
         "\"rebind-timer\": 2000, "
         "\"rebind-timer\": 2000, "
         "\"renew-timer\": 1000, "
         "\"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\": [ { "
         "\"subnet6\": [ { "
         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
         "    \"pools\": [ { \"pool\": \"2001:db8:1::/64\" } ],"
         "    \"pd-pools\": ["
         "    \"pd-pools\": ["
@@ -311,8 +230,6 @@ const char* REBIND_CONFIGS[] = {
         "    \"interface\": \"eth0\""
         "    \"interface\": \"eth0\""
         " } ],"
         " } ],"
         "\"valid-lifetime\": 4000 }"
         "\"valid-lifetime\": 4000 }"
-
-
 };
 };
 
 
 /// @brief Test fixture class for testing Rebind.
 /// @brief Test fixture class for testing Rebind.
@@ -354,8 +271,10 @@ TEST_F(RebindTest, directClient) {
     EXPECT_TRUE(lease_server2);
     EXPECT_TRUE(lease_server2);
 }
 }
 
 
-// Test that server doesn't extend the lease when the configuration has changed
+// Test that server allocates a lease from a new subnet when the server
-// such that the existing subnet is replaced with a different subnet.
+// 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) {
 TEST_F(RebindTest, directClientChangingSubnet) {
     Dhcp6Client client;
     Dhcp6Client client;
     // Configure client to request IA_NA.
     // Configure client to request IA_NA.
@@ -373,29 +292,26 @@ TEST_F(RebindTest, directClientChangingSubnet) {
 
 
     ASSERT_NO_THROW(client.doRebind());
     ASSERT_NO_THROW(client.doRebind());
 
 
-    // We are expecting that the server didn't extend the lease because
+    // We are expecting that the server has allocated a lease from the new
-    // the address that client is using doesn't match the new subnet.
+    // subnet and sent zero lifetimes for a previous lease.
-    // But, the client still has an old lease.
+
-    ASSERT_EQ(1, client.getLeaseNum());
+    std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime();
-    Lease6 lease_client2 = client.getLease(0);
+    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,
+    std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime();
-    // because server shouldn't have extended.
+    ASSERT_EQ(1, new_leases.size());
-    EXPECT_TRUE(lease_client.addr_ == lease_client2.addr_);
-    EXPECT_EQ(0, lease_client2.preferred_lft_);
-    EXPECT_EQ(0, lease_client2.valid_lft_);
 
 
     // Make sure, that the lease that client has, is matching the lease
     // Make sure, that the lease that client has, is matching the lease
     // in the lease database.
     // in the lease database.
-    Lease6Ptr lease_server2 = checkLease(lease_client2);
+    Lease6Ptr lease_server2 = checkLease(new_leases[0]);
     EXPECT_TRUE(lease_server2);
     EXPECT_TRUE(lease_server2);
-    // Client should have received NoBinding status code.
+    // Client should have received Success status code.
-    EXPECT_EQ(STATUS_NoBinding, client.getStatusCode(1234));
+    EXPECT_EQ(STATUS_Success, client.getStatusCode(1234));
-
 }
 }
 
 
-// Check that the server doesn't extend the lease for the client when the
+// Check that the server allocates a new lease when the client sends IA_NA
-// client sends IAID which doesn't belong to the lease that client has.
+// with a new IAID.
 TEST_F(RebindTest, directClientChangingIAID) {
 TEST_F(RebindTest, directClientChangingIAID) {
     Dhcp6Client client;
     Dhcp6Client client;
     // Configure client to request IA_NA.
     // Configure client to request IA_NA.
@@ -406,23 +322,29 @@ TEST_F(RebindTest, directClientChangingIAID) {
     Lease6 lease_client = client.getLease(0);
     Lease6 lease_client = client.getLease(0);
     // Modify the IAID of the lease record that client stores. By adding
     // Modify the IAID of the lease record that client stores. By adding
     // one to IAID we guarantee that the IAID will change.
     // one to IAID we guarantee that the IAID will change.
-    ++client.config_.leases_[0].iaid_;
+    client.config_.leases_[0].iaid_ = 1235;
-    // Try to Rebind. Note that client will use a different IAID (which
+    client.useNA(true, 1235);
-    // is not matching IAID that server retains for the client). Server
+
-    // should not find the lease that client is trying to extend and
+    // Try to Rebind. The server should allocate new lease for this IAID.
-    // should return NoBinding.
     ASSERT_NO_THROW(client.doRebind());
     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
+// Check that the server allocates a requested lease for the client when
-// the database and client is trying to Rebind it.
+// this lease has been lost from the database.
 TEST_F(RebindTest, directClientLostLease) {
 TEST_F(RebindTest, directClientLostLease) {
     Dhcp6Client client;
     Dhcp6Client client;
     // Configure client to request IA_NA.
     // 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
     // The lease has been acquired. Now, let's explicitly remove it from the
     // lease database.
     // lease database.
     LeaseMgrFactory::instance().deleteLease(lease_client.addr_);
     LeaseMgrFactory::instance().deleteLease(lease_client.addr_);
-    // An attempt to Rebind should fail. The lease should not be found by
+    // Send Rebind.
-    // the server and the server should return NoBinding status code.
     ASSERT_NO_THROW(client.doRebind());
     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.
 /// @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));
     ASSERT_NO_FATAL_FAILURE(requestLease(REBIND_CONFIGS[2], 2, client));
     // Keep the client's lease for future reference.
     // Keep the client's lease for future reference.
     Lease6 lease_client = client.getLease(0);
     Lease6 lease_client = client.getLease(0);
+
     // Modify the IAID of the lease record that client stores. By adding
     // Modify the IAID of the lease record that client stores. By adding
     // one to IAID we guarantee that the IAID will change.
     // one to IAID we guarantee that the IAID will change.
-    ++client.config_.leases_[0].iaid_;
+    client.config_.leases_[0].iaid_ = 1235;
-    // Try to Rebind. Note that client will use a different IAID (which
+    client.useNA(true, 1235);
-    // is not matching IAID that server retains for the client). Server
+
-    // should not find the lease that client is trying to extend and
+    // Try to Rebind. The server should allocate new lease for this IAID.
-    // should return NoBinding.
     ASSERT_NO_THROW(client.doRebind());
     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
+// Check that the server allocates a requested lease for the client when
-// is Rebinding has been lost from the database.
+// this lease has been lost from the database.
 TEST_F(RebindTest, relayedClientLostLease) {
 TEST_F(RebindTest, relayedClientLostLease) {
     Dhcp6Client client;
     Dhcp6Client client;
     // Configure client to request IA_NA.
     // 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
     // The lease has been acquired. Now, let's explicitly remove it from the
     // lease database.
     // lease database.
     LeaseMgrFactory::instance().deleteLease(lease_client.addr_);
     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_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
 // Check that relayed client receives the IA with lifetimes of 0, when
@@ -642,9 +580,10 @@ TEST_F(RebindTest, directClientPD) {
     EXPECT_TRUE(lease_server2);
     EXPECT_TRUE(lease_server2);
 }
 }
 
 
-// Check that the prefix lifetime is not extended for the client in case
+// Test that server allocates a lease from a new subnet when the server
-// the configuration has been changed such, that the subnet he is using
+// is reconfigured such that the previous subnet is replaced with a
-// doesn't exist anymore.
+// new subnet. The client should get the new lease and an old lease
+// with zero lifetimes in the Reply.
 TEST_F(RebindTest, directClientPDChangingSubnet) {
 TEST_F(RebindTest, directClientPDChangingSubnet) {
     Dhcp6Client client;
     Dhcp6Client client;
     // Configure client to request IA_PD.
     // 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
     // client's interface. Note that there will also be a new subnet
     // id assigned to the subnet on this interface.
     // id assigned to the subnet on this interface.
     configure(REBIND_CONFIGS[5], *client.getServer());
     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.
     // previous server configuration.
-    ASSERT_NO_THROW(client.doRebind());
+    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.
+    // We are expecting that the server has allocated a lease from the new
-    EXPECT_FALSE(client.getContext().response_)
+    // subnet and sent zero lifetimes for a previous lease.
-        << "The server responded to the Rebind message, while it should have"
+
-        " discarded it because there is no binding for the client.";
+    std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime();
-    // We are expecting that the server didn't extend the lease because
+    ASSERT_EQ(1, old_leases.size());
-    // the address that client is using doesn't match the new subnet.
+    EXPECT_EQ(lease_client.addr_, old_leases[0].addr_);
-    // But, the client still has an old lease.
+
-    ASSERT_EQ(1, client.getLeaseNum());
+    std::vector<Lease6> new_leases = client.getLeasesWithNonZeroLifetime();
-    Lease6 lease_client2 = client.getLease(0);
+    ASSERT_EQ(1, new_leases.size());
-    // The current lease should be exactly the same as old lease,
+
-    // because server shouldn't have extended.
-    EXPECT_TRUE(lease_client == lease_client2);
     // Make sure, that the lease that client has, is matching the lease
     // Make sure, that the lease that client has, is matching the lease
     // in the lease database.
     // in the lease database.
-    Lease6Ptr lease_server2 = checkLease(lease_client2);
+    Lease6Ptr lease_server2 = checkLease(new_leases[0]);
     EXPECT_TRUE(lease_server2);
     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
+// Check that the server allocates a new lease when the client sends IA_PD
-// IAID used in the Rebind is not matching the one recorded by the server
+// with a new IAID.
-// for the particular client.
 TEST_F(RebindTest, directClientPDChangingIAID) {
 TEST_F(RebindTest, directClientPDChangingIAID) {
     Dhcp6Client client;
     Dhcp6Client client;
     // Configure client to request IA_PD.
     // Configure client to request IA_PD.
@@ -690,24 +629,28 @@ TEST_F(RebindTest, directClientPDChangingIAID) {
     ASSERT_NO_FATAL_FAILURE(requestLease(REBIND_CONFIGS[4], 2, client));
     ASSERT_NO_FATAL_FAILURE(requestLease(REBIND_CONFIGS[4], 2, client));
     // Keep the client's lease for future reference.
     // Keep the client's lease for future reference.
     Lease6 lease_client = client.getLease(0);
     Lease6 lease_client = client.getLease(0);
+
     // Modify the IAID of the lease record that client stores. By adding
     // Modify the IAID of the lease record that client stores. By adding
     // one to IAID we guarantee that the IAID will change.
     // one to IAID we guarantee that the IAID will change.
-    ++client.config_.leases_[0].iaid_;
+    client.config_.leases_[0].iaid_ = 5679;
-    // Try to Rebind. Note that client will use a different IAID (which
+    client.usePD(true, 5679);
-    // is not matching IAID that server retains for the client). This is
+
-    // a condition described in RFC3633, section 12.2 as the server finds
+    // Try to Rebind. The server should allocate new lease for this IAID.
-    // 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.
     ASSERT_NO_THROW(client.doRebind());
     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.
+    // The old lease should be returned with 0 lifetimes.
-    EXPECT_FALSE(client.getContext().response_)
+    std::vector<Lease6> old_leases = client.getLeasesWithZeroLifetime();
-        << "The server responded to the Rebind message, while it should have"
+    ASSERT_EQ(1, old_leases.size());
-        " discarded it because there is no binding for the client.";
+    EXPECT_EQ(lease_client.addr_, old_leases[0].addr_);
-    // Check that server still has the same lease.
+
-    Lease6Ptr lease_server = checkLease(lease_client);
+    // The new lease should be allocated.
-    EXPECT_TRUE(lease_server);
+    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
 // Check that the prefix lifetime is not extended for the client when the
@@ -839,7 +782,7 @@ TEST_F(RebindTest, requestPrefixInRebind) {
     client.usePD();
     client.usePD();
 
 
     // Configure the server with NA pools only.
     // 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.
     // Perform 4-way exchange.
     ASSERT_NO_THROW(client.doSARR());
     ASSERT_NO_THROW(client.doSARR());
@@ -864,7 +807,7 @@ TEST_F(RebindTest, requestPrefixInRebind) {
     ASSERT_EQ(STATUS_NoPrefixAvail, client.getStatusCode(5678));
     ASSERT_EQ(STATUS_NoPrefixAvail, client.getStatusCode(5678));
 
 
     // Reconfigure the server to use both NA and PD pools.
     // 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.
     // Send Rebind message to the server, including IA_NA and requesting IA_PD.
     ASSERT_NO_THROW(client.doRebind());
     ASSERT_NO_THROW(client.doRebind());
@@ -894,7 +837,7 @@ TEST_F(RebindTest, requestAddressInRebind) {
     client.usePD();
     client.usePD();
 
 
     // Configure the server with PD pools only.
     // 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.
     // Perform 4-way exchange.
     ASSERT_NO_THROW(client.doSARR());
     ASSERT_NO_THROW(client.doSARR());
@@ -921,7 +864,7 @@ TEST_F(RebindTest, requestAddressInRebind) {
     ASSERT_EQ(STATUS_NoAddrsAvail, client.getStatusCode(1234));
     ASSERT_EQ(STATUS_NoAddrsAvail, client.getStatusCode(1234));
 
 
     // Reconfigure the server to use both NA and PD pools.
     // 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.
     // Send Rebind message to the server, including IA_PD and requesting IA_NA.
     ASSERT_NO_THROW(client.doRebind());
     ASSERT_NO_THROW(client.doRebind());
@@ -939,102 +882,5 @@ TEST_F(RebindTest, requestAddressInRebind) {
     EXPECT_EQ(STATUS_Success, client.getStatusCode(1234));
     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
 } // end of anonymous namespace

+ 0 - 189
src/bin/dhcp6/tests/renew_unittest.cc

@@ -44,23 +44,6 @@ namespace {
 ///   - address pool: 2001:db8:1::/64
 ///   - address pool: 2001:db8:1::/64
 ///   - prefix pool: 3000::/72
 ///   - 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[] = {
 const char* RENEW_CONFIGS[] = {
 // Configuration 0
 // Configuration 0
     "{ \"interfaces-config\": {"
     "{ \"interfaces-config\": {"
@@ -114,63 +97,6 @@ const char* RENEW_CONFIGS[] = {
         "    \"interface-id\": \"\","
         "    \"interface-id\": \"\","
         "    \"interface\": \"eth0\""
         "    \"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 }"
         "\"valid-lifetime\": 4000 }"
 };
 };
 
 
@@ -427,120 +353,5 @@ TEST_F(RenewTest, requestAddressInRenewHint) {
     EXPECT_EQ(STATUS_Success, client.getStatusCode(1234));
     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
 } // end of anonymous namespace

+ 3 - 16
src/lib/dhcpsrv/alloc_engine.cc

@@ -297,7 +297,7 @@ AllocEngine::ClientContext6::ClientContext6()
     : subnet_(), duid_(), iaid_(0), type_(Lease::TYPE_NA), hwaddr_(),
     : subnet_(), duid_(), iaid_(0), type_(Lease::TYPE_NA), hwaddr_(),
       hints_(), fwd_dns_update_(false), rev_dns_update_(false), hostname_(""),
       hints_(), fwd_dns_update_(false), rev_dns_update_(false), hostname_(""),
       callout_handle_(), fake_allocation_(false), old_leases_(), host_(),
       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,
 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_(),
     subnet_(subnet), duid_(duid), iaid_(iaid), type_(type), hwaddr_(),
     hints_(), fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns),
     hints_(), fwd_dns_update_(fwd_dns), rev_dns_update_(rev_dns),
     hostname_(hostname), fake_allocation_(fake_allocation),
     hostname_(hostname), fake_allocation_(fake_allocation),
-    old_leases_(), host_(), query_(), ia_rsp_(),
+    old_leases_(), host_(), query_(), ia_rsp_() {
-    allow_new_leases_in_renewals_(false) {
 
 
     static asiolink::IOAddress any("::");
     static asiolink::IOAddress any("::");
 
 
@@ -1093,18 +1092,6 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
         Lease6Collection leases = LeaseMgrFactory::instance()
         Lease6Collection leases = LeaseMgrFactory::instance()
             .getLeases6(ctx.type_, *ctx.duid_, ctx.iaid_, ctx.subnet_->getID());
             .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()) {
         if (!leases.empty()) {
             LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
             LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
                       ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED)
                       ALLOC_ENGINE_V6_RENEW_REMOVE_RESERVED)
@@ -1135,7 +1122,7 @@ AllocEngine::renewLeases6(ClientContext6& ctx) {
         // Depending on the configuration, we may enable or disable granting
         // Depending on the configuration, we may enable or disable granting
         // new leases during renewals. This is controlled with the
         // new leases during renewals. This is controlled with the
         // allow_new_leases_in_renewals_ field.
         // 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,
             LOG_DEBUG(alloc_engine_logger, ALLOC_ENGINE_DBG_TRACE,
                       ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED)
                       ALLOC_ENGINE_V6_EXTEND_ALLOC_UNRESERVED)

+ 0 - 12
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
         /// @brief A pointer to the IA_NA/IA_PD option to be sent in response
         Option6IAPtr ia_rsp_;
         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.
         /// @brief Default constructor.
         ClientContext6();
         ClientContext6();
 
 

+ 0 - 9
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
 This informational message signals that the specified client was assigned the prefix
 reserved for it.
 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
 % 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
 This debug message is issued when the allocation engine tries to
 allocate reserved leases for the client sending a Renew message.
 allocate reserved leases for the client sending a Renew message.

+ 0 - 2
src/lib/dhcpsrv/tests/alloc_engine_utils.cc

@@ -233,7 +233,6 @@ AllocEngine6Test::simpleAlloc6Test(const Pool6Ptr& pool, const IOAddress& hint,
 Lease6Collection
 Lease6Collection
 AllocEngine6Test::renewTest(AllocEngine& engine, const Pool6Ptr& pool,
 AllocEngine6Test::renewTest(AllocEngine& engine, const Pool6Ptr& pool,
                             AllocEngine::HintContainer& hints,
                             AllocEngine::HintContainer& hints,
-                            bool allow_new_leases_in_renewal,
                             bool in_pool) {
                             bool in_pool) {
 
 
     Lease::Type type = pool->getType();
     Lease::Type type = pool->getType();
@@ -243,7 +242,6 @@ AllocEngine6Test::renewTest(AllocEngine& engine, const Pool6Ptr& pool,
                                     type, false, false, "", false);
                                     type, false, false, "", false);
     ctx.hints_ = hints;
     ctx.hints_ = hints;
     ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 123));
     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));
     ctx.query_.reset(new Pkt6(DHCPV6_RENEW, 1234));
 
 
     findReservation(engine, ctx);
     findReservation(engine, ctx);

+ 0 - 3
src/lib/dhcpsrv/tests/alloc_engine_utils.h

@@ -246,13 +246,10 @@ public:
     /// @param engine a reference to Allocation Engine
     /// @param engine a reference to Allocation Engine
     /// @param pool pool from which the lease will be allocated from
     /// @param pool pool from which the lease will be allocated from
     /// @param hints address to be used as a hint
     /// @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
     /// @param in_pool specifies whether the lease is expected to be in pool
     /// @return allocated lease(s) (may be empty)
     /// @return allocated lease(s) (may be empty)
     Lease6Collection renewTest(AllocEngine& engine, const Pool6Ptr& pool,
     Lease6Collection renewTest(AllocEngine& engine, const Pool6Ptr& pool,
                                AllocEngine::HintContainer& hints,
                                AllocEngine::HintContainer& hints,
-                               bool allow_new_leases_in_renewal,
                                bool in_pool = true);
                                bool in_pool = true);
 
 
     /// @brief Checks if the address allocation with a hint that is in range,
     /// @brief Checks if the address allocation with a hint that is in range,