diff options
author | Miroslav Lichvar <mlichvar@redhat.com> | 2022-09-16 15:06:36 +0200 |
---|---|---|
committer | Denys Vlasenko <vda.linux@googlemail.com> | 2023-01-17 16:48:54 +0100 |
commit | 85acf71d2579ebe4eec05c6f31901adffa700adc (patch) | |
tree | 1f350548b148e952971a547667a8b2ec80029feb | |
parent | ca96022d6edaaf619324db5a481698231d74d1df (diff) | |
download | busybox-w32-85acf71d2579ebe4eec05c6f31901adffa700adc.tar.gz busybox-w32-85acf71d2579ebe4eec05c6f31901adffa700adc.tar.bz2 busybox-w32-85acf71d2579ebe4eec05c6f31901adffa700adc.zip |
ntpd: make NTP client and server Y2036/2038-ready
The 32-bit integer part of the NTP timestamp overflows in year 2036,
which starts the second NTP era.
Modify the timestamp conversion to shift values between 1900-1970 (in
the first era) to the second era to enable the client to measure its
offset correctly until year 2106 (assuming 64-bit time_t).
Also update the conversion from double used when stepping the clock to
work with 64-bit time_t after reaching the maximum 32-bit value in 2038
and the server conversion to work correctly in the next NTP era.
function old new delta
lfp_to_d 51 64 +13
step_time 326 332 +6
.rodata 105260 105264 +4
d_to_lfp 100 86 -14
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 3/1 up/down: 23/-14) Total: 9 bytes
Signed-off-by: Miroslav Lichvar <mlichvar@redhat.com>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
-rw-r--r-- | networking/ntpd.c | 14 |
1 files changed, 11 insertions, 3 deletions
diff --git a/networking/ntpd.c b/networking/ntpd.c index 204e1d7c2..4365166ff 100644 --- a/networking/ntpd.c +++ b/networking/ntpd.c | |||
@@ -554,7 +554,7 @@ gettime1900d(void) | |||
554 | static void | 554 | static void |
555 | d_to_tv(struct timeval *tv, double d) | 555 | d_to_tv(struct timeval *tv, double d) |
556 | { | 556 | { |
557 | tv->tv_sec = (long)d; | 557 | tv->tv_sec = (time_t)d; |
558 | tv->tv_usec = (d - tv->tv_sec) * 1000000; | 558 | tv->tv_usec = (d - tv->tv_sec) * 1000000; |
559 | } | 559 | } |
560 | 560 | ||
@@ -565,6 +565,14 @@ lfp_to_d(l_fixedpt_t lfp) | |||
565 | lfp.int_partl = ntohl(lfp.int_partl); | 565 | lfp.int_partl = ntohl(lfp.int_partl); |
566 | lfp.fractionl = ntohl(lfp.fractionl); | 566 | lfp.fractionl = ntohl(lfp.fractionl); |
567 | ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX); | 567 | ret = (double)lfp.int_partl + ((double)lfp.fractionl / UINT_MAX); |
568 | /* | ||
569 | * Shift timestamps before 1970 to the second NTP era (2036-2106): | ||
570 | * int_partl value of OFFSET_1900_1970 (2208988800) is interpreted as | ||
571 | * the start of year 1970 and it is the minimal representable time, | ||
572 | * all values form the sequence 2208988800..0xffffffff,0..2208988799. | ||
573 | */ | ||
574 | if (lfp.int_partl < OFFSET_1900_1970) | ||
575 | ret += (double)(1ULL << 32); /* because int_partl is 32-bit wide */ | ||
568 | return ret; | 576 | return ret; |
569 | } | 577 | } |
570 | static NOINLINE double | 578 | static NOINLINE double |
@@ -582,8 +590,8 @@ d_to_lfp(l_fixedpt_t *lfp, double d) | |||
582 | { | 590 | { |
583 | uint32_t intl; | 591 | uint32_t intl; |
584 | uint32_t frac; | 592 | uint32_t frac; |
585 | intl = (uint32_t)d; | 593 | intl = (uint32_t)(time_t)d; |
586 | frac = (uint32_t)((d - intl) * UINT_MAX); | 594 | frac = (uint32_t)((d - (time_t)d) * UINT_MAX); |
587 | lfp->int_partl = htonl(intl); | 595 | lfp->int_partl = htonl(intl); |
588 | lfp->fractionl = htonl(frac); | 596 | lfp->fractionl = htonl(frac); |
589 | } | 597 | } |