]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
[master] Correct calculation of client timeout to include MRD
authorShawn Routhier <sar@isc.org>
Wed, 30 Apr 2014 20:21:48 +0000 (13:21 -0700)
committerShawn Routhier <sar@isc.org>
Wed, 30 Apr 2014 20:21:48 +0000 (13:21 -0700)
Correc the calculation of the next climet timeout period to
properly include MRD.

RELNOTES
client/dhc6.c

index 73cf849ebe1f0a73b68826098e3d1299e9064bff..e8aa5be4f06da7b135670d9e372dd526e38dc3e4 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -98,6 +98,11 @@ by Eric Young (eay@cryptsoft.com).
 - Remove unused RCSID tags.
   [ISC-Bugs #35846]
 
+- Correct the v6 client timing code.  When doing the timing backoff
+  for MRT limit it to MRD.
+  Thanks to Jiri Popelka at Red Hat for the bug and fix.
+  [ISC-Bugs #21238
+
                        Changes since 4.3.0rc1
 
 - None
index 98f4cf26c03ca41c357cd8b88aded019847c0719..3954b43e54b27b9699943adb9e46988b1825bb52 100644 (file)
@@ -1,7 +1,7 @@
 /* dhc6.c - DHCPv6 client routines. */
 
 /*
- * Copyright (c) 2012-2013 by Internet Systems Consortium, Inc. ("ISC")
+ * Copyright (c) 2012-2014 by Internet Systems Consortium, Inc. ("ISC")
  * Copyright (c) 2006-2010 by Internet Systems Consortium, Inc. ("ISC")
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -300,7 +300,7 @@ dhc6_retrans_init(struct client_state *client)
 static void
 dhc6_retrans_advance(struct client_state *client)
 {
-       struct timeval elapsed;
+       struct timeval elapsed, elapsed_plus_rt;
 
        /* elapsed = cur - start */
        elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
@@ -317,6 +317,12 @@ dhc6_retrans_advance(struct client_state *client)
                elapsed.tv_sec += 1;
                elapsed.tv_usec -= 1000000;
        }
+       /*
+        * Save what the time will be after the current RT to determine
+        * what the delta to MRD will be.
+        */
+       elapsed_plus_rt.tv_sec = elapsed.tv_sec;
+       elapsed_plus_rt.tv_usec = elapsed.tv_usec;
 
        /*
         * RT for each subsequent message transmission is based on the previous
@@ -355,12 +361,16 @@ dhc6_retrans_advance(struct client_state *client)
        }
        if (elapsed.tv_sec >= client->MRD) {
                /*
-                * wake at RT + cur = start + MRD
+                * The desired RT is the time that will be remaining in MRD
+                * when the current timeout finishes.  We then have 
+                * desired RT = MRD - (elapsed time + previous RT); or
+                * desired RT = MRD - elapsed_plut_rt;
                 */
-               client->RT = client->MRD +
-                       (client->start_time.tv_sec - cur_tv.tv_sec);
-               client->RT = client->RT * 100 +
-                       (client->start_time.tv_usec - cur_tv.tv_usec) / 10000;
+               client->RT = client->MRD - elapsed_plus_rt.tv_sec;
+               client->RT = (client->RT * 100) -
+                       (elapsed_plus_rt.tv_usec / 10000);
+               if (client->RT < 0)
+                       client->RT = 0;
        }
        client->txcount++;
 }
@@ -1437,7 +1447,7 @@ check_timing6 (struct client_state *client, u_int8_t msg_type,
        }
 
        /* Check if finished (-1 argument). */
-       if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
+       if ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD)) {
                log_info("Max retransmission duration exceeded.");
                return(CHK_TIM_MRD_EXCEEDED);
        }