re
we've found a real bug behind the buffer sizes.
dns resolver was not limiting the response (ip list)
to any maximum number which is even defined already
as MAX_SERVERS_DNS. thus check that now.
now we can get away w/ much smaller buffers and
correct (non-overflowing) behaviour (;
cu

On Fri, May 15, 2009 at 03:19:02PM +0000, Michael Shalayeff wrote:
> re
> first try out of the zoo shown that we need to keep MAX_IMSGSIZE
> at 8k for more dns addresses (:
> diff updated
> cu
> 
> On Fri, May 15, 2009 at 02:58:36PM +0000, Michael Shalayeff wrote:
> > re
> > forgot to mention that while there touching structs
> > also rearrange fields for optimal alignment (save memory)
> > and shrink io buffers to a half K from 8k since we will
> > never have a valid packet larger than that.
> > cu
> > 
> > On Fri, May 15, 2009 at 02:39:29PM +0000, Michael Shalayeff wrote:
> > > re
> > > using floating point for ntpd math is not a good idea.
> > > this comes from the fact that mixing small and large numbers
> > > in one fp expression leads to a huge loss of precision.
> > > besides the fact that there is no need to change representation
> > > from fixed point (ntp timestamps) to floating point and
> > > back all the time. plus to that using fpu in daemons is
> > > not polite and eats even more cpu time (:
> > > 
> > > this diff converts internal math to fixed point (64bit)
> > > except for one place -- local clock frequency drift.
> > > this part is still broken as one can see by constantly
> > > flipping frequency adjucements in the logs since math
> > > currently used performs computation on very large
> > > numbers (products of time stamps) and very small
> > > ones (products of time offsets) and thus totally useless.
> > > i have figured a better way to follow frequency drift
> > > but that can be done in the next step.
> > > 
> > > this has ran on both i386 and sparc64 for months now
> > > and only has shown massive improvement in precision
> > > (decrease of deviation). thus local clock offset still
> > > flips every few hours from positive to negative and back
> > > due to broken frequency adjucements.
> > > 
> > > please read and try.

Index: Makefile
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/Makefile,v
retrieving revision 1.2
diff -u -p -r1.2 Makefile
--- Makefile    13 May 2009 18:10:04 -0000      1.2
+++ Makefile    15 May 2009 16:09:17 -0000
@@ -3,7 +3,7 @@
 
 PROG=  ntpd
 SRCS=  ntpd.c buffer.c log.c imsg.c ntp.c ntp_msg.c ntp_dns.c \
-       parse.y config.c server.c client.c sensors.c util.c
+       parse.y config.c server.c client.c sensors.c
 CFLAGS+= -Wall -I${.CURDIR}
 CFLAGS+= -Wstrict-prototypes -Wmissing-prototypes
 CFLAGS+= -Wmissing-declarations
Index: client.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/client.c,v
retrieving revision 1.4
diff -u -p -r1.4 client.c
--- client.c    15 May 2009 11:40:42 -0000      1.4
+++ client.c    15 May 2009 16:09:17 -0000
@@ -195,19 +195,21 @@ client_query(struct ntp_peer *p)
 int
 client_dispatch(struct ntp_peer *p, u_int8_t settime)
 {
-       struct ntp_msg           msg;
-       struct msghdr            somsg;
-       struct iovec             iov[1];   
-       struct timeval           tv1;
-       char                     buf[NTP_MSGSIZE];
+       extern int debug; /* from log.c */
+       struct ntp_msg  msg;
+       struct msghdr   somsg;
+       struct iovec    iov[1];
+       struct timeval  tv1, tv2;
+       char            buf[NTP_MSGSIZE];
        union {
                struct cmsghdr hdr;
                char buf[CMSG_SPACE(sizeof tv1)];
        } cmsgbuf;
-       struct cmsghdr          *cmsg;
-       ssize_t                  size;
-       double                   T1, T2, T3, T4;
-       time_t                   interval;
+       int64_t         T1, T2, T3, T4;
+       struct cmsghdr  *cmsg;
+       struct ntp_offset *reply;
+       ssize_t         size;
+       time_t          interval;
 
        somsg.msg_name = NULL;
        somsg.msg_namelen = 0;
@@ -219,7 +221,7 @@ client_dispatch(struct ntp_peer *p, u_in
        somsg.msg_controllen = sizeof cmsgbuf.buf;
        somsg.msg_flags = 0;
 
-       T4 = getoffset();
+       getoffset(&tv2);
        if ((size = recvmsg(p->query->fd, &somsg, 0)) < 0) {
                if (errno == EHOSTUNREACH || errno == EHOSTDOWN ||
                    errno == ENETUNREACH || errno == ENETDOWN ||
@@ -243,17 +245,20 @@ client_dispatch(struct ntp_peer *p, u_in
                return (0);
        }
 
+       T4 = 0;
        for (cmsg = CMSG_FIRSTHDR(&somsg); cmsg != NULL;
            cmsg = CMSG_NXTHDR(&somsg, cmsg)) {
                if (cmsg->cmsg_level == SOL_SOCKET &&
                    cmsg->cmsg_type == SCM_TIMESTAMP) {
                        memcpy(&tv1, CMSG_DATA(cmsg), sizeof tv1);
-                       T4 += tv1.tv_sec + JAN_1970 + 1.0e-6 * tv1.tv_usec;
+                       T4 = timeval2int64(&tv1);
+                       T4 += (int64_t)JAN_1970 << 31;
+                       T4 += timeval2int64(&tv2);
                        break;
                }
        }
 
-       if (T4 < JAN_1970) {
+       if (T4 == 0) {
                client_log_error(p, "recvmsg control format", EBADF);
                set_next(p, error_interval());
                return (0);
@@ -301,8 +306,8 @@ client_dispatch(struct ntp_peer *p, u_in
         */
 
        T1 = p->query->xmttime;
-       T2 = lfp_to_d(msg.rectime);
-       T3 = lfp_to_d(msg.xmttime);
+       T2 = lfxt2int64(&msg.rectime);
+       T3 = lfxt2int64(&msg.xmttime);
 
        /*
         * XXX workaround: time_t / tv_sec must never wrap.
@@ -314,32 +319,51 @@ client_dispatch(struct ntp_peer *p, u_in
                return (0);
        }
 
-       p->reply[p->shift].offset = ((T2 - T1) + (T3 - T4)) / 2;
-       p->reply[p->shift].delay = (T4 - T1) - (T3 - T2);
-       if (p->reply[p->shift].delay < 0) {
+       if (T4 <= T1) {
                interval = error_interval();
                set_next(p, interval);
-               log_info("reply from %s: negative delay %fs, "
+               log_info("local clock is not monotonic");
+               return (0);
+       }
+
+       reply = &p->reply[p->shift];
+
+       reply->offset = ((T2 - T1) + (T3 - T4)) / 2;
+       reply->delay = (T4 - T1) - (T3 - T2);
+       if (reply->delay < 0) {
+               char *s = "";
+               int64_t val = reply->delay;
+               if (val < 0) {
+                       s = "-";
+                       val = -val;
+               }
+               int642timeval(val, &tv2);
+               interval = error_interval();
+               set_next(p, interval);
+               log_info("reply from %s: negative delay %s%ld.%06lus "
                    "next query %ds",
                    log_sockaddr((struct sockaddr *)&p->addr->ss),
-                   p->reply[p->shift].delay, interval);
+                   s, tv2.tv_sec, tv2.tv_usec, interval);
                return (0);
        }
-       p->reply[p->shift].error = (T2 - T1) - (T3 - T4);
-       p->reply[p->shift].rcvd = getmonotime();
-       p->reply[p->shift].good = 1;
-
-       p->reply[p->shift].status.leap = (msg.status & LIMASK);
-       p->reply[p->shift].status.precision = msg.precision;
-       p->reply[p->shift].status.rootdelay = sfp_to_d(msg.rootdelay);
-       p->reply[p->shift].status.rootdispersion = sfp_to_d(msg.dispersion);
-       p->reply[p->shift].status.refid = msg.refid;
-       p->reply[p->shift].status.reftime = lfp_to_d(msg.reftime);
-       p->reply[p->shift].status.poll = msg.ppoll;
-       p->reply[p->shift].status.stratum = msg.stratum;
+
+       p->shift = (p->shift + 1) % OFFSET_ARRAY_SIZE;
+
+       reply->error = (T2 - T1) - (T3 - T4);
+       reply->rcvd = getmonotime();
+       reply->good = 1;
+
+       reply->status.leap = msg.status & LIMASK;
+       reply->status.precision = msg.precision;
+       reply->status.refid = ntohl(msg.refid);
+       reply->status.poll = msg.ppoll;
+       reply->status.stratum = msg.stratum;
+       reply->status.rootdelay = sfxt2int64(&msg.rootdelay);
+       reply->status.rootdispersion = sfxt2int64(&msg.dispersion);
+       reply->status.reftime = lfxt2int64(&msg.reftime);
 
        if (p->addr->ss.ss_family == AF_INET) {
-               p->reply[p->shift].status.send_refid =
+               reply->status.send_refid =
                    ((struct sockaddr_in *)&p->addr->ss)->sin_addr.s_addr;
        } else if (p->addr->ss.ss_family == AF_INET6) {
                MD5_CTX         context;
@@ -349,10 +373,10 @@ client_dispatch(struct ntp_peer *p, u_in
                MD5Update(&context, ((struct sockaddr_in6 *)&p->addr->ss)->
                    sin6_addr.s6_addr, sizeof(struct in6_addr));
                MD5Final(digest, &context);
-               memcpy((char *)&p->reply[p->shift].status.send_refid, digest,
+               memcpy((char *)&reply->status.send_refid, digest,
                    sizeof(u_int32_t));
        } else
-               p->reply[p->shift].status.send_refid = msg.xmttime.fractionl;
+               reply->status.send_refid = msg.xmttime.fractionl;
 
        if (p->trustlevel < TRUSTLEVEL_PATHETIC)
                interval = scale_interval(INTERVAL_QUERY_PATHETIC);
@@ -373,16 +397,25 @@ client_dispatch(struct ntp_peer *p, u_in
                p->trustlevel++;
        }
 
-       log_debug("reply from %s: offset %f delay %f, "
-           "next query %ds", log_sockaddr((struct sockaddr *)&p->addr->ss),
-           p->reply[p->shift].offset, p->reply[p->shift].delay, interval);
+       if (debug) {
+               char *s = "";
+               int64_t val = reply->offset;
+               if (val < 0) {
+                       s = "-";
+                       val = -val;
+               }
+               int642timeval(val, &tv1);
+               int642timeval(reply->delay, &tv2);
+               log_debug("reply from %s: "
+                   "offset %s%ld.%06lus delay %ld.%06lus, next query %ds",
+                   log_sockaddr((struct sockaddr *)&p->addr->ss),
+                   s, tv1.tv_sec, tv1.tv_usec, tv2.tv_sec, tv2.tv_usec,
+                   interval);
+       }
 
        client_update(p);
        if (settime)
-               priv_settime(p->reply[p->shift].offset);
-
-       if (++p->shift >= OFFSET_ARRAY_SIZE)
-               p->shift = 0;
+               priv_settime(reply->offset);
 
        return (0);
 }
@@ -390,7 +423,8 @@ client_dispatch(struct ntp_peer *p, u_in
 int
 client_update(struct ntp_peer *p)
 {
-       int     i, best = 0, good = 0;
+       struct ntp_offset       *reply, *best, *last;
+       int     good;
 
        /*
         * clock filter
@@ -399,28 +433,26 @@ client_update(struct ntp_peer *p)
         * invalidate it and all older ones
         */
 
-       for (i = 0; good == 0 && i < OFFSET_ARRAY_SIZE; i++)
-               if (p->reply[i].good) {
-                       good++;
-                       best = i;
-               }
-
-       for (; i < OFFSET_ARRAY_SIZE; i++)
-               if (p->reply[i].good) {
-                       good++;
-                       if (p->reply[i].delay < p->reply[best].delay)
-                               best = i;
-               }
+       for (good = 0, best = NULL, reply = &p->reply[0],
+           last = &p->reply[OFFSET_ARRAY_SIZE]; reply < last; reply++) {
+               if (!reply->good)
+                       continue;
+               good++;
+               if (!best)
+                       best = reply;
+               if (reply->delay < best->delay)
+                       best = reply;
+       }
 
-       if (good < 8)
+       if (good < OFFSET_ARRAY_SIZE)
                return (-1);
 
-       memcpy(&p->update, &p->reply[best], sizeof(p->update));
-       if (priv_adjtime() == 0) {
-               for (i = 0; i < OFFSET_ARRAY_SIZE; i++)
-                       if (p->reply[i].rcvd <= p->reply[best].rcvd)
-                               p->reply[i].good = 0;
-       }
+       memcpy(&p->update, best, sizeof(p->update));
+       if (priv_adjtime() == 0)
+               for (reply = &p->reply[0], last = &p->reply[OFFSET_ARRAY_SIZE];
+                   reply < last; reply++)
+                       if (reply->rcvd <= best->rcvd)
+                               reply->good = 0;
        return (0);
 }
 
Index: ntp.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp.c,v
retrieving revision 1.3
diff -u -p -r1.3 ntp.c
--- ntp.c       13 May 2009 18:10:04 -0000      1.3
+++ ntp.c       15 May 2009 16:09:17 -0000
@@ -1,4 +1,3 @@
-
 /*
  * Copyright (c) 2003, 2004 Henning Brauer <henn...@openbsd.org>
  * Copyright (c) 2004 Alexander Guy <alexander....@andern.org>
@@ -168,7 +167,7 @@ ntp_main(int pipe_prnt[2], struct ntpd_c
        conf->freq.xx = 0.0;
        conf->freq.xy = 0.0;
        conf->freq.y = 0.0;
-       conf->freq.overall_offset = 0.0;
+       conf->freq.overall_offset = 0;
 
        conf->status.synced = 0;
        clock_getres(CLOCK_REALTIME, &tp);
@@ -522,9 +521,10 @@ peer_remove(struct ntp_peer *p)
 }
 
 static void
-priv_adjfreq(double offset)
+priv_adjfreq(int64_t offset)
 {
-       double curtime, freq;
+       double curtime, freq, doff;
+       int64_t relfreq;
 
        if (!conf->status.synced)
                return;
@@ -535,12 +535,12 @@ priv_adjfreq(double offset)
                return;
 
        conf->freq.overall_offset += offset;
-       offset = conf->freq.overall_offset;
 
        curtime = gettime_corrected();
-       conf->freq.xy += offset * curtime;
+       doff = conf->freq.overall_offset;
+       conf->freq.xy += doff * curtime;
        conf->freq.x += curtime;
-       conf->freq.y += offset;
+       conf->freq.y += doff;
        conf->freq.xx += curtime * curtime;
 
        if (conf->freq.samples % FREQUENCY_SAMPLES != 0)
@@ -556,13 +556,14 @@ priv_adjfreq(double offset)
        else if (freq < -MAX_FREQUENCY_ADJUST)
                freq = -MAX_FREQUENCY_ADJUST;
 
-       imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, &freq, sizeof(freq));
+       relfreq = freq * 1e9 * (1LL << 32);
+       imsg_compose(ibuf_main, IMSG_ADJFREQ, 0, 0, &relfreq, sizeof(relfreq));
        conf->freq.xy = 0.0;
        conf->freq.x = 0.0;
        conf->freq.y = 0.0;
        conf->freq.xx = 0.0;
        conf->freq.samples = 0;
-       conf->freq.overall_offset = 0.0;
+       conf->freq.overall_offset = 0;
        conf->freq.num++;
 }
 
@@ -573,7 +574,7 @@ priv_adjtime(void)
        struct ntp_sensor        *s;
        int                       offset_cnt = 0, i = 0, j;
        struct ntp_offset       **offsets;
-       double                    offset_median;
+       int64_t                   offset_median;
 
        TAILQ_FOREACH(p, &conf->ntp_peers, entry) {
                if (p->trustlevel < TRUSTLEVEL_BADPEER)
@@ -626,8 +627,8 @@ priv_adjtime(void)
        }
        conf->status.leap = offsets[i]->status.leap;
 
-       imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0,
-           &offset_median, sizeof(offset_median));
+       imsg_compose(ibuf_main, IMSG_ADJTIME, 0, 0, &offset_median,
+           sizeof(offset_median));
 
        priv_adjfreq(offset_median);
 
@@ -671,9 +672,12 @@ offset_compare(const void *aa, const voi
 }
 
 void
-priv_settime(double offset)
+priv_settime(int64_t offset)
 {
-       imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &offset, sizeof(offset));
+       struct timeval tv;
+
+       int642timeval(offset, &tv);
+       imsg_compose(ibuf_main, IMSG_SETTIME, 0, 0, &tv, sizeof(tv));
        conf->settime = 0;
 }
 
@@ -687,19 +691,24 @@ priv_host_dns(char *name, u_int32_t peer
 }
 
 void
-update_scale(double offset)
+update_scale(int64_t offset)
 {
-       offset += getoffset();
-       if (offset < 0)
-               offset = -offset;
+       struct timeval tv;
+       int64_t qscale;
+
+       getoffset(&tv);
+       offset += timeval2int64(&tv);
 
-       if (offset > QSCALE_OFF_MAX || !conf->status.synced ||
-           conf->freq.num < 3)
+       qscale = int64init(QSCALE_OFF_MAX / 1000000, QSCALE_OFF_MAX % 1000000);
+       if (offset > qscale || !conf->status.synced || conf->freq.num < 3)
                conf->scale = 1;
-       else if (offset < QSCALE_OFF_MIN)
-               conf->scale = QSCALE_OFF_MAX / QSCALE_OFF_MIN;
-       else
-               conf->scale = QSCALE_OFF_MAX / offset;
+       else {
+               conf->scale = qscale / offset;  /* XXX */
+               qscale = int64init(QSCALE_OFF_MIN / 1000000,
+                   QSCALE_OFF_MIN % 1000000);
+               if (offset < qscale)
+                       conf->scale = QSCALE_OFF_MAX / QSCALE_OFF_MIN;
+       }
 }
 
 time_t
@@ -776,4 +785,41 @@ report_peers(int always)
                                log_warnx("bad sensor %s", s->device);
                }
        }
+}
+
+int64_t
+gettime_corrected()
+{
+       struct timeval tv;
+       getoffset(&tv);
+       return gettime() + timeval2int64(&tv);
+}
+
+void
+getoffset(struct timeval *tv)
+{
+       if (adjtime(NULL, tv) == -1)
+               memset(tv, 0, sizeof(*tv));
+}
+
+int64_t
+gettime()
+{
+       struct timeval  tv;
+
+       if (gettimeofday(&tv, NULL) == -1)
+               fatal("gettimeofday");
+
+       return timeval2int64(&tv) + ((int64_t)JAN_1970 << 31);
+}
+
+time_t
+getmonotime(void)
+{
+       struct timespec ts;
+
+       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
+               fatal("clock_gettime");
+
+       return (ts.tv_sec);
 }
Index: ntp.h
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp.h,v
retrieving revision 1.2
diff -u -p -r1.2 ntp.h
--- ntp.h       13 May 2009 18:10:04 -0000      1.2
+++ ntp.h       15 May 2009 16:09:17 -0000
@@ -43,11 +43,41 @@ struct l_fixedpt {
        u_int32_t fractionl;
 };
 
+       /* 2147 = 2^31 / 1000000 */
+#define        timeval2int64(tv)                                       \
+    (((int64_t)(tv)->tv_sec << 31) + (2147U * (tv)->tv_usec))
+
+#define        int64init(s,u)  (((int64_t)(s) << 31) + (2147U * (u)))
+
+#define        int642timeval(i,tv) do {                                \
+       (tv)->tv_sec = (i) >> 31;                               \
+       (tv)->tv_usec = ((i) & 0x7fffffff) / 2148;              \
+} while (0)
+
+#define        lfxt2int64(lf)                                          \
+    (((int64_t)ntohl((lf)->int_partl) << 31) + (ntohl((lf)->fractionl) >> 1))
+
+#define        int642lfxt(i,lf) do {                                   \
+       (lf)->int_partl = htonl((i) >> 31);                     \
+       (lf)->fractionl = htonl((i) << 1);                      \
+} while (0)
+
+#define        us2int64(us)    (2147ULL * (us))
+
 struct s_fixedpt {
        u_int16_t int_parts;
        u_int16_t fractions;
 };
 
+#define        int642sfxt(i,lf) do {                                   \
+       (lf)->int_parts = htons((i) >> 31);                     \
+       (lf)->fractions = htons((i & 0x7fffffff) >> 15);        \
+} while (0)
+
+#define        sfxt2int64(lf)                          \
+    (((int64_t)ntohs((lf)->int_parts) << 31) + \
+    ((u_int)ntohs((lf)->fractions) << 15))
+
 /* RFC Section 4
  *
  *    0                          1                   2                   3
@@ -107,9 +137,9 @@ struct ntp_msg {
 } __packed;
 
 struct ntp_query {
-       int                     fd;
-       struct ntp_msg          msg;
-       double                  xmttime;
+       struct ntp_msg  msg;
+       int64_t         xmttime;
+       int             fd;
 };
 
 /*
@@ -139,8 +169,8 @@ struct ntp_query {
 #define        MODE_RES1       6       /* reserved for NTP control message */
 #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 
*/
+#define        JAN_1970 2208988800LL   /* 1970 - 1900 in seconds */
+#define        JAN_2030 ((JAN_1970 + 1893456000LL) << 31) /* 1. 1. 2030 
00:00:00 */
 
 #define        NTP_VERSION     4
 #define        NTP_MAXSTRATUM  15
Index: ntp_dns.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntp_dns.c,v
retrieving revision 1.2
diff -u -p -r1.2 ntp_dns.c
--- ntp_dns.c   14 May 2009 12:23:33 -0000      1.2
+++ ntp_dns.c   15 May 2009 16:09:17 -0000
@@ -147,14 +147,15 @@ dns_dispatch_imsg(void)
                                fatalx("invalid IMSG_HOST_DNS received");
                        if ((cnt = host_dns(name, &hn, conf)) == -1)
                                break;
+                       if (cnt > MAX_SERVERS_DNS)
+                               cnt = MAX_SERVERS_DNS;
                        buf = imsg_create(ibuf_dns, IMSG_HOST_DNS,
                            imsg.hdr.peerid, 0,
                            cnt * sizeof(struct sockaddr_storage));
                        if (buf == NULL)
                                break;
-                       if (cnt > 0)
-                               for (h = hn; h != NULL; h = h->next)
-                                       imsg_add(buf, &h->ss, sizeof(h->ss));
+                       for (h = hn; cnt-- && h != NULL; h = h->next)
+                               imsg_add(buf, &h->ss, sizeof(h->ss));
 
                        imsg_close(ibuf_dns, buf);
                        break;
Index: ntpd.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.c,v
retrieving revision 1.4
diff -u -p -r1.4 ntpd.c
--- ntpd.c      14 May 2009 12:23:33 -0000      1.4
+++ ntpd.c      15 May 2009 16:09:17 -0000
@@ -38,11 +38,11 @@ int         main(int, char *[]);
 int            check_child(pid_t, const char *);
 int            dispatch_imsg(struct ntpd_conf *);
 void           reset_adjtime(void);
-int            ntpd_adjtime(double);
-void           ntpd_adjfreq(double, int);
-void           ntpd_settime(double);
+int            ntpd_adjtime(int64_t);
+void           ntpd_adjfreq(int64_t, int);
+void           ntpd_settime(struct timeval *);
 void           readfreq(void);
-int            writefreq(double);
+int            writefreq(int64_t);
 
 volatile sig_atomic_t   quit = 0;
 volatile sig_atomic_t   reconfig = 0;
@@ -271,10 +271,11 @@ dispatch_imsg(struct ntpd_conf *lconf)
 {
        struct imsg              imsg;
        int                      n, cnt;
-       double                   d;
+       struct timeval           tv;
        char                    *name;
        struct ntp_addr         *h, *hn;
        struct buf              *buf;
+       int64_t                  d;
 
        if ((n = imsg_read(ibuf)) == -1)
                return (-1);
@@ -306,13 +307,13 @@ dispatch_imsg(struct ntpd_conf *lconf)
                        ntpd_adjfreq(d, 1);
                        break;
                case IMSG_SETTIME:
-                       if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(d))
+                       if (imsg.hdr.len != IMSG_HEADER_SIZE + sizeof(tv))
                                fatalx("invalid IMSG_SETTIME received");
                        if (!lconf->settime)
                                break;
                        log_init(lconf->debug);
-                       memcpy(&d, imsg.data, sizeof(d));
-                       ntpd_settime(d);
+                       memcpy(&tv, imsg.data, sizeof(tv));
+                       ntpd_settime(&tv);
                        /* daemonize now */
                        if (!lconf->debug)
                                if (daemon(1, 0))
@@ -361,19 +362,30 @@ reset_adjtime(void)
 }
 
 int
-ntpd_adjtime(double d)
+ntpd_adjtime(int64_t d)
 {
-       struct timeval  tv, olddelta;
-       int             synced = 0;
        static int      firstadj = 1;
+       struct timeval  tv, tv1, olddelta;
+       char            *s = "";
+       int             synced = 0;
 
-       d += getoffset();
-       if (d >= (double)LOG_NEGLIGIBLE_ADJTIME / 1000 ||
-           d <= -1 * (double)LOG_NEGLIGIBLE_ADJTIME / 1000)
-               log_info("adjusting local clock by %fs", d);
+       getoffset(&olddelta);
+       int642timeval(d, &tv);
+       timeradd(&tv, &olddelta, &tv);
+
+       if (d < 0) {
+               s = "-";
+               d = -d;
+       }
+
+       int642timeval(d, &tv1);
+       if (tv1.tv_sec || tv1.tv_usec >= LOG_NEGLIGEE * 1000)
+               log_info("adjusting local clock by %s%ld.%06lus",
+                   s, tv1.tv_sec, tv1.tv_usec);
        else
-               log_debug("adjusting local clock by %fs", d);
-       d_to_tv(d, &tv);
+               log_debug("adjusting local clock by %s%ld.%06lus",
+                   s, tv1.tv_sec, tv1.tv_usec);
+
        if (adjtime(&tv, &olddelta) == -1)
                log_warn("adjtime failed");
        else if (!firstadj && olddelta.tv_sec == 0 && olddelta.tv_usec == 0)
@@ -383,44 +395,42 @@ ntpd_adjtime(double d)
 }
 
 void
-ntpd_adjfreq(double relfreq, int wrlog)
+ntpd_adjfreq(int64_t relfreq, int wrlog)
 {
        int64_t curfreq;
-       double ppmfreq;
+       char *sign = "";
        int r;
 
        if (adjfreq(NULL, &curfreq) == -1) {
                log_warn("adjfreq failed");
                return;
        }
+       curfreq += relfreq;
 
        /*
-        * adjfreq's unit is ns/s shifted left 32; convert relfreq to
-        * that unit before adding. We log values in part per million.
+        * adjfreq's unit is ns/s shifted left 32.
+        * We log values in part per million.
         */
-       curfreq += relfreq * 1e9 * (1LL << 32);
-       r = writefreq(curfreq / 1e9 / (1LL << 32));
-       ppmfreq = relfreq * 1e6;
-       if (wrlog) {
-               if (ppmfreq >= LOG_NEGLIGIBLE_ADJFREQ ||
-                   ppmfreq <= -LOG_NEGLIGIBLE_ADJFREQ)
-                       log_info("adjusting clock frequency by %f to %fppm%s",
-                           ppmfreq, curfreq / 1e3 / (1LL << 32),
-                           r ? "" : " (no drift file)");
-               else
-                       log_debug("adjusting clock frequency by %f to %fppm%s",
-                           ppmfreq, curfreq / 1e3 / (1LL << 32),
-                           r ? "" : " (no drift file)");
-       }
+       r = writefreq(curfreq);
+       if (relfreq < 0) {
+               relfreq = -relfreq;
+               sign = "-";
+       }
+       if (wrlog)
+               log_info("adjusting clock frequency by %s0.%06d to 
%d.%06dppm%s",
+                   sign, (int)(relfreq >> 32) % 1000000,
+                   (int)(curfreq >> 32) / 1000000,
+                   (int)(curfreq >> 32) % 1000000,
+                   r ? " (no drift file)" : "");
 
        if (adjfreq(&curfreq, NULL) == -1)
                log_warn("adjfreq failed");
 }
 
 void
-ntpd_settime(double d)
+ntpd_settime(struct timeval *tv)
 {
-       struct timeval  tv, curtime;
+       struct timeval  curtime;
        char            buf[80];
        time_t          tval;
 
@@ -428,9 +438,8 @@ ntpd_settime(double d)
                log_warn("gettimeofday");
                return;
        }
-       d_to_tv(d, &tv);
-       curtime.tv_usec += tv.tv_usec + 1000000;
-       curtime.tv_sec += tv.tv_sec - 1 + (curtime.tv_usec / 1000000);
+       curtime.tv_usec += tv->tv_usec + 1000000;
+       curtime.tv_sec += tv->tv_sec - 1 + (curtime.tv_usec / 1000000);
        curtime.tv_usec %= 1000000;
 
        if (settimeofday(&curtime, NULL) == -1) {
@@ -440,15 +449,15 @@ ntpd_settime(double d)
        tval = curtime.tv_sec;
        strftime(buf, sizeof(buf), "%a %b %e %H:%M:%S %Z %Y",
            localtime(&tval));
-       log_info("set local clock to %s (offset %fs)", buf, d);
+       log_info("set local clock to %s (offset %ld.%06lus)", buf,
+           tv->tv_sec, tv->tv_usec);
 }
 
 void
 readfreq(void)
 {
+       int64_t current, d;
        FILE *fp;
-       int64_t current;
-       double d;
 
        fp = fopen(DRIFTFILE, "r");
        if (fp == NULL) {
@@ -463,7 +472,7 @@ readfreq(void)
        if (adjfreq(NULL, &current) == -1)
                log_warn("adjfreq failed");
        else if (current == 0) {
-               if (fscanf(fp, "%le", &d) == 1)
+               if (fscanf(fp, "%lld", &d) == 1)
                        ntpd_adjfreq(d, 0);
                else
                        log_warnx("can't read %s", DRIFTFILE);
@@ -472,7 +481,7 @@ readfreq(void)
 }
 
 int
-writefreq(double d)
+writefreq(int64_t d)
 {
        int r;
        FILE *fp;
@@ -484,10 +493,10 @@ writefreq(double d)
                        log_warn("can't open %s", DRIFTFILE);
                        warnonce = 0;
                }
-               return 0;
+               return -1;
        }
 
-       fprintf(fp, "%e\n", d);
+       fprintf(fp, "%lld\n", d);
        r = ferror(fp);
        if (fclose(fp) != 0 || r != 0) {
                if (warnonce) {
@@ -495,7 +504,7 @@ writefreq(double d)
                        warnonce = 0;
                }
                unlink(DRIFTFILE);
-               return 0;
+               return -1;
        }
-       return 1;
+       return 0;
 }
Index: ntpd.h
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/ntpd.h,v
retrieving revision 1.4
diff -u -p -r1.4 ntpd.h
--- ntpd.h      14 May 2009 12:23:33 -0000      1.4
+++ ntpd.h      15 May 2009 16:09:17 -0000
@@ -34,7 +34,7 @@
 #define        CONFFILE        "/etc/ntpd.conf"
 #define DRIFTFILE      "/var/db/ntpd.drift"
 
-#define        READ_BUF_SIZE           8192
+#define        READ_BUF_SIZE           (256 * 10)
 
 #define        INTERVAL_QUERY_NORMAL           30      /* sync to peers every 
n secs */
 #define        INTERVAL_QUERY_PATHETIC         60
@@ -47,15 +47,14 @@
 
 #define        MAX_SERVERS_DNS                 8
 
-#define        QSCALE_OFF_MIN                  0.001
-#define        QSCALE_OFF_MAX                  0.050
+#define        QSCALE_OFF_MIN                  50000   /* us */
+#define        QSCALE_OFF_MAX                  500000  /* us */
 
 #define        QUERYTIME_MAX           15      /* single query might take n 
secs max */
 #define        OFFSET_ARRAY_SIZE       8
 #define        SENSOR_OFFSETS          7
 #define        SETTIME_TIMEOUT         15      /* max seconds to wait with -s 
*/
-#define        LOG_NEGLIGIBLE_ADJTIME  32      /* negligible drift to not log 
(ms) */
-#define        LOG_NEGLIGIBLE_ADJFREQ  0.05    /* negligible rate to not log 
(ppm) */
+#define        LOG_NEGLIGEE            32      /* negligible drift to not log 
(ms) */
 #define        FREQUENCY_SAMPLES       8       /* samples for est. of 
permanent drift */
 #define        MAX_FREQUENCY_ADJUST    128e-5  /* max correction per iteration 
*/
 #define REPORT_INTERVAL                (24*60*60) /* interval between status 
reports */
@@ -94,9 +93,9 @@ struct ntp_addr_wrap {
 };
 
 struct ntp_status {
-       double          rootdelay;
-       double          rootdispersion;
-       double          reftime;
+       int64_t         rootdelay;
+       int64_t         rootdispersion;
+       int64_t         reftime;
        u_int32_t       refid;
        u_int32_t       send_refid;
        u_int8_t        synced;
@@ -108,9 +107,9 @@ struct ntp_status {
 
 struct ntp_offset {
        struct ntp_status       status;
-       double                  offset;
-       double                  delay;
-       double                  error;
+       int64_t                 offset;
+       int64_t                 delay;
+       int64_t                 error;
        time_t                  rcvd;
        u_int8_t                good;
 };
@@ -126,56 +125,56 @@ struct ntp_peer {
        time_t                           next;
        time_t                           deadline;
        u_int32_t                        id;
+       int                              lasterror;
+       int                              senderrors;
        u_int8_t                         shift;
        u_int8_t                         trustlevel;
        u_int8_t                         weight;
-       int                              lasterror;
-       int                              senderrors;
 };
 
 struct ntp_sensor {
        TAILQ_ENTRY(ntp_sensor)          entry;
        struct ntp_offset                offsets[SENSOR_OFFSETS];
        struct ntp_offset                update;
+       int64_t                          correction;
        time_t                           next;
        time_t                           last;
        char                            *device;
        u_int32_t                        refid;
        int                              sensordevid;
-       int                              correction;
        u_int8_t                         weight;
        u_int8_t                         shift;
 };
 
 struct ntp_conf_sensor {
-       TAILQ_ENTRY(ntp_conf_sensor)             entry;
-       char                                    *device;
-       char                                    *refstr;
-       int                                      correction;
-       u_int8_t                                 weight;
+       TAILQ_ENTRY(ntp_conf_sensor)     entry;
+       char                            *device;
+       char                            *refstr;
+       int                              correction;
+       u_int8_t                         weight;
 };
 
 struct ntp_freq {
-       double                          overall_offset;
-       double                          x, y;
-       double                          xx, xy;
-       int                             samples;
-       u_int                           num;
+       double  x, y;
+       double  xx, xy;
+       int64_t overall_offset;
+       int     samples;
+       u_int   num;
 };
 
 struct ntpd_conf {
-       TAILQ_HEAD(listen_addrs, listen_addr)           listen_addrs;
-       TAILQ_HEAD(ntp_peers, ntp_peer)                 ntp_peers;
-       TAILQ_HEAD(ntp_sensors, ntp_sensor)             ntp_sensors;
-       TAILQ_HEAD(ntp_conf_sensors, ntp_conf_sensor)   ntp_conf_sensors;
-       struct ntp_status                               status;
-       struct ntp_freq                                 freq;
-       u_int8_t                                        listen_all;
-       u_int8_t                                        settime;
-       u_int8_t                                        debug;
-       u_int32_t                                       scale;
-       u_int8_t                                        noaction;
-       u_int8_t                                        family;
+       TAILQ_HEAD(, listen_addr)       listen_addrs;
+       TAILQ_HEAD(, ntp_peer)          ntp_peers;
+       TAILQ_HEAD(, ntp_sensor)        ntp_sensors;
+       TAILQ_HEAD(, ntp_conf_sensor)   ntp_conf_sensors;
+       struct ntp_status               status;
+       struct ntp_freq                 freq;
+       u_int32_t                       scale;
+       u_int8_t                        listen_all;
+       u_int8_t                        settime;
+       u_int8_t                        debug;
+       u_int8_t                        noaction;
+       u_int8_t                        family;
 };
 
 struct buf {
@@ -201,7 +200,7 @@ struct buf_read {
 /* ipc messages */
 
 #define        IMSG_HEADER_SIZE        sizeof(struct imsg_hdr)
-#define        MAX_IMSGSIZE            8192
+#define        MAX_IMSGSIZE            (256 * 10)
 
 struct imsgbuf {
        int                     fd;
@@ -264,14 +263,18 @@ int        imsg_close(struct imsgbuf *, struct
 void    imsg_free(struct imsg *);
 
 /* ntp.c */
-pid_t   ntp_main(int[2], struct ntpd_conf *, struct passwd *);
-int     priv_adjtime(void);
-void    priv_settime(double);
-void    priv_host_dns(char *, u_int32_t);
-int     offset_compare(const void *, const void *);
-void    update_scale(double);
-time_t  scale_interval(time_t);
-time_t  error_interval(void);
+pid_t  ntp_main(int[2], struct ntpd_conf *, struct passwd *);
+int    priv_adjtime(void);
+void   priv_settime(int64_t);
+void   priv_host_dns(char *, u_int32_t);
+int    offset_compare(const void *, const void *);
+void   update_scale(int64_t);
+time_t scale_interval(time_t);
+time_t error_interval(void);
+int64_t        gettime_corrected(void);
+void   getoffset(struct timeval *);
+int64_t        gettime(void);
+time_t getmonotime(void);
 extern struct ntpd_conf *conf;
 
 /* parse.y */
@@ -301,23 +304,12 @@ int       client_dispatch(struct ntp_peer *, u
 void   client_log_error(struct ntp_peer *, const char *, int);
 void   set_next(struct ntp_peer *, time_t);
 
-/* util.c */
-double                 gettime_corrected(void);
-double                 getoffset(void);
-double                 gettime(void);
-time_t                 getmonotime(void);
-void                   d_to_tv(double, struct timeval *);
-double                 lfp_to_d(struct l_fixedpt);
-struct l_fixedpt       d_to_lfp(double);
-double                 sfp_to_d(struct s_fixedpt);
-struct s_fixedpt       d_to_sfp(double);
-
 /* sensors.c */
-void                   sensor_init(void);
-int                    sensor_scan(void);
-void                   sensor_query(struct ntp_sensor *);
-int                    sensor_hotplugfd(void);
-void                   sensor_hotplugevent(int);
+void   sensor_init(void);
+int    sensor_scan(void);
+void   sensor_query(struct ntp_sensor *);
+int    sensor_hotplugfd(void);
+void   sensor_hotplugevent(int);
 
 /* ntp_dns.c */
 pid_t  ntp_dns(int[2], struct ntpd_conf *, struct passwd *);
Index: sensors.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/sensors.c,v
retrieving revision 1.3
diff -u -p -r1.3 sensors.c
--- sensors.c   13 May 2009 18:10:04 -0000      1.3
+++ sensors.c   15 May 2009 16:09:18 -0000
@@ -121,7 +121,7 @@ sensor_add(int sensordev, char *dxname)
 
        s->next = getmonotime();
        s->weight = cs->weight;
-       s->correction = cs->correction;
+       s->correction = us2int64(cs->correction);
        if ((s->device = strdup(dxname)) == NULL)
                fatal("sensor_add strdup");
        s->sensordevid = sensordev;
@@ -135,8 +135,10 @@ sensor_add(int sensordev, char *dxname)
 
        TAILQ_INSERT_TAIL(&conf->ntp_sensors, s, entry);
 
-       log_debug("sensor %s added (weight %d, correction %.6f, refstr %.4s)",
-           s->device, s->weight, s->correction / 1e6, &s->refid);
+       log_debug(
+           "sensor %s added (weight %d, correction %d.%06u, refstr %-4s)",
+           s->device, s->weight,
+           cs->correction / 1000000, cs->correction % 1000000, &s->refid);
 }
 
 void
@@ -152,6 +154,7 @@ sensor_query(struct ntp_sensor *s)
 {
        char             dxname[MAXDEVNAMLEN];
        struct sensor    sensor;
+       struct timeval   tv;
 
        if (conf->settime)
                s->next = getmonotime() + SENSOR_QUERY_INTERVAL_SETTIME;
@@ -186,16 +189,17 @@ sensor_query(struct ntp_sensor *s)
         * sensor.value = TS - TD in ns
         * if value is positive, system time is ahead
         */
-       s->offsets[s->shift].offset = (sensor.value / -1e9) - getoffset() +
-           (s->correction / 1e6);
+       getoffset(&tv);
+       s->offsets[s->shift].offset = s->correction +
+           us2int64(sensor.value / 1000) - timeval2int64(&tv);
        s->offsets[s->shift].rcvd = sensor.tv.tv_sec;
        s->offsets[s->shift].good = 1;
 
        s->offsets[s->shift].status.send_refid = s->refid;
-       s->offsets[s->shift].status.stratum = 0;        /* increased when sent 
out */
+       s->offsets[s->shift].status.stratum = 0;  /* increased when sent out */
        s->offsets[s->shift].status.rootdelay = 0;
        s->offsets[s->shift].status.rootdispersion = 0;
-       s->offsets[s->shift].status.reftime = sensor.tv.tv_sec;
+       s->offsets[s->shift].status.reftime = timeval2int64(&sensor.tv);
        s->offsets[s->shift].status.synced = 1;
 
        log_debug("sensor %s: offset %f", s->device,
@@ -226,10 +230,9 @@ sensor_update(struct ntp_sensor *s)
 
        i = SENSOR_OFFSETS / 2;
        memcpy(&s->update, offsets[i], sizeof(s->update));
-       if (SENSOR_OFFSETS % 2 == 0) {
+       if (SENSOR_OFFSETS % 2 == 0)
                s->update.offset =
                    (offsets[i - 1]->offset + offsets[i]->offset) / 2;
-       }
        free(offsets);
 
        log_debug("sensor update %s: offset %f", s->device, s->update.offset);
Index: server.c
===================================================================
RCS file: /cvs/src/usr.sbin/ntpd/server.c,v
retrieving revision 1.3
diff -u -p -r1.3 server.c
--- server.c    13 May 2009 18:10:04 -0000      1.3
+++ server.c    15 May 2009 16:09:18 -0000
@@ -127,11 +127,11 @@ server_dispatch(int fd, struct ntpd_conf
 {
        ssize_t                  size;
        u_int8_t                 version;
-       double                   rectime;
        struct sockaddr_storage  fsa;
        socklen_t                fsa_len;
        struct ntp_msg           query, reply;
        char                     buf[NTP_MSGSIZE];
+       int64_t                  rectime;
 
        fsa_len = sizeof(fsa);
        if ((size = recvfrom(fd, &buf, sizeof(buf), 0,
@@ -146,7 +146,6 @@ server_dispatch(int fd, struct ntpd_conf
        }
 
        rectime = gettime_corrected();
-
        if (ntp_getmsg((struct sockaddr *)&fsa, buf, size, &query) == -1)
                return (0);
 
@@ -163,15 +162,16 @@ server_dispatch(int fd, struct ntpd_conf
        else
                reply.status |= MODE_SYM_PAS;
 
+       reply.refid = lconf->status.refid;
        reply.stratum = lconf->status.stratum;
        reply.ppoll = query.ppoll;
        reply.precision = lconf->status.precision;
-       reply.rectime = d_to_lfp(rectime);
-       reply.reftime = d_to_lfp(lconf->status.reftime);
-       reply.xmttime = d_to_lfp(gettime_corrected());
        reply.orgtime = query.xmttime;
-       reply.rootdelay = d_to_sfp(lconf->status.rootdelay);
-       reply.refid = lconf->status.refid;
+       int642lfxt(rectime, &reply.rectime);
+       int642lfxt(lconf->status.reftime, &reply.reftime);
+       int642sfxt(lconf->status.rootdelay, &reply.rootdelay);
+       rectime = gettime_corrected();
+       int642lfxt(rectime, &reply.xmttime);  
 
        ntp_sendmsg(fd, (struct sockaddr *)&fsa, &reply, size, 0);
        return (0);
Index: util.c
===================================================================
RCS file: util.c
diff -N util.c
--- util.c      26 Aug 2008 14:44:25 -0000      1.1.1.1
+++ /dev/null   1 Jan 1970 00:00:00 -0000
@@ -1,118 +0,0 @@
-
-/*
- * Copyright (c) 2004 Alexander Guy <alexander....@andern.org>
- *
- * Permission to use, copy, modify, and distribute this software for any
- * purpose with or without fee is hereby granted, provided that the above
- * copyright notice and this permission notice appear in all copies.
- *
- * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
- * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
- * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
- * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
- * WHATSOEVER RESULTING FROM LOSS OF MIND, USE, DATA OR PROFITS, WHETHER
- * IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING
- * OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
- */
-
-#include <sys/time.h>
-#include <limits.h>
-
-#include "ntpd.h"
-
-double
-gettime_corrected(void)
-{
-       return (gettime() + getoffset());
-}
-
-double
-getoffset(void)
-{
-       struct timeval  tv;
-       if (adjtime(NULL, &tv) == -1)
-               return (0.0);
-       return (tv.tv_sec + 1.0e-6 * tv.tv_usec);
-}
-
-double
-gettime(void)
-{
-       struct timeval  tv;
-
-       if (gettimeofday(&tv, NULL) == -1)
-               fatal("gettimeofday");
-
-       return (tv.tv_sec + JAN_1970 + 1.0e-6 * tv.tv_usec);
-}
-
-time_t
-getmonotime(void)
-{
-       struct timespec ts;
-
-       if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
-               fatal("clock_gettime");
-
-       return (ts.tv_sec);
-}
-
-
-void
-d_to_tv(double d, struct timeval *tv)
-{
-       tv->tv_sec = (long)d;
-       tv->tv_usec = (d - tv->tv_sec) * 1000000;
-       while (tv->tv_usec < 0) {
-               tv->tv_usec += 1000000;
-               tv->tv_sec -= 1;
-       }
-}
-
-double
-lfp_to_d(struct l_fixedpt lfp)
-{
-       double  ret;
-
-       lfp.int_partl = ntohl(lfp.int_partl);
-       lfp.fractionl = ntohl(lfp.fractionl);
-
-       ret = (double)(lfp.int_partl) + ((double)lfp.fractionl / UINT_MAX);
-
-       return (ret);
-}
-
-struct l_fixedpt
-d_to_lfp(double d)
-{
-       struct l_fixedpt        lfp;
-
-       lfp.int_partl = htonl((u_int32_t)d);
-       lfp.fractionl = htonl((u_int32_t)((d - (u_int32_t)d) * UINT_MAX));
-
-       return (lfp);
-}
-
-double
-sfp_to_d(struct s_fixedpt sfp)
-{
-       double  ret;
-
-       sfp.int_parts = ntohs(sfp.int_parts);
-       sfp.fractions = ntohs(sfp.fractions);
-
-       ret = (double)(sfp.int_parts) + ((double)sfp.fractions / USHRT_MAX);
-
-       return (ret);
-}
-
-struct s_fixedpt
-d_to_sfp(double d)
-{
-       struct s_fixedpt        sfp;
-
-       sfp.int_parts = htons((u_int16_t)d);
-       sfp.fractions = htons((u_int16_t)((d - (u_int16_t)d) * USHRT_MAX));
-
-       return (sfp);
-}

Reply via email to