]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Add abandon-lease-time parameter
authorThomas Markwalder <tmark@isc.org>
Thu, 7 Jul 2016 18:11:26 +0000 (14:11 -0400)
committerThomas Markwalder <tmark@isc.org>
Thu, 7 Jul 2016 18:11:26 +0000 (14:11 -0400)
    Merges in rt41815.

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

index 3d05131271d2b474a3dc2816aaebdd32d30ddcc1..352dd7f6897ce670848933d5525b753a87f4fef2 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -92,6 +92,12 @@ by Eric Young (eay@cryptsoft.com).
   are issues while cleaning up the A or AAAA records.
   [ISC-Bugs #23954]
 
+- Added global configuration parameter, abandon-lease-time, which determines
+  the amount of time a lease remains abandoned.  The default is 84600 seconds.
+  Additionaly, the server now conducts a ping check (if ping checks are
+  enabled) prior to offering an abandoned lease to client.
+  [ISC-Bugs #41815]
+
                        Changes since 4.3.4b1
 
 - None
index d149792842c48f7676e612060c22330a43c59003..261714dcc91bd7fe39a72a2e52e822a535c68fab 100644 (file)
@@ -798,6 +798,7 @@ struct lease_state {
 #define SV_SERVER_ID_CHECK             86
 #define SV_PREFIX_LEN_MODE             87
 #define SV_DHCPV6_SET_TEE_TIMES                88
+#define SV_ABANDON_LEASE_TIME          89
 
 #if !defined (DEFAULT_PING_TIMEOUT)
 # define DEFAULT_PING_TIMEOUT 1
@@ -846,6 +847,10 @@ struct lease_state {
 # define MIN_LEASE_WRITE 15
 #endif
 
+#if !defined (DEFAULT_ABANDON_LEASE_TIME)
+# define DEFAULT_ABANDON_LEASE_TIME 86400
+#endif
+
 #define PLM_IGNORE 0
 #define PLM_PREFER 1
 #define PLM_EXACT 2
@@ -2069,6 +2074,7 @@ extern int server_id_check;
 extern int prefix_length_mode;
 extern int authoring_byte_order;
 extern int lease_id_format;
+extern u_int32_t abandon_lease_time;
 
 extern const char *path_dhcpd_conf;
 extern const char *path_dhcpd_db;
index a823a4e834b75d5720f52470eea6f31abb664a25..55a67bfbd8cc6ea420d06f9754339390f86281c0 100644 (file)
@@ -3490,7 +3490,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
        /* If this is a DHCPOFFER, ping the lease address before actually
           sending the offer. */
        if (offer == DHCPOFFER && !(lease -> flags & STATIC_LEASE) &&
-           ((cur_time - lease_cltt) > 60) &&
+           (((cur_time - lease_cltt) > 60) ||
+             (lease->binding_state == FTS_ABANDONED)) &&
            (!(oc = lookup_option (&server_universe, state -> options,
                                   SV_PING_CHECKS)) ||
             evaluate_boolean_option_cache (&ignorep, packet, lease,
@@ -4871,8 +4872,11 @@ int allocate_lease (struct lease **lp, struct packet *packet,
                 * "no free leases" error when the last lease has been
                 * offered, but it's not exactly broken either.
                 */
-               if (!candl || (candl -> ends > cur_time))
+               if (!candl ||
+                   (candl->binding_state != FTS_ABANDONED &&
+                    (candl->ends > cur_time))) {
                        continue;
+               }
 
                if (!lease) {
                        lease = candl;
index a42d7591dffb70571d3b0f013da0b1a03c1d5b97..43642823a81c6cb9c7a1798d7dd2baeb09419999 100644 (file)
@@ -78,6 +78,7 @@ int prefix_length_mode = PLM_EXACT;
 
 int authoring_byte_order = 0; /* 0 = not set */
 int lease_id_format = TOKEN_OCTAL; /* octal by default */
+u_int32_t abandon_lease_time = DEFAULT_ABANDON_LEASE_TIME;
 
 const char *path_dhcpd_conf = _PATH_DHCPD_CONF;
 const char *path_dhcpd_db = _PATH_DHCPD_DB;
@@ -1241,6 +1242,20 @@ void postconf_initialization (int quiet)
                data_string_forget(&db, MDL);
        }
 
+       // Set global abandon-lease-time option.
+       oc = lookup_option (&server_universe, options, SV_ABANDON_LEASE_TIME);
+       if ((oc != NULL) &&
+           evaluate_option_cache(&db, NULL, NULL, NULL, options, NULL,
+                                 &global_scope, oc, MDL)) {
+               if (db.len == sizeof (u_int32_t)) {
+                       abandon_lease_time = getULong (db.data);
+               } else {
+                       log_fatal("invalid abandon-lease-time");
+               }
+
+               data_string_forget (&db, MDL);
+        }
+
 #if defined (BINARY_LEASES)
        if (local_family == AF_INET) {
                log_info("Source compiled to use binary-leases");
index 9c99676d10a43b500c319c3204dc7d89bb22956d..a053ef14e7804261635acf35c0a722e794a9c28d 100644 (file)
@@ -405,7 +405,8 @@ the lease as in use.
 If a response is received to an ICMP Echo request, the DHCP server
 assumes that there is a configuration error - the IP address is in use
 by some host on the network that is not a DHCP client.  It marks the
-address as abandoned, and will not assign it to clients.
+address as abandoned, and will not assign it to clients. The lease will
+remain abandoned for a minimum of abandon-lease-time seconds.
 .PP
 If a DHCP client tries to get an IP address, but none are available,
 but there are abandoned IP addresses, then the DHCP server will
@@ -1882,6 +1883,27 @@ min-lease-time allows for a gradual change.
 e.g. 4 2007/08/24 11:14:32 -7200
 .SH REFERENCE: PARAMETERS
 The
+.I abandon-lease-time
+statement
+.RS 0.25i
+.PP
+.B adandon-lease-time \fItime\fR\fB;\fR
+.PP
+.I Time
+should be the maximum amount of time (in seconds) that an abandoned IPv4 lease
+remains unavailable for assignment to a client.  Abandoned leases will only be
+offered to clients if there are no free leases.  If not defined, the default
+abandon lease time is 86400 seconds (24 hours).  Note the abandoned lease time
+for a given lease is preserved across server restarts.  The parameter may only
+be set at the global scope and is evaluated only once during server startup.
+.PP
+Values less than sixty seconds are not recommended as this is below the ping
+check threshold and can cause leases once abandoned but since returned to the
+free state to not be pinged before being offered.  If the requested time is
+larger than 0x7FFFFFFF - 1 or the sum of the current time plus the abandoned time isgreater than 0x7FFFFFFF it is treated as infinite.
+.RE
+.PP
+The
 .I adaptive-lease-time-threshold
 statement
 .RS 0.25i
@@ -2802,7 +2824,12 @@ address to a client, it first sends an ICMP Echo request (a \fIping\fR)
 to the address being assigned.  It waits for a second, and if no
 ICMP Echo response has been heard, it assigns the address.  If a
 response \fIis\fR heard, the lease is abandoned, and the server does
-not respond to the client.
+not respond to the client.  The lease will remain abandoned for a minimum
+of abandon-lease-time seconds.
+.PP
+If a there are no free addressses but there are abandoned IP addresses, the
+DHCP server will attempt to reclaim an abandoned IP address regardless of the
+value of abandon-lease-time.
 .PP
 This \fIping check\fR introduces a default one-second delay in responding
 to DHCPDISCOVER messages, which can be a problem for some clients.  The
index 48947c5132decd9bddea5bc6a9e0f81689f2c823..6af6b631ed515f0ea8ef6692dff2fd57822badec 100644 (file)
@@ -1808,30 +1808,40 @@ void abandon_lease (lease, message)
        struct lease *lease;
        const char *message;
 {
-       struct lease *lt = (struct lease *)0;
+       struct lease *lt = NULL;
 #if defined (NSUPDATE)
        (void) ddns_removals(lease, NULL, NULL, ISC_FALSE);
 #endif
 
-       if (!lease_copy (&lt, lease, MDL))
+       if (!lease_copy(&lt, lease, MDL)) {
                return;
+       }
 
-       if (lt->scope)
+       if (lt->scope) {
                binding_scope_dereference(&lt->scope, MDL);
+       }
 
-       lt -> ends = cur_time; /* XXX */
-       lt -> next_binding_state = FTS_ABANDONED;
+       /* Calculate the abandone expiry time.  If it wraps,
+        * use the maximum expiry time. */
+       lt->ends = cur_time + abandon_lease_time;
+       if (lt->ends < cur_time || lt->ends > MAX_TIME) {
+               lt->ends = MAX_TIME;
+       }
 
-       log_error ("Abandoning IP address %s: %s",
-             piaddr (lease -> ip_addr), message);
-       lt -> hardware_addr.hlen = 0;
-       if (lt -> uid && lt -> uid != lt -> uid_buf)
-               dfree (lt -> uid, MDL);
-       lt -> uid = (unsigned char *)0;
-       lt -> uid_len = 0;
-       lt -> uid_max = 0;
-       supersede_lease (lease, lt, 1, 1, 1, 0);
-       lease_dereference (&lt, MDL);
+       lt->next_binding_state = FTS_ABANDONED;
+
+       log_error ("Abandoning IP address %s: %s", piaddr(lease->ip_addr),
+                    message);
+       lt->hardware_addr.hlen = 0;
+       if (lt->uid && lt->uid != lt->uid_buf) {
+               dfree(lt->uid, MDL);
+       }
+
+       lt->uid = NULL;
+       lt->uid_len = 0;
+       lt->uid_max = 0;
+       supersede_lease(lease, lt, 1, 1, 1, 0);
+       lease_dereference(&lt, MDL);
 }
 
 #if 0
index 3a83acbe9e8a16ff4a507c94accf933078126288..445ef0fd971d6ffdcd40a047dd3d2a6b6acd149b 100644 (file)
@@ -276,6 +276,7 @@ static struct option server_options[] = {
        { "server-id-check", "f",               &server_universe,  SV_SERVER_ID_CHECK, 1 },
        { "prefix-length-mode", "Nprefix_length_modes.",        &server_universe,  SV_PREFIX_LEN_MODE, 1 },
        { "dhcpv6-set-tee-times", "f",          &server_universe,  SV_DHCPV6_SET_TEE_TIMES, 1 },
+       { "abandon-lease-time", "T",            &server_universe,  SV_ABANDON_LEASE_TIME, 1 },
        { NULL, NULL, NULL, 0, 0 }
 };