From: Harlan Stenn Date: Fri, 13 Apr 2001 04:05:45 +0000 (-0000) Subject: Many files: X-Git-Tag: NTP_4_0_99_M~90 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=8598db78abc0bf15dff562f102cb76140c561b81;p=thirdparty%2Fntp.git Many files: * util/ntp-genkeys.c: sys_minpoll. * ntpd/refclock_atom.c: Comment additions. * ntpd/ntp_proto.c: mode_ntpdate and peer_ntpdate added. (transmit): We want 3, not 2, consecutive polls. hpoll logic cleanup. mode_ntpdate changes. (receive): When setting up a newpeer, use our sys_minpoll, not the peer->ppoll. (clock_update): sys_minpoll changes. Reorder some case 1 code. Don't exit in case 2. (poll_update): hpoll cleanup. (peer_clear): u_rand. Use u_rand to randomize the initial poll. * ntpd/ntp_peer.c (newpeer): Bump peer_ntpdate if we're in mode_ntpdate. * ntpd/ntp_loopfilter.c: Initialize sys_poll and sys_minpoll to NTP_MINDPOLL. (local_clock): Clean up some debug/info messages. (rstclock): Use sys_minpoll. (loop_config): KERNEL_PLL sanity checks. LOOP_MINPOLL support. * ntpd/ntp_crypto.c (crypto_recv): Turn off FLAG_AUTOKEY when we turn off TEST10. * ntpd/ntp_control.c (ctl_getitem): Buffer overflow check. Clean up some loop logic. * ntpd/ntp_config.c: Added "tinker" and "minpoll". Use sys_minpoll now, instead of old manifest constant. (save_resolve): Print keyid using decimal, not hex. * include/ntpd.h: Added peer_ntpdate and sys_minpoll. * include/ntp_config.h (CONF_CLOCK_MINPOLL): Added. * include/ntp.h: keyid cleanup. LOOP_* cleanup. From Dave Mills. bk: 3ad67b19JCvhi6Kp1LQJJExNvnoKWw --- diff --git a/ChangeLog b/ChangeLog index a5f0d8ed2d..5b78668f29 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,35 @@ +2001-04-13 Harlan Stenn + + * util/ntp-genkeys.c: sys_minpoll. + * ntpd/refclock_atom.c: Comment additions. + * ntpd/ntp_proto.c: mode_ntpdate and peer_ntpdate added. + (transmit): We want 3, not 2, consecutive polls. hpoll logic + cleanup. mode_ntpdate changes. + (receive): When setting up a newpeer, use our sys_minpoll, not the + peer->ppoll. + (clock_update): sys_minpoll changes. Reorder some case 1 code. + Don't exit in case 2. + (poll_update): hpoll cleanup. + (peer_clear): u_rand. Use u_rand to randomize the initial poll. + * ntpd/ntp_peer.c (newpeer): Bump peer_ntpdate if we're in + mode_ntpdate. + * ntpd/ntp_loopfilter.c: Initialize sys_poll and sys_minpoll to + NTP_MINDPOLL. + (local_clock): Clean up some debug/info messages. + (rstclock): Use sys_minpoll. + (loop_config): KERNEL_PLL sanity checks. LOOP_MINPOLL support. + * ntpd/ntp_crypto.c (crypto_recv): Turn off FLAG_AUTOKEY when we + turn off TEST10. + * ntpd/ntp_control.c (ctl_getitem): Buffer overflow check. Clean + up some loop logic. + * ntpd/ntp_config.c: Added "tinker" and "minpoll". Use + sys_minpoll now, instead of old manifest constant. + (save_resolve): Print keyid using decimal, not hex. + * include/ntpd.h: Added peer_ntpdate and sys_minpoll. + * include/ntp_config.h (CONF_CLOCK_MINPOLL): Added. + * include/ntp.h: keyid cleanup. LOOP_* cleanup. + From Dave Mills. + 2001-04-03 Harlan Stenn * ntpd/ntp_proto.c (clock_filter): Swell stuff. diff --git a/Makefile.in b/Makefile.in index 549d9c9a89..923b5cd9e3 100644 --- a/Makefile.in +++ b/Makefile.in @@ -94,6 +94,9 @@ MAKE_NTPTIME = @MAKE_NTPTIME@ MAKE_NTP_GENKEYS = @MAKE_NTP_GENKEYS@ MAKE_PARSEKMODULE = @MAKE_PARSEKMODULE@ MAKE_TICKADJ = @MAKE_TICKADJ@ +OPENSSL = @OPENSSL@ +OPENSSL_INC = @OPENSSL_INC@ +OPENSSL_LIB = @OPENSSL_LIB@ PACKAGE = @PACKAGE@ PATH_PERL = @PATH_PERL@ PATH_SH = @PATH_SH@ diff --git a/include/ntp.h b/include/ntp.h index 7fbf65e41a..b2c56a654a 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -267,6 +267,7 @@ struct peer { /* * Variables used by authenticated client */ + keyid_t keyid; /* current key ID */ #ifdef AUTOKEY #define clear_to_zero assoc associd_t assoc; /* peer association ID */ @@ -276,12 +277,7 @@ struct peer { struct value certif; /* certificate */ u_char *keystr; /* host name */ #endif /* PUBKEY */ -#else /* AUTOKEY */ -#define clear_to_zero keyid -#endif /* AUTOKEY */ - keyid_t keyid; /* current key ID */ keyid_t pkeyid; /* previous key ID */ -#ifdef AUTOKEY keyid_t hcookie; /* host cookie */ struct cookie pcookie; /* peer cookie */ struct autokey recauto; /* autokey */ @@ -292,6 +288,8 @@ struct peer { keyid_t *keylist; /* session key ID list */ int keynumber; /* current key number */ struct autokey sndauto; /* autokey */ +#else /* AUTOKEY */ +#define clear_to_zero status #endif /* AUTOKEY */ /* @@ -668,12 +666,11 @@ struct pkt { */ #define LOOP_DRIFTINIT 1 /* set initial frequency offset */ #define LOOP_DRIFTCOMP 2 /* set frequency offset */ -#define LOOP_PPSDELAY 3 /* set pps delay */ -#define LOOP_PPSBAUD 4 /* set pps baud rate */ -#define LOOP_MAX 5 /* set step offset */ -#define LOOP_PANIC 6 /* set panic offseet */ -#define LOOP_PHI 7 /* set dispersion rate */ -#define LOOP_MINSTEP 8 /* set step timeout */ +#define LOOP_MAX 3 /* set step offset */ +#define LOOP_PANIC 4 /* set panic offseet */ +#define LOOP_PHI 5 /* set dispersion rate */ +#define LOOP_MINSTEP 6 /* set step timeout */ +#define LOOP_MINPOLL 7 /* set min poll interval (log2 s) */ /* * Configuration items for the stats printer diff --git a/include/ntp_config.h b/include/ntp_config.h index d6bf707439..94b5a30884 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -131,6 +131,7 @@ #define CONF_CLOCK_PANIC 2 #define CONF_CLOCK_PHI 3 #define CONF_CLOCK_MINSTEP 4 +#define CONF_CLOCK_MINPOLL 5 #ifdef PUBKEY /* diff --git a/include/ntpd.h b/include/ntpd.h index 97dafb2bb9..60f877b72a 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -286,11 +286,13 @@ extern int cal_enable; /* refclock calibrate enable */ extern int allow_step; /* allow step correction */ extern int allow_panic; /* allow panic correction */ extern int mode_ntpdate; /* exit on first clock set */ +extern int peer_ntpdate; /* count of ntpdate peers */ /* * Clock state machine variables */ -extern u_char sys_poll; /* log2 of system poll interval */ +extern u_char sys_poll; /* system poll interval (log2 s) */ +extern u_char sys_minpoll; /* min system poll interval (log2 s) */ extern int state; /* clock discipline state */ extern int tc_counter; /* poll-adjust counter */ extern u_long last_time; /* time of last clock update (s) */ diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index 4076d07355..91a6475881 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -134,6 +134,7 @@ static struct keyword keywords[] = { { "setvar", CONFIG_SETVAR }, { "statistics", CONFIG_STATISTICS }, { "statsdir", CONFIG_STATSDIR }, + { "tinker", CONFIG_TINKER }, { "trap", CONFIG_TRAP }, { "trustedkey", CONFIG_TRUSTEDKEY }, { "", CONFIG_UNKNOWN } @@ -263,6 +264,7 @@ static struct keyword tinker_keywords[] = { { "panic", CONF_CLOCK_PANIC }, { "dispersion", CONF_CLOCK_PHI }, { "stepout", CONF_CLOCK_MINSTEP }, + { "minpoll", CONF_CLOCK_MINPOLL }, { "", CONFIG_UNKNOWN } }; @@ -648,7 +650,7 @@ getconfig( } peerversion = NTP_VERSION; - minpoll = NTP_MINDPOLL; + minpoll = sys_minpoll; maxpoll = NTP_MAXDPOLL; peerkey = 0; peerkeystr = "*"; @@ -692,8 +694,8 @@ getconfig( break; } minpoll = atoi(tokens[++i]); - if (minpoll < NTP_MINPOLL) - minpoll = NTP_MINPOLL; + if (minpoll < sys_minpoll) + minpoll = sys_minpoll; break; case CONF_MOD_MAXPOLL: @@ -948,6 +950,10 @@ getconfig( case CONF_CLOCK_MINSTEP: loop_config(LOOP_MINSTEP, ftemp); break; + + case CONF_CLOCK_MINPOLL: + loop_config(LOOP_MINPOLL, ftemp); + break; } } break; @@ -2037,7 +2043,7 @@ save_resolve( } #endif - (void)fprintf(res_fp, "%s %d %d %d %d %d %d %08x %s\n", name, + (void)fprintf(res_fp, "%s %d %d %d %d %d %d %d %s\n", name, mode, version, minpoll, maxpoll, flags, ttl, keyid, keystr); #ifdef DEBUG if (debug > 1) diff --git a/ntpd/ntp_control.c b/ntpd/ntp_control.c index 57bca2eb2e..38b66baac9 100644 --- a/ntpd/ntp_control.c +++ b/ntpd/ntp_control.c @@ -1859,17 +1859,21 @@ ctl_getitem( if (*cp == '=') { cp++; tp = buf; - while (cp < reqend && - isspace((int)*cp)) + while (cp < reqend && isspace((int)*cp)) cp++; - while (cp < reqend && *cp != - ',') + while (cp < reqend && *cp != ',') { *tp++ = *cp++; + if (tp >= buf + sizeof(buf)) + return (0); + } if (cp < reqend) cp++; - *tp = '\0'; - while (isspace((int)(*(tp-1)))) - *(--tp) = '\0'; + *tp-- = '\0'; + while (tp > buf) { + *tp-- = '\0'; + if (!isspace((int)(*tp))) + break; + } reqpt = cp; *data = buf; return (v); diff --git a/ntpd/ntp_crypto.c b/ntpd/ntp_crypto.c index 6ed8db55ee..a01869de59 100644 --- a/ntpd/ntp_crypto.c +++ b/ntpd/ntp_crypto.c @@ -881,6 +881,7 @@ crypto_recv( break; } peer->flash &= ~TEST10; + peer->flags &= ~FLAG_AUTOKEY; peer->assoc = ntohl(pkt[i + 1]); peer->pcookie.tstamp = tstamp; if (temp != peer->pcookie.key) { diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index a3e0b9d884..ca114719d0 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -50,7 +50,26 @@ /* * Clock discipline state machine. This is used to control the * synchronization behavior during initialization and following a - * timewarp. + * timewarp. + * + * State < max > max Comments + * ==================================================== + * NSET FREQ FREQ no ntp.drift + * + * FSET TSET if (allow) TSET, ntp.drift + * else FREQ + * + * TSET SYNC FREQ time set + * + * FREQ SYNC if (mu < 900) FREQ calculate frequency + * else if (allow) TSET + * else FREQ + * + * SYNC SYNC if (mu < 900) SYNC normal state + * else SPIK + * + * SPIK SYNC if (allow) TSET spike detector + * else FREQ */ #define S_NSET 0 /* clock never set */ #define S_FSET 1 /* frequency set from the drift file */ @@ -124,7 +143,8 @@ int mode_ntpdate = FALSE; /* exit on first clock set */ /* * Clock state machine variables */ -u_char sys_poll; /* log2 of system poll interval */ +u_char sys_minpoll = NTP_MINDPOLL; /* min sys poll interval (log2 s) */ +u_char sys_poll = NTP_MINDPOLL; /* system poll interval (log2 s) */ int state; /* clock discipline state */ int tc_counter; /* poll-adjust counter */ u_long last_time; /* time of last clock update (s) */ @@ -210,13 +230,13 @@ local_clock( NLOG(NLOG_SYNCEVENT|NLOG_SYSEVENT) msyslog(LOG_NOTICE, "time reset %.6f s", fp_offset); - printf("ntpd: time reset %.6f s\n", fp_offset); + printf("ntpd: time reset %.6fs\n", fp_offset); } else { adj_systime(fp_offset); NLOG(NLOG_SYNCEVENT|NLOG_SYSEVENT) msyslog(LOG_NOTICE, "time slew %.6f s", fp_offset); - printf("ntpd: time slew %.6f s\n", fp_offset); + printf("ntpd: time slew %.6fs\n", fp_offset); } record_loop_stats(); exit(0); @@ -255,6 +275,9 @@ local_clock( retval = 0; clock_frequency = flladj = plladj = 0; mu = current_time - last_time; + +printf("yyy %f %f %d\n", fabs(fp_offset), mu, state); + if (fabs(fp_offset) > clock_max) { switch (state) { @@ -283,8 +306,8 @@ local_clock( /* * In S_FREQ state we ignore outlyers. At the first - * outlyer after 900 s, compute the * apparent phase - * and frequency correction. + * outlyer after 900 s, compute the apparent phase and + * frequency correction. */ case S_FREQ: if (mu < clock_minstep) @@ -326,6 +349,9 @@ local_clock( break; } } else { + +printf("xxx %f %f %d\n", mu, clock_minstep, state); + switch (state) { /* @@ -341,7 +367,7 @@ local_clock( /* * In S_FREQ state we ignore updates until 900 s. After - * that, correct the phase and frequency * and switch to + * that, correct the phase and frequency and switch to * S_SYNC state. */ case S_FREQ: @@ -697,7 +723,7 @@ rstclock( * measurements. */ case S_FREQ: - sys_poll = NTP_MINDPOLL; + sys_poll = sys_minpoll; allan_xpt = CLOCK_ALLAN; last_time = current_time; break; @@ -706,7 +732,7 @@ rstclock( * Synchronized mode. Discipline the poll interval. */ case S_SYNC: - sys_poll = NTP_MINDPOLL; + sys_poll = sys_minpoll; allan_xpt = CLOCK_ALLAN; tc_counter = 0; break; @@ -723,7 +749,7 @@ rstclock( * the time reference for future frequency updates. */ default: - sys_poll = NTP_MINDPOLL; + sys_poll = sys_minpoll; allan_xpt = CLOCK_ALLAN; last_time = current_time; last_offset = clock_offset = 0; @@ -819,12 +845,22 @@ loop_config( drift_comp = -NTP_MAXFREQ; #ifdef KERNEL_PLL + /* + * Sanity check. If the kernel is enabled, load the + * frequency and light up the loop. If not, set the + * kernel frequency to zero and leave the loop dark. In + * either case set the time to zero to cancel any + * previous nonsense. + */ if (pll_control) { memset((char *)&ntv, 0, sizeof ntv); - ntv.modes = MOD_FREQUENCY; - if (kern_enable) + ntv.modes = MOD_OFFSET | MOD_FREQUENCY; + if (kern_enable) { + ntv.modes |= MOD_STATUS; + ntv.status = STA_PLL; ntv.freq = (int32)(drift_comp * 65536e6); + } (void)ntp_adjtime(&ntv); } break; @@ -845,6 +881,11 @@ loop_config( case LOOP_MINSTEP: clock_minstep = freq; break; + + case LOOP_MINPOLL: + if (freq < NTP_MINPOLL) + freq = NTP_MINPOLL; + sys_minpoll = (u_char)freq; } } diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index d34f713730..359c4ad65b 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -547,6 +547,8 @@ newpeer( peer->keyid = key; peer->precision = sys_precision; peer_clear(peer); + if (mode_ntpdate) + peer_ntpdate++; /* * Assign an association ID and increment the system variable. diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 8a4377ac0f..718a35ea78 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -54,6 +54,8 @@ static double sys_syserr; /* system error (squares) */ keyid_t sys_private; /* private value for session seed */ int sys_manycastserver; /* respond to manycast client pkts */ u_int sys_survivors; /* truest of the truechimers */ +int mode_ntpdate; /* simulate ntpdate */ +int peer_ntpdate; /* active peers in ntpdate mode */ #ifdef AUTOKEY char *sys_hostname; /* gethostname() name */ #endif /* AUTOKEY */ @@ -184,7 +186,7 @@ transmit( /* * Here the peer is reachable. If it has not - * been heard for two consecutive polls, stuff + * been heard for three consecutive polls, stuff * the clock filter. Next, determine the poll * interval. If the peer is a synchronization * candidate, use the system poll interval. If @@ -194,17 +196,16 @@ transmit( * minimum. This is to quickly recover the time * variables when a noisy peer shows life. */ - if (!(peer->reach & 0x03)) { + if (!(peer->reach & 0x07)) { clock_filter(peer, 0., 0., MAXDISPERSE); clock_select(); } - if (peer->unreach == NTP_UNREACH && - ((peer->stratum > 1 && peer->refid == + if ((peer->stratum > 1 && peer->refid == peer->dstadr->sin.sin_addr.s_addr) || - peer->stratum >= STRATUM_UNSPEC || - (root_distance(peer) >= MAXDISTANCE + 2 * - clock_phi * ULOGTOD(sys_poll)))) + peer->stratum >= STRATUM_UNSPEC) hpoll++; + else + hpoll = sys_poll; if (peer->flags & FLAG_BURST) peer->burst = NTP_SHIFT; } @@ -226,7 +227,16 @@ transmit( } poll_update(peer, hpoll); clock_select(); + + /* + * If ntpdate mode and the clock has not been + * set and all peers have completed the burst, + * we declare a successful failure. + */ if (mode_ntpdate) { + peer_ntpdate--; + if (peer_ntpdate > 0) + return; NLOG(NLOG_SYNCEVENT|NLOG_SYSEVENT) msyslog(LOG_NOTICE, "no reply; clock not set"); @@ -619,7 +629,7 @@ receive( peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_CLIENT, PKT_VERSION(pkt->li_vn_mode), - pkt->ppoll, NTP_MAXDPOLL, FLAG_IBURST | + sys_minpoll, NTP_MAXDPOLL, FLAG_IBURST | (peer2->flags & (FLAG_AUTHENABLE | FLAG_SKEY)), MDF_UCAST, 0, skeyid); if (peer == NULL) @@ -640,7 +650,7 @@ receive( } peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_PASSIVE, PKT_VERSION(pkt->li_vn_mode), - pkt->ppoll, NTP_MAXDPOLL, sys_authenticate ? + sys_minpoll, NTP_MAXDPOLL, sys_authenticate ? FLAG_AUTHENABLE : 0, MDF_UCAST, 0, skeyid); if (peer == NULL) return; @@ -661,7 +671,7 @@ receive( peer = newpeer(&rbufp->recv_srcadr, rbufp->dstadr, MODE_CLIENT, PKT_VERSION(pkt->li_vn_mode), - pkt->ppoll, NTP_MAXDPOLL, FLAG_MCAST | + sys_minpoll, NTP_MAXDPOLL, FLAG_MCAST | FLAG_IBURST | (sys_authenticate ? FLAG_AUTHENABLE : 0), MDF_BCLNT, 0, skeyid); if (peer == NULL) @@ -1055,21 +1065,14 @@ clock_update(void) */ case 1: clear_all(); - NLOG(NLOG_SYNCSTATUS) - msyslog(LOG_INFO, "synchronisation lost"); sys_peer = NULL; - sys_poll = NTP_MINDPOLL; sys_stratum = STRATUM_UNSPEC; + sys_poll = sys_minpoll; + NLOG(NLOG_SYNCSTATUS) + msyslog(LOG_INFO, "synchronisation lost"); report_event(EVNT_CLOCKRESET, (struct peer *)0); break; - /* - * Clock was set; emulating ntpdate - */ - case 2: - exit(0); - /*NOTREACHED*/; - /* * Update the system stratum, leap bits, root delay, root * dispersion, reference ID and reference time. We also update @@ -1106,39 +1109,27 @@ poll_update( int hpoll ) { - int xpoll; #ifdef AUTOKEY int oldpoll; #endif /* AUTOKEY */ -#ifdef AUTOKEY - oldpoll = peer->kpoll; -#endif /* AUTOKEY */ - /* * A little foxtrot to determine what controls the poll - * interval. If the peer is reachable, but but the last four - * polls have not been answered, use the minimum. If declared + * interval. If the peer is reachable, but the last four polls + * have not been answered, use the minimum. If declared * truechimer, use the system poll interval. This allows each * association to ramp up the poll interval for useless sources * and to clamp it to the minimum when first starting up. */ - xpoll = hpoll; - if (peer->reach) { - if (!(peer->reach & 0x0f)) - xpoll = peer->minpoll; - else if (peer->flags & FLAG_SYSPEER) - xpoll = sys_poll; -#ifdef PUBKEY - } else if (peer->crypto && !(peer->flags & FLAG_AUTOKEY)) { - xpoll = peer->minpoll; -#endif /* PUBKEY */ - } - if (xpoll > peer->maxpoll) - xpoll = peer->maxpoll; - else if (xpoll < peer->minpoll) - xpoll = peer->minpoll; - peer->hpoll = xpoll; +#ifdef AUTOKEY + oldpoll = peer->kpoll; +#endif /* AUTOKEY */ + if (hpoll > peer->maxpoll) + peer->hpoll = peer->maxpoll; + else if (hpoll < peer->minpoll) + peer->hpoll = peer->minpoll; + else + peer->hpoll = hpoll; /* * Bit of adventure here. If during a burst and not timeout, @@ -1158,7 +1149,7 @@ poll_update( if (peer->burst > 0) { if (peer->nextdate != current_time) return; - if (peer->flags & FLAG_REFCLOCK) + else if (peer->flags & FLAG_REFCLOCK) peer->nextdate++; else if (peer->reach & 0x1) peer->nextdate += RANDPOLL(BURST_INTERVAL2); @@ -1206,6 +1197,7 @@ peer_clear( ) { register int i; + u_long u_rand; /* * If cryptographic credentials have been acquired, toss them to @@ -1241,11 +1233,11 @@ peer_clear( * clock_select(), since the perp has already been voted off * the island at this point. */ - peer->flags &= ~(FLAG_AUTOKEY | FLAG_ASSOC); if (peer->cast_flags & MDF_BCLNT) { peer->flags |= FLAG_MCAST; peer->hmode = MODE_CLIENT; } + peer->flags &= ~(FLAG_AUTOKEY | FLAG_ASSOC); peer->estbdelay = sys_bdelay; peer->hpoll = peer->kpoll = peer->minpoll; peer->ppoll = peer->maxpoll; @@ -1259,9 +1251,14 @@ peer_clear( peer->filter_disp[i] = MAXDISPERSE; peer->filter_epoch[i] = current_time; } + + /* + * Randomize the first poll over 1-16s to avoid bunching. + */ peer->update = peer->outdate = current_time; - peer->nextdate = peer->outdate + (RANDOM & (1 << - BURST_INTERVAL1)); + u_rand = RANDOM; + peer->nextdate = current_time + (u_rand & ((1 << + BURST_INTERVAL1) - 1)) + 1; } @@ -1277,35 +1274,32 @@ clock_filter( double sample_disp ) { - register int i, j, k, n, imin; + register int i, j, k, m, n; register u_char *ord; - double distance[NTP_SHIFT]; - double off, dly, dsp, jit, dmin, dtemp, etemp; + double off, dly, dsp, jit, dtemp, etemp; /* * Shift the new sample into the register and discard the oldest * one. The new offset and delay come directly from the caller. - * The dispersion from the caller is increased by the sum of the - * peer precision and the system precision. + * The caller delay can sometimes swing negative due to + * frequency skew, so it is clamped non-negative. The dispersion + * from the caller is increased by the sum of the peer precision + * and the system precision. */ - dsp = LOGTOD(peer->precision) + LOGTOD(sys_precision) + - sample_disp; + dsp = min(LOGTOD(peer->precision) + LOGTOD(sys_precision) + + sample_disp, MAXDISPERSE); j = peer->filter_nextpt; peer->filter_offset[j] = sample_offset; peer->filter_delay[j] = max(0, sample_delay); - peer->filter_disp[j] = min(dsp, MAXDISPERSE); + peer->filter_disp[j] = dsp; peer->filter_epoch[j] = current_time; j++; j %=NTP_SHIFT; peer->filter_nextpt = j; /* - * Update dispersions and calculate distances. The distance for - * each sample is equal to the sample dispersion plus one-half - * the sample delay. Also initialize the sort index vector. + * Update dispersions since the last update. */ dtemp = clock_phi * (current_time - peer->update); - dmin = 1e9; - imin = 0; peer->update = current_time; ord = peer->filter_order; for (i = 0; i < NTP_SHIFT; i++) { @@ -1314,21 +1308,15 @@ clock_filter( if (peer->filter_disp[j] > MAXDISPERSE) peer->filter_disp[j] = MAXDISPERSE; } - if (peer->filter_delay[j] < dmin) { - dmin = peer->filter_delay[j]; - imin = j; - } - distance[i] = peer->filter_delay[j] / 2 + - peer->filter_disp[j]; ord[i] = j; j++; j %= NTP_SHIFT; } /* - * Sort the samples in the register by distance. The winning - * sample will be in ord[0]. Sort the samples only if they - * are younger than the Allen intercept; however, keep a minimum - * of two samples so that we can compute jitter. + * Sort the samples in the register by delay. The winning sample + * will be in ord[0]. Sort the samples only if they are younger + * than the Allen intercept; however, keep a minimum of two + * samples so that we can compute jitter. */ dtemp = min(allan_xpt, NTP_SHIFT * ULOGTOD(sys_poll)); for (n = 0; n < NTP_SHIFT; n++) { @@ -1336,12 +1324,11 @@ clock_filter( dtemp) break; for (j = 0; j < n; j++) { - if (distance[j] > distance[n]) { - etemp = distance[j]; + if (peer->filter_delay[ord[j]] > + peer->filter_delay[ord[n]] || + peer->filter_disp[ord[j]] >= MAXDISPERSE) { k = ord[j]; - distance[j] = distance[n]; ord[j] = ord[n]; - distance[n] = etemp; ord[n] = k; } } @@ -1349,56 +1336,71 @@ clock_filter( /* * Compute the offset, delay, dispersion and jitter squares - * weighted by the reciprocal of distance and normalized. The - * dispersion is weighted exponentially by NTP_FWEIGHT (0.5) so - * to normalize close to 1.0. If no acceptable samples remain in + * weighted by the sample metric and normalized. The sample + * metric is the distance from the limb line with slope 0.5 + * centered on the minimum delay sample offset. The dispersion + * is weighted exponentially by NTP_FWEIGHT (0.5) so to + * normalize close to 1.0. If no acceptable samples remain in * the shift register, quietly tiptoe home leaving only the * dispersion. */ off = dly = jit = dtemp = 0; peer->disp = 0; + k = ord[0]; + m = 0; for (i = NTP_SHIFT - 1; i >= 0; i--) { + double xtemp, ytemp; + j = ord[i]; peer->disp = NTP_FWEIGHT * (peer->disp + peer->filter_disp[j]); - if (i >= n || distance[i] >= MAXDISTANCE) + etemp = peer->filter_delay[j] / 2. + + peer->filter_disp[j]; + if (i >= n || etemp >= MAXDISTANCE) continue; - etemp = 2 * fabs(peer->filter_offset[j] - - peer->filter_offset[imin]); - etemp /= max(peer->filter_delay[j] - dmin, dsp); - etemp = max(0, 1. - etemp); + m++; + xtemp = 2 * fabs(peer->filter_offset[j] - + peer->filter_offset[k]); + ytemp = max(peer->filter_delay[j] - + peer->filter_delay[k], dsp); + etemp = max(dsp, 1. - xtemp / ytemp); dtemp += etemp; off += peer->filter_offset[j] * etemp; dly += peer->filter_delay[j] * etemp; jit += DIFF(peer->filter_offset[j], - peer->filter_offset[ord[0]]); + peer->filter_offset[k]); +#ifdef DEBUG + if (debug > 1) + printf("clock_filter: %d %.6f %.6f %.6f\n", + j, xtemp, ytemp, etemp); +#endif } /* * If no acceptable samples remain in the shift register, * quietly tiptoe home leaving only the dispersion. Otherwise * normalize the offset, delay and jitter averages. Note the - * jitter must be at least the clock precision. + * jitter must not be less than the system precision. */ - if (n == 0) + if (m == 0) return; peer->epoch = current_time; etemp = peer->offset; peer->offset = off / dtemp; peer->delay = dly / dtemp; - if (n > 1) - jit /= n - 1; + if (m > 1) + jit /= m - 1; peer->jitter = max(jit, SQUARE(LOGTOD(sys_precision))); /* * A new sample is useful only if it is younger than the last * one used. */ - if (peer->filter_epoch[ord[0]] > peer->epoch) { + if (peer->filter_epoch[k] > peer->epoch) { #ifdef DEBUG if (debug) printf("clock_filter: discard %lu\n", - peer->filter_epoch[ord[0]] - peer->epoch); + peer->filter_epoch[k] - peer->epoch); #endif return; } @@ -1409,13 +1411,13 @@ clock_filter( * the last update is less than twice the system poll interval, * consider the update a popcorn spike and ignore it. */ - if (fabs(peer->offset - etemp) > SQRT(peer->jitter) * - CLOCK_SGATE && peer->filter_epoch[ord[0]] - peer->epoch < + if (m > 1 && fabs(peer->offset - etemp) > SQRT(peer->jitter) * + CLOCK_SGATE && peer->filter_epoch[k] - peer->epoch < (1 << (sys_poll + 1))) { #ifdef DEBUG if (debug) - printf("clock_filter: popcorn spike %.6f jitter %.6f\n", - peer->offset, SQRT(peer->jitter)); + printf("clock_filter: samples %d popcorn spike %.6f jitter %.6f\n", + m, peer->offset, SQRT(peer->jitter)); #endif return; } @@ -1424,7 +1426,7 @@ clock_filter( * The mitigated sample statistics are saved for later * processing, but can be processed only once. */ - peer->epoch = peer->filter_epoch[ord[0]]; + peer->epoch = peer->filter_epoch[k]; peer->pollsw = TRUE; #ifdef DEBUG if (debug) @@ -1643,12 +1645,12 @@ clock_select(void) nlist = 1; } else { if (osys_peer != NULL) { - sys_poll = NTP_MINDPOLL; - report_event(EVNT_PEERSTCHG, - (struct peer *)0); + sys_poll = sys_minpoll; NLOG(NLOG_SYNCSTATUS) - msyslog(LOG_INFO, + msyslog(LOG_INFO, "synchronisation lost"); + report_event(EVNT_PEERSTCHG, + (struct peer *)0); } sys_survivors = 0; #ifdef AUTOKEY diff --git a/ntpd/refclock_atom.c b/ntpd/refclock_atom.c index 9dd6765167..ed79536edc 100644 --- a/ntpd/refclock_atom.c +++ b/ntpd/refclock_atom.c @@ -40,7 +40,7 @@ * pin 8 (DCD) of a serial port. This requires a level converter and * may require a one-shot flipflop to lengthen the pulse. The other is * to connect the PPS signal directly to pin 10 (ACK) of a PC paralell - * port. + * port. These methods are architecture dependent. * * Both methods require a modified device driver and kernel interface * compatible with the Pulse-per-Second API for Unix-like Operating @@ -59,11 +59,17 @@ * device(s) must be placed before the PPS driver(s) in the * configuration file. * + * This driver normally uses the PLL/FLL clock discipline implemented in + * the ntpd code. If kernel support is available, the kernel PLL/FLL + * clock discipline is used instead. The default configuration is not to + * use the kernel PPS discipline, if present. The kernel PPS discipline + * can be enabled using the pps command. + * * Fudge Factors * * There are no special fudge factors other than the generic. The fudge * time1 parameter can be used to compensate for miscellaneous device - * driver and OS delays. + * driver and OS delays. */ /* * Interface definitions @@ -188,7 +194,7 @@ atom_start( "refclock_atom: time_pps_create failed: %m"); return (0); } - return(atom_ppsapi(peer, pps_assert, pps_hardpps)); + return (atom_ppsapi(peer, pps_assert, pps_hardpps)); #else /* HAVE_PPSAPI */ return (1); #endif /* HAVE_PPSAPI */ @@ -394,7 +400,7 @@ pps_sample( peer = pps_peer; if (peer == 0) /* nobody home */ - return 1; + return (1); pp = peer->procptr; /* diff --git a/util/ntp-genkeys.c b/util/ntp-genkeys.c index d7e44c4360..d0b0f8a1be 100644 --- a/util/ntp-genkeys.c +++ b/util/ntp-genkeys.c @@ -176,6 +176,7 @@ u_long client_limit_period; l_fp sys_revoketime; u_long sys_revoke; /* keys revoke timeout */ volatile int debug = 0; /* debugging flag */ +u_char sys_minpoll; /* min poll interval (log2 s) */ struct peer * peer_config(