In dhcpd, variable cur_time is set only once per dispatch loop.
Unfortunately, this is done before the poll(2) call. Since poll(2)
may sleep for an arbitrary amount of time, the value of cur_time
might refer to some long ago point in time. When message dispatching
is done, timeouts and lease ends are calculated based on this
outdated cur_time value that was set before the call to poll(2).

It's fine to set cur_time only once per loop, but we should do it after
the blocking poll(2) syscall so that its value is more accurate.

ok?

Gerhard



Index: usr.sbin/dhcpd/dispatch.c
===================================================================
RCS file: /cvs/src/usr.sbin/dhcpd/dispatch.c,v
retrieving revision 1.30
diff -u -p -r1.30 dispatch.c
--- usr.sbin/dhcpd/dispatch.c   19 Apr 2013 21:25:39 -0000      1.30
+++ usr.sbin/dhcpd/dispatch.c   15 May 2013 08:09:17 -0000
@@ -306,8 +306,6 @@ dispatch(void)
                 * still a timeout registered, time out the poll
                 * call then.
                 */
-               time(&cur_time);
-another:
                if (timeouts) {
                        if (timeouts->when <= cur_time) {
                                struct dhcpd_timeout *t = timeouts;
@@ -315,7 +313,7 @@ another:
                                (*(t->func))(t->what);
                                t->next = free_timeouts;
                                free_timeouts = t;
-                               goto another;
+                               continue;
                        }
 
                        /*
@@ -360,6 +358,7 @@ another:
                case 0:
                        continue;       /* no packets */
                }
+               time(&cur_time);
 
                for (i = 0, l = protocols; l; l = l->next) {
                        struct interface_info *ip = l->local;

Reply via email to