From: Harlan Stenn Date: Tue, 19 Apr 2005 02:29:49 +0000 (-0400) Subject: anti-clockhop changes from Dave Mills X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=218b142eb41c9aa8f314fa8eea36cf7ebb2b2780;p=thirdparty%2Fntp.git anti-clockhop changes from Dave Mills bk: 42646d1dksGv88IKXkOMMdVrLTlokg --- diff --git a/include/ntp.h b/include/ntp.h index 9167bd4751..2c600702d7 100644 --- a/include/ntp.h +++ b/include/ntp.h @@ -127,8 +127,7 @@ typedef char s_char; #define MAXDISTANCE 1. /* max root distance */ #define CLOCK_SGATE 3. /* popcorn spike gate */ #define HUFFPUFF 900 /* huff-n'-puff sample interval (s) */ -#define HYST .5 /* anti-clockhop hysteresis */ -#define HYST_TC .875 /* anti-clockhop hysteresis decay */ +#define HOPPER 3 /* anti-clockhop threshold */ #define MAX_TTL 8 /* max ttl mapping vector size */ #define NTP_MAXEXTEN 1024 /* max extension field size */ @@ -339,7 +338,6 @@ struct peer { double jitter; /* peer jitter (squares) */ double disp; /* peer dispersion */ double estbdelay; /* clock offset to broadcast server */ - double hyst; /* anti-clockhop hysteresis */ /* * End of clear-to-zero area diff --git a/ntpd/ntp_proto.c b/ntpd/ntp_proto.c index 1b09f264e1..27a5675e8c 100644 --- a/ntpd/ntp_proto.c +++ b/ntpd/ntp_proto.c @@ -66,6 +66,7 @@ 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) */ double sys_jitter; /* system jitter (s) */ +int sys_hopper; /* anticlockhop counter */ keyid_t sys_private; /* private value for session seed */ int sys_manycastserver; /* respond to manycast client pkts */ int peer_ntpdate; /* active peers in ntpdate mode */ @@ -165,10 +166,11 @@ transmit( if (peer->burst == 0) { u_char oreach; + if (peer == sys_peer) + sys_hopper++; oreach = peer->reach; peer->outdate = current_time; peer->reach <<= 1; - peer->hyst *= HYST_TC; if (!peer->reach) { /* @@ -1931,11 +1933,6 @@ clock_select(void) * configured, his association raft is drowned as well, but only * if at at least eight poll intervals have gone. We must leave * at least one peer to collect the million bucks. - * - * Note the hysteresis gimmick that increases the effective - * distance for those rascals that have not made the final cut. - * This is to discourage clockhopping. Note also the prejudice - * against lower stratum peers if the floor is elevated. */ j = 0; for (i = 0; i < nlist; i++) { @@ -1957,7 +1954,6 @@ clock_select(void) * hasn't been heard for awhile. */ d = root_distance(peer) + peer->stratum * sys_maxdist; - d *= 1. - peer->hyst; if (j >= NTP_MAXCLOCK) { if (d >= synch[j - 1]) continue; @@ -2092,15 +2088,8 @@ clock_select(void) * stratum. Note that the head of the list is at the lowest * stratum and that unsynchronized peers cannot survive this * far. - * - * Fiddle for hysteresis. Pump it up for a peer only if the peer - * stratum is at least the floor and there are enough survivors. - * This minimizes the pain when tossing out rascals beneath the - * floorboard. Don't count peers with stratum above the ceiling. - * Manycast is sooo complicated. */ leap_consensus = 0; - typesystem = peer_list[0]; for (i = nlist - 1; i >= 0; i--) { peer = peer_list[i]; leap_consensus |= peer->leap; @@ -2108,18 +2097,30 @@ clock_select(void) sys_survivors++; if (peer->flags & FLAG_PREFER) sys_prefer = peer; + if (peer == osys_peer) + typesystem = peer; #ifdef REFCLOCK if (peer->refclktype == REFCLK_ATOM_PPS) sys_pps = peer; #endif /* REFCLOCK */ #if DEBUG if (debug > 1) - printf("cluster: survivor %s metric %.6f hyst %.6f\n", - ntoa(&peer_list[i]->srcadr), synch[i], - peer_list[i]->hyst); + printf("cluster: survivor %s metric %.6f\n", + ntoa(&peer_list[i]->srcadr), synch[i]); #endif } + /* + * Anticlockhop provision. Keep the current system peer if it is + * a survivor but not first in the list. But do that only HOPPER + * times. + */ + if (osys_peer == NULL || typesystem == NULL || typesystem == + peer_list[0] || sys_hopper > HOPPER) { + typesystem = peer_list[0]; + sys_hopper = 0; + } + /* * In manycast client mode we may have spooked a sizeable number * of peers that we don't need. If there are at least @@ -2174,9 +2175,9 @@ clock_select(void) } else { /* - * Otherwise, choose the head of the survivor list. + * Otherwise, choose the anticlockhopper. */ - sys_peer = peer_list[0]; + sys_peer = typesystem; sys_peer->status = CTL_PST_SEL_SYSPEER; clock_combine(peer_list, nlist); sys_jitter = SQRT(SQUARE(sys_peer->jitter) + @@ -2189,14 +2190,9 @@ clock_select(void) } /* - * We have found the alpha male. Mark its scent and ding the - * anticlockhop hysteresis. + * We have found the alpha male. */ sys_peer->flags |= FLAG_SYSPEER; - if (osurv >= sys_minclock) - sys_peer->hyst = HYST; - else - sys_peer->hyst = 0; if (osys_peer != sys_peer) { char *src;