From: Harlan Stenn Date: Tue, 23 Oct 2012 02:16:06 +0000 (+0000) Subject: [Bug 2293] add support for SO_BINTIME, refine support for SO_TIMESTAMPNS (bug 1374) X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=ff9c526c8fcd137f1a3f4032ff365d421d473894;p=thirdparty%2Fntp.git [Bug 2293] add support for SO_BINTIME, refine support for SO_TIMESTAMPNS (bug 1374) bk: 5085fde6f217coNrBvh6zlRPp372vw --- diff --git a/ChangeLog b/ChangeLog index c02521357c..7228b01b31 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,6 @@ * [Bug 2291] sntp should report why it cannot open file.kod. +* [Bug 2293] add support for SO_BINTIME, refine support for + SO_TIMESTAMPNS (bug 1374) (4.2.7p312) 2012/10/11 Released by Harlan Stenn * Clean up testing/debugging of fix for [Bug 938] from sntp/main.c . (4.2.7p311) 2012/10/10 Released by Harlan Stenn diff --git a/ntpd/ntp_io.c b/ntpd/ntp_io.c index 091254aa91..58e4c85bb6 100644 --- a/ntpd/ntp_io.c +++ b/ntpd/ntp_io.c @@ -33,6 +33,7 @@ #include "ntp_request.h" #include "ntp_assert.h" #include "timevalops.h" +#include "timespecops.h" #include "ntpd-opts.h" /* Don't include ISC's version of IPv6 variables and structures */ @@ -87,7 +88,15 @@ struct nic_rule_tag { nic_rule *nic_rule_list; -#if defined(SO_TIMESTAMPNS) && defined(SCM_TIMESTAMPNS) && defined(CMSG_FIRSTHDR) +#if defined(SO_BINTIME) && defined(SCM_BINTIME) && defined(CMSG_FIRSTHDR) +# define HAVE_PACKET_TIMESTAMP +# define HAVE_BINTIME +# ifdef BINTIME_CTLMSGBUF_SIZE +# define CMSG_BUFSIZE BINTIME_CTLMSGBUF_SIZE +# else +# define CMSG_BUFSIZE 1536 /* moderate default */ +# endif +#elif defined(SO_TIMESTAMPNS) && defined(SCM_TIMESTAMPNS) && defined(CMSG_FIRSTHDR) # define HAVE_PACKET_TIMESTAMP # define HAVE_TIMESTAMPNS # ifdef TIMESTAMPNS_CTLMSGBUF_SIZE @@ -2963,6 +2972,18 @@ open_socket( fd, stoa(addr))); } #endif +#ifdef HAVE_BINTIME + { + if (setsockopt(fd, SOL_SOCKET, SO_BINTIME, + (char*)&on, sizeof(on))) + msyslog(LOG_DEBUG, + "setsockopt SO_BINTIME on fails on address %s: %m", + stoa(addr)); + else + DPRINTF(4, ("setsockopt SO_BINTIME enabled on fd %d address %s\n", + fd, stoa(addr))); + } +#endif DPRINTF(4, ("bind(%d) AF_INET%s, addr %s%%%d#%d, flags 0x%x\n", fd, IS_IPV6(addr) ? "6" : "", stoa(addr), @@ -3209,8 +3230,16 @@ fetch_timestamp( ) { struct cmsghdr * cmsghdr; +#ifdef HAVE_BINTIME + struct bintime * btp; +#endif +#ifdef HAVE_TIMESTAMPNS + struct timespec * tsp; +#endif +#ifdef HAVE_TIMESTAMP struct timeval * tvp; - long ticks; +#endif + unsigned long ticks; double fuzz; l_fp lfpfuzz; l_fp nts; @@ -3222,19 +3251,66 @@ fetch_timestamp( while (cmsghdr != NULL) { switch (cmsghdr->cmsg_type) { +#ifdef HAVE_BINTIME + case SCM_BINTIME: +#endif /* HAVE_BINTIME */ +#ifdef HAVE_TIMESTAMPNS + case SCM_TIMESTAMPNS: +#endif /* HAVE_TIMESTAMPNS */ #ifdef HAVE_TIMESTAMP case SCM_TIMESTAMP: - tvp = (struct timeval *)CMSG_DATA(cmsghdr); - if (sys_tick > measured_tick && - sys_tick > 1e-6) { - ticks = (long)((tvp->tv_usec * 1e-6) / - sys_tick); - tvp->tv_usec = (long)(ticks * 1e6 * - sys_tick); +#endif /* HAVE_TIMESTAMP */ +#if defined(HAVE_BINTIME) || defined (HAVE_TIMESTAMPNS) || defined(HAVE_TIMESTAMP) + switch (cmsghdr->cmsg_type) + { +#ifdef HAVE_BINTIME + case SCM_BINTIME: + btp = (struct bintime *)CMSG_DATA(cmsghdr); + /* + * bintime documentation is at http://phk.freebsd.dk/pubs/timecounter.pdf + */ + nts.l_i = btp->sec + JAN_1970; + nts.l_uf = (u_int32)(btp->frac >> 32); + if (sys_tick > measured_tick && + sys_tick > 1e-9) { + ticks = (unsigned long)(nts.l_uf / (unsigned long)(sys_tick * FRAC)); + nts.l_uf = (unsigned long)(ticks * (unsigned long)(sys_tick * FRAC)); + } + DPRINTF(4, ("fetch_timestamp: system bintime network time stamp: %ld.%09lu\n", + btp->sec, (unsigned long)((nts.l_uf / FRAC) * 1e9))); + break; +#endif /* HAVE_BINTIME */ +#ifdef HAVE_TIMESTAMPNS + case SCM_TIMESTAMPNS: + tsp = (struct timespec *)CMSG_DATA(cmsghdr); + if (sys_tick > measured_tick && + sys_tick > 1e-9) { + ticks = (unsigned long)((tsp->tv_nsec * 1e-9) / + sys_tick); + tsp->tv_nsec = (long)(ticks * 1e9 * + sys_tick); + } + DPRINTF(4, ("fetch_timestamp: system nsec network time stamp: %ld.%09ld\n", + tsp->tv_sec, tsp->tv_nsec)); + nts = tspec_stamp_to_lfp(*tsp); + break; +#endif /* HAVE_TIMESTAMPNS */ +#ifdef HAVE_TIMESTAMP + case SCM_TIMESTAMP: + tvp = (struct timeval *)CMSG_DATA(cmsghdr); + if (sys_tick > measured_tick && + sys_tick > 1e-6) { + ticks = (unsigned long)((tvp->tv_usec * 1e-6) / + sys_tick); + tvp->tv_usec = (long)(ticks * 1e6 * + sys_tick); + } + DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %ld.%06ld\n", + tvp->tv_sec, tvp->tv_usec)); + nts = tval_stamp_to_lfp(*tvp); + break; +#endif /* HAVE_TIMESTAMP */ } - DPRINTF(4, ("fetch_timestamp: system usec network time stamp: %ld.%06ld\n", - tvp->tv_sec, tvp->tv_usec)); - nts = tval_stamp_to_lfp(*tvp); fuzz = ntp_random() * 2. / FRAC * sys_fuzz; DTOLFP(fuzz, &lfpfuzz); L_ADD(&nts, &lfpfuzz); @@ -3248,39 +3324,7 @@ fetch_timestamp( #endif /* DEBUG_TIMING */ ts = nts; /* network time stamp */ break; -#endif /* HAVE_TIMESTAMP */ - -#ifdef HAVE_TIMESTAMPNS - case SCM_TIMESTAMPNS: - { - struct timespec *tsp; - double dtemp; - l_fp nts; - - tsp = (struct timespec *)CMSG_DATA(cmsghdr); - DPRINTF(4, ("fetch_timestamp: system nsec network time stamp: %ld.%09ld\n", - tsp->tv_sec, tsp->tv_nsec)); - nts.l_i = tsp->tv_sec + JAN_1970; - dtemp = (tsp->tv_nsec - + (ntp_random() * 2. / FRAC)) / 1e9; - nts.l_uf = (u_int32)(dtemp * FRAC); -#ifdef DEBUG_TIMING - { - l_fp dts; - - dts = ts; - L_SUB(&dts, &nts); - collect_timing(rb, - "input processing delay", - 1, &dts); - DPRINTF(4, ("fetch_timestamp: timestamp delta: %s (incl. prec fuzz)\n", - lfptoa(&dts, 9))); - } -#endif - ts = nts; /* network time stamp */ - break; - } -#endif /* HAVE_TIMESTAMPNS */ +#endif /* HAVE_BINTIME || HAVE_TIMESTAMPNS || HAVE_TIMESTAMP */ default: DPRINTF(4, ("fetch_timestamp: skipping control message 0x%x\n",