From: Harlan Stenn Date: Tue, 15 Sep 2009 05:28:52 +0000 (-0400) Subject: Make the code agree with the spec and the book (Dave Mills) X-Git-Tag: NTP_4_2_5P212~3^2~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=09914bacaef5284077b8f7d26136cc42a34c1d67;p=thirdparty%2Fntp.git Make the code agree with the spec and the book (Dave Mills) bk: 4aaf2614MFAC3wyeS-LKFnYKr9aQkQ --- diff --git a/ChangeLog b/ChangeLog index b2f39b471..ab56ab81a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,4 @@ +* Make the code agree with the spec and the book (Dave Mills). (4.2.5p211) 2009/09/14 Released by Harlan Stenn * [Bug 663] respect ntpq -c and -p order on command line. * [Bug 1292] more VC6 unsigned __int64 workarounds. diff --git a/include/ntp.h b/include/ntp.h index cb4cdc206..f3e06078a 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -126,7 +126,7 @@ typedef char s_char; #define NTP_MINCLOCK 3 /* min survivors */ #define NTP_MAXCLOCK 10 /* max candidates */ #define NTP_MAXASSOC 50 /* max associations */ -#define MINDISPERSE .005 /* min dispersion increment */ +#define MINDISPERSE .001 /* min distance */ #define MAXDISTANCE 1.5 /* max root distance (select threshold) */ #define CLOCK_SGATE 3. /* popcorn spike gate */ #define HUFFPUFF 900 /* huff-n'-puff sample interval (s) */ diff --git a/libntp/systime.c b/libntp/systime.c index 0dfe3eeed..e45c4d626 100644 --- a/libntp/systime.c +++ b/libntp/systime.c @@ -22,6 +22,9 @@ # include #endif /* HAVE_UTMPX_H */ + +#define FUZZ 500e-6 /* fuzz pivot */ + /* * These routines (get_systime, step_systime, adj_systime) implement an * interface between the system independent NTP clock and the Unix @@ -36,20 +39,16 @@ * with an unbiased random fuzz. * * The sys_tick variable secifies the system clock tick interval in - * seconds and fraction. For systems that can interpolate between timer - * interrupts, the assumed tick interval and resolution is 1 us - * consistent with the timeval format used by the Unix getimeofday() abd - * adjtime() routines. With routines that use the timespec format, the - * resolution is 1 ns. For systems that cannot interpolate, such as - * Reliant and SCO, the resolution is as specified by the sys_tick - * variable, which defaults to 10 ms. The default can be changed by the - * tick configuration command. + * seconds. For systems that can interpolate between timer interrupts, + * the resolution is presumed much less than the time to read the system + * clock, which is the value of sys_tick after the precision has been + * determined. For those systems that cannot interpolate between timer + * interrupts, sys_tick will be much larger in the order of 10 ms, so the + * fuzz should be that value. For Sunses the tick is not interpolated, but + * the system clock is derived from a 2-MHz oscillator, so the resolution + * is 500 ns and sys_tick is 500 ns. */ -#if defined RELIANTUNIX_CLOCK || defined SCO5_CLOCK -double sys_tick = .01; /* 10 ms resolution */ -#else -double sys_tick = 1e-6; /* 1 us resolution */ -#endif +double sys_tick = 0; /* precision (time to read the clock) */ double sys_residual = 0; /* adjustment residue (s) */ #ifndef SIM @@ -77,9 +76,12 @@ get_systime( getclock(TIMEOFDAY, &ts); # endif now->l_i = (int32)ts.tv_sec + JAN_1970; - dtemp = ts.tv_nsec + (ntp_random() * 2. / FRAC) * sys_tick * - 1e6; - dtemp = dtemp / 1e9 + sys_residual; + dtemp = 0; + if (sys_tick > FUZZ) + dtemp = ntp_random() * 2. / FRAC * sys_tick * 1e9; + else if (sys_tick > 0) + dtemp = ntp_random() * 2. / FRAC; + dtemp = (ts.tv_nsec + dtemp) * 1e-9 + sys_residual; if (dtemp >= 1.) { dtemp -= 1.; now->l_i++; @@ -98,9 +100,12 @@ get_systime( */ GETTIMEOFDAY(&tv, NULL); now->l_i = tv.tv_sec + JAN_1970; - dtemp = tv.tv_usec + (ntp_random() * 2. / FRAC) * sys_tick * - 1e6; - dtemp = dtemp / 1e6 + sys_residual; + dtemp = 0; + if (sys_tick > FUZZ) + dtemp = ntp_random() * 2. / FRAC * sys_tick * 1e6; + else if (sys_tick > 0) + dtemp = ntp_random() * 2. / FRAC; + dtemp = (tv.tv_usec + dtemp) * 1e-6 + sys_residual; if (dtemp >= 1.) { dtemp -= 1.; now->l_i++; diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 1dd0c2622..ce7270674 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -25,10 +25,6 @@ #include "ntp_refclock.h" #endif -#if defined(__FreeBSD__) && __FreeBSD__ >= 3 -#include -#endif - /* * This macro defines the authentication state. If x is 1 authentication * is required; othewise it is optional. @@ -78,7 +74,7 @@ double sys_bdelay; /* broadcast client default delay */ int sys_authenticate; /* requre authentication for config */ l_fp sys_authdelay; /* authentication delay */ double sys_offset; /* current local clock offset */ -double sys_mindisp = MINDISPERSE; /* min disp increment (s) */ +double sys_mindisp = MINDISPERSE; /* minimum distance (s) */ double sys_maxdist = MAXDISTANCE; /* selection threshold */ double sys_jitter; /* system jitter */ u_long sys_epoch; /* last clock update time */ @@ -802,9 +798,9 @@ receive( return; /* not enabled */ } if ((peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, - MODE_CLIENT, hisversion, NTP_MINDPOLL, - NTP_MAXDPOLL, FLAG_IBURST | FLAG_PREEMPT, - MDF_UCAST | MDF_ACLNT, 0, skeyid)) == NULL) { + MODE_CLIENT, hisversion, NTP_MINDPOLL, NTP_MAXDPOLL, + FLAG_PREEMPT, MDF_UCAST | MDF_ACLNT, 0, skeyid)) == + NULL) { sys_declined++; return; /* ignore duplicate */ } @@ -812,7 +808,10 @@ receive( /* * We don't need these, but it warms the billboards. */ - peer->ttl = peer2->ttl; + if (peer2->flags & FLAG_IBURST) + peer->flags |= FLAG_IBURST; + peer->minpoll = peer2->minpoll; + peer->maxpoll = peer2->maxpoll; break; /* @@ -920,7 +919,7 @@ receive( /* * If authenticated but cannot mobilize an - * association, send a summetric passive + * association, send a symmetric passive * response without mobilizing an association. * This is for drat broken Windows clients. See * Microsoft KB 875424 for preferred workaround. @@ -1648,14 +1647,6 @@ clock_update( sys_refid = addr2refid(&peer->srcadr); dtemp = sys_jitter + fabs(sys_offset) + peer->disp + clock_phi * (current_time - peer->update); -#ifdef REFCLOCK - if (!(peer->flags & FLAG_REFCLOCK) && sys_rootdisp < - sys_mindisp) - dtemp = sys_mindisp; -#else - if (sys_rootdisp < sys_mindisp) - dtemp = sys_mindisp; -#endif /* REFCLOCK */ sys_rootdisp = dtemp + peer->rootdisp; sys_rootdelay = peer->delay + peer->rootdelay; sys_reftime = peer->dst; @@ -1713,10 +1704,7 @@ clock_update( break; /* - * Clock was slewed. Update the system stratum, leap bits, root - * delay, root dispersion, reference ID and reference time. - * Except for reference clocks, the minimum dispersion increment - * is not less than sys_mindisp. + * Clock was slewed. Handle the leapsecond stuff. */ case 1: @@ -2626,8 +2614,8 @@ clock_select(void) * least one kitten in the litter. */ if (nlist > 0 && nlist >= sys_minsane) { - if (synch[j] < synch[0] + sys_mindisp + - ULOGTOD(sys_poll) * sys_maxhop * clock_phi) + if (synch[j] < synch[0] + ULOGTOD(sys_poll) * + sys_maxhop * clock_phi) typesystem = peer_list[j]; else typesystem = peer_list[0]; @@ -2742,6 +2730,7 @@ root_distance( struct peer *peer /* peer structure pointer */ ) { + double dtemp; /* * Careful squeak here. The value returned must be greater than @@ -2750,9 +2739,12 @@ root_distance( * cannot exceed the sys_maxdist, as this is the cutoff by the * selection algorithm. */ - return ((peer->delay + peer->rootdelay) / 2 + peer->disp + + dtemp = (peer->delay + peer->rootdelay) / 2 + peer->disp + peer->rootdisp + clock_phi * (current_time - peer->update) + - peer->jitter); + peer->jitter; + if (dtemp < sys_mindisp) + dtemp = sys_mindisp; + return (dtemp); } @@ -3469,14 +3461,15 @@ default_get_precision(void) if (++i >= MINLOOPS) break; } + sys_tick = tick; /* * Find the nearest power of two. */ - msyslog(LOG_NOTICE, "proto: precision = %.3f usec", tick * 1e6); + msyslog(LOG_NOTICE, "proto: precision = %.3f usec", tick * 1e6); for (i = 0; tick <= 1; i++) tick *= 2; - if (tick - 1. > 1. - tick / 2) + if (tick - 1 > 1 - tick / 2) i--; return (-i); } @@ -3626,7 +3619,7 @@ proto_config( sys_minclock = (int)dvalue; break; - case PROTO_MINDISP: /* distance increment (mindist) */ + case PROTO_MINDISP: /* minimum distance (mindist) */ sys_mindisp = dvalue; break; diff --git a/ntpd/ntp_timer.c b/ntpd/ntp_timer.c index baa7ec9bb..dd178a557 100644 --- a/ntpd/ntp_timer.c +++ b/ntpd/ntp_timer.c @@ -321,7 +321,7 @@ timer(void) memcpy(&sys_refid, "LOOP", 4); sys_offset = 0; sys_rootdelay = 0; - sys_rootdisp = sys_mindisp; + sys_rootdisp = 0; } /*