]> git.ipfire.org Git - thirdparty/ntp.git/commitdiff
preempt stuff from Dave Mills
authorHarlan Stenn <stenn@ntp.org>
Tue, 16 Aug 2005 06:49:46 +0000 (02:49 -0400)
committerHarlan Stenn <stenn@ntp.org>
Tue, 16 Aug 2005 06:49:46 +0000 (02:49 -0400)
bk: 43018c8ayS-fWMScyWCyfqMz4_X7WA

include/ntp.h
include/ntp_config.h
include/ntpd.h
ntpd/ntp_config.c
ntpd/ntp_peer.c
ntpd/ntp_proto.c

index 695f1794d7cb70a125b7646fd53a8e0ed3736964..63d381ddd5bb0e09a8179139fdcb2b536f0eca9c 100644 (file)
@@ -124,8 +124,8 @@ typedef char s_char;
 #define        NTP_MINCLOCK    3       /* min survivors */
 #define        NTP_MAXCLOCK    10      /* max candidates */
 #define        NTP_MAXASSOC    50      /* max associations */
-#define MINDISTANCE    .01     /* min root distance */
-#define MAXDISTANCE    1.      /* max root distance */
+#define MINDISPERSE    .01     /* min dispersion increment */
+#define MAXDISTANCE    1.      /* max root distance (select threshold) */
 #define CLOCK_SGATE    3.      /* popcorn spike gate */
 #define HUFFPUFF       900     /* huff-n'-puff sample interval (s) */
 #define MAXHOP         2       /* anti-clockhop threshold */
@@ -343,11 +343,12 @@ struct peer {
         * End of clear-to-zero area
         */
        u_long  update;         /* receive epoch */
-#define end_clear_to_zero update
+       u_int   unshift;        /* unreachable shift register */
        u_int   unreach;        /* unreachable count */
+#define end_clear_to_zero unreach
        u_long  outdate;        /* send time last packet */
        u_long  nextdate;       /* send time next packet */
-       u_long  nextaction;     /* peer local activity timeout (refclocks mainly) */
+       u_long  nextaction;     /* peer local activity timeout (refclocks) */
        void (*action) P((struct peer *)); /* action timeout function */
 
        /*
@@ -733,7 +734,7 @@ struct pkt {
 #define PROTO_CEILING          18
 #define PROTO_COHORT           19
 #define PROTO_CALLDELAY                20
-#define PROTO_MINDIST          21
+#define PROTO_MINDISP          21
 #define PROTO_MAXDIST          22
 #define PROTO_ADJ              23
 #define        PROTO_MAXHOP            24
index b2872b8e7c4a0e0bf34370415c497620f154e58e..7919bff6325a726c1fc5c3ca3482d5f6f71b347a 100644 (file)
 #define CONF_TOS_FLOOR         4
 #define CONF_TOS_CEILING       5
 #define CONF_TOS_COHORT                6
-#define CONF_TOS_MINDIST       7
+#define CONF_TOS_MINDISP       7
 #define CONF_TOS_MAXDIST       8
 #define        CONF_TOS_MAXHOP         9
 
index 501238dd3b2b33d423fa85c92cfe4685ed9539c1..37baa173eb3f6bc701ef84f2a0d7cef11ecc6709 100644 (file)
@@ -139,7 +139,6 @@ extern      void    clear_all       P((void));
 extern void    expire_all      P((void));
 #endif /* OPENSSL */
 extern struct  peer *findmanycastpeer  P((struct recvbuf *));
-extern void    resetmanycast   P((void));
 
 /* ntp_crypto.c */
 #ifdef OPENSSL
index fe57f55793b10ae09f87958f7ba422e4dc421980..138344ee8ef969cc5af87cd9393ae73a77e60b37 100644 (file)
@@ -242,7 +242,7 @@ static struct keyword tos_keywords[] = {
        { "floor",              CONF_TOS_FLOOR },
        { "ceiling",            CONF_TOS_CEILING },
        { "cohort",             CONF_TOS_COHORT },
-       { "mindist",            CONF_TOS_MINDIST },
+       { "mindist",            CONF_TOS_MINDISP },
        { "maxdist",            CONF_TOS_MAXDIST },
        { "maxhop",             CONF_TOS_MAXHOP },
        { "",                   CONFIG_UNKNOWN }
@@ -1097,8 +1097,8 @@ getconfig(
                                proto_config(PROTO_COHORT, 0, ftemp, NULL);
                                break;
 
-                           case CONF_TOS_MINDIST:
-                               proto_config(PROTO_MINDIST, 0, ftemp, NULL);
+                           case CONF_TOS_MINDISP:
+                               proto_config(PROTO_MINDISP, 0, ftemp, NULL);
                                break;
 
                            case CONF_TOS_MAXDIST:
index 629c4bf6222b945237c5eb80ac2df23d43192bac..4bdde1c7898ce08d315047dad2f2c6a7cabe1baf 100644 (file)
@@ -302,8 +302,6 @@ clear_all(void)
                            MDF_BCAST))) {
                                peer->hpoll = peer->minpoll;
                                peer_clear(peer, "STEP");
-                               if (!(peer->flags & FLAG_CONFIG))
-                                       unpeer(peer);
                        }
                }
        }
@@ -342,6 +340,7 @@ unpeer(
                printf("demobilize %u %d %d\n", peer_to_remove->associd,
                    peer_associations, peer_preempt);
 #endif
+       peer_clear(peer_to_remove, "KILL");
        hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
        peer_hash_count[hash]--;
        peer_demobilizations++;
@@ -820,13 +819,13 @@ expire_all(void)
         */
        if (!crypto_flags)
                return;
+
        for (n = 0; n < NTP_HASH_SIZE; n++) {
                for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
                        next_peer = peer->next;
                        if (!(peer->flags & FLAG_SKEY)) {
                                continue;
-                       } else if (peer->cast_flags & MDF_ACAST) {
-                               peer_clear(peer, "ACST");
+
                        } else if (peer->hmode == MODE_ACTIVE ||
                            peer->hmode == MODE_PASSIVE) {
                                key_expire(peer);
@@ -838,7 +837,6 @@ expire_all(void)
        }
        RAND_bytes((u_char *)&sys_private, 4);
        crypto_update();
-       resetmanycast();
 }
 #endif /* OPENSSL */
 
@@ -857,8 +855,8 @@ findmanycastpeer(
        int i;
 
        /*
-        * This routine is called upon arrival of a client-mode message
-        * from a manycast server. Search the peer list for a manycast
+        * This routine is called upon arrival of a server-mode message
+        * from a manycast client. Search the peer list for a manycast
         * client association where the last transmit timestamp matches
         * the originate timestamp. This assumes the transmit timestamps
         * for possibly more than one manycast association are unique.
@@ -879,28 +877,3 @@ findmanycastpeer(
        }
        return (NULL);
 }
-
-
-/*
- * resetmanycast - reset all manycast clients
- */
-void
-resetmanycast(void)
-{
-       struct peer *peer, *next_peer;
-       int i;
-
-       /*
-        * This routine is called when the number of client associations
-        * falls below the minimum. Search the peer list for manycast
-        * client associations and reset the ttl and poll interval.
-        */
-       for (i = 0; i < NTP_HASH_SIZE; i++) {
-               for (peer = peer_hash[i]; peer != NULL; peer =
-                   next_peer) {
-                       next_peer= peer->next;
-                       if (peer->cast_flags & MDF_ACLNT) 
-                               unpeer(peer);
-               }
-       }
-}
index eaa286a4380f891d532e1f679c8daf344e52ad91..d232937820a758a8d7168b252003d77b34fb8829 100644 (file)
@@ -62,8 +62,8 @@ int   sys_authenticate;       /* requre authentication for config */
 l_fp   sys_authdelay;          /* authentication delay */
 static u_long sys_authdly[2];  /* authentication delay shift reg */
 static u_char leap_consensus;  /* consensus of survivor leap bits */
-static double sys_mindist = MINDISTANCE; /* selection threshold (s) */
-static double sys_maxdist = MAXDISTANCE; /* selection ceiling (s) */
+static double sys_mindisp = MINDISPERSE; /* min disp increment (s) */
+static double sys_maxdist = MAXDISTANCE; /* selection threshold (s) */
 double sys_jitter;             /* system jitter (s) */
 static int sys_hopper;         /* anticlockhop counter */
 static int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */
@@ -144,8 +144,10 @@ transmit(
         * In manycast mode we start with unity ttl. The ttl is
         * increased by one for each poll until either sys_maxclock
         * servers have been found or the maximum ttl is reached. When
-        * sys_maxclock servers are found we stop polling until either
-        * fewer servers are available
+        * sys_maxclock servers are found we stop polling until one or
+        * more servers have timed out or until less than minpoll
+        * associations turn up. In this case additional better servers
+        * are dragged in and preempt the existing ones.
         */
        if (peer->cast_flags & MDF_ACAST) {
                peer->outdate = current_time;
@@ -189,6 +191,9 @@ transmit(
                                hpoll++;
                        }
                }
+               peer->unshift <<= 1;
+               if (peer->unshift & 0x1000)
+                       peer->unreach--;
                if (peer == sys_peer)
                        sys_hopper++;
                peer->outdate = current_time;
@@ -228,8 +233,11 @@ transmit(
                         * system poll interval. Send a burst only if
                         * enabled and the peer is fit.
                         */
-                       if (!(peer->flags & FLAG_PREEMPT))
-                               peer->unreach = 0;
+                       if (!(peer->flags & FLAG_PREEMPT) &&
+                           peer->unshift & 0x1) {
+                               peer->unshift &= ~0x1;
+                               peer->unreach--;
+                       }
                        if (!(peer->reach & 0x07))
                                clock_filter(peer, 0., 0., MAXDISPERSE);
                        hpoll = sys_poll;
@@ -237,6 +245,7 @@ transmit(
                            peer_unfit(peer))
                                peer->burst = NTP_BURST;
                }
+               peer->unshift |=0x1;
                peer->unreach++;
        } else {
                peer->burst--;
@@ -678,7 +687,7 @@ receive(
                 */
                if (sys_leap == LEAP_NOTINSYNC || sys_stratum <
                    sys_floor || sys_stratum >= sys_ceiling)
-                       return;
+                       return;                 /* bad stratum */
 
                /*
                 * Do not respond if our stratum is greater than the
@@ -755,7 +764,7 @@ receive(
                 */
                if (hisleap == LEAP_NOTINSYNC || hisstratum <
                    sys_floor || hisstratum >= sys_ceiling)
-                       return;
+                       return;                 /* bad stratum */
 
                switch (sys_bclient) {
 
@@ -775,19 +784,17 @@ receive(
                        if ((peer = newpeer(&rbufp->recv_srcadr,
                            rbufp->dstadr, MODE_CLIENT, hisversion,
                            NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_MCAST |
-                           FLAG_IBURST, MDF_BCLNT, 0, skeyid)) == NULL)
+                           FLAG_IBURST | FLAG_PREEMPT, MDF_BCLNT, 0,
+                           skeyid)) == NULL)
                                return;         /* system error */
 #ifdef OPENSSL
                        if (skeyid <= NTP_MAXKEY)
-                               return;
-
-                       if (crypto_recv(peer, rbufp) == XEVNT_OK)
-                               return;
+                               return;         /* symmetric keys */
 
-                       peer_clear(peer, "CRYP");
-                       unpeer(peer);
+                       if (crypto_recv(peer, rbufp) != XEVNT_OK)
+                               unpeer(peer);   /* crypto failure */
 #endif /* OPENSSL */
-                       return;
+                       return;                 /* hooray */
 
 
                /*
@@ -807,8 +814,8 @@ receive(
 #endif /* OPENSSL */
                        if ((peer = newpeer(&rbufp->recv_srcadr,
                            rbufp->dstadr, MODE_BCLIENT, hisversion,
-                           NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_BCLNT, 0,
-                           skeyid)) == NULL)
+                           NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_PREEMPT,
+                           MDF_BCLNT, 0, skeyid)) == NULL)
                                return;         /* system error */
                }
                break;
@@ -847,12 +854,12 @@ receive(
                 */
                if (hisleap == LEAP_NOTINSYNC || hisstratum <
                    sys_floor || hisstratum >= sys_ceiling)
-                       return;
+                       return;                 /* bad stratum */
 
                if ((peer = newpeer(&rbufp->recv_srcadr,
                    rbufp->dstadr, MODE_PASSIVE, hisversion,
-                   NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0,
-                   skeyid)) == NULL)
+                   NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_PREEMPT, MDF_UCAST,
+                   0, skeyid)) == NULL)
                        return;                 /* system error */
 
                break;
@@ -865,12 +872,12 @@ receive(
 
        /*
         * A passive packet matches a passive association. This is
-        * usually the result of reconfiguring a client on the fly. The
-        * association must be ephemeral, so just kill it.
+        * usually the result of reconfiguring a client on the fly. As
+        * this association might be legitamate and this packet an
+        * attempt to deny service, just ignore it.
         */
        case AM_ERR:
-               unpeer(peer);
-               /* fall through */
+               return;
 
        /*
         * For everything else there is the bit bucket.
@@ -925,8 +932,6 @@ receive(
         */
        if (is_authentic == AUTH_CRYPTO) {
                peer_clear(peer, "AUTH");
-               if (!(peer->flags & FLAG_CONFIG))
-                       unpeer(peer);
                return;                         /* crypto-NAK */
 
        /* 
@@ -981,10 +986,8 @@ receive(
                if (rval != XEVNT_OK) {
                        peer_clear(peer, "CRYP");
                        peer->flash |= TEST9;   /* crypto error */
-                       if (!(peer->flags & FLAG_CONFIG)) {
-                               unpeer(peer);
-                               return;
-                       }
+                       return;
+
                } else if (hismode == MODE_SERVER) {
                        if (skeyid == peer->keyid)
                                peer->flash &= ~TEST8;
@@ -1037,8 +1040,6 @@ receive(
        if (peer->flash & TEST4) {
                msyslog(LOG_INFO, "receive: fatal error %04x for %s",
                    peer->flash, stoa(&peer->srcadr));
-               if (!(peer->flags & FLAG_CONFIG))
-                       unpeer(peer);
                return;
        }
 
@@ -1055,8 +1056,6 @@ receive(
                            "receive: flash auto %04x\n", peer->flash);
 #endif
                peer_clear(peer, "AUTO");
-               if (!(peer->flags & FLAG_CONFIG))
-                       unpeer(peer);
        }
 #endif /* OPENSSL */
 }
@@ -1102,10 +1101,6 @@ process_packet(
                if (memcmp(&pkt->refid, "DENY", 4) == 0) {
                        peer_clear(peer, "DENY");
                        peer->flash |= TEST4;   /* access denied */
-                       if (!(peer->flags & FLAG_CONFIG)) {
-                               unpeer(peer);
-                               return;
-                       }
                }
        }
 
@@ -1302,11 +1297,11 @@ clock_update(void)
                    fabs(sys_peer->offset);
 #ifdef REFCLOCK
                if (!(sys_peer->flags & FLAG_REFCLOCK) && dtemp <
-                   sys_mindist)
-                       dtemp = sys_mindist;
+                   sys_mindisp)
+                       dtemp = sys_mindisp;
 #else
-               if (dtemp < sys_mindist)
-                       dtemp = sys_mindist;
+               if (dtemp < sys_mindisp)
+                       dtemp = sys_mindisp;
 #endif /* REFCLOCK */
                sys_rootdispersion = sys_peer->rootdispersion + dtemp;
                sys_leap = leap_consensus;
@@ -2097,7 +2092,11 @@ clock_select(void)
        for (i = 0; i < nlist; i++) {
                peer = peer_list[i];
                sys_survivors++;
-               peer->unreach = 0;
+               if (sys_survivors <= sys_maxclock && peer->unshift &
+                   0x1) {
+                       peer->unshift &= ~0x1;
+                       peer->unreach--;
+               }
                leap_consensus |= peer->leap;
                peer->status = CTL_PST_SEL_SYNCCAND;
                if (peer->flags & FLAG_PREFER)
@@ -3020,7 +3019,7 @@ proto_config(
                break;
 
        /*
-        * Turn on/off facility to listen to broadcasts.
+        * Turn on/off enable broadcasts.
         */
        case PROTO_BROADCLIENT:
                sys_bclient = (int)value;
@@ -3030,6 +3029,13 @@ proto_config(
                        io_setbclient();
                break;
 
+       /*
+        * Turn on/off PPS discipline.
+        */
+       case PROTO_PPS:
+               pps_enable = (int)value;
+               break;
+
        /*
         * Add muliticast group address.
         */
@@ -3062,85 +3068,78 @@ proto_config(
                break;
 
        /*
-        * Require authentication to mobilize ephemeral associations.
+        * Turn on/off authentication to mobilize ephemeral
+        * associations.
         */
        case PROTO_AUTHENTICATE:
                sys_authenticate = (int)value;
                break;
 
        /*
-        * Turn on/off PPS discipline.
-        */
-       case PROTO_PPS:
-               pps_enable = (int)value;
-               break;
-
-       /*
-        * Set the minimum number of survivors.
+        * Set minimum number of survivors.
         */
        case PROTO_MINCLOCK:
                sys_minclock = (int)dvalue;
                break;
 
        /*
-        * Set the minimum number of survivors.
+        * Set maximum number of preemptable associations.
         */
        case PROTO_MAXCLOCK:
                sys_maxclock = (int)dvalue;
                break;
 
-
        /*
-        * Set the minimum number of candidates.
+        * Set minimum number of survivors.
         */
        case PROTO_MINSANE:
                sys_minsane = (int)dvalue;
                break;
 
        /*
-        * Set the stratum floor.
+        * Set stratum floor.
         */
        case PROTO_FLOOR:
                sys_floor = (int)dvalue;
                break;
 
        /*
-        * Set the stratum ceiling.
+        * Set stratum ceiling.
         */
        case PROTO_CEILING:
                sys_ceiling = (int)dvalue;
                break;
 
        /*
-        * Set the select threshold.
+        * Set cohort switch.
         */
-       case PROTO_MINDIST:
-               sys_mindist = dvalue;
+       case PROTO_COHORT:
+               sys_cohort = (int)dvalue;
                break;
 
        /*
-        * Set the select threshold.
+        * Set minimum dispersion increment.
         */
-       case PROTO_MAXDIST:
-               sys_maxdist = dvalue;
+       case PROTO_MINDISP:
+               sys_mindisp = dvalue;
                break;
 
        /*
-        * Set the cohort switch.
+        * Set maximum distance (select threshold).
         */
-       case PROTO_COHORT:
-               sys_cohort = (int)dvalue;
+       case PROTO_MAXDIST:
+               sys_maxdist = dvalue;
                break;
 
        /*
-        * Set the anticlockhop threshold.
+        * Set anticlockhop threshold.
         */
        case PROTO_MAXHOP:
                sys_maxhop = (int)dvalue;
                break;
 
        /*
-        * Set the adjtime() resolution (s).
+        * Set adjtime() resolution (s).
         */
        case PROTO_ADJ:
                sys_tick = dvalue;