2
0
mirror of https://gitlab.isc.org/isc-projects/dhcp synced 2025-08-28 12:57:42 +00:00

finer granularity timers

This commit is contained in:
Francis Dupont 2008-01-03 00:30:14 +00:00
parent 1d9774ab57
commit be62cf0675
13 changed files with 459 additions and 157 deletions

View File

@ -89,6 +89,8 @@ suggested fixes to <dhcp-users@isc.org>.
- Return in place of raise an impossible condition when one tries to release - Return in place of raise an impossible condition when one tries to release
an empty active lease. an empty active lease.
- Timer granularity is now 1/100s in the DHCPv6 client.
Changes since 4.0.0b3 Changes since 4.0.0b3
- The reverse dns name for PTR updates on IPv6 addresses has been fixed to - The reverse dns name for PTR updates on IPv6 addresses has been fixed to

View File

@ -284,7 +284,6 @@ dhc6_retrans_init(struct client_state *client)
int xid; int xid;
/* Initialize timers. */ /* Initialize timers. */
client->start_time = cur_time;
client->txcount = 0; client->txcount = 0;
client->RT = client->IRT + dhc6_rand(client->IRT); client->RT = client->IRT + dhc6_rand(client->IRT);
@ -309,11 +308,23 @@ dhc6_retrans_init(struct client_state *client)
static void static void
dhc6_retrans_advance(struct client_state *client) 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. */ /* 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 /* RT for each subsequent message transmission is based on the previous
* value of RT: * 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 /* Further, if there's an MRD, we should wake up upon reaching
* the MRD rather than at some point after it. * the MRD rather than at some point after it.
*/ */
if ((client->MRD != 0) && ((elapsed + client->RT) > client->MRD)) { if (client->MRD == 0) {
client->RT = (client->start_time + client->MRD) - cur_time; /* 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++; client->txcount++;
} }
@ -1204,12 +1232,14 @@ dhc6_score_lease(struct client_state *client, struct dhc6_lease *lease)
void void
start_init6(struct client_state *client) start_init6(struct client_state *client)
{ {
struct timeval tv;
log_debug("PRC: Soliciting for leases (INIT)."); log_debug("PRC: Soliciting for leases (INIT).");
client->state = S_INIT; client->state = S_INIT;
/* Initialize timers, RFC3315 section 17.1.2. */ /* Initialize timers, RFC3315 section 17.1.2. */
client->IRT = SOL_TIMEOUT; client->IRT = SOL_TIMEOUT * 100;
client->MRT = SOL_MAX_RT; client->MRT = SOL_MAX_RT * 100;
client->MRC = 0; client->MRC = 0;
client->MRD = 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 * Also, the first RT MUST be selected to be strictly greater than IRT
* by choosing RAND to be strictly greater than 0. * 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) if (client->RT <= client->IRT)
client->RT = client->IRT + 1; 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 * between 0 and SOL_MAX_DELAY seconds. The good news is
* SOL_MAX_DELAY is 1. * SOL_MAX_DELAY is 1.
*/ */
add_timeout(cur_time + (random() % SOL_MAX_DELAY), do_init6, client, tv.tv_sec = cur_tv.tv_sec;
NULL, NULL); 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) if (nowait)
go_daemon(); go_daemon();
@ -1242,6 +1282,8 @@ start_init6(struct client_state *client)
void void
start_confirm6(struct client_state *client) start_confirm6(struct client_state *client)
{ {
struct timeval tv;
/* If there is no active lease, there is nothing to check. */ /* If there is no active lease, there is nothing to check. */
if (client->active_lease == NULL) { if (client->active_lease == NULL) {
start_init6(client); start_init6(client);
@ -1252,8 +1294,8 @@ start_confirm6(struct client_state *client)
client->state = S_REBOOTING; client->state = S_REBOOTING;
/* Initialize timers, RFC3315 section 17.1.3. */ /* Initialize timers, RFC3315 section 17.1.3. */
client->IRT = CNF_TIMEOUT; client->IRT = CNF_TIMEOUT * 100;
client->MRT = CNF_MAX_RT; client->MRT = CNF_MAX_RT * 100;
client->MRC = 0; client->MRC = 0;
client->MRD = CNF_MAX_RD; client->MRD = CNF_MAX_RD;
@ -1261,8 +1303,18 @@ start_confirm6(struct client_state *client)
client->v6_handler = reply_handler; client->v6_handler = reply_handler;
add_timeout(cur_time + (random() % CNF_MAX_DELAY), do_confirm6, client, /* RFC3315 section 18.1.2 says we MUST start the first packet
NULL, NULL); * 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. /* do_init6() marshals and transmits a solicit.
@ -1276,7 +1328,7 @@ do_init6(void *input)
struct data_string ds; struct data_string ds;
struct data_string ia; struct data_string ia;
struct data_string addr; struct data_string addr;
TIME elapsed; struct timeval elapsed, tv;
u_int32_t t1, t2; u_int32_t t1, t2;
int idx, len, send_ret; int idx, len, send_ret;
@ -1295,8 +1347,22 @@ do_init6(void *input)
return; 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."); log_info("Max retransmission duration exceeded.");
return; return;
} }
@ -1313,11 +1379,18 @@ do_init6(void *input)
memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3); memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
/* Form an elapsed option. */ /* 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; client->elapsed = 0xffff;
else } else {
client->elapsed = elapsed * 100; client->elapsed = elapsed.tv_sec * 100;
client->elapsed += elapsed.tv_usec / 10000;
}
if (client->elapsed == 0)
log_debug("XMT: Forming Solicit, 0 ms elapsed.");
else
log_debug("XMT: Forming Solicit, %u0 ms elapsed.", log_debug("XMT: Forming Solicit, %u0 ms elapsed.",
(unsigned)client->elapsed); (unsigned)client->elapsed);
@ -1415,7 +1488,7 @@ do_init6(void *input)
/* Transmit and wait. */ /* 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, client->name ? client->name : client->interface->name,
(long int)client->RT); (long int)client->RT);
@ -1428,7 +1501,14 @@ do_init6(void *input)
data_string_forget(&ds, MDL); 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); dhc6_retrans_advance(client);
} }
@ -1442,7 +1522,7 @@ do_confirm6(void *input)
struct client_state *client; struct client_state *client;
struct data_string ds; struct data_string ds;
int send_ret; int send_ret;
TIME elapsed; struct timeval elapsed, tv;
client = input; client = input;
@ -1469,8 +1549,22 @@ do_confirm6(void *input)
return; 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."); log_info("Max retransmission duration exceeded.");
start_bound(client); start_bound(client);
return; return;
@ -1488,11 +1582,18 @@ do_confirm6(void *input)
memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3); memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
/* Form an elapsed option. */ /* 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; client->elapsed = 0xffff;
else } else {
client->elapsed = elapsed * 100; client->elapsed = elapsed.tv_sec * 100;
client->elapsed += elapsed.tv_usec / 10000;
}
if (client->elapsed == 0)
log_debug("XMT: Forming Confirm, 0 ms elapsed.");
else
log_debug("XMT: Forming Confirm, %u0 ms elapsed.", log_debug("XMT: Forming Confirm, %u0 ms elapsed.",
(unsigned)client->elapsed); (unsigned)client->elapsed);
@ -1516,7 +1617,7 @@ do_confirm6(void *input)
/* Transmit and wait. */ /* 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, client->name ? client->name : client->interface->name,
(long int)client->RT); (long int)client->RT);
@ -1529,7 +1630,14 @@ do_confirm6(void *input)
data_string_forget(&ds, MDL); 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); dhc6_retrans_advance(client);
} }
@ -1555,9 +1663,9 @@ start_release6(struct client_state *client)
unconfigure6(client, "RELEASE6"); unconfigure6(client, "RELEASE6");
/* Set timers per RFC3315 section 18.1.1. */ /* Set timers per RFC3315 section 18.1.1. */
client->IRT = REL_TIMEOUT; client->IRT = REL_TIMEOUT * 100;
client->MRT = 0; client->MRT = 0;
client->MRC = REL_MAX_RC; client->MRC = REL_MAX_RC * 100;
client->MRD = 0; client->MRD = 0;
dhc6_retrans_init(client); dhc6_retrans_init(client);
@ -1577,6 +1685,7 @@ do_release6(void *input)
struct data_string ds; struct data_string ds;
struct option_cache *oc; struct option_cache *oc;
int send_ret; int send_ret;
struct timeval tv;
client = input; client = input;
@ -1588,6 +1697,14 @@ do_release6(void *input)
return; 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 * Check whether the server has sent a unicast option; if so, we can
* use the address it specified. * use the address it specified.
@ -1636,7 +1753,7 @@ do_release6(void *input)
} }
/* Transmit and wait. */ /* 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, client->name ? client->name : client->interface->name,
(long int)client->RT); (long int)client->RT);
@ -1649,7 +1766,14 @@ do_release6(void *input)
data_string_forget(&ds, MDL); 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); dhc6_retrans_advance(client);
} }
@ -2359,8 +2483,8 @@ start_selecting6(struct client_state *client)
client->selected_lease = lease; client->selected_lease = lease;
/* Set timers per RFC3315 section 18.1.1. */ /* Set timers per RFC3315 section 18.1.1. */
client->IRT = REQ_TIMEOUT; client->IRT = REQ_TIMEOUT * 100;
client->MRT = REQ_MAX_RT; client->MRT = REQ_MAX_RT * 100;
client->MRC = REQ_MAX_RC; client->MRC = REQ_MAX_RC;
client->MRD = 0; client->MRD = 0;
@ -2382,7 +2506,7 @@ do_select6(void *input)
struct client_state *client; struct client_state *client;
struct dhc6_lease *lease; struct dhc6_lease *lease;
struct data_string ds; struct data_string ds;
TIME elapsed; struct timeval elapsed, tv;
int abort = ISC_FALSE; int abort = ISC_FALSE;
int send_ret; int send_ret;
@ -2401,8 +2525,22 @@ do_select6(void *input)
abort = ISC_TRUE; 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."); log_info("Max retransmission duration exceeded.");
abort = ISC_TRUE; abort = ISC_TRUE;
} }
@ -2447,11 +2585,18 @@ do_select6(void *input)
memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3); memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3);
/* Form an elapsed option. */ /* 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; client->elapsed = 0xffff;
else } else {
client->elapsed = elapsed * 100; client->elapsed = elapsed.tv_sec * 100;
client->elapsed += elapsed.tv_usec / 10000;
}
if (client->elapsed == 0)
log_debug("XMT: Forming Request, 0 ms elapsed.");
else
log_debug("XMT: Forming Request, %u0 ms elapsed.", log_debug("XMT: Forming Request, %u0 ms elapsed.",
(unsigned)client->elapsed); (unsigned)client->elapsed);
@ -2473,7 +2618,7 @@ do_select6(void *input)
return; return;
} }
log_info("XMT: Request on %s, interval %ld", log_info("XMT: Request on %s, interval %ld0ms.",
client->name ? client->name : client->interface->name, client->name ? client->name : client->interface->name,
(long int)client->RT); (long int)client->RT);
@ -2486,7 +2631,14 @@ do_select6(void *input)
data_string_forget(&ds, MDL); 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); 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, TIME renew=MAX_TIME, rebind=MAX_TIME, depref=MAX_TIME,
lo_expire=MAX_TIME, hi_expire=0, tmp; lo_expire=MAX_TIME, hi_expire=0, tmp;
int has_addrs = ISC_FALSE; int has_addrs = ISC_FALSE;
struct timeval tv;
lease = client->active_lease; lease = client->active_lease;
@ -2955,8 +3108,10 @@ dhc6_check_times(struct client_state *client)
"to run for %u seconds.", "to run for %u seconds.",
(int)(renew - cur_time), (int)(renew - cur_time),
(unsigned)(rebind - renew)); (unsigned)(rebind - renew));
client->next_MRD = rebind - cur_time; client->next_MRD = rebind;
add_timeout(renew, start_renew6, client, NULL, NULL); tv.tv_sec = renew;
tv.tv_usec = 0;
add_timeout(&tv, start_renew6, client, NULL, NULL);
break; break;
} }
@ -2972,8 +3127,10 @@ dhc6_check_times(struct client_state *client)
"to run for %d seconds.", "to run for %d seconds.",
(int)(rebind - cur_time), (int)(rebind - cur_time),
(int)(hi_expire - rebind)); (int)(hi_expire - rebind));
client->next_MRD = hi_expire - cur_time; client->next_MRD = hi_expire;
add_timeout(rebind, start_rebind6, client, NULL, NULL); tv.tv_sec = rebind;
tv.tv_usec = 0;
add_timeout(&tv, start_rebind6, client, NULL, NULL);
} }
break; break;
@ -2996,12 +3153,16 @@ dhc6_check_times(struct client_state *client)
if (depref != MAX_TIME) { if (depref != MAX_TIME) {
log_debug("PRC: Depreference scheduled in %d seconds.", log_debug("PRC: Depreference scheduled in %d seconds.",
(int)(depref - cur_time)); (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) { if (lo_expire != MAX_TIME) {
log_debug("PRC: Expiration scheduled in %d seconds.", log_debug("PRC: Expiration scheduled in %d seconds.",
(int)(lo_expire - cur_time)); (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. /* 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 * Note that client->next_MRD must be set before entering this function -
* be set to the time at which the client should start Rebinding. * it must be set to the time at which the client should start Rebinding.
*/ */
void void
start_renew6(void *input) start_renew6(void *input)
@ -3254,13 +3415,13 @@ start_renew6(void *input)
client->v6_handler = reply_handler; client->v6_handler = reply_handler;
/* Times per RFC3315 section 18.1.3. */ /* Times per RFC3315 section 18.1.3. */
client->IRT = REN_TIMEOUT; client->IRT = REN_TIMEOUT * 100;
client->MRT = REN_MAX_RT; client->MRT = REN_MAX_RT * 100;
client->MRC = 0; client->MRC = 0;
/* MRD is special in renew - we need to set it by checking timer /* MRD is special in renew - we need to set it by checking timer
* state. * state.
*/ */
client->MRD = client->next_MRD; client->MRD = client->next_MRD - cur_time;
dhc6_retrans_init(client); dhc6_retrans_init(client);
@ -3280,7 +3441,7 @@ do_refresh6(void *input)
struct data_string ds; struct data_string ds;
struct client_state *client; struct client_state *client;
struct dhc6_lease *lease; struct dhc6_lease *lease;
TIME elapsed; struct timeval elapsed, tv;
int send_ret; int send_ret;
client = (struct client_state *)input; client = (struct client_state *)input;
@ -3302,9 +3463,23 @@ do_refresh6(void *input)
client->refresh_type, MDL); 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)) || 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. */ /* We're done. Move on to the next phase, if any. */
dhc6_check_times(client); dhc6_check_times(client);
return; return;
@ -3345,11 +3520,20 @@ do_refresh6(void *input)
ds.buffer->data[0] = client->refresh_type; ds.buffer->data[0] = client->refresh_type;
memcpy(ds.buffer->data + 1, client->dhcpv6_transaction_id, 3); 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; client->elapsed = 0xffff;
else } else {
client->elapsed = elapsed * 100; client->elapsed = elapsed.tv_sec * 100;
client->elapsed += elapsed.tv_usec / 10000;
}
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.", log_debug("XMT: Forming %s, %u0 ms elapsed.",
dhcpv6_type_names[client->refresh_type], dhcpv6_type_names[client->refresh_type],
(unsigned)client->elapsed); (unsigned)client->elapsed);
@ -3371,7 +3555,7 @@ do_refresh6(void *input)
return; return;
} }
log_info("XMT: %s on %s, interval %ld", log_info("XMT: %s on %s, interval %ld0ms.",
dhcpv6_type_names[client->refresh_type], dhcpv6_type_names[client->refresh_type],
client->name ? client->name : client->interface->name, client->name ? client->name : client->interface->name,
(long int)client->RT); (long int)client->RT);
@ -3385,13 +3569,20 @@ do_refresh6(void *input)
data_string_forget(&ds, MDL); 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); dhc6_retrans_advance(client);
} }
/* start_rebind6() gets us all set up to go and rebind a lease. Note that /* 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 * MRD must be set to the maximum time any address in the packet will
* expire. * expire.
*/ */
@ -3409,13 +3600,13 @@ start_rebind6(void *input)
client->v6_handler = reply_handler; client->v6_handler = reply_handler;
/* Times per RFC3315 section 18.1.4. */ /* Times per RFC3315 section 18.1.4. */
client->IRT = REB_TIMEOUT; client->IRT = REB_TIMEOUT * 100;
client->MRT = REB_MAX_RT; client->MRT = REB_MAX_RT * 100;
client->MRC = 0; client->MRC = 0;
/* MRD is special in rebind - it's determined by the timer /* MRD is special in rebind - it's determined by the timer
* state. * state.
*/ */
client->MRD = client->next_MRD; client->MRD = client->next_MRD - cur_time;
dhc6_retrans_init(client); dhc6_retrans_init(client);

View File

@ -34,6 +34,7 @@
#include <syslog.h> #include <syslog.h>
#include <signal.h> #include <signal.h>
#include <errno.h> #include <errno.h>
#include <sys/time.h>
#include <sys/wait.h> #include <sys/wait.h>
#include <limits.h> #include <limits.h>
@ -91,6 +92,7 @@ main(int argc, char **argv) {
isc_result_t status; isc_result_t status;
int exit_mode = 0; int exit_mode = 0;
int release_mode = 0; int release_mode = 0;
struct timeval tv;
omapi_object_t *listener; omapi_object_t *listener;
isc_result_t result; isc_result_t result;
int persist = 0; int persist = 0;
@ -342,7 +344,7 @@ main(int argc, char **argv) {
} }
/* Get the current time... */ /* Get the current time... */
time(&cur_time); gettimeofday(&cur_tv, NULL);
sockaddr_broadcast.sin_family = AF_INET; sockaddr_broadcast.sin_family = AF_INET;
sockaddr_broadcast.sin_port = remote_port; sockaddr_broadcast.sin_port = remote_port;
@ -492,8 +494,10 @@ main(int argc, char **argv) {
/* Set up a timeout to start the /* Set up a timeout to start the
* initialization process. * initialization process.
*/ */
add_timeout(cur_time + random() % 5, tv.tv_sec = cur_time + random() % 5;
state_reboot, client, 0, 0); tv.tv_usec = 0;
add_timeout(&tv, state_reboot,
client, 0, 0);
} }
} }
} }
@ -927,6 +931,8 @@ void dhcpack (packet)
void bind_lease (client) void bind_lease (client)
struct client_state *client; struct client_state *client;
{ {
struct timeval tv;
/* Remember the medium. */ /* Remember the medium. */
client -> new -> medium = client -> medium; client -> new -> medium = client -> medium;
@ -966,8 +972,9 @@ void bind_lease (client)
client -> new = (struct client_lease *)0; client -> new = (struct client_lease *)0;
/* Set up a timeout to start the renewal process. */ /* Set up a timeout to start the renewal process. */
add_timeout (client -> active -> renewal, tv . tv_sec = client -> active -> renewal;
state_bound, client, 0, 0); tv . tv_usec = 0;
add_timeout (&tv, state_bound, client, 0, 0);
log_info ("bound to %s -- renewal in %ld seconds.", log_info ("bound to %s -- renewal in %ld seconds.",
piaddr (client -> active -> address), piaddr (client -> active -> address),
@ -1217,6 +1224,7 @@ void dhcpoffer (packet)
int stop_selecting; int stop_selecting;
const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY"; const char *name = packet -> packet_type ? "DHCPOFFER" : "BOOTREPLY";
char obuf [1024]; char obuf [1024];
struct timeval tv;
#ifdef DEBUG_PACKET #ifdef DEBUG_PACKET
dump_packet (packet); dump_packet (packet);
@ -1329,7 +1337,9 @@ void dhcpoffer (packet)
if (stop_selecting <= 0) if (stop_selecting <= 0)
state_selecting (client); state_selecting (client);
else { 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); cancel_timeout (send_discover, client);
} }
log_info ("%s", obuf); log_info ("%s", obuf);
@ -1546,6 +1556,7 @@ void send_discover (cpp)
int result; int result;
int interval; int interval;
int increase = 1; int increase = 1;
struct timeval tv;
/* Figure out how long it's been since we started transmitting. */ /* Figure out how long it's been since we started transmitting. */
interval = cur_time - client -> first_sending; interval = cur_time - client -> first_sending;
@ -1631,8 +1642,9 @@ void send_discover (cpp)
inaddr_any, &sockaddr_broadcast, inaddr_any, &sockaddr_broadcast,
(struct hardware *)0); (struct hardware *)0);
add_timeout (cur_time + client -> interval, tv . tv_sec = cur_time + client -> interval;
send_discover, client, 0, 0); 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 /* 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_state *client = cpp;
struct client_lease *loop; struct client_lease *loop;
struct client_lease *lp; struct client_lease *lp;
struct timeval tv;
loop = lp = client -> active; loop = lp = client -> active;
@ -1679,8 +1692,9 @@ void state_panic (cpp)
log_info ("bound: renewal in %ld %s.", log_info ("bound: renewal in %ld %s.",
(long)(client -> active -> renewal - (long)(client -> active -> renewal -
cur_time), "seconds"); cur_time), "seconds");
add_timeout (client -> active -> renewal, tv . tv_sec = client -> active -> renewal;
state_bound, client, 0, 0); tv . tv_usec = 0;
add_timeout (&tv, state_bound, client, 0, 0);
} else { } else {
client -> state = S_BOUND; client -> state = S_BOUND;
log_info ("bound: immediate renewal."); log_info ("bound: immediate renewal.");
@ -1736,10 +1750,11 @@ void state_panic (cpp)
script_write_params (client, "alias_", client -> alias); script_write_params (client, "alias_", client -> alias);
script_go (client); script_go (client);
client -> state = S_INIT; client -> state = S_INIT;
add_timeout (cur_time + tv . tv_sec = cur_time +
((client -> config -> retry_interval + 1) / 2 + ((client -> config -> retry_interval + 1) / 2 +
(random () % client -> config -> retry_interval)), (random () % client -> config -> retry_interval));
state_init, client, 0, 0); tv . tv_usec = 0;
add_timeout (&tv, state_init, client, 0, 0);
go_daemon (); go_daemon ();
} }
@ -1752,6 +1767,7 @@ void send_request (cpp)
int interval; int interval;
struct sockaddr_in destination; struct sockaddr_in destination;
struct in_addr from; struct in_addr from;
struct timeval tv;
/* Figure out how long it's been since we started transmitting. */ /* Figure out how long it's been since we started transmitting. */
interval = cur_time - client -> first_sending; interval = cur_time - client -> first_sending;
@ -1893,8 +1909,9 @@ void send_request (cpp)
from, &destination, from, &destination,
(struct hardware *)0); (struct hardware *)0);
add_timeout (cur_time + client -> interval, tv . tv_sec = cur_time + client -> interval;
send_request, client, 0, 0); tv . tv_usec = 0;
add_timeout (&tv, send_request, client, 0, 0);
} }
void send_decline (cpp) void send_decline (cpp)
@ -2961,7 +2978,7 @@ int script_go (client)
client -> envc = 0; client -> envc = 0;
} }
dfree (envp, MDL); dfree (envp, MDL);
time(&cur_time); gettimeofday(&cur_tv, NULL);
return (WIFEXITED (wstatus) ? return (WIFEXITED (wstatus) ?
WEXITSTATUS (wstatus) : -WTERMSIG (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 interface_info *ip;
struct client_state *client; struct client_state *client;
struct timeval tv;
/* This code needs some rethinking. It doesn't test against /* This code needs some rethinking. It doesn't test against
a signal name, and it just kind of bulls into doing something 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; client -> state = S_INIT;
/* Set up a timeout to start the initialization /* Set up a timeout to start the initialization
process. */ process. */
add_timeout (cur_time + random () % 5, tv . tv_sec = cur_time + random () % 5;
state_reboot, client, 0, 0); tv . tv_usec = 0;
add_timeout (&tv, state_reboot, client, 0, 0);
} }
} }
return ISC_R_SUCCESS; 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 interface_info *ip;
struct client_state *client; struct client_state *client;
struct timeval tv;
/* Do the right thing for each interface. */ /* Do the right thing for each interface. */
for (ip = interfaces; ip; ip = ip -> next) { 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) if (newstate == server_shutdown) {
add_timeout (cur_time + 1, shutdown_exit, 0, 0, 0); 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; return ISC_R_SUCCESS;
} }
@ -3377,6 +3400,7 @@ dhclient_schedule_updates(struct client_state *client, struct iaddr *addr,
int offset) int offset)
{ {
struct dns_update_state *ustate; struct dns_update_state *ustate;
struct timeval tv;
if (!client->config->do_forward_update) if (!client->config->do_forward_update)
return; return;
@ -3388,7 +3412,9 @@ dhclient_schedule_updates(struct client_state *client, struct iaddr *addr,
ustate->address = *addr; ustate->address = *addr;
ustate->dns_update_timeout = 1; 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); ustate, NULL, NULL);
} else { } else {
log_error("Unable to allocate dns update state for %s.", 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; struct dns_update_state *ustate = cp;
isc_result_t status = ISC_R_FAILURE; isc_result_t status = ISC_R_FAILURE;
struct timeval tv;
/* XXX: DNS TTL is a problem we need to solve properly. Until /* XXX: DNS TTL is a problem we need to solve properly. Until
* that time, 300 is a placeholder default for something that is * 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 (status == ISC_R_TIMEDOUT) {
if (ustate->dns_update_timeout < 3600) if (ustate->dns_update_timeout < 3600)
ustate->dns_update_timeout *= 10; ustate->dns_update_timeout *= 10;
add_timeout(cur_time + ustate->dns_update_timeout, tv.tv_sec = cur_time + ustate->dns_update_timeout;
client_dns_update_timeout, ustate, NULL, NULL); tv.tv_usec = 0;
add_timeout(&tv, client_dns_update_timeout,
ustate, NULL, NULL);
} else } else
dfree(ustate, MDL); dfree(ustate, MDL);
} }

View File

@ -40,8 +40,9 @@ static struct timeout *free_timeouts;
void set_time(TIME t) void set_time(TIME t)
{ {
/* Do any outstanding timeouts. */ /* Do any outstanding timeouts. */
if (cur_time != t) { if (cur_tv . tv_sec != t) {
cur_time = t; cur_tv . tv_sec = t;
cur_tv . tv_usec = 0;
process_outstanding_timeouts ((struct timeval *)0); process_outstanding_timeouts ((struct timeval *)0);
} }
} }
@ -54,7 +55,9 @@ struct timeval *process_outstanding_timeouts (struct timeval *tvp)
another: another:
if (timeouts) { if (timeouts) {
struct timeout *t; 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; t = timeouts;
timeouts = timeouts -> next; timeouts = timeouts -> next;
(*(t -> func)) (t -> what); (*(t -> func)) (t -> what);
@ -65,8 +68,8 @@ struct timeval *process_outstanding_timeouts (struct timeval *tvp)
goto another; goto another;
} }
if (tvp) { if (tvp) {
tvp -> tv_sec = timeouts -> when; tvp -> tv_sec = timeouts -> when . tv_sec;
tvp -> tv_usec = 0; tvp -> tv_usec = timeouts -> when . tv_usec;
} }
return tvp; return tvp;
} else } else
@ -93,7 +96,7 @@ void dispatch ()
} }
void add_timeout (when, where, what, ref, unref) void add_timeout (when, where, what, ref, unref)
TIME when; struct timeval *when;
void (*where) PROTO ((void *)); void (*where) PROTO ((void *));
void *what; void *what;
tvref_t ref; tvref_t ref;
@ -137,12 +140,15 @@ void add_timeout (when, where, what, ref, unref)
q -> what = what; 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. */ /* Now sort this timeout into the timeout list. */
/* Beginning of 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; q -> next = timeouts;
timeouts = q; timeouts = q;
return; return;
@ -150,7 +156,9 @@ void add_timeout (when, where, what, ref, unref)
/* Middle of list? */ /* Middle of list? */
for (t = timeouts; t -> next; t = t -> next) { 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; q -> next = t -> next;
t -> next = q; t -> next = q;
return; return;

View File

@ -1046,17 +1046,17 @@ struct client_state {
struct dhc6_lease *selected_lease; struct dhc6_lease *selected_lease;
struct dhc6_lease *held_leases; struct dhc6_lease *held_leases;
TIME start_time; struct timeval start_time;
u_int16_t elapsed; u_int16_t elapsed;
int txcount; int txcount;
/* See RFC3315 section 14. */ /* See RFC3315 section 14. */
TIME RT; TIME RT; /* In hundredths of seconds. */
TIME IRT; TIME IRT; /* In hundredths of seconds. */
TIME MRC; TIME MRC; /* Count. */
TIME MRT; TIME MRT; /* In hundredths of seconds. */
TIME MRD; TIME MRD; /* In seconds, relative. */
TIME next_MRD; TIME next_MRD; /* In seconds, absolute. */
/* Rather than a state, we use a function that shifts around /* Rather than a state, we use a function that shifts around
* depending what stage of life the v6 state machine is in. * 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); typedef void (*tvunref_t)(void *, const char *, int);
struct timeout { struct timeout {
struct timeout *next; struct timeout *next;
TIME when; struct timeval when;
void (*func) PROTO ((void *)); void (*func) PROTO ((void *));
void *what; void *what;
tvref_t ref; tvref_t ref;
@ -1643,7 +1643,8 @@ int add_option(struct option_state *options,
unsigned int data_len); unsigned int data_len);
/* dhcpd.c */ /* dhcpd.c */
extern TIME cur_time; extern struct timeval cur_tv;
#define cur_time cur_tv.tv_sec
extern int ddns_update_style; extern int ddns_update_style;
@ -2362,7 +2363,7 @@ isc_result_t interface_stuff_values (omapi_object_t *,
omapi_object_t *, 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)); tvref_t, tvunref_t));
void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *)); void cancel_timeout PROTO ((void (*) PROTO ((void *)), void *));
void cancel_all_timeouts (void); void cancel_all_timeouts (void);

View File

@ -120,7 +120,8 @@ int MRns_name_pton(const char *, u_char *, size_t);
#define b64_ntop MRb64_ntop #define b64_ntop MRb64_ntop
extern const struct res_sym __p_type_syms[]; 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 *, int dn_comp (const char *,
unsigned char *, unsigned, unsigned char **, unsigned char **); unsigned char *, unsigned, unsigned char **, unsigned char **);

View File

@ -38,7 +38,7 @@
#include <sys/time.h> #include <sys/time.h>
static omapi_io_object_t omapi_io_states; static omapi_io_object_t omapi_io_states;
time_t cur_time; struct timeval cur_tv;
OMAPI_OBJECT_ALLOC (omapi_io, OMAPI_OBJECT_ALLOC (omapi_io,
omapi_io_object_t, omapi_type_io_object) 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. */ /* First, see if the timeout has expired, and if so return. */
if (t) { if (t) {
gettimeofday (&now, (struct timezone *)0); 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 || if (now.tv_sec > t -> tv_sec ||
(now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec)) (now.tv_sec == t -> tv_sec && now.tv_usec >= t -> tv_usec))
return ISC_R_TIMEDOUT; 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); count = select (max + 1, &r, &w, &x, t ? &to : (struct timeval *)0);
/* Get the current time... */ /* Get the current time... */
gettimeofday (&now, (struct timezone *)0); gettimeofday (&cur_tv, (struct timezone *)0);
cur_time = now.tv_sec;
/* We probably have a bad file descriptor. Figure out which one. /* We probably have a bad file descriptor. Figure out which one.
When we find it, call the reaper function on it, which will When we find it, call the reaper function on it, which will

View File

@ -34,6 +34,7 @@
#include "dhcpd.h" #include "dhcpd.h"
#include <syslog.h> #include <syslog.h>
#include <sys/time.h>
static void usage PROTO ((void)); static void usage PROTO ((void));
@ -266,7 +267,7 @@ main(int argc, char **argv) {
} }
/* Get the current time... */ /* Get the current time... */
time(&cur_time); gettimeofday(&cur_tv, NULL);
/* Discover all the network interfaces. */ /* Discover all the network interfaces. */
discover_interfaces (DISCOVER_RELAY); discover_interfaces (DISCOVER_RELAY);

View File

@ -1457,6 +1457,7 @@ void ack_lease (packet, lease, offer, when, msg, ms_nulltp, hp)
unsigned i, j; unsigned i, j;
int s1; int s1;
int ignorep; int ignorep;
struct timeval tv;
/* If we're already acking this lease, don't do it again. */ /* If we're already acking this lease, don't do it again. */
if (lease -> state) 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); log_debug ("Ping timeout: %ld", (long)ping_timeout);
#endif #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, (tvref_t)lease_reference,
(tvunref_t)lease_dereference); (tvunref_t)lease_dereference);
++outstanding_pings; ++outstanding_pings;

View File

@ -44,6 +44,7 @@ static char url [] = "For info, please visit http://www.isc.org/sw/dhcp/";
#include <errno.h> #include <errno.h>
#include <limits.h> #include <limits.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/time.h>
#include <signal.h> #include <signal.h>
static void usage(void); static void usage(void);
@ -173,6 +174,7 @@ static void omapi_listener_start (void *foo)
{ {
omapi_object_t *listener; omapi_object_t *listener;
isc_result_t result; isc_result_t result;
struct timeval tv;
listener = (omapi_object_t *)0; listener = (omapi_object_t *)0;
result = omapi_generic_new (&listener, MDL); result = omapi_generic_new (&listener, MDL);
@ -187,7 +189,9 @@ static void omapi_listener_start (void *foo)
if (result != ISC_R_SUCCESS) { if (result != ISC_R_SUCCESS) {
log_error ("Can't start OMAPI protocol: %s", log_error ("Can't start OMAPI protocol: %s",
isc_result_totext (result)); 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); omapi_object_dereference (&listener, MDL);
} }
@ -496,7 +500,7 @@ main(int argc, char **argv) {
} }
/* Get the current time... */ /* Get the current time... */
time(&cur_time); gettimeofday(&cur_tv, NULL);
/* Set up the initial dhcp option universe. */ /* Set up the initial dhcp option universe. */
initialize_common_option_spaces (); initialize_common_option_spaces ();
@ -1214,6 +1218,7 @@ static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
#if defined (FAILOVER_PROTOCOL) #if defined (FAILOVER_PROTOCOL)
int failover_connection_count = 0; int failover_connection_count = 0;
#endif #endif
struct timeval tv;
oncemore: oncemore:
if (shutdown_state == shutdown_listeners || if (shutdown_state == shutdown_listeners ||
@ -1299,7 +1304,9 @@ static isc_result_t dhcp_io_shutdown_countdown (void *vlp)
shutdown_time = cur_time; shutdown_time = cur_time;
goto oncemore; 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); (void (*)(void *))dhcp_io_shutdown_countdown, 0, 0, 0);
return ISC_R_SUCCESS; return ISC_R_SUCCESS;
} }

View File

@ -59,6 +59,7 @@ void dhcp_failover_startup ()
{ {
dhcp_failover_state_t *state; dhcp_failover_state_t *state;
isc_result_t status; isc_result_t status;
struct timeval tv;
for (state = failover_states; state; state = state -> next) { for (state = failover_states; state; state = state -> next) {
dhcp_failover_state_transition (state, "startup"); dhcp_failover_state_transition (state, "startup");
@ -79,7 +80,9 @@ void dhcp_failover_startup ()
#if defined (DEBUG_FAILOVER_TIMING) #if defined (DEBUG_FAILOVER_TIMING)
log_info ("add_timeout +90 dhcp_failover_reconnect"); log_info ("add_timeout +90 dhcp_failover_reconnect");
#endif #endif
add_timeout (cur_time + 90, tv . tv_sec = cur_time + 90;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_reconnect, state, dhcp_failover_reconnect, state,
(tvref_t) (tvref_t)
dhcp_failover_state_reference, dhcp_failover_state_reference,
@ -96,7 +99,9 @@ void dhcp_failover_startup ()
log_info ("add_timeout +90 %s", log_info ("add_timeout +90 %s",
"dhcp_failover_listener_restart"); "dhcp_failover_listener_restart");
#endif #endif
add_timeout (cur_time + 90, tv . tv_sec = cur_time + 90;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_listener_restart, dhcp_failover_listener_restart,
state, state,
(tvref_t)omapi_object_reference, (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; dhcp_failover_state_t *s, *state = (dhcp_failover_state_t *)0;
char *sname; char *sname;
int slen; int slen;
struct timeval tv;
if (h -> type != dhcp_type_failover_link) { if (h -> type != dhcp_type_failover_link) {
/* XXX shouldn't happen. Put an assert here? */ /* 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", log_info ("add_timeout +15 %s",
"dhcp_failover_link_startup_timeout"); "dhcp_failover_link_startup_timeout");
#endif #endif
add_timeout (cur_time + 15, tv . tv_sec = cur_time + 15;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_link_startup_timeout, dhcp_failover_link_startup_timeout,
link, link,
(tvref_t)dhcp_failover_link_reference, (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", log_info ("add_timeout +5 %s",
"dhcp_failover_reconnect"); "dhcp_failover_reconnect");
#endif #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, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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", log_info ("add_timeout +5 %s",
"dhcp_failover_reconnect"); "dhcp_failover_reconnect");
#endif #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, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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; isc_result_t status;
dhcp_failover_state_t *state; dhcp_failover_state_t *state;
dhcp_failover_link_t *link; dhcp_failover_link_t *link;
struct timeval tv;
if (!o || o -> type != dhcp_type_failover_state) if (!o || o -> type != dhcp_type_failover_state)
return ISC_R_INVALIDARG; 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", log_info ("add_timeout +90 %s",
"dhcp_failover_reconnect"); "dhcp_failover_reconnect");
#endif #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, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t) (tvunref_t)
@ -1359,8 +1374,10 @@ isc_result_t dhcp_failover_state_signal (omapi_object_t *o,
(int)state -> partner.max_response_delay / 3, (int)state -> partner.max_response_delay / 3,
"dhcp_failover_send_contact"); "dhcp_failover_send_contact");
#endif #endif
add_timeout (cur_time + tv . tv_sec = cur_time +
(int)state -> partner.max_response_delay / 3, (int)state -> partner.max_response_delay / 3;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_send_contact, state, dhcp_failover_send_contact, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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, (int)state -> me.max_response_delay,
"dhcp_failover_timeout"); "dhcp_failover_timeout");
#endif #endif
add_timeout (cur_time + tv . tv_sec = cur_time +
(int)state -> me.max_response_delay, (int)state -> me.max_response_delay;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_timeout, state, dhcp_failover_timeout, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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, (int)state -> me.max_response_delay,
"dhcp_failover_timeout"); "dhcp_failover_timeout");
#endif #endif
add_timeout (cur_time + tv . tv_sec = cur_time +
(int)state -> me.max_response_delay, (int)state -> me.max_response_delay;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_timeout, state, dhcp_failover_timeout, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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 pool *p;
struct shared_network *s; struct shared_network *s;
struct lease *l; struct lease *l;
struct timeval tv;
/* If we're in certain states where we're sending updates, and the peer /* 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 * 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", log_info ("add_timeout +15 %s",
"dhcp_failover_startup_timeout"); "dhcp_failover_startup_timeout");
#endif #endif
add_timeout (cur_time + 15, tv . tv_sec = cur_time + 15;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_startup_timeout, dhcp_failover_startup_timeout,
state, state,
(tvref_t)omapi_object_reference, (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), state -> me.stos + state -> mclt),
"dhcp_failover_startup_timeout"); "dhcp_failover_startup_timeout");
#endif #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, dhcp_failover_recover_done,
state, state,
(tvref_t)omapi_object_reference, (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), (int)(cur_time - p->next_event_time),
"pool_timer"); "pool_timer");
#endif #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, (tvref_t)pool_reference,
(tvunref_t)pool_dereference); (tvunref_t)pool_dereference);
} }
@ -2496,6 +2524,7 @@ dhcp_failover_pool_check(struct pool *pool)
{ {
dhcp_failover_state_t *peer; dhcp_failover_state_t *peer;
TIME est1, est2; TIME est1, est2;
struct timeval tv;
peer = pool->failover_peer; peer = pool->failover_peer;
@ -2574,7 +2603,9 @@ dhcp_failover_pool_check(struct pool *pool)
log_info("add_timeout +%d dhcp_failover_pool_rebalance", log_info("add_timeout +%d dhcp_failover_pool_rebalance",
est1 - cur_time); est1 - cur_time);
#endif #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, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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, int dhcp_failover_queue_ack (dhcp_failover_state_t *state,
failover_message_t *msg) failover_message_t *msg)
{ {
struct timeval tv;
if (state -> toack_queue_head) { if (state -> toack_queue_head) {
failover_message_reference failover_message_reference
(&state -> toack_queue_tail -> next, msg, MDL); (&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", log_info ("add_timeout +2 %s",
"dhcp_failover_toack_queue_timeout"); "dhcp_failover_toack_queue_timeout");
#endif #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, dhcp_failover_toack_queue_timeout, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (tvunref_t)dhcp_failover_state_dereference);
@ -2915,6 +2950,7 @@ void dhcp_failover_reconnect (void *vs)
{ {
dhcp_failover_state_t *state = vs; dhcp_failover_state_t *state = vs;
isc_result_t status; isc_result_t status;
struct timeval tv;
#if defined (DEBUG_FAILOVER_TIMING) #if defined (DEBUG_FAILOVER_TIMING)
log_info ("dhcp_failover_reconnect"); log_info ("dhcp_failover_reconnect");
@ -2932,7 +2968,9 @@ void dhcp_failover_reconnect (void *vs)
log_info ("add_timeout +90 %s", log_info ("add_timeout +90 %s",
"dhcp_failover_listener_restart"); "dhcp_failover_listener_restart");
#endif #endif
add_timeout (cur_time + 90, tv . tv_sec = cur_time + 90;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_listener_restart, state, dhcp_failover_listener_restart, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (tvunref_t)dhcp_failover_state_dereference);
@ -2970,6 +3008,7 @@ void dhcp_failover_listener_restart (void *vs)
{ {
dhcp_failover_state_t *state = vs; dhcp_failover_state_t *state = vs;
isc_result_t status; isc_result_t status;
struct timeval tv;
#if defined (DEBUG_FAILOVER_TIMING) #if defined (DEBUG_FAILOVER_TIMING)
log_info ("dhcp_failover_listener_restart"); log_info ("dhcp_failover_listener_restart");
@ -2983,7 +3022,9 @@ void dhcp_failover_listener_restart (void *vs)
log_info ("add_timeout +90 %s", log_info ("add_timeout +90 %s",
"dhcp_failover_listener_restart"); "dhcp_failover_listener_restart");
#endif #endif
add_timeout (cur_time + 90, tv . tv_sec = cur_time + 90;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_listener_restart, state, dhcp_failover_listener_restart, state,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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; unsigned char *opbuf;
isc_result_t status = ISC_R_SUCCESS; isc_result_t status = ISC_R_SUCCESS;
unsigned char cbuf; unsigned char cbuf;
struct timeval tv;
/* Run through the argument list once to compute the length of /* Run through the argument list once to compute the length of
the option portion of the message. */ 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, partner.max_response_delay) / 3,
"dhcp_failover_send_contact"); "dhcp_failover_send_contact");
#endif #endif
add_timeout (cur_time + tv . tv_sec = cur_time +
(int)(link -> state_object -> (int)(link -> state_object ->
partner.max_response_delay) / 3, partner.max_response_delay) / 3;
tv . tv_usec = 0;
add_timeout (&tv,
dhcp_failover_send_contact, link -> state_object, dhcp_failover_send_contact, link -> state_object,
(tvref_t)dhcp_failover_state_reference, (tvref_t)dhcp_failover_state_reference,
(tvunref_t)dhcp_failover_state_dereference); (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"; const char *message = "no memory";
u_int32_t pot_expire; u_int32_t pot_expire;
int send_to_backup = ISC_FALSE; int send_to_backup = ISC_FALSE;
struct timeval tv;
ia.len = sizeof msg -> assigned_addr; ia.len = sizeof msg -> assigned_addr;
memcpy (ia.iabuf, &msg -> assigned_addr, ia.len); 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 succession (e.g., when stealing leases from the
secondary), we do not do an immediate commit for secondary), we do not do an immediate commit for
each one. */ each one. */
add_timeout(cur_time + 2, tv.tv_sec = cur_time + 2;
commit_leases_timeout, (void *)0, 0, 0); tv.tv_usec = 0;
add_timeout(&tv, commit_leases_timeout, (void *)0, 0, 0);
} }
unqueue: unqueue:
@ -5361,6 +5407,8 @@ isc_result_t
dhcp_failover_process_update_done (dhcp_failover_state_t *state, dhcp_failover_process_update_done (dhcp_failover_state_t *state,
failover_message_t *msg) failover_message_t *msg)
{ {
struct timeval tv;
log_info ("failover peer %s: peer update completed.", log_info ("failover peer %s: peer update completed.",
state -> name); state -> name);
@ -5419,7 +5467,9 @@ dhcp_failover_process_update_done (dhcp_failover_state_t *state,
state -> me.stos + state -> mclt), state -> me.stos + state -> mclt),
"dhcp_failover_recover_done"); "dhcp_failover_recover_done");
#endif #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, dhcp_failover_recover_done,
state, state,
(tvref_t)omapi_object_reference, (tvref_t)omapi_object_reference,

View File

@ -1060,6 +1060,7 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
if (pimmediate && !commit) if (pimmediate && !commit)
return 0; return 0;
#endif #endif
struct timeval tv;
/* If there is no sample lease, just do the move. */ /* If there is no sample lease, just do the move. */
if (!lease) if (!lease)
@ -1335,7 +1336,9 @@ int supersede_lease (comp, lease, commit, propogate, pimmediate)
(comp -> sort_time < comp -> pool -> next_event_time || (comp -> sort_time < comp -> pool -> next_event_time ||
comp -> pool -> next_event_time == MIN_TIME)) { comp -> pool -> next_event_time == MIN_TIME)) {
comp -> pool -> next_event_time = comp -> sort_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, pool_timer, comp -> pool,
(tvref_t)pool_reference, (tvref_t)pool_reference,
(tvunref_t)pool_dereference); (tvunref_t)pool_dereference);
@ -1753,6 +1756,7 @@ void pool_timer (vpool)
struct lease **lptr[RESERVED_LEASES+1]; struct lease **lptr[RESERVED_LEASES+1];
TIME next_expiry = MAX_TIME; TIME next_expiry = MAX_TIME;
int i; int i;
struct timeval tv;
pool = (struct pool *)vpool; pool = (struct pool *)vpool;
@ -1821,7 +1825,9 @@ void pool_timer (vpool)
} }
if (next_expiry != MAX_TIME) { if (next_expiry != MAX_TIME) {
pool -> next_event_time = next_expiry; 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, (tvref_t)pool_reference,
(tvunref_t)pool_dereference); (tvunref_t)pool_dereference);
} else } else

View File

@ -2136,6 +2136,7 @@ schedule_lease_timeout(struct ipv6_pool *pool) {
struct iaaddr *tmp; struct iaaddr *tmp;
time_t timeout; time_t timeout;
time_t next_timeout; time_t next_timeout;
struct timeval tv;
next_timeout = MAX_TIME; next_timeout = MAX_TIME;
@ -2158,7 +2159,9 @@ schedule_lease_timeout(struct ipv6_pool *pool) {
} }
if (next_timeout < MAX_TIME) { 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, (tvref_t)ipv6_pool_reference,
(tvunref_t)ipv6_pool_dereference); (tvunref_t)ipv6_pool_dereference);
} }