From: Tomek Mrugalski Date: Thu, 22 Jan 2015 21:50:50 +0000 (+0100) Subject: [3563] removeNonreservedLeases6 implemented X-Git-Tag: trac3712_base~21^2~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=e233de20fcf6a2ec6f0e25f3067693df565c67c1;p=thirdparty%2Fkea.git [3563] removeNonreservedLeases6 implemented --- diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 0174a1c56e..30de403160 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -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 diff --git a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc index 2388c1e129..89d4b7d481 100644 --- a/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc +++ b/src/lib/dhcpsrv/tests/alloc_engine_unittest.cc @@ -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);