]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Enhance support for long and infinite leases in v6 server
authorShawn Routhier <sar@isc.org>
Tue, 26 Jan 2016 05:16:00 +0000 (21:16 -0800)
committerShawn Routhier <sar@isc.org>
Tue, 26 Jan 2016 05:16:00 +0000 (21:16 -0800)
RELNOTES
server/dhcpv6.c

index 1efaa460ca35ba62772610fc731684e2ca425a7b..6a40abe86580a9d8dc3389a4cc1f2ab360268589 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -172,6 +172,11 @@ by Eric Young (eay@cryptsoft.com).
   Thanks to Antoine Beaupré from Debian for the suggested patch.
   [ISC-Bugs #41288]
 
+- The DHCPv6 server now handles long valid and preferred lease times better.
+  Values that would cause the internal end time of the lease to wrap are
+  modified to work as infinite.
+  [ISC-Bugs #40773]
+
                        Changes since 4.3.3b1
 
 - None
index ec9c9bf7694a29a16f393804a239daad6b5fa2bd..335e7296f53cc5f98785c00039e4cc0a53fe9152 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 2006-2015 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (C) 2006-2016 by Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and distribute this software for any
  * purpose with or without fee is hereby granted, provided that the above
@@ -2173,7 +2173,7 @@ reply_process_ia_na(struct reply_state *reply, struct option_cache *ia) {
                        tmp = reply->ia->iasubopt[i];
 
                        log_info("%s NA: address %s to client with duid %s "
-                                "iaid = %d valid for %d seconds",
+                                "iaid = %d valid for %u seconds",
                                 dhcpv6_type_names[reply->buf.reply.msg_type],
                                 inet_ntop(AF_INET6, &tmp->addr,
                                           tmp_addr, sizeof(tmp_addr)),
@@ -2893,7 +2893,7 @@ reply_process_ia_ta(struct reply_state *reply, struct option_cache *ia) {
                        tmp = reply->ia->iasubopt[i];
 
                        log_info("%s TA: address %s to client with duid %s "
-                                "iaid = %d valid for %d seconds",
+                                "iaid = %d valid for %u seconds",
                                 dhcpv6_type_names[reply->buf.reply.msg_type],
                                 inet_ntop(AF_INET6, &tmp->addr,
                                           tmp_addr, sizeof(tmp_addr)),
@@ -3456,12 +3456,24 @@ reply_process_is_addressed(struct reply_state *reply,
                data_string_forget(&data, MDL);
        }
 
+       /* Check to see if the lease time would cause us to wrap
+        * in which case we make it infinite.
+        * The following doesn't work on at least some systems:
+        * (cur_time + reply->send_valid < cur_time)
+        */
+       if (reply->send_valid != 0xFFFFFFFF) {
+               time_t test_time = cur_time + reply->send_valid;
+               if (test_time < cur_time)
+                       reply->send_valid = 0xFFFFFFFF;
+        }
+
        if (reply->client_prefer == 0)
                reply->send_prefer = reply->send_valid;
        else
                reply->send_prefer = reply->client_prefer;
 
-       if (reply->send_prefer >= reply->send_valid)
+       if ((reply->send_prefer >= reply->send_valid) &&
+           (reply->send_valid != 0xFFFFFFFF))
                reply->send_prefer = (reply->send_valid / 2) +
                                     (reply->send_valid / 8);
 
@@ -3511,10 +3523,17 @@ reply_process_is_addressed(struct reply_state *reply,
                reply->lease->prefer = reply->send_prefer;
                reply->lease->valid = reply->send_valid;
 
-               /* Advance (or rewind) the valid lifetime. */
+               /* Advance (or rewind) the valid lifetime.
+                * In the protocol 0xFFFFFFFF is infinite
+                * when connecting to the lease file MAX_TIME is
+                */
                if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
-                       reply->lease->soft_lifetime_end_time =
-                               cur_time + reply->send_valid;
+                       if (reply->send_valid == 0xFFFFFFFF) {
+                               reply->lease->soft_lifetime_end_time = MAX_TIME;
+                       } else {
+                               reply->lease->soft_lifetime_end_time =
+                                 cur_time + reply->send_valid;
+                       }
                        /* Wait before renew! */
                }
 
@@ -3977,7 +3996,7 @@ reply_process_ia_pd(struct reply_state *reply, struct option_cache *ia) {
                        tmp = reply->ia->iasubopt[i];
 
                        log_info("%s PD: address %s/%d to client with duid %s"
-                                " iaid = %d valid for %d seconds",
+                                " iaid = %d valid for %u seconds",
                                 dhcpv6_type_names[reply->buf.reply.msg_type],
                                 inet_ntop(AF_INET6, &tmp->addr,
                                           tmp_addr, sizeof(tmp_addr)),
@@ -4725,12 +4744,24 @@ reply_process_is_prefixed(struct reply_state *reply,
                data_string_forget(&data, MDL);
        }
 
+       /* Check to see if the lease time would cause us to wrap
+        * in which case we make it infinite.
+        * The following doesn't work on at least some systems:
+        * (cur_time + reply->send_valid < cur_time)
+        */
+       if (reply->send_valid != 0xFFFFFFFF) {
+               time_t test_time = cur_time + reply->send_valid;
+               if (test_time < cur_time)
+                       reply->send_valid = 0xFFFFFFFF;
+        }
+
        if (reply->client_prefer == 0)
                reply->send_prefer = reply->send_valid;
        else
                reply->send_prefer = reply->client_prefer;
 
-       if (reply->send_prefer >= reply->send_valid)
+       if ((reply->send_prefer >= reply->send_valid) &&
+           (reply->send_valid != 0xFFFFFFFF))
                reply->send_prefer = (reply->send_valid / 2) +
                                     (reply->send_valid / 8);
 
@@ -4765,10 +4796,17 @@ reply_process_is_prefixed(struct reply_state *reply,
                reply->lease->prefer = reply->send_prefer;
                reply->lease->valid = reply->send_valid;
 
-               /* Advance (or rewind) the valid lifetime. */
+               /* Advance (or rewind) the valid lifetime.
+                * In the protocol 0xFFFFFFFF is infinite
+                * when connecting to the lease file MAX_TIME is
+                */
                if (reply->buf.reply.msg_type == DHCPV6_REPLY) {
-                       reply->lease->soft_lifetime_end_time =
-                               cur_time + reply->send_valid;
+                       if (reply->send_valid == 0xFFFFFFFF) {
+                               reply->lease->soft_lifetime_end_time = MAX_TIME;
+                       } else {
+                               reply->lease->soft_lifetime_end_time =
+                                 cur_time + reply->send_valid;
+                       }
                        /* Wait before renew! */
                }