]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
Many files:
authorHarlan Stenn <stenn@ntp.org>
Fri, 13 Apr 2001 04:05:45 +0000 (04:05 -0000)
committerHarlan Stenn <stenn@ntp.org>
Fri, 13 Apr 2001 04:05:45 +0000 (04:05 -0000)
  * 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

13 files changed:
ChangeLog
Makefile.in
include/ntp.h
include/ntp_config.h
include/ntpd.h
ntpd/ntp_config.c
ntpd/ntp_control.c
ntpd/ntp_crypto.c
ntpd/ntp_loopfilter.c
ntpd/ntp_peer.c
ntpd/ntp_proto.c
ntpd/refclock_atom.c
util/ntp-genkeys.c

index a5f0d8ed2d5d71aa4a3b39301f7ae2b5fe2c8e6f..5b78668f299b2353ad9a30af55a143d2acdd521a 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,35 @@
+2001-04-13  Harlan Stenn  <stenn@whimsy.udel.edu>
+
+       * 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  <stenn@whimsy.udel.edu>
 
        * ntpd/ntp_proto.c (clock_filter): Swell stuff.
index 549d9c9a89943c3f78673107784adaa35f297c2e..923b5cd9e335636849e8e180f0ca9ed600b88d25 100644 (file)
@@ -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@
index 7fbf65e41a2e022d7b8b9412731220d536ca75cf..b2c56a654a4232d869935ef0f80a4c254cf31451 100644 (file)
@@ -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
index d6bf70743905af5a3699309e916e6b1271f006f0..94b5a30884229ff33add33eef3edf223a8680838 100644 (file)
 #define CONF_CLOCK_PANIC       2
 #define CONF_CLOCK_PHI         3
 #define CONF_CLOCK_MINSTEP     4
+#define CONF_CLOCK_MINPOLL     5
 
 #ifdef PUBKEY
 /*
index 97dafb2bb961f896e3eb63376b28ddfe585570cd..60f877b72a4d9c956ea7af8b506217a6f0c3f459 100644 (file)
@@ -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) */
index 4076d073551675b108e6a25aa24441d5ea82d3bb..91a6475881c9fb0f105bb57bf6c4f5400c81ba09 100644 (file)
@@ -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)
index 57bca2eb2eacf600f82650e4ff7e73059895de78..38b66baac998bc805aacf8b210b810b1f917179f 100644 (file)
@@ -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);
index 6ed8db55ee02ef42636a0f27a9185d0a3db05c00..a01869de5956b645139a383e672eb72734836eb4 100644 (file)
@@ -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) {
index a3e0b9d88469f6928d6dde7ef3b4f11174e102bc..ca114719d0e99b47c1d8c5724be8a4a50b734ee1 100644 (file)
 /*
  * 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;
        }
 }
 
index d34f7137308e66cf2ff6c8f4150a1f736d79c6c9..359c4ad65b0db94e903b75a580a431092edad7a3 100644 (file)
@@ -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.
index 8a4377ac0f60250f5790d09ce3c9b114036d7080..718a35ea782c9e58a9716a6ac9bab7b23652055b 100644 (file)
@@ -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
index 9dd6765167039f408081e4ea4ec0a76d4795507a..ed79536edcd606ff4c05ac2b4f2114bdc1ee2f89 100644 (file)
@@ -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
  * 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;
 
        /*
index d7e44c436064a191bb79d64c45786bb9e729144b..d0b0f8a1bee62b132dd6b93a48d78593477c2e88 100644 (file)
@@ -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(