On Mon, Jan 20, 2020 at 07:08:26AM +0100, Otto Moerbeek wrote:

> On Fri, Jan 10, 2020 at 03:14:42PM +0100, Otto Moerbeek wrote:
> 
> > Hi,
> > 
> > THe ntp protocol uses 32-bit unsigned timestamps counting seconds
> > since 1900. That means that in 2036 the timestamp field will wrap.
> > This difff makes sure ntpd handles that correctly by assuming we are
> > in era 0 unless we see "small" timestamps.
> > 
> > tested in the future (incuding wrapping form era 0 to 1) on a couple
> > of machines including one running xntpd for interoperability.
> > 
> > ok?
> 
> ping...

Firts post on Jan 10th, zero feedback. I think I'll commit and let the
community do the testing. We'll have 16 years to fix the bugs.

        -Otto

> 
> > 
> > Index: client.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/ntpd/client.c,v
> > retrieving revision 1.112
> > diff -u -p -r1.112 client.c
> > --- client.c        10 Nov 2019 19:24:47 -0000      1.112
> > +++ client.c        10 Jan 2020 14:06:14 -0000
> > @@ -324,12 +324,6 @@ client_dispatch(struct ntp_peer *p, u_in
> >             }
> >     }
> >  
> > -   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 ||
> > @@ -374,16 +368,6 @@ client_dispatch(struct ntp_peer *p, u_in
> >     T1 = p->query->xmttime;
> >     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 &&
> > Index: ntp.h
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/ntpd/ntp.h,v
> > retrieving revision 1.13
> > diff -u -p -r1.13 ntp.h
> > --- ntp.h   22 Apr 2009 07:42:17 -0000      1.13
> > +++ ntp.h   10 Jan 2020 14:06:14 -0000
> > @@ -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
> > Index: util.c
> > ===================================================================
> > RCS file: /cvs/src/usr.sbin/ntpd/util.c,v
> > retrieving revision 1.24
> > diff -u -p -r1.24 util.c
> > --- util.c  1 Mar 2017 00:56:30 -0000       1.24
> > +++ util.c  10 Jan 2020 14:06:14 -0000
> > @@ -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));
> >  
> > 
> > 
> 

Reply via email to