]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
- If a client renews before 'dhcp-cache-threshold' percent of its lease
authorTomek Mrugalski <tomek@isc.org>
Thu, 12 May 2011 14:01:15 +0000 (14:01 +0000)
committerTomek Mrugalski <tomek@isc.org>
Thu, 12 May 2011 14:01:15 +0000 (14:01 +0000)
  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]

RELNOTES
includes/dhcpd.h
server/dhcp.c
server/dhcpd.conf.5
server/stables.c

index fde0124f1de11c725be273c0a027b8aae6ad4e08..9ae00bb27184481709fa46b95f0db8ad28978e1f 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -132,6 +132,13 @@ work on other platforms. Please report any problems and suggested fixes to
 
 - Compilation problem with gcc4.5 and omshell.c resolved. [ISC-Bugs #23831]
 
+- 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]
+
                        Changes since 4.2.1rc1
 
 - None
@@ -160,7 +167,6 @@ work on other platforms. Please report any problems and suggested fixes to
 - Modify the dlpi code to accept getmsg() returning a positive value.
   [ISC-Bugs #22824]
 
-
                        Changes since 4.2.0
 
 - 'get-host-names true;' now also works even if 'use-host-decl-names true;'
index 1ec7305ed3e2908539502dc2a76a83a2250b6765..29aa1e9fef1f95a2dafd353d86877aa922fe1859 100644 (file)
@@ -691,6 +691,29 @@ struct lease_state {
 #define SV_LIMIT_PREFS_PER_IA          57
 #define SV_DELAYED_ACK                 58
 #define SV_MAX_ACK_DELAY               59
+#if defined(LDAP_CONFIGURATION)
+# define SV_LDAP_SERVER                 60
+# define SV_LDAP_PORT                   61
+# define SV_LDAP_USERNAME               62
+# define SV_LDAP_PASSWORD               63
+# define SV_LDAP_BASE_DN                64
+# define SV_LDAP_METHOD                 65
+# define SV_LDAP_DEBUG_FILE             66
+# define SV_LDAP_DHCP_SERVER_CN         67
+# define SV_LDAP_REFERRALS              68
+#if defined (LDAP_USE_SSL)
+# define SV_LDAP_SSL                    69
+# define SV_LDAP_TLS_REQCERT            70
+# define SV_LDAP_TLS_CA_FILE            71
+# define SV_LDAP_TLS_CA_DIR             72
+# define SV_LDAP_TLS_CERT               73
+# define SV_LDAP_TLS_KEY                74
+# define SV_LDAP_TLS_CRLCHECK           75
+# define SV_LDAP_TLS_CIPHERS            76
+# define SV_LDAP_TLS_RANDFILE           77
+#endif
+#endif
+#define SV_CACHE_THRESHOLD             78
 
 #if !defined (DEFAULT_PING_TIMEOUT)
 # define DEFAULT_PING_TIMEOUT 1
@@ -712,27 +735,8 @@ struct lease_state {
 # define DEFAULT_MIN_ACK_DELAY_USECS 10000 /* 1/100 second */
 #endif
 
-#if defined(LDAP_CONFIGURATION)
-# define SV_LDAP_SERVER                        60
-# define SV_LDAP_PORT                  61
-# define SV_LDAP_USERNAME              62
-# define SV_LDAP_PASSWORD              63
-# define SV_LDAP_BASE_DN               64
-# define SV_LDAP_METHOD                        65
-# define SV_LDAP_DEBUG_FILE            66
-# define SV_LDAP_DHCP_SERVER_CN                67
-# define SV_LDAP_REFERRALS             68
-#if defined (LDAP_USE_SSL)
-# define SV_LDAP_SSL                   69
-# define SV_LDAP_TLS_REQCERT           70
-# define SV_LDAP_TLS_CA_FILE           71
-# define SV_LDAP_TLS_CA_DIR            72
-# define SV_LDAP_TLS_CERT              73
-# define SV_LDAP_TLS_KEY               74
-# define SV_LDAP_TLS_CRLCHECK          75
-# define SV_LDAP_TLS_CIPHERS           76
-# define SV_LDAP_TLS_RANDFILE          77
-#endif
+#if !defined (DEFAULT_CACHE_THRESHOLD)
+# define DEFAULT_CACHE_THRESHOLD 25
 #endif
 
 #if !defined (DEFAULT_DEFAULT_LEASE_TIME)
index cce0951f3a75c7b64dd0aed49f9ef439c7ab38b1..3ca61912ba5778ab4a86509ebd5b245a5e6ec57a 100644 (file)
@@ -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,
+                                         &lt->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
index 2b3796f21b91276eb03dfe41589ef1c5758f2986..f6004c991b521439b7899c27e1e58cbfa7edb4e8 100644 (file)
@@ -27,7 +27,7 @@
 .\" Support and other services are available for ISC products - see
 .\" https://www.isc.org for more information or to learn more about ISC.
 .\"
-.\" $Id: dhcpd.conf.5,v 1.106.18.3 2011/04/25 23:49:52 sar Exp $
+.\" $Id: dhcpd.conf.5,v 1.106.18.4 2011/05/12 14:01:15 tomasz Exp $
 .\"
 .TH dhcpd.conf 5
 .SH NAME
@@ -2158,6 +2158,30 @@ feature is not compiled in by default, but must be enabled at compile time
 with \'./configure --enable-delayed-ack\'.
 .RE
 .PP
+The 
+.I dhcp-cache-threshold 
+statement
+.RS 0.25i
+.PP
+.B dhcp-cache-threshold \fIpercentage\fB;\fR
+.PP
+The \fIdhcp-cache-threshold\fR statement takes one integer parameter
+with allowed values between 0 and 100. The default value is 25 (25% of
+the lease time). This parameter expresses the percentage of the total
+lease time, measured from the beginning, during which a
+client's attempt to renew its lease will result in getting
+the already assigned lease, rather than an extended lease.
+.PP
+Clients that attempt renewal frequently can cause the server to
+update and write the database frequently resulting in a performance
+impact on the server.  The \fIdhcp-cache-threshold\fR
+statement instructs the DHCP server to avoid updating leases too
+frequently thus avoiding this behavior.  Instead the server assigns the
+same lease with no modifications except for CLTT (Client Last
+Transmission Time) which does not require disk operations. This
+feature applies to IPv4 only.
+.RE
+.PP
 The
 .I do-forward-updates
 statement
index 82945277475144446769d428ff5a57bb481b9ff5..a8e499890830d4733bab7c7e32170e93811ae9e8 100644 (file)
@@ -266,6 +266,7 @@ static struct option server_options[] = {
        { "ldap-tls-randfile", "t",             &server_universe,  77, 1 },
 #endif /* LDAP_USE_SSL */
 #endif /* LDAP_CONFIGURATION */
+       { "dhcp-cache-threshold", "B",          &server_universe,  78, 1 },
        { NULL, NULL, NULL, 0, 0 }
 };