ntp_proto.c revision 182007
154359Sroberto/*
254359Sroberto * ntp_proto.c - NTP version 4 protocol machinery
354363Sroberto *
4132454Sroberto * ATTENTION: Get approval from Dave Mills on all changes to this file!
5132454Sroberto *
654359Sroberto */
754359Sroberto#ifdef HAVE_CONFIG_H
854359Sroberto#include <config.h>
954359Sroberto#endif
1054359Sroberto
1154359Sroberto#include "ntpd.h"
1254359Sroberto#include "ntp_stdlib.h"
1354359Sroberto#include "ntp_unixtime.h"
1454359Sroberto#include "ntp_control.h"
1554359Sroberto#include "ntp_string.h"
1654359Sroberto
1782505Sroberto#include <stdio.h>
1882505Sroberto
1954359Sroberto#if defined(VMS) && defined(VMS_LOCALUNIT)	/*wjm*/
2054359Sroberto#include "ntp_refclock.h"
2154359Sroberto#endif
2254359Sroberto
2354359Sroberto#if defined(__FreeBSD__) && __FreeBSD__ >= 3
2454359Sroberto#include <sys/sysctl.h>
2554359Sroberto#endif
2654359Sroberto
2754359Sroberto/*
28182007Sroberto * This macro defines the authentication state. If x is 1 authentication
29182007Sroberto * is required; othewise it is optional.
30182007Sroberto */
31182007Sroberto#define	AUTH(x, y)	((x) ? (y) == AUTH_OK : (y) == AUTH_OK || \
32182007Sroberto			    (y) == AUTH_NONE)
33182007Sroberto
34182007Sroberto/*
3582505Sroberto * System variables are declared here. See Section 3.2 of the
3654359Sroberto * specification.
3754359Sroberto */
3854359Srobertou_char	sys_leap;		/* system leap indicator */
3954359Srobertou_char	sys_stratum;		/* stratum of system */
40182007Srobertos_char	sys_precision;		/* local clock precision (log2 s) */
4182505Srobertodouble	sys_rootdelay;		/* roundtrip delay to primary source */
4282505Srobertodouble	sys_rootdispersion;	/* dispersion to primary source */
43182007Srobertou_int32 sys_refid;		/* source/loop in network byte order */
4454359Srobertostatic	double sys_offset;	/* current local clock offset */
4554359Srobertol_fp	sys_reftime;		/* time we were last updated */
46132454Srobertostruct	peer *sys_peer;		/* our current peer */
47182007Srobertostruct	peer *sys_pps;		/* our PPS peer */
4882505Srobertostruct	peer *sys_prefer;	/* our cherished peer */
49132454Srobertoint	sys_kod;		/* kod credit */
50132454Srobertoint	sys_kod_rate = 2;	/* max kod packets per second */
51132454Sroberto#ifdef OPENSSL
5254359Srobertou_long	sys_automax;		/* maximum session key lifetime */
53132454Sroberto#endif /* OPENSSL */
5454359Sroberto
5554359Sroberto/*
5654359Sroberto * Nonspecified system state variables.
5754359Sroberto */
58132454Srobertoint	sys_bclient;		/* broadcast client enable */
59132454Srobertodouble	sys_bdelay;		/* broadcast client default delay */
60132454Srobertoint	sys_calldelay;		/* modem callup delay (s) */
6154359Srobertoint	sys_authenticate;	/* requre authentication for config */
6254359Srobertol_fp	sys_authdelay;		/* authentication delay */
63132454Srobertostatic	u_long sys_authdly[2];	/* authentication delay shift reg */
64182007Srobertostatic	double sys_mindisp = MINDISPERSE; /* min disp increment (s) */
65182007Srobertostatic	double sys_maxdist = MAXDISTANCE; /* selection threshold (s) */
66182007Srobertodouble	sys_jitter;		/* system jitter (s) */
67182007Srobertostatic	int sys_hopper;		/* anticlockhop counter */
68182007Srobertostatic	int sys_maxhop = MAXHOP; /* anticlockhop counter threshold */
69182007Srobertoint	leap_next;		/* leap consensus */
7082505Srobertokeyid_t	sys_private;		/* private value for session seed */
7182505Srobertoint	sys_manycastserver;	/* respond to manycast client pkts */
7282505Srobertoint	peer_ntpdate;		/* active peers in ntpdate mode */
73132454Srobertoint	sys_survivors;		/* truest of the truechimers */
74132454Sroberto#ifdef OPENSSL
7582505Srobertochar	*sys_hostname;		/* gethostname() name */
76132454Sroberto#endif /* OPENSSL */
7754359Sroberto
7854359Sroberto/*
79132454Sroberto * TOS and multicast mapping stuff
80132454Sroberto */
81182007Srobertoint	sys_floor = 0;		/* cluster stratum floor */
82182007Srobertoint	sys_ceiling = STRATUM_UNSPEC; /* cluster stratum ceiling */
83132454Srobertoint	sys_minsane = 1;	/* minimum candidates */
84132454Srobertoint	sys_minclock = NTP_MINCLOCK; /* minimum survivors */
85182007Srobertoint	sys_maxclock = NTP_MAXCLOCK; /* maximum candidates */
86132454Srobertoint	sys_cohort = 0;		/* cohort switch */
87182007Srobertoint	sys_orphan = STRATUM_UNSPEC + 1; /* orphan stratum */
88182007Srobertodouble	sys_orphandelay = 0;	/* orphan root delay */
89182007Srobertoint	sys_beacon = BEACON;	/* manycast beacon interval */
90132454Srobertoint	sys_ttlmax;		/* max ttl mapping vector index */
91132454Srobertou_char	sys_ttl[MAX_TTL];	/* ttl mapping vector */
92132454Sroberto
93132454Sroberto/*
9454359Sroberto * Statistics counters
9554359Sroberto */
96132454Srobertou_long	sys_stattime;		/* time since reset */
97132454Srobertou_long	sys_received;		/* packets received */
9854359Srobertou_long	sys_processed;		/* packets processed */
99132454Srobertou_long	sys_newversionpkt;	/* current version */
100132454Srobertou_long	sys_oldversionpkt;	/* recent version */
101132454Srobertou_long	sys_unknownversion;	/* invalid version */
102132454Srobertou_long	sys_restricted;		/* access denied */
103132454Srobertou_long	sys_badlength;		/* bad length or format */
104132454Srobertou_long	sys_badauth;		/* bad authentication */
105132454Srobertou_long	sys_limitrejected;	/* rate exceeded */
10654359Sroberto
10754359Srobertostatic	double	root_distance	P((struct peer *));
108182007Srobertostatic	void	clock_combine	P((struct peer **, int));
10954359Srobertostatic	void	peer_xmit	P((struct peer *));
110182007Srobertostatic	void	fast_xmit	P((struct recvbuf *, int, keyid_t,
111182007Sroberto				    int));
11254359Srobertostatic	void	clock_update	P((void));
113182007Srobertostatic	int	default_get_precision	P((void));
114132454Srobertostatic	int	peer_unfit	P((struct peer *));
11554359Sroberto
116182007Sroberto
11754359Sroberto/*
11854359Sroberto * transmit - Transmit Procedure. See Section 3.4.2 of the
11954359Sroberto *	specification.
12054359Sroberto */
12154359Srobertovoid
12254359Srobertotransmit(
12354359Sroberto	struct peer *peer	/* peer structure pointer */
12454359Sroberto	)
12554359Sroberto{
126132454Sroberto	int	hpoll;
12754359Sroberto
128132454Sroberto	/*
129132454Sroberto	 * The polling state machine. There are two kinds of machines,
130132454Sroberto	 * those that never expect a reply (broadcast and manycast
131132454Sroberto	 * server modes) and those that do (all other modes). The dance
132132454Sroberto	 * is intricate...
133132454Sroberto	 */
134182007Sroberto	/*
135182007Sroberto	 * Orphan mode is active when enabled and when no servers less
136182007Sroberto	 * than the orphan statum are available. In this mode packets
137182007Sroberto	 * are sent at the orphan stratum. An orphan with no other
138182007Sroberto	 * synchronization source is an orphan parent. It assumes root
139182007Sroberto	 * delay zero and reference ID the loopback address. All others
140182007Sroberto	 * are orphan children with root delay randomized over a 1-s
141182007Sroberto	 * range. The root delay is used by the election algorithm to
142182007Sroberto	 * select the order of synchronization.
143182007Sroberto	 */
14454359Sroberto	hpoll = peer->hpoll;
145182007Sroberto	if (sys_orphan < STRATUM_UNSPEC && sys_peer == NULL) {
146182007Sroberto		sys_leap = LEAP_NOWARNING;
147182007Sroberto		sys_stratum = sys_orphan;
148182007Sroberto		sys_refid = htonl(LOOPBACKADR);
149182007Sroberto		sys_rootdelay = 0;
150182007Sroberto		sys_rootdispersion = 0;
151182007Sroberto	}
152182007Sroberto
153182007Sroberto	/*
154182007Sroberto	 * In broadcast mode the poll interval is never changed from
155182007Sroberto	 * minpoll.
156182007Sroberto	 */
157132454Sroberto	if (peer->cast_flags & (MDF_BCAST | MDF_MCAST)) {
158182007Sroberto		peer->outdate = current_time;
159182007Sroberto		peer_xmit(peer);
160182007Sroberto		poll_update(peer, hpoll);
161182007Sroberto		return;
162182007Sroberto	}
16354359Sroberto
164182007Sroberto	/*
165182007Sroberto	 * In manycast mode we start with unity ttl. The ttl is
166182007Sroberto	 * increased by one for each poll until either sys_maxclock
167182007Sroberto	 * servers have been found or the maximum ttl is reached. When
168182007Sroberto	 * sys_maxclock servers are found we stop polling until one or
169182007Sroberto	 * more servers have timed out or until less than minpoll
170182007Sroberto	 * associations turn up. In this case additional better servers
171182007Sroberto	 * are dragged in and preempt the existing ones.
172182007Sroberto	 */
173182007Sroberto	if (peer->cast_flags & MDF_ACAST) {
174182007Sroberto		peer->outdate = current_time;
175182007Sroberto		if (peer->unreach > sys_beacon) {
176182007Sroberto			peer->unreach = 0;
177182007Sroberto			peer->ttl = 0;
178182007Sroberto			peer_xmit(peer);
179182007Sroberto		} else if (sys_survivors < sys_minclock ||
180182007Sroberto		    peer_preempt < sys_maxclock) {
181182007Sroberto			if (peer->ttl < sys_ttlmax)
182182007Sroberto				peer->ttl++;
183182007Sroberto			peer_xmit(peer);
184182007Sroberto		}
185182007Sroberto		peer->unreach++;
186182007Sroberto		poll_update(peer, hpoll);
187182007Sroberto		return;
188182007Sroberto	}
18982505Sroberto
190182007Sroberto	/*
191182007Sroberto	 * In unicast modes the dance is much more intricate. It is
192182007Sroberto	 * desigmed to back off whenever possible to minimize network
193182007Sroberto	 * traffic.
194182007Sroberto	 */
195182007Sroberto	if (peer->burst == 0) {
196182007Sroberto		u_char oreach;
197182007Sroberto
198132454Sroberto		/*
199182007Sroberto		 * Update the reachability status. If not heard for
200182007Sroberto		 * three consecutive polls, stuff infinity in the clock
201182007Sroberto		 * filter.
202132454Sroberto		 */
203182007Sroberto		oreach = peer->reach;
204182007Sroberto		peer->outdate = current_time;
205182007Sroberto		if (peer == sys_peer)
206182007Sroberto			sys_hopper++;
207182007Sroberto		peer->reach <<= 1;
208182007Sroberto		if (!(peer->reach & 0x07))
209182007Sroberto			clock_filter(peer, 0., 0., MAXDISPERSE);
210182007Sroberto		if (!peer->reach) {
21182505Sroberto
212182007Sroberto			/*
213182007Sroberto			 * Here the peer is unreachable. If it was
214182007Sroberto			 * previously reachable, raise a trap.
215182007Sroberto			 */
216182007Sroberto			if (oreach) {
217182007Sroberto				report_event(EVNT_UNREACH, peer);
218182007Sroberto				peer->timereachable = current_time;
219182007Sroberto			}
220182007Sroberto
221182007Sroberto			/*
222182007Sroberto			 * Send a burst if enabled, but only once after
223182007Sroberto			 * a peer becomes unreachable. If the prempt
224182007Sroberto			 * flag is dim, bump the unreach counter by one;
225182007Sroberto			 * otherwise, bump it by three.
226182007Sroberto			 */
227182007Sroberto			if (peer->flags & FLAG_IBURST &&
228182007Sroberto			    peer->unreach == 0) {
229182007Sroberto				peer->burst = NTP_BURST;
230182007Sroberto			}
231182007Sroberto			if (!(peer->flags & FLAG_PREEMPT))
232182007Sroberto				peer->unreach++;
233182007Sroberto			else
234182007Sroberto				peer->unreach += 3;
235182007Sroberto		} else {
236182007Sroberto
237182007Sroberto			/*
238182007Sroberto			 * Here the peer is reachable. Set the poll
239182007Sroberto			 * interval to the system poll interval. Send a
240182007Sroberto			 * burst only if enabled and the peer is fit.
241182007Sroberto			 *
242182007Sroberto			 * Respond to the peer evaluation produced by
243182007Sroberto			 * the selection algorithm. If less than the
244182007Sroberto			 * outlyer level, up the unreach by three. If
245182007Sroberto			 * there are excess associations, up the unreach
246182007Sroberto			 * by two if not a candidate and by one if so.
247182007Sroberto			 */
248182007Sroberto			if (!(peer->flags & FLAG_PREEMPT)) {
249182007Sroberto				peer->unreach = 0;
250182007Sroberto			} else if (peer->status < CTL_PST_SEL_SELCAND) {
251182007Sroberto				peer->unreach += 3;
252182007Sroberto			} else if (peer_preempt > sys_maxclock) {
253182007Sroberto				if (peer->status < CTL_PST_SEL_SYNCCAND)
254182007Sroberto					peer->unreach += 2;
255182007Sroberto				else
256182007Sroberto					peer->unreach++;
257182007Sroberto			} else {
258182007Sroberto				peer->unreach = 0;
259182007Sroberto			}
260182007Sroberto			hpoll = sys_poll;
261182007Sroberto			if (peer->flags & FLAG_BURST &&
262182007Sroberto			    !peer_unfit(peer))
263182007Sroberto				peer->burst = NTP_BURST;
264182007Sroberto		}
265182007Sroberto
266132454Sroberto		/*
267182007Sroberto		 * Watch for timeout. If ephemeral or preemptable, toss
268182007Sroberto		 * the rascal; otherwise, bump the poll interval.
269182007Sroberto		 */
270132454Sroberto		if (peer->unreach >= NTP_UNREACH) {
271182007Sroberto			if (peer->flags & FLAG_PREEMPT ||
272182007Sroberto			    !(peer->flags & FLAG_CONFIG)) {
273182007Sroberto				peer_clear(peer, "TIME");
27482505Sroberto				unpeer(peer);
27582505Sroberto				return;
276182007Sroberto			} else {
277182007Sroberto				hpoll++;
27882505Sroberto			}
27982505Sroberto		}
280182007Sroberto	} else {
281182007Sroberto		peer->burst--;
282182007Sroberto
283182007Sroberto		/*
284182007Sroberto		 * If a broadcast client at this point, the burst has
285182007Sroberto		 * concluded, so we switch to client mode and purge the
286182007Sroberto		 * keylist, since no further transmissions will be made.
287182007Sroberto		 */
288132454Sroberto		if (peer->burst == 0) {
289182007Sroberto			if (peer->cast_flags & MDF_BCLNT) {
290182007Sroberto				peer->hmode = MODE_BCLIENT;
291182007Sroberto#ifdef OPENSSL
292182007Sroberto				key_expire(peer);
293182007Sroberto#endif /* OPENSSL */
29454359Sroberto			}
29554359Sroberto
29654359Sroberto			/*
297182007Sroberto			 * If ntpdate mode and the clock has not been
298182007Sroberto			 * set and all peers have completed the burst,
299182007Sroberto			 * we declare a successful failure.
30054359Sroberto			 */
301182007Sroberto			if (mode_ntpdate) {
302182007Sroberto				peer_ntpdate--;
303182007Sroberto				if (peer_ntpdate == 0) {
304132454Sroberto					msyslog(LOG_NOTICE,
305132454Sroberto					    "no reply; clock not set");
306132454Sroberto					exit (0);
307132454Sroberto				}
30854359Sroberto			}
30954359Sroberto		}
31054359Sroberto	}
31154359Sroberto
31254359Sroberto	/*
313182007Sroberto	 * Do not transmit if in broadcast client mode.
31454359Sroberto	 */
315182007Sroberto	if (peer->hmode != MODE_BCLIENT)
316182007Sroberto		peer_xmit(peer);
317132454Sroberto	poll_update(peer, hpoll);
31854359Sroberto}
31954359Sroberto
320182007Sroberto
32154359Sroberto/*
32254359Sroberto * receive - Receive Procedure.  See section 3.4.3 in the specification.
32354359Sroberto */
32454359Srobertovoid
32554359Srobertoreceive(
32654359Sroberto	struct recvbuf *rbufp
32754359Sroberto	)
32854359Sroberto{
329132454Sroberto	register struct peer *peer;	/* peer structure pointer */
330132454Sroberto	register struct pkt *pkt;	/* receive packet pointer */
331182007Sroberto	int	hisversion;		/* packet version */
332182007Sroberto	int	hisleap;		/* packet leap indicator */
333132454Sroberto	int	hismode;		/* packet mode */
334182007Sroberto	int	hisstratum;		/* packet stratum */
335132454Sroberto	int	restrict_mask;		/* restrict bits */
336132454Sroberto	int	has_mac;		/* length of MAC field */
337132454Sroberto	int	authlen;		/* offset of MAC field */
338182007Sroberto	int	is_authentic = 0;	/* cryptosum ok */
339132454Sroberto	keyid_t	skeyid = 0;		/* key ID */
340132454Sroberto	struct sockaddr_storage *dstadr_sin; /* active runway */
341132454Sroberto	struct peer *peer2;		/* aux peer structure pointer */
342182007Sroberto	l_fp	p_org;			/* origin timestamp */
343182007Sroberto	l_fp	p_rec;			/* receive timestamp */
344132454Sroberto	l_fp	p_xmt;			/* transmit timestamp */
345132454Sroberto#ifdef OPENSSL
346132454Sroberto	keyid_t tkeyid = 0;		/* temporary key ID */
347132454Sroberto	keyid_t	pkeyid = 0;		/* previous key ID */
348132454Sroberto	struct autokey *ap;		/* autokey structure pointer */
349132454Sroberto	int	rval;			/* cookie snatcher */
350132454Sroberto#endif /* OPENSSL */
35154359Sroberto	int retcode = AM_NOMATCH;
352182007Sroberto	int	at_listhead;
35354359Sroberto
35454359Sroberto	/*
35582505Sroberto	 * Monitor the packet and get restrictions. Note that the packet
35682505Sroberto	 * length for control and private mode packets must be checked
35782505Sroberto	 * by the service routines. Note that no statistics counters are
35882505Sroberto	 * recorded for restrict violations, since these counters are in
35982505Sroberto	 * the restriction routine. Note the careful distinctions here
36082505Sroberto	 * between a packet with a format error and a packet that is
36182505Sroberto	 * simply discarded without prejudice. Some restrictions have to
36282505Sroberto	 * be handled later in order to generate a kiss-of-death packet.
36354359Sroberto	 */
364132454Sroberto	/*
365132454Sroberto	 * Bogus port check is before anything, since it probably
366132454Sroberto	 * reveals a clogging attack.
367132454Sroberto	 */
368132454Sroberto	sys_received++;
369132454Sroberto	if (SRCPORT(&rbufp->recv_srcadr) == 0) {
370132454Sroberto		sys_badlength++;
371132454Sroberto		return;				/* bogus port */
372132454Sroberto	}
373182007Sroberto	at_listhead = ntp_monitor(rbufp);
374182007Sroberto	restrict_mask = restrictions(&rbufp->recv_srcadr, at_listhead);
37554359Sroberto#ifdef DEBUG
376132454Sroberto	if (debug > 1)
377182007Sroberto		printf("receive: at %ld %s<-%s flags %x restrict %03x\n",
378132454Sroberto		    current_time, stoa(&rbufp->dstadr->sin),
379182007Sroberto		    stoa(&rbufp->recv_srcadr),
380182007Sroberto		    rbufp->dstadr->flags, restrict_mask);
38154359Sroberto#endif
382132454Sroberto	if (restrict_mask & RES_IGNORE) {
383132454Sroberto		sys_restricted++;
384182007Sroberto		return;				/* ignore everything */
385132454Sroberto	}
38654359Sroberto	pkt = &rbufp->recv_pkt;
387182007Sroberto	hisversion = PKT_VERSION(pkt->li_vn_mode);
388182007Sroberto	hisleap = PKT_LEAP(pkt->li_vn_mode);
389132454Sroberto	hismode = (int)PKT_MODE(pkt->li_vn_mode);
390182007Sroberto	hisstratum = PKT_TO_STRATUM(pkt->stratum);
391132454Sroberto	if (hismode == MODE_PRIVATE) {
392132454Sroberto		if (restrict_mask & RES_NOQUERY) {
393132454Sroberto			sys_restricted++;
39482505Sroberto			return;			/* no query private */
395132454Sroberto		}
39656749Sroberto		process_private(rbufp, ((restrict_mask &
39756749Sroberto		    RES_NOMODIFY) == 0));
39854359Sroberto		return;
39954359Sroberto	}
400132454Sroberto	if (hismode == MODE_CONTROL) {
401132454Sroberto		if (restrict_mask & RES_NOQUERY) {
402132454Sroberto			sys_restricted++;
40382505Sroberto			return;			/* no query control */
404132454Sroberto		}
40554359Sroberto		process_control(rbufp, restrict_mask);
40654359Sroberto		return;
40754359Sroberto	}
408132454Sroberto	if (restrict_mask & RES_DONTSERVE) {
409132454Sroberto		sys_restricted++;
410132454Sroberto		return;				/* no time */
411132454Sroberto	}
41282505Sroberto	if (rbufp->recv_length < LEN_PKT_NOMAC) {
41382505Sroberto		sys_badlength++;
41482505Sroberto		return;				/* runt packet */
41582505Sroberto	}
416132454Sroberto
417132454Sroberto	/*
418132454Sroberto	 * Version check must be after the query packets, since they
419132454Sroberto	 * intentionally use early version.
420132454Sroberto	 */
421182007Sroberto	if (hisversion == NTP_VERSION) {
422132454Sroberto		sys_newversionpkt++;		/* new version */
423182007Sroberto	} else if (!(restrict_mask & RES_VERSION) && hisversion >=
424182007Sroberto	    NTP_OLDVERSION) {
425132454Sroberto		sys_oldversionpkt++;		/* previous version */
426132454Sroberto	} else {
427132454Sroberto		sys_unknownversion++;
428132454Sroberto		return;				/* old version */
429132454Sroberto	}
43054359Sroberto
43154359Sroberto	/*
432132454Sroberto	 * Figure out his mode and validate the packet. This has some
433132454Sroberto	 * legacy raunch that probably should be removed. In very early
434132454Sroberto	 * NTP versions mode 0 was equivalent to what later versions
435132454Sroberto	 * would interpret as client mode.
43654359Sroberto	 */
43782505Sroberto	if (hismode == MODE_UNSPEC) {
438182007Sroberto		if (hisversion == NTP_OLDVERSION) {
439132454Sroberto			hismode = MODE_CLIENT;
440132454Sroberto		} else {
441132454Sroberto			sys_badlength++;
442132454Sroberto			return;                 /* invalid mode */
443132454Sroberto		}
44482505Sroberto	}
44554359Sroberto
44654359Sroberto	/*
44782505Sroberto	 * Parse the extension field if present. We figure out whether
44882505Sroberto	 * an extension field is present by measuring the MAC size. If
449182007Sroberto	 * the number of words following the packet header is 0, no MAC
450182007Sroberto	 * is present and the packet is not authenticated. If 1, the
451182007Sroberto	 * packet is a crypto-NAK; if 3, the packet is authenticated
452182007Sroberto	 * with DES; if 5, the packet is authenticated with MD5. If 2 or
453182007Sroberto	 * 4, the packet is a runt and discarded forthwith. If greater
454182007Sroberto	 * than 5, an extension field is present, so we subtract the
455182007Sroberto	 * length of the field and go around again.
45654359Sroberto	 */
45754359Sroberto	authlen = LEN_PKT_NOMAC;
458132454Sroberto	has_mac = rbufp->recv_length - authlen;
459132454Sroberto	while (has_mac > 0) {
46082505Sroberto		int temp;
46182505Sroberto
46282505Sroberto		if (has_mac % 4 != 0 || has_mac < 0) {
46354359Sroberto			sys_badlength++;
464132454Sroberto			return;			/* bad MAC length */
46554359Sroberto		}
46682505Sroberto		if (has_mac == 1 * 4 || has_mac == 3 * 4 || has_mac ==
46782505Sroberto		    MAX_MAC_LEN) {
46882505Sroberto			skeyid = ntohl(((u_int32 *)pkt)[authlen / 4]);
46982505Sroberto			break;
47054359Sroberto
47182505Sroberto		} else if (has_mac > MAX_MAC_LEN) {
47282505Sroberto			temp = ntohl(((u_int32 *)pkt)[authlen / 4]) &
47382505Sroberto			    0xffff;
474132454Sroberto			if (temp < 4 || temp > NTP_MAXEXTEN || temp % 4
475132454Sroberto			    != 0) {
47682505Sroberto				sys_badlength++;
477132454Sroberto				return;		/* bad MAC length */
47882505Sroberto			}
47982505Sroberto			authlen += temp;
480132454Sroberto			has_mac -= temp;
48182505Sroberto		} else {
48282505Sroberto			sys_badlength++;
483132454Sroberto			return;			/* bad MAC length */
48482505Sroberto		}
48554359Sroberto	}
486132454Sroberto#ifdef OPENSSL
487132454Sroberto	pkeyid = tkeyid = 0;
488132454Sroberto#endif /* OPENSSL */
48954359Sroberto
49054359Sroberto	/*
49182505Sroberto	 * We have tossed out as many buggy packets as possible early in
49282505Sroberto	 * the game to reduce the exposure to a clogging attack. Now we
49382505Sroberto	 * have to burn some cycles to find the association and
49482505Sroberto	 * authenticate the packet if required. Note that we burn only
495132454Sroberto	 * MD5 cycles, again to reduce exposure. There may be no
49682505Sroberto	 * matching association and that's okay.
49782505Sroberto	 *
49882505Sroberto	 * More on the autokey mambo. Normally the local interface is
49982505Sroberto	 * found when the association was mobilized with respect to a
50082505Sroberto	 * designated remote address. We assume packets arriving from
50182505Sroberto	 * the remote address arrive via this interface and the local
50282505Sroberto	 * address used to construct the autokey is the unicast address
50382505Sroberto	 * of the interface. However, if the sender is a broadcaster,
50482505Sroberto	 * the interface broadcast address is used instead.
505182007Sroberto	 & Notwithstanding this technobabble, if the sender is a
50682505Sroberto	 * multicaster, the broadcast address is null, so we use the
50782505Sroberto	 * unicast address anyway. Don't ask.
50854359Sroberto	 */
509182007Sroberto	peer = findpeer(&rbufp->recv_srcadr, rbufp->dstadr,  hismode,
510182007Sroberto	    &retcode);
51182505Sroberto	dstadr_sin = &rbufp->dstadr->sin;
512182007Sroberto	NTOHL_FP(&pkt->org, &p_org);
513182007Sroberto	NTOHL_FP(&pkt->rec, &p_rec);
514182007Sroberto	NTOHL_FP(&pkt->xmt, &p_xmt);
515182007Sroberto
516182007Sroberto	/*
517182007Sroberto	 * Authentication is conditioned by three switches:
518182007Sroberto	 *
519182007Sroberto	 * NOPEER  (RES_NOPEER) do not mobilize an association unless
520182007Sroberto	 *         authenticated
521182007Sroberto	 * NOTRUST (RES_DONTTRUST) do not allow access unless
522182007Sroberto	 *         authenticated (implies NOPEER)
523182007Sroberto	 * enable  (sys_authenticate) master NOPEER switch, by default
524182007Sroberto	 *         on
525182007Sroberto	 *
526182007Sroberto	 * The NOPEER and NOTRUST can be specified on a per-client basis
527182007Sroberto	 * using the restrict command. The enable switch if on implies
528182007Sroberto	 * NOPEER for all clients. There are four outcomes:
529182007Sroberto	 *
530182007Sroberto	 * NONE    The packet has no MAC.
531182007Sroberto	 * OK      the packet has a MAC and authentication succeeds
532182007Sroberto	 * ERROR   the packet has a MAC and authentication fails
533182007Sroberto	 * CRYPTO  crypto-NAK. The MAC has four octets only.
534182007Sroberto	 *
535182007Sroberto	 * Note: The AUTH(x, y) macro is used to filter outcomes. If x
536182007Sroberto	 * is zero, acceptable outcomes of y are NONE and OK. If x is
537182007Sroberto	 * one, the only acceptable outcome of y is OK.
538182007Sroberto	 */
53954359Sroberto	if (has_mac == 0) {
540182007Sroberto		is_authentic = AUTH_NONE; /* not required */
54154359Sroberto#ifdef DEBUG
54254359Sroberto		if (debug)
543182007Sroberto			printf("receive: at %ld %s<-%s mode %d code %d auth %d\n",
544182007Sroberto			    current_time, stoa(dstadr_sin),
545182007Sroberto			    stoa(&rbufp->recv_srcadr), hismode, retcode,
546182007Sroberto			    is_authentic);
54754359Sroberto#endif
548182007Sroberto	} else if (has_mac == 4) {
549182007Sroberto			is_authentic = AUTH_CRYPTO; /* crypto-NAK */
550182007Sroberto#ifdef DEBUG
551182007Sroberto		if (debug)
552182007Sroberto			printf(
553182007Sroberto			    "receive: at %ld %s<-%s mode %d code %d keyid %08x len %d mac %d auth %d\n",
554182007Sroberto			    current_time, stoa(dstadr_sin),
555182007Sroberto			    stoa(&rbufp->recv_srcadr), hismode, retcode,
556182007Sroberto			    skeyid, authlen, has_mac, is_authentic);
557182007Sroberto#endif
55854359Sroberto	} else {
559132454Sroberto#ifdef OPENSSL
56082505Sroberto		/*
56182505Sroberto		 * For autokey modes, generate the session key
56282505Sroberto		 * and install in the key cache. Use the socket
56382505Sroberto		 * broadcast or unicast address as appropriate.
56482505Sroberto		 */
56582505Sroberto		if (skeyid > NTP_MAXKEY) {
56682505Sroberto
56782505Sroberto			/*
56882505Sroberto			 * More on the autokey dance (AKD). A cookie is
56982505Sroberto			 * constructed from public and private values.
57082505Sroberto			 * For broadcast packets, the cookie is public
57182505Sroberto			 * (zero). For packets that match no
57282505Sroberto			 * association, the cookie is hashed from the
57382505Sroberto			 * addresses and private value. For server
57482505Sroberto			 * packets, the cookie was previously obtained
57582505Sroberto			 * from the server. For symmetric modes, the
57682505Sroberto			 * cookie was previously constructed using an
57782505Sroberto			 * agreement protocol; however, should PKI be
57882505Sroberto			 * unavailable, we construct a fake agreement as
57982505Sroberto			 * the EXOR of the peer and host cookies.
58082505Sroberto			 *
58182505Sroberto			 * hismode	ephemeral	persistent
58282505Sroberto			 * =======================================
58382505Sroberto			 * active	0		cookie#
58482505Sroberto			 * passive	0%		cookie#
58582505Sroberto			 * client	sys cookie	0%
58682505Sroberto			 * server	0%		sys cookie
58782505Sroberto			 * broadcast	0		0
58882505Sroberto			 *
58982505Sroberto			 * # if unsync, 0
59082505Sroberto			 * % can't happen
59182505Sroberto			 */
59282505Sroberto			if (hismode == MODE_BROADCAST) {
59354359Sroberto
59482505Sroberto				/*
59582505Sroberto				 * For broadcaster, use the interface
59682505Sroberto				 * broadcast address when available;
59782505Sroberto				 * otherwise, use the unicast address
59882505Sroberto				 * found when the association was
599182007Sroberto				 * mobilized. However, if this is from
600182007Sroberto				 * the wildcard interface, game over.
60182505Sroberto				 */
602182007Sroberto				if (crypto_flags && rbufp->dstadr ==
603182007Sroberto				    any_interface) {
604182007Sroberto					sys_restricted++;
605182007Sroberto					return;	     /* no wildcard */
606182007Sroberto				}
60782505Sroberto				pkeyid = 0;
608132454Sroberto				if (!SOCKNUL(&rbufp->dstadr->bcast))
60982505Sroberto					dstadr_sin =
61082505Sroberto					    &rbufp->dstadr->bcast;
61182505Sroberto			} else if (peer == NULL) {
61282505Sroberto				pkeyid = session_key(
61382505Sroberto				    &rbufp->recv_srcadr, dstadr_sin, 0,
61482505Sroberto				    sys_private, 0);
61582505Sroberto			} else {
616132454Sroberto				pkeyid = peer->pcookie;
61782505Sroberto			}
61882505Sroberto
61954359Sroberto			/*
62082505Sroberto			 * The session key includes both the public
62182505Sroberto			 * values and cookie. In case of an extension
62282505Sroberto			 * field, the cookie used for authentication
62382505Sroberto			 * purposes is zero. Note the hash is saved for
62482505Sroberto			 * use later in the autokey mambo.
62554359Sroberto			 */
62682505Sroberto			if (authlen > LEN_PKT_NOMAC && pkeyid != 0) {
62782505Sroberto				session_key(&rbufp->recv_srcadr,
62882505Sroberto				    dstadr_sin, skeyid, 0, 2);
62954359Sroberto				tkeyid = session_key(
63082505Sroberto				    &rbufp->recv_srcadr, dstadr_sin,
63182505Sroberto				    skeyid, pkeyid, 0);
63282505Sroberto			} else {
63354359Sroberto				tkeyid = session_key(
63482505Sroberto				    &rbufp->recv_srcadr, dstadr_sin,
63582505Sroberto				    skeyid, pkeyid, 2);
63654359Sroberto			}
63754359Sroberto
63854359Sroberto		}
639132454Sroberto#endif /* OPENSSL */
64054359Sroberto
64154359Sroberto		/*
64254359Sroberto		 * Compute the cryptosum. Note a clogging attack may
64382505Sroberto		 * succeed in bloating the key cache. If an autokey,
64482505Sroberto		 * purge it immediately, since we won't be needing it
645182007Sroberto		 * again. If the packet is authentic, it can mobilize an
646182007Sroberto		 * association. Note that there is no key zero.
64754359Sroberto		 */
648182007Sroberto		if (!authdecrypt(skeyid, (u_int32 *)pkt, authlen,
649132454Sroberto		    has_mac)) {
650182007Sroberto			is_authentic = AUTH_ERROR;
651182007Sroberto			sys_badauth++;
652132454Sroberto		} else {
653182007Sroberto			is_authentic = AUTH_OK;
654132454Sroberto		}
655132454Sroberto#ifdef OPENSSL
65682505Sroberto		if (skeyid > NTP_MAXKEY)
65782505Sroberto			authtrust(skeyid, 0);
658132454Sroberto#endif /* OPENSSL */
65954359Sroberto#ifdef DEBUG
66054359Sroberto		if (debug)
66154359Sroberto			printf(
66282505Sroberto			    "receive: at %ld %s<-%s mode %d code %d keyid %08x len %d mac %d auth %d\n",
663132454Sroberto			    current_time, stoa(dstadr_sin),
664132454Sroberto			    stoa(&rbufp->recv_srcadr), hismode, retcode,
665182007Sroberto			    skeyid, authlen, has_mac, is_authentic);
66654359Sroberto#endif
66754359Sroberto	}
66854359Sroberto
66954359Sroberto	/*
67082505Sroberto	 * The association matching rules are implemented by a set of
671182007Sroberto	 * routines and an association table. A packet matching an
672182007Sroberto	 * association is processed by the peer process for that
673182007Sroberto	 * association. If there are no errors, an ephemeral association
674182007Sroberto	 * is mobilized: a broadcast packet mobilizes a broadcast client
675132454Sroberto	 * aassociation; a manycast server packet mobilizes a manycast
676132454Sroberto	 * client association; a symmetric active packet mobilizes a
677182007Sroberto	 * symmetric passive association.
67854359Sroberto	 */
67954359Sroberto	switch (retcode) {
680182007Sroberto
681182007Sroberto	/*
682182007Sroberto	 * This is a client mode packet not matching any association. If
683182007Sroberto	 * an ordinary client, simply toss a server mode packet back
684182007Sroberto	 * over the fence. If a manycast client, we have to work a
685182007Sroberto	 * little harder.
686182007Sroberto	 */
68754359Sroberto	case AM_FXMIT:
68854359Sroberto
68956749Sroberto		/*
690182007Sroberto		 * The vanilla case is when this is not a multicast
691182007Sroberto		 * interface. If authentication succeeds, return a
692182007Sroberto		 * server mode packet; if not and the key ID is nonzero,
693182007Sroberto		 * return a crypto-NAK.
69456749Sroberto		 */
695182007Sroberto		if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) {
696182007Sroberto			if (AUTH(restrict_mask & RES_DONTTRUST,
697182007Sroberto			   is_authentic))
698182007Sroberto				fast_xmit(rbufp, MODE_SERVER, skeyid,
699182007Sroberto				    restrict_mask);
700182007Sroberto			else if (is_authentic == AUTH_ERROR)
701182007Sroberto				fast_xmit(rbufp, MODE_SERVER, 0,
702182007Sroberto				    restrict_mask);
703182007Sroberto			return;			/* hooray */
70456749Sroberto		}
70554359Sroberto
70656749Sroberto		/*
707182007Sroberto		 * This must be manycast. Do not respond if not
708182007Sroberto		 * configured as a manycast server.
70956749Sroberto		 */
710182007Sroberto		if (!sys_manycastserver) {
711182007Sroberto			sys_restricted++;
712182007Sroberto			return;			/* not enabled */
713182007Sroberto		}
714182007Sroberto
715182007Sroberto		/*
716182007Sroberto		 * Do not respond if unsynchronized or stratum is below
717182007Sroberto		 * the floor or at or above the ceiling.
718182007Sroberto		 */
719182007Sroberto		if (sys_leap == LEAP_NOTINSYNC || sys_stratum <
720182007Sroberto		    sys_floor || sys_stratum >= sys_ceiling)
721182007Sroberto			return;			/* bad stratum */
722182007Sroberto
723182007Sroberto		/*
724182007Sroberto		 * Do not respond if our stratum is greater than the
725182007Sroberto		 * manycaster or it has already synchronized to us.
726182007Sroberto		 */
727182007Sroberto		if (sys_peer == NULL || hisstratum < sys_stratum ||
728182007Sroberto		    (sys_cohort && hisstratum == sys_stratum) ||
729182007Sroberto		    rbufp->dstadr->addr_refid == pkt->refid)
730182007Sroberto			return;			/* no help */
731182007Sroberto
732182007Sroberto		/*
733182007Sroberto		 * Respond only if authentication succeeds. Don't do a
734182007Sroberto		 * crypto-NAK, as that would not be useful.
735182007Sroberto		 */
736182007Sroberto		if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic))
73782505Sroberto			fast_xmit(rbufp, MODE_SERVER, skeyid,
73882505Sroberto			    restrict_mask);
73956749Sroberto
740182007Sroberto		return;				/* hooray */
741182007Sroberto
742182007Sroberto	/*
743182007Sroberto	 * This is a server mode packet returned in response to a client
744182007Sroberto	 * mode packet sent to a multicast group address. The origin
745182007Sroberto	 * timestamp is a good nonce to reliably associate the reply
746182007Sroberto	 * with what was sent. If there is no match, that's curious and
747182007Sroberto	 * could be an intruder attempting to clog, so we just ignore
748182007Sroberto	 * it.
749182007Sroberto	 *
750182007Sroberto	 * If the packet is authentic and the manycast association is
751182007Sroberto	 * found, we mobilize a client association and copy pertinent
752182007Sroberto	 * variables from the manycast association to the new client
753182007Sroberto	 * association. If not, just ignore the packet.
754182007Sroberto	 *
755182007Sroberto	 * There is an implosion hazard at the manycast client, since
756182007Sroberto	 * the manycast servers send the server packet immediately. If
757182007Sroberto	 * the guy is already here, don't fire up a duplicate.
758182007Sroberto	 */
75954359Sroberto	case AM_MANYCAST:
760182007Sroberto		if (!AUTH(sys_authenticate | (restrict_mask &
761182007Sroberto		    (RES_NOPEER | RES_DONTTRUST)), is_authentic))
762182007Sroberto			return;			/* bad auth */
76354359Sroberto
764182007Sroberto		if ((peer2 = findmanycastpeer(rbufp)) == NULL) {
765132454Sroberto			sys_restricted++;
766182007Sroberto			return;			/* not enabled */
767132454Sroberto		}
768182007Sroberto		if ((peer = newpeer(&rbufp->recv_srcadr,
769182007Sroberto		    rbufp->dstadr, MODE_CLIENT,
770182007Sroberto		    hisversion, NTP_MINDPOLL, NTP_MAXDPOLL,
771182007Sroberto		    FLAG_IBURST | FLAG_PREEMPT, MDF_UCAST | MDF_ACLNT,
772182007Sroberto		    0, skeyid)) == NULL)
773132454Sroberto			return;			/* system error */
774132454Sroberto
775132454Sroberto		/*
776132454Sroberto		 * We don't need these, but it warms the billboards.
777132454Sroberto		 */
778132454Sroberto		peer->ttl = peer2->ttl;
77956749Sroberto		break;
78056749Sroberto
781182007Sroberto	/*
782182007Sroberto	 * This is the first packet received from a broadcast server. If
783182007Sroberto	 * the packet is authentic and we are enabled as broadcast
784182007Sroberto	 * client, mobilize a broadcast client association. We don't
785182007Sroberto	 * kiss any frogs here.
786182007Sroberto	 */
787182007Sroberto	case AM_NEWBCL:
788182007Sroberto		if (!AUTH(sys_authenticate | (restrict_mask &
789182007Sroberto		    (RES_NOPEER | RES_DONTTRUST)), is_authentic))
790182007Sroberto			return;			/* bad auth */
79154359Sroberto
79256749Sroberto		/*
793182007Sroberto		 * Do not respond if unsynchronized or stratum is below
794182007Sroberto		 * the floor or at or above the ceiling.
79556749Sroberto		 */
796182007Sroberto		if (hisleap == LEAP_NOTINSYNC || hisstratum <
797182007Sroberto		    sys_floor || hisstratum >= sys_ceiling)
798182007Sroberto			return;			/* bad stratum */
799132454Sroberto
800182007Sroberto		switch (sys_bclient) {
80156749Sroberto
80256749Sroberto		/*
803182007Sroberto		 * If not enabled, just skedaddle.
80456749Sroberto		 */
805182007Sroberto		case 0:
806132454Sroberto			sys_restricted++;
807182007Sroberto			return;			/* not enabled */
80882505Sroberto
809132454Sroberto		/*
810182007Sroberto		 * Execute the initial volley in order to calibrate the
811182007Sroberto		 * propagation delay and run the Autokey protocol, if
812182007Sroberto		 * enabled.
813132454Sroberto		 */
814182007Sroberto		case 1:
815182007Sroberto			if ((peer = newpeer(&rbufp->recv_srcadr,
816182007Sroberto			    rbufp->dstadr, MODE_CLIENT, hisversion,
817182007Sroberto			    NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_MCAST |
818182007Sroberto			    FLAG_IBURST, MDF_BCLNT, 0, skeyid)) ==
819182007Sroberto			    NULL)
820182007Sroberto				return;		/* system error */
821182007Sroberto#ifdef OPENSSL
822182007Sroberto			if (skeyid > NTP_MAXKEY)
823182007Sroberto				crypto_recv(peer, rbufp);
824132454Sroberto#endif /* OPENSSL */
825182007Sroberto			return;			/* hooray */
82656749Sroberto
827132454Sroberto
828132454Sroberto		/*
829182007Sroberto		 * Do not execute the initial volley.
83056749Sroberto		 */
831182007Sroberto		case 2:
832182007Sroberto#ifdef OPENSSL
833182007Sroberto			/*
834182007Sroberto			 * If a two-way exchange is not possible,
835182007Sroberto			 * neither is Autokey.
836182007Sroberto			 */
837182007Sroberto			if (skeyid > NTP_MAXKEY) {
838182007Sroberto				msyslog(LOG_INFO,
839182007Sroberto				    "receive: autokey requires two-way communication");
840182007Sroberto				return;		/* no autokey */
841182007Sroberto			}
842182007Sroberto#endif /* OPENSSL */
843182007Sroberto			if ((peer = newpeer(&rbufp->recv_srcadr,
844182007Sroberto			    rbufp->dstadr, MODE_BCLIENT, hisversion,
845182007Sroberto			    NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_BCLNT, 0,
846182007Sroberto			    skeyid)) == NULL)
847182007Sroberto				return;		/* system error */
848132454Sroberto		}
84956749Sroberto		break;
85056749Sroberto
851182007Sroberto	/*
852182007Sroberto	 * This is the first packet received from a symmetric active
853182007Sroberto	 * peer. If the packet is authentic and the first he sent,
854182007Sroberto	 * mobilize a passive association. If not, kiss the frog.
855182007Sroberto	 */
856182007Sroberto	case AM_NEWPASS:
85756749Sroberto
85856749Sroberto		/*
859182007Sroberto		 * If the inbound packet is correctly authenticated and
860182007Sroberto		 * enabled, a symmetric passive association is
861182007Sroberto		 * mobilized. If not but correctly authenticated, a
862182007Sroberto		 * symmetric active response is sent. If authentication
863182007Sroberto		 * fails, send a crypto-NAK packet.
86456749Sroberto		 */
865182007Sroberto		if (!AUTH(restrict_mask & RES_DONTTRUST, is_authentic))
866182007Sroberto		    {
867182007Sroberto			if (is_authentic == AUTH_ERROR)
868182007Sroberto				fast_xmit(rbufp, MODE_ACTIVE, 0,
869182007Sroberto				    restrict_mask);
870182007Sroberto			return;			/* bad auth */
871182007Sroberto		}
872182007Sroberto		if (!AUTH(sys_authenticate | (restrict_mask &
873182007Sroberto		    RES_NOPEER), is_authentic)) {
874182007Sroberto			fast_xmit(rbufp, MODE_ACTIVE, skeyid,
875182007Sroberto			    restrict_mask);
876182007Sroberto			return;			/* hooray */
877182007Sroberto		}
87854359Sroberto
879182007Sroberto		/*
880182007Sroberto		 * Do not respond if stratum is below the floor.
881182007Sroberto		 */
882182007Sroberto		if (hisstratum < sys_floor)
883182007Sroberto			return;			/* bad stratum */
884182007Sroberto
885182007Sroberto		if ((peer = newpeer(&rbufp->recv_srcadr,
886182007Sroberto		    rbufp->dstadr, MODE_PASSIVE, hisversion,
887182007Sroberto		    NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0,
888182007Sroberto		    skeyid)) == NULL)
889182007Sroberto			return;			/* system error */
890182007Sroberto		break;
891182007Sroberto
89254359Sroberto	/*
893182007Sroberto	 * Process regular packet. Nothing special.
89454359Sroberto	 */
895182007Sroberto	case AM_PROCPKT:
896182007Sroberto		break;
89754359Sroberto
89854359Sroberto	/*
899182007Sroberto	 * A passive packet matches a passive association. This is
900182007Sroberto	 * usually the result of reconfiguring a client on the fly. As
901182007Sroberto	 * this association might be legitamate and this packet an
902182007Sroberto	 * attempt to deny service, just ignore it.
90354359Sroberto	 */
904182007Sroberto	case AM_ERR:
905182007Sroberto		return;
906132454Sroberto
907132454Sroberto	/*
908182007Sroberto	 * For everything else there is the bit bucket.
909132454Sroberto	 */
910182007Sroberto	default:
911182007Sroberto		return;
912182007Sroberto	}
913182007Sroberto	peer->flash &= ~PKT_TEST_MASK;
914132454Sroberto
915132454Sroberto	/*
916182007Sroberto	 * Next comes a rigorous schedule of timestamp checking. If the
917182007Sroberto	 * transmit timestamp is zero, the server is horribly broken.
918132454Sroberto	 */
919182007Sroberto	if (L_ISZERO(&p_xmt)) {
920182007Sroberto		return;				/* read rfc1305 */
921132454Sroberto
922132454Sroberto	/*
923182007Sroberto	 * If the transmit timestamp duplicates a previous one, the
924182007Sroberto	 * packet is a replay. This prevents the bad guys from replaying
925182007Sroberto	 * the most recent packet, authenticated or not.
926132454Sroberto	 */
927182007Sroberto	} else if (L_ISEQU(&peer->org, &p_xmt)) {
928182007Sroberto		peer->flash |= TEST1;
929182007Sroberto		peer->oldpkt++;
930182007Sroberto		return;				/* duplicate packet */
931182007Sroberto
932132454Sroberto
933132454Sroberto	/*
934182007Sroberto	 * If this is a broadcast mode packet, skip further checking.
935132454Sroberto	 */
936182007Sroberto	} else if (hismode != MODE_BROADCAST) {
937182007Sroberto		if (L_ISZERO(&p_org))
938182007Sroberto			peer->flash |= TEST3;	/* protocol unsynch */
939182007Sroberto		else if (!L_ISEQU(&p_org, &peer->xmt))
940182007Sroberto			peer->flash |= TEST2;	/* bogus packet */
941182007Sroberto	}
942132454Sroberto
943132454Sroberto	/*
944182007Sroberto	 * Update the origin and destination timestamps. If
945182007Sroberto	 * unsynchronized or bogus abandon ship. If the crypto machine
946182007Sroberto	 * breaks, light the crypto bit and plaint the log.
947132454Sroberto	 */
948182007Sroberto	peer->org = p_xmt;
949182007Sroberto	peer->rec = rbufp->recv_time;
950182007Sroberto	if (peer->flash & PKT_TEST_MASK) {
951182007Sroberto#ifdef OPENSSL
952182007Sroberto		if (crypto_flags && (peer->flags & FLAG_SKEY)) {
953182007Sroberto			rval = crypto_recv(peer, rbufp);
954182007Sroberto			if (rval != XEVNT_OK) {
955182007Sroberto				peer_clear(peer, "CRYP");
956182007Sroberto				peer->flash |= TEST9; /* crypto error */
957182007Sroberto			}
958182007Sroberto		}
959182007Sroberto#endif /* OPENSSL */
960182007Sroberto		return;				/* unsynch */
961182007Sroberto	}
962132454Sroberto
963132454Sroberto	/*
964182007Sroberto	 * The timestamps are valid and the receive packet matches the
965182007Sroberto	 * last one sent. If the packet is a crypto-NAK, the server
966182007Sroberto	 * might have just changed keys. We reset the association
967182007Sroberto	 * and restart the protocol.
968132454Sroberto	 */
969182007Sroberto	if (is_authentic == AUTH_CRYPTO) {
970182007Sroberto		peer_clear(peer, "AUTH");
971182007Sroberto		return;				/* crypto-NAK */
972182007Sroberto
973182007Sroberto	/*
974182007Sroberto	 * If the association is authenticated, the key ID is nonzero
975182007Sroberto	 * and received packets must be authenticated. This is designed
976182007Sroberto	 * to avoid a bait-and-switch attack, which was possible in past
977182007Sroberto	 * versions. If symmetric modes, return a crypto-NAK. The peer
978182007Sroberto	 * should restart the protocol.
979182007Sroberto	 */
980182007Sroberto	} else if (!AUTH(peer->keyid || (restrict_mask & RES_DONTTRUST),
981182007Sroberto	    is_authentic)) {
982182007Sroberto		peer->flash |= TEST5;
983182007Sroberto		if (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE)
984132454Sroberto			fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask);
985182007Sroberto		return;				/* bad auth */
98654359Sroberto	}
98754359Sroberto
988182007Sroberto	/*
989182007Sroberto	 * That was hard and I am sweaty, but the packet is squeaky
990182007Sroberto	 * clean. Get on with real work.
991182007Sroberto	 */
992182007Sroberto	peer->received++;
993182007Sroberto	peer->timereceived = current_time;
994182007Sroberto	if (is_authentic == AUTH_OK)
995182007Sroberto		peer->flags |= FLAG_AUTHENTIC;
996182007Sroberto	else
997182007Sroberto		peer->flags &= ~FLAG_AUTHENTIC;
998132454Sroberto#ifdef OPENSSL
99954359Sroberto	/*
100082505Sroberto	 * More autokey dance. The rules of the cha-cha are as follows:
100182505Sroberto	 *
100282505Sroberto	 * 1. If there is no key or the key is not auto, do nothing.
100382505Sroberto	 *
1004132454Sroberto	 * 2. If this packet is in response to the one just previously
1005132454Sroberto	 *    sent or from a broadcast server, do the extension fields.
1006132454Sroberto	 *    Otherwise, assume bogosity and bail out.
1007132454Sroberto	 *
1008132454Sroberto	 * 3. If an extension field contains a verified signature, it is
100982505Sroberto	 *    self-authenticated and we sit the dance.
101082505Sroberto	 *
1011132454Sroberto	 * 4. If this is a server reply, check only to see that the
101282505Sroberto	 *    transmitted key ID matches the received key ID.
101382505Sroberto	 *
1014132454Sroberto	 * 5. Check to see that one or more hashes of the current key ID
101582505Sroberto	 *    matches the previous key ID or ultimate original key ID
101682505Sroberto	 *    obtained from the broadcaster or symmetric peer. If no
101782505Sroberto	 *    match, sit the dance and wait for timeout.
1018182007Sroberto	 *
1019182007Sroberto	 * In case of crypto error, fire the orchestra and stop dancing.
1020182007Sroberto	 * This is considered a permanant error, so light the crypto bit
1021182007Sroberto	 * to suppress further requests. If preemptable or ephemeral,
1022182007Sroberto	 * scuttle the ship.
102354359Sroberto	 */
1024132454Sroberto	if (crypto_flags && (peer->flags & FLAG_SKEY)) {
1025182007Sroberto		peer->flash |= TEST8;
1026132454Sroberto		rval = crypto_recv(peer, rbufp);
1027132454Sroberto		if (rval != XEVNT_OK) {
1028182007Sroberto			peer_clear(peer, "CRYP");
1029182007Sroberto			peer->flash |= TEST9;	/* crypto error */
1030182007Sroberto			if (peer->flags & FLAG_PREEMPT ||
1031182007Sroberto			    !(peer->flags & FLAG_CONFIG))
1032182007Sroberto				unpeer(peer);
1033182007Sroberto			return;
1034132454Sroberto
1035132454Sroberto		} else if (hismode == MODE_SERVER) {
103682505Sroberto			if (skeyid == peer->keyid)
1037182007Sroberto				peer->flash &= ~TEST8;
1038182007Sroberto		} else if (!(peer->flash & TEST8)) {
103982505Sroberto			peer->pkeyid = skeyid;
1040132454Sroberto		} else if ((ap = (struct autokey *)peer->recval.ptr) !=
1041132454Sroberto		    NULL) {
104282505Sroberto			int i;
104382505Sroberto
104482505Sroberto			for (i = 0; ; i++) {
104582505Sroberto				if (tkeyid == peer->pkeyid ||
1046132454Sroberto				    tkeyid == ap->key) {
1047182007Sroberto					peer->flash &= ~TEST8;
104882505Sroberto					peer->pkeyid = skeyid;
104982505Sroberto					break;
105082505Sroberto				}
1051132454Sroberto				if (i > ap->seq)
105282505Sroberto					break;
105354359Sroberto				tkeyid = session_key(
105482505Sroberto				    &rbufp->recv_srcadr, dstadr_sin,
105582505Sroberto				    tkeyid, pkeyid, 0);
105654359Sroberto			}
105754359Sroberto		}
1058182007Sroberto		if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */
1059182007Sroberto			peer->flash |= TEST8;	/* not proventic */
106082505Sroberto
106182505Sroberto		/*
1062132454Sroberto		 * If the transmit queue is nonempty, clamp the host
1063132454Sroberto		 * poll interval to the packet poll interval.
106482505Sroberto		 */
1065132454Sroberto		if (peer->cmmd != 0) {
1066132454Sroberto			peer->ppoll = pkt->ppoll;
1067182007Sroberto			poll_update(peer, peer->hpoll);
1068132454Sroberto		}
106954359Sroberto	}
1070132454Sroberto#endif /* OPENSSL */
107154359Sroberto
107254359Sroberto	/*
1073182007Sroberto	 * The dance is complete and the flash bits have been lit. Toss
1074182007Sroberto	 * the packet over the fence for processing, which may light up
1075182007Sroberto	 * more flashers.
107654359Sroberto	 */
1077182007Sroberto	process_packet(peer, pkt);
1078182007Sroberto
1079182007Sroberto	/*
1080182007Sroberto	 * Well, that was nice. If TEST4 is lit, either the crypto
1081182007Sroberto	 * machine jammed or a kiss-o'-death packet flew in, either of
1082182007Sroberto	 * which is fatal.
1083182007Sroberto	 */
1084182007Sroberto	if (peer->flash & TEST4) {
1085182007Sroberto		msyslog(LOG_INFO, "receive: fatal error %04x for %s",
1086182007Sroberto		    peer->flash, stoa(&peer->srcadr));
1087182007Sroberto		return;
1088182007Sroberto	}
108954359Sroberto}
109054359Sroberto
109154359Sroberto
109254359Sroberto/*
109354359Sroberto * process_packet - Packet Procedure, a la Section 3.4.4 of the
109454359Sroberto *	specification. Or almost, at least. If we're in here we have a
109554359Sroberto *	reasonable expectation that we will be having a long term
109654359Sroberto *	relationship with this host.
109754359Sroberto */
109882505Srobertovoid
109954359Srobertoprocess_packet(
110054359Sroberto	register struct peer *peer,
1101182007Sroberto	register struct pkt *pkt
110254359Sroberto	)
110354359Sroberto{
1104182007Sroberto	double	t34, t21;
1105132454Sroberto	double	p_offset, p_del, p_disp;
1106132454Sroberto	l_fp	p_rec, p_xmt, p_org, p_reftime;
1107132454Sroberto	l_fp	ci;
1108132454Sroberto	u_char	pmode, pleap, pstratum;
110954359Sroberto
111054359Sroberto	sys_processed++;
111154359Sroberto	peer->processed++;
111254359Sroberto	p_del = FPTOD(NTOHS_FP(pkt->rootdelay));
111354359Sroberto	p_disp = FPTOD(NTOHS_FP(pkt->rootdispersion));
111454359Sroberto	NTOHL_FP(&pkt->reftime, &p_reftime);
111554359Sroberto	NTOHL_FP(&pkt->rec, &p_rec);
111654359Sroberto	NTOHL_FP(&pkt->xmt, &p_xmt);
1117132454Sroberto	pmode = PKT_MODE(pkt->li_vn_mode);
1118132454Sroberto	pleap = PKT_LEAP(pkt->li_vn_mode);
1119132454Sroberto	if (pmode != MODE_BROADCAST)
112054359Sroberto		NTOHL_FP(&pkt->org, &p_org);
112154359Sroberto	else
112254359Sroberto		p_org = peer->rec;
1123132454Sroberto	pstratum = PKT_TO_STRATUM(pkt->stratum);
112454359Sroberto
112554359Sroberto	/*
1126182007Sroberto	 * Test for kiss-o'death packet)
112754359Sroberto	 */
1128182007Sroberto	if (pleap == LEAP_NOTINSYNC && pstratum == STRATUM_UNSPEC) {
1129182007Sroberto		if (memcmp(&pkt->refid, "DENY", 4) == 0) {
1130182007Sroberto			peer_clear(peer, "DENY");
1131182007Sroberto			peer->flash |= TEST4;	/* access denied */
1132182007Sroberto		}
1133182007Sroberto	}
113454359Sroberto
113554359Sroberto	/*
1136182007Sroberto	 * Capture the header values.
113754359Sroberto	 */
1138182007Sroberto	record_raw_stats(&peer->srcadr, peer->dstadr ? &peer->dstadr->sin : NULL, &p_org,
1139182007Sroberto	    &p_rec, &p_xmt, &peer->rec);
1140132454Sroberto	peer->leap = pleap;
1141182007Sroberto	peer->stratum = min(pstratum, STRATUM_UNSPEC);
1142182007Sroberto	peer->pmode = pmode;
1143182007Sroberto	peer->ppoll = pkt->ppoll;
1144182007Sroberto	peer->precision = pkt->precision;
1145182007Sroberto	peer->rootdelay = p_del;
1146182007Sroberto	peer->rootdispersion = p_disp;
1147182007Sroberto	peer->refid = pkt->refid;		/* network byte order */
1148182007Sroberto	peer->reftime = p_reftime;
114982505Sroberto
115082505Sroberto	/*
1151182007Sroberto	 * Verify the server is synchronized; that is, the leap bits and
1152182007Sroberto	 * stratum are valid, the root delay and root dispersion are
1153182007Sroberto	 * valid and the reference timestamp is not later than the
1154182007Sroberto	 * transmit timestamp.
115582505Sroberto	 */
1156132454Sroberto	if (pleap == LEAP_NOTINSYNC ||		/* test 6 */
1157182007Sroberto	    pstratum < sys_floor || pstratum >= sys_ceiling)
1158182007Sroberto		peer->flash |= TEST6;		/* peer not synch */
1159182007Sroberto	if (p_del < 0 || p_disp < 0 || p_del /	/* test 7 */
1160182007Sroberto	    2 + p_disp >= MAXDISPERSE || !L_ISHIS(&p_xmt, &p_reftime))
1161182007Sroberto		peer->flash |= TEST7;		/* bad header */
1162132454Sroberto
1163132454Sroberto	/*
1164132454Sroberto	 * If any tests fail at this point, the packet is discarded.
1165182007Sroberto	 * Note that some flashers may have already been set in the
1166182007Sroberto	 * receive() routine.
1167132454Sroberto	 */
1168182007Sroberto	if (peer->flash & PKT_TEST_MASK) {
116954359Sroberto#ifdef DEBUG
117054359Sroberto		if (debug)
1171182007Sroberto			printf("packet: flash header %04x\n",
117282505Sroberto			    peer->flash);
117354359Sroberto#endif
117482505Sroberto		return;
117554359Sroberto	}
117682505Sroberto	if (!(peer->reach)) {
117754359Sroberto		report_event(EVNT_REACH, peer);
117854359Sroberto		peer->timereachable = current_time;
117954359Sroberto	}
1180182007Sroberto	poll_update(peer, peer->hpoll);
118154359Sroberto	peer->reach |= 1;
118254359Sroberto
118354359Sroberto	/*
1184182007Sroberto	 * For a client/server association, calculate the clock offset,
1185182007Sroberto	 * roundtrip delay and dispersion. The equations are reordered
1186182007Sroberto	 * from the spec for more efficient use of temporaries. For a
1187182007Sroberto	 * broadcast association, offset the last measurement by the
1188182007Sroberto	 * computed delay during the client/server volley. Note that
1189182007Sroberto	 * org has been set to the time of last reception. Note the
1190182007Sroberto	 * computation of dispersion includes the system precision plus
1191182007Sroberto	 * that due to the frequency error since the origin time.
119254359Sroberto	 *
1193182007Sroberto	 * It is very important to respect the hazards of overflow. The
1194182007Sroberto	 * only permitted operation on raw timestamps is subtraction,
1195182007Sroberto	 * where the result is a signed quantity spanning from 68 years
1196182007Sroberto	 * in the past to 68 years in the future. To avoid loss of
1197182007Sroberto	 * precision, these calculations are done using 64-bit integer
1198182007Sroberto	 * arithmetic. However, the offset and delay calculations are
1199182007Sroberto	 * sums and differences of these first-order differences, which
1200182007Sroberto	 * if done using 64-bit integer arithmetic, would be valid over
1201182007Sroberto	 * only half that span. Since the typical first-order
1202182007Sroberto	 * differences are usually very small, they are converted to 64-
1203182007Sroberto	 * bit doubles and all remaining calculations done in floating-
1204182007Sroberto	 * point arithmetic. This preserves the accuracy while retaining
1205182007Sroberto	 * the 68-year span.
1206182007Sroberto	 *
1207132454Sroberto	 * Let t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->rec:
120854359Sroberto	 */
1209182007Sroberto	ci = p_xmt;			/* t3 - t4 */
1210182007Sroberto	L_SUB(&ci, &peer->rec);
1211182007Sroberto	LFPTOD(&ci, t34);
1212182007Sroberto	ci = p_rec;			/* t2 - t1 */
1213182007Sroberto	L_SUB(&ci, &p_org);
1214182007Sroberto	LFPTOD(&ci, t21);
1215132454Sroberto	ci = peer->rec;			/* t4 - t1 */
1216132454Sroberto	L_SUB(&ci, &p_org);
121754359Sroberto
121854359Sroberto	/*
121956749Sroberto	 * If running in a broadcast association, the clock offset is
122056749Sroberto	 * (t1 - t0) corrected by the one-way delay, but we can't
122182505Sroberto	 * measure that directly. Therefore, we start up in MODE_CLIENT
122282505Sroberto	 * mode, set FLAG_MCAST and exchange eight messages to determine
122382505Sroberto	 * the clock offset. When the last message is sent, we switch to
122482505Sroberto	 * MODE_BCLIENT mode. The next broadcast message after that
122582505Sroberto	 * computes the broadcast offset and clears FLAG_MCAST.
122654359Sroberto	 */
122754359Sroberto	if (pmode == MODE_BROADCAST) {
1228182007Sroberto		p_offset = t34;
122982505Sroberto		if (peer->flags & FLAG_MCAST) {
123054359Sroberto			peer->estbdelay = peer->offset - p_offset;
123182505Sroberto			if (peer->hmode == MODE_CLIENT)
123282505Sroberto				return;
123354359Sroberto
1234182007Sroberto			peer->flags &= ~(FLAG_MCAST | FLAG_BURST);
123554359Sroberto		}
1236182007Sroberto		p_offset += peer->estbdelay;
123754359Sroberto		p_del = peer->delay;
1238182007Sroberto		p_disp = 0;
123954359Sroberto	} else {
1240182007Sroberto		p_offset = (t21 + t34) / 2.;
1241182007Sroberto		p_del = t21 - t34;
1242182007Sroberto		LFPTOD(&ci, p_disp);
1243182007Sroberto		p_disp = LOGTOD(sys_precision) +
1244182007Sroberto		    LOGTOD(peer->precision) + clock_phi * p_disp;
124554359Sroberto	}
124682505Sroberto	p_del = max(p_del, LOGTOD(sys_precision));
124782505Sroberto	clock_filter(peer, p_offset, p_del, p_disp);
124854359Sroberto	record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
1249182007Sroberto	    peer->offset, peer->delay, peer->disp, peer->jitter);
125054359Sroberto}
125154359Sroberto
125254359Sroberto
125354359Sroberto/*
125454359Sroberto * clock_update - Called at system process update intervals.
125554359Sroberto */
125654359Srobertostatic void
125754359Srobertoclock_update(void)
125854359Sroberto{
1259182007Sroberto	u_char	oleap;
1260182007Sroberto	u_char	ostratum;
1261182007Sroberto	double	dtemp;
126254359Sroberto
126354359Sroberto	/*
1264182007Sroberto	 * There must be a system peer at this point. If we just changed
1265182007Sroberto	 * the system peer, but have a newer sample from the old one,
1266182007Sroberto	 * wait until newer data are available.
126754359Sroberto	 */
1268182007Sroberto	if (sys_poll < sys_peer->minpoll)
1269182007Sroberto		sys_poll = sys_peer->minpoll;
1270182007Sroberto	if (sys_poll > sys_peer->maxpoll)
1271182007Sroberto		sys_poll = sys_peer->maxpoll;
1272182007Sroberto	poll_update(sys_peer, sys_poll);
1273182007Sroberto	if (sys_peer->epoch <= sys_clocktime)
127454359Sroberto		return;
1275182007Sroberto
127654359Sroberto#ifdef DEBUG
127754359Sroberto	if (debug)
127854359Sroberto		printf("clock_update: at %ld assoc %d \n", current_time,
127954359Sroberto		    peer_associations);
128054359Sroberto#endif
128154359Sroberto	oleap = sys_leap;
128254359Sroberto	ostratum = sys_stratum;
1283182007Sroberto	switch (local_clock(sys_peer, sys_offset)) {
128454359Sroberto
128582505Sroberto	/*
1286182007Sroberto	 * Clock exceeds panic threshold. Life as we know it ends.
128782505Sroberto	 */
128882505Sroberto	case -1:
1289132454Sroberto		report_event(EVNT_SYSFAULT, NULL);
1290132454Sroberto		exit (-1);
1291182007Sroberto		/* not reached */
129254359Sroberto
129382505Sroberto	/*
129482505Sroberto	 * Clock was stepped. Flush all time values of all peers.
129582505Sroberto	 */
1296182007Sroberto	case 2:
129782505Sroberto		clear_all();
1298182007Sroberto		sys_leap = LEAP_NOTINSYNC;
1299182007Sroberto		sys_stratum = STRATUM_UNSPEC;
130082505Sroberto		sys_peer = NULL;
1301182007Sroberto		sys_rootdelay = 0;
1302182007Sroberto		sys_rootdispersion = 0;
1303182007Sroberto		memcpy(&sys_refid, "STEP", 4);
1304132454Sroberto		report_event(EVNT_CLOCKRESET, NULL);
130554359Sroberto		break;
130654359Sroberto
130782505Sroberto	/*
1308182007Sroberto	 * Clock was slewed. Update the system stratum, leap bits, root
1309182007Sroberto	 * delay, root dispersion, reference ID and reference time. If
1310182007Sroberto	 * the leap changes, we gotta reroll the keys. Except for
1311182007Sroberto	 * reference clocks, the minimum dispersion increment is not
1312182007Sroberto	 * less than sys_mindisp.
131382505Sroberto	 */
1314182007Sroberto	case 1:
1315182007Sroberto		sys_leap = leap_next;
1316182007Sroberto		sys_stratum = min(sys_peer->stratum + 1,
1317182007Sroberto		    STRATUM_UNSPEC);
131854359Sroberto		sys_reftime = sys_peer->rec;
1319182007Sroberto
1320182007Sroberto		/*
1321182007Sroberto		 * In orphan mode the stratum defaults to the orphan
1322182007Sroberto		 * stratum. The root delay is set to a random value
1323182007Sroberto		 * generated at startup. The root dispersion is set from
1324182007Sroberto		 * the peer dispersion; the peer root dispersion is
1325182007Sroberto		 * ignored.
1326182007Sroberto		 */
1327182007Sroberto		dtemp = sys_peer->disp + clock_phi * (current_time -
1328182007Sroberto		    sys_peer->update) + sys_jitter +
1329182007Sroberto		    fabs(sys_peer->offset);
1330182007Sroberto#ifdef REFCLOCK
1331182007Sroberto		if (!(sys_peer->flags & FLAG_REFCLOCK) && dtemp <
1332182007Sroberto		    sys_mindisp)
1333182007Sroberto			dtemp = sys_mindisp;
1334182007Sroberto#else
1335182007Sroberto		if (dtemp < sys_mindisp)
1336182007Sroberto			dtemp = sys_mindisp;
1337182007Sroberto#endif /* REFCLOCK */
1338182007Sroberto		if (sys_stratum >= sys_orphan) {
1339182007Sroberto			sys_stratum = sys_orphan;
1340182007Sroberto			sys_rootdelay = sys_peer->delay;
1341182007Sroberto			sys_rootdispersion = dtemp;
1342182007Sroberto		} else {
1343182007Sroberto			sys_rootdelay = sys_peer->delay +
1344182007Sroberto			    sys_peer->rootdelay;
1345182007Sroberto			sys_rootdispersion = dtemp +
1346182007Sroberto			    sys_peer->rootdispersion;
1347182007Sroberto		}
1348132454Sroberto		if (oleap == LEAP_NOTINSYNC) {
1349132454Sroberto			report_event(EVNT_SYNCCHG, NULL);
1350132454Sroberto#ifdef OPENSSL
1351132454Sroberto			expire_all();
1352182007Sroberto			crypto_update();
1353132454Sroberto#endif /* OPENSSL */
1354132454Sroberto		}
1355182007Sroberto		break;
1356182007Sroberto	/*
1357182007Sroberto	 * Popcorn spike or step threshold exceeded. Pretend it never
1358182007Sroberto	 * happened.
1359182007Sroberto	 */
1360182007Sroberto	default:
1361182007Sroberto		break;
136254359Sroberto	}
136354359Sroberto	if (ostratum != sys_stratum)
1364132454Sroberto		report_event(EVNT_PEERSTCHG, NULL);
136554359Sroberto}
136654359Sroberto
136754359Sroberto
136854359Sroberto/*
136982505Sroberto * poll_update - update peer poll interval
137054359Sroberto */
137154359Srobertovoid
137254359Srobertopoll_update(
137354359Sroberto	struct peer *peer,
1374182007Sroberto	int	mpoll
137554359Sroberto	)
137654359Sroberto{
1377182007Sroberto	int	hpoll;
137854359Sroberto
137954359Sroberto	/*
1380182007Sroberto	 * This routine figures out when the next poll should be sent.
1381182007Sroberto	 * That turns out to be wickedly complicated. The big problem is
1382182007Sroberto	 * that sometimes the time for the next poll is in the past.
1383182007Sroberto	 * Watch out for races here between the receive process and the
1384182007Sroberto	 * poll process. The key assertion is that, if nextdate equals
1385182007Sroberto	 * current_time, the call is from the poll process; otherwise,
1386182007Sroberto	 * it is from the receive process.
1387182007Sroberto	 *
1388182007Sroberto	 * First, bracket the poll interval according to the type of
1389182007Sroberto	 * association and options. If a fixed interval is configured,
1390182007Sroberto	 * use minpoll. This primarily is for reference clocks, but
1391182007Sroberto	 * works for any association.
139254359Sroberto	 */
1393182007Sroberto	if (peer->flags & FLAG_FIXPOLL) {
1394182007Sroberto		hpoll = peer->minpoll;
1395182007Sroberto
1396182007Sroberto	/*
1397182007Sroberto	 * The ordinary case; clamp the poll interval between minpoll
1398182007Sroberto	 * and maxpoll.
1399182007Sroberto	 */
1400182007Sroberto	} else {
1401182007Sroberto		hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll);
1402182007Sroberto	}
1403132454Sroberto#ifdef OPENSSL
1404182007Sroberto	/*
1405182007Sroberto	 * Bit of crass arrogance at this point. If the poll interval
1406182007Sroberto	 * has changed and we have a keylist, the lifetimes in the
1407182007Sroberto	 * keylist are probably bogus. In this case purge the keylist
1408182007Sroberto	 * and regenerate it later.
1409182007Sroberto	 */
1410182007Sroberto	if (hpoll != peer->hpoll)
1411182007Sroberto		key_expire(peer);
1412132454Sroberto#endif /* OPENSSL */
1413182007Sroberto	peer->hpoll = hpoll;
141482505Sroberto
141582505Sroberto	/*
1416182007Sroberto	 * Now we figure out if there is an override. If during the
1417182007Sroberto	 * crypto protocol and a message is pending, make it wait not
1418182007Sroberto	 * more than two seconds.
141982505Sroberto	 */
1420132454Sroberto#ifdef OPENSSL
1421132454Sroberto	if (peer->cmmd != NULL && (sys_leap != LEAP_NOTINSYNC ||
1422132454Sroberto	    peer->crypto)) {
1423132454Sroberto		peer->nextdate = current_time + RESP_DELAY;
1424182007Sroberto
1425182007Sroberto	/*
1426182007Sroberto	 * If we get called from the receive routine while a burst is
1427182007Sroberto	 * pending, just slink away. If from the poll routine and a
1428182007Sroberto	 * reference clock or a pending crypto response, delay for one
1429182007Sroberto	 * second. If this is the first sent in a burst, wait for the
1430182007Sroberto	 * modem to come up. For others in the burst, delay two seconds.
1431182007Sroberto	 */
1432132454Sroberto	} else if (peer->burst > 0) {
1433132454Sroberto#else /* OPENSSL */
143454359Sroberto	if (peer->burst > 0) {
1435132454Sroberto#endif /* OPENSSL */
1436182007Sroberto		if (peer->nextdate != current_time)
143754359Sroberto			return;
143882505Sroberto#ifdef REFCLOCK
143982505Sroberto		else if (peer->flags & FLAG_REFCLOCK)
1440132454Sroberto			peer->nextdate += RESP_DELAY;
1441182007Sroberto#endif /* REFCLOCK */
1442132454Sroberto		else if (peer->flags & (FLAG_IBURST | FLAG_BURST) &&
1443132454Sroberto		    peer->burst == NTP_BURST)
1444132454Sroberto			peer->nextdate += sys_calldelay;
144554359Sroberto		else
1446132454Sroberto			peer->nextdate += BURST_DELAY;
1447182007Sroberto	/*
1448182007Sroberto	 * The ordinary case; use the minimum of the host and peer
1449182007Sroberto	 * intervals, but not less than minpoll. In other words,
1450182007Sroberto	 * oversampling is okay but understampling is evil.
1451182007Sroberto	 */
145254359Sroberto	} else {
1453182007Sroberto		peer->nextdate = peer->outdate +
1454182007Sroberto		    RANDPOLL(max(min(peer->ppoll, hpoll),
1455182007Sroberto		    peer->minpoll));
145654359Sroberto	}
1457182007Sroberto
145882505Sroberto	/*
1459182007Sroberto	 * If the time for the next poll has already happened, bring it
1460182007Sroberto	 * up to the next second after this one. This way the only way
1461182007Sroberto	 * to get nexdate == current time is from the poll routine.
146282505Sroberto	 */
1463182007Sroberto	if (peer->nextdate <= current_time)
1464182007Sroberto		peer->nextdate = current_time + 1;
146554359Sroberto#ifdef DEBUG
146654359Sroberto	if (debug > 1)
146782505Sroberto		printf("poll_update: at %lu %s flags %04x poll %d burst %d last %lu next %lu\n",
146882505Sroberto		    current_time, ntoa(&peer->srcadr), peer->flags,
1469182007Sroberto		    peer->hpoll, peer->burst, peer->outdate,
147082505Sroberto		    peer->nextdate);
147154359Sroberto#endif
147254359Sroberto}
147354359Sroberto
147454359Sroberto/*
1475182007Sroberto * peer_crypto_clear - discard crypto information
147654359Sroberto */
147754359Srobertovoid
1478182007Srobertopeer_crypto_clear(
1479182007Sroberto		  struct peer *peer
1480182007Sroberto		  )
148154359Sroberto{
148282505Sroberto	/*
148382505Sroberto	 * If cryptographic credentials have been acquired, toss them to
148482505Sroberto	 * Valhalla. Note that autokeys are ephemeral, in that they are
148582505Sroberto	 * tossed immediately upon use. Therefore, the keylist can be
148682505Sroberto	 * purged anytime without needing to preserve random keys. Note
148782505Sroberto	 * that, if the peer is purged, the cryptographic variables are
148882505Sroberto	 * purged, too. This makes it much harder to sneak in some
148982505Sroberto	 * unauthenticated data in the clock filter.
149082505Sroberto	 */
1491182007Sroberto	DPRINTF(1, ("peer_crypto_clear: at %ld next %ld assoc ID %d\n",
1492182007Sroberto		    current_time, peer->nextdate, peer->associd));
1493182007Sroberto
1494132454Sroberto#ifdef OPENSSL
1495182007Sroberto	peer->assoc = 0;
1496182007Sroberto	peer->crypto = 0;
1497182007Sroberto
1498132454Sroberto	if (peer->pkey != NULL)
1499132454Sroberto		EVP_PKEY_free(peer->pkey);
1500182007Sroberto	peer->pkey = NULL;
1501182007Sroberto
1502182007Sroberto	peer->digest = NULL;	/* XXX MEMLEAK? check whether this needs to be freed in any way - never was freed */
1503182007Sroberto
1504132454Sroberto	if (peer->subject != NULL)
1505132454Sroberto		free(peer->subject);
1506182007Sroberto	peer->subject = NULL;
1507182007Sroberto
1508132454Sroberto	if (peer->issuer != NULL)
1509132454Sroberto		free(peer->issuer);
1510182007Sroberto	peer->issuer = NULL;
1511182007Sroberto
1512182007Sroberto	peer->pkeyid = 0;
1513182007Sroberto
1514182007Sroberto	peer->pcookie = 0;
1515182007Sroberto
1516182007Sroberto	if (peer->ident_pkey != NULL)
1517182007Sroberto		EVP_PKEY_free(peer->ident_pkey);
1518182007Sroberto	peer->ident_pkey = NULL;
1519182007Sroberto
1520182007Sroberto	memset(&peer->fstamp, 0, sizeof(peer->fstamp));
1521182007Sroberto
1522132454Sroberto	if (peer->iffval != NULL)
1523132454Sroberto		BN_free(peer->iffval);
1524182007Sroberto	peer->iffval = NULL;
1525182007Sroberto
1526132454Sroberto	if (peer->grpkey != NULL)
1527132454Sroberto		BN_free(peer->grpkey);
1528182007Sroberto	peer->grpkey = NULL;
1529182007Sroberto
1530132454Sroberto	value_free(&peer->cookval);
1531132454Sroberto	value_free(&peer->recval);
1532182007Sroberto
1533182007Sroberto	if (peer->cmmd != NULL) {
1534182007Sroberto		free(peer->cmmd);
1535182007Sroberto		peer->cmmd = NULL;
1536182007Sroberto	}
1537182007Sroberto
1538182007Sroberto	key_expire(peer);
1539182007Sroberto
1540132454Sroberto	value_free(&peer->encrypt);
1541132454Sroberto#endif /* OPENSSL */
1542182007Sroberto}
154382505Sroberto
1544182007Sroberto/*
1545182007Sroberto * peer_clear - clear peer filter registers.  See Section 3.4.8 of the spec.
1546182007Sroberto */
1547182007Srobertovoid
1548182007Srobertopeer_clear(
1549182007Sroberto	struct peer *peer,		/* peer structure */
1550182007Sroberto	char	*ident			/* tally lights */
1551182007Sroberto	)
1552182007Sroberto{
1553182007Sroberto	int	i;
1554182007Sroberto
1555182007Sroberto	peer_crypto_clear(peer);
1556182007Sroberto
1557182007Sroberto	if (peer == sys_peer)
1558182007Sroberto		sys_peer = NULL;
1559182007Sroberto
156082505Sroberto	/*
1561132454Sroberto	 * Wipe the association clean and initialize the nonzero values.
156282505Sroberto	 */
1563132454Sroberto	memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO);
156454359Sroberto	peer->estbdelay = sys_bdelay;
156582505Sroberto	peer->ppoll = peer->maxpoll;
1566182007Sroberto	peer->hpoll = peer->minpoll;
1567182007Sroberto	peer->disp = MAXDISPERSE;
1568182007Sroberto	peer->jitter = LOGTOD(sys_precision);
1569182007Sroberto	for (i = 0; i < NTP_SHIFT; i++) {
1570182007Sroberto		peer->filter_order[i] = i;
1571182007Sroberto		peer->filter_disp[i] = MAXDISPERSE;
1572182007Sroberto	}
157382505Sroberto#ifdef REFCLOCK
157482505Sroberto	if (!(peer->flags & FLAG_REFCLOCK)) {
157582505Sroberto		peer->leap = LEAP_NOTINSYNC;
157682505Sroberto		peer->stratum = STRATUM_UNSPEC;
1577132454Sroberto		memcpy(&peer->refid, ident, 4);
157882505Sroberto	}
1579132454Sroberto#else
1580132454Sroberto	peer->leap = LEAP_NOTINSYNC;
1581132454Sroberto	peer->stratum = STRATUM_UNSPEC;
1582132454Sroberto	memcpy(&peer->refid, ident, 4);
1583182007Sroberto#endif /* REFCLOCK */
158454359Sroberto
158554359Sroberto	/*
1586182007Sroberto	 * During initialization use the association count to spread out
1587182007Sroberto	 * the polls at one-second intervals. Othersie, randomize over
1588182007Sroberto	 * the minimum poll interval in order to avoid broadcast
1589182007Sroberto	 * implosion.
159054359Sroberto	 */
1591132454Sroberto	peer->nextdate = peer->update = peer->outdate = current_time;
1592182007Sroberto	if (initializing)
1593182007Sroberto		peer->nextdate += peer_associations;
1594182007Sroberto	else if (peer->hmode == MODE_PASSIVE)
1595182007Sroberto		peer->nextdate += RESP_DELAY;
1596132454Sroberto	else
1597182007Sroberto		peer->nextdate += (ntp_random() & ((1 << NTP_MINDPOLL) -
1598182007Sroberto		    1));
1599182007Sroberto
1600182007Sroberto	DPRINTF(1, ("peer_clear: at %ld next %ld assoc ID %d refid %s\n",
1601182007Sroberto		    current_time, peer->nextdate, peer->associd, ident));
160254359Sroberto}
160354359Sroberto
160454359Sroberto
160554359Sroberto/*
160654359Sroberto * clock_filter - add incoming clock sample to filter register and run
160754359Sroberto *		  the filter procedure to find the best sample.
160854359Sroberto */
160954359Srobertovoid
161054359Srobertoclock_filter(
1611132454Sroberto	struct peer *peer,		/* peer structure pointer */
1612132454Sroberto	double	sample_offset,		/* clock offset */
1613132454Sroberto	double	sample_delay,		/* roundtrip delay */
1614132454Sroberto	double	sample_disp		/* dispersion */
161554359Sroberto	)
161654359Sroberto{
1617132454Sroberto	double	dst[NTP_SHIFT];		/* distance vector */
1618132454Sroberto	int	ord[NTP_SHIFT];		/* index vector */
1619132454Sroberto	int	i, j, k, m;
1620182007Sroberto	double	dtemp, etemp;
162154359Sroberto
162254359Sroberto	/*
162382505Sroberto	 * Shift the new sample into the register and discard the oldest
162482505Sroberto	 * one. The new offset and delay come directly from the
162582505Sroberto	 * timestamp calculations. The dispersion grows from the last
162682505Sroberto	 * outbound packet or reference clock update to the present time
162782505Sroberto	 * and increased by the sum of the peer precision and the system
162882505Sroberto	 * precision. The delay can sometimes swing negative due to
162982505Sroberto	 * frequency skew, so it is clamped non-negative.
163054359Sroberto	 */
163154359Sroberto	j = peer->filter_nextpt;
163282505Sroberto	peer->filter_offset[j] = sample_offset;
163382505Sroberto	peer->filter_delay[j] = max(0, sample_delay);
1634182007Sroberto	peer->filter_disp[j] = sample_disp;
1635182007Sroberto	peer->filter_epoch[j] = current_time;
1636182007Sroberto	j = (j + 1) % NTP_SHIFT;
1637182007Sroberto	peer->filter_nextpt = j;
163854359Sroberto
163954359Sroberto	/*
164082505Sroberto	 * Update dispersions since the last update and at the same
164182505Sroberto	 * time initialize the distance and index lists. The distance
164282505Sroberto	 * list uses a compound metric. If the sample is valid and
164382505Sroberto	 * younger than the minimum Allan intercept, use delay;
164482505Sroberto	 * otherwise, use biased dispersion.
164554359Sroberto	 */
164682505Sroberto	dtemp = clock_phi * (current_time - peer->update);
164782505Sroberto	peer->update = current_time;
164882505Sroberto	for (i = NTP_SHIFT - 1; i >= 0; i--) {
1649132454Sroberto		if (i != 0)
165082505Sroberto			peer->filter_disp[j] += dtemp;
1651132454Sroberto		if (peer->filter_disp[j] >= MAXDISPERSE)
1652132454Sroberto			peer->filter_disp[j] = MAXDISPERSE;
165382505Sroberto		if (peer->filter_disp[j] >= MAXDISPERSE)
165482505Sroberto			dst[i] = MAXDISPERSE;
165582505Sroberto		else if (peer->update - peer->filter_epoch[j] >
165682505Sroberto		    allan_xpt)
1657182007Sroberto			dst[i] = sys_maxdist + peer->filter_disp[j];
165882505Sroberto		else
1659132454Sroberto			dst[i] = peer->filter_delay[j];
166082505Sroberto		ord[i] = j;
166182505Sroberto		j++; j %= NTP_SHIFT;
166282505Sroberto	}
166354359Sroberto
166482505Sroberto        /*
1665182007Sroberto	 * If the clock discipline has stabilized, sort the samples in
1666182007Sroberto	 * both lists by distance. Note, we do not displace a higher
1667182007Sroberto	 * distance sample by a lower distance one unless lower by at
1668182007Sroberto	 * least the precision.
166954359Sroberto	 */
1670182007Sroberto	if (state == 4) {
1671182007Sroberto		for (i = 1; i < NTP_SHIFT; i++) {
1672182007Sroberto			for (j = 0; j < i; j++) {
1673182007Sroberto				if (dst[j] > dst[i] +
1674182007Sroberto				    LOGTOD(sys_precision)) {
1675182007Sroberto					k = ord[j];
1676182007Sroberto					ord[j] = ord[i];
1677182007Sroberto					ord[i] = k;
1678182007Sroberto					etemp = dst[j];
1679182007Sroberto					dst[j] = dst[i];
1680182007Sroberto					dst[i] = etemp;
1681182007Sroberto				}
168254359Sroberto			}
168354359Sroberto		}
168482505Sroberto	}
168582505Sroberto
168682505Sroberto	/*
168782505Sroberto	 * Copy the index list to the association structure so ntpq
168882505Sroberto	 * can see it later. Prune the distance list to samples less
1689182007Sroberto	 * than max distance, but keep at least two valid samples for
169082505Sroberto	 * jitter calculation.
169182505Sroberto	 */
169282505Sroberto	m = 0;
169382505Sroberto	for (i = 0; i < NTP_SHIFT; i++) {
1694132454Sroberto		peer->filter_order[i] = (u_char) ord[i];
169582505Sroberto		if (dst[i] >= MAXDISPERSE || (m >= 2 && dst[i] >=
1696182007Sroberto		    sys_maxdist))
169782505Sroberto			continue;
169882505Sroberto		m++;
169982505Sroberto	}
170054359Sroberto
170154359Sroberto	/*
1702182007Sroberto	 * Compute the dispersion and jitter. The dispersion is weighted
1703182007Sroberto	 * exponentially by NTP_FWEIGHT (0.5) so it is normalized close
1704182007Sroberto	 * to 1.0. The jitter is the RMS differences relative to the
1705182007Sroberto	 * lowest delay sample. If no acceptable samples remain in the
1706182007Sroberto	 * shift register, quietly tiptoe home leaving only the
1707182007Sroberto	 * dispersion.
170854359Sroberto	 */
1709182007Sroberto	peer->disp = peer->jitter = 0;
171082505Sroberto	k = ord[0];
171154359Sroberto	for (i = NTP_SHIFT - 1; i >= 0; i--) {
171282505Sroberto		j = ord[i];
171382505Sroberto		peer->disp = NTP_FWEIGHT * (peer->disp +
171482505Sroberto		    peer->filter_disp[j]);
171582505Sroberto		if (i < m)
1716182007Sroberto			peer->jitter += DIFF(peer->filter_offset[j],
171782505Sroberto			    peer->filter_offset[k]);
171854359Sroberto	}
171954359Sroberto
172054359Sroberto	/*
172182505Sroberto	 * If no acceptable samples remain in the shift register,
172282505Sroberto	 * quietly tiptoe home leaving only the dispersion. Otherwise,
1723182007Sroberto	 * save the offset, delay and jitter. Note the jitter must not
1724182007Sroberto	 * be less than the precision.
172582505Sroberto	 */
172682505Sroberto	if (m == 0)
172782505Sroberto		return;
1728182007Sroberto
1729132454Sroberto	etemp = fabs(peer->offset - peer->filter_offset[k]);
173082505Sroberto	peer->offset = peer->filter_offset[k];
173182505Sroberto	peer->delay = peer->filter_delay[k];
173282505Sroberto	if (m > 1)
1733182007Sroberto		peer->jitter /= m - 1;
1734182007Sroberto	peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision));
173582505Sroberto
173682505Sroberto	/*
173754359Sroberto	 * A new sample is useful only if it is younger than the last
1738182007Sroberto	 * one used. Note the order is FIFO if the clock discipline has
1739182007Sroberto	 * not stabilized.
174054359Sroberto	 */
1741182007Sroberto	if (peer->filter_epoch[k] <= peer->epoch) {
174254359Sroberto#ifdef DEBUG
174354359Sroberto		if (debug)
174454359Sroberto			printf("clock_filter: discard %lu\n",
174582505Sroberto			    peer->epoch - peer->filter_epoch[k]);
174654359Sroberto#endif
174754359Sroberto		return;
174854359Sroberto	}
174954359Sroberto
175054359Sroberto	/*
175182505Sroberto	 * If the difference between the last offset and the current one
1752132454Sroberto	 * exceeds the jitter by CLOCK_SGATE and the interval since the
1753132454Sroberto	 * last update is less than twice the system poll interval,
175482505Sroberto	 * consider the update a popcorn spike and ignore it.
175554359Sroberto	 */
1756182007Sroberto	if (etemp > CLOCK_SGATE * peer->jitter && m > 1 &&
1757182007Sroberto	    peer->filter_epoch[k] - peer->epoch < 2. *
1758182007Sroberto	    ULOGTOD(sys_poll)) {
175954359Sroberto#ifdef DEBUG
176054359Sroberto		if (debug)
1761132454Sroberto			printf("clock_filter: popcorn %.6f %.6f\n",
1762132454Sroberto			    etemp, dtemp);
176354359Sroberto#endif
176454359Sroberto		return;
176554359Sroberto	}
176682505Sroberto
176782505Sroberto	/*
176882505Sroberto	 * The mitigated sample statistics are saved for later
1769182007Sroberto	 * processing. If not in a burst, tickle the select.
177082505Sroberto	 */
177182505Sroberto	peer->epoch = peer->filter_epoch[k];
177254359Sroberto#ifdef DEBUG
177354359Sroberto	if (debug)
177454359Sroberto		printf(
177582505Sroberto		    "clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f, age %lu\n",
177682505Sroberto		    m, peer->offset, peer->delay, peer->disp,
1777182007Sroberto		    peer->jitter, current_time - peer->epoch);
177854359Sroberto#endif
1779182007Sroberto	if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC)
1780182007Sroberto		clock_select();
178154359Sroberto}
178254359Sroberto
178354359Sroberto
178454359Sroberto/*
178554359Sroberto * clock_select - find the pick-of-the-litter clock
1786132454Sroberto *
1787132454Sroberto * LOCKCLOCK: If the local clock is the prefer peer, it will always be
1788132454Sroberto * enabled, even if declared falseticker, (2) only the prefer peer can
1789132454Sroberto * be selected as the system peer, (3) if the external source is down,
1790132454Sroberto * the system leap bits are set to 11 and the stratum set to infinity.
179154359Sroberto */
179254359Srobertovoid
179354359Srobertoclock_select(void)
179454359Sroberto{
1795132454Sroberto	struct peer *peer;
1796132454Sroberto	int	i, j, k, n;
1797132454Sroberto	int	nlist, nl3;
1798132454Sroberto
1799182007Sroberto	int	allow, osurv;
1800182007Sroberto	double	d, e, f, g;
1801132454Sroberto	double	high, low;
1802182007Sroberto	double	synch[NTP_MAXASSOC], error[NTP_MAXASSOC];
180354359Sroberto	struct peer *osys_peer;
180482505Sroberto	struct peer *typeacts = NULL;
180582505Sroberto	struct peer *typelocal = NULL;
180682505Sroberto	struct peer *typesystem = NULL;
180754359Sroberto
180854359Sroberto	static int list_alloc = 0;
180954359Sroberto	static struct endpoint *endpoint = NULL;
181082505Sroberto	static int *indx = NULL;
181154359Sroberto	static struct peer **peer_list = NULL;
181254359Sroberto	static u_int endpoint_size = 0;
181382505Sroberto	static u_int indx_size = 0;
181454359Sroberto	static u_int peer_list_size = 0;
181554359Sroberto
181654359Sroberto	/*
181782505Sroberto	 * Initialize and create endpoint, index and peer lists big
181882505Sroberto	 * enough to handle all associations.
181954359Sroberto	 */
182082505Sroberto	osys_peer = sys_peer;
182182505Sroberto	sys_peer = NULL;
1822182007Sroberto	sys_pps = NULL;
1823182007Sroberto	sys_prefer = NULL;
1824132454Sroberto	osurv = sys_survivors;
1825132454Sroberto	sys_survivors = 0;
1826132454Sroberto#ifdef LOCKCLOCK
1827132454Sroberto	sys_leap = LEAP_NOTINSYNC;
1828132454Sroberto	sys_stratum = STRATUM_UNSPEC;
1829132454Sroberto	memcpy(&sys_refid, "DOWN", 4);
1830132454Sroberto#endif /* LOCKCLOCK */
1831132454Sroberto	nlist = 0;
1832182007Sroberto	for (n = 0; n < NTP_HASH_SIZE; n++)
183354359Sroberto		nlist += peer_hash_count[n];
183454359Sroberto	if (nlist > list_alloc) {
183554359Sroberto		if (list_alloc > 0) {
183654359Sroberto			free(endpoint);
183782505Sroberto			free(indx);
183854359Sroberto			free(peer_list);
183954359Sroberto		}
184054359Sroberto		while (list_alloc < nlist) {
184154359Sroberto			list_alloc += 5;
184282505Sroberto			endpoint_size += 5 * 3 * sizeof(*endpoint);
184382505Sroberto			indx_size += 5 * 3 * sizeof(*indx);
184482505Sroberto			peer_list_size += 5 * sizeof(*peer_list);
184554359Sroberto		}
1846182007Sroberto		endpoint = (struct endpoint *)emalloc(endpoint_size);
1847182007Sroberto		indx = (int *)emalloc(indx_size);
1848182007Sroberto		peer_list = (struct peer **)emalloc(peer_list_size);
184954359Sroberto	}
185054359Sroberto
185154359Sroberto	/*
185282505Sroberto	 * Initially, we populate the island with all the rifraff peers
185382505Sroberto	 * that happen to be lying around. Those with seriously
185482505Sroberto	 * defective clocks are immediately booted off the island. Then,
185582505Sroberto	 * the falsetickers are culled and put to sea. The truechimers
185682505Sroberto	 * remaining are subject to repeated rounds where the most
185782505Sroberto	 * unpopular at each round is kicked off. When the population
1858132454Sroberto	 * has dwindled to sys_minclock, the survivors split a million
1859132454Sroberto	 * bucks and collectively crank the chimes.
186054359Sroberto	 */
186154359Sroberto	nlist = nl3 = 0;	/* none yet */
1862182007Sroberto	for (n = 0; n < NTP_HASH_SIZE; n++) {
186382505Sroberto		for (peer = peer_hash[n]; peer != NULL; peer =
186482505Sroberto		    peer->next) {
186554359Sroberto			peer->flags &= ~FLAG_SYSPEER;
186654359Sroberto			peer->status = CTL_PST_SEL_REJECT;
186754359Sroberto
186854359Sroberto			/*
1869132454Sroberto			 * Leave the island immediately if the peer is
1870132454Sroberto			 * unfit to synchronize.
1871132454Sroberto			 */
1872132454Sroberto			if (peer_unfit(peer))
187382505Sroberto				continue;
187482505Sroberto
187582505Sroberto			/*
187682505Sroberto			 * Don't allow the local clock or modem drivers
187754359Sroberto			 * in the kitchen at this point, unless the
187854359Sroberto			 * prefer peer. Do that later, but only if
187982505Sroberto			 * nobody else is around. These guys are all
188082505Sroberto			 * configured, so we never throw them away.
188154359Sroberto			 */
1882182007Sroberto#ifdef REFCLOCK
188354359Sroberto			if (peer->refclktype == REFCLK_LOCALCLOCK
188454359Sroberto#if defined(VMS) && defined(VMS_LOCALUNIT)
1885132454Sroberto			/* wjm: VMS_LOCALUNIT taken seriously */
1886132454Sroberto			    && REFCLOCKUNIT(&peer->srcadr) !=
1887132454Sroberto			    VMS_LOCALUNIT
188854359Sroberto#endif	/* VMS && VMS_LOCALUNIT */
188954359Sroberto				) {
189054359Sroberto				typelocal = peer;
1891182007Sroberto#ifndef LOCKCLOCK
189254359Sroberto				if (!(peer->flags & FLAG_PREFER))
189354359Sroberto					continue; /* no local clock */
1894132454Sroberto#endif /* LOCKCLOCK */
189554359Sroberto			}
189654359Sroberto			if (peer->sstclktype == CTL_SST_TS_TELEPHONE) {
189754359Sroberto				typeacts = peer;
189854359Sroberto				if (!(peer->flags & FLAG_PREFER))
189954359Sroberto					continue; /* no acts */
190054359Sroberto			}
1901182007Sroberto#endif /* REFCLOCK */
190254359Sroberto
190354359Sroberto			/*
190482505Sroberto			 * If we get this far, the peer can stay on the
190582505Sroberto			 * island, but does not yet have the immunity
190682505Sroberto			 * idol.
190754359Sroberto			 */
190854359Sroberto			peer->status = CTL_PST_SEL_SANE;
190954359Sroberto			peer_list[nlist++] = peer;
191054359Sroberto
191154359Sroberto			/*
191254359Sroberto			 * Insert each interval endpoint on the sorted
191354359Sroberto			 * list.
191454359Sroberto			 */
191554359Sroberto			e = peer->offset;	 /* Upper end */
191654359Sroberto			f = root_distance(peer);
191754359Sroberto			e = e + f;
191854359Sroberto			for (i = nl3 - 1; i >= 0; i--) {
191982505Sroberto				if (e >= endpoint[indx[i]].val)
192054359Sroberto					break;
1921182007Sroberto
192282505Sroberto				indx[i + 3] = indx[i];
192354359Sroberto			}
192482505Sroberto			indx[i + 3] = nl3;
192554359Sroberto			endpoint[nl3].type = 1;
192654359Sroberto			endpoint[nl3++].val = e;
192754359Sroberto
192854359Sroberto			e = e - f;		/* Center point */
1929132454Sroberto			for (; i >= 0; i--) {
193082505Sroberto				if (e >= endpoint[indx[i]].val)
193154359Sroberto					break;
1932182007Sroberto
193382505Sroberto				indx[i + 2] = indx[i];
193454359Sroberto			}
193582505Sroberto			indx[i + 2] = nl3;
193654359Sroberto			endpoint[nl3].type = 0;
193754359Sroberto			endpoint[nl3++].val = e;
193854359Sroberto
193954359Sroberto			e = e - f;		/* Lower end */
1940132454Sroberto			for (; i >= 0; i--) {
194182505Sroberto				if (e >= endpoint[indx[i]].val)
194254359Sroberto					break;
1943182007Sroberto
194482505Sroberto				indx[i + 1] = indx[i];
194554359Sroberto			}
194682505Sroberto			indx[i + 1] = nl3;
194754359Sroberto			endpoint[nl3].type = -1;
194854359Sroberto			endpoint[nl3++].val = e;
194954359Sroberto		}
195054359Sroberto	}
195154359Sroberto#ifdef DEBUG
195282505Sroberto	if (debug > 2)
195354359Sroberto		for (i = 0; i < nl3; i++)
195482505Sroberto			printf("select: endpoint %2d %.6f\n",
195582505Sroberto			   endpoint[indx[i]].type,
195682505Sroberto			   endpoint[indx[i]].val);
195754359Sroberto#endif
1958132454Sroberto	/*
1959132454Sroberto	 * This is the actual algorithm that cleaves the truechimers
1960132454Sroberto	 * from the falsetickers. The original algorithm was described
1961132454Sroberto	 * in Keith Marzullo's dissertation, but has been modified for
1962132454Sroberto	 * better accuracy.
1963132454Sroberto	 *
1964132454Sroberto	 * Briefly put, we first assume there are no falsetickers, then
1965132454Sroberto	 * scan the candidate list first from the low end upwards and
1966132454Sroberto	 * then from the high end downwards. The scans stop when the
1967132454Sroberto	 * number of intersections equals the number of candidates less
1968132454Sroberto	 * the number of falsetickers. If this doesn't happen for a
1969132454Sroberto	 * given number of falsetickers, we bump the number of
1970132454Sroberto	 * falsetickers and try again. If the number of falsetickers
1971132454Sroberto	 * becomes equal to or greater than half the number of
1972132454Sroberto	 * candidates, the Albanians have won the Byzantine wars and
1973132454Sroberto	 * correct synchronization is not possible.
1974132454Sroberto	 *
1975132454Sroberto	 * Here, nlist is the number of candidates and allow is the
1976182007Sroberto	 * number of falsetickers. Upon exit, the truechimers are the
1977182007Sroberto	 * susvivors with offsets not less than low and not greater than
1978182007Sroberto	 * high. There may be none of them.
1979132454Sroberto	 */
1980132454Sroberto	low = 1e9;
1981132454Sroberto	high = -1e9;
1982132454Sroberto	for (allow = 0; 2 * allow < nlist; allow++) {
1983132454Sroberto		int	found;
1984132454Sroberto
1985132454Sroberto		/*
1986132454Sroberto		 * Bound the interval (low, high) as the largest
1987132454Sroberto		 * interval containing points from presumed truechimers.
1988132454Sroberto		 */
1989132454Sroberto		found = 0;
1990132454Sroberto		n = 0;
1991132454Sroberto		for (i = 0; i < nl3; i++) {
1992132454Sroberto			low = endpoint[indx[i]].val;
1993132454Sroberto			n -= endpoint[indx[i]].type;
1994132454Sroberto			if (n >= nlist - allow)
199554359Sroberto				break;
199682505Sroberto			if (endpoint[indx[i]].type == 0)
199754359Sroberto				found++;
199854359Sroberto		}
1999132454Sroberto		n = 0;
2000132454Sroberto		for (j = nl3 - 1; j >= 0; j--) {
2001132454Sroberto			high = endpoint[indx[j]].val;
200282505Sroberto			n += endpoint[indx[j]].type;
2003132454Sroberto			if (n >= nlist - allow)
200454359Sroberto				break;
200582505Sroberto			if (endpoint[indx[j]].type == 0)
200654359Sroberto				found++;
200754359Sroberto		}
2008132454Sroberto
2009132454Sroberto		/*
2010132454Sroberto		 * If the number of candidates found outside the
2011132454Sroberto		 * interval is greater than the number of falsetickers,
2012132454Sroberto		 * then at least one truechimer is outside the interval,
2013132454Sroberto		 * so go around again. This is what makes this algorithm
2014132454Sroberto		 * different than Marzullo's.
2015132454Sroberto		 */
201654359Sroberto		if (found > allow)
2017132454Sroberto			continue;
2018132454Sroberto
2019132454Sroberto		/*
2020132454Sroberto		 * If an interval containing truechimers is found, stop.
2021132454Sroberto		 * If not, increase the number of falsetickers and go
2022132454Sroberto		 * around again.
2023132454Sroberto		 */
2024132454Sroberto		if (high > low)
202554359Sroberto			break;
202654359Sroberto	}
202754359Sroberto
202854359Sroberto	/*
2029182007Sroberto	 * Clustering algorithm. Construct candidate list in order first
2030182007Sroberto	 * by stratum then by root distance, but keep only the best
2031182007Sroberto	 * NTP_MAXASSOC of them. Scan the list to find falsetickers, who
2032182007Sroberto	 * leave the island immediately. The TRUE peer is always a
2033182007Sroberto	 * truechimer. We must leave at least one peer to collect the
2034182007Sroberto	 * million bucks. If in orphan mode, rascals found with lower
2035182007Sroberto	 * stratum are guaranteed a seat on the bus.
2036182007Sroberto	 */
2037182007Sroberto	j = 0;
2038182007Sroberto	for (i = 0; i < nlist; i++) {
2039182007Sroberto		peer = peer_list[i];
2040182007Sroberto		if (nlist > 1 && (peer->offset <= low || peer->offset >=
2041182007Sroberto		    high) && !(peer->flags & FLAG_TRUE) &&
2042182007Sroberto		    !(sys_stratum >= sys_orphan && peer->stratum <
2043182007Sroberto		    sys_orphan))
2044182007Sroberto			continue;
2045182007Sroberto
2046182007Sroberto		peer->status = CTL_PST_SEL_DISTSYSPEER;
2047182007Sroberto
2048182007Sroberto		/*
2049182007Sroberto		 * The order metric is formed from the stratum times
2050182007Sroberto		 * max distance (1.) plus the root distance. It strongly
2051182007Sroberto		 * favors the lowest stratum, but a higher stratum peer
2052182007Sroberto		 * can capture the clock if the low stratum dominant
2053182007Sroberto		 * hasn't been heard for awhile.
2054182007Sroberto		 */
2055182007Sroberto		d = root_distance(peer) + peer->stratum * sys_maxdist;
2056182007Sroberto		if (j >= NTP_MAXASSOC) {
2057182007Sroberto			if (d >= synch[j - 1])
2058182007Sroberto				continue;
2059182007Sroberto			else
2060182007Sroberto				j--;
2061182007Sroberto		}
2062182007Sroberto		for (k = j; k > 0; k--) {
2063182007Sroberto			if (d >= synch[k - 1])
2064182007Sroberto				break;
2065182007Sroberto
2066182007Sroberto			peer_list[k] = peer_list[k - 1];
2067182007Sroberto			error[k] = error[k - 1];
2068182007Sroberto			synch[k] = synch[k - 1];
2069182007Sroberto		}
2070182007Sroberto		peer_list[k] = peer;
2071182007Sroberto		error[k] = peer->jitter;
2072182007Sroberto		synch[k] = d;
2073182007Sroberto		j++;
2074182007Sroberto	}
2075182007Sroberto	nlist = j;
2076182007Sroberto
2077182007Sroberto	/*
207882505Sroberto	 * If no survivors remain at this point, check if the local
207982505Sroberto	 * clock or modem drivers have been found. If so, nominate one
2080132454Sroberto	 * of them as the only survivor. Otherwise, give up and leave
2081132454Sroberto	 * the island to the rats.
208254359Sroberto	 */
2083182007Sroberto	if (nlist == 0) {
208454359Sroberto		if (typeacts != 0) {
2085182007Sroberto			typeacts->status = CTL_PST_SEL_DISTSYSPEER;
208654359Sroberto			peer_list[0] = typeacts;
208754359Sroberto			nlist = 1;
208854359Sroberto		} else if (typelocal != 0) {
2089182007Sroberto			typelocal->status = CTL_PST_SEL_DISTSYSPEER;
209054359Sroberto			peer_list[0] = typelocal;
209154359Sroberto			nlist = 1;
209254359Sroberto		} else {
209382505Sroberto			if (osys_peer != NULL) {
209482505Sroberto				NLOG(NLOG_SYNCSTATUS)
209582505Sroberto				    msyslog(LOG_INFO,
2096132454Sroberto				    "no servers reachable");
2097132454Sroberto				report_event(EVNT_PEERSTCHG, NULL);
209854359Sroberto			}
209954359Sroberto		}
210054359Sroberto	}
210154359Sroberto
210254359Sroberto	/*
2103132454Sroberto	 * We can only trust the survivors if the number of candidates
2104132454Sroberto	 * sys_minsane is at least the number required to detect and
2105132454Sroberto	 * cast out one falsticker. For the Byzantine agreement
2106132454Sroberto	 * algorithm used here, that number is 4; however, the default
2107132454Sroberto	 * sys_minsane is 1 to speed initial synchronization. Careful
2108182007Sroberto	 * operators will tinker a higher value and use at least that
2109132454Sroberto	 * number of synchronization sources.
2110132454Sroberto	 */
2111132454Sroberto	if (nlist < sys_minsane)
2112132454Sroberto		return;
2113132454Sroberto
2114182007Sroberto	for (i = 0; i < nlist; i++)
211582505Sroberto		peer_list[i]->status = CTL_PST_SEL_SELCAND;
211654359Sroberto
211754359Sroberto	/*
211882505Sroberto	 * Now, vote outlyers off the island by select jitter weighted
2119182007Sroberto	 * by root distance. Continue voting as long as there are more
2120182007Sroberto	 * than sys_minclock survivors and the minimum select jitter is
2121182007Sroberto	 * greater than the maximum peer jitter. Stop if we are about to
2122182007Sroberto	 * discard a TRUE or PREFER  peer, who of course has the
2123182007Sroberto	 * immunity idol.
212454359Sroberto	 */
212554359Sroberto	while (1) {
212682505Sroberto		d = 1e9;
212782505Sroberto		e = -1e9;
2128182007Sroberto		f = g = 0;
212982505Sroberto		k = 0;
213082505Sroberto		for (i = 0; i < nlist; i++) {
213182505Sroberto			if (error[i] < d)
213282505Sroberto				d = error[i];
213382505Sroberto			f = 0;
213482505Sroberto			if (nlist > 1) {
213582505Sroberto				for (j = 0; j < nlist; j++)
213682505Sroberto					f += DIFF(peer_list[j]->offset,
213782505Sroberto					    peer_list[i]->offset);
2138182007Sroberto				f = SQRT(f / (nlist - 1));
213954359Sroberto			}
214082505Sroberto			if (f * synch[i] > e) {
2141182007Sroberto				g = f;
214282505Sroberto				e = f * synch[i];
214354359Sroberto				k = i;
214454359Sroberto			}
214554359Sroberto		}
2146182007Sroberto		f = max(f, LOGTOD(sys_precision));
2147132454Sroberto		if (nlist <= sys_minclock || f <= d ||
2148182007Sroberto		    peer_list[k]->flags & (FLAG_TRUE | FLAG_PREFER))
2149132454Sroberto			break;
215054359Sroberto#ifdef DEBUG
215182505Sroberto		if (debug > 2)
215254359Sroberto			printf(
2153132454Sroberto			    "select: drop %s select %.6f jitter %.6f\n",
2154182007Sroberto			    ntoa(&peer_list[k]->srcadr), g, d);
215554359Sroberto#endif
215654359Sroberto		for (j = k + 1; j < nlist; j++) {
215754359Sroberto			peer_list[j - 1] = peer_list[j];
215854359Sroberto			error[j - 1] = error[j];
215954359Sroberto		}
216054359Sroberto		nlist--;
216154359Sroberto	}
216282505Sroberto
216382505Sroberto	/*
2164132454Sroberto	 * What remains is a list usually not greater than sys_minclock
216554359Sroberto	 * peers. We want only a peer at the lowest stratum to become
216654359Sroberto	 * the system peer, although all survivors are eligible for the
2167182007Sroberto	 * combining algorithm. Consider each peer in turn and OR the
2168182007Sroberto	 * leap bits on the assumption that, if some of them honk
2169182007Sroberto	 * nonzero bits, they must know what they are doing. Check for
2170182007Sroberto	 * prefer and pps peers at any stratum. Note that the head of
2171182007Sroberto	 * the list is at the lowest stratum and that unsynchronized
2172182007Sroberto	 * peers cannot survive this far.
217354359Sroberto	 */
2174182007Sroberto	leap_next = 0;
2175182007Sroberto	for (i = 0; i < nlist; i++) {
217682505Sroberto		peer = peer_list[i];
2177182007Sroberto		sys_survivors++;
2178182007Sroberto		leap_next |= peer->leap;
217982505Sroberto		peer->status = CTL_PST_SEL_SYNCCAND;
2180132454Sroberto		if (peer->flags & FLAG_PREFER)
2181132454Sroberto			sys_prefer = peer;
2182182007Sroberto		if (peer == osys_peer)
2183132454Sroberto			typesystem = peer;
2184182007Sroberto#ifdef REFCLOCK
2185182007Sroberto		if (peer->refclktype == REFCLK_ATOM_PPS)
2186182007Sroberto			sys_pps = peer;
2187182007Sroberto#endif /* REFCLOCK */
2188182007Sroberto#if DEBUG
2189182007Sroberto		if (debug > 1)
2190182007Sroberto			printf("cluster: survivor %s metric %.6f\n",
2191182007Sroberto			    ntoa(&peer_list[i]->srcadr), synch[i]);
2192182007Sroberto#endif
219354359Sroberto	}
219454359Sroberto
219554359Sroberto	/*
2196182007Sroberto	 * Anticlockhop provision. Keep the current system peer if it is
2197182007Sroberto	 * a survivor but not first in the list. But do that only HOPPER
2198182007Sroberto	 * times.
2199132454Sroberto	 */
2200182007Sroberto	if (osys_peer == NULL || typesystem == NULL || typesystem ==
2201182007Sroberto	    peer_list[0] || sys_hopper > sys_maxhop) {
2202182007Sroberto		typesystem = peer_list[0];
2203182007Sroberto		sys_hopper = 0;
2204182007Sroberto	} else {
2205182007Sroberto		peer->selbroken++;
2206182007Sroberto	}
2207132454Sroberto
2208132454Sroberto	/*
220954359Sroberto	 * Mitigation rules of the game. There are several types of
2210182007Sroberto	 * peers that can be selected here: (1) orphan, (2) prefer peer
2211182007Sroberto	 * (flag FLAG_PREFER) (3) pps peers (type REFCLK_ATOM_PPS), (4)
2212182007Sroberto	 * the existing system peer, if any, and (5) the head of the
2213182007Sroberto	 * survivor list.
221454359Sroberto	 */
2215182007Sroberto	if (typesystem->stratum >= sys_orphan) {
2216182007Sroberto
2217182007Sroberto		/*
2218182007Sroberto		 * If in orphan mode, choose the system peer. If the
2219182007Sroberto		 * lowest distance, we are the orphan parent and the
2220182007Sroberto		 * offset is zero.
2221182007Sroberto		 */
2222182007Sroberto		sys_peer = typesystem;
222354359Sroberto		sys_peer->status = CTL_PST_SEL_SYSPEER;
2224182007Sroberto		if (sys_orphandelay < sys_peer->rootdelay) {
2225182007Sroberto			sys_offset = 0;
2226182007Sroberto			sys_refid = htonl(LOOPBACKADR);
2227182007Sroberto		} else {
2228182007Sroberto			sys_offset = sys_peer->offset;
2229182007Sroberto			sys_refid = addr2refid(&sys_peer->srcadr);
2230182007Sroberto		}
2231182007Sroberto		sys_jitter = LOGTOD(sys_precision);
223254359Sroberto#ifdef DEBUG
223354359Sroberto		if (debug > 1)
2234182007Sroberto			printf("select: orphan offset %.6f\n",
223556749Sroberto			    sys_offset);
223654359Sroberto#endif
2237182007Sroberto	} else if (sys_prefer) {
2238182007Sroberto
2239182007Sroberto		/*
2240182007Sroberto		 * If a pps peer is present, choose it; otherwise,
2241182007Sroberto		 * choose the prefer peer.
2242182007Sroberto		 */
2243182007Sroberto		if (sys_pps) {
2244182007Sroberto			sys_peer = sys_pps;
2245182007Sroberto			sys_peer->status = CTL_PST_SEL_PPS;
2246182007Sroberto			sys_offset = sys_peer->offset;
2247182007Sroberto			if (!pps_control)
2248182007Sroberto				NLOG(NLOG_SYSEVENT)
2249182007Sroberto				    msyslog(LOG_INFO,
2250182007Sroberto				    "pps sync enabled");
2251182007Sroberto			pps_control = current_time;
225254359Sroberto#ifdef DEBUG
2253182007Sroberto			if (debug > 1)
2254182007Sroberto				printf("select: pps offset %.6f\n",
2255182007Sroberto				    sys_offset);
225654359Sroberto#endif
2257182007Sroberto		} else {
2258182007Sroberto			sys_peer = sys_prefer;
2259182007Sroberto			sys_peer->status = CTL_PST_SEL_SYSPEER;
2260182007Sroberto			sys_offset = sys_peer->offset;
2261182007Sroberto#ifdef DEBUG
2262182007Sroberto			if (debug > 1)
2263182007Sroberto				printf("select: prefer offset %.6f\n",
2264182007Sroberto				    sys_offset);
2265182007Sroberto#endif
2266182007Sroberto		}
2267182007Sroberto		if (sys_peer->stratum == STRATUM_REFCLOCK ||
2268182007Sroberto		    sys_peer->stratum == STRATUM_UNSPEC)
2269182007Sroberto			sys_refid = sys_peer->refid;
2270182007Sroberto		else
2271182007Sroberto			sys_refid = addr2refid(&sys_peer->srcadr);
2272182007Sroberto		sys_jitter = sys_peer->jitter;
227354359Sroberto	} else {
2274182007Sroberto
2275182007Sroberto		/*
2276182007Sroberto		 * Otherwise, choose the anticlockhopper.
2277182007Sroberto		 */
2278182007Sroberto		sys_peer = typesystem;
2279182007Sroberto		sys_peer->status = CTL_PST_SEL_SYSPEER;
2280182007Sroberto		clock_combine(peer_list, nlist);
2281182007Sroberto		if (sys_peer->stratum == STRATUM_REFCLOCK ||
2282182007Sroberto		    sys_peer->stratum == STRATUM_UNSPEC)
2283182007Sroberto			sys_refid = sys_peer->refid;
228482505Sroberto		else
2285182007Sroberto			sys_refid = addr2refid(&sys_peer->srcadr);
2286182007Sroberto		sys_jitter = SQRT(SQUARE(sys_peer->jitter) +
2287182007Sroberto		    SQUARE(sys_jitter));
228854359Sroberto#ifdef DEBUG
228954359Sroberto		if (debug > 1)
229054359Sroberto			printf("select: combine offset %.6f\n",
229154359Sroberto			   sys_offset);
229254359Sroberto#endif
229354359Sroberto	}
2294182007Sroberto
2295182007Sroberto	/*
2296182007Sroberto	 * We have found the alpha male.
2297182007Sroberto	 */
2298182007Sroberto	sys_peer->flags |= FLAG_SYSPEER;
2299132454Sroberto	if (osys_peer != sys_peer) {
2300132454Sroberto		char *src;
2301132454Sroberto
2302132454Sroberto		report_event(EVNT_PEERSTCHG, NULL);
2303132454Sroberto
2304132454Sroberto#ifdef REFCLOCK
2305182007Sroberto                if (sys_peer->flags & FLAG_REFCLOCK)
2306132454Sroberto                        src = refnumtoa(&sys_peer->srcadr);
2307132454Sroberto                else
2308182007Sroberto#endif /* REFCLOCK */
2309132454Sroberto                        src = ntoa(&sys_peer->srcadr);
2310132454Sroberto		NLOG(NLOG_SYNCSTATUS)
2311182007Sroberto		    msyslog(LOG_INFO, "synchronized to %s, stratum %d",
2312182007Sroberto			src, sys_peer->stratum);
2313132454Sroberto	}
231454359Sroberto	clock_update();
231554359Sroberto}
231654359Sroberto
2317182007Sroberto
231854359Sroberto/*
2319182007Sroberto * clock_combine - compute system offset and jitter from selected peers
232054359Sroberto */
2321182007Srobertostatic void
232254359Srobertoclock_combine(
2323182007Sroberto	struct peer **peers,		/* survivor list */
2324182007Sroberto	int	npeers			/* number of survivors */
232554359Sroberto	)
232654359Sroberto{
2327132454Sroberto	int	i;
2328182007Sroberto	double	x, y, z, w;
2329132454Sroberto
2330182007Sroberto	y = z = w = 0;
233154359Sroberto	for (i = 0; i < npeers; i++) {
233254359Sroberto		x = root_distance(peers[i]);
233354359Sroberto		y += 1. / x;
233454359Sroberto		z += peers[i]->offset / x;
2335182007Sroberto		w += SQUARE(peers[i]->offset - peers[0]->offset) / x;
233654359Sroberto	}
2337182007Sroberto	sys_offset = z / y;
2338182007Sroberto	sys_jitter = SQRT(w / y);
233954359Sroberto}
234054359Sroberto
234154359Sroberto/*
234254359Sroberto * root_distance - compute synchronization distance from peer to root
234354359Sroberto */
234454359Srobertostatic double
234554359Srobertoroot_distance(
234654359Sroberto	struct peer *peer
234754359Sroberto	)
234854359Sroberto{
2349182007Sroberto	double	dist;
2350182007Sroberto
235182505Sroberto	/*
235282505Sroberto	 * Careful squeak here. The value returned must be greater than
2353182007Sroberto	 * the minimum root dispersion in order to avoid clockhop with
2354182007Sroberto	 * highly precise reference clocks. In orphan mode lose the peer
2355182007Sroberto	 * root delay, as that is used by the election algorithm.
235682505Sroberto	 */
2357182007Sroberto	if (peer->stratum >= sys_orphan)
2358182007Sroberto		dist = 0;
2359182007Sroberto	else
2360182007Sroberto		dist = peer->rootdelay;
2361182007Sroberto	dist += max(sys_mindisp, dist + peer->delay) / 2 +
236282505Sroberto	    peer->rootdispersion + peer->disp + clock_phi *
2363182007Sroberto	    (current_time - peer->update) + peer->jitter;
2364182007Sroberto	return (dist);
236554359Sroberto}
236654359Sroberto
236754359Sroberto/*
236854359Sroberto * peer_xmit - send packet for persistent association.
236954359Sroberto */
237054359Srobertostatic void
237154359Srobertopeer_xmit(
237254359Sroberto	struct peer *peer	/* peer structure pointer */
237354359Sroberto	)
237454359Sroberto{
237582505Sroberto	struct pkt xpkt;	/* transmit packet */
2376132454Sroberto	int	sendlen, authlen;
2377182007Sroberto	keyid_t	xkeyid = 0;	/* transmit key ID */
2378132454Sroberto	l_fp	xmt_tx;
237954359Sroberto
2380182007Sroberto	if (!peer->dstadr)	/* don't bother with peers without interface */
2381182007Sroberto		return;
2382182007Sroberto
238354359Sroberto	/*
2384182007Sroberto	 * This is deliciously complicated. There are three cases.
2385182007Sroberto	 *
2386182007Sroberto	 * case		leap	stratum	refid	delay	dispersion
2387182007Sroberto	 *
2388182007Sroberto	 * normal	system	system	system	system	system
2389182007Sroberto	 * orphan child	00	orphan	system	orphan	system
2390182007Sroberto	 * orphan parent 00	orphan	loopbk	0	0
239154359Sroberto	 */
2392182007Sroberto	/*
2393182007Sroberto	 * This is a normal packet. Use the system variables.
2394182007Sroberto	 */
2395182007Sroberto	if (sys_stratum < sys_orphan) {
2396182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
2397182007Sroberto		    peer->version, peer->hmode);
2398182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
2399182007Sroberto		xpkt.refid = sys_refid;
2400182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
2401182007Sroberto		xpkt.rootdispersion =
2402182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2403182007Sroberto
2404182007Sroberto	/*
2405182007Sroberto	 * This is a orphan child packet. The host is synchronized to an
2406182007Sroberto	 * orphan parent. Show leap synchronized, orphan stratum, system
2407182007Sroberto	 * reference ID, orphan root delay and system root dispersion.
2408182007Sroberto	 */
2409182007Sroberto	} else if (sys_peer != NULL) {
2410182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2411182007Sroberto		    peer->version, peer->hmode);
2412182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2413182007Sroberto		xpkt.refid = htonl(LOOPBACKADR);
2414182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay));
2415182007Sroberto		xpkt.rootdispersion =
2416182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2417182007Sroberto
2418182007Sroberto	/*
2419182007Sroberto	 * This is an orphan parent. Show leap synchronized, orphan
2420182007Sroberto	 * stratum, loopack reference ID and zero root delay and root
2421182007Sroberto	 * dispersion.
2422182007Sroberto	 */
2423182007Sroberto	} else {
2424182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2425182007Sroberto		    peer->version, peer->hmode);
2426182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2427182007Sroberto		xpkt.refid = sys_refid;
2428182007Sroberto		xpkt.rootdelay = 0;
2429182007Sroberto		xpkt.rootdispersion = 0;
2430182007Sroberto	}
243154359Sroberto	xpkt.ppoll = peer->hpoll;
243254359Sroberto	xpkt.precision = sys_precision;
243354359Sroberto	HTONL_FP(&sys_reftime, &xpkt.reftime);
243454359Sroberto	HTONL_FP(&peer->org, &xpkt.org);
243554359Sroberto	HTONL_FP(&peer->rec, &xpkt.rec);
243654359Sroberto
243754359Sroberto	/*
243882505Sroberto	 * If the received packet contains a MAC, the transmitted packet
243982505Sroberto	 * is authenticated and contains a MAC. If not, the transmitted
244082505Sroberto	 * packet is not authenticated.
244182505Sroberto	 *
2442182007Sroberto	 * It is most important when autokey is in use that the local
2443182007Sroberto	 * interface IP address be known before the first packet is
2444182007Sroberto	 * sent. Otherwise, it is not possible to compute a correct MAC
2445182007Sroberto	 * the recipient will accept. Thus, the I/O semantics have to do
2446182007Sroberto	 * a little more work. In particular, the wildcard interface
2447182007Sroberto	 * might not be usable.
244854359Sroberto	 */
244954359Sroberto	sendlen = LEN_PKT_NOMAC;
245082505Sroberto	if (!(peer->flags & FLAG_AUTHENABLE)) {
245182505Sroberto		get_systime(&peer->xmt);
245282505Sroberto		HTONL_FP(&peer->xmt, &xpkt.xmt);
2453132454Sroberto		sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl],
2454182007Sroberto			&xpkt, sendlen);
245582505Sroberto		peer->sent++;
245682505Sroberto#ifdef DEBUG
245782505Sroberto		if (debug)
245882505Sroberto			printf("transmit: at %ld %s->%s mode %d\n",
2459182007Sroberto			       current_time, peer->dstadr ? stoa(&peer->dstadr->sin) : "-",
2460182007Sroberto			       stoa(&peer->srcadr), peer->hmode);
246182505Sroberto#endif
246282505Sroberto		return;
246382505Sroberto	}
246454359Sroberto
246582505Sroberto	/*
246682505Sroberto	 * The received packet contains a MAC, so the transmitted packet
246782505Sroberto	 * must be authenticated. If autokey is enabled, fuss with the
2468182007Sroberto	 * various modes; otherwise, symmetric key cryptography is used.
246982505Sroberto	 */
2470132454Sroberto#ifdef OPENSSL
2471132454Sroberto	if (crypto_flags && (peer->flags & FLAG_SKEY)) {
2472132454Sroberto		struct exten *exten;	/* extension field */
247382505Sroberto
247454359Sroberto		/*
247582505Sroberto		 * The Public Key Dance (PKD): Cryptographic credentials
247682505Sroberto		 * are contained in extension fields, each including a
247782505Sroberto		 * 4-octet length/code word followed by a 4-octet
247882505Sroberto		 * association ID and optional additional data. Optional
247982505Sroberto		 * data includes a 4-octet data length field followed by
248082505Sroberto		 * the data itself. Request messages are sent from a
248182505Sroberto		 * configured association; response messages can be sent
248282505Sroberto		 * from a configured association or can take the fast
248382505Sroberto		 * path without ever matching an association. Response
248482505Sroberto		 * messages have the same code as the request, but have
248582505Sroberto		 * a response bit and possibly an error bit set. In this
248682505Sroberto		 * implementation, a message may contain no more than
248782505Sroberto		 * one command and no more than one response.
248882505Sroberto		 *
248982505Sroberto		 * Cryptographic session keys include both a public and
249082505Sroberto		 * a private componet. Request and response messages
249182505Sroberto		 * using extension fields are always sent with the
249282505Sroberto		 * private component set to zero. Packets without
249382505Sroberto		 * extension fields indlude the private component when
249482505Sroberto		 * the session key is generated.
249554359Sroberto		 */
249682505Sroberto		while (1) {
249782505Sroberto
249854359Sroberto			/*
249982505Sroberto			 * Allocate and initialize a keylist if not
250082505Sroberto			 * already done. Then, use the list in inverse
250182505Sroberto			 * order, discarding keys once used. Keep the
250282505Sroberto			 * latest key around until the next one, so
250382505Sroberto			 * clients can use client/server packets to
250482505Sroberto			 * compute propagation delay.
250582505Sroberto			 *
250682505Sroberto			 * Note that once a key is used from the list,
250782505Sroberto			 * it is retained in the key cache until the
250882505Sroberto			 * next key is used. This is to allow a client
250982505Sroberto			 * to retrieve the encrypted session key
251082505Sroberto			 * identifier to verify authenticity.
251182505Sroberto			 *
251282505Sroberto			 * If for some reason a key is no longer in the
251382505Sroberto			 * key cache, a birthday has happened and the
251482505Sroberto			 * pseudo-random sequence is probably broken. In
251582505Sroberto			 * that case, purge the keylist and regenerate
251682505Sroberto			 * it.
251754359Sroberto			 */
251882505Sroberto			if (peer->keynumber == 0)
251982505Sroberto				make_keylist(peer, peer->dstadr);
252082505Sroberto			else
252182505Sroberto				peer->keynumber--;
252282505Sroberto			xkeyid = peer->keylist[peer->keynumber];
252382505Sroberto			if (authistrusted(xkeyid))
252482505Sroberto				break;
252582505Sroberto			else
252682505Sroberto				key_expire(peer);
252754359Sroberto		}
252882505Sroberto		peer->keyid = xkeyid;
2529182007Sroberto		exten = NULL;
253082505Sroberto		switch (peer->hmode) {
253154359Sroberto
2532182007Sroberto			/*
2533182007Sroberto			 * In broadcast server mode the autokey values are
2534182007Sroberto			 * required by the broadcast clients. Push them when a
2535182007Sroberto			 * new keylist is generated; otherwise, push the
2536182007Sroberto			 * association message so the client can request them at
2537182007Sroberto			 * other times.
2538182007Sroberto			 */
253982505Sroberto		case MODE_BROADCAST:
254082505Sroberto			if (peer->flags & FLAG_ASSOC)
2541132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO |
2542182007Sroberto						    CRYPTO_RESP, NULL);
254382505Sroberto			else
2544132454Sroberto				exten = crypto_args(peer, CRYPTO_ASSOC |
2545182007Sroberto						    CRYPTO_RESP, NULL);
254682505Sroberto			break;
254782505Sroberto
254854359Sroberto		/*
2549132454Sroberto		 * In symmetric modes the digest, certificate, agreement
2550132454Sroberto		 * parameters, cookie and autokey values are required.
2551132454Sroberto		 * The leapsecond table is optional. But, a passive peer
2552132454Sroberto		 * will not believe the active peer until the latter has
2553132454Sroberto		 * synchronized, so the agreement must be postponed
2554132454Sroberto		 * until then. In any case, if a new keylist is
2555132454Sroberto		 * generated, the autokey values are pushed.
2556182007Sroberto		 *
2557182007Sroberto		 * If the crypto bit is lit, don't send requests.
255854359Sroberto		 */
255982505Sroberto		case MODE_ACTIVE:
256082505Sroberto		case MODE_PASSIVE:
2561182007Sroberto			if (peer->flash & TEST9)
2562182007Sroberto				break;
2563182007Sroberto			/*
2564182007Sroberto			 * Parameter and certificate.
2565182007Sroberto			 */
256682505Sroberto			if (!peer->crypto)
2567132454Sroberto				exten = crypto_args(peer, CRYPTO_ASSOC,
2568182007Sroberto						    sys_hostname);
2569132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VALID))
2570132454Sroberto				exten = crypto_args(peer, CRYPTO_CERT,
2571182007Sroberto						    peer->issuer);
2572132454Sroberto
2573132454Sroberto			/*
2574132454Sroberto			 * Identity. Note we have to sign the
2575132454Sroberto			 * certificate before the cookie to avoid a
2576132454Sroberto			 * deadlock when the passive peer is walking the
2577132454Sroberto			 * certificate trail. Awesome.
2578132454Sroberto			 */
2579182007Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VRFY))
2580182007Sroberto				exten = crypto_args(peer,
2581182007Sroberto						    crypto_ident(peer), NULL);
2582132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2583182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_SIGN))
2584132454Sroberto				exten = crypto_args(peer, CRYPTO_SIGN,
2585182007Sroberto						    sys_hostname);
2586132454Sroberto
2587132454Sroberto			/*
2588132454Sroberto			 * Autokey. We request the cookie only when the
2589132454Sroberto			 * server and client are synchronized and
2590132454Sroberto			 * signatures work both ways. On the other hand,
2591132454Sroberto			 * the active peer needs the autokey values
2592132454Sroberto			 * before then and when the passive peer is
2593132454Sroberto			 * waiting for the active peer to synchronize.
2594132454Sroberto			 * Any time we regenerate the key list, we offer
2595132454Sroberto			 * the autokey values without being asked.
2596132454Sroberto			 */
2597132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2598182007Sroberto				 peer->leap != LEAP_NOTINSYNC &&
2599182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_AGREE))
2600132454Sroberto				exten = crypto_args(peer, CRYPTO_COOK,
2601182007Sroberto						    NULL);
2602132454Sroberto			else if (peer->flags & FLAG_ASSOC)
2603132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO |
2604182007Sroberto						    CRYPTO_RESP, NULL);
2605132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_AUTO))
2606132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO,
2607182007Sroberto						    NULL);
2608132454Sroberto
2609132454Sroberto			/*
2610132454Sroberto			 * Postamble. We trade leapseconds only when the
2611132454Sroberto			 * server and client are synchronized.
2612132454Sroberto			 */
2613132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2614182007Sroberto				 peer->leap != LEAP_NOTINSYNC &&
2615182007Sroberto				 peer->crypto & CRYPTO_FLAG_TAI &&
2616182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_LEAP))
2617132454Sroberto				exten = crypto_args(peer, CRYPTO_TAI,
2618182007Sroberto						    NULL);
261982505Sroberto			break;
262082505Sroberto
262182505Sroberto		/*
2622132454Sroberto		 * In client mode the digest, certificate, agreement
2623132454Sroberto		 * parameters and cookie are required. The leapsecond
2624132454Sroberto		 * table is optional. If broadcast client mode, the
2625132454Sroberto		 * autokey values are required as well. In broadcast
2626132454Sroberto		 * client mode, these values must be acquired during the
262782505Sroberto		 * client/server exchange to avoid having to wait until
262882505Sroberto		 * the next key list regeneration. Otherwise, the poor
262982505Sroberto		 * dude may die a lingering death until becoming
2630132454Sroberto		 * unreachable and attempting rebirth.
2631132454Sroberto		 *
2632132454Sroberto		 * If neither the server or client have the agreement
2633132454Sroberto		 * parameters, the protocol transmits the cookie in the
2634132454Sroberto		 * clear. If the server has the parameters, the client
2635132454Sroberto		 * requests them and the protocol blinds it using the
2636132454Sroberto		 * agreed key. It is a protocol error if the client has
2637132454Sroberto		 * the parameters but the server does not.
2638182007Sroberto		 *
2639182007Sroberto		 * If the crypto bit is lit, don't send requests.
264082505Sroberto		 */
264182505Sroberto		case MODE_CLIENT:
2642182007Sroberto			if (peer->flash & TEST9)
2643182007Sroberto				break;
2644182007Sroberto			/*
2645182007Sroberto			 * Parameter and certificate.
2646182007Sroberto			 */
264782505Sroberto			if (!peer->crypto)
2648132454Sroberto				exten = crypto_args(peer, CRYPTO_ASSOC,
2649182007Sroberto						    sys_hostname);
2650132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VALID))
2651132454Sroberto				exten = crypto_args(peer, CRYPTO_CERT,
2652182007Sroberto						    peer->issuer);
2653132454Sroberto
2654132454Sroberto			/*
2655182007Sroberto			 * Identity
2656132454Sroberto			 */
2657182007Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VRFY))
2658182007Sroberto				exten = crypto_args(peer,
2659182007Sroberto						    crypto_ident(peer), NULL);
2660132454Sroberto
2661132454Sroberto			/*
2662132454Sroberto			 * Autokey
2663132454Sroberto			 */
2664132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_AGREE))
2665132454Sroberto				exten = crypto_args(peer, CRYPTO_COOK,
2666182007Sroberto						    NULL);
2667132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_AUTO) &&
2668182007Sroberto				 (peer->cast_flags & MDF_BCLNT))
2669132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO,
2670182007Sroberto						    NULL);
2671132454Sroberto
2672132454Sroberto			/*
2673132454Sroberto			 * Postamble. We can sign the certificate here,
2674132454Sroberto			 * since there is no chance of deadlock.
2675132454Sroberto			 */
2676132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2677182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_SIGN))
2678132454Sroberto				exten = crypto_args(peer, CRYPTO_SIGN,
2679182007Sroberto						    sys_hostname);
2680132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2681182007Sroberto				 peer->crypto & CRYPTO_FLAG_TAI &&
2682182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_LEAP))
2683132454Sroberto				exten = crypto_args(peer, CRYPTO_TAI,
2684182007Sroberto						    NULL);
268582505Sroberto			break;
268682505Sroberto		}
268782505Sroberto
268882505Sroberto		/*
2689182007Sroberto		 * Build the extension fields as directed. A response to
2690182007Sroberto		 * a request is always sent, even if an error. If an
2691182007Sroberto		 * error occurs when sending a request, the crypto
2692182007Sroberto		 * machinery broke or was misconfigured. In that case
2693182007Sroberto		 * light the crypto bit to suppress further requests.
2694182007Sroberto		 */
2695182007Sroberto		if (peer->cmmd != NULL) {
2696182007Sroberto			peer->cmmd->associd = htonl(peer->associd);
2697182007Sroberto			sendlen += crypto_xmit(&xpkt, &peer->srcadr,
2698182007Sroberto					       sendlen, peer->cmmd, 0);
2699182007Sroberto			free(peer->cmmd);
2700182007Sroberto			peer->cmmd = NULL;
2701182007Sroberto		}
2702182007Sroberto		if (exten != NULL) {
2703182007Sroberto			int ltemp = 0;
2704182007Sroberto
2705182007Sroberto			if (exten->opcode != 0) {
2706182007Sroberto				ltemp = crypto_xmit(&xpkt,
2707182007Sroberto						       &peer->srcadr, sendlen, exten, 0);
2708182007Sroberto				if (ltemp == 0) {
2709182007Sroberto					peer->flash |= TEST9; /* crypto error */
2710182007Sroberto					free(exten);
2711182007Sroberto					return;
2712182007Sroberto				}
2713182007Sroberto			}
2714182007Sroberto			sendlen += ltemp;
2715182007Sroberto			free(exten);
2716182007Sroberto		}
2717182007Sroberto
2718182007Sroberto		/*
271982505Sroberto		 * If extension fields are present, we must use a
2720182007Sroberto		 * private cookie value of zero. Don't send if the
2721182007Sroberto		 * crypto bit is set and no extension field is present,
2722182007Sroberto		 * but in that case give back the key. Most intricate.
272382505Sroberto		 */
2724182007Sroberto		if (sendlen > LEN_PKT_NOMAC) {
272582505Sroberto			session_key(&peer->dstadr->sin, &peer->srcadr,
272682505Sroberto			    xkeyid, 0, 2);
2727182007Sroberto		} else if (peer->flash & TEST9) {
2728182007Sroberto			authtrust(xkeyid, 0);
2729182007Sroberto			return;
2730182007Sroberto		}
273182505Sroberto	}
2732132454Sroberto#endif /* OPENSSL */
2733182007Sroberto
2734182007Sroberto	/*
2735182007Sroberto	 * Stash the transmit timestamp corrected for the encryption
2736182007Sroberto	 * delay. If autokey, give back the key, as we use keys only
2737182007Sroberto	 * once. Check for errors such as missing keys, buffer overflow,
2738182007Sroberto	 * etc.
2739182007Sroberto	 */
274082505Sroberto	xkeyid = peer->keyid;
274182505Sroberto	get_systime(&peer->xmt);
274282505Sroberto	L_ADD(&peer->xmt, &sys_authdelay);
274382505Sroberto	HTONL_FP(&peer->xmt, &xpkt.xmt);
274482505Sroberto	authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen);
274582505Sroberto	if (authlen == 0) {
2746182007Sroberto		msyslog(LOG_INFO, "transmit: %s key %u not found",
2747182007Sroberto		    stoa(&peer->srcadr), xkeyid);
2748182007Sroberto		peer->flash |= TEST9;		/* no key found */
274982505Sroberto		return;
275082505Sroberto	}
275182505Sroberto	sendlen += authlen;
2752132454Sroberto#ifdef OPENSSL
275382505Sroberto	if (xkeyid > NTP_MAXKEY)
275482505Sroberto		authtrust(xkeyid, 0);
2755132454Sroberto#endif /* OPENSSL */
275682505Sroberto	get_systime(&xmt_tx);
275782505Sroberto	if (sendlen > sizeof(xpkt)) {
275882505Sroberto		msyslog(LOG_ERR, "buffer overflow %u", sendlen);
2759132454Sroberto		exit (-1);
276082505Sroberto	}
2761132454Sroberto	sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt,
2762182007Sroberto		sendlen);
276382505Sroberto
276482505Sroberto	/*
276582505Sroberto	 * Calculate the encryption delay. Keep the minimum over
276682505Sroberto	 * the latest two samples.
276782505Sroberto	 */
276882505Sroberto	L_SUB(&xmt_tx, &peer->xmt);
276982505Sroberto	L_ADD(&xmt_tx, &sys_authdelay);
277082505Sroberto	sys_authdly[1] = sys_authdly[0];
277182505Sroberto	sys_authdly[0] = xmt_tx.l_uf;
277282505Sroberto	if (sys_authdly[0] < sys_authdly[1])
277382505Sroberto		sys_authdelay.l_uf = sys_authdly[0];
277482505Sroberto	else
277582505Sroberto		sys_authdelay.l_uf = sys_authdly[1];
277682505Sroberto	peer->sent++;
2777132454Sroberto#ifdef OPENSSL
277854359Sroberto#ifdef DEBUG
277982505Sroberto	if (debug)
278082505Sroberto		printf(
2781182007Sroberto			"transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d index %d\n",
2782182007Sroberto			current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-",
2783182007Sroberto			ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen -
2784182007Sroberto			authlen, authlen, peer->keynumber);
278554359Sroberto#endif
278682505Sroberto#else
278782505Sroberto#ifdef DEBUG
278882505Sroberto	if (debug)
278982505Sroberto		printf(
2790182007Sroberto			"transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n",
2791182007Sroberto			current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-",
2792182007Sroberto			ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen -
2793182007Sroberto			authlen, authlen);
279482505Sroberto#endif
2795132454Sroberto#endif /* OPENSSL */
279654359Sroberto}
279754359Sroberto
279882505Sroberto
279954359Sroberto/*
280082505Sroberto * fast_xmit - Send packet for nonpersistent association. Note that
280182505Sroberto * neither the source or destination can be a broadcast address.
280254359Sroberto */
280354359Srobertostatic void
280454359Srobertofast_xmit(
280554359Sroberto	struct recvbuf *rbufp,	/* receive packet pointer */
2806132454Sroberto	int	xmode,		/* transmit mode */
2807132454Sroberto	keyid_t	xkeyid,		/* transmit key ID */
2808132454Sroberto	int	mask		/* restrict mask */
280954359Sroberto	)
281054359Sroberto{
2811132454Sroberto	struct pkt xpkt;		/* transmit packet structure */
2812132454Sroberto	struct pkt *rpkt;		/* receive packet structure */
2813132454Sroberto	l_fp	xmt_ts;			/* timestamp */
2814132454Sroberto	l_fp	xmt_tx;			/* timestamp after authent */
2815132454Sroberto	int	sendlen, authlen;
2816132454Sroberto#ifdef OPENSSL
2817132454Sroberto	u_int32	temp32;
2818132454Sroberto#endif
281954359Sroberto
282054359Sroberto	/*
282182505Sroberto	 * Initialize transmit packet header fields from the receive
282282505Sroberto	 * buffer provided. We leave some fields intact as received. If
2823182007Sroberto	 * the gazinta was from a multicast address, the gazoutta must
2824182007Sroberto	 * go out another way.
2825182007Sroberto	 *
2826182007Sroberto	 * The root delay field is special. If the system stratum is
2827182007Sroberto	 * less than the orphan stratum, send the real root delay.
2828182007Sroberto	 * Otherwise, if there is no system peer, send the orphan delay.
2829182007Sroberto	 * Otherwise, we must be an orphan parent, so send zero.
283054359Sroberto	 */
283154359Sroberto	rpkt = &rbufp->recv_pkt;
2832182007Sroberto	if (rbufp->dstadr->flags & INT_MCASTOPEN)
283382505Sroberto		rbufp->dstadr = findinterface(&rbufp->recv_srcadr);
283482505Sroberto
283582505Sroberto	/*
2836182007Sroberto	 * This is deliciously complicated. There are four cases.
2837182007Sroberto	 *
2838182007Sroberto	 * case		leap	stratum	refid	delay	dispersion
2839182007Sroberto	 *
2840182007Sroberto	 * KoD		11	16	KISS	system	system
2841182007Sroberto	 * normal	system	system	system	system	system
2842182007Sroberto	 * orphan child	00	orphan	system	orphan	system
2843182007Sroberto	 * orphan parent 00	orphan	loopbk	0	0
284482505Sroberto	 */
2845182007Sroberto	/*
2846182007Sroberto	 * This is a kiss-of-death (KoD) packet. Show leap
2847182007Sroberto	 * unsynchronized, stratum zero, reference ID the four-character
2848182007Sroberto	 * kiss code and system root delay. Note the rate limit on these
2849182007Sroberto	 * packets. Once a second initialize a bucket counter. Every
2850182007Sroberto	 * packet sent decrements the counter until reaching zero. If
2851182007Sroberto	 * the counter is zero, drop the kiss.
2852182007Sroberto	 */
2853182007Sroberto	if (mask & RES_LIMITED) {
2854182007Sroberto		sys_limitrejected++;
2855132454Sroberto		if (sys_kod == 0 || !(mask & RES_DEMOBILIZE))
285682505Sroberto			return;
2857132454Sroberto
2858132454Sroberto		sys_kod--;
2859132454Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
2860132454Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
2861132454Sroberto		xpkt.stratum = STRATUM_UNSPEC;
2862182007Sroberto		memcpy(&xpkt.refid, "RATE", 4);
2863182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
2864182007Sroberto		xpkt.rootdispersion =
2865182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2866182007Sroberto
2867182007Sroberto	/*
2868182007Sroberto	 * This is a normal packet. Use the system variables.
2869182007Sroberto	 */
2870182007Sroberto	} else if (sys_stratum < sys_orphan) {
287182505Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
287282505Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
287382505Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
287482505Sroberto		xpkt.refid = sys_refid;
2875182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
2876182007Sroberto		xpkt.rootdispersion =
2877182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2878182007Sroberto
2879182007Sroberto	/*
2880182007Sroberto	 * This is a orphan child packet. The host is synchronized to an
2881182007Sroberto	 * orphan parent. Show leap synchronized, orphan stratum, system
2882182007Sroberto	 * reference ID and orphan root delay.
2883182007Sroberto	 */
2884182007Sroberto	} else if (sys_peer != NULL) {
2885182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2886182007Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
2887182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2888182007Sroberto		xpkt.refid = sys_refid;
2889182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay));
2890182007Sroberto		xpkt.rootdispersion =
2891182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2892182007Sroberto
2893182007Sroberto	/*
2894182007Sroberto	 * This is an orphan parent. Show leap synchronized, orphan
2895182007Sroberto	 * stratum, loopack reference ID and zero root delay.
2896182007Sroberto	 */
2897182007Sroberto	} else {
2898182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2899182007Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
2900182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2901182007Sroberto		xpkt.refid = htonl(LOOPBACKADR);
2902182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(0));
2903182007Sroberto		xpkt.rootdispersion = HTONS_FP(DTOFP(0));
290482505Sroberto	}
290554359Sroberto	xpkt.ppoll = rpkt->ppoll;
290654359Sroberto	xpkt.precision = sys_precision;
2907182007Sroberto	xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion));
290854359Sroberto	HTONL_FP(&sys_reftime, &xpkt.reftime);
290954359Sroberto	xpkt.org = rpkt->xmt;
291054359Sroberto	HTONL_FP(&rbufp->recv_time, &xpkt.rec);
291182505Sroberto
291282505Sroberto	/*
291382505Sroberto	 * If the received packet contains a MAC, the transmitted packet
291482505Sroberto	 * is authenticated and contains a MAC. If not, the transmitted
291582505Sroberto	 * packet is not authenticated.
291682505Sroberto	 */
291754359Sroberto	sendlen = LEN_PKT_NOMAC;
291882505Sroberto	if (rbufp->recv_length == sendlen) {
291954359Sroberto		get_systime(&xmt_ts);
292054359Sroberto		HTONL_FP(&xmt_ts, &xpkt.xmt);
292182505Sroberto		sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt,
292256749Sroberto		    sendlen);
292354359Sroberto#ifdef DEBUG
292454359Sroberto		if (debug)
292582505Sroberto			printf("transmit: at %ld %s->%s mode %d\n",
2926132454Sroberto			    current_time, stoa(&rbufp->dstadr->sin),
2927132454Sroberto			    stoa(&rbufp->recv_srcadr), xmode);
292854359Sroberto#endif
292982505Sroberto		return;
293082505Sroberto	}
293154359Sroberto
293282505Sroberto	/*
293382505Sroberto	 * The received packet contains a MAC, so the transmitted packet
2934182007Sroberto	 * must be authenticated. For symmetric key cryptography, use
2935182007Sroberto	 * the predefined and trusted symmetric keys to generate the
2936182007Sroberto	 * cryptosum. For autokey cryptography, use the server private
2937182007Sroberto	 * value to generate the cookie, which is unique for every
2938182007Sroberto	 * source-destination-key ID combination.
293982505Sroberto	 */
2940132454Sroberto#ifdef OPENSSL
294182505Sroberto	if (xkeyid > NTP_MAXKEY) {
294282505Sroberto		keyid_t cookie;
294382505Sroberto
294454359Sroberto		/*
294582505Sroberto		 * The only way to get here is a reply to a legitimate
294682505Sroberto		 * client request message, so the mode must be
294782505Sroberto		 * MODE_SERVER. If an extension field is present, there
294882505Sroberto		 * can be only one and that must be a command. Do what
294982505Sroberto		 * needs, but with private value of zero so the poor
295082505Sroberto		 * jerk can decode it. If no extension field is present,
295182505Sroberto		 * use the cookie to generate the session key.
295254359Sroberto		 */
295382505Sroberto		cookie = session_key(&rbufp->recv_srcadr,
295482505Sroberto		    &rbufp->dstadr->sin, 0, sys_private, 0);
2955182007Sroberto		if (rbufp->recv_length >= (int)(sendlen + MAX_MAC_LEN +
2956182007Sroberto		    2 * sizeof(u_int32))) {
295782505Sroberto			session_key(&rbufp->dstadr->sin,
295882505Sroberto			    &rbufp->recv_srcadr, xkeyid, 0, 2);
2959132454Sroberto			temp32 = CRYPTO_RESP;
2960132454Sroberto			rpkt->exten[0] |= htonl(temp32);
2961132454Sroberto			sendlen += crypto_xmit(&xpkt,
2962132454Sroberto			    &rbufp->recv_srcadr, sendlen,
2963132454Sroberto			    (struct exten *)rpkt->exten, cookie);
296482505Sroberto		} else {
296582505Sroberto			session_key(&rbufp->dstadr->sin,
296682505Sroberto			    &rbufp->recv_srcadr, xkeyid, cookie, 2);
296782505Sroberto		}
296882505Sroberto	}
2969132454Sroberto#endif /* OPENSSL */
297082505Sroberto	get_systime(&xmt_ts);
297182505Sroberto	L_ADD(&xmt_ts, &sys_authdelay);
297282505Sroberto	HTONL_FP(&xmt_ts, &xpkt.xmt);
297382505Sroberto	authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen);
297482505Sroberto	sendlen += authlen;
2975132454Sroberto#ifdef OPENSSL
297682505Sroberto	if (xkeyid > NTP_MAXKEY)
297782505Sroberto		authtrust(xkeyid, 0);
2978132454Sroberto#endif /* OPENSSL */
297982505Sroberto	get_systime(&xmt_tx);
298082505Sroberto	if (sendlen > sizeof(xpkt)) {
298182505Sroberto		msyslog(LOG_ERR, "buffer overflow %u", sendlen);
2982132454Sroberto		exit (-1);
298382505Sroberto	}
298482505Sroberto	sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen);
298582505Sroberto
298682505Sroberto	/*
298782505Sroberto	 * Calculate the encryption delay. Keep the minimum over the
298882505Sroberto	 * latest two samples.
298982505Sroberto	 */
299082505Sroberto	L_SUB(&xmt_tx, &xmt_ts);
299182505Sroberto	L_ADD(&xmt_tx, &sys_authdelay);
299282505Sroberto	sys_authdly[1] = sys_authdly[0];
299382505Sroberto	sys_authdly[0] = xmt_tx.l_uf;
299482505Sroberto	if (sys_authdly[0] < sys_authdly[1])
299582505Sroberto		sys_authdelay.l_uf = sys_authdly[0];
299682505Sroberto	else
299782505Sroberto		sys_authdelay.l_uf = sys_authdly[1];
299854359Sroberto#ifdef DEBUG
299982505Sroberto	if (debug)
300082505Sroberto		printf(
300182505Sroberto		    "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n",
300282505Sroberto		    current_time, ntoa(&rbufp->dstadr->sin),
3003132454Sroberto		    ntoa(&rbufp->recv_srcadr), xmode, xkeyid, sendlen -
3004132454Sroberto		    authlen, authlen);
300554359Sroberto#endif
300654359Sroberto}
300754359Sroberto
300882505Sroberto
3009132454Sroberto#ifdef OPENSSL
301054359Sroberto/*
301182505Sroberto * key_expire - purge the key list
301254359Sroberto */
301382505Srobertovoid
301482505Srobertokey_expire(
301582505Sroberto	struct peer *peer	/* peer structure pointer */
301654359Sroberto	)
301754359Sroberto{
301854359Sroberto	int i;
301954359Sroberto
3020132454Sroberto	if (peer->keylist != NULL) {
302182505Sroberto		for (i = 0; i <= peer->keynumber; i++)
302282505Sroberto			authtrust(peer->keylist[i], 0);
302382505Sroberto		free(peer->keylist);
302482505Sroberto		peer->keylist = NULL;
302554359Sroberto	}
3026132454Sroberto	value_free(&peer->sndval);
3027132454Sroberto	peer->keynumber = 0;
302882505Sroberto#ifdef DEBUG
302982505Sroberto	if (debug)
303082505Sroberto		printf("key_expire: at %lu\n", current_time);
303182505Sroberto#endif
303254359Sroberto}
3033132454Sroberto#endif /* OPENSSL */
303454359Sroberto
3035132454Sroberto
303654359Sroberto/*
3037132454Sroberto * Determine if the peer is unfit for synchronization
3038132454Sroberto *
3039132454Sroberto * A peer is unfit for synchronization if
3040182007Sroberto * > TEST10 bad leap or stratum below floor or at or above ceiling
3041182007Sroberto * > TEST11 root distance exceeded
3042182007Sroberto * > TEST12 a direct or indirect synchronization loop would form
3043182007Sroberto * > TEST13 unreachable or noselect
3044132454Sroberto */
3045182007Srobertoint				/* FALSE if fit, TRUE if unfit */
3046132454Srobertopeer_unfit(
3047132454Sroberto	struct peer *peer	/* peer structure pointer */
3048132454Sroberto	)
3049132454Sroberto{
3050182007Sroberto	int	rval = 0;
3051182007Sroberto
3052182007Sroberto	/*
3053182007Sroberto	 * A stratum error occurs if (1) the server has never been
3054182007Sroberto	 * synchronized, (2) the server stratum is below the floor or
3055182007Sroberto	 * greater than or equal to the ceiling, (3) the system stratum
3056182007Sroberto	 * is below the orphan stratum and the server stratum is greater
3057182007Sroberto	 * than or equal to the orphan stratum.
3058182007Sroberto	 */
3059182007Sroberto	if (peer->leap == LEAP_NOTINSYNC || peer->stratum < sys_floor ||
3060182007Sroberto	    peer->stratum >= sys_ceiling || (sys_stratum < sys_orphan &&
3061182007Sroberto	    peer->stratum >= sys_orphan))
3062182007Sroberto		rval |= TEST10;		/* stratum out of bounds */
3063182007Sroberto
3064182007Sroberto	/*
3065182007Sroberto	 * A distance error occurs if the root distance is greater than
3066182007Sroberto	 * or equal to the distance threshold plus the increment due to
3067182007Sroberto	 * one poll interval.
3068182007Sroberto	 */
3069182007Sroberto	if (root_distance(peer) >= sys_maxdist + clock_phi *
3070182007Sroberto	    ULOGTOD(sys_poll))
3071182007Sroberto		rval |= TEST11;		/* distance exceeded */
3072182007Sroberto
3073182007Sroberto	/*
3074182007Sroberto	 * A loop error occurs if the remote peer is synchronized to the
3075182007Sroberto	 * local peer of if the remote peer is synchronized to the same
3076182007Sroberto	 * server as the local peer, but only if the remote peer is not
3077182007Sroberto	 * the orphan parent.
3078182007Sroberto	 */
3079182007Sroberto	if (peer->stratum > 1 && peer->refid != htonl(LOOPBACKADR) &&
3080182007Sroberto	    ((!peer->dstadr || peer->refid == peer->dstadr->addr_refid) ||
3081182007Sroberto	    peer->refid == sys_refid))
3082182007Sroberto		rval |= TEST12;		/* synch loop */
3083182007Sroberto
3084182007Sroberto	/*
3085182007Sroberto	 * An unreachable error occurs if the server is unreachable or
3086182007Sroberto	 * the noselect bit is set.
3087182007Sroberto	 */
3088182007Sroberto	if (!peer->reach || peer->flags & FLAG_NOSELECT)
3089182007Sroberto		rval |= TEST13;		/* unreachable */
3090182007Sroberto
3091182007Sroberto	peer->flash &= ~PEER_TEST_MASK;
3092182007Sroberto	peer->flash |= rval;
3093182007Sroberto	return (rval);
3094132454Sroberto}
3095132454Sroberto
3096132454Sroberto
3097132454Sroberto/*
309854359Sroberto * Find the precision of this particular machine
309954359Sroberto */
3100132454Sroberto#define MINSTEP 100e-9		/* minimum clock increment (s) */
3101132454Sroberto#define MAXSTEP 20e-3		/* maximum clock increment (s) */
3102132454Sroberto#define MINLOOPS 5		/* minimum number of step samples */
310354359Sroberto
310454359Sroberto/*
3105132454Sroberto * This routine calculates the system precision, defined as the minimum
3106182007Sroberto * of a sequence of differences between successive readings of the
3107132454Sroberto * system clock. However, if the system clock can be read more than once
3108132454Sroberto * during a tick interval, the difference can be zero or one LSB unit,
3109132454Sroberto * where the LSB corresponds to one nanosecond or one microsecond.
3110132454Sroberto * Conceivably, if some other process preempts this one and reads the
3111132454Sroberto * clock, the difference can be more than one LSB unit.
3112132454Sroberto *
3113132454Sroberto * For hardware clock frequencies of 10 MHz or less, we assume the
3114132454Sroberto * logical clock advances only at the hardware clock tick. For higher
3115132454Sroberto * frequencies, we assume the logical clock can advance no more than 100
3116132454Sroberto * nanoseconds between ticks.
311754359Sroberto */
311854359Srobertoint
311954359Srobertodefault_get_precision(void)
312054359Sroberto{
3121132454Sroberto	l_fp	val;		/* current seconds fraction */
3122132454Sroberto	l_fp	last;		/* last seconds fraction */
3123132454Sroberto	l_fp	diff;		/* difference */
3124132454Sroberto	double	tick;		/* computed tick value */
3125132454Sroberto	double	dtemp;		/* scratch */
3126132454Sroberto	int	i;		/* log2 precision */
312754359Sroberto
3128132454Sroberto	/*
3129132454Sroberto	 * Loop to find tick value in nanoseconds. Toss out outlyer
3130132454Sroberto	 * values less than the minimun tick value. In wacky cases, use
3131132454Sroberto	 * the default maximum value.
313254359Sroberto	 */
3133132454Sroberto	get_systime(&last);
3134132454Sroberto	tick = MAXSTEP;
3135132454Sroberto	for (i = 0; i < MINLOOPS;) {
3136132454Sroberto		get_systime(&val);
3137132454Sroberto		diff = val;
3138132454Sroberto		L_SUB(&diff, &last);
3139132454Sroberto		last = val;
3140132454Sroberto		LFPTOD(&diff, dtemp);
3141132454Sroberto		if (dtemp < MINSTEP)
3142132454Sroberto			continue;
3143132454Sroberto		i++;
3144132454Sroberto		if (dtemp < tick)
3145132454Sroberto			tick = dtemp;
314654359Sroberto	}
3147132454Sroberto
3148132454Sroberto	/*
3149132454Sroberto	 * Find the nearest power of two.
3150132454Sroberto	 */
3151132454Sroberto	NLOG(NLOG_SYSEVENT)
3152132454Sroberto	    msyslog(LOG_INFO, "precision = %.3f usec", tick * 1e6);
3153132454Sroberto	for (i = 0; tick <= 1; i++)
3154132454Sroberto		tick *= 2;
3155132454Sroberto	if (tick - 1. > 1. - tick / 2)
3156132454Sroberto		i--;
3157132454Sroberto	return (-i);
315854359Sroberto}
315954359Sroberto
3160132454Sroberto
316154359Sroberto/*
3162132454Sroberto * kod_proto - called once per second to limit kiss-of-death packets
3163132454Sroberto */
3164132454Srobertovoid
3165132454Srobertokod_proto(void)
3166132454Sroberto{
3167132454Sroberto	sys_kod = sys_kod_rate;
3168132454Sroberto}
3169132454Sroberto
3170132454Sroberto
3171132454Sroberto/*
317254359Sroberto * init_proto - initialize the protocol module's data
317354359Sroberto */
317454359Srobertovoid
317554359Srobertoinit_proto(void)
317654359Sroberto{
3177132454Sroberto	l_fp	dummy;
3178132454Sroberto	int	i;
317954359Sroberto
318054359Sroberto	/*
318154359Sroberto	 * Fill in the sys_* stuff.  Default is don't listen to
318254359Sroberto	 * broadcasting, authenticate.
318354359Sroberto	 */
318454359Sroberto	sys_leap = LEAP_NOTINSYNC;
318554359Sroberto	sys_stratum = STRATUM_UNSPEC;
3186132454Sroberto	memcpy(&sys_refid, "INIT", 4);
318754359Sroberto	sys_precision = (s_char)default_get_precision();
318882505Sroberto	sys_jitter = LOGTOD(sys_precision);
318954359Sroberto	sys_rootdelay = 0;
3190182007Sroberto	sys_orphandelay = (double)(ntp_random() & 0xffff) / 65536. *
3191182007Sroberto	    sys_maxdist;
319254359Sroberto	sys_rootdispersion = 0;
319354359Sroberto	L_CLR(&sys_reftime);
319482505Sroberto	sys_peer = NULL;
319582505Sroberto	sys_survivors = 0;
319654359Sroberto	get_systime(&dummy);
3197132454Sroberto	sys_manycastserver = 0;
319854359Sroberto	sys_bclient = 0;
319954359Sroberto	sys_bdelay = DEFBROADDELAY;
3200132454Sroberto	sys_calldelay = BURST_DELAY;
320154359Sroberto	sys_authenticate = 1;
320254359Sroberto	L_CLR(&sys_authdelay);
320354359Sroberto	sys_authdly[0] = sys_authdly[1] = 0;
320454359Sroberto	sys_stattime = 0;
3205132454Sroberto	proto_clr_stats();
3206132454Sroberto	for (i = 0; i < MAX_TTL; i++) {
3207132454Sroberto		sys_ttl[i] = (u_char)((i * 256) / MAX_TTL);
3208132454Sroberto		sys_ttlmax = i;
3209132454Sroberto	}
3210132454Sroberto#ifdef OPENSSL
321154359Sroberto	sys_automax = 1 << NTP_AUTOMAX;
3212132454Sroberto#endif /* OPENSSL */
321354359Sroberto
321454359Sroberto	/*
321554359Sroberto	 * Default these to enable
321654359Sroberto	 */
321754359Sroberto	ntp_enable = 1;
321854359Sroberto#ifndef KERNEL_FLL_BUG
321954359Sroberto	kern_enable = 1;
322054359Sroberto#endif
322182505Sroberto	pps_enable = 0;
322254359Sroberto	stats_control = 1;
322354359Sroberto}
322454359Sroberto
322554359Sroberto
322654359Sroberto/*
322754359Sroberto * proto_config - configure the protocol module
322854359Sroberto */
322954359Srobertovoid
323054359Srobertoproto_config(
3231132454Sroberto	int	item,
3232132454Sroberto	u_long	value,
3233132454Sroberto	double	dvalue,
3234132454Sroberto	struct sockaddr_storage* svalue
323554359Sroberto	)
323654359Sroberto{
323754359Sroberto	/*
323854359Sroberto	 * Figure out what he wants to change, then do it
323954359Sroberto	 */
324054359Sroberto	switch (item) {
3241132454Sroberto
3242132454Sroberto	/*
3243132454Sroberto	 * Turn on/off kernel discipline.
3244132454Sroberto	 */
324556749Sroberto	case PROTO_KERNEL:
324654359Sroberto		kern_enable = (int)value;
324754359Sroberto		break;
324854359Sroberto
3249132454Sroberto	/*
3250132454Sroberto	 * Turn on/off clock discipline.
3251132454Sroberto	 */
325256749Sroberto	case PROTO_NTP:
325354359Sroberto		ntp_enable = (int)value;
325454359Sroberto		break;
325554359Sroberto
3256132454Sroberto	/*
3257132454Sroberto	 * Turn on/off monitoring.
3258132454Sroberto	 */
325956749Sroberto	case PROTO_MONITOR:
326054359Sroberto		if (value)
326154359Sroberto			mon_start(MON_ON);
326254359Sroberto		else
326354359Sroberto			mon_stop(MON_ON);
326454359Sroberto		break;
326554359Sroberto
3266132454Sroberto	/*
3267132454Sroberto	 * Turn on/off statistics.
3268132454Sroberto	 */
326956749Sroberto	case PROTO_FILEGEN:
327054359Sroberto		stats_control = (int)value;
327154359Sroberto		break;
327254359Sroberto
3273132454Sroberto	/*
3274182007Sroberto	 * Turn on/off enable broadcasts.
3275132454Sroberto	 */
327656749Sroberto	case PROTO_BROADCLIENT:
327754359Sroberto		sys_bclient = (int)value;
3278182007Sroberto		if (sys_bclient == 0)
3279182007Sroberto			io_unsetbclient();
3280182007Sroberto		else
328154359Sroberto			io_setbclient();
328254359Sroberto		break;
328354359Sroberto
3284132454Sroberto	/*
3285182007Sroberto	 * Turn on/off PPS discipline.
3286182007Sroberto	 */
3287182007Sroberto	case PROTO_PPS:
3288182007Sroberto		pps_enable = (int)value;
3289182007Sroberto		break;
3290182007Sroberto
3291182007Sroberto	/*
3292132454Sroberto	 * Add muliticast group address.
3293132454Sroberto	 */
329456749Sroberto	case PROTO_MULTICAST_ADD:
3295132454Sroberto		if (svalue)
3296132454Sroberto		    io_multicast_add(*svalue);
3297182007Sroberto		sys_bclient = 1;
329854359Sroberto		break;
329954359Sroberto
3300132454Sroberto	/*
3301132454Sroberto	 * Delete multicast group address.
3302132454Sroberto	 */
330356749Sroberto	case PROTO_MULTICAST_DEL:
3304132454Sroberto		if (svalue)
3305132454Sroberto		    io_multicast_del(*svalue);
330654359Sroberto		break;
330754359Sroberto
3308132454Sroberto	/*
3309132454Sroberto	 * Set default broadcast delay.
3310132454Sroberto	 */
331156749Sroberto	case PROTO_BROADDELAY:
331254359Sroberto		sys_bdelay = dvalue;
331354359Sroberto		break;
331454359Sroberto
3315132454Sroberto	/*
3316132454Sroberto	 * Set modem call delay.
3317132454Sroberto	 */
3318132454Sroberto	case PROTO_CALLDELAY:
3319132454Sroberto		sys_calldelay = (int)value;
3320132454Sroberto		break;
3321132454Sroberto
3322132454Sroberto	/*
3323182007Sroberto	 * Turn on/off authentication to mobilize ephemeral
3324182007Sroberto	 * associations.
3325132454Sroberto	 */
332656749Sroberto	case PROTO_AUTHENTICATE:
332754359Sroberto		sys_authenticate = (int)value;
332854359Sroberto		break;
332954359Sroberto
3330132454Sroberto	/*
3331182007Sroberto	 * Set minimum number of survivors.
3332132454Sroberto	 */
3333182007Sroberto	case PROTO_MINCLOCK:
3334182007Sroberto		sys_minclock = (int)dvalue;
333582505Sroberto		break;
333682505Sroberto
3337132454Sroberto	/*
3338182007Sroberto	 * Set maximum number of preemptable associations.
3339132454Sroberto	 */
3340182007Sroberto	case PROTO_MAXCLOCK:
3341182007Sroberto		sys_maxclock = (int)dvalue;
3342132454Sroberto		break;
3343132454Sroberto
3344132454Sroberto	/*
3345182007Sroberto	 * Set minimum number of survivors.
3346132454Sroberto	 */
3347132454Sroberto	case PROTO_MINSANE:
3348132454Sroberto		sys_minsane = (int)dvalue;
3349132454Sroberto		break;
3350132454Sroberto
3351132454Sroberto	/*
3352182007Sroberto	 * Set stratum floor.
3353132454Sroberto	 */
3354132454Sroberto	case PROTO_FLOOR:
3355132454Sroberto		sys_floor = (int)dvalue;
3356132454Sroberto		break;
3357132454Sroberto
3358132454Sroberto	/*
3359182007Sroberto	 * Set stratum ceiling.
3360132454Sroberto	 */
3361132454Sroberto	case PROTO_CEILING:
3362132454Sroberto		sys_ceiling = (int)dvalue;
3363132454Sroberto		break;
3364132454Sroberto
3365132454Sroberto	/*
3366182007Sroberto	 * Set orphan stratum.
3367132454Sroberto	 */
3368182007Sroberto	case PROTO_ORPHAN:
3369182007Sroberto		sys_orphan = (int)dvalue;
3370182007Sroberto		break;
3371182007Sroberto
3372182007Sroberto	/*
3373182007Sroberto	 * Set cohort switch.
3374182007Sroberto	 */
3375132454Sroberto	case PROTO_COHORT:
3376182007Sroberto		sys_cohort = (int)dvalue;
3377132454Sroberto		break;
3378182007Sroberto
3379132454Sroberto	/*
3380182007Sroberto	 * Set minimum dispersion increment.
3381132454Sroberto	 */
3382182007Sroberto	case PROTO_MINDISP:
3383182007Sroberto		sys_mindisp = dvalue;
3384182007Sroberto		break;
3385182007Sroberto
3386182007Sroberto	/*
3387182007Sroberto	 * Set maximum distance (select threshold).
3388182007Sroberto	 */
3389182007Sroberto	case PROTO_MAXDIST:
3390182007Sroberto		sys_maxdist = dvalue;
3391182007Sroberto		break;
3392182007Sroberto
3393182007Sroberto	/*
3394182007Sroberto	 * Set anticlockhop threshold.
3395182007Sroberto	 */
3396182007Sroberto	case PROTO_MAXHOP:
3397182007Sroberto		sys_maxhop = (int)dvalue;
3398182007Sroberto		break;
3399182007Sroberto
3400182007Sroberto	/*
3401182007Sroberto	 * Set adjtime() resolution (s).
3402182007Sroberto	 */
3403132454Sroberto	case PROTO_ADJ:
3404132454Sroberto		sys_tick = dvalue;
3405132454Sroberto		break;
3406132454Sroberto
3407182007Sroberto	/*
3408182007Sroberto	 * Set manycast beacon interval.
3409182007Sroberto	 */
3410182007Sroberto	case PROTO_BEACON:
3411182007Sroberto		sys_beacon = (int)dvalue;
3412182007Sroberto		break;
3413182007Sroberto
341482505Sroberto#ifdef REFCLOCK
3415132454Sroberto	/*
3416132454Sroberto	 * Turn on/off refclock calibrate
3417132454Sroberto	 */
341882505Sroberto	case PROTO_CAL:
341982505Sroberto		cal_enable = (int)value;
342082505Sroberto		break;
3421182007Sroberto#endif /* REFCLOCK */
342256749Sroberto	default:
342356749Sroberto
342454359Sroberto		/*
3425132454Sroberto		 * Log this error.
342654359Sroberto		 */
3427132454Sroberto		msyslog(LOG_INFO,
3428182007Sroberto		    "proto_config: illegal item %d, value %ld", item,
3429182007Sroberto		    value);
343054359Sroberto	}
343154359Sroberto}
343254359Sroberto
343354359Sroberto
343454359Sroberto/*
343554359Sroberto * proto_clr_stats - clear protocol stat counters
343654359Sroberto */
343754359Srobertovoid
343854359Srobertoproto_clr_stats(void)
343954359Sroberto{
3440132454Sroberto	sys_stattime = current_time;
3441132454Sroberto	sys_received = 0;
3442132454Sroberto	sys_processed = 0;
3443132454Sroberto	sys_newversionpkt = 0;
344454359Sroberto	sys_oldversionpkt = 0;
344554359Sroberto	sys_unknownversion = 0;
3446132454Sroberto	sys_restricted = 0;
344754359Sroberto	sys_badlength = 0;
344854359Sroberto	sys_badauth = 0;
344954359Sroberto	sys_limitrejected = 0;
345054359Sroberto}
3451