From: Dave Hart Date: Sun, 15 May 2011 19:19:24 +0000 (+0000) Subject: [Bug 1554] peer may stay selected as system peer after becoming X-Git-Tag: NTP_4_2_6P4_BETA1~1 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=edafb39c24a5fcefffc2dae0cf85c48cefde249a;p=thirdparty%2Fntp.git [Bug 1554] peer may stay selected as system peer after becoming unreachable. [Bug 1921] LOCAL, ACTS drivers with "prefer" excluded from initial candidate list. [Bug 1923] orphan parent favored over LOCAL, ACTS drivers. [Bug 1924] Billboard tally codes sometimes do not match operation, variables. Enable tickadj-like taming of wildly off-spec Windows clock using NTPD_TICKADJ_PPM env. var. specifying baseline slew. bk: 4dd0273cnTABBtICQyKYf3V6wGNNbw --- diff --git a/ChangeLog b/ChangeLog index 17264f8a5..360c13d5f 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,14 @@ --- +* [Bug 1554] peer may stay selected as system peer after becoming + unreachable. +* [Bug 1921] LOCAL, ACTS drivers with "prefer" excluded from initial + candidate list. +* [Bug 1923] orphan parent favored over LOCAL, ACTS drivers. +* [Bug 1924] Billboard tally codes sometimes do not match operation, + variables. +* Enable tickadj-like taming of wildly off-spec Windows clock using + NTPD_TICKADJ_PPM env. var. specifying baseline slew. * Upgrade to AutoGen 5.11.9 (and require it). * Upgrade to libopts 35.0.10 from AutoGen 5.11.9pre8. diff --git a/include/ntp.h b/include/ntp.h index 732dff352..b719803e4 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -334,6 +334,7 @@ struct peer { * Ephemeral state variables */ u_char status; /* peer status */ + u_char new_status; /* under-construction status */ u_char reach; /* reachability register */ int flash; /* protocol error test tally bits */ u_long epoch; /* reference epoch */ @@ -441,17 +442,16 @@ struct peer { * Values for peer.flags */ #define FLAG_CONFIG 0x0001 /* association was configured */ -#define FLAG_PREEMPT 0x0002 /* preemptable association */ +#define FLAG_PREEMPT 0x0002 /* preemptable association */ #define FLAG_AUTHENTIC 0x0004 /* last message was authentic */ #define FLAG_REFCLOCK 0x0008 /* this is actually a reference clock */ -#define FLAG_SYSPEER 0x0010 /* system peer */ -#define FLAG_PREFER 0x0020 /* prefer peer */ -#define FLAG_BURST 0x0040 /* burst mode */ -#define FLAG_PPS 0x0080 /* steered by PPS */ -#define FLAG_IBURST 0x0100 /* initial burst mode */ -#define FLAG_NOSELECT 0x0200 /* never select */ -#define FLAG_TRUE 0x0400 /* force truechimer */ -#define FLAG_SKEY 0x0800 /* autokey authentication */ +#define FLAG_PREFER 0x0020 /* prefer peer */ +#define FLAG_BURST 0x0040 /* burst mode */ +#define FLAG_PPS 0x0080 /* steered by PPS */ +#define FLAG_IBURST 0x0100 /* initial burst mode */ +#define FLAG_NOSELECT 0x0200 /* never select */ +#define FLAG_TRUE 0x0400 /* force truechimer */ +#define FLAG_SKEY 0x0800 /* autokey authentication */ #define FLAG_XLEAVE 0x1000 /* interleaved protocol */ #define FLAG_XB 0x2000 /* interleaved broadcast */ #define FLAG_XBOGUS 0x4000 /* interleaved bogus packet */ diff --git a/libntp/mktime.c b/libntp/mktime.c index 91be60015..381cc4f6d 100644 --- a/libntp/mktime.c +++ b/libntp/mktime.c @@ -226,9 +226,9 @@ time2( t = (t < 0) ? 0 : ((time_t) 1 << bits); for ( ; ; ) { if (usezn) - mytm = *localtime(&t); + mytm = *localtime(&t); else - mytm = *gmtime(&t); + mytm = *gmtime(&t); dir = tmcomp(&mytm, &yourtm); if (dir != 0) { if (bits-- < 0) diff --git a/ntpd/ntp_loopfilter.c b/ntpd/ntp_loopfilter.c index 1846b552e..3eb09e100 100644 --- a/ntpd/ntp_loopfilter.c +++ b/ntpd/ntp_loopfilter.c @@ -323,7 +323,7 @@ local_clock( switch (state) { /* - * In SYNC state we ignore the first outlyer amd switch + * In SYNC state we ignore the first outlyer and switch * to SPIK state. */ case EVNT_SYNC: diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 3bea82159..9651fc050 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -77,7 +77,7 @@ double sys_offset; /* current local clock offset */ 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 */ +u_long sys_epoch; /* last clock update time */ static double sys_clockhop; /* clockhop threshold */ int leap_tai; /* TAI at next next leap */ u_long leap_sec; /* next scheduled leap from file */ @@ -2016,7 +2016,7 @@ clock_filter( /* * A sample consists of the offset, delay, dispersion and epoch * of arrival. The offset and delay are determined by the on- - * wire protcol. The dispersion grows from the last outbound + * wire protocol. The dispersion grows from the last outbound * packet to the arrival of this one increased by the sum of the * peer precision and the system precision as required by the * error budget. First, shift the new arrival into the shift @@ -2120,8 +2120,10 @@ clock_filter( * save the offset, delay and jitter. Note the jitter must not * be less than the precision. */ - if (m == 0) + if (m == 0) { + clock_select(); return; + } etemp = fabs(peer->offset - peer->filter_offset[k]); peer->offset = peer->filter_offset[k]; @@ -2267,8 +2269,7 @@ clock_select(void) for (n = 0; n < NTP_HASH_SIZE; n++) { for (peer = peer_hash[n]; peer != NULL; peer = peer->next) { - peer->flags &= ~FLAG_SYSPEER; - peer->status = CTL_PST_SEL_REJECT; + peer->new_status = CTL_PST_SEL_REJECT; /* * Leave the island immediately if the peer is @@ -2297,18 +2298,18 @@ clock_select(void) * The following are special cases. We deal * with them later. */ - switch (peer->refclktype) { - case REFCLK_LOCALCLOCK: - if (typelocal == NULL && - !(peer->flags & FLAG_PREFER)) - typelocal = peer; - continue; - - case REFCLK_ACTS: - if (typeacts == NULL && - !(peer->flags & FLAG_PREFER)) - typeacts = peer; - continue; + if (!(peer->flags & FLAG_PREFER)) { + switch (peer->refclktype) { + case REFCLK_LOCALCLOCK: + if (typelocal == NULL) + typelocal = peer; + continue; + + case REFCLK_ACTS: + if (typeacts == NULL) + typeacts = peer; + continue; + } } #endif /* REFCLOCK */ @@ -2317,7 +2318,7 @@ clock_select(void) * island, but does not yet have the immunity * idol. */ - peer->status = CTL_PST_SEL_SANE; + peer->new_status = CTL_PST_SEL_SANE; peer_list[nlist++] = peer; /* @@ -2386,7 +2387,7 @@ clock_select(void) * * Here, nlist is the number of candidates and allow is the * number of falsetickers. Upon exit, the truechimers are the - * susvivors with offsets not less than low and not greater than + * survivors with offsets not less than low and not greater than * high. There may be none of them. */ low = 1e9; @@ -2454,7 +2455,7 @@ clock_select(void) #ifdef REFCLOCK /* - * Elegible PPS peers must survive the intersection + * Eligible PPS peers must survive the intersection * algorithm. Use the first one found, but don't * include any of them in the cluster population. */ @@ -2508,7 +2509,7 @@ clock_select(void) } else if (typelocal != NULL) { peer_list[0] = typelocal; nlist = 1; - } + } else #endif /* REFCLOCK */ if (typeorphan != NULL) { peer_list[0] = typeorphan; @@ -2520,7 +2521,7 @@ clock_select(void) * Mark the candidates at this point as truechimers. */ for (i = 0; i < nlist; i++) { - peer_list[i]->status = CTL_PST_SEL_SELCAND; + peer_list[i]->new_status = CTL_PST_SEL_SELCAND; #ifdef DEBUG if (debug > 1) printf("select: survivor %s %f\n", @@ -2574,7 +2575,7 @@ clock_select(void) ntoa(&peer_list[k]->srcadr), g, d); #endif if (nlist > sys_maxclock) - peer_list[k]->status = CTL_PST_SEL_EXCESS; + peer_list[k]->new_status = CTL_PST_SEL_EXCESS; for (j = k + 1; j < nlist; j++) { peer_list[j - 1] = peer_list[j]; synch[j - 1] = synch[j]; @@ -2598,7 +2599,7 @@ clock_select(void) for (i = 0; i < nlist; i++) { peer = peer_list[i]; peer->unreach = 0; - peer->status = CTL_PST_SEL_SYNCCAND; + peer->new_status = CTL_PST_SEL_SYNCCAND; sys_survivors++; if (peer->leap == LEAP_ADDSECOND) { if (peer->flags & FLAG_REFCLOCK) @@ -2651,14 +2652,14 @@ clock_select(void) */ if (typesystem != NULL) { if (sys_prefer == NULL) { - typesystem->status = CTL_PST_SEL_SYSPEER; + typesystem->new_status = CTL_PST_SEL_SYSPEER; clock_combine(peer_list, sys_survivors); sys_jitter = SQRT(SQUARE(typesystem->jitter) + SQUARE(sys_jitter) + SQUARE(seljitter)); } else { typesystem = sys_prefer; sys_clockhop = 0; - typesystem->status = CTL_PST_SEL_SYSPEER; + typesystem->new_status = CTL_PST_SEL_SYSPEER; sys_offset = typesystem->offset; sys_jitter = typesystem->jitter; } @@ -2682,7 +2683,7 @@ clock_select(void) NULL || (typesystem == NULL && sys_minsane == 0))))) { typesystem = typepps; sys_clockhop = 0; - typesystem->status = CTL_PST_SEL_PPS; + typesystem->new_status = CTL_PST_SEL_PPS; sys_offset = typesystem->offset; sys_jitter = typesystem->jitter; #ifdef DEBUG @@ -2702,6 +2703,10 @@ clock_select(void) if (osys_peer != NULL) report_event(EVNT_NOPEER, NULL, NULL); sys_peer = NULL; + for (n = 0; n < NTP_HASH_SIZE; n++) + for (peer = peer_hash[n]; peer != NULL; peer = + peer->next) + peer->status = peer->new_status; return; } @@ -2715,9 +2720,12 @@ clock_select(void) /* * We have found the alpha male. Wind the clock. */ - if (osys_peer != typesystem) + if (osys_peer != typesystem) report_event(PEVNT_NEWPEER, typesystem, NULL); - typesystem->flags |= FLAG_SYSPEER; + for (n = 0; n < NTP_HASH_SIZE; n++) + for (peer = peer_hash[n]; peer != NULL; peer = + peer->next) + peer->status = peer->new_status; clock_update(typesystem); } diff --git a/ports/winnt/include/config.h b/ports/winnt/include/config.h index 63cb3507b..c09fe5764 100644 --- a/ports/winnt/include/config.h +++ b/ports/winnt/include/config.h @@ -272,6 +272,7 @@ typedef int socklen_t; #define isatty _isatty #define mktemp _mktemp #define getpid _getpid +#define timegm _mkgmtime typedef int pid_t; /* PID is an int */ typedef int ssize_t; /* ssize is an int */ @@ -345,6 +346,7 @@ typedef __int32 int32_t; /* define a typedef for int32_t */ # define HAVE_STDARG_H # define HAVE_NO_NICE # define HAVE_MKTIME +# define HAVE_TIMEGM 1 /* actually _mkgmtime */ # define HAVE_STRUCT_TIMESPEC # define TIME_WITH_SYS_TIME # define HAVE_IO_COMPLETION_PORT diff --git a/ports/winnt/ntpd/nt_clockstuff.c b/ports/winnt/ntpd/nt_clockstuff.c index 5188868ab..b76d1447f 100644 --- a/ports/winnt/ntpd/nt_clockstuff.c +++ b/ports/winnt/ntpd/nt_clockstuff.c @@ -187,6 +187,13 @@ static int is_qpc_built_on_pcc(void); */ static DOUBLE ppm_per_adjust_unit = 0.0; +/* + * wintickadj emulates the functionality provided by unix tickadj, + * providing a baseline clock correction if needed to get the + * clock within a few hundred PPM of correct frequency. + */ +static long wintickadj; + /* * performance counter frequency observations */ @@ -557,6 +564,7 @@ adj_systime( /* only adjust the clock if adjustment changes */ + TimeAdjustment += wintickadj; if (last_Adj != TimeAdjustment) { last_Adj = TimeAdjustment; DPRINTF(1, ("SetSystemTimeAdjustment(%+ld)\n", TimeAdjustment)); @@ -592,6 +600,9 @@ init_winnt_time(void) LARGE_INTEGER Freq; FT_ULL initial_hectonanosecs; FT_ULL next_hectonanosecs; + double adjppm; + double rawadj; + char * pch; if (winnt_time_initialized) return; @@ -775,6 +786,18 @@ init_winnt_time(void) (LONGLONG)os_clock_precision / 1e4, ppm_per_adjust_unit); + pch = getenv("NTPD_TICKADJ_PPM"); + if (pch != NULL && 1 == sscanf(pch, "%lf", &adjppm)) { + rawadj = adjppm / ppm_per_adjust_unit; + rawadj += (rawadj < 0) + ? -0.5 + : 0.5; + wintickadj = (long)rawadj; + msyslog(LOG_INFO, + "Using NTPD_TICKADJ_PPM %+g ppm (%+ld)", + adjppm, wintickadj); + } + winnt_time_initialized = TRUE; choose_interp_counter();