]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Correct the dhcp-cache-threshold codes treatment of hostname
authorShawn Routhier <sar@isc.org>
Tue, 26 Jul 2016 18:41:47 +0000 (11:41 -0700)
committerShawn Routhier <sar@isc.org>
Tue, 26 Jul 2016 18:41:47 +0000 (11:41 -0700)
If a lease is reused as part of dhcp-cache-threshold processing
the hostname (if it exists) needs to be copied from the temporary
lease back to the permanent lease.

Also add additional checks to see if the lease can be reused.
The host pointer, client ID and hardware address shouldn't have
changed.

RELNOTES
server/dhcp.c
server/dhcpd.conf.5

index 2ddd24320526006bd7e0c92984a1a9d72075ea89..41f6def63918a457319299f58a540c2b2986db75 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -110,6 +110,11 @@ by Eric Young (eay@cryptsoft.com).
   output.
   [ISC-Bugs #42113]
 
+- When reusing a lease for dhcp-cache-threshold return the hostname
+  to the original lease.  Also if the host pointer, UID or hardware address
+  change don't allow reuse of the lease.
+  [ISC-Bugs #42849]
+
                        Changes since 4.3.4b1
 
 - None
index 55a67bfbd8cc6ea420d06f9754339390f86281c0..915d1b1aab73db7adb5b89e63409c394b8ed827d 100644 (file)
@@ -3062,6 +3062,8 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
                        lt -> client_hostname [d1.len] = 0;
                }
                data_string_forget (&d1, MDL);
+               /* hostname changed, can't reuse lease */
+               lease->cannot_reuse = 1;
        }
 
        /* Record the hardware address, if given... */
@@ -5523,7 +5525,10 @@ void use_host_decl_name(struct packet* packet,
  *  c. The lease "age" is less than that allowed by the threshold
  *  d. DNS updates are not being performed on the new lease.
  *  e. Lease has not been otherwise disqualified for reuse (Ex: billing class
- *  changed)
+ *  or hostname changed)
+ *  f. The host declaration has changed (either a new one was added
+ *  or an older one was found due to something like a change in the uid)
+ *  g. The UID or hardware address have changed.
  *
  * Clients may renew leases using full DORA cycles or just RAs. This means
  * that reusability must be checked when acking both DISCOVERs and REQUESTs.
@@ -5538,6 +5543,8 @@ void use_host_decl_name(struct packet* packet,
  * \param new_lease candidate new lease to associate with the client
  * \param lease current lease associated with the client
  * \param options option state to search and update
+ *
+ * \return 1 if the lease can be reused.
  */
 int
 reuse_lease (struct packet* packet,
@@ -5550,10 +5557,20 @@ reuse_lease (struct packet* packet,
        /* To even consider reuse all of the following must be true:
         * 1 - reuse hasn't already disqualified
         * 2 - current lease is active
-        * 3 - DNS info hasn't changed */
+        * 3 - DNS info hasn't changed
+        * 4 - the host declaration hasn't changed
+        * 5 - the uid hasn't changed
+        * 6 - the hardware address hasn't changed */
        if ((lease->cannot_reuse == 0) &&
            (lease->binding_state == FTS_ACTIVE) &&
-           (new_lease->ddns_cb == NULL)) {
+           (new_lease->ddns_cb == NULL) &&
+           (lease->host == new_lease->host) &&
+           (lease->uid_len == new_lease->uid_len) &&
+           (memcmp(lease->uid, new_lease->uid, lease->uid_len) == 0) &&
+           (lease->hardware_addr.hlen == new_lease->hardware_addr.hlen) &&
+           (memcmp(&lease->hardware_addr.hbuf[0],
+                   &new_lease->hardware_addr.hbuf[0],
+                   lease->hardware_addr.hlen) == 0)) {
                int thresh = DEFAULT_CACHE_THRESHOLD;
                struct option_cache* oc = NULL;
                struct data_string d1;
@@ -5587,7 +5604,7 @@ reuse_lease (struct packet* packet,
                        /* Note new_lease->starts is really just cur_time */
                        lease_age = new_lease->starts - lease->starts;
 
-                       /* Is the lease is young enough to reuse? */
+                       /* Is the lease young enough to reuse? */
                        if (lease_age <= limit) {
                                /* Restore expiry to its original value */
                                state->offered_expiry = lease->ends;
@@ -5604,6 +5621,13 @@ reuse_lease (struct packet* packet,
                                                        new_lease->scope, MDL);
                                }
 
+                               /* restore client hostname, fixes 42849. */
+                               if (new_lease->client_hostname) {
+                                       lease->client_hostname =
+                                         new_lease->client_hostname;
+                                       new_lease->client_hostname = NULL;
+                               }
+
                                /* We're cleared to reuse it */
                                log_debug("reuse_lease: lease age %ld (secs)"
                                          " under %d%% threshold, reply with "
index 295d9a657beaeb8852e8921fcf76cc45528b59ee..4090debeff7f425b3467213700dcaaa1d037e11d 100644 (file)
@@ -2196,7 +2196,14 @@ if all of the following conditions are true:
     any of the following:
        a. DNS information and DNS updates are enabled
        b. Billing class to which the lease is associated
+       c. The host declaration associated with the lease
+       d. The client id - this may happen if a client boots without
+       a client id and then starts using one in subsequent requests.
 .fi
+.PP
+Note that the lease can be reused if the options the client or relay agent
+sends are changed.  These changes will not be recorded in the in-memory or
+on-disk databases until the client renews after the threshold time is reached.
 .RE
 .PP
 The