diff options
author | Francis Dupont <fdupont@isc.org> | 2020-11-12 10:52:12 +0100 |
---|---|---|
committer | Francis Dupont <fdupont@isc.org> | 2021-01-11 16:05:46 +0100 |
commit | 64dfcb35039949354efba53f10a35ecca6364bfc (patch) | |
tree | a5fa84bd64fe634eb1885cbd1747218a9b3350db /src | |
parent | [#1418] Checkpoint: preparation code done (diff) | |
download | kea-64dfcb35039949354efba53f10a35ecca6364bfc.tar.xz kea-64dfcb35039949354efba53f10a35ecca6364bfc.zip |
[#1418] Checkpoint: small improvements
Diffstat (limited to 'src')
-rw-r--r-- | src/bin/dhcp6/dhcp6_srv.cc | 12 | ||||
-rw-r--r-- | src/lib/dhcpsrv/alloc_engine.cc | 83 | ||||
-rw-r--r-- | src/lib/dhcpsrv/alloc_engine.h | 26 | ||||
-rw-r--r-- | src/lib/dhcpsrv/lease.cc | 7 | ||||
-rw-r--r-- | src/lib/dhcpsrv/lease.h | 8 |
5 files changed, 112 insertions, 24 deletions
diff --git a/src/bin/dhcp6/dhcp6_srv.cc b/src/bin/dhcp6/dhcp6_srv.cc index 656d291c04..cbae8670f3 100644 --- a/src/bin/dhcp6/dhcp6_srv.cc +++ b/src/bin/dhcp6/dhcp6_srv.cc @@ -2072,9 +2072,8 @@ Dhcpv6Srv::assignIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer, .arg(ia->getIAID()) .arg(Lease::lifetimeToText(lease->valid_lft_)); } else { - auto age = lease->valid_lft_ - lease->remaining_valid_lft_; lease->valid_lft_ = lease->remaining_valid_lft_; - lease->preferred_lft_ -= age; + lease->preferred_lft_ = lease->remaining_preferred_lft_; LOG_INFO(lease6_logger, DHCP6_LEASE_REUSE) .arg(query->getLabel()) .arg(lease->addr_.toText()) @@ -2198,9 +2197,8 @@ Dhcpv6Srv::assignIA_PD(const Pkt6Ptr& query, const Pkt6Ptr& /*answer*/, .arg(ia->getIAID()) .arg(Lease::lifetimeToText((*l)->valid_lft_)); } else { - auto age = (*l)->valid_lft_ - (*l)->remaining_valid_lft_; (*l)->valid_lft_ = (*l)->remaining_valid_lft_; - (*l)->preferred_lft_ -= age; + (*l)->preferred_lft_ = (*l)->remaining_preferred_lft_; LOG_INFO(lease6_logger, DHCP6_PD_LEASE_REUSE) .arg(query->getLabel()) .arg((*l)->addr_.toText()) @@ -2357,9 +2355,8 @@ Dhcpv6Srv::extendIA_NA(const Pkt6Ptr& query, const Pkt6Ptr& answer, .arg((*l)->addr_.toText()) .arg(ia->getIAID()); } else { - auto age = (*l)->valid_lft_ - (*l)->remaining_valid_lft_; (*l)->valid_lft_ = (*l)->remaining_valid_lft_; - (*l)->preferred_lft_ -= age; + (*l)->preferred_lft_ = (*l)->remaining_preferred_lft_; LOG_INFO(lease6_logger, DHCP6_LEASE_REUSE) .arg(query->getLabel()) .arg((*l)->addr_.toText()) @@ -2563,9 +2560,8 @@ Dhcpv6Srv::extendIA_PD(const Pkt6Ptr& query, .arg(static_cast<int>((*l)->prefixlen_)) .arg(ia->getIAID()); } else { - auto age = (*l)->valid_lft_ - (*l)->remaining_valid_lft_; (*l)->valid_lft_ = (*l)->remaining_valid_lft_; - (*l)->preferred_lft_ -= age; + (*l)->preferred_lft_ = (*l)->remaining_preferred_lft_; LOG_INFO(lease6_logger, DHCP6_PD_LEASE_REUSE) .arg(query->getLabel()) .arg((*l)->addr_.toText()) diff --git a/src/lib/dhcpsrv/alloc_engine.cc b/src/lib/dhcpsrv/alloc_engine.cc index 9718d10580..53b5456047 100644 --- a/src/lib/dhcpsrv/alloc_engine.cc +++ b/src/lib/dhcpsrv/alloc_engine.cc @@ -4362,25 +4362,29 @@ AllocEngine::updateLease6ExtendedInfo(const Lease6Ptr& lease, } void -AllocEngine::setLeaseRemainingLife(Lease& lease, const SubnetPtr& subnet) const { +AllocEngine::setLeaseRemainingLife(const Lease4Ptr& lease, + const ClientContext4& ctx) const { // Sanity. - lease.remaining_valid_lft_ = 0; + lease->remaining_valid_lft_ = 0; + const Subnet4Ptr& subnet = ctx.subnet_; if (!subnet) { return; } // Always reuse infinite lifetime leases. - if (lease.valid_lft_ == Lease::INFINITY_LFT) { - lease.remaining_valid_lft_ = Lease::INFINITY_LFT; + if (lease->valid_lft_ == Lease::INFINITY_LFT) { + lease->remaining_valid_lft_ = Lease::INFINITY_LFT; + return; } - // Refuse time going backward. - if (lease.cltt_ > lease.current_cltt_) { + // Refuse time not going forward. + if (lease->cltt_ >= lease->current_cltt_) { return; } - uint32_t age = lease.current_cltt_ - lease.cltt_; + + uint32_t age = lease->current_cltt_ - lease->cltt_; // Already expired. - if (age > lease.current_valid_lft_) { + if (age >= lease->current_valid_lft_) { return; } @@ -4399,14 +4403,73 @@ AllocEngine::setLeaseRemainingLife(Lease& lease, const SubnetPtr& subnet) const if ((threshold <= 0.) || (threshold > 1.)) { return; } - max_age = lease.valid_lft_ * threshold; + max_age = lease->valid_lft_ * threshold; if (age > max_age) { return; } } // Seems to be reusable. - lease.remaining_valid_lft_ = lease.current_cltt_ - age; + lease->remaining_valid_lft_ = lease->current_valid_lft_ - age; +} + +void +AllocEngine::setLeaseRemainingLife(const Lease6Ptr& lease, + const ClientContext6& ctx) const { + // Sanity. + lease->remaining_valid_lft_ = 0; + const Subnet6Ptr& subnet = ctx.subnet_; + if (!subnet) { + return; + } + + // Refuse time not going forward. + if (lease->cltt_ >= lease->current_cltt_) { + return; + } + + uint32_t age = lease->current_cltt_ - lease->cltt_; + // Already expired. + if (age >= lease->current_valid_lft_) { + return; + } + + // Try cache max age. + uint32_t max_age = 0; + if (!subnet->getCacheMaxAge().unspecified()) { + max_age = subnet->getCacheMaxAge().get(); + if ((max_age == 0) || (age > max_age)) { + return; + } + } + + // Try cache threshold. + if (!subnet->getCacheThreshold().unspecified()) { + double threshold = subnet->getCacheThreshold().get(); + if ((threshold <= 0.) || (threshold > 1.)) { + return; + } + max_age = lease->valid_lft_ * threshold; + if (age > max_age) { + return; + } + } + + // Seems to be reusable. + if ((lease->remaining_preferred_lft_ == Lease::INFINITY_LFT) || + (lease->remaining_preferred_lft_ == 0)) { + // Keep these values. + } else if (lease->remaining_preferred_lft_ > age) { + lease->remaining_preferred_lft_ -= age; + } else { + // Can be a misconfiguration so stay safe... + return; + } + if (lease->current_valid_lft_ == Lease::INFINITY_LFT) { + lease->remaining_valid_lft_ = Lease::INFINITY_LFT; + } else { + lease->remaining_valid_lft_ = lease->current_valid_lft_ - age; + } } } // namespace dhcp diff --git a/src/lib/dhcpsrv/alloc_engine.h b/src/lib/dhcpsrv/alloc_engine.h index de0046bcbe..6e1cdf903e 100644 --- a/src/lib/dhcpsrv/alloc_engine.h +++ b/src/lib/dhcpsrv/alloc_engine.h @@ -1858,9 +1858,31 @@ private: /// - the lease is not updated in the lease database. /// - the previous value of the lease can be returned to the client. /// - /// @param [in,out] lease The lease to be updated. + /// @param [in,out] lease A pointer to the lease to be updated. /// @param subnet A pointer to the lease subnet. - void setLeaseRemainingLife(Lease& lease, const SubnetPtr& subnet) const; + void setLeaseRemainingLife(const Lease4Ptr& lease, + const ClientContext4& ctx) const; + + /// @brief Try to reuse an already allocated lease. + /// + /// This function computes and sets when acceptable the remaining + /// valid lifetime of an already allocated lease. + /// This uses the cache-threshold and cache-max-age parameters. + /// + /// A not zero value for the remaining valid lifetime means the + /// lease can reuse i.e.: + /// - the lease is not updated in the lease database. + /// - the previous value of the lease can be returned to the client. + /// + /// @note: there is no current_preferred_lft_ field in the lease + /// so the remaining_preferred_lft_ is used too for this: + /// - it must be set to the previous preferred lifetime before call. + /// - after call it must be ignored if remaining valid lifetime is zero. + /// + /// @param [in,out] lease A pointer to the lease to be updated. + /// @param subnet A pointer to the lease subnet. + void setLeaseRemainingLife(const Lease6Ptr& lease, + const ClientContext6& ctx) const; private: diff --git a/src/lib/dhcpsrv/lease.cc b/src/lib/dhcpsrv/lease.cc index 3e7157a06e..a05b78ee48 100644 --- a/src/lib/dhcpsrv/lease.cc +++ b/src/lib/dhcpsrv/lease.cc @@ -489,7 +489,7 @@ Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr, SubnetID subnet_id, const HWAddrPtr& hwaddr, uint8_t prefixlen) : Lease(addr, valid, subnet_id, 0/*cltt*/, false, false, "", hwaddr), type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid), - preferred_lft_(preferred) { + preferred_lft_(preferred), remaining_preferred_lft_(0) { if (!duid) { isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease"); } @@ -506,7 +506,7 @@ Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr, : Lease(addr, valid, subnet_id, 0/*cltt*/, fqdn_fwd, fqdn_rev, hostname, hwaddr), type_(type), prefixlen_(prefixlen), iaid_(iaid), duid_(duid), - preferred_lft_(preferred) { + preferred_lft_(preferred), remaining_preferred_lft_(0) { if (!duid) { isc_throw(InvalidOperation, "DUID is mandatory for an IPv6 lease"); } @@ -518,7 +518,7 @@ Lease6::Lease6(Lease::Type type, const isc::asiolink::IOAddress& addr, Lease6::Lease6() : Lease(isc::asiolink::IOAddress("::"), 0, 0, 0, false, false, "", HWAddrPtr()), type_(TYPE_NA), prefixlen_(0), iaid_(0), - duid_(DuidPtr()), preferred_lft_(0) { + duid_(DuidPtr()), preferred_lft_(0), remaining_preferred_lft_(0) { } std::string @@ -621,6 +621,7 @@ Lease6::operator==(const Lease6& other) const { prefixlen_ == other.prefixlen_ && iaid_ == other.iaid_ && preferred_lft_ == other.preferred_lft_ && + remaining_preferred_lft_ == other.remaining_preferred_lft_ && valid_lft_ == other.valid_lft_ && current_valid_lft_ == other.current_valid_lft_ && remaining_valid_lft_ == other.remaining_valid_lft_ && diff --git a/src/lib/dhcpsrv/lease.h b/src/lib/dhcpsrv/lease.h index 48d81ca428..7def545356 100644 --- a/src/lib/dhcpsrv/lease.h +++ b/src/lib/dhcpsrv/lease.h @@ -521,12 +521,18 @@ struct Lease6 : public Lease { /// @brief Client identifier DuidPtr duid_; - /// @brief preferred lifetime + /// @brief Preferred lifetime /// /// This parameter specifies the preferred lifetime since the lease was /// assigned or renewed (cltt), expressed in seconds. uint32_t preferred_lft_; + /// @brief Remaining preferred lifetime + /// + /// Expressed as number of seconds since current time, also + /// preferred lifetime - age where age is old cltt - new cltt. + uint32_t remaining_preferred_lft_; + /// @todo: Add DHCPv6 failover related fields here /// @brief Constructor |