From 8d05e1a0f880cf524f11bd5fedd9e433d5c92f48 Mon Sep 17 00:00:00 2001 From: Antonio Huete Jimenez Date: Wed, 15 Aug 2012 03:15:12 +0200 Subject: [PATCH] dhclient - Have only one timeout at once. - Terminate with extreme prejudice the multiple timeout queuing mechanism that was a holdover from when dhclient handled multiple interfaces at once. - Also move calculation of current time to just before check to see if the timeout has expired. Taken-from: OpenBSD --- sbin/dhclient/dhclient.c | 32 +++++------- sbin/dhclient/dhcpd.h | 6 +-- sbin/dhclient/dispatch.c | 110 ++++++--------------------------------- 3 files changed, 33 insertions(+), 115 deletions(-) diff --git a/sbin/dhclient/dhclient.c b/sbin/dhclient/dhclient.c index ff1a326236..159e956fef 100644 --- a/sbin/dhclient/dhclient.c +++ b/sbin/dhclient/dhclient.c @@ -1,4 +1,4 @@ -/* $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.145 2012/06/24 16:01:18 krw Exp $ */ +/* $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.146 2012/07/09 16:21:21 krw Exp $ */ /* * Copyright 2004 Henning Brauer @@ -454,11 +454,7 @@ state_reboot(void) { /* Cancel all timeouts, since a link state change gets us here and can happen anytime. */ - cancel_timeout(state_init); - cancel_timeout(state_selecting); - cancel_timeout(state_bound); - cancel_timeout(send_discover); - cancel_timeout(send_request); + cancel_timeout(); /* If we don't remember an active lease, go straight to INIT. */ if (!client->active || client->active->is_bootp) { @@ -515,8 +511,7 @@ state_selecting(void) /* Cancel state_selecting and send_discover timeouts, since either one could have got us here. */ - cancel_timeout(state_selecting); - cancel_timeout(send_discover); + cancel_timeout(); /* We have received one or more DHCPOFFER packets. Currently, the only criterion by which we judge leases is whether or @@ -600,7 +595,7 @@ dhcpack(struct iaddr client_addr, struct option_data *options) client->new = lease; /* Stop resending DHCPREQUEST. */ - cancel_timeout(send_request); + cancel_timeout(); /* Figure out the lease time. */ if (client->new->options[DHO_DHCP_LEASE_TIME].data) @@ -667,8 +662,8 @@ bind_lease(void) /* Write out new leases file. */ rewrite_client_leases(); - /* Set up a timeout to start the renewal process. */ - add_timeout(client->active->renewal, state_bound); + /* Set timeout to start the renewal process. */ + set_timeout(client->active->renewal, state_bound); note("bound to %s -- renewal in %ld seconds.", piaddr(client->active->address), @@ -781,8 +776,7 @@ dhcpoffer(struct iaddr client_addr, struct option_data *options) if (stop_selecting <= cur_time) state_selecting(); else { - add_timeout(stop_selecting, state_selecting); - cancel_timeout(send_discover); + set_timeout(stop_selecting, state_selecting); } } @@ -880,7 +874,7 @@ dhcpnak(struct iaddr client_addr, struct option_data *options) client->active = NULL; /* Stop sending DHCPREQUEST packets... */ - cancel_timeout(send_request); + cancel_timeout(); client->state = S_INIT; state_init(); @@ -950,7 +944,7 @@ send_discover(void) /* Send out a packet. */ send_packet(inaddr_any, &sockaddr_broadcast, NULL); - add_timeout(cur_time + client->interval, send_discover); + set_timeout(cur_time + client->interval, send_discover); } /* @@ -992,7 +986,7 @@ state_panic(void) note("bound: renewal in %ld seconds.", client->active->renewal - cur_time); - add_timeout(client->active->renewal, + set_timeout(client->active->renewal, state_bound); } else { client->state = S_BOUND; @@ -1039,7 +1033,7 @@ activate_next: script_init("FAIL"); script_go(); client->state = S_INIT; - add_timeout(cur_time + config->retry_interval, state_init); + set_timeout(cur_time + config->retry_interval, state_init); go_daemon(); } @@ -1067,7 +1061,7 @@ send_request(void) client->state == S_REQUESTING) && interval > config->reboot_timeout) { client->state = S_INIT; - cancel_timeout(send_request); + cancel_timeout(); state_init(); return; } @@ -1139,7 +1133,7 @@ send_request(void) /* Send out a packet. */ send_packet(from, &destination, NULL); - add_timeout(cur_time + client->interval, send_request); + set_timeout(cur_time + client->interval, send_request); } void diff --git a/sbin/dhclient/dhcpd.h b/sbin/dhclient/dhcpd.h index 27055566f0..6b208c97ab 100644 --- a/sbin/dhclient/dhcpd.h +++ b/sbin/dhclient/dhcpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.75 2012/06/24 16:01:18 krw Exp $ */ +/* $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.76 2012/07/09 16:21:21 krw Exp $ */ /* * Copyright (c) 2004 Henning Brauer @@ -249,8 +249,8 @@ void discover_interface(void); void reinitialize_interface(void); void dispatch(void); void got_one(void); -void add_timeout(time_t, void (*)(void)); -void cancel_timeout(void (*)(void)); +void set_timeout(time_t, void (*)(void)); +void cancel_timeout(void); int interface_status(char *); int interface_link_forceup(char *); diff --git a/sbin/dhclient/dispatch.c b/sbin/dhclient/dispatch.c index 16a94cbcf0..e199159ed0 100644 --- a/sbin/dhclient/dispatch.c +++ b/sbin/dhclient/dispatch.c @@ -1,4 +1,4 @@ -/* $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.51 2012/06/24 16:01:18 krw Exp $ */ +/* $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.52 2012/07/09 16:21:21 krw Exp $ */ /* * Copyright 2004 Henning Brauer @@ -48,8 +48,7 @@ #include "dhcpd.h" -struct timeout *timeouts; -static struct timeout *free_timeouts; +struct timeout timeout; static int interfaces_invalidated; /* @@ -125,10 +124,11 @@ dispatch(void) int count, to_msec; struct pollfd fds[2]; time_t howlong; + void (*func)(void); do { /* - * Call any expired timeouts, and then if there's still + * Call expired timeout, and then if there's still * a timeout registered, time out the select call then. */ another: @@ -138,25 +138,21 @@ another: if (!ifi->linkstat) interfaces_invalidated = 0; - if (timeouts) { - struct timeout *t; - - if (timeouts->when <= cur_time) { - t = timeouts; - timeouts = timeouts->next; - (*(t->func))(); - t->next = free_timeouts; - free_timeouts = t; + if (timeout.func) { + time(&cur_time); + if (timeout.when <= cur_time) { + func = timeout.func; + cancel_timeout(); + (*(func))(); goto another; } - /* * Figure timeout in milliseconds, and check for * potential overflow, so we can cram into an * int for poll, while not polling with a * negative timeout and blocking indefinitely. */ - howlong = timeouts->when - cur_time; + howlong = timeout.when - cur_time; if (howlong > INT_MAX / 1000) howlong = INT_MAX / 1000; to_msec = howlong * 1000; @@ -174,9 +170,6 @@ another: /* Wait for a packet or a timeout... XXX */ count = poll(fds, 2, to_msec); - /* Get the current time... */ - time(&cur_time); - /* Not likely to be transitory... */ if (count == -1) { if (errno == EAGAIN || errno == EINTR) { @@ -312,84 +305,15 @@ active: } void -add_timeout(time_t when, void (*where)(void)) +set_timeout(time_t when, void (*where)(void)) { - struct timeout *t, *q; - - /* See if this timeout supersedes an existing timeout. */ - t = NULL; - for (q = timeouts; q; q = q->next) { - if (q->func == where) { - if (t) - t->next = q->next; - else - timeouts = q->next; - break; - } - t = q; - } - - /* If we didn't supersede a timeout, allocate a timeout - structure now. */ - if (!q) { - if (free_timeouts) { - q = free_timeouts; - free_timeouts = q->next; - q->func = where; - } else { - q = malloc(sizeof(struct timeout)); - if (!q) - error("Can't allocate timeout structure!"); - q->func = where; - } - } - - q->when = when; - - /* Now sort this timeout into the timeout list. */ - - /* Beginning of list? */ - if (!timeouts || timeouts->when > q->when) { - q->next = timeouts; - timeouts = q; - return; - } - - /* Middle of list? */ - for (t = timeouts; t->next; t = t->next) { - if (t->next->when > q->when) { - q->next = t->next; - t->next = q; - return; - } - } - - /* End of list. */ - t->next = q; - q->next = NULL; + timeout.when = when; + timeout.func = where; } void -cancel_timeout(void (*where)(void)) +cancel_timeout(void) { - struct timeout *t, *q; - - /* Look for this timeout on the list, and unlink it if we find it. */ - t = NULL; - for (q = timeouts; q; q = q->next) { - if (q->func == where) { - if (t) - t->next = q->next; - else - timeouts = q->next; - break; - } - t = q; - } - - /* If we found the timeout, put it on the free list. */ - if (q) { - q->next = free_timeouts; - free_timeouts = q; - } + timeout.when = 0; + timeout.func = NULL; } -- 2.41.0