MDF_BCAST))) {
peer->hpoll = peer->minpoll;
peer_clear(peer, "STEP");
- if (!(peer->flags & FLAG_CONFIG))
- unpeer(peer);
}
}
}
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++;
*/
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);
}
RAND_bytes((u_char *)&sys_private, 4);
crypto_update();
- resetmanycast();
}
#endif /* OPENSSL */
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.
}
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);
- }
- }
-}
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 */
* 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;
hpoll++;
}
}
+ peer->unshift <<= 1;
+ if (peer->unshift & 0x1000)
+ peer->unreach--;
if (peer == sys_peer)
sys_hopper++;
peer->outdate = current_time;
* 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;
peer_unfit(peer))
peer->burst = NTP_BURST;
}
+ peer->unshift |=0x1;
peer->unreach++;
} else {
peer->burst--;
*/
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
*/
if (hisleap == LEAP_NOTINSYNC || hisstratum <
sys_floor || hisstratum >= sys_ceiling)
- return;
+ return; /* bad stratum */
switch (sys_bclient) {
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 */
/*
#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;
*/
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;
/*
* 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.
*/
if (is_authentic == AUTH_CRYPTO) {
peer_clear(peer, "AUTH");
- if (!(peer->flags & FLAG_CONFIG))
- unpeer(peer);
return; /* crypto-NAK */
/*
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;
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;
}
"receive: flash auto %04x\n", peer->flash);
#endif
peer_clear(peer, "AUTO");
- if (!(peer->flags & FLAG_CONFIG))
- unpeer(peer);
}
#endif /* OPENSSL */
}
if (memcmp(&pkt->refid, "DENY", 4) == 0) {
peer_clear(peer, "DENY");
peer->flash |= TEST4; /* access denied */
- if (!(peer->flags & FLAG_CONFIG)) {
- unpeer(peer);
- return;
- }
}
}
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;
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)
break;
/*
- * Turn on/off facility to listen to broadcasts.
+ * Turn on/off enable broadcasts.
*/
case PROTO_BROADCLIENT:
sys_bclient = (int)value;
io_setbclient();
break;
+ /*
+ * Turn on/off PPS discipline.
+ */
+ case PROTO_PPS:
+ pps_enable = (int)value;
+ break;
+
/*
* Add muliticast group address.
*/
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;