]> git.ipfire.org Git - thirdparty/kea.git/commitdiff
[3563] removeNonreservedLeases6 implemented
authorTomek Mrugalski <tomasz@isc.org>
Thu, 22 Jan 2015 21:50:50 +0000 (22:50 +0100)
committerTomek Mrugalski <tomasz@isc.org>
Thu, 22 Jan 2015 21:50:50 +0000 (22:50 +0100)
src/lib/dhcpsrv/alloc_engine.cc
src/lib/dhcpsrv/tests/alloc_engine_unittest.cc

index 0174a1c56e471933068c23a9b96a7a29fefef4be..30de4031606396935172ac8ea23c0c100742ca73 100644 (file)
@@ -692,7 +692,7 @@ AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx,
         ConstHostPtr host = HostMgr::instance().get6(ctx.subnet_->getID(),
                                                      (*candidate)->addr_);
 
-        if (!host && (host == ctx.host_)) {
+        if (!host || (host == ctx.host_)) {
             // Not reserved or reserved for us. That's ok, let's check
             // the next lease.
             continue;
@@ -701,9 +701,6 @@ AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx,
         // Ok, we have a problem. This host has a lease that is reserved
         // for someone else. We need to recover from this.
 
-        // Let's remove this candidate from existing leases
-        removeLeases(existing_leases, (*candidate)->addr_);
-
         // Remove this lease from LeaseMgr
         LeaseMgrFactory::instance().deleteLease((*candidate)->addr_);
 
@@ -711,6 +708,9 @@ AllocEngine::removeNonmatchingReservedLeases6(ClientContext6& ctx,
 
         // Add this to the list of removed leases.
         ctx.old_leases_.push_back(*candidate);
+
+        // Let's remove this candidate from existing leases
+        removeLeases(existing_leases, (*candidate)->addr_);
     }
 }
 
@@ -731,10 +731,45 @@ AllocEngine::removeLeases(Lease6Collection& container, const asiolink::IOAddress
 void
 AllocEngine::removeNonreservedLeases6(ClientContext6& ctx,
                                       Lease6Collection& existing_leases) {
-    /// @todo
-    if (!ctx.host_ || existing_leases.empty()) {
+    // This method removes leases that are not reserved for this host.
+    // It will keep at least one lease, though.
+    if (existing_leases.empty() || !ctx.host_ || !ctx.host_->hasIPv6Reservation()) {
         return;
     }
+
+    // This is the total number of leases. We should not remove the last one.
+    int total = existing_leases.size();
+
+    // This is tricky/scary code. It iterates and possibly deletes at the same time.
+    for (Lease6Collection::iterator lease = existing_leases.begin();
+         lease != existing_leases.end();) {
+        IPv6Resrv resv(ctx.type_ == Lease::TYPE_NA ? IPv6Resrv::TYPE_NA : IPv6Resrv::TYPE_PD,
+                       (*lease)->addr_, (*lease)->prefixlen_);
+        if (ctx.host_->hasReservation(resv)) {
+            // This is a lease for reserved address. Let's keep it.
+            ++lease;
+        } else {
+            // We have reservations, but not for this lease. Release it.
+
+            // Remove this lease from LeaseMgr
+            LeaseMgrFactory::instance().deleteLease((*lease)->addr_);
+
+            /// @todo: Probably trigger a hook here
+
+            // Add this to the list of removed leases.
+            ctx.old_leases_.push_back(*lease);
+
+            // This is tricky part. We move lease to the next element and
+            // then pass the old value to erase.
+            existing_leases.erase(lease++);
+
+            if (--total == 1) {
+                // If there's only one lease left, return.
+                return;
+            }
+        }
+
+    }
 }
 
 Lease4Ptr
index 2388c1e12948c7235aa72cf2f26fda7ab524c5c7..89d4b7d481a7bd7a9db7c24b441497941532fa03 100644 (file)
@@ -1372,7 +1372,7 @@ TEST_F(AllocEngine6Test, reservedAddressInPoolReassignedThis) {
 
     // Check that the reserved lease is in the database.
     Lease6Ptr from_mgr = LeaseMgrFactory::instance().getLease6(lease1->type_,
-                                                  IOAddress("2001:db8:1::c"));
+                                                  IOAddress("2001:db8:1::1c"));
 
     ASSERT_TRUE(from_mgr);