diff --git a/RELNOTES b/RELNOTES index 0efba5ef..df73ecc6 100644 --- a/RELNOTES +++ b/RELNOTES @@ -89,6 +89,8 @@ suggested fixes to . - 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 diff --git a/client/dhc6.c b/client/dhc6.c index c84a8a53..a9902f02 100644 --- a/client/dhc6.c +++ b/client/dhc6.c @@ -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); diff --git a/client/dhclient.c b/client/dhclient.c index c2276875..bd630ef9 100644 --- a/client/dhclient.c +++ b/client/dhclient.c @@ -34,6 +34,7 @@ #include #include #include +#include #include #include @@ -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); } diff --git a/common/dispatch.c b/common/dispatch.c index 475fad98..bf4c2319 100644 --- a/common/dispatch.c +++ b/common/dispatch.c @@ -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; diff --git a/includes/dhcpd.h b/includes/dhcpd.h index 243c7857..6afe74ab 100644 --- a/includes/dhcpd.h +++ b/includes/dhcpd.h @@ -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); diff --git a/includes/minires/minires.h b/includes/minires/minires.h index 1e64e93a..4cd8bd94 100644 --- a/includes/minires/minires.h +++ b/includes/minires/minires.h @@ -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 **); diff --git a/omapip/dispatch.c b/omapip/dispatch.c index 8ca68d4c..2f33a8a8 100644 --- a/omapip/dispatch.c +++ b/omapip/dispatch.c @@ -38,7 +38,7 @@ #include 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 diff --git a/relay/dhcrelay.c b/relay/dhcrelay.c index 8563ae04..3df1a586 100644 --- a/relay/dhcrelay.c +++ b/relay/dhcrelay.c @@ -34,6 +34,7 @@ #include "dhcpd.h" #include +#include 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); diff --git a/server/dhcp.c b/server/dhcp.c index 5eeef2c9..0d3207b1 100644 --- a/server/dhcp.c +++ b/server/dhcp.c @@ -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; diff --git a/server/dhcpd.c b/server/dhcpd.c index 41e3813a..8eda8727 100644 --- a/server/dhcpd.c +++ b/server/dhcpd.c @@ -44,6 +44,7 @@ static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/"; #include #include #include +#include #include 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; } diff --git a/server/failover.c b/server/failover.c index fe4fe481..c12938a2 100644 --- a/server/failover.c +++ b/server/failover.c @@ -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, diff --git a/server/mdb.c b/server/mdb.c index 74ab7789..0b99335e 100644 --- a/server/mdb.c +++ b/server/mdb.c @@ -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 diff --git a/server/mdb6.c b/server/mdb6.c index 0c08ea93..6c208e9f 100644 --- a/server/mdb6.c +++ b/server/mdb6.c @@ -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); }