summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorFrancis Dupont <fdupont@isc.org>2020-11-12 10:52:12 +0100
committerFrancis Dupont <fdupont@isc.org>2021-01-11 16:05:46 +0100
commit64dfcb35039949354efba53f10a35ecca6364bfc (patch)
treea5fa84bd64fe634eb1885cbd1747218a9b3350db /src
parent[#1418] Checkpoint: preparation code done (diff)
downloadkea-64dfcb35039949354efba53f10a35ecca6364bfc.tar.xz
kea-64dfcb35039949354efba53f10a35ecca6364bfc.zip
[#1418] Checkpoint: small improvements
Diffstat (limited to 'src')
-rw-r--r--src/bin/dhcp6/dhcp6_srv.cc12
-rw-r--r--src/lib/dhcpsrv/alloc_engine.cc83
-rw-r--r--src/lib/dhcpsrv/alloc_engine.h26
-rw-r--r--src/lib/dhcpsrv/lease.cc7
-rw-r--r--src/lib/dhcpsrv/lease.h8
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