]> git.ipfire.org Git - thirdparty/dhcp.git/commitdiff
finer granularity timers
authorFrancis Dupont <fdupont@isc.org>
Thu, 3 Jan 2008 00:30:14 +0000 (00:30 +0000)
committerFrancis Dupont <fdupont@isc.org>
Thu, 3 Jan 2008 00:30:14 +0000 (00:30 +0000)
13 files changed:
RELNOTES
client/dhc6.c
client/dhclient.c
common/dispatch.c
includes/dhcpd.h
includes/minires/minires.h
omapip/dispatch.c
relay/dhcrelay.c
server/dhcp.c
server/dhcpd.c
server/failover.c
server/mdb.c
server/mdb6.c

index 0efba5efc3c967d229b6bd534c08be4d1282c049..df73ecc6b398e07618d44de7b166fff1386e5b60 100644 (file)
--- a/RELNOTES
+++ b/RELNOTES
@@ -89,6 +89,8 @@ suggested fixes to <dhcp-users@isc.org>.
 - Return in place of raise an impossible condition when one tries to release
   an empty active lease.
 
+- Timer granularity is now 1/100s in the DHCPv6 client.
+
                        Changes since 4.0.0b3
 
 - The reverse dns name for PTR updates on IPv6 addresses has been fixed to
index c84a8a53c6c8a2a2ab1fe6e2338c37fdc88c2d93..a9902f02315881bc62367d7c7f57b048ab7a28ed 100644 (file)
@@ -284,7 +284,6 @@ dhc6_retrans_init(struct client_state *client)
        int xid;
 
        /* Initialize timers. */
-       client->start_time = cur_time;
        client->txcount = 0;
        client->RT = client->IRT + dhc6_rand(client->IRT);
 
@@ -309,11 +308,23 @@ dhc6_retrans_init(struct client_state *client)
 static void
 dhc6_retrans_advance(struct client_state *client)
 {
-       TIME elapsed;
+       struct timeval elapsed;
 
-       elapsed = cur_time - client->start_time;
+       /* elapsed = cur - start */
+       elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
+       elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
+       if (elapsed.tv_usec < 0) {
+               elapsed.tv_sec -= 1;
+               elapsed.tv_usec += 1000000;
+       }
        /* retrans_advance is called after consuming client->RT. */
-       elapsed += client->RT;
+       /* elapsed += RT */
+       elapsed.tv_sec += client->RT / 100;
+       elapsed.tv_usec += (client->RT % 100) * 10000;
+       if (elapsed.tv_usec >= 1000000) {
+               elapsed.tv_sec += 1;
+               elapsed.tv_usec -= 1000000;
+       }
 
         /* RT for each subsequent message transmission is based on the previous
          * value of RT:
@@ -335,10 +346,27 @@ dhc6_retrans_advance(struct client_state *client)
        /* Further, if there's an MRD, we should wake up upon reaching
         * the MRD rather than at some point after it.
         */
-       if ((client->MRD != 0) && ((elapsed + client->RT) > client->MRD)) {
-               client->RT = (client->start_time + client->MRD) - cur_time;
+       if (client->MRD == 0) {
+               /* Done. */
+               client->txcount++;
+               return;
+       }
+       /* elapsed += client->RT */
+       elapsed.tv_sec += client->RT / 100;
+       elapsed.tv_usec += (client->RT % 100) * 10000;
+       if (elapsed.tv_usec >= 1000000) {
+               elapsed.tv_sec += 1;
+               elapsed.tv_usec -= 1000000;
+       }
+       if (elapsed.tv_sec >= client->MRD) {
+               /*
+                * wake at RT + cur = start + MRD
+                */
+               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->txcount++;
 }
 
@@ -1204,12 +1232,14 @@ dhc6_score_lease(struct client_state *client, struct dhc6_lease *lease)
 void
 start_init6(struct client_state *client)
 {
+       struct timeval tv;
+
        log_debug("PRC: Soliciting for leases (INIT).");
        client->state = S_INIT;
 
        /* Initialize timers, RFC3315 section 17.1.2. */
-       client->IRT = SOL_TIMEOUT;
-       client->MRT = SOL_MAX_RT;
+       client->IRT = SOL_TIMEOUT * 100;
+       client->MRT = SOL_MAX_RT * 100;
        client->MRC = 0;
        client->MRD = 0;
 
@@ -1219,6 +1249,10 @@ start_init6(struct client_state *client)
         * Also, the first RT MUST be selected to be strictly greater than IRT
         * by choosing RAND to be strictly greater than 0.
         */
+       /* if RAND < 0 then RAND = -RAND */
+       if (client->RT <= client->IRT)
+               client->RT = client->IRT + (client->IRT - client->RT);
+       /* if RAND == 0 then RAND = 1 */
        if (client->RT <= client->IRT)
                client->RT = client->IRT + 1;
 
@@ -1228,8 +1262,14 @@ start_init6(struct client_state *client)
         * between 0 and SOL_MAX_DELAY seconds.  The good news is
         * SOL_MAX_DELAY is 1.
         */
-       add_timeout(cur_time + (random() % SOL_MAX_DELAY), do_init6, client,
-                   NULL, NULL);
+       tv.tv_sec = cur_tv.tv_sec;
+       tv.tv_usec = cur_tv.tv_usec;
+       tv.tv_usec += (random() % (SOL_MAX_DELAY * 100)) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_init6, client, NULL, NULL);
 
        if (nowait)
                go_daemon();
@@ -1242,6 +1282,8 @@ start_init6(struct client_state *client)
 void
 start_confirm6(struct client_state *client)
 {
+       struct timeval tv;
+
        /* If there is no active lease, there is nothing to check. */
        if (client->active_lease == NULL) {
                start_init6(client);
@@ -1252,8 +1294,8 @@ start_confirm6(struct client_state *client)
        client->state = S_REBOOTING;
 
        /* Initialize timers, RFC3315 section 17.1.3. */
-       client->IRT = CNF_TIMEOUT;
-       client->MRT = CNF_MAX_RT;
+       client->IRT = CNF_TIMEOUT * 100;
+       client->MRT = CNF_MAX_RT * 100;
        client->MRC = 0;
        client->MRD = CNF_MAX_RD;
 
@@ -1261,8 +1303,18 @@ start_confirm6(struct client_state *client)
 
        client->v6_handler = reply_handler;
 
-       add_timeout(cur_time + (random() % CNF_MAX_DELAY), do_confirm6, client,
-                   NULL, NULL);
+       /* RFC3315 section 18.1.2 says we MUST start the first packet
+        * between 0 and CNF_MAX_DELAY seconds.  The good news is
+        * CNF_MAX_DELAY is 1.
+        */
+       tv.tv_sec = cur_tv.tv_sec;
+       tv.tv_usec = cur_tv.tv_usec;
+       tv.tv_usec += (random() % (CNF_MAX_DELAY * 100)) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_confirm6, client, NULL, NULL);
 }
 
 /* do_init6() marshals and transmits a solicit.
@@ -1276,7 +1328,7 @@ do_init6(void *input)
        struct data_string ds;
        struct data_string ia;
        struct data_string addr;
-       TIME elapsed;
+       struct timeval elapsed, tv;
        u_int32_t t1, t2;
        int idx, len, send_ret;
 
@@ -1295,8 +1347,22 @@ do_init6(void *input)
                return;
        }
 
-       elapsed = cur_time - client->start_time;
-       if ((client->MRD != 0) && (elapsed > client->MRD)) {
+       /*
+        * Start_time starts at the first transmission.
+        */
+       if (client->txcount == 0) {
+               client->start_time.tv_sec = cur_tv.tv_sec;
+               client->start_time.tv_usec = cur_tv.tv_usec;
+       }
+
+       /* elapsed = cur - start */
+       elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
+       elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
+       if (elapsed.tv_usec < 0) {
+               elapsed.tv_sec -= 1;
+               elapsed.tv_usec += 1000000;
+       }
+       if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
                log_info("Max retransmission duration exceeded.");
                return;
        }
@@ -1313,13 +1379,20 @@ do_init6(void *input)
        memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
 
        /* Form an elapsed option. */
-       if ((elapsed < 0) || (elapsed > 655))
+       /* Maximum value is 65535 1/100s coded as 0xffff. */
+       if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
+           ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
                client->elapsed = 0xffff;
-       else
-               client->elapsed = elapsed * 100;
+       } else {
+               client->elapsed = elapsed.tv_sec * 100;
+               client->elapsed += elapsed.tv_usec / 10000;
+       }
 
-       log_debug("XMT: Forming Solicit, %u0 ms elapsed.",
-                 (unsigned)client->elapsed);
+       if (client->elapsed == 0)
+               log_debug("XMT: Forming Solicit, 0 ms elapsed.");
+       else
+               log_debug("XMT: Forming Solicit, %u0 ms elapsed.",
+                         (unsigned)client->elapsed);
 
        client->elapsed = htons(client->elapsed);
 
@@ -1415,7 +1488,7 @@ do_init6(void *input)
 
        /* Transmit and wait. */
 
-       log_info("XMT: Solicit on %s, interval %ld",
+       log_info("XMT: Solicit on %s, interval %ld0ms.",
                 client->name ? client->name : client->interface->name,
                 (long int)client->RT);
 
@@ -1428,7 +1501,14 @@ do_init6(void *input)
 
        data_string_forget(&ds, MDL);
 
-       add_timeout(cur_time + client->RT, do_init6, client, NULL, NULL);
+       /* Wait RT */
+       tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
+       tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_init6, client, NULL, NULL);
 
        dhc6_retrans_advance(client);
 }
@@ -1442,7 +1522,7 @@ do_confirm6(void *input)
        struct client_state *client;
        struct data_string ds;
        int send_ret;
-       TIME elapsed;
+       struct timeval elapsed, tv;
 
        client = input;
 
@@ -1469,8 +1549,22 @@ do_confirm6(void *input)
                return;
        }
 
-       elapsed = cur_time - client->start_time;
-       if ((client->MRD != 0) && (elapsed > client->MRD)) {
+       /*
+        * Start_time starts at the first transmission.
+        */
+       if (client->txcount == 0) {
+               client->start_time.tv_sec = cur_tv.tv_sec;
+               client->start_time.tv_usec = cur_tv.tv_usec;
+       }
+
+       /* elapsed = cur - start */
+       elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
+       elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
+       if (elapsed.tv_usec < 0) {
+               elapsed.tv_sec -= 1;
+               elapsed.tv_usec += 1000000;
+       }
+       if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
                log_info("Max retransmission duration exceeded.");
                start_bound(client);
                return;
@@ -1488,13 +1582,20 @@ do_confirm6(void *input)
        memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
 
        /* Form an elapsed option. */
-       if ((elapsed < 0) || (elapsed > 655))
+       /* Maximum value is 65535 1/100s coded as 0xffff. */
+       if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
+           ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
                client->elapsed = 0xffff;
-       else
-               client->elapsed = elapsed * 100;
+       } else {
+               client->elapsed = elapsed.tv_sec * 100;
+               client->elapsed += elapsed.tv_usec / 10000;
+       }
 
-       log_debug("XMT: Forming Confirm, %u0 ms elapsed.",
-                 (unsigned)client->elapsed);
+       if (client->elapsed == 0)
+               log_debug("XMT: Forming Confirm, 0 ms elapsed.");
+       else
+               log_debug("XMT: Forming Confirm, %u0 ms elapsed.",
+                         (unsigned)client->elapsed);
 
        client->elapsed = htons(client->elapsed);
 
@@ -1516,7 +1617,7 @@ do_confirm6(void *input)
 
        /* Transmit and wait. */
 
-       log_info("XMT: Confirm on %s, interval %ld.",
+       log_info("XMT: Confirm on %s, interval %ld0ms.",
                 client->name ? client->name : client->interface->name,
                 (long int)client->RT);
 
@@ -1529,7 +1630,14 @@ do_confirm6(void *input)
 
        data_string_forget(&ds, MDL);
 
-       add_timeout(cur_time + client->RT, do_confirm6, client, NULL, NULL);
+       /* Wait RT */
+       tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
+       tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_confirm6, client, NULL, NULL);
 
        dhc6_retrans_advance(client);
 }
@@ -1555,9 +1663,9 @@ start_release6(struct client_state *client)
         unconfigure6(client, "RELEASE6");
 
        /* Set timers per RFC3315 section 18.1.1. */
-       client->IRT = REL_TIMEOUT;
+       client->IRT = REL_TIMEOUT * 100;
        client->MRT = 0;
-       client->MRC = REL_MAX_RC;
+       client->MRC = REL_MAX_RC * 100;
        client->MRD = 0;
 
        dhc6_retrans_init(client);
@@ -1577,6 +1685,7 @@ do_release6(void *input)
        struct data_string ds;
        struct option_cache *oc;
        int send_ret;
+       struct timeval tv;
 
        client = input;
 
@@ -1588,6 +1697,14 @@ do_release6(void *input)
                return;
        }
 
+       /*
+        * Start_time starts at the first transmission.
+        */
+       if (client->txcount == 0) {
+               client->start_time.tv_sec = cur_tv.tv_sec;
+               client->start_time.tv_usec = cur_tv.tv_usec;
+       }
+
        /*
         * Check whether the server has sent a unicast option; if so, we can
         * use the address it specified.
@@ -1636,7 +1753,7 @@ do_release6(void *input)
        }
 
        /* Transmit and wait. */
-       log_info("XMT: Release on %s, interval %ld.",
+       log_info("XMT: Release on %s, interval %ld0ms.",
                 client->name ? client->name : client->interface->name,
                 (long int)client->RT);
 
@@ -1649,7 +1766,14 @@ do_release6(void *input)
 
        data_string_forget(&ds, MDL);
 
-       add_timeout(cur_time + client->RT, do_release6, client, NULL, NULL);
+       /* Wait RT */
+       tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
+       tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_release6, client, NULL, NULL);
        dhc6_retrans_advance(client);
 }
 
@@ -2359,8 +2483,8 @@ start_selecting6(struct client_state *client)
        client->selected_lease = lease;
 
        /* Set timers per RFC3315 section 18.1.1. */
-       client->IRT = REQ_TIMEOUT;
-       client->MRT = REQ_MAX_RT;
+       client->IRT = REQ_TIMEOUT * 100;
+       client->MRT = REQ_MAX_RT * 100;
        client->MRC = REQ_MAX_RC;
        client->MRD = 0;
 
@@ -2382,7 +2506,7 @@ do_select6(void *input)
        struct client_state *client;
        struct dhc6_lease *lease;
        struct data_string ds;
-       TIME elapsed;
+       struct timeval elapsed, tv;
        int abort = ISC_FALSE;
        int send_ret;
 
@@ -2401,8 +2525,22 @@ do_select6(void *input)
                abort = ISC_TRUE;
        }
 
-       elapsed = cur_time - client->start_time;
-       if ((client->MRD != 0) && (elapsed > client->MRD)) {
+       /*
+        * Start_time starts at the first transmission.
+        */
+       if (client->txcount == 0) {
+               client->start_time.tv_sec = cur_tv.tv_sec;
+               client->start_time.tv_usec = cur_tv.tv_usec;
+       }
+
+       /* elapsed = cur - start */
+       elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
+       elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
+       if (elapsed.tv_usec < 0) {
+               elapsed.tv_sec -= 1;
+               elapsed.tv_usec += 1000000;
+       }
+       if ((client->MRD != 0) && (elapsed.tv_sec > client->MRD)) {
                log_info("Max retransmission duration exceeded.");
                abort = ISC_TRUE;
        }
@@ -2447,13 +2585,20 @@ do_select6(void *input)
        memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
 
        /* Form an elapsed option. */
-       if ((elapsed < 0) || (elapsed > 655))
+       /* Maximum value is 65535 1/100s coded as 0xffff. */
+       if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
+           ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
                client->elapsed = 0xffff;
-       else
-               client->elapsed = elapsed * 100;
+       } else {
+               client->elapsed = elapsed.tv_sec * 100;
+               client->elapsed += elapsed.tv_usec / 10000;
+       }
 
-       log_debug("XMT: Forming Request, %u0 ms elapsed.",
-                 (unsigned)client->elapsed);
+       if (client->elapsed == 0)
+               log_debug("XMT: Forming Request, 0 ms elapsed.");
+       else
+               log_debug("XMT: Forming Request, %u0 ms elapsed.",
+                         (unsigned)client->elapsed);
 
        client->elapsed = htons(client->elapsed);
 
@@ -2473,7 +2618,7 @@ do_select6(void *input)
                return;
        }
 
-       log_info("XMT: Request on %s, interval %ld",
+       log_info("XMT: Request on %s, interval %ld0ms.",
                 client->name ? client->name : client->interface->name,
                 (long int)client->RT);
 
@@ -2486,7 +2631,14 @@ do_select6(void *input)
 
        data_string_forget(&ds, MDL);
 
-       add_timeout(cur_time + client->RT, do_select6, client, NULL, NULL);
+       /* Wait RT */
+       tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
+       tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_select6, client, NULL, NULL);
 
        dhc6_retrans_advance(client);
 }
@@ -2827,6 +2979,7 @@ dhc6_check_times(struct client_state *client)
        TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME,
             lo_expire=MAX_TIME, hi_expire=0, tmp;
        int has_addrs = ISC_FALSE;
+       struct timeval tv;
 
        lease = client->active_lease;
 
@@ -2955,8 +3108,10 @@ dhc6_check_times(struct client_state *client)
                                  "to run for %u seconds.",
                                  (int)(renew - cur_time),
                                  (unsigned)(rebind - renew));
-                       client->next_MRD = rebind - cur_time;
-                       add_timeout(renew, start_renew6, client, NULL, NULL);
+                       client->next_MRD = rebind;
+                       tv.tv_sec = renew;
+                       tv.tv_usec = 0;
+                       add_timeout(&tv, start_renew6, client, NULL, NULL);
 
                        break;
                }
@@ -2972,8 +3127,10 @@ dhc6_check_times(struct client_state *client)
                                  "to run for %d seconds.",
                                  (int)(rebind - cur_time),
                                  (int)(hi_expire - rebind));
-                       client->next_MRD = hi_expire - cur_time;
-                       add_timeout(rebind, start_rebind6, client, NULL, NULL);
+                       client->next_MRD = hi_expire;
+                       tv.tv_sec = rebind;
+                       tv.tv_usec = 0;
+                       add_timeout(&tv, start_rebind6, client, NULL, NULL);
                }
                break;
 
@@ -2996,12 +3153,16 @@ dhc6_check_times(struct client_state *client)
        if (depref != MAX_TIME) {
                log_debug("PRC: Depreference scheduled in %d seconds.",
                          (int)(depref - cur_time));
-               add_timeout(depref, do_depref, client, NULL, NULL);
+               tv.tv_sec = depref;
+               tv.tv_usec = 0;
+               add_timeout(&tv, do_depref, client, NULL, NULL);
        }
        if (lo_expire != MAX_TIME) {
                log_debug("PRC: Expiration scheduled in %d seconds.",
                          (int)(lo_expire - cur_time));
-               add_timeout(lo_expire, do_expire, client, NULL, NULL);
+               tv.tv_sec = lo_expire;
+               tv.tv_usec = 0;
+               add_timeout(&tv, do_expire, client, NULL, NULL);
        }
 }
 
@@ -3237,8 +3398,8 @@ bound_handler(struct packet *packet, struct client_state *client)
 }
 
 /* start_renew6() gets us all ready to go to start transmitting Renew packets.
- * Note that client->MRD must be set before entering this function - it must
- * be set to the time at which the client should start Rebinding.
+ * Note that client->next_MRD must be set before entering this function -
+ * it must be set to the time at which the client should start Rebinding.
  */
 void
 start_renew6(void *input)
@@ -3254,13 +3415,13 @@ start_renew6(void *input)
        client->v6_handler = reply_handler;
 
        /* Times per RFC3315 section 18.1.3. */
-       client->IRT = REN_TIMEOUT;
-       client->MRT = REN_MAX_RT;
+       client->IRT = REN_TIMEOUT * 100;
+       client->MRT = REN_MAX_RT * 100;
        client->MRC = 0;
        /* MRD is special in renew - we need to set it by checking timer
         * state.
         */
-       client->MRD = client->next_MRD;
+       client->MRD = client->next_MRD - cur_time;
 
        dhc6_retrans_init(client);
 
@@ -3280,7 +3441,7 @@ do_refresh6(void *input)
        struct data_string ds;
        struct client_state *client;
        struct dhc6_lease *lease;
-       TIME elapsed;
+       struct timeval elapsed, tv;
        int send_ret;
 
        client = (struct client_state *)input;
@@ -3302,9 +3463,23 @@ do_refresh6(void *input)
                          client->refresh_type, MDL);
        }
 
-       elapsed = cur_time - client->start_time;
+       /*
+        * Start_time starts at the first transmission.
+        */
+       if (client->txcount == 0) {
+               client->start_time.tv_sec = cur_tv.tv_sec;
+               client->start_time.tv_usec = cur_tv.tv_usec;
+       }
+
+       /* elapsed = cur - start */
+       elapsed.tv_sec = cur_tv.tv_sec - client->start_time.tv_sec;
+       elapsed.tv_usec = cur_tv.tv_usec - client->start_time.tv_usec;
+       if (elapsed.tv_usec < 0) {
+               elapsed.tv_sec -= 1;
+               elapsed.tv_usec += 1000000;
+       }
        if (((client->MRC != 0) && (client->txcount > client->MRC)) ||
-           ((client->MRD != 0) && (elapsed >= client->MRD))) {
+           ((client->MRD != 0) && (elapsed.tv_sec >= client->MRD))) {
                /* We're done.  Move on to the next phase, if any. */
                dhc6_check_times(client);
                return;
@@ -3345,14 +3520,23 @@ do_refresh6(void *input)
        ds.buffer->data[0] = client->refresh_type;
        memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
 
-       if ((elapsed < 0) || (elapsed > 655))
+       /* Form an elapsed option. */
+       /* Maximum value is 65535 1/100s coded as 0xffff. */
+       if ((elapsed.tv_sec < 0) || (elapsed.tv_sec > 655) ||
+           ((elapsed.tv_sec == 655) && (elapsed.tv_usec > 350000))) {
                client->elapsed = 0xffff;
-       else
-               client->elapsed = elapsed * 100;
+       } else {
+               client->elapsed = elapsed.tv_sec * 100;
+               client->elapsed += elapsed.tv_usec / 10000;
+       }
 
-       log_debug("XMT: Forming %s, %u0 ms elapsed.",
-                 dhcpv6_type_names[client->refresh_type],
-                 (unsigned)client->elapsed);
+       if (client->elapsed == 0)
+               log_debug("XMT: Forming %s, 0 ms elapsed.",
+                         dhcpv6_type_names[client->refresh_type]);
+       else
+               log_debug("XMT: Forming %s, %u0 ms elapsed.",
+                         dhcpv6_type_names[client->refresh_type],
+                         (unsigned)client->elapsed);
 
        client->elapsed = htons(client->elapsed);
 
@@ -3371,7 +3555,7 @@ do_refresh6(void *input)
                return;
        }
 
-       log_info("XMT: %s on %s, interval %ld",
+       log_info("XMT: %s on %s, interval %ld0ms.",
                 dhcpv6_type_names[client->refresh_type],
                 client->name ? client->name : client->interface->name,
                 (long int)client->RT);
@@ -3385,13 +3569,20 @@ do_refresh6(void *input)
 
        data_string_forget(&ds, MDL);
 
-       add_timeout(cur_time + client->RT, do_refresh6, client, NULL, NULL);
+       /* Wait RT */
+       tv.tv_sec = cur_tv.tv_sec + client->RT / 100;
+       tv.tv_usec = cur_tv.tv_usec + (client->RT % 100) * 10000;
+       if (tv.tv_usec >= 1000000) {
+               tv.tv_sec += 1;
+               tv.tv_usec -= 1000000;
+       }
+       add_timeout(&tv, do_refresh6, client, NULL, NULL);
 
        dhc6_retrans_advance(client);
 }
 
 /* start_rebind6() gets us all set up to go and rebind a lease.  Note that
- * client->MRD must be set before entering this function.  In this case,
+ * client->next_MRD must be set before entering this function.  In this case,
  * MRD must be set to the maximum time any address in the packet will
  * expire.
  */
@@ -3409,13 +3600,13 @@ start_rebind6(void *input)
        client->v6_handler = reply_handler;
 
        /* Times per RFC3315 section 18.1.4. */
-       client->IRT = REB_TIMEOUT;
-       client->MRT = REB_MAX_RT;
+       client->IRT = REB_TIMEOUT * 100;
+       client->MRT = REB_MAX_RT * 100;
        client->MRC = 0;
        /* MRD is special in rebind - it's determined by the timer
         * state.
         */
-       client->MRD = client->next_MRD;
+       client->MRD = client->next_MRD - cur_time;
 
        dhc6_retrans_init(client);
 
index c2276875ea53b2fa40f78a12388aee4e396fdd0b..bd630ef9d470174c80d4a66b3b6e73b736aa2955 100644 (file)
@@ -34,6 +34,7 @@
 #include <syslog.h>
 #include <signal.h>
 #include <errno.h>
+#include <sys/time.h>
 #include <sys/wait.h>
 #include <limits.h>
 
@@ -91,6 +92,7 @@ main(int argc, char **argv) {
        isc_result_t status;
        int exit_mode = 0;
        int release_mode = 0;
+       struct timeval tv;
        omapi_object_t *listener;
        isc_result_t result;
        int persist = 0;
@@ -342,7 +344,7 @@ main(int argc, char **argv) {
        }
 
        /* Get the current time... */
-       time(&cur_time);
+       gettimeofday(&cur_tv, NULL);
 
        sockaddr_broadcast.sin_family = AF_INET;
        sockaddr_broadcast.sin_port = remote_port;
@@ -492,8 +494,10 @@ main(int argc, char **argv) {
                                        /* Set up a timeout to start the
                                         * initialization process.
                                         */
-                                       add_timeout(cur_time + random() % 5,
-                                                   state_reboot, client, 0, 0);
+                                       tv.tv_sec = cur_time + random() % 5;
+                                       tv.tv_usec = 0;
+                                       add_timeout(&tv, state_reboot,
+                                                   client, 0, 0);
                                }
                        }
                }
@@ -927,6 +931,8 @@ void dhcpack (packet)
 void bind_lease (client)
        struct client_state *client;
 {
+       struct timeval tv;
+
        /* Remember the medium. */
        client -> new -> medium = client -> medium;
 
@@ -966,8 +972,9 @@ void bind_lease (client)
        client -> new = (struct client_lease *)0;
 
        /* Set up a timeout to start the renewal process. */
-       add_timeout (client -> active -> renewal,
-                    state_bound, client, 0, 0);
+       tv . tv_sec = client -> active -> renewal;
+       tv . tv_usec = 0;
+       add_timeout (&tv, state_bound, client, 0, 0);
 
        log_info ("bound to %s -- renewal in %ld seconds.",
              piaddr (client -> active -> address),
@@ -1217,6 +1224,7 @@ void dhcpoffer (packet)
        int stop_selecting;
        const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
        char obuf [1024];
+       struct timeval tv;
        
 #ifdef DEBUG_PACKET
        dump_packet (packet);
@@ -1329,7 +1337,9 @@ void dhcpoffer (packet)
        if (stop_selecting <= 0)
                state_selecting (client);
        else {
-               add_timeout (stop_selecting, state_selecting, client, 0, 0);
+               tv . tv_sec = stop_selecting;
+               tv . tv_usec = 0;
+               add_timeout (&tv, state_selecting, client, 0, 0);
                cancel_timeout (send_discover, client);
        }
        log_info ("%s", obuf);
@@ -1546,6 +1556,7 @@ void send_discover (cpp)
        int result;
        int interval;
        int increase = 1;
+       struct timeval tv;
 
        /* Figure out how long it's been since we started transmitting. */
        interval = cur_time - client -> first_sending;
@@ -1631,8 +1642,9 @@ void send_discover (cpp)
                              inaddr_any, &sockaddr_broadcast,
                              (struct hardware *)0);
 
-       add_timeout (cur_time + client -> interval,
-                    send_discover, client, 0, 0);
+       tv . tv_sec = cur_time + client -> interval;
+       tv . tv_usec = 0;
+       add_timeout (&tv, send_discover, client, 0, 0);
 }
 
 /* state_panic gets called if we haven't received any offers in a preset
@@ -1646,6 +1658,7 @@ void state_panic (cpp)
        struct client_state *client = cpp;
        struct client_lease *loop;
        struct client_lease *lp;
+       struct timeval tv;
 
        loop = lp = client -> active;
 
@@ -1679,8 +1692,9 @@ void state_panic (cpp)
                                log_info ("bound: renewal in %ld %s.",
                                          (long)(client -> active -> renewal -
                                                 cur_time), "seconds");
-                               add_timeout (client -> active -> renewal,
-                                            state_bound, client, 0, 0);
+                               tv . tv_sec = client -> active -> renewal;
+                               tv . tv_usec = 0;
+                               add_timeout (&tv, state_bound, client, 0, 0);
                            } else {
                                client -> state = S_BOUND;
                                log_info ("bound: immediate renewal.");
@@ -1736,10 +1750,11 @@ void state_panic (cpp)
                script_write_params (client, "alias_", client -> alias);
        script_go (client);
        client -> state = S_INIT;
-       add_timeout (cur_time +
+       tv . tv_sec = cur_time +
                     ((client -> config -> retry_interval + 1) / 2 +
-                     (random () % client -> config -> retry_interval)),
-                    state_init, client, 0, 0);
+                     (random () % client -> config -> retry_interval));
+       tv . tv_usec = 0;
+       add_timeout (&tv, state_init, client, 0, 0);
        go_daemon ();
 }
 
@@ -1752,6 +1767,7 @@ void send_request (cpp)
        int interval;
        struct sockaddr_in destination;
        struct in_addr from;
+       struct timeval tv;
 
        /* Figure out how long it's been since we started transmitting. */
        interval = cur_time - client -> first_sending;
@@ -1893,8 +1909,9 @@ void send_request (cpp)
                                      from, &destination,
                                      (struct hardware *)0);
 
-       add_timeout (cur_time + client -> interval,
-                    send_request, client, 0, 0);
+       tv . tv_sec = cur_time + client -> interval;
+       tv . tv_usec = 0;
+       add_timeout (&tv, send_request, client, 0, 0);
 }
 
 void send_decline (cpp)
@@ -2961,7 +2978,7 @@ int script_go (client)
                client -> envc = 0;
        }
        dfree (envp, MDL);
-       time(&cur_time);
+       gettimeofday(&cur_tv, NULL);
        return (WIFEXITED (wstatus) ?
                WEXITSTATUS (wstatus) : -WTERMSIG (wstatus));
 }
@@ -3252,6 +3269,7 @@ isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
 {
        struct interface_info *ip;
        struct client_state *client;
+       struct timeval tv;
 
        /* This code needs some rethinking.   It doesn't test against
           a signal name, and it just kind of bulls into doing something
@@ -3293,8 +3311,9 @@ isc_result_t dhclient_interface_startup_hook (struct interface_info *interface)
                        client -> state = S_INIT;
                        /* Set up a timeout to start the initialization
                           process. */
-                       add_timeout (cur_time + random () % 5,
-                                    state_reboot, client, 0, 0);
+                       tv . tv_sec = cur_time + random () % 5;
+                       tv . tv_usec = 0;
+                       add_timeout (&tv, state_reboot, client, 0, 0);
                }
        }
        return ISC_R_SUCCESS;
@@ -3333,6 +3352,7 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
 {
        struct interface_info *ip;
        struct client_state *client;
+       struct timeval tv;
 
        /* Do the right thing for each interface. */
        for (ip = interfaces; ip; ip = ip -> next) {
@@ -3365,8 +3385,11 @@ isc_result_t dhcp_set_control_state (control_object_state_t oldstate,
            }
        }
 
-       if (newstate == server_shutdown)
-               add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0);
+       if (newstate == server_shutdown) {
+               tv . tv_sec = cur_tv . tv_sec + 1;
+               tv . tv_usec = cur_tv . tv_usec;
+               add_timeout (&tv, shutdown_exit, 0, 0, 0);
+       }
        return ISC_R_SUCCESS;
 }
 
@@ -3377,6 +3400,7 @@ dhclient_schedule_updates(struct client_state *client, struct iaddr *addr,
                          int offset)
 {
        struct dns_update_state *ustate;
+       struct timeval tv;
 
        if (!client->config->do_forward_update)
                return;
@@ -3388,7 +3412,9 @@ dhclient_schedule_updates(struct client_state *client, struct iaddr *addr,
                ustate->address = *addr;
                ustate->dns_update_timeout = 1;
 
-               add_timeout(cur_time + offset, client_dns_update_timeout,
+               tv.tv_sec = cur_time + offset;
+               tv.tv_usec = 0;
+               add_timeout(&tv, client_dns_update_timeout,
                            ustate, NULL, NULL);
        } else {
                log_error("Unable to allocate dns update state for %s.",
@@ -3404,6 +3430,7 @@ void client_dns_update_timeout (void *cp)
 {
        struct dns_update_state *ustate = cp;
        isc_result_t status = ISC_R_FAILURE;
+       struct timeval tv;
 
        /* XXX: DNS TTL is a problem we need to solve properly.  Until
         * that time, 300 is a placeholder default for something that is
@@ -3417,8 +3444,10 @@ void client_dns_update_timeout (void *cp)
        if (status == ISC_R_TIMEDOUT) {
                if (ustate->dns_update_timeout < 3600)
                        ustate->dns_update_timeout *= 10;
-               add_timeout(cur_time + ustate->dns_update_timeout,
-                           client_dns_update_timeout, ustate, NULL, NULL);
+               tv.tv_sec = cur_time + ustate->dns_update_timeout;
+               tv.tv_usec = 0;
+               add_timeout(&tv, client_dns_update_timeout,
+                           ustate, NULL, NULL);
        } else
                dfree(ustate, MDL);
 }
index 475fad98019ec67e821e0ab03b049ad02e5cb9a4..bf4c231997cdf087d4298b1ee5edf69fd022f68e 100644 (file)
@@ -40,8 +40,9 @@ static struct timeout *free_timeouts;
 void set_time(TIME t)
 {
        /* Do any outstanding timeouts. */
-       if (cur_time != t) {
-               cur_time = t;
+       if (cur_tv . tv_sec != t) {
+               cur_tv . tv_sec = t;
+               cur_tv . tv_usec = 0;
                process_outstanding_timeouts ((struct timeval *)0);
        }
 }
@@ -54,7 +55,9 @@ struct timeval *process_outstanding_timeouts (struct timeval *tvp)
       another:
        if (timeouts) {
                struct timeout *t;
-               if (timeouts -> when <= cur_time) {
+               if ((timeouts -> when . tv_sec < cur_tv . tv_sec) ||
+                   ((timeouts -> when . tv_sec == cur_tv . tv_sec) &&
+                    (timeouts -> when . tv_usec <= cur_tv . tv_usec))) {
                        t = timeouts;
                        timeouts = timeouts -> next;
                        (*(t -> func)) (t -> what);
@@ -65,8 +68,8 @@ struct timeval *process_outstanding_timeouts (struct timeval *tvp)
                        goto another;
                }
                if (tvp) {
-                       tvp -> tv_sec = timeouts -> when;
-                       tvp -> tv_usec = 0;
+                       tvp -> tv_sec = timeouts -> when . tv_sec;
+                       tvp -> tv_usec = timeouts -> when . tv_usec;
                }
                return tvp;
        } else
@@ -93,7 +96,7 @@ void dispatch ()
 }
 
 void add_timeout (when, where, what, ref, unref)
-       TIME when;
+       struct timeval *when;
        void (*where) PROTO ((void *));
        void *what;
        tvref_t ref;
@@ -137,12 +140,15 @@ void add_timeout (when, where, what, ref, unref)
                        q -> what = what;
        }
 
-       q -> when = when;
+       q -> when . tv_sec = when -> tv_sec;
+       q -> when . tv_usec = when -> tv_usec;
 
        /* Now sort this timeout into the timeout list. */
 
        /* Beginning of list? */
-       if (!timeouts || timeouts -> when > q -> when) {
+       if (!timeouts || (timeouts -> when . tv_sec > q -> when . tv_sec) ||
+           ((timeouts -> when . tv_sec == q -> when . tv_sec) &&
+            (timeouts -> when . tv_usec > q -> when . tv_usec))) {
                q -> next = timeouts;
                timeouts = q;
                return;
@@ -150,7 +156,9 @@ void add_timeout (when, where, what, ref, unref)
 
        /* Middle of list? */
        for (t = timeouts; t -> next; t = t -> next) {
-               if (t -> next -> when > q -> when) {
+               if ((t -> next -> when . tv_sec > q -> when . tv_sec) ||
+                   ((t -> next -> when . tv_sec == q -> when . tv_sec) &&
+                    (t -> next -> when . tv_usec > q -> when . tv_usec))) {
                        q -> next = t -> next;
                        t -> next = q;
                        return;
index 243c785752dbfeb47ead8b15d83844f62ea8ffc3..6afe74ab3f40a29a0cb56bf3409828bddc5f7193 100644 (file)
@@ -1046,17 +1046,17 @@ struct client_state {
        struct dhc6_lease *selected_lease;
        struct dhc6_lease *held_leases;
 
-       TIME start_time;
+       struct timeval start_time;
        u_int16_t elapsed;
        int txcount;
 
        /* See RFC3315 section 14. */
-       TIME RT;
-       TIME IRT;
-       TIME MRC;
-       TIME MRT;
-       TIME MRD;
-       TIME next_MRD;
+       TIME RT;                /* In hundredths of seconds. */
+       TIME IRT;               /* In hundredths of seconds. */
+       TIME MRC;               /* Count. */
+       TIME MRT;               /* In hundredths of seconds. */
+       TIME MRD;               /* In seconds, relative. */
+       TIME next_MRD;          /* In seconds, absolute. */
 
        /* Rather than a state, we use a function that shifts around
         * depending what stage of life the v6 state machine is in.
@@ -1142,7 +1142,7 @@ typedef void (*tvref_t)(void *, void *, const char *, int);
 typedef void (*tvunref_t)(void *, const char *, int);
 struct timeout {
        struct timeout *next;
-       TIME when;
+       struct timeval when;
        void (*func) PROTO ((void *));
        void *what;
        tvref_t ref;
@@ -1643,7 +1643,8 @@ int add_option(struct option_state *options,
                       unsigned int data_len);
 
 /* dhcpd.c */
-extern TIME cur_time;
+extern struct timeval cur_tv;
+#define cur_time cur_tv.tv_sec
 
 extern int ddns_update_style;
 
@@ -2362,7 +2363,7 @@ isc_result_t interface_stuff_values (omapi_object_t *,
                                     omapi_object_t *,
                                     omapi_object_t *);
 
-void add_timeout PROTO ((TIME, void (*) PROTO ((void *)), void *,
+void add_timeout PROTO ((struct timeval *, void (*) PROTO ((void *)), void *,
                         tvref_t, tvunref_t));
 void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *));
 void cancel_all_timeouts (void);
index 1e64e93ac2fed5695be78193106cae51a7c38802..4cd8bd944275e1a5e1676a0d89f96d90e15cf402 100644 (file)
@@ -120,7 +120,8 @@ int MRns_name_pton(const char *, u_char *, size_t);
 #define b64_ntop MRb64_ntop
 
 extern const struct res_sym __p_type_syms[];
-extern time_t cur_time;
+extern struct timeval cur_tv;
+#define cur_time cur_tv.tv_sec
 
 int dn_comp (const char *,
             unsigned char *, unsigned, unsigned char **, unsigned char **);
index 8ca68d4c9bef11126ee32dab73ae109a2e57919e..2f33a8a8b6b725701a8cced43b1d0da082ce068f 100644 (file)
@@ -38,7 +38,7 @@
 #include <sys/time.h>
 
 static omapi_io_object_t omapi_io_states;
-time_t cur_time;
+struct timeval cur_tv;
 
 OMAPI_OBJECT_ALLOC (omapi_io,
                    omapi_io_object_t, omapi_type_io_object)
@@ -227,7 +227,8 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo,
        /* First, see if the timeout has expired, and if so return. */
        if (t) {
                gettimeofday (&now, (struct timezone *)0);
-               cur_time = now.tv_sec;
+               cur_tv.tv_sec = now.tv_sec;
+               cur_tv.tv_usec = now.tv_usec;
                if (now.tv_sec > t -> tv_sec ||
                    (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec))
                        return ISC_R_TIMEDOUT;
@@ -295,8 +296,7 @@ isc_result_t omapi_one_dispatch (omapi_object_t *wo,
        count = select (max + 1, &r, &w, &x, t ? &to : (struct timeval *)0);
 
        /* Get the current time... */
-       gettimeofday (&now, (struct timezone *)0);
-       cur_time = now.tv_sec;
+       gettimeofday (&cur_tv, (struct timezone *)0);
 
        /* We probably have a bad file descriptor.   Figure out which one.
           When we find it, call the reaper function on it, which will
index 8563ae04fc478894ec3157edbde244a5f06e70f9..3df1a58605f16726566c2d18f5d8ffa6caf2271e 100644 (file)
@@ -34,6 +34,7 @@
 
 #include "dhcpd.h"
 #include <syslog.h>
+#include <sys/time.h>
 
 static void usage PROTO ((void));
 
@@ -266,7 +267,7 @@ main(int argc, char **argv) {
        }
 
        /* Get the current time... */
-       time(&cur_time);
+       gettimeofday(&cur_tv, NULL);
 
        /* Discover all the network interfaces. */
        discover_interfaces (DISCOVER_RELAY);
index 5eeef2c92ce8531b622756f7f782a5d23296f2a0..0d3207b1c43bda3210d9814b5bce3e635ce8287b 100644 (file)
@@ -1457,6 +1457,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
        unsigned i, j;
        int s1;
        int ignorep;
+       struct timeval tv;
 
        /* If we're already acking this lease, don't do it again. */
        if (lease -> state)
@@ -2792,7 +2793,9 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
                log_debug ("Ping timeout: %ld", (long)ping_timeout);
 #endif
 
-               add_timeout (cur_time + ping_timeout, lease_ping_timeout, lease,
+               tv . tv_sec = cur_time + ping_timeout;
+               tv . tv_usec = 0;
+               add_timeout (&tv, lease_ping_timeout, lease,
                             (tvref_t)lease_reference,
                             (tvunref_t)lease_dereference);
                ++outstanding_pings;
index 41e3813ad10e35ec23bc82bd9dd335239f6ebf84..8eda87274ba05734fb843fbba8e828d427eca7f8 100644 (file)
@@ -44,6 +44,7 @@ static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/";
 #include <errno.h>
 #include <limits.h>
 #include <sys/types.h>
+#include <sys/time.h>
 #include <signal.h>
 
 static void usage(void);
@@ -173,6 +174,7 @@ static void omapi_listener_start (void *foo)
 {
        omapi_object_t *listener;
        isc_result_t result;
+       struct timeval tv;
 
        listener = (omapi_object_t *)0;
        result = omapi_generic_new (&listener, MDL);
@@ -187,7 +189,9 @@ static void omapi_listener_start (void *foo)
        if (result != ISC_R_SUCCESS) {
                log_error ("Can't start OMAPI protocol: %s",
                           isc_result_totext (result));
-               add_timeout (cur_time + 5, omapi_listener_start, 0, 0, 0);
+               tv.tv_sec = cur_time + 5;
+               tv.tv_usec = 0;
+               add_timeout (&tv, omapi_listener_start, 0, 0, 0);
        }
        omapi_object_dereference (&listener, MDL);
 }
@@ -496,7 +500,7 @@ main(int argc, char **argv) {
        }
 
        /* Get the current time... */
-       time(&cur_time);
+       gettimeofday(&cur_tv, NULL);
 
        /* Set up the initial dhcp option universe. */
        initialize_common_option_spaces ();
@@ -1214,6 +1218,7 @@ static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
 #if defined (FAILOVER_PROTOCOL)
        int failover_connection_count = 0;
 #endif
+       struct timeval tv;
 
       oncemore:
        if (shutdown_state == shutdown_listeners ||
@@ -1299,7 +1304,9 @@ static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
                shutdown_time = cur_time;
                goto oncemore;
        }
-       add_timeout (cur_time + 1,
+       tv.tv_sec = cur_tv.tv_sec + 1;
+       tv.tv_usec = cur_tv.tv_usec;
+       add_timeout (&tv,
                     (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
        return ISC_R_SUCCESS;
 }
index fe4fe4818cc7b730fe47a278881f74bc1f594e7c..c12938a28ea1a965de7e9a60d76f29b633642772 100644 (file)
@@ -59,6 +59,7 @@ void dhcp_failover_startup ()
 {
        dhcp_failover_state_t *state;
        isc_result_t status;
+       struct timeval tv;
 
        for (state = failover_states; state; state = state -> next) {
                dhcp_failover_state_transition (state, "startup");
@@ -79,7 +80,9 @@ void dhcp_failover_startup ()
 #if defined (DEBUG_FAILOVER_TIMING)
                        log_info ("add_timeout +90 dhcp_failover_reconnect");
 #endif
-                       add_timeout (cur_time + 90,
+                       tv . tv_sec = cur_time + 90;
+                       tv . tv_usec = 0;
+                       add_timeout (&tv,
                                     dhcp_failover_reconnect, state,
                                     (tvref_t)
                                     dhcp_failover_state_reference,
@@ -96,7 +99,9 @@ void dhcp_failover_startup ()
                        log_info ("add_timeout +90 %s",
                                  "dhcp_failover_listener_restart");
 #endif
-                       add_timeout (cur_time + 90,
+                       tv . tv_sec = cur_time + 90;
+                       tv . tv_usec = 0;
+                       add_timeout (&tv,
                                     dhcp_failover_listener_restart,
                                     state,
                                     (tvref_t)omapi_object_reference,
@@ -279,6 +284,7 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
        dhcp_failover_state_t *s, *state = (dhcp_failover_state_t *)0;
        char *sname;
        int slen;
+       struct timeval tv;
 
        if (h -> type != dhcp_type_failover_link) {
                /* XXX shouldn't happen.   Put an assert here? */
@@ -302,7 +308,9 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
            log_info ("add_timeout +15 %s",
                      "dhcp_failover_link_startup_timeout");
 #endif
-           add_timeout (cur_time + 15,
+           tv . tv_sec = cur_time + 15;
+           tv . tv_usec = 0;
+           add_timeout (&tv,
                         dhcp_failover_link_startup_timeout,
                         link,
                         (tvref_t)dhcp_failover_link_reference,
@@ -326,7 +334,9 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
                    log_info ("add_timeout +5 %s",
                              "dhcp_failover_reconnect");
 #endif
-                   add_timeout (cur_time + 5, dhcp_failover_reconnect,
+                   tv . tv_sec = cur_time + 5;
+                   tv . tv_usec = 0;
+                   add_timeout (&tv, dhcp_failover_reconnect,
                                 state,
                                 (tvref_t)dhcp_failover_state_reference,
                                 (tvunref_t)dhcp_failover_state_dereference);
@@ -356,7 +366,9 @@ isc_result_t dhcp_failover_link_signal (omapi_object_t *h,
              log_info ("add_timeout +5 %s",
                        "dhcp_failover_reconnect");
 #endif
-             add_timeout (cur_time + 5, dhcp_failover_reconnect,
+             tv . tv_sec = cur_time + 5;
+             tv . tv_usec = 0;
+             add_timeout (&tv, dhcp_failover_reconnect,
                           state,
                           (tvref_t)dhcp_failover_state_reference,
                           (tvunref_t)dhcp_failover_state_dereference);
@@ -1195,6 +1207,7 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
        isc_result_t status;
        dhcp_failover_state_t *state;
        dhcp_failover_link_t *link;
+       struct timeval tv;
 
        if (!o || o -> type != dhcp_type_failover_state)
                return ISC_R_INVALIDARG;
@@ -1221,7 +1234,9 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
                        log_info ("add_timeout +90 %s",
                                  "dhcp_failover_reconnect");
 #endif
-                       add_timeout (cur_time + 90, dhcp_failover_reconnect,
+                       tv . tv_sec = cur_time + 90;
+                       tv . tv_usec = 0;
+                       add_timeout (&tv, dhcp_failover_reconnect,
                                     state,
                                     (tvref_t)dhcp_failover_state_reference,
                                     (tvunref_t)
@@ -1359,8 +1374,10 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
                              (int)state -> partner.max_response_delay / 3,
                              "dhcp_failover_send_contact");
 #endif
-                   add_timeout (cur_time +
-                                (int)state -> partner.max_response_delay / 3,
+                   tv . tv_sec = cur_time +
+                           (int)state -> partner.max_response_delay / 3;
+                   tv . tv_usec = 0;
+                   add_timeout (&tv,
                                 dhcp_failover_send_contact, state,
                                 (tvref_t)dhcp_failover_state_reference,
                                 (tvunref_t)dhcp_failover_state_dereference);
@@ -1369,8 +1386,10 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
                              (int)state -> me.max_response_delay,
                              "dhcp_failover_timeout");
 #endif
-                   add_timeout (cur_time +
-                                (int)state -> me.max_response_delay,
+                   tv . tv_sec = cur_time +
+                           (int)state -> me.max_response_delay;
+                   tv . tv_usec = 0;
+                   add_timeout (&tv,
                                 dhcp_failover_timeout, state,
                                 (tvref_t)dhcp_failover_state_reference,
                                 (tvunref_t)dhcp_failover_state_dereference);
@@ -1420,8 +1439,10 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
                              (int)state -> me.max_response_delay,
                              "dhcp_failover_timeout");
 #endif
-                   add_timeout (cur_time +
-                                (int)state -> me.max_response_delay,
+                   tv . tv_sec = cur_time +
+                           (int)state -> me.max_response_delay;
+                   tv . tv_usec = 0;
+                   add_timeout (&tv,
                                 dhcp_failover_timeout, state,
                                 (tvref_t)dhcp_failover_state_reference,
                                 (tvunref_t)dhcp_failover_state_dereference);
@@ -1649,6 +1670,7 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
     struct pool *p;
     struct shared_network *s;
     struct lease *l;
+    struct timeval tv;
 
     /* If we're in certain states where we're sending updates, and the peer
      * state changes, we need to re-schedule any pending updates just to
@@ -1772,7 +1794,9 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
            log_info ("add_timeout +15 %s",
                      "dhcp_failover_startup_timeout");
 #endif
-           add_timeout (cur_time + 15,
+           tv . tv_sec = cur_time + 15;
+           tv . tv_usec = 0;
+           add_timeout (&tv,
                         dhcp_failover_startup_timeout,
                         state,
                         (tvref_t)omapi_object_reference,
@@ -1790,7 +1814,9 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
                                    state -> me.stos + state -> mclt),
                              "dhcp_failover_startup_timeout");
 #endif
-                   add_timeout ((int)(state -> me.stos + state -> mclt),
+                   tv . tv_sec = (int)(state -> me.stos + state -> mclt);
+                   tv . tv_usec = 0;
+                   add_timeout (&tv,
                                 dhcp_failover_recover_done,
                                 state,
                                 (tvref_t)omapi_object_reference,
@@ -1828,7 +1854,9 @@ isc_result_t dhcp_failover_set_state (dhcp_failover_state_t *state,
                                      (int)(cur_time - p->next_event_time),
                                      "pool_timer");
 #endif
-                           add_timeout(p->next_event_time, pool_timer, p,
+                           tv.tv_sec = p->next_event_time;
+                           tv.tv_usec = 0;
+                           add_timeout(&tv, pool_timer, p,
                                        (tvref_t)pool_reference,
                                        (tvunref_t)pool_dereference);
                        }
@@ -2496,6 +2524,7 @@ dhcp_failover_pool_check(struct pool *pool)
 {
        dhcp_failover_state_t *peer;
        TIME est1, est2;
+       struct timeval tv;
 
        peer = pool->failover_peer;
 
@@ -2574,7 +2603,9 @@ dhcp_failover_pool_check(struct pool *pool)
        log_info("add_timeout +%d dhcp_failover_pool_rebalance",
                 est1 - cur_time);
 #endif
-       add_timeout(est1, dhcp_failover_pool_rebalance, peer,
+       tv.tv_sec = est1;
+       tv.tv_usec = 0;
+       add_timeout(&tv, dhcp_failover_pool_rebalance, peer,
                        (tvref_t)dhcp_failover_state_reference,
                        (tvunref_t)dhcp_failover_state_dereference);
 }
@@ -2750,6 +2781,8 @@ void dhcp_failover_toack_queue_timeout (void *vs)
 int dhcp_failover_queue_ack (dhcp_failover_state_t *state,
                             failover_message_t *msg)
 {
+       struct timeval tv;
+
        if (state -> toack_queue_head) {
                failover_message_reference
                        (&state -> toack_queue_tail -> next, msg, MDL);
@@ -2774,7 +2807,9 @@ int dhcp_failover_queue_ack (dhcp_failover_state_t *state,
                log_info ("add_timeout +2 %s",
                          "dhcp_failover_toack_queue_timeout");
 #endif
-               add_timeout (cur_time + 2,
+               tv . tv_sec = cur_time + 2;
+               tv . tv_usec = 0;
+               add_timeout (&tv,
                             dhcp_failover_toack_queue_timeout, state,
                             (tvref_t)dhcp_failover_state_reference,
                             (tvunref_t)dhcp_failover_state_dereference);
@@ -2915,6 +2950,7 @@ void dhcp_failover_reconnect (void *vs)
 {
        dhcp_failover_state_t *state = vs;
        isc_result_t status;
+       struct timeval tv;
 
 #if defined (DEBUG_FAILOVER_TIMING)
        log_info ("dhcp_failover_reconnect");
@@ -2932,7 +2968,9 @@ void dhcp_failover_reconnect (void *vs)
                log_info ("add_timeout +90 %s",
                          "dhcp_failover_listener_restart");
 #endif
-               add_timeout (cur_time + 90,
+               tv . tv_sec = cur_time + 90;
+               tv . tv_usec = 0;
+               add_timeout (&tv,
                             dhcp_failover_listener_restart, state,
                             (tvref_t)dhcp_failover_state_reference,
                             (tvunref_t)dhcp_failover_state_dereference);
@@ -2970,6 +3008,7 @@ void dhcp_failover_listener_restart (void *vs)
 {
        dhcp_failover_state_t *state = vs;
        isc_result_t status;
+       struct timeval tv;
 
 #if defined (DEBUG_FAILOVER_TIMING)
        log_info ("dhcp_failover_listener_restart");
@@ -2983,7 +3022,9 @@ void dhcp_failover_listener_restart (void *vs)
                log_info ("add_timeout +90 %s",
                          "dhcp_failover_listener_restart");
 #endif
-               add_timeout (cur_time + 90,
+               tv . tv_sec = cur_time + 90;
+               tv . tv_usec = 0;
+               add_timeout (&tv,
                             dhcp_failover_listener_restart, state,
                             (tvref_t)dhcp_failover_state_reference,
                             (tvunref_t)dhcp_failover_state_dereference);
@@ -4021,6 +4062,7 @@ isc_result_t dhcp_failover_put_message (dhcp_failover_link_t *link,
        unsigned char *opbuf;
        isc_result_t status = ISC_R_SUCCESS;
        unsigned char cbuf;
+       struct timeval tv;
 
        /* Run through the argument list once to compute the length of
           the option portion of the message. */
@@ -4104,9 +4146,11 @@ isc_result_t dhcp_failover_put_message (dhcp_failover_link_t *link,
                                partner.max_response_delay) / 3,
                          "dhcp_failover_send_contact");
 #endif
-               add_timeout (cur_time +
-                            (int)(link -> state_object ->
-                                  partner.max_response_delay) / 3,
+               tv . tv_sec = cur_time +
+                       (int)(link -> state_object ->
+                             partner.max_response_delay) / 3;
+               tv . tv_usec = 0;
+               add_timeout (&tv,
                             dhcp_failover_send_contact, link -> state_object,
                             (tvref_t)dhcp_failover_state_reference,
                             (tvunref_t)dhcp_failover_state_dereference);
@@ -5097,6 +5141,7 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state,
        const char *message = "no memory";
        u_int32_t pot_expire;
        int send_to_backup = ISC_FALSE;
+       struct timeval tv;
 
        ia.len = sizeof msg -> assigned_addr;
        memcpy (ia.iabuf, &msg -> assigned_addr, ia.len);
@@ -5198,8 +5243,9 @@ isc_result_t dhcp_failover_process_bind_ack (dhcp_failover_state_t *state,
                   succession (e.g., when stealing leases from the
                   secondary), we do not do an immediate commit for
                   each one. */
-               add_timeout(cur_time + 2,
-                           commit_leases_timeout, (void *)0, 0, 0);
+               tv.tv_sec = cur_time + 2;
+               tv.tv_usec = 0;
+               add_timeout(&tv, commit_leases_timeout, (void *)0, 0, 0);
        }
 
       unqueue:
@@ -5361,6 +5407,8 @@ isc_result_t
 dhcp_failover_process_update_done (dhcp_failover_state_t *state,
                                   failover_message_t *msg)
 {
+       struct timeval tv;
+
        log_info ("failover peer %s: peer update completed.",
                  state -> name);
 
@@ -5419,7 +5467,9 @@ dhcp_failover_process_update_done (dhcp_failover_state_t *state,
                                        state -> me.stos + state -> mclt),
                                  "dhcp_failover_recover_done");
 #endif
-                       add_timeout ((int)(state -> me.stos + state -> mclt),
+                       tv . tv_sec = (int)(state -> me.stos + state -> mclt);
+                       tv . tv_usec = 0;
+                       add_timeout (&tv,
                                     dhcp_failover_recover_done,
                                     state,
                                     (tvref_t)omapi_object_reference,
index 74ab7789fc98b78b362e2a162860dbf4ce00fc49..0b99335ef3c8bd4466af7d6f5cc826c38d9e376d 100644 (file)
@@ -1060,6 +1060,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
        if (pimmediate && !commit)
                return 0;
 #endif
+       struct timeval tv;
 
        /* If there is no sample lease, just do the move. */
        if (!lease)
@@ -1335,7 +1336,9 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
            (comp -> sort_time < comp -> pool -> next_event_time ||
             comp -> pool -> next_event_time == MIN_TIME)) {
                comp -> pool -> next_event_time = comp -> sort_time;
-               add_timeout (comp -> pool -> next_event_time,
+               tv . tv_sec = comp -> pool -> next_event_time;
+               tv . tv_usec = 0;
+               add_timeout (&tv,
                             pool_timer, comp -> pool,
                             (tvref_t)pool_reference,
                             (tvunref_t)pool_dereference);
@@ -1753,6 +1756,7 @@ void pool_timer (vpool)
        struct lease **lptr[RESERVED_LEASES+1];
        TIME next_expiry = MAX_TIME;
        int i;
+       struct timeval tv;
 
        pool = (struct pool *)vpool;
 
@@ -1821,7 +1825,9 @@ void pool_timer (vpool)
        }
        if (next_expiry != MAX_TIME) {
                pool -> next_event_time = next_expiry;
-               add_timeout (pool -> next_event_time, pool_timer, pool,
+               tv . tv_sec = pool -> next_event_time;
+               tv . tv_usec = 0;
+               add_timeout (&tv, pool_timer, pool,
                             (tvref_t)pool_reference,
                             (tvunref_t)pool_dereference);
        } else
index 0c08ea930d96120eed14a0abb7a54ede2cc66df0..6c208e9f5ffe1e9d02bca645d4beb9f573ac4377 100644 (file)
@@ -2136,6 +2136,7 @@ schedule_lease_timeout(struct ipv6_pool *pool) {
        struct iaaddr *tmp;
        time_t timeout;
        time_t next_timeout;
+       struct timeval tv;
 
        next_timeout = MAX_TIME;
 
@@ -2158,7 +2159,9 @@ schedule_lease_timeout(struct ipv6_pool *pool) {
        }
 
        if (next_timeout < MAX_TIME) {
-               add_timeout(next_timeout, lease_timeout_support, pool,
+               tv.tv_sec = next_timeout;
+               tv.tv_usec = 0;
+               add_timeout(&tv, lease_timeout_support, pool,
                            (tvref_t)ipv6_pool_reference, 
                            (tvunref_t)ipv6_pool_dereference);
        }