mirror of
https://gitlab.isc.org/isc-projects/dhcp
synced 2025-08-31 14:25:41 +00:00
- If a client renews before 'dhcp-cache-threshold' percent of its lease
has elapsed (default 25%), the server will reuse the allocated lease (provide a lease within the currently allocated lease-time) rather than extend or renew the lease. This absolves the server of needing to perform an fsync() operation on the lease database before reply, which improves performance. [ISC-Bugs #22228]
This commit is contained in:
@@ -1502,6 +1502,10 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
struct in_addr from;
|
||||
TIME remaining_time;
|
||||
struct iaddr cip;
|
||||
#if defined(DELAYED_ACK)
|
||||
isc_boolean_t enqueue = ISC_TRUE;
|
||||
#endif
|
||||
int use_old_lease = 0;
|
||||
|
||||
unsigned i, j;
|
||||
int s1;
|
||||
@@ -2445,6 +2449,48 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
packet -> raw -> chaddr,
|
||||
sizeof packet -> raw -> chaddr); /* XXX */
|
||||
} else {
|
||||
int commit = (!offer || (offer == DHCPACK));
|
||||
int thresh = DEFAULT_CACHE_THRESHOLD;
|
||||
|
||||
/*
|
||||
* Check if the lease was issued recently, if so replay the
|
||||
* current lease and do not require a database sync event.
|
||||
* Recently is defined as being issued less than a given
|
||||
* percentage of the lease previously. The percentage can be
|
||||
* chosen either from a default value or via configuration.
|
||||
*
|
||||
*/
|
||||
if ((oc = lookup_option(&server_universe, state->options,
|
||||
SV_CACHE_THRESHOLD)) &&
|
||||
evaluate_option_cache(&d1, packet, lt, NULL,
|
||||
packet->options, state->options,
|
||||
<->scope, oc, MDL)) {
|
||||
if (d1.len == 1 &&
|
||||
(d1.data[0] >= 0) && (d1.data[0] < 100))
|
||||
thresh = d1.data[0];
|
||||
|
||||
data_string_forget(&d1, MDL);
|
||||
}
|
||||
|
||||
if ((thresh > 0) && (offer == DHCPACK) &&
|
||||
(lease->binding_state == FTS_ACTIVE)) {
|
||||
int limit;
|
||||
int prev_lease = lease->ends - lease->starts;
|
||||
|
||||
/* it is better to avoid division by 0 */
|
||||
if (prev_lease <= (INT_MAX / thresh))
|
||||
limit = prev_lease * thresh / 100;
|
||||
else
|
||||
limit = prev_lease / 100 * thresh;
|
||||
|
||||
if ((lt->starts - lease->starts) <= limit) {
|
||||
lt->starts = lease->starts;
|
||||
state->offered_expiry = lt->ends = lease->ends;
|
||||
commit = 0;
|
||||
use_old_lease = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(DELAYED_ACK)
|
||||
/* Install the new information on 'lt' onto the lease at
|
||||
* 'lease'. If this is a DHCPOFFER, it is a 'soft' promise,
|
||||
@@ -2454,9 +2500,19 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
* the same lease to another client later, and that would be
|
||||
* a conflict.
|
||||
*/
|
||||
if (!supersede_lease(lease, lt, !offer || (offer == DHCPACK),
|
||||
if (!use_old_lease && !supersede_lease(lease, lt, commit,
|
||||
offer == DHCPACK, offer == DHCPACK)) {
|
||||
#else /* defined(DELAYED_ACK) */
|
||||
/*
|
||||
* If there already isn't a need for a lease commit, and we
|
||||
* can just answer right away, set a flag to indicate this.
|
||||
*/
|
||||
if (commit && !(lease->flags & STATIC_LEASE) &&
|
||||
(!offer || (offer == DHCPACK)))
|
||||
enqueue = ISC_TRUE;
|
||||
else
|
||||
enqueue = ISC_FALSE;
|
||||
|
||||
/* Install the new information on 'lt' onto the lease at
|
||||
* 'lease'. We will not 'commit' this information to disk
|
||||
* yet (fsync()), we will 'propogate' the information if
|
||||
@@ -2865,8 +2921,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
|
||||
} else {
|
||||
lease->cltt = cur_time;
|
||||
#if defined(DELAYED_ACK)
|
||||
if (!(lease->flags & STATIC_LEASE) &&
|
||||
(!offer || (offer == DHCPACK)))
|
||||
if (enqueue)
|
||||
delayed_ack_enqueue(lease);
|
||||
else
|
||||
#endif
|
||||
|
Reference in New Issue
Block a user