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