]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
[Bug 1554] peer may stay selected as system peer after becoming
authorDave Hart <hart@ntp.org>
Sun, 15 May 2011 19:19:24 +0000 (19:19 +0000)
committerDave Hart <hart@ntp.org>
Sun, 15 May 2011 19:19:24 +0000 (19:19 +0000)
  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

ChangeLog
include/ntp.h
libntp/mktime.c
ntpd/ntp_loopfilter.c
ntpd/ntp_proto.c
ports/winnt/include/config.h
ports/winnt/ntpd/nt_clockstuff.c

index 17264f8a51b0df9dfe30d597e6bce36ddde89cee..360c13d5f43e675a909b59921e9152f8aabaa694 100644 (file)
--- 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.
 
index 732dff352d6f49e1c7fdbcdec91b244057b0c57b..b719803e49898e8b804096688f95460403f12b54 100644 (file)
@@ -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 */
index 91be60015b007668bedf01e9600fc321871a5a80..381cc4f6dd5e40f09789453d9ca66211c24b1269 100644 (file)
@@ -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)
index 1846b552e4930e6468b8ae776b7ada29c907d680..3eb09e10060a1e6f9cd27c288d7ad648f1bc00e9 100644 (file)
@@ -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:
index 3bea82159c7f825c1f21a62fca85741f6d75192a..9651fc050516f22631c4964be01fecac702d84a1 100644 (file)
@@ -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);
 }
 
index 63cb3507b5ec0a6302659fa30d0e2b107c7a1af9..c09fe57644cdeb6d6323fce8a321bf743888357b 100644 (file)
@@ -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
index 5188868ab1a3239fe76738cb589a4cb98387731e..b76d1447f6f1eb4e341a2da26ae92bdb1c34d962 100644 (file)
@@ -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();