Adaptive Lease Time patch for ISC DHCPD 3.0.3

The following patch (now with fancy configuration options) modifies dhcp.c so, that once a pool reaches “adaptive-lease-time-threshold %” active leases, the server hands out only short min_lease_time leases - until the allocation drop down under the threshold, when it reverts back to default_lease_time.

Update: As of ISC DHCPD 3.0.6 this patch is now part of the main distribution.

diff -rc dhcp-3.0.3/includes/dhcpd.h dhcp-3.0.3-cc/includes/dhcpd.h
*** dhcp-3.0.3/includes/dhcpd.h Sat Apr 30 01:10:57 2005
--- dhcp-3.0.3-cc/includes/dhcpd.h      Tue Sep 13 13:42:24 2005
***************
*** 411,416 ****
--- 411,418 ----
  #define SV_LOG_FACILITY                       44
  #define SV_DO_FORWARD_UPDATES         45
  #define SV_PING_TIMEOUT         46
+ #define SV_ADAPTIVE_LEASE_TIME_THRESHOLD      47
+ #define SV_UPDATE_CONFLICT_DETECTION    48
 
  #if !defined (DEFAULT_PING_TIMEOUT)
  # define DEFAULT_PING_TIMEOUT 1
diff -rc dhcp-3.0.3/server/dhcp.c dhcp-3.0.3-cc/server/dhcp.c
*** dhcp-3.0.3/server/dhcp.c    Sat Apr 30 01:10:57 2005
--- dhcp-3.0.3-cc/server/dhcp.c Tue Sep 13 14:42:36 2005
***************
*** 1508,1513 ****
--- 1508,1514 ----
        int s1, s2;
        int val;
        int ignorep;
+       int poolfilled;
 
        /* If we're already acking this lease, don't do it again. */
        if (lease -> state)
***************
*** 2001,2006 ****
--- 2002,2050 ----
                        }
                }
 
+               /* CC: If there are less than
+                  adaptive-lease-time-threshold % free leases,
+                    hand out only short term leases */
+
+               memset (&d1, 0, sizeof d1);
+               if (lease -> pool &&
+                   (oc = lookup_option (&server_universe, state -> options,
+                               SV_ADAPTIVE_LEASE_TIME_THRESHOLD)) &&
+                   evaluate_option_cache (&d1, packet, lease,
+                                          (struct client_state *)0,
+                                          packet -> options,
+                                          state -> options,
+                                          &lease -> scope, oc, MDL)) {
+                   if (d1.len && d1.data [0] > 0 && d1.data [0] < 100) {
+                        poolfilled = ((lease -> pool -> lease_count -
+                               lease -> pool -> free_leases) * 100 ) /
+                               lease -> pool -> lease_count;
+                        log_info ("Adap-lease: %s%d, %s%d, %s%d, %s%d, %s%d",
+                               "Total: ", lease -> pool -> lease_count,
+                               "Free: ", lease -> pool -> free_leases,
+                               "Ends: ", (int) (lease -> ends - cur_time),
+                               "Fill: ",poolfilled,
+                               "Threshold: ",d1.data [0]);
+
+                       if (poolfilled >= d1.data [0]) {
+                          /* CC: if the client has a long lease already,
+                             do not cut the running lease beyond what we
+                               already committed. */
+                          if (lease -> ends - cur_time > min_lease_time)
+                                  min_lease_time = lease -> ends - cur_time;
+                          if (lease_time > min_lease_time) {
+                                 log_info ("Pool over %s %s from %d to %d",
+                                     "threshold, reduce lease time for",
+                                               piaddr (lease -> ip_addr),
+                                                       (int) lease_time,
+                                               (int) min_lease_time);
+                                  lease_time = min_lease_time;
+                          }
+                       }
+                   }
+                   data_string_forget (&d1, MDL);
+               }
+
                if (lease_time < min_lease_time) {
                        if (min_lease_time)
                                lease_time = min_lease_time;
diff -rc dhcp-3.0.3/server/dhcpd.conf.5 dhcp-3.0.3-cc/server/dhcpd.conf.5
*** dhcp-3.0.3/server/dhcpd.conf.5      Tue May  3 00:43:24 2005
--- dhcp-3.0.3-cc/server/dhcpd.conf.5   Tue Sep 13 14:24:36 2005
***************
*** 1629,1634 ****
--- 1629,1653 ----
  obtain new addresses immediately when they next renew.
  .SH REFERENCE: PARAMETERS
  The
+ .I adaptive-lease-time-threshold
+ statement
+ .RS 0.25i
+ .PP
+ .B adaptive-lease-time-threshold \fIpercentage\fR\fB;\fR
+ .PP
+ When the number of allocated leases within a pool rises above the \fIpercentage\fR
+ given in this statement, the DHCP server decreases the lease lenght for
+ new clients within this pool to \fImin-lease-time\fR seconds. Clients renewing
+ an already valid (long) leases get at least the remaining time from the
+ current lease. Since the leases expire faster,
+ the server may either recover more quickly
+ or avoid pool exhaustion entirely.
+ Once the number of allocated leases drop below the
+ threshold, the server reverts back to normal lease times.
+ Valid percentages are between 1 and 99.
+ .RE
+ .PP
+ The
  .I always-broadcast
  statement
  .RS 0.25i
diff -rc dhcp-3.0.3/server/stables.c dhcp-3.0.3-cc/server/stables.c
*** dhcp-3.0.3/server/stables.c Thu Jun 10 19:59:58 2004
--- dhcp-3.0.3-cc/server/stables.c      Tue Sep 13 11:42:49 2005
***************
*** 483,490 ****
        { "log-facility", "Nsyslog-facilities.",        &server_universe, 44 },
        { "do-forward-updates", "f",                    &server_universe, 45 },
        { "ping-timeout", "T",                          &server_universe, 46 },
!       { "unknown-47", "X",                            &server_universe, 47 },
!       { "unknown-48", "X",                            &server_universe, 48 },
        { "unknown-49", "X",                            &server_universe, 49 },
        { "unknown-50", "X",                            &server_universe, 50 },
        { "unknown-51", "X",                            &server_universe, 51 },
--- 483,490 ----
        { "log-facility", "Nsyslog-facilities.",        &server_universe, 44 },
        { "do-forward-updates", "f",                    &server_universe, 45 },
        { "ping-timeout", "T",                          &server_universe, 46 },
!       { "adaptive-lease-time-threshold", "B",         &server_universe, 47 },
!       { "update-conflict-detection", "f",             &server_universe, 48 },
        { "unknown-49", "X",                            &server_universe, 49 },
        { "unknown-50", "X",                            &server_universe, 50 },
        { "unknown-51", "X",                            &server_universe, 51 },
Copyright © 2024 Christof Chen