From: Marcin Siodelski Date: Tue, 27 Jan 2015 19:50:32 +0000 (+0100) Subject: [3690] Tentative fix for allocating v4 address reserved to someone else. X-Git-Tag: trac3712_base~11^2~2 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=796ca1b18eb5686210ec9334767018b60ff88030;p=thirdparty%2Fkea.git [3690] Tentative fix for allocating v4 address reserved to someone else. --- diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 28677e98a8..e306eb76fb 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -611,47 +611,51 @@ AllocEngine::allocateLease4(const SubnetPtr& subnet, const ClientIdPtr& clientid const IOAddress& candidate = ctx.host_ ? ctx.host_->getIPv4Reservation() : ctx.requested_address_; - // Once we picked an address we want to allocate, we have to check - // if this address is available. - existing = LeaseMgrFactory::instance().getLease4(candidate); - if (!existing) { - // The candidate address is currently unused. Let's create a - // lease for it. - Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, - candidate, fwd_dns_update, - rev_dns_update, - hostname, callout_handle, - fake_allocation); - - // If we have allocated the lease let's return it. Also, - // always return when tried to allocate reserved address, - // regardless if allocation was successful or not. If it - // was not successful, we will return a NULL pointer which - // indicates to the server that it should send NAK to the - // client. - if (lease || ctx.host_) { - return (lease); - } - - // There is a lease for this address in the lease database but - // it is possible that the lease has expired, in which case - // we will be able to reuse it. - } else { - if (existing->expired()) { - // Save the old lease, before reusing it. - old_lease.reset(new Lease4(*existing)); - return (reuseExpiredLease(existing, ctx)); - - // The existing lease is not expired (is in use by some - // other client). If we are trying to get this lease because - // the address has been reserved for the client we have no - // choice but to return a NULL lease to indicate that the - // allocation has failed. - } else if (ctx.host_) { - return (Lease4Ptr()); + if (ctx.host_ || + (!ctx.host_ && !HostMgr::instance().get4(ctx.subnet_->getID(), + candidate))) { + // Once we picked an address we want to allocate, we have to check + // if this address is available. + existing = LeaseMgrFactory::instance().getLease4(candidate); + if (!existing) { + // The candidate address is currently unused. Let's create a + // lease for it. + Lease4Ptr lease = createLease4(subnet, clientid, hwaddr, + candidate, fwd_dns_update, + rev_dns_update, + hostname, callout_handle, + fake_allocation); + + // If we have allocated the lease let's return it. Also, + // always return when tried to allocate reserved address, + // regardless if allocation was successful or not. If it + // was not successful, we will return a NULL pointer which + // indicates to the server that it should send NAK to the + // client. + if (lease || ctx.host_) { + return (lease); + } + + // There is a lease for this address in the lease database but + // it is possible that the lease has expired, in which case + // we will be able to reuse it. + } else { + if (existing->expired()) { + // Save the old lease, before reusing it. + old_lease.reset(new Lease4(*existing)); + return (reuseExpiredLease(existing, ctx)); + + // The existing lease is not expired (is in use by some + // other client). If we are trying to get this lease because + // the address has been reserved for the client we have no + // choice but to return a NULL lease to indicate that the + // allocation has failed. + } else if (ctx.host_) { + return (Lease4Ptr()); + + } } - } }