dhclient - Remove cur_time global.
authorAntonio Huete Jimenez <tuxillo@quantumachine.net>
Fri, 1 Aug 2014 18:19:04 +0000 (20:19 +0200)
committerAntonio Huete Jimenez <tuxillo@quantumachine.net>
Sat, 9 Aug 2014 16:29:12 +0000 (18:29 +0200)
- Junk global cur_time, and use time(NULL) or local variables where
  time is checked multiple times. Add a set_timeout_interval() function
  to allow setting a timeout based on an interval from current time.

- Fixes issues with initial startup where the global cur_time was
  always old and caused initial DHCPDISCOVER or DHCPREQUEST packets
  to be sent multiple times. And probably other timeout related
  oddities.

Taken-from: OpenBSD

sbin/dhclient/clparse.c
sbin/dhclient/dhclient.c
sbin/dhclient/dhcpd.h
sbin/dhclient/dispatch.c

index 229fb4a..36e958e 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/clparse.c,v 1.39 2012/08/22 00:14:42 tedu Exp $     */
+/*     $OpenBSD: src/sbin/dhclient/clparse.c,v 1.40 2012/08/26 23:33:29 krw Exp $      */
 
 /* Parser for dhclient config and lease files... */
 
@@ -471,7 +471,7 @@ parse_client_lease_statement(FILE *cfile, int is_static)
         * active.
         */
        if (client->active) {
-               if (client->active->expiry < cur_time)
+               if (client->active->expiry < time(NULL))
                        free_client_lease(client->active);
                else if (addr_eq(client->active->address, lease->address))
                        free_client_lease(client->active);
index d362807..d3dac0d 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.151 2012/08/22 00:14:42 tedu Exp $   */
+/*     $OpenBSD: src/sbin/dhclient/dhclient.c,v 1.152 2012/08/26 23:33:29 krw Exp $    */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -68,8 +68,6 @@
 #define POLL_FAILURES          10
 #define POLL_FAILURE_WAIT      1       /* Back off multiplier (seconds) */
 
-time_t cur_time;
-
 char *path_dhclient_conf = _PATH_DHCLIENT_CONF;
 char *path_dhclient_db = NULL;
 
@@ -215,7 +213,7 @@ routehandler(void)
                if (findproto((char *)(ifam + 1), ifam->ifam_addrs) != AF_INET)
                        break;
                /* XXX check addrs like RTM_NEWADDR instead of this? */
-               if (scripttime == 0 || cur_time < scripttime + 10)
+               if (scripttime == 0 || time(NULL) < scripttime + 10)
                        break;
                errmsg = "interface address deleted";
                goto die;
@@ -318,7 +316,6 @@ main(int argc, char *argv[])
                log_perror = 0;
 
        tzset();
-       time(&cur_time);
 
        memset(&sockaddr_broadcast, 0, sizeof(sockaddr_broadcast));
        sockaddr_broadcast.sin_family = AF_INET;
@@ -468,7 +465,7 @@ state_reboot(void)
           flags. */
        make_request(client->active);
        client->destination = iaddr_broadcast;
-       client->first_sending = cur_time;
+       client->first_sending = time(NULL);
        client->interval = 0;
 
        /* Send out the first DHCPREQUEST packet. */
@@ -488,7 +485,7 @@ state_init(void)
        client->xid = client->packet.xid;
        client->destination = iaddr_broadcast;
        client->state = S_SELECTING;
-       client->first_sending = cur_time;
+       client->first_sending = time(NULL);
        client->interval = 0;
 
        /* Add an immediate timeout to cause the first DHCPDISCOVER packet
@@ -504,6 +501,7 @@ void
 state_selecting(void)
 {
        struct client_lease *lp, *next, *picked;
+       time_t cur_time;
 
        /* Cancel state_selecting and send_discover timeouts, since either
           one could have got us here. */
@@ -535,6 +533,8 @@ state_selecting(void)
        }
        picked->next = NULL;
 
+       time(&cur_time);
+
        /* If it was a BOOTREPLY, we can just take the address right now. */
        if (!picked->options[DHO_DHCP_MESSAGE_TYPE].len) {
                client->new = picked;
@@ -573,6 +573,7 @@ void
 dhcpack(struct iaddr client_addr, struct option_data *options)
 {
        struct client_lease *lease;
+       time_t cur_time;
 
 
        if (client->state != S_REBOOTING &&
@@ -623,6 +624,8 @@ dhcpack(struct iaddr client_addr, struct option_data *options)
                client->new->rebind = client->new->renewal +
                    client->new->renewal / 2 + client->new->renewal / 4;
 
+       time(&cur_time);
+
        client->new->expiry += cur_time;
        /* Lease lengths can never be negative. */
        if (client->new->expiry < cur_time)
@@ -663,7 +666,7 @@ bind_lease(void)
 
        note("bound to %s -- renewal in %lld seconds.",
            piaddr(client->active->address),
-           (long long)(client->active->renewal - cur_time));
+           (long long)(client->active->renewal - time(NULL)));
        client->state = S_BOUND;
        reinitialize_interface();
        go_daemon();
@@ -690,7 +693,7 @@ state_bound(void)
        } else
                client->destination = iaddr_broadcast;
 
-       client->first_sending = cur_time;
+       client->first_sending = time(NULL);
        client->interval = 0;
        client->state = S_RENEWING;
 
@@ -769,7 +772,7 @@ dhcpoffer(struct iaddr client_addr, struct option_data *options)
        /* If the selecting interval has expired, go immediately to
           state_selecting().  Otherwise, time out into
           state_selecting at the select interval. */
-       if (stop_selecting <= cur_time)
+       if (stop_selecting <= time(NULL))
                state_selecting();
        else {
                set_timeout(stop_selecting, state_selecting);
@@ -884,8 +887,11 @@ dhcpnak(struct iaddr client_addr, struct option_data *options)
 void
 send_discover(void)
 {
+       time_t cur_time;
        int interval, increase = 1;
 
+       time(&cur_time);
+
        /* Figure out how long it's been since we started transmitting. */
        interval = cur_time - client->first_sending;
 
@@ -940,7 +946,7 @@ send_discover(void)
        /* Send out a packet. */
        send_packet(inaddr_any, &sockaddr_broadcast, NULL);
 
-       set_timeout(cur_time + client->interval, send_discover);
+       set_timeout_interval(client->interval, send_discover);
 }
 
 /*
@@ -954,6 +960,7 @@ state_panic(void)
 {
        struct client_lease *loop = client->active;
        struct client_lease *lp;
+       time_t cur_time;
 
        note("No DHCPOFFERS received.");
 
@@ -963,6 +970,7 @@ state_panic(void)
                goto activate_next;
 
        /* Run through the list of leases and see if one can be used. */
+       time(&cur_time);
        while (client->active) {
                if (client->active->expiry > cur_time) {
                        note("Trying recorded lease %s",
@@ -976,8 +984,7 @@ state_panic(void)
                           yet need renewal, go into BOUND state and
                           timeout at the renewal time. */
                        if (!script_go()) {
-                               if (cur_time <
-                                   client->active->renewal) {
+                               if (cur_time < client->active->renewal) {
                                        client->state = S_BOUND;
                                        note("bound: renewal in %lld seconds.",
                                            (long long)(client->active->renewal
@@ -1029,7 +1036,7 @@ activate_next:
        script_init("FAIL");
        script_go();
        client->state = S_INIT;
-       set_timeout(cur_time + config->retry_interval, state_init);
+       set_timeout_interval(config->retry_interval, state_init);
        go_daemon();
 }
 
@@ -1038,10 +1045,13 @@ send_request(void)
 {
        struct sockaddr_in destination;
        struct in_addr from;
+       time_t cur_time;
        int interval;
 
+       time(&cur_time);
+
        /* Figure out how long it's been since we started transmitting. */
-       interval = cur_time - client->first_sending;
+       interval = (int)(cur_time - client->first_sending);
 
        /* If we're in the INIT-REBOOT or REQUESTING state and we're
           past the reboot timeout, go to INIT and see if we can
@@ -1129,7 +1139,7 @@ send_request(void)
        /* Send out a packet. */
        send_packet(from, &destination, NULL);
 
-       set_timeout(cur_time + client->interval, send_request);
+       set_timeout_interval(client->interval, send_request);
 }
 
 void
index c95793f..d350f87 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.78 2012/08/22 00:14:42 tedu Exp $       */
+/*     $OpenBSD: src/sbin/dhclient/dhcpd.h,v 1.79 2012/08/26 23:33:30 krw Exp $        */
 
 /*
  * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@@ -250,6 +250,7 @@ void reinitialize_interface(void);
 void dispatch(void);
 void got_one(void);
 void set_timeout(time_t, void (*)(void));
+void set_timeout_interval(time_t, void (*)(void));
 void cancel_timeout(void);
 int interface_status(char *);
 int interface_link_forceup(char *);
@@ -276,7 +277,6 @@ char *piaddr(struct iaddr);
 /* dhclient.c */
 extern char *path_dhclient_conf;
 extern char *path_dhclient_db;
-extern time_t cur_time;
 extern int log_perror;
 extern int routefd;
 
index c7ebad4..5df7a02 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.54 2012/08/18 00:20:01 krw Exp $     */
+/*     $OpenBSD: src/sbin/dhclient/dispatch.c,v 1.55 2012/08/26 23:33:31 krw Exp $     */
 
 /*
  * Copyright 2004 Henning Brauer <henning@openbsd.org>
@@ -123,7 +123,7 @@ dispatch(void)
 {
        int count, to_msec;
        struct pollfd fds[2];
-       time_t howlong;
+       time_t cur_time, howlong;
        void (*func)(void);
 
        do {
@@ -170,9 +170,6 @@ another:
                /* Wait for a packet or a timeout... XXX */
                count = poll(fds, 2, to_msec);
 
-               /* Time may have moved on while we polled! */
-               time(&cur_time);
-
                /* Not likely to be transitory... */
                if (count == -1) {
                        if (errno == EAGAIN || errno == EINTR) {
@@ -317,6 +314,13 @@ set_timeout(time_t when, void (*where)(void))
        timeout.func = where;
 }
 
+void
+set_timeout_interval(time_t secs, void (*where)(void))
+{
+       timeout.when = time(NULL) + secs;
+       timeout.func = where;
+}
+
 void
 cancel_timeout(void)
 {