]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[v4_1_esv] Added abandon-lease-time parameter
authorThomas Markwalder <tmark@isc.org>
Thu, 7 Jul 2016 19:48:38 +0000 (15:48 -0400)
committerThomas Markwalder <tmark@isc.org>
Thu, 7 Jul 2016 19:48:38 +0000 (15:48 -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 5480b220cb5f167b81b507a9125a8f52285698fa..031f7cd919250276ce78cb68efcecfc1e6bb6a28 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -81,6 +81,12 @@ by Eric Young (eay@cryptsoft.com).
   a cut and paste error.
   [ISC-Bugs #42253]
 
+- 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.1-ESV-R13b1
 
 - None
index c4804f65d6eaada57d87d8a10197eaa77c6bad95..06c80a4059d0497492d59ede61c56bb9341b858a 100644 (file)
@@ -622,6 +622,7 @@ struct lease_state {
 #define SV_DELAYED_ACK                 58
 #define SV_MAX_ACK_DELAY               59
 #define SV_DHCPV6_SET_TEE_TIMES                60
+#define SV_ABANDON_LEASE_TIME          61
 
 #if !defined (DEFAULT_PING_TIMEOUT)
 # define DEFAULT_PING_TIMEOUT 1
@@ -663,6 +664,10 @@ struct lease_state {
 # define MIN_LEASE_WRITE 15
 #endif
 
+#if !defined (DEFAULT_ABANDON_LEASE_TIME)
+# define DEFAULT_ABANDON_LEASE_TIME 86400
+#endif
+
 /* Client option names */
 
 #define        CL_TIMEOUT              1
@@ -1683,6 +1688,7 @@ extern struct timeval cur_tv;
 
 extern int ddns_update_style;
 extern int authoring_byte_order;
+extern u_int32_t abandon_lease_time;
 
 extern const char *path_dhcpd_conf;
 extern const char *path_dhcpd_db;
index 94a80e4a7367697d1b7a68ae52e2909258f3df7d..5af25f473a8cf10b0ec9a7bbe9457255b9d0fa0e 100644 (file)
@@ -2863,7 +2863,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,
@@ -4155,8 +4156,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 8b3c78442ead715c00a974c19fbee38afe333c08..e4f8cf988f7e1fa8c50e04af2a83a94a452edc8e 100644 (file)
@@ -154,6 +154,7 @@ int ddns_update_style;
 #endif /* NSUPDATE */
 
 int authoring_byte_order = 0; /* 0 = not set */
+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;
@@ -1187,6 +1188,20 @@ void postconf_initialization (int quiet)
        }
 #endif
 
+       // 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);
+       }
+
        /* Don't need the options anymore. */
        option_state_dereference (&options, MDL);
        
index 63990a7dd0fd71b39573710efa623004875f3572..d065a81c5243889e4d34ee0ae6762e77f0a19f2a 100644 (file)
@@ -397,7 +397,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
@@ -1900,6 +1901,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
@@ -2649,7 +2671,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 2e3767fa5b9c334ee4a910f60c7ac890b71f6187..25610bf54cab15e1321abb7f4fec3ef80fc4f1ed 100644 (file)
@@ -1720,30 +1720,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)
        ddns_removals(lease, NULL);
 #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);
 }
 
 /* Abandon the specified lease (set its timeout to infinity and its
index 7dd979af639dbe25f33fc00e224d606516e91d86..d2bea4427452efb8f93950cc1458daf623935456 100644 (file)
@@ -239,6 +239,7 @@ static struct option server_options[] = {
        { "max-ack-delay", "L",                 &server_universe,  59, 1 },
 #endif
        { "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 }
 };