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;