All of lore.kernel.org
 help / color / mirror / Atom feed
From: Denis Kenzior <denkenz@gmail.com>
To: ell@lists.01.org
Subject: Re: [PATCH] dhcp-server: Fix lease expiry time calculation
Date: Fri, 04 Jun 2021 13:00:42 -0500	[thread overview]
Message-ID: <c39a0d15-9977-7f7c-1f2f-48402c830fa9@gmail.com> (raw)
In-Reply-To: <CAOq732+o4mhNgPD0O1Rhri5Bh9T_3zJo9vfEwAVJy_jyG3FNDg@mail.gmail.com>

[-- Attachment #1: Type: text/plain, Size: 4918 bytes --]

Hi Andrew,

On 6/4/21 12:35 PM, Andrew Zaborowski wrote:
> Hi Denis,
> 
> On Fri, 4 Jun 2021 at 18:49, Denis Kenzior <denkenz@gmail.com> wrote:
>> On 6/1/21 6:53 PM, Andrew Zaborowski wrote:
>>> We were comparing the l_time_now() (usecs) to lease->lifetime (secs)
>>> and then converting the result from usecs to secs, so the "diff" and the
>>> "to_secs" operations need to be switched around.  While there, use the
>>> opportunity to replace the "diff" operation so that if lease->lifetime is
>>> already in the past (e.g. because processing took to long), we schedule
>>> the timeout in 1 millisec instead of the absolute value of the difference.
>>>
>>> Since we're using uint32_t for the timestamps, use the overflow-safe(r)
>>> comparisons in set_next_expire_timer and in is_expired_lease.
>>> ---
>>>    ell/dhcp-server.c | 12 +++++++-----
>>>    1 file changed, 7 insertions(+), 5 deletions(-)
>>>
>>> diff --git a/ell/dhcp-server.c b/ell/dhcp-server.c
>>> index ebd4438..38193a2 100644
>>> --- a/ell/dhcp-server.c
>>> +++ b/ell/dhcp-server.c
>>> @@ -104,7 +104,7 @@ struct l_dhcp_server {
>>>
>>>    static bool is_expired_lease(struct l_dhcp_lease *lease)
>>>    {
>>> -     if (lease->lifetime < l_time_to_secs(l_time_now()))
>>> +     if ((int32_t) (lease->lifetime - l_time_to_secs(l_time_now())) < 0)
>>
>> Why not use l_time_before / l_time_after.
> 
> l_time_after is basically what we currently have here (a simple "<'),
> and the idea was to make the comparison a little safer just in case.

We avoid the whole Y2038 problem by using uint64_t and l_time* utilities.  So 
why make things 'a little' safer, when you can make them fully safe? :)

> 
>>   And with these changes I'm not sure
>> there's any point to store lease->lifetime in seconds.  I suspect this was done
>> originally to use 'second' versions of l_timeout_*.
> 
> Right, we could just convert it to the time.h format, uint64_t
> microseconds, but it would break the API.
> 

What API?

>>
>>>                return true;
>>>
>>>        return false;
>>> @@ -191,7 +191,8 @@ static void set_next_expire_timer(struct l_dhcp_server *server,
>>>                                        struct l_dhcp_lease *expired)
>>>    {
>>>        struct l_dhcp_lease *next;
>>> -     unsigned int next_timeout;
>>> +     unsigned long next_timeout;
>>
>> Why unsigned long?  It is different between 32 bit and 64 bit, so if you need
>> overflow protection, just use uint64_t instead?
> 
> "unsigned int" is the type of the l_timeout_modify parameter so I
> changed it to the type of the l_timeout_modify_ms parameter since that
> will limit the max value even if we pass a larger type.

So just FYI, sizeof(unsigned long) == sizeof(unsigned int) on 32 bit.  So you're 
actually introducing differing behavior depending on the platform.  This is the 
point I'm making above...

> 
>>
>>> +     uint32_t now;
>>>
>>>        /*
>>>         * If this is an expiring lease put it into the expired queue, removing
>>> @@ -214,11 +215,12 @@ static void set_next_expire_timer(struct l_dhcp_server *server,
>>>                return;
>>>        }
>>>
>>> -     next_timeout = l_time_to_secs(l_time_diff(l_time_now(),
>>> -                                                     next->lifetime));
>>> +     now = l_time_to_secs(l_time_now());
>>> +     next_timeout = (int32_t) (next->lifetime - now) > 0 ?
>>> +             (next->lifetime - now) * 1000L : 1;
>>
>> Why 1000L?  next_timeout is unsigned?
> 
> My logic was to make sure the multiplication is treated as uint32_t *
> long rather than uint32_t * int to avoid an overflow (if the result

See above.  Also, shouldn't this be 1000UL/ULL?  Probably doesn't matter, but if 
you're going through the trouble, might as well get it perfect...

> fits in a long...).  I'm not sure if this is needed but checking with
> gdb seems to indicate it is:
> 
> (gdb) print sizeof(int)
> $1 = 4
> (gdb) print sizeof(long)
> $2 = 8

On 64 bit, sure...

> (gdb) print (unsigned int) 0x10000000 * 1000
> $3 = 3892314112
> (gdb) print (unsigned int) 0x10000000 * 1000L
> $4 = 16777216000
> 
>>
>> Also, why not use existing l_time_after, l_time_diff and l_time_to_msecs utilities?
> 
> As for l_time_after, I was trying to improve on the overflow safety a
> bit like I mentioned in the commit.

I suspect you need a sanity check regardless if the l_time_to_msec conversion 
results in something > UINT_MAX since the result is just truncated and that is 
likely not what you want anyway.

> 
> As for l_time_diff, we can use it, I just thought it might be worth
> saving that one extra comparison in it.
> 
> As for l_time_to_msecs we're converting from secs to msecs, not from
> usecs to msecs, but I can use L_MSEC_PER_SEC instead of 1000L.
> 

Yes, that would be better.

Regards,
-Denis

  reply	other threads:[~2021-06-04 18:00 UTC|newest]

Thread overview: 6+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-06-01 23:53 [PATCH] dhcp-server: Fix lease expiry time calculation Andrew Zaborowski
2021-06-04 16:49 ` Denis Kenzior
2021-06-04 17:35   ` Andrew Zaborowski
2021-06-04 18:00     ` Denis Kenzior [this message]
2021-06-04 18:34       ` Andrew Zaborowski
2021-06-04 18:48         ` Denis Kenzior

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c39a0d15-9977-7f7c-1f2f-48402c830fa9@gmail.com \
    --to=denkenz@gmail.com \
    --cc=ell@lists.01.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.