Browse Source

Properly determine era 0 or era 1, making it possible to move past

the ntp timestamp wrapping in 2036.
OPENBSD_6_7
otto 4 years ago
parent
commit
0e2d622180
3 changed files with 25 additions and 22 deletions
  1. +1
    -17
      src/usr.sbin/ntpd/client.c
  2. +14
    -2
      src/usr.sbin/ntpd/ntp.h
  3. +10
    -3
      src/usr.sbin/ntpd/util.c

+ 1
- 17
src/usr.sbin/ntpd/client.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: client.c,v 1.112 2019/11/10 19:24:47 otto Exp $ */
/* $OpenBSD: client.c,v 1.113 2020/01/30 15:55:41 otto Exp $ */
/*
* Copyright (c) 2003, 2004 Henning Brauer <henning@openbsd.org>
@ -324,12 +324,6 @@ client_dispatch(struct ntp_peer *p, u_int8_t settime, u_int8_t automatic)
}
}
if (T4 < JAN_1970) {
client_log_error(p, "recvmsg control format", EBADF);
set_next(p, error_interval());
return (0);
}
ntp_getmsg((struct sockaddr *)&p->addr->ss, buf, size, &msg);
if (msg.orgtime.int_partl != p->query->msg.xmttime.int_partl ||
@ -375,16 +369,6 @@ client_dispatch(struct ntp_peer *p, u_int8_t settime, u_int8_t automatic)
T2 = lfp_to_d(msg.rectime);
T3 = lfp_to_d(msg.xmttime);
/*
* XXX workaround: time_t / tv_sec must never wrap.
* around 2020 we will need a solution (64bit time_t / tv_sec).
* consider every answer with a timestamp beyond january 2030 bogus.
*/
if (T2 > JAN_2030 || T3 > JAN_2030) {
set_next(p, error_interval());
return (0);
}
/* Detect liars */
if (!p->trusted && conf->constraint_median != 0 &&
(constraint_check(T2) != 0 || constraint_check(T3) != 0)) {


+ 14
- 2
src/usr.sbin/ntpd/ntp.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: ntp.h,v 1.13 2009/04/22 07:42:17 henning Exp $ */
/* $OpenBSD: ntp.h,v 1.14 2020/01/30 15:55:41 otto Exp $ */
/*
* Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
@ -141,7 +141,19 @@ struct ntp_query {
#define MODE_RES2 7 /* reserved for private use */
#define JAN_1970 2208988800UL /* 1970 - 1900 in seconds */
#define JAN_2030 1893456000UL + JAN_1970 /* 1. 1. 2030 00:00:00 */
/*
* The era we're in if we have no reason to assume otherwise.
* If lfp_to_d() sees an offset <= INT32_MAX the era is is assumed to be
* NTP_ERA + 1.
* Once the actual year is well into era 1, (after 2036) define NTP_ERA to 1
* and adapt (remove) the test in lfp_to_d().
* Once more than half of era 1 has elapsed (after 2104), re-inroduce the test
* to move to era 2 if offset <= INT32_MAX, repeat for each half era.
*/
#define NTP_ERA 0
#define SECS_IN_ERA (UINT32_MAX + 1ULL)
#define NTP_VERSION 4
#define NTP_MAXSTRATUM 15


+ 10
- 3
src/usr.sbin/ntpd/util.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: util.c,v 1.24 2017/03/01 00:56:30 gsoares Exp $ */
/* $OpenBSD: util.c,v 1.25 2020/01/30 15:55:41 otto Exp $ */
/*
* Copyright (c) 2004 Alexander Guy <alexander.guy@andern.org>
@ -86,12 +86,17 @@ d_to_tv(double d, struct timeval *tv)
double
lfp_to_d(struct l_fixedpt lfp)
{
double ret;
double base, ret;
lfp.int_partl = ntohl(lfp.int_partl);
lfp.fractionl = ntohl(lfp.fractionl);
ret = (double)(lfp.int_partl) + ((double)lfp.fractionl / UINT_MAX);
/* see comment in ntp.h */
base = NTP_ERA;
if (lfp.int_partl <= INT32_MAX)
base++;
ret = base * SECS_IN_ERA;
ret += (double)(lfp.int_partl) + ((double)lfp.fractionl / UINT_MAX);
return (ret);
}
@ -101,6 +106,8 @@ d_to_lfp(double d)
{
struct l_fixedpt lfp;
while (d > SECS_IN_ERA)
d -= SECS_IN_ERA;
lfp.int_partl = htonl((u_int32_t)d);
lfp.fractionl = htonl((u_int32_t)((d - (u_int32_t)d) * UINT_MAX));


Loading…
Cancel
Save