Commit 95cc8210 authored by Tomek Mrugalski's avatar Tomek Mrugalski 🛰
Browse files

[2327] Reuse of expired leases implemented.

parent a7e16e85
......@@ -44,8 +44,10 @@ AllocEngine::IterativeAllocator::increaseAddress(const isc::asiolink::IOAddress&
len = 16;
}
// Start increasing the least significant byte
for (int i = len - 1; i >= 0; --i) {
++packed[i];
// if we haven't overflowed (0xff -> 0x0), than we are done
if (packed[i] != 0) {
break;
}
......@@ -197,6 +199,12 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
if (lease) {
return (lease);
}
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation));
}
}
}
......@@ -220,6 +228,11 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
// Although the address was free just microseconds ago, it may have
// been taken just now. If the lease insertion fails, we continue
// allocation attempts.
} else {
if (existing->expired()) {
return (reuseExpiredLease(existing, subnet, duid, iaid,
fake_allocation));
}
}
// continue trying allocation until we run out of attempts
......@@ -231,6 +244,46 @@ AllocEngine::allocateAddress6(const Subnet6Ptr& subnet,
<< " tries");
}
Lease6Ptr AllocEngine::reuseExpiredLease(Lease6Ptr& expired,
const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
bool fake_allocation /*= false */ ) {
if (!expired->expired()) {
isc_throw(BadValue, "Attempt to recycle lease that is still valid");
}
// address, lease type and prefixlen (0) stay the same
expired->iaid_ = iaid;
expired->duid_ = duid;
expired->preferred_lft_ = subnet->getPreferred();
expired->valid_lft_ = subnet->getValid();
expired->t1_ = subnet->getT1();
expired->t2_ = subnet->getT2();
expired->cltt_ = time(NULL);
expired->subnet_id_ = subnet->getID();
expired->fixed_ = false;
expired->hostname_ = std::string("");
expired->fqdn_fwd_ = false;
expired->fqdn_rev_ = false;
/// @todo: log here that the lease was reused (there's ticket #2524 for
/// logging in libdhcpsrv)
if (!fake_allocation) {
// for REQUEST we do update the lease
LeaseMgrFactory::instance().updateLease6(expired);
}
// We do nothing for SOLICIT. We'll just update database when
// the client gets back to us with REQUEST message.
// it's not really expired at this stage anymore - let's return it as
// an updated lease
return (expired);
}
Lease6Ptr AllocEngine::createLease(const Subnet6Ptr& subnet,
const DuidPtr& duid,
uint32_t iaid,
......
......@@ -216,6 +216,24 @@ private:
uint32_t iaid, const isc::asiolink::IOAddress& addr,
bool fake_allocation = false);
/// @brief reuses expired lease
///
/// Updates existing expired lease with new information. Lease database
/// is updated if this is real (i.e. REQUEST, fake_allocation = false), not
/// dummy allocation request (i.e. SOLICIT, fake_allocation = true).
///
/// @param expired old, expired lease
/// @param subnet subnet the lease is allocated from
/// @param duid client's DUID
/// @param iaid IAID from the IA_NA container the client sent to us
/// @param fake_allocation is this real i.e. REQUEST (false) or just picking
/// an address for SOLICIT that is not really allocated (true)
/// @return refreshed lease
/// @throw BadValue if trying to recycle lease that is still valid
Lease6Ptr reuseExpiredLease(Lease6Ptr& expired, const Subnet6Ptr& subnet,
const DuidPtr& duid, uint32_t iaid,
bool fake_allocation = false);
/// @brief a pointer to currently used allocator
boost::shared_ptr<Allocator> allocator_;
......
......@@ -46,6 +46,14 @@ Lease6::Lease6(LeaseType type, const isc::asiolink::IOAddress& addr,
cltt_ = time(NULL);
}
bool Lease6::expired() const {
// Let's use int64 to avoid problems with negative/large uint32 values
int64_t expire_time = cltt_ + valid_lft_;
return (expire_time < time(NULL));
}
std::string LeaseMgr::getParameter(const std::string& name) const {
ParameterMap::const_iterator param = parameters_.find(name);
if (param == parameters_.end()) {
......
......@@ -379,6 +379,10 @@ struct Lease6 {
/// @return String form of the lease
std::string toText();
/// @brief returns true if the lease is expired
/// @return true if the lease is expired
bool expired() const;
/// @brief Compare two leases for equality
///
/// @param other lease6 object with which to compare
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment