On Wed, May 15, 2013 at 10:15:54AM +0200, Gerhard Roth wrote:

> 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

I don't think the first call to time() should be left out. cur_time is
potentially used in the first iteration of the loop. 

        -Otto
 
> 
> 
> 
> 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