From: Harlan Stenn Date: Tue, 16 Aug 2005 06:49:46 +0000 (-0400) Subject: preempt stuff from Dave Mills X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=93defc246635d4c0eb46c992991fb244c8d6fc4c;p=thirdparty%2Fntp.git preempt stuff from Dave Mills bk: 43018c8ayS-fWMScyWCyfqMz4_X7WA --- diff --git a/include/ntp.h b/include/ntp.h index 695f1794d7..63d381ddd5 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -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 diff --git a/include/ntp_config.h b/include/ntp_config.h index b2872b8e7c..7919bff632 100644 --- a/include/ntp_config.h +++ b/include/ntp_config.h @@ -149,7 +149,7 @@ #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 diff --git a/include/ntpd.h b/include/ntpd.h index 501238dd3b..37baa173eb 100644 --- a/include/ntpd.h +++ b/include/ntpd.h @@ -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 diff --git a/ntpd/ntp_config.c b/ntpd/ntp_config.c index fe57f55793..138344ee8e 100644 --- a/ntpd/ntp_config.c +++ b/ntpd/ntp_config.c @@ -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: diff --git a/ntpd/ntp_peer.c b/ntpd/ntp_peer.c index 629c4bf622..4bdde1c789 100644 --- a/ntpd/ntp_peer.c +++ b/ntpd/ntp_peer.c @@ -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); - } - } -} diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index eaa286a438..d232937820 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -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;