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++;
652276158Sdes			return;
653132454Sroberto		} else {
654182007Sroberto			is_authentic = AUTH_OK;
655132454Sroberto		}
656132454Sroberto#ifdef OPENSSL
65782505Sroberto		if (skeyid > NTP_MAXKEY)
65882505Sroberto			authtrust(skeyid, 0);
659132454Sroberto#endif /* OPENSSL */
66054359Sroberto#ifdef DEBUG
66154359Sroberto		if (debug)
66254359Sroberto			printf(
66382505Sroberto			    "receive: at %ld %s<-%s mode %d code %d keyid %08x len %d mac %d auth %d\n",
664132454Sroberto			    current_time, stoa(dstadr_sin),
665132454Sroberto			    stoa(&rbufp->recv_srcadr), hismode, retcode,
666182007Sroberto			    skeyid, authlen, has_mac, is_authentic);
66754359Sroberto#endif
66854359Sroberto	}
66954359Sroberto
67054359Sroberto	/*
67182505Sroberto	 * The association matching rules are implemented by a set of
672182007Sroberto	 * routines and an association table. A packet matching an
673182007Sroberto	 * association is processed by the peer process for that
674182007Sroberto	 * association. If there are no errors, an ephemeral association
675182007Sroberto	 * is mobilized: a broadcast packet mobilizes a broadcast client
676132454Sroberto	 * aassociation; a manycast server packet mobilizes a manycast
677132454Sroberto	 * client association; a symmetric active packet mobilizes a
678182007Sroberto	 * symmetric passive association.
67954359Sroberto	 */
68054359Sroberto	switch (retcode) {
681182007Sroberto
682182007Sroberto	/*
683182007Sroberto	 * This is a client mode packet not matching any association. If
684182007Sroberto	 * an ordinary client, simply toss a server mode packet back
685182007Sroberto	 * over the fence. If a manycast client, we have to work a
686182007Sroberto	 * little harder.
687182007Sroberto	 */
68854359Sroberto	case AM_FXMIT:
68954359Sroberto
69056749Sroberto		/*
691182007Sroberto		 * The vanilla case is when this is not a multicast
692182007Sroberto		 * interface. If authentication succeeds, return a
693182007Sroberto		 * server mode packet; if not and the key ID is nonzero,
694182007Sroberto		 * return a crypto-NAK.
69556749Sroberto		 */
696182007Sroberto		if (!(rbufp->dstadr->flags & INT_MCASTOPEN)) {
697182007Sroberto			if (AUTH(restrict_mask & RES_DONTTRUST,
698182007Sroberto			   is_authentic))
699182007Sroberto				fast_xmit(rbufp, MODE_SERVER, skeyid,
700182007Sroberto				    restrict_mask);
701182007Sroberto			else if (is_authentic == AUTH_ERROR)
702182007Sroberto				fast_xmit(rbufp, MODE_SERVER, 0,
703182007Sroberto				    restrict_mask);
704182007Sroberto			return;			/* hooray */
70556749Sroberto		}
70654359Sroberto
70756749Sroberto		/*
708182007Sroberto		 * This must be manycast. Do not respond if not
709182007Sroberto		 * configured as a manycast server.
71056749Sroberto		 */
711182007Sroberto		if (!sys_manycastserver) {
712182007Sroberto			sys_restricted++;
713182007Sroberto			return;			/* not enabled */
714182007Sroberto		}
715182007Sroberto
716182007Sroberto		/*
717182007Sroberto		 * Do not respond if unsynchronized or stratum is below
718182007Sroberto		 * the floor or at or above the ceiling.
719182007Sroberto		 */
720182007Sroberto		if (sys_leap == LEAP_NOTINSYNC || sys_stratum <
721182007Sroberto		    sys_floor || sys_stratum >= sys_ceiling)
722182007Sroberto			return;			/* bad stratum */
723182007Sroberto
724182007Sroberto		/*
725182007Sroberto		 * Do not respond if our stratum is greater than the
726182007Sroberto		 * manycaster or it has already synchronized to us.
727182007Sroberto		 */
728182007Sroberto		if (sys_peer == NULL || hisstratum < sys_stratum ||
729182007Sroberto		    (sys_cohort && hisstratum == sys_stratum) ||
730182007Sroberto		    rbufp->dstadr->addr_refid == pkt->refid)
731182007Sroberto			return;			/* no help */
732182007Sroberto
733182007Sroberto		/*
734182007Sroberto		 * Respond only if authentication succeeds. Don't do a
735182007Sroberto		 * crypto-NAK, as that would not be useful.
736182007Sroberto		 */
737182007Sroberto		if (AUTH(restrict_mask & RES_DONTTRUST, is_authentic))
73882505Sroberto			fast_xmit(rbufp, MODE_SERVER, skeyid,
73982505Sroberto			    restrict_mask);
74056749Sroberto
741182007Sroberto		return;				/* hooray */
742182007Sroberto
743182007Sroberto	/*
744182007Sroberto	 * This is a server mode packet returned in response to a client
745182007Sroberto	 * mode packet sent to a multicast group address. The origin
746182007Sroberto	 * timestamp is a good nonce to reliably associate the reply
747182007Sroberto	 * with what was sent. If there is no match, that's curious and
748182007Sroberto	 * could be an intruder attempting to clog, so we just ignore
749182007Sroberto	 * it.
750182007Sroberto	 *
751182007Sroberto	 * If the packet is authentic and the manycast association is
752182007Sroberto	 * found, we mobilize a client association and copy pertinent
753182007Sroberto	 * variables from the manycast association to the new client
754182007Sroberto	 * association. If not, just ignore the packet.
755182007Sroberto	 *
756182007Sroberto	 * There is an implosion hazard at the manycast client, since
757182007Sroberto	 * the manycast servers send the server packet immediately. If
758182007Sroberto	 * the guy is already here, don't fire up a duplicate.
759182007Sroberto	 */
76054359Sroberto	case AM_MANYCAST:
761182007Sroberto		if (!AUTH(sys_authenticate | (restrict_mask &
762182007Sroberto		    (RES_NOPEER | RES_DONTTRUST)), is_authentic))
763182007Sroberto			return;			/* bad auth */
76454359Sroberto
765182007Sroberto		if ((peer2 = findmanycastpeer(rbufp)) == NULL) {
766132454Sroberto			sys_restricted++;
767182007Sroberto			return;			/* not enabled */
768132454Sroberto		}
769182007Sroberto		if ((peer = newpeer(&rbufp->recv_srcadr,
770182007Sroberto		    rbufp->dstadr, MODE_CLIENT,
771182007Sroberto		    hisversion, NTP_MINDPOLL, NTP_MAXDPOLL,
772182007Sroberto		    FLAG_IBURST | FLAG_PREEMPT, MDF_UCAST | MDF_ACLNT,
773182007Sroberto		    0, skeyid)) == NULL)
774132454Sroberto			return;			/* system error */
775132454Sroberto
776132454Sroberto		/*
777132454Sroberto		 * We don't need these, but it warms the billboards.
778132454Sroberto		 */
779132454Sroberto		peer->ttl = peer2->ttl;
78056749Sroberto		break;
78156749Sroberto
782182007Sroberto	/*
783182007Sroberto	 * This is the first packet received from a broadcast server. If
784182007Sroberto	 * the packet is authentic and we are enabled as broadcast
785182007Sroberto	 * client, mobilize a broadcast client association. We don't
786182007Sroberto	 * kiss any frogs here.
787182007Sroberto	 */
788182007Sroberto	case AM_NEWBCL:
789182007Sroberto		if (!AUTH(sys_authenticate | (restrict_mask &
790182007Sroberto		    (RES_NOPEER | RES_DONTTRUST)), is_authentic))
791182007Sroberto			return;			/* bad auth */
79254359Sroberto
79356749Sroberto		/*
794182007Sroberto		 * Do not respond if unsynchronized or stratum is below
795182007Sroberto		 * the floor or at or above the ceiling.
79656749Sroberto		 */
797182007Sroberto		if (hisleap == LEAP_NOTINSYNC || hisstratum <
798182007Sroberto		    sys_floor || hisstratum >= sys_ceiling)
799182007Sroberto			return;			/* bad stratum */
800132454Sroberto
801182007Sroberto		switch (sys_bclient) {
80256749Sroberto
80356749Sroberto		/*
804182007Sroberto		 * If not enabled, just skedaddle.
80556749Sroberto		 */
806182007Sroberto		case 0:
807132454Sroberto			sys_restricted++;
808182007Sroberto			return;			/* not enabled */
80982505Sroberto
810132454Sroberto		/*
811182007Sroberto		 * Execute the initial volley in order to calibrate the
812182007Sroberto		 * propagation delay and run the Autokey protocol, if
813182007Sroberto		 * enabled.
814132454Sroberto		 */
815182007Sroberto		case 1:
816182007Sroberto			if ((peer = newpeer(&rbufp->recv_srcadr,
817182007Sroberto			    rbufp->dstadr, MODE_CLIENT, hisversion,
818182007Sroberto			    NTP_MINDPOLL, NTP_MAXDPOLL, FLAG_MCAST |
819182007Sroberto			    FLAG_IBURST, MDF_BCLNT, 0, skeyid)) ==
820182007Sroberto			    NULL)
821182007Sroberto				return;		/* system error */
822182007Sroberto#ifdef OPENSSL
823182007Sroberto			if (skeyid > NTP_MAXKEY)
824182007Sroberto				crypto_recv(peer, rbufp);
825132454Sroberto#endif /* OPENSSL */
826182007Sroberto			return;			/* hooray */
82756749Sroberto
828132454Sroberto
829132454Sroberto		/*
830182007Sroberto		 * Do not execute the initial volley.
83156749Sroberto		 */
832182007Sroberto		case 2:
833182007Sroberto#ifdef OPENSSL
834182007Sroberto			/*
835182007Sroberto			 * If a two-way exchange is not possible,
836182007Sroberto			 * neither is Autokey.
837182007Sroberto			 */
838182007Sroberto			if (skeyid > NTP_MAXKEY) {
839182007Sroberto				msyslog(LOG_INFO,
840182007Sroberto				    "receive: autokey requires two-way communication");
841182007Sroberto				return;		/* no autokey */
842182007Sroberto			}
843182007Sroberto#endif /* OPENSSL */
844182007Sroberto			if ((peer = newpeer(&rbufp->recv_srcadr,
845182007Sroberto			    rbufp->dstadr, MODE_BCLIENT, hisversion,
846182007Sroberto			    NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_BCLNT, 0,
847182007Sroberto			    skeyid)) == NULL)
848182007Sroberto				return;		/* system error */
849132454Sroberto		}
85056749Sroberto		break;
85156749Sroberto
852182007Sroberto	/*
853182007Sroberto	 * This is the first packet received from a symmetric active
854182007Sroberto	 * peer. If the packet is authentic and the first he sent,
855182007Sroberto	 * mobilize a passive association. If not, kiss the frog.
856182007Sroberto	 */
857182007Sroberto	case AM_NEWPASS:
85856749Sroberto
85956749Sroberto		/*
860182007Sroberto		 * If the inbound packet is correctly authenticated and
861182007Sroberto		 * enabled, a symmetric passive association is
862182007Sroberto		 * mobilized. If not but correctly authenticated, a
863182007Sroberto		 * symmetric active response is sent. If authentication
864182007Sroberto		 * fails, send a crypto-NAK packet.
86556749Sroberto		 */
866182007Sroberto		if (!AUTH(restrict_mask & RES_DONTTRUST, is_authentic))
867182007Sroberto		    {
868182007Sroberto			if (is_authentic == AUTH_ERROR)
869182007Sroberto				fast_xmit(rbufp, MODE_ACTIVE, 0,
870182007Sroberto				    restrict_mask);
871182007Sroberto			return;			/* bad auth */
872182007Sroberto		}
873182007Sroberto		if (!AUTH(sys_authenticate | (restrict_mask &
874182007Sroberto		    RES_NOPEER), is_authentic)) {
875182007Sroberto			fast_xmit(rbufp, MODE_ACTIVE, skeyid,
876182007Sroberto			    restrict_mask);
877182007Sroberto			return;			/* hooray */
878182007Sroberto		}
87954359Sroberto
880182007Sroberto		/*
881182007Sroberto		 * Do not respond if stratum is below the floor.
882182007Sroberto		 */
883182007Sroberto		if (hisstratum < sys_floor)
884182007Sroberto			return;			/* bad stratum */
885182007Sroberto
886182007Sroberto		if ((peer = newpeer(&rbufp->recv_srcadr,
887182007Sroberto		    rbufp->dstadr, MODE_PASSIVE, hisversion,
888182007Sroberto		    NTP_MINDPOLL, NTP_MAXDPOLL, 0, MDF_UCAST, 0,
889182007Sroberto		    skeyid)) == NULL)
890182007Sroberto			return;			/* system error */
891182007Sroberto		break;
892182007Sroberto
89354359Sroberto	/*
894182007Sroberto	 * Process regular packet. Nothing special.
89554359Sroberto	 */
896182007Sroberto	case AM_PROCPKT:
897182007Sroberto		break;
89854359Sroberto
89954359Sroberto	/*
900182007Sroberto	 * A passive packet matches a passive association. This is
901182007Sroberto	 * usually the result of reconfiguring a client on the fly. As
902182007Sroberto	 * this association might be legitamate and this packet an
903182007Sroberto	 * attempt to deny service, just ignore it.
90454359Sroberto	 */
905182007Sroberto	case AM_ERR:
906182007Sroberto		return;
907132454Sroberto
908132454Sroberto	/*
909182007Sroberto	 * For everything else there is the bit bucket.
910132454Sroberto	 */
911182007Sroberto	default:
912182007Sroberto		return;
913182007Sroberto	}
914182007Sroberto	peer->flash &= ~PKT_TEST_MASK;
915132454Sroberto
916132454Sroberto	/*
917182007Sroberto	 * Next comes a rigorous schedule of timestamp checking. If the
918182007Sroberto	 * transmit timestamp is zero, the server is horribly broken.
919132454Sroberto	 */
920182007Sroberto	if (L_ISZERO(&p_xmt)) {
921182007Sroberto		return;				/* read rfc1305 */
922132454Sroberto
923132454Sroberto	/*
924182007Sroberto	 * If the transmit timestamp duplicates a previous one, the
925182007Sroberto	 * packet is a replay. This prevents the bad guys from replaying
926182007Sroberto	 * the most recent packet, authenticated or not.
927132454Sroberto	 */
928182007Sroberto	} else if (L_ISEQU(&peer->org, &p_xmt)) {
929182007Sroberto		peer->flash |= TEST1;
930182007Sroberto		peer->oldpkt++;
931182007Sroberto		return;				/* duplicate packet */
932182007Sroberto
933132454Sroberto
934132454Sroberto	/*
935182007Sroberto	 * If this is a broadcast mode packet, skip further checking.
936132454Sroberto	 */
937182007Sroberto	} else if (hismode != MODE_BROADCAST) {
938182007Sroberto		if (L_ISZERO(&p_org))
939182007Sroberto			peer->flash |= TEST3;	/* protocol unsynch */
940182007Sroberto		else if (!L_ISEQU(&p_org, &peer->xmt))
941182007Sroberto			peer->flash |= TEST2;	/* bogus packet */
942182007Sroberto	}
943132454Sroberto
944132454Sroberto	/*
945182007Sroberto	 * Update the origin and destination timestamps. If
946182007Sroberto	 * unsynchronized or bogus abandon ship. If the crypto machine
947182007Sroberto	 * breaks, light the crypto bit and plaint the log.
948132454Sroberto	 */
949182007Sroberto	peer->org = p_xmt;
950182007Sroberto	peer->rec = rbufp->recv_time;
951182007Sroberto	if (peer->flash & PKT_TEST_MASK) {
952182007Sroberto#ifdef OPENSSL
953182007Sroberto		if (crypto_flags && (peer->flags & FLAG_SKEY)) {
954182007Sroberto			rval = crypto_recv(peer, rbufp);
955182007Sroberto			if (rval != XEVNT_OK) {
956182007Sroberto				peer_clear(peer, "CRYP");
957182007Sroberto				peer->flash |= TEST9; /* crypto error */
958182007Sroberto			}
959182007Sroberto		}
960182007Sroberto#endif /* OPENSSL */
961182007Sroberto		return;				/* unsynch */
962182007Sroberto	}
963132454Sroberto
964132454Sroberto	/*
965182007Sroberto	 * The timestamps are valid and the receive packet matches the
966182007Sroberto	 * last one sent. If the packet is a crypto-NAK, the server
967182007Sroberto	 * might have just changed keys. We reset the association
968182007Sroberto	 * and restart the protocol.
969132454Sroberto	 */
970182007Sroberto	if (is_authentic == AUTH_CRYPTO) {
971182007Sroberto		peer_clear(peer, "AUTH");
972182007Sroberto		return;				/* crypto-NAK */
973182007Sroberto
974182007Sroberto	/*
975182007Sroberto	 * If the association is authenticated, the key ID is nonzero
976182007Sroberto	 * and received packets must be authenticated. This is designed
977182007Sroberto	 * to avoid a bait-and-switch attack, which was possible in past
978182007Sroberto	 * versions. If symmetric modes, return a crypto-NAK. The peer
979182007Sroberto	 * should restart the protocol.
980182007Sroberto	 */
981182007Sroberto	} else if (!AUTH(peer->keyid || (restrict_mask & RES_DONTTRUST),
982182007Sroberto	    is_authentic)) {
983182007Sroberto		peer->flash |= TEST5;
984182007Sroberto		if (hismode == MODE_ACTIVE || hismode == MODE_PASSIVE)
985132454Sroberto			fast_xmit(rbufp, MODE_ACTIVE, 0, restrict_mask);
986182007Sroberto		return;				/* bad auth */
98754359Sroberto	}
98854359Sroberto
989182007Sroberto	/*
990182007Sroberto	 * That was hard and I am sweaty, but the packet is squeaky
991182007Sroberto	 * clean. Get on with real work.
992182007Sroberto	 */
993182007Sroberto	peer->received++;
994182007Sroberto	peer->timereceived = current_time;
995182007Sroberto	if (is_authentic == AUTH_OK)
996182007Sroberto		peer->flags |= FLAG_AUTHENTIC;
997182007Sroberto	else
998182007Sroberto		peer->flags &= ~FLAG_AUTHENTIC;
999132454Sroberto#ifdef OPENSSL
100054359Sroberto	/*
100182505Sroberto	 * More autokey dance. The rules of the cha-cha are as follows:
100282505Sroberto	 *
100382505Sroberto	 * 1. If there is no key or the key is not auto, do nothing.
100482505Sroberto	 *
1005132454Sroberto	 * 2. If this packet is in response to the one just previously
1006132454Sroberto	 *    sent or from a broadcast server, do the extension fields.
1007132454Sroberto	 *    Otherwise, assume bogosity and bail out.
1008132454Sroberto	 *
1009132454Sroberto	 * 3. If an extension field contains a verified signature, it is
101082505Sroberto	 *    self-authenticated and we sit the dance.
101182505Sroberto	 *
1012132454Sroberto	 * 4. If this is a server reply, check only to see that the
101382505Sroberto	 *    transmitted key ID matches the received key ID.
101482505Sroberto	 *
1015132454Sroberto	 * 5. Check to see that one or more hashes of the current key ID
101682505Sroberto	 *    matches the previous key ID or ultimate original key ID
101782505Sroberto	 *    obtained from the broadcaster or symmetric peer. If no
101882505Sroberto	 *    match, sit the dance and wait for timeout.
1019182007Sroberto	 *
1020182007Sroberto	 * In case of crypto error, fire the orchestra and stop dancing.
1021182007Sroberto	 * This is considered a permanant error, so light the crypto bit
1022182007Sroberto	 * to suppress further requests. If preemptable or ephemeral,
1023182007Sroberto	 * scuttle the ship.
102454359Sroberto	 */
1025132454Sroberto	if (crypto_flags && (peer->flags & FLAG_SKEY)) {
1026182007Sroberto		peer->flash |= TEST8;
1027132454Sroberto		rval = crypto_recv(peer, rbufp);
1028132454Sroberto		if (rval != XEVNT_OK) {
1029182007Sroberto			peer_clear(peer, "CRYP");
1030182007Sroberto			peer->flash |= TEST9;	/* crypto error */
1031182007Sroberto			if (peer->flags & FLAG_PREEMPT ||
1032182007Sroberto			    !(peer->flags & FLAG_CONFIG))
1033182007Sroberto				unpeer(peer);
1034182007Sroberto			return;
1035132454Sroberto
1036132454Sroberto		} else if (hismode == MODE_SERVER) {
103782505Sroberto			if (skeyid == peer->keyid)
1038182007Sroberto				peer->flash &= ~TEST8;
1039182007Sroberto		} else if (!(peer->flash & TEST8)) {
104082505Sroberto			peer->pkeyid = skeyid;
1041132454Sroberto		} else if ((ap = (struct autokey *)peer->recval.ptr) !=
1042132454Sroberto		    NULL) {
104382505Sroberto			int i;
104482505Sroberto
104582505Sroberto			for (i = 0; ; i++) {
104682505Sroberto				if (tkeyid == peer->pkeyid ||
1047132454Sroberto				    tkeyid == ap->key) {
1048182007Sroberto					peer->flash &= ~TEST8;
104982505Sroberto					peer->pkeyid = skeyid;
105082505Sroberto					break;
105182505Sroberto				}
1052132454Sroberto				if (i > ap->seq)
105382505Sroberto					break;
105454359Sroberto				tkeyid = session_key(
105582505Sroberto				    &rbufp->recv_srcadr, dstadr_sin,
105682505Sroberto				    tkeyid, pkeyid, 0);
105754359Sroberto			}
105854359Sroberto		}
1059182007Sroberto		if (!(peer->crypto & CRYPTO_FLAG_PROV)) /* test 9 */
1060182007Sroberto			peer->flash |= TEST8;	/* not proventic */
106182505Sroberto
106282505Sroberto		/*
1063132454Sroberto		 * If the transmit queue is nonempty, clamp the host
1064132454Sroberto		 * poll interval to the packet poll interval.
106582505Sroberto		 */
1066132454Sroberto		if (peer->cmmd != 0) {
1067132454Sroberto			peer->ppoll = pkt->ppoll;
1068182007Sroberto			poll_update(peer, peer->hpoll);
1069132454Sroberto		}
107054359Sroberto	}
1071132454Sroberto#endif /* OPENSSL */
107254359Sroberto
107354359Sroberto	/*
1074182007Sroberto	 * The dance is complete and the flash bits have been lit. Toss
1075182007Sroberto	 * the packet over the fence for processing, which may light up
1076182007Sroberto	 * more flashers.
107754359Sroberto	 */
1078182007Sroberto	process_packet(peer, pkt);
1079182007Sroberto
1080182007Sroberto	/*
1081182007Sroberto	 * Well, that was nice. If TEST4 is lit, either the crypto
1082182007Sroberto	 * machine jammed or a kiss-o'-death packet flew in, either of
1083182007Sroberto	 * which is fatal.
1084182007Sroberto	 */
1085182007Sroberto	if (peer->flash & TEST4) {
1086182007Sroberto		msyslog(LOG_INFO, "receive: fatal error %04x for %s",
1087182007Sroberto		    peer->flash, stoa(&peer->srcadr));
1088182007Sroberto		return;
1089182007Sroberto	}
109054359Sroberto}
109154359Sroberto
109254359Sroberto
109354359Sroberto/*
109454359Sroberto * process_packet - Packet Procedure, a la Section 3.4.4 of the
109554359Sroberto *	specification. Or almost, at least. If we're in here we have a
109654359Sroberto *	reasonable expectation that we will be having a long term
109754359Sroberto *	relationship with this host.
109854359Sroberto */
109982505Srobertovoid
110054359Srobertoprocess_packet(
110154359Sroberto	register struct peer *peer,
1102182007Sroberto	register struct pkt *pkt
110354359Sroberto	)
110454359Sroberto{
1105182007Sroberto	double	t34, t21;
1106132454Sroberto	double	p_offset, p_del, p_disp;
1107132454Sroberto	l_fp	p_rec, p_xmt, p_org, p_reftime;
1108132454Sroberto	l_fp	ci;
1109132454Sroberto	u_char	pmode, pleap, pstratum;
111054359Sroberto
111154359Sroberto	sys_processed++;
111254359Sroberto	peer->processed++;
111354359Sroberto	p_del = FPTOD(NTOHS_FP(pkt->rootdelay));
111454359Sroberto	p_disp = FPTOD(NTOHS_FP(pkt->rootdispersion));
111554359Sroberto	NTOHL_FP(&pkt->reftime, &p_reftime);
111654359Sroberto	NTOHL_FP(&pkt->rec, &p_rec);
111754359Sroberto	NTOHL_FP(&pkt->xmt, &p_xmt);
1118132454Sroberto	pmode = PKT_MODE(pkt->li_vn_mode);
1119132454Sroberto	pleap = PKT_LEAP(pkt->li_vn_mode);
1120132454Sroberto	if (pmode != MODE_BROADCAST)
112154359Sroberto		NTOHL_FP(&pkt->org, &p_org);
112254359Sroberto	else
112354359Sroberto		p_org = peer->rec;
1124132454Sroberto	pstratum = PKT_TO_STRATUM(pkt->stratum);
112554359Sroberto
112654359Sroberto	/*
1127182007Sroberto	 * Test for kiss-o'death packet)
112854359Sroberto	 */
1129182007Sroberto	if (pleap == LEAP_NOTINSYNC && pstratum == STRATUM_UNSPEC) {
1130182007Sroberto		if (memcmp(&pkt->refid, "DENY", 4) == 0) {
1131182007Sroberto			peer_clear(peer, "DENY");
1132182007Sroberto			peer->flash |= TEST4;	/* access denied */
1133182007Sroberto		}
1134182007Sroberto	}
113554359Sroberto
113654359Sroberto	/*
1137182007Sroberto	 * Capture the header values.
113854359Sroberto	 */
1139182007Sroberto	record_raw_stats(&peer->srcadr, peer->dstadr ? &peer->dstadr->sin : NULL, &p_org,
1140182007Sroberto	    &p_rec, &p_xmt, &peer->rec);
1141132454Sroberto	peer->leap = pleap;
1142182007Sroberto	peer->stratum = min(pstratum, STRATUM_UNSPEC);
1143182007Sroberto	peer->pmode = pmode;
1144182007Sroberto	peer->ppoll = pkt->ppoll;
1145182007Sroberto	peer->precision = pkt->precision;
1146182007Sroberto	peer->rootdelay = p_del;
1147182007Sroberto	peer->rootdispersion = p_disp;
1148182007Sroberto	peer->refid = pkt->refid;		/* network byte order */
1149182007Sroberto	peer->reftime = p_reftime;
115082505Sroberto
115182505Sroberto	/*
1152182007Sroberto	 * Verify the server is synchronized; that is, the leap bits and
1153182007Sroberto	 * stratum are valid, the root delay and root dispersion are
1154182007Sroberto	 * valid and the reference timestamp is not later than the
1155182007Sroberto	 * transmit timestamp.
115682505Sroberto	 */
1157132454Sroberto	if (pleap == LEAP_NOTINSYNC ||		/* test 6 */
1158182007Sroberto	    pstratum < sys_floor || pstratum >= sys_ceiling)
1159182007Sroberto		peer->flash |= TEST6;		/* peer not synch */
1160182007Sroberto	if (p_del < 0 || p_disp < 0 || p_del /	/* test 7 */
1161182007Sroberto	    2 + p_disp >= MAXDISPERSE || !L_ISHIS(&p_xmt, &p_reftime))
1162182007Sroberto		peer->flash |= TEST7;		/* bad header */
1163132454Sroberto
1164132454Sroberto	/*
1165132454Sroberto	 * If any tests fail at this point, the packet is discarded.
1166182007Sroberto	 * Note that some flashers may have already been set in the
1167182007Sroberto	 * receive() routine.
1168132454Sroberto	 */
1169182007Sroberto	if (peer->flash & PKT_TEST_MASK) {
117054359Sroberto#ifdef DEBUG
117154359Sroberto		if (debug)
1172182007Sroberto			printf("packet: flash header %04x\n",
117382505Sroberto			    peer->flash);
117454359Sroberto#endif
117582505Sroberto		return;
117654359Sroberto	}
117782505Sroberto	if (!(peer->reach)) {
117854359Sroberto		report_event(EVNT_REACH, peer);
117954359Sroberto		peer->timereachable = current_time;
118054359Sroberto	}
1181182007Sroberto	poll_update(peer, peer->hpoll);
118254359Sroberto	peer->reach |= 1;
118354359Sroberto
118454359Sroberto	/*
1185182007Sroberto	 * For a client/server association, calculate the clock offset,
1186182007Sroberto	 * roundtrip delay and dispersion. The equations are reordered
1187182007Sroberto	 * from the spec for more efficient use of temporaries. For a
1188182007Sroberto	 * broadcast association, offset the last measurement by the
1189182007Sroberto	 * computed delay during the client/server volley. Note that
1190182007Sroberto	 * org has been set to the time of last reception. Note the
1191182007Sroberto	 * computation of dispersion includes the system precision plus
1192182007Sroberto	 * that due to the frequency error since the origin time.
119354359Sroberto	 *
1194182007Sroberto	 * It is very important to respect the hazards of overflow. The
1195182007Sroberto	 * only permitted operation on raw timestamps is subtraction,
1196182007Sroberto	 * where the result is a signed quantity spanning from 68 years
1197182007Sroberto	 * in the past to 68 years in the future. To avoid loss of
1198182007Sroberto	 * precision, these calculations are done using 64-bit integer
1199182007Sroberto	 * arithmetic. However, the offset and delay calculations are
1200182007Sroberto	 * sums and differences of these first-order differences, which
1201182007Sroberto	 * if done using 64-bit integer arithmetic, would be valid over
1202182007Sroberto	 * only half that span. Since the typical first-order
1203182007Sroberto	 * differences are usually very small, they are converted to 64-
1204182007Sroberto	 * bit doubles and all remaining calculations done in floating-
1205182007Sroberto	 * point arithmetic. This preserves the accuracy while retaining
1206182007Sroberto	 * the 68-year span.
1207182007Sroberto	 *
1208132454Sroberto	 * Let t1 = p_org, t2 = p_rec, t3 = p_xmt, t4 = peer->rec:
120954359Sroberto	 */
1210182007Sroberto	ci = p_xmt;			/* t3 - t4 */
1211182007Sroberto	L_SUB(&ci, &peer->rec);
1212182007Sroberto	LFPTOD(&ci, t34);
1213182007Sroberto	ci = p_rec;			/* t2 - t1 */
1214182007Sroberto	L_SUB(&ci, &p_org);
1215182007Sroberto	LFPTOD(&ci, t21);
1216132454Sroberto	ci = peer->rec;			/* t4 - t1 */
1217132454Sroberto	L_SUB(&ci, &p_org);
121854359Sroberto
121954359Sroberto	/*
122056749Sroberto	 * If running in a broadcast association, the clock offset is
122156749Sroberto	 * (t1 - t0) corrected by the one-way delay, but we can't
122282505Sroberto	 * measure that directly. Therefore, we start up in MODE_CLIENT
122382505Sroberto	 * mode, set FLAG_MCAST and exchange eight messages to determine
122482505Sroberto	 * the clock offset. When the last message is sent, we switch to
122582505Sroberto	 * MODE_BCLIENT mode. The next broadcast message after that
122682505Sroberto	 * computes the broadcast offset and clears FLAG_MCAST.
122754359Sroberto	 */
122854359Sroberto	if (pmode == MODE_BROADCAST) {
1229182007Sroberto		p_offset = t34;
123082505Sroberto		if (peer->flags & FLAG_MCAST) {
123154359Sroberto			peer->estbdelay = peer->offset - p_offset;
123282505Sroberto			if (peer->hmode == MODE_CLIENT)
123382505Sroberto				return;
123454359Sroberto
1235182007Sroberto			peer->flags &= ~(FLAG_MCAST | FLAG_BURST);
123654359Sroberto		}
1237182007Sroberto		p_offset += peer->estbdelay;
123854359Sroberto		p_del = peer->delay;
1239182007Sroberto		p_disp = 0;
124054359Sroberto	} else {
1241182007Sroberto		p_offset = (t21 + t34) / 2.;
1242182007Sroberto		p_del = t21 - t34;
1243182007Sroberto		LFPTOD(&ci, p_disp);
1244182007Sroberto		p_disp = LOGTOD(sys_precision) +
1245182007Sroberto		    LOGTOD(peer->precision) + clock_phi * p_disp;
124654359Sroberto	}
124782505Sroberto	p_del = max(p_del, LOGTOD(sys_precision));
124882505Sroberto	clock_filter(peer, p_offset, p_del, p_disp);
124954359Sroberto	record_peer_stats(&peer->srcadr, ctlpeerstatus(peer),
1250182007Sroberto	    peer->offset, peer->delay, peer->disp, peer->jitter);
125154359Sroberto}
125254359Sroberto
125354359Sroberto
125454359Sroberto/*
125554359Sroberto * clock_update - Called at system process update intervals.
125654359Sroberto */
125754359Srobertostatic void
125854359Srobertoclock_update(void)
125954359Sroberto{
1260182007Sroberto	u_char	oleap;
1261182007Sroberto	u_char	ostratum;
1262182007Sroberto	double	dtemp;
126354359Sroberto
126454359Sroberto	/*
1265182007Sroberto	 * There must be a system peer at this point. If we just changed
1266182007Sroberto	 * the system peer, but have a newer sample from the old one,
1267182007Sroberto	 * wait until newer data are available.
126854359Sroberto	 */
1269182007Sroberto	if (sys_poll < sys_peer->minpoll)
1270182007Sroberto		sys_poll = sys_peer->minpoll;
1271182007Sroberto	if (sys_poll > sys_peer->maxpoll)
1272182007Sroberto		sys_poll = sys_peer->maxpoll;
1273182007Sroberto	poll_update(sys_peer, sys_poll);
1274182007Sroberto	if (sys_peer->epoch <= sys_clocktime)
127554359Sroberto		return;
1276182007Sroberto
127754359Sroberto#ifdef DEBUG
127854359Sroberto	if (debug)
127954359Sroberto		printf("clock_update: at %ld assoc %d \n", current_time,
128054359Sroberto		    peer_associations);
128154359Sroberto#endif
128254359Sroberto	oleap = sys_leap;
128354359Sroberto	ostratum = sys_stratum;
1284182007Sroberto	switch (local_clock(sys_peer, sys_offset)) {
128554359Sroberto
128682505Sroberto	/*
1287182007Sroberto	 * Clock exceeds panic threshold. Life as we know it ends.
128882505Sroberto	 */
128982505Sroberto	case -1:
1290132454Sroberto		report_event(EVNT_SYSFAULT, NULL);
1291132454Sroberto		exit (-1);
1292182007Sroberto		/* not reached */
129354359Sroberto
129482505Sroberto	/*
129582505Sroberto	 * Clock was stepped. Flush all time values of all peers.
129682505Sroberto	 */
1297182007Sroberto	case 2:
129882505Sroberto		clear_all();
1299182007Sroberto		sys_leap = LEAP_NOTINSYNC;
1300182007Sroberto		sys_stratum = STRATUM_UNSPEC;
130182505Sroberto		sys_peer = NULL;
1302182007Sroberto		sys_rootdelay = 0;
1303182007Sroberto		sys_rootdispersion = 0;
1304182007Sroberto		memcpy(&sys_refid, "STEP", 4);
1305132454Sroberto		report_event(EVNT_CLOCKRESET, NULL);
130654359Sroberto		break;
130754359Sroberto
130882505Sroberto	/*
1309182007Sroberto	 * Clock was slewed. Update the system stratum, leap bits, root
1310182007Sroberto	 * delay, root dispersion, reference ID and reference time. If
1311182007Sroberto	 * the leap changes, we gotta reroll the keys. Except for
1312182007Sroberto	 * reference clocks, the minimum dispersion increment is not
1313182007Sroberto	 * less than sys_mindisp.
131482505Sroberto	 */
1315182007Sroberto	case 1:
1316182007Sroberto		sys_leap = leap_next;
1317182007Sroberto		sys_stratum = min(sys_peer->stratum + 1,
1318182007Sroberto		    STRATUM_UNSPEC);
131954359Sroberto		sys_reftime = sys_peer->rec;
1320182007Sroberto
1321182007Sroberto		/*
1322182007Sroberto		 * In orphan mode the stratum defaults to the orphan
1323182007Sroberto		 * stratum. The root delay is set to a random value
1324182007Sroberto		 * generated at startup. The root dispersion is set from
1325182007Sroberto		 * the peer dispersion; the peer root dispersion is
1326182007Sroberto		 * ignored.
1327182007Sroberto		 */
1328182007Sroberto		dtemp = sys_peer->disp + clock_phi * (current_time -
1329182007Sroberto		    sys_peer->update) + sys_jitter +
1330182007Sroberto		    fabs(sys_peer->offset);
1331182007Sroberto#ifdef REFCLOCK
1332182007Sroberto		if (!(sys_peer->flags & FLAG_REFCLOCK) && dtemp <
1333182007Sroberto		    sys_mindisp)
1334182007Sroberto			dtemp = sys_mindisp;
1335182007Sroberto#else
1336182007Sroberto		if (dtemp < sys_mindisp)
1337182007Sroberto			dtemp = sys_mindisp;
1338182007Sroberto#endif /* REFCLOCK */
1339182007Sroberto		if (sys_stratum >= sys_orphan) {
1340182007Sroberto			sys_stratum = sys_orphan;
1341182007Sroberto			sys_rootdelay = sys_peer->delay;
1342182007Sroberto			sys_rootdispersion = dtemp;
1343182007Sroberto		} else {
1344182007Sroberto			sys_rootdelay = sys_peer->delay +
1345182007Sroberto			    sys_peer->rootdelay;
1346182007Sroberto			sys_rootdispersion = dtemp +
1347182007Sroberto			    sys_peer->rootdispersion;
1348182007Sroberto		}
1349132454Sroberto		if (oleap == LEAP_NOTINSYNC) {
1350132454Sroberto			report_event(EVNT_SYNCCHG, NULL);
1351132454Sroberto#ifdef OPENSSL
1352132454Sroberto			expire_all();
1353182007Sroberto			crypto_update();
1354132454Sroberto#endif /* OPENSSL */
1355132454Sroberto		}
1356182007Sroberto		break;
1357182007Sroberto	/*
1358182007Sroberto	 * Popcorn spike or step threshold exceeded. Pretend it never
1359182007Sroberto	 * happened.
1360182007Sroberto	 */
1361182007Sroberto	default:
1362182007Sroberto		break;
136354359Sroberto	}
136454359Sroberto	if (ostratum != sys_stratum)
1365132454Sroberto		report_event(EVNT_PEERSTCHG, NULL);
136654359Sroberto}
136754359Sroberto
136854359Sroberto
136954359Sroberto/*
137082505Sroberto * poll_update - update peer poll interval
137154359Sroberto */
137254359Srobertovoid
137354359Srobertopoll_update(
137454359Sroberto	struct peer *peer,
1375182007Sroberto	int	mpoll
137654359Sroberto	)
137754359Sroberto{
1378182007Sroberto	int	hpoll;
137954359Sroberto
138054359Sroberto	/*
1381182007Sroberto	 * This routine figures out when the next poll should be sent.
1382182007Sroberto	 * That turns out to be wickedly complicated. The big problem is
1383182007Sroberto	 * that sometimes the time for the next poll is in the past.
1384182007Sroberto	 * Watch out for races here between the receive process and the
1385182007Sroberto	 * poll process. The key assertion is that, if nextdate equals
1386182007Sroberto	 * current_time, the call is from the poll process; otherwise,
1387182007Sroberto	 * it is from the receive process.
1388182007Sroberto	 *
1389182007Sroberto	 * First, bracket the poll interval according to the type of
1390182007Sroberto	 * association and options. If a fixed interval is configured,
1391182007Sroberto	 * use minpoll. This primarily is for reference clocks, but
1392182007Sroberto	 * works for any association.
139354359Sroberto	 */
1394182007Sroberto	if (peer->flags & FLAG_FIXPOLL) {
1395182007Sroberto		hpoll = peer->minpoll;
1396182007Sroberto
1397182007Sroberto	/*
1398182007Sroberto	 * The ordinary case; clamp the poll interval between minpoll
1399182007Sroberto	 * and maxpoll.
1400182007Sroberto	 */
1401182007Sroberto	} else {
1402182007Sroberto		hpoll = max(min(peer->maxpoll, mpoll), peer->minpoll);
1403182007Sroberto	}
1404132454Sroberto#ifdef OPENSSL
1405182007Sroberto	/*
1406182007Sroberto	 * Bit of crass arrogance at this point. If the poll interval
1407182007Sroberto	 * has changed and we have a keylist, the lifetimes in the
1408182007Sroberto	 * keylist are probably bogus. In this case purge the keylist
1409182007Sroberto	 * and regenerate it later.
1410182007Sroberto	 */
1411182007Sroberto	if (hpoll != peer->hpoll)
1412182007Sroberto		key_expire(peer);
1413132454Sroberto#endif /* OPENSSL */
1414182007Sroberto	peer->hpoll = hpoll;
141582505Sroberto
141682505Sroberto	/*
1417182007Sroberto	 * Now we figure out if there is an override. If during the
1418182007Sroberto	 * crypto protocol and a message is pending, make it wait not
1419182007Sroberto	 * more than two seconds.
142082505Sroberto	 */
1421132454Sroberto#ifdef OPENSSL
1422132454Sroberto	if (peer->cmmd != NULL && (sys_leap != LEAP_NOTINSYNC ||
1423132454Sroberto	    peer->crypto)) {
1424132454Sroberto		peer->nextdate = current_time + RESP_DELAY;
1425182007Sroberto
1426182007Sroberto	/*
1427182007Sroberto	 * If we get called from the receive routine while a burst is
1428182007Sroberto	 * pending, just slink away. If from the poll routine and a
1429182007Sroberto	 * reference clock or a pending crypto response, delay for one
1430182007Sroberto	 * second. If this is the first sent in a burst, wait for the
1431182007Sroberto	 * modem to come up. For others in the burst, delay two seconds.
1432182007Sroberto	 */
1433132454Sroberto	} else if (peer->burst > 0) {
1434132454Sroberto#else /* OPENSSL */
143554359Sroberto	if (peer->burst > 0) {
1436132454Sroberto#endif /* OPENSSL */
1437182007Sroberto		if (peer->nextdate != current_time)
143854359Sroberto			return;
143982505Sroberto#ifdef REFCLOCK
144082505Sroberto		else if (peer->flags & FLAG_REFCLOCK)
1441132454Sroberto			peer->nextdate += RESP_DELAY;
1442182007Sroberto#endif /* REFCLOCK */
1443132454Sroberto		else if (peer->flags & (FLAG_IBURST | FLAG_BURST) &&
1444132454Sroberto		    peer->burst == NTP_BURST)
1445132454Sroberto			peer->nextdate += sys_calldelay;
144654359Sroberto		else
1447132454Sroberto			peer->nextdate += BURST_DELAY;
1448182007Sroberto	/*
1449182007Sroberto	 * The ordinary case; use the minimum of the host and peer
1450182007Sroberto	 * intervals, but not less than minpoll. In other words,
1451182007Sroberto	 * oversampling is okay but understampling is evil.
1452182007Sroberto	 */
145354359Sroberto	} else {
1454182007Sroberto		peer->nextdate = peer->outdate +
1455182007Sroberto		    RANDPOLL(max(min(peer->ppoll, hpoll),
1456182007Sroberto		    peer->minpoll));
145754359Sroberto	}
1458182007Sroberto
145982505Sroberto	/*
1460182007Sroberto	 * If the time for the next poll has already happened, bring it
1461182007Sroberto	 * up to the next second after this one. This way the only way
1462182007Sroberto	 * to get nexdate == current time is from the poll routine.
146382505Sroberto	 */
1464182007Sroberto	if (peer->nextdate <= current_time)
1465182007Sroberto		peer->nextdate = current_time + 1;
146654359Sroberto#ifdef DEBUG
146754359Sroberto	if (debug > 1)
146882505Sroberto		printf("poll_update: at %lu %s flags %04x poll %d burst %d last %lu next %lu\n",
146982505Sroberto		    current_time, ntoa(&peer->srcadr), peer->flags,
1470182007Sroberto		    peer->hpoll, peer->burst, peer->outdate,
147182505Sroberto		    peer->nextdate);
147254359Sroberto#endif
147354359Sroberto}
147454359Sroberto
147554359Sroberto/*
1476182007Sroberto * peer_crypto_clear - discard crypto information
147754359Sroberto */
147854359Srobertovoid
1479182007Srobertopeer_crypto_clear(
1480182007Sroberto		  struct peer *peer
1481182007Sroberto		  )
148254359Sroberto{
148382505Sroberto	/*
148482505Sroberto	 * If cryptographic credentials have been acquired, toss them to
148582505Sroberto	 * Valhalla. Note that autokeys are ephemeral, in that they are
148682505Sroberto	 * tossed immediately upon use. Therefore, the keylist can be
148782505Sroberto	 * purged anytime without needing to preserve random keys. Note
148882505Sroberto	 * that, if the peer is purged, the cryptographic variables are
148982505Sroberto	 * purged, too. This makes it much harder to sneak in some
149082505Sroberto	 * unauthenticated data in the clock filter.
149182505Sroberto	 */
1492182007Sroberto	DPRINTF(1, ("peer_crypto_clear: at %ld next %ld assoc ID %d\n",
1493182007Sroberto		    current_time, peer->nextdate, peer->associd));
1494182007Sroberto
1495132454Sroberto#ifdef OPENSSL
1496182007Sroberto	peer->assoc = 0;
1497182007Sroberto	peer->crypto = 0;
1498182007Sroberto
1499132454Sroberto	if (peer->pkey != NULL)
1500132454Sroberto		EVP_PKEY_free(peer->pkey);
1501182007Sroberto	peer->pkey = NULL;
1502182007Sroberto
1503182007Sroberto	peer->digest = NULL;	/* XXX MEMLEAK? check whether this needs to be freed in any way - never was freed */
1504182007Sroberto
1505132454Sroberto	if (peer->subject != NULL)
1506132454Sroberto		free(peer->subject);
1507182007Sroberto	peer->subject = NULL;
1508182007Sroberto
1509132454Sroberto	if (peer->issuer != NULL)
1510132454Sroberto		free(peer->issuer);
1511182007Sroberto	peer->issuer = NULL;
1512182007Sroberto
1513182007Sroberto	peer->pkeyid = 0;
1514182007Sroberto
1515182007Sroberto	peer->pcookie = 0;
1516182007Sroberto
1517182007Sroberto	if (peer->ident_pkey != NULL)
1518182007Sroberto		EVP_PKEY_free(peer->ident_pkey);
1519182007Sroberto	peer->ident_pkey = NULL;
1520182007Sroberto
1521182007Sroberto	memset(&peer->fstamp, 0, sizeof(peer->fstamp));
1522182007Sroberto
1523132454Sroberto	if (peer->iffval != NULL)
1524132454Sroberto		BN_free(peer->iffval);
1525182007Sroberto	peer->iffval = NULL;
1526182007Sroberto
1527132454Sroberto	if (peer->grpkey != NULL)
1528132454Sroberto		BN_free(peer->grpkey);
1529182007Sroberto	peer->grpkey = NULL;
1530182007Sroberto
1531132454Sroberto	value_free(&peer->cookval);
1532132454Sroberto	value_free(&peer->recval);
1533182007Sroberto
1534182007Sroberto	if (peer->cmmd != NULL) {
1535182007Sroberto		free(peer->cmmd);
1536182007Sroberto		peer->cmmd = NULL;
1537182007Sroberto	}
1538182007Sroberto
1539182007Sroberto	key_expire(peer);
1540182007Sroberto
1541132454Sroberto	value_free(&peer->encrypt);
1542132454Sroberto#endif /* OPENSSL */
1543182007Sroberto}
154482505Sroberto
1545182007Sroberto/*
1546182007Sroberto * peer_clear - clear peer filter registers.  See Section 3.4.8 of the spec.
1547182007Sroberto */
1548182007Srobertovoid
1549182007Srobertopeer_clear(
1550182007Sroberto	struct peer *peer,		/* peer structure */
1551182007Sroberto	char	*ident			/* tally lights */
1552182007Sroberto	)
1553182007Sroberto{
1554182007Sroberto	int	i;
1555182007Sroberto
1556182007Sroberto	peer_crypto_clear(peer);
1557182007Sroberto
1558182007Sroberto	if (peer == sys_peer)
1559182007Sroberto		sys_peer = NULL;
1560182007Sroberto
156182505Sroberto	/*
1562132454Sroberto	 * Wipe the association clean and initialize the nonzero values.
156382505Sroberto	 */
1564132454Sroberto	memset(CLEAR_TO_ZERO(peer), 0, LEN_CLEAR_TO_ZERO);
156554359Sroberto	peer->estbdelay = sys_bdelay;
156682505Sroberto	peer->ppoll = peer->maxpoll;
1567182007Sroberto	peer->hpoll = peer->minpoll;
1568182007Sroberto	peer->disp = MAXDISPERSE;
1569182007Sroberto	peer->jitter = LOGTOD(sys_precision);
1570182007Sroberto	for (i = 0; i < NTP_SHIFT; i++) {
1571182007Sroberto		peer->filter_order[i] = i;
1572182007Sroberto		peer->filter_disp[i] = MAXDISPERSE;
1573182007Sroberto	}
157482505Sroberto#ifdef REFCLOCK
157582505Sroberto	if (!(peer->flags & FLAG_REFCLOCK)) {
157682505Sroberto		peer->leap = LEAP_NOTINSYNC;
157782505Sroberto		peer->stratum = STRATUM_UNSPEC;
1578132454Sroberto		memcpy(&peer->refid, ident, 4);
157982505Sroberto	}
1580132454Sroberto#else
1581132454Sroberto	peer->leap = LEAP_NOTINSYNC;
1582132454Sroberto	peer->stratum = STRATUM_UNSPEC;
1583132454Sroberto	memcpy(&peer->refid, ident, 4);
1584182007Sroberto#endif /* REFCLOCK */
158554359Sroberto
158654359Sroberto	/*
1587182007Sroberto	 * During initialization use the association count to spread out
1588182007Sroberto	 * the polls at one-second intervals. Othersie, randomize over
1589182007Sroberto	 * the minimum poll interval in order to avoid broadcast
1590182007Sroberto	 * implosion.
159154359Sroberto	 */
1592132454Sroberto	peer->nextdate = peer->update = peer->outdate = current_time;
1593182007Sroberto	if (initializing)
1594182007Sroberto		peer->nextdate += peer_associations;
1595182007Sroberto	else if (peer->hmode == MODE_PASSIVE)
1596182007Sroberto		peer->nextdate += RESP_DELAY;
1597132454Sroberto	else
1598182007Sroberto		peer->nextdate += (ntp_random() & ((1 << NTP_MINDPOLL) -
1599182007Sroberto		    1));
1600182007Sroberto
1601182007Sroberto	DPRINTF(1, ("peer_clear: at %ld next %ld assoc ID %d refid %s\n",
1602182007Sroberto		    current_time, peer->nextdate, peer->associd, ident));
160354359Sroberto}
160454359Sroberto
160554359Sroberto
160654359Sroberto/*
160754359Sroberto * clock_filter - add incoming clock sample to filter register and run
160854359Sroberto *		  the filter procedure to find the best sample.
160954359Sroberto */
161054359Srobertovoid
161154359Srobertoclock_filter(
1612132454Sroberto	struct peer *peer,		/* peer structure pointer */
1613132454Sroberto	double	sample_offset,		/* clock offset */
1614132454Sroberto	double	sample_delay,		/* roundtrip delay */
1615132454Sroberto	double	sample_disp		/* dispersion */
161654359Sroberto	)
161754359Sroberto{
1618132454Sroberto	double	dst[NTP_SHIFT];		/* distance vector */
1619132454Sroberto	int	ord[NTP_SHIFT];		/* index vector */
1620132454Sroberto	int	i, j, k, m;
1621182007Sroberto	double	dtemp, etemp;
162254359Sroberto
162354359Sroberto	/*
162482505Sroberto	 * Shift the new sample into the register and discard the oldest
162582505Sroberto	 * one. The new offset and delay come directly from the
162682505Sroberto	 * timestamp calculations. The dispersion grows from the last
162782505Sroberto	 * outbound packet or reference clock update to the present time
162882505Sroberto	 * and increased by the sum of the peer precision and the system
162982505Sroberto	 * precision. The delay can sometimes swing negative due to
163082505Sroberto	 * frequency skew, so it is clamped non-negative.
163154359Sroberto	 */
163254359Sroberto	j = peer->filter_nextpt;
163382505Sroberto	peer->filter_offset[j] = sample_offset;
163482505Sroberto	peer->filter_delay[j] = max(0, sample_delay);
1635182007Sroberto	peer->filter_disp[j] = sample_disp;
1636182007Sroberto	peer->filter_epoch[j] = current_time;
1637182007Sroberto	j = (j + 1) % NTP_SHIFT;
1638182007Sroberto	peer->filter_nextpt = j;
163954359Sroberto
164054359Sroberto	/*
164182505Sroberto	 * Update dispersions since the last update and at the same
164282505Sroberto	 * time initialize the distance and index lists. The distance
164382505Sroberto	 * list uses a compound metric. If the sample is valid and
164482505Sroberto	 * younger than the minimum Allan intercept, use delay;
164582505Sroberto	 * otherwise, use biased dispersion.
164654359Sroberto	 */
164782505Sroberto	dtemp = clock_phi * (current_time - peer->update);
164882505Sroberto	peer->update = current_time;
164982505Sroberto	for (i = NTP_SHIFT - 1; i >= 0; i--) {
1650132454Sroberto		if (i != 0)
165182505Sroberto			peer->filter_disp[j] += dtemp;
1652132454Sroberto		if (peer->filter_disp[j] >= MAXDISPERSE)
1653132454Sroberto			peer->filter_disp[j] = MAXDISPERSE;
165482505Sroberto		if (peer->filter_disp[j] >= MAXDISPERSE)
165582505Sroberto			dst[i] = MAXDISPERSE;
165682505Sroberto		else if (peer->update - peer->filter_epoch[j] >
165782505Sroberto		    allan_xpt)
1658182007Sroberto			dst[i] = sys_maxdist + peer->filter_disp[j];
165982505Sroberto		else
1660132454Sroberto			dst[i] = peer->filter_delay[j];
166182505Sroberto		ord[i] = j;
166282505Sroberto		j++; j %= NTP_SHIFT;
166382505Sroberto	}
166454359Sroberto
166582505Sroberto        /*
1666182007Sroberto	 * If the clock discipline has stabilized, sort the samples in
1667182007Sroberto	 * both lists by distance. Note, we do not displace a higher
1668182007Sroberto	 * distance sample by a lower distance one unless lower by at
1669182007Sroberto	 * least the precision.
167054359Sroberto	 */
1671182007Sroberto	if (state == 4) {
1672182007Sroberto		for (i = 1; i < NTP_SHIFT; i++) {
1673182007Sroberto			for (j = 0; j < i; j++) {
1674182007Sroberto				if (dst[j] > dst[i] +
1675182007Sroberto				    LOGTOD(sys_precision)) {
1676182007Sroberto					k = ord[j];
1677182007Sroberto					ord[j] = ord[i];
1678182007Sroberto					ord[i] = k;
1679182007Sroberto					etemp = dst[j];
1680182007Sroberto					dst[j] = dst[i];
1681182007Sroberto					dst[i] = etemp;
1682182007Sroberto				}
168354359Sroberto			}
168454359Sroberto		}
168582505Sroberto	}
168682505Sroberto
168782505Sroberto	/*
168882505Sroberto	 * Copy the index list to the association structure so ntpq
168982505Sroberto	 * can see it later. Prune the distance list to samples less
1690182007Sroberto	 * than max distance, but keep at least two valid samples for
169182505Sroberto	 * jitter calculation.
169282505Sroberto	 */
169382505Sroberto	m = 0;
169482505Sroberto	for (i = 0; i < NTP_SHIFT; i++) {
1695132454Sroberto		peer->filter_order[i] = (u_char) ord[i];
169682505Sroberto		if (dst[i] >= MAXDISPERSE || (m >= 2 && dst[i] >=
1697182007Sroberto		    sys_maxdist))
169882505Sroberto			continue;
169982505Sroberto		m++;
170082505Sroberto	}
170154359Sroberto
170254359Sroberto	/*
1703182007Sroberto	 * Compute the dispersion and jitter. The dispersion is weighted
1704182007Sroberto	 * exponentially by NTP_FWEIGHT (0.5) so it is normalized close
1705182007Sroberto	 * to 1.0. The jitter is the RMS differences relative to the
1706182007Sroberto	 * lowest delay sample. If no acceptable samples remain in the
1707182007Sroberto	 * shift register, quietly tiptoe home leaving only the
1708182007Sroberto	 * dispersion.
170954359Sroberto	 */
1710182007Sroberto	peer->disp = peer->jitter = 0;
171182505Sroberto	k = ord[0];
171254359Sroberto	for (i = NTP_SHIFT - 1; i >= 0; i--) {
171382505Sroberto		j = ord[i];
171482505Sroberto		peer->disp = NTP_FWEIGHT * (peer->disp +
171582505Sroberto		    peer->filter_disp[j]);
171682505Sroberto		if (i < m)
1717182007Sroberto			peer->jitter += DIFF(peer->filter_offset[j],
171882505Sroberto			    peer->filter_offset[k]);
171954359Sroberto	}
172054359Sroberto
172154359Sroberto	/*
172282505Sroberto	 * If no acceptable samples remain in the shift register,
172382505Sroberto	 * quietly tiptoe home leaving only the dispersion. Otherwise,
1724182007Sroberto	 * save the offset, delay and jitter. Note the jitter must not
1725182007Sroberto	 * be less than the precision.
172682505Sroberto	 */
172782505Sroberto	if (m == 0)
172882505Sroberto		return;
1729182007Sroberto
1730132454Sroberto	etemp = fabs(peer->offset - peer->filter_offset[k]);
173182505Sroberto	peer->offset = peer->filter_offset[k];
173282505Sroberto	peer->delay = peer->filter_delay[k];
173382505Sroberto	if (m > 1)
1734182007Sroberto		peer->jitter /= m - 1;
1735182007Sroberto	peer->jitter = max(SQRT(peer->jitter), LOGTOD(sys_precision));
173682505Sroberto
173782505Sroberto	/*
173854359Sroberto	 * A new sample is useful only if it is younger than the last
1739182007Sroberto	 * one used. Note the order is FIFO if the clock discipline has
1740182007Sroberto	 * not stabilized.
174154359Sroberto	 */
1742182007Sroberto	if (peer->filter_epoch[k] <= peer->epoch) {
174354359Sroberto#ifdef DEBUG
174454359Sroberto		if (debug)
174554359Sroberto			printf("clock_filter: discard %lu\n",
174682505Sroberto			    peer->epoch - peer->filter_epoch[k]);
174754359Sroberto#endif
174854359Sroberto		return;
174954359Sroberto	}
175054359Sroberto
175154359Sroberto	/*
175282505Sroberto	 * If the difference between the last offset and the current one
1753132454Sroberto	 * exceeds the jitter by CLOCK_SGATE and the interval since the
1754132454Sroberto	 * last update is less than twice the system poll interval,
175582505Sroberto	 * consider the update a popcorn spike and ignore it.
175654359Sroberto	 */
1757182007Sroberto	if (etemp > CLOCK_SGATE * peer->jitter && m > 1 &&
1758182007Sroberto	    peer->filter_epoch[k] - peer->epoch < 2. *
1759182007Sroberto	    ULOGTOD(sys_poll)) {
176054359Sroberto#ifdef DEBUG
176154359Sroberto		if (debug)
1762132454Sroberto			printf("clock_filter: popcorn %.6f %.6f\n",
1763132454Sroberto			    etemp, dtemp);
176454359Sroberto#endif
176554359Sroberto		return;
176654359Sroberto	}
176782505Sroberto
176882505Sroberto	/*
176982505Sroberto	 * The mitigated sample statistics are saved for later
1770182007Sroberto	 * processing. If not in a burst, tickle the select.
177182505Sroberto	 */
177282505Sroberto	peer->epoch = peer->filter_epoch[k];
177354359Sroberto#ifdef DEBUG
177454359Sroberto	if (debug)
177554359Sroberto		printf(
177682505Sroberto		    "clock_filter: n %d off %.6f del %.6f dsp %.6f jit %.6f, age %lu\n",
177782505Sroberto		    m, peer->offset, peer->delay, peer->disp,
1778182007Sroberto		    peer->jitter, current_time - peer->epoch);
177954359Sroberto#endif
1780182007Sroberto	if (peer->burst == 0 || sys_leap == LEAP_NOTINSYNC)
1781182007Sroberto		clock_select();
178254359Sroberto}
178354359Sroberto
178454359Sroberto
178554359Sroberto/*
178654359Sroberto * clock_select - find the pick-of-the-litter clock
1787132454Sroberto *
1788132454Sroberto * LOCKCLOCK: If the local clock is the prefer peer, it will always be
1789132454Sroberto * enabled, even if declared falseticker, (2) only the prefer peer can
1790132454Sroberto * be selected as the system peer, (3) if the external source is down,
1791132454Sroberto * the system leap bits are set to 11 and the stratum set to infinity.
179254359Sroberto */
179354359Srobertovoid
179454359Srobertoclock_select(void)
179554359Sroberto{
1796132454Sroberto	struct peer *peer;
1797132454Sroberto	int	i, j, k, n;
1798132454Sroberto	int	nlist, nl3;
1799132454Sroberto
1800182007Sroberto	int	allow, osurv;
1801182007Sroberto	double	d, e, f, g;
1802132454Sroberto	double	high, low;
1803182007Sroberto	double	synch[NTP_MAXASSOC], error[NTP_MAXASSOC];
180454359Sroberto	struct peer *osys_peer;
180582505Sroberto	struct peer *typeacts = NULL;
180682505Sroberto	struct peer *typelocal = NULL;
180782505Sroberto	struct peer *typesystem = NULL;
180854359Sroberto
180954359Sroberto	static int list_alloc = 0;
181054359Sroberto	static struct endpoint *endpoint = NULL;
181182505Sroberto	static int *indx = NULL;
181254359Sroberto	static struct peer **peer_list = NULL;
181354359Sroberto	static u_int endpoint_size = 0;
181482505Sroberto	static u_int indx_size = 0;
181554359Sroberto	static u_int peer_list_size = 0;
181654359Sroberto
181754359Sroberto	/*
181882505Sroberto	 * Initialize and create endpoint, index and peer lists big
181982505Sroberto	 * enough to handle all associations.
182054359Sroberto	 */
182182505Sroberto	osys_peer = sys_peer;
182282505Sroberto	sys_peer = NULL;
1823182007Sroberto	sys_pps = NULL;
1824182007Sroberto	sys_prefer = NULL;
1825132454Sroberto	osurv = sys_survivors;
1826132454Sroberto	sys_survivors = 0;
1827132454Sroberto#ifdef LOCKCLOCK
1828132454Sroberto	sys_leap = LEAP_NOTINSYNC;
1829132454Sroberto	sys_stratum = STRATUM_UNSPEC;
1830132454Sroberto	memcpy(&sys_refid, "DOWN", 4);
1831132454Sroberto#endif /* LOCKCLOCK */
1832132454Sroberto	nlist = 0;
1833182007Sroberto	for (n = 0; n < NTP_HASH_SIZE; n++)
183454359Sroberto		nlist += peer_hash_count[n];
183554359Sroberto	if (nlist > list_alloc) {
183654359Sroberto		if (list_alloc > 0) {
183754359Sroberto			free(endpoint);
183882505Sroberto			free(indx);
183954359Sroberto			free(peer_list);
184054359Sroberto		}
184154359Sroberto		while (list_alloc < nlist) {
184254359Sroberto			list_alloc += 5;
184382505Sroberto			endpoint_size += 5 * 3 * sizeof(*endpoint);
184482505Sroberto			indx_size += 5 * 3 * sizeof(*indx);
184582505Sroberto			peer_list_size += 5 * sizeof(*peer_list);
184654359Sroberto		}
1847182007Sroberto		endpoint = (struct endpoint *)emalloc(endpoint_size);
1848182007Sroberto		indx = (int *)emalloc(indx_size);
1849182007Sroberto		peer_list = (struct peer **)emalloc(peer_list_size);
185054359Sroberto	}
185154359Sroberto
185254359Sroberto	/*
185382505Sroberto	 * Initially, we populate the island with all the rifraff peers
185482505Sroberto	 * that happen to be lying around. Those with seriously
185582505Sroberto	 * defective clocks are immediately booted off the island. Then,
185682505Sroberto	 * the falsetickers are culled and put to sea. The truechimers
185782505Sroberto	 * remaining are subject to repeated rounds where the most
185882505Sroberto	 * unpopular at each round is kicked off. When the population
1859132454Sroberto	 * has dwindled to sys_minclock, the survivors split a million
1860132454Sroberto	 * bucks and collectively crank the chimes.
186154359Sroberto	 */
186254359Sroberto	nlist = nl3 = 0;	/* none yet */
1863182007Sroberto	for (n = 0; n < NTP_HASH_SIZE; n++) {
186482505Sroberto		for (peer = peer_hash[n]; peer != NULL; peer =
186582505Sroberto		    peer->next) {
186654359Sroberto			peer->flags &= ~FLAG_SYSPEER;
186754359Sroberto			peer->status = CTL_PST_SEL_REJECT;
186854359Sroberto
186954359Sroberto			/*
1870132454Sroberto			 * Leave the island immediately if the peer is
1871132454Sroberto			 * unfit to synchronize.
1872132454Sroberto			 */
1873132454Sroberto			if (peer_unfit(peer))
187482505Sroberto				continue;
187582505Sroberto
187682505Sroberto			/*
187782505Sroberto			 * Don't allow the local clock or modem drivers
187854359Sroberto			 * in the kitchen at this point, unless the
187954359Sroberto			 * prefer peer. Do that later, but only if
188082505Sroberto			 * nobody else is around. These guys are all
188182505Sroberto			 * configured, so we never throw them away.
188254359Sroberto			 */
1883182007Sroberto#ifdef REFCLOCK
188454359Sroberto			if (peer->refclktype == REFCLK_LOCALCLOCK
188554359Sroberto#if defined(VMS) && defined(VMS_LOCALUNIT)
1886132454Sroberto			/* wjm: VMS_LOCALUNIT taken seriously */
1887132454Sroberto			    && REFCLOCKUNIT(&peer->srcadr) !=
1888132454Sroberto			    VMS_LOCALUNIT
188954359Sroberto#endif	/* VMS && VMS_LOCALUNIT */
189054359Sroberto				) {
189154359Sroberto				typelocal = peer;
1892182007Sroberto#ifndef LOCKCLOCK
189354359Sroberto				if (!(peer->flags & FLAG_PREFER))
189454359Sroberto					continue; /* no local clock */
1895132454Sroberto#endif /* LOCKCLOCK */
189654359Sroberto			}
189754359Sroberto			if (peer->sstclktype == CTL_SST_TS_TELEPHONE) {
189854359Sroberto				typeacts = peer;
189954359Sroberto				if (!(peer->flags & FLAG_PREFER))
190054359Sroberto					continue; /* no acts */
190154359Sroberto			}
1902182007Sroberto#endif /* REFCLOCK */
190354359Sroberto
190454359Sroberto			/*
190582505Sroberto			 * If we get this far, the peer can stay on the
190682505Sroberto			 * island, but does not yet have the immunity
190782505Sroberto			 * idol.
190854359Sroberto			 */
190954359Sroberto			peer->status = CTL_PST_SEL_SANE;
191054359Sroberto			peer_list[nlist++] = peer;
191154359Sroberto
191254359Sroberto			/*
191354359Sroberto			 * Insert each interval endpoint on the sorted
191454359Sroberto			 * list.
191554359Sroberto			 */
191654359Sroberto			e = peer->offset;	 /* Upper end */
191754359Sroberto			f = root_distance(peer);
191854359Sroberto			e = e + f;
191954359Sroberto			for (i = nl3 - 1; i >= 0; i--) {
192082505Sroberto				if (e >= endpoint[indx[i]].val)
192154359Sroberto					break;
1922182007Sroberto
192382505Sroberto				indx[i + 3] = indx[i];
192454359Sroberto			}
192582505Sroberto			indx[i + 3] = nl3;
192654359Sroberto			endpoint[nl3].type = 1;
192754359Sroberto			endpoint[nl3++].val = e;
192854359Sroberto
192954359Sroberto			e = e - f;		/* Center point */
1930132454Sroberto			for (; i >= 0; i--) {
193182505Sroberto				if (e >= endpoint[indx[i]].val)
193254359Sroberto					break;
1933182007Sroberto
193482505Sroberto				indx[i + 2] = indx[i];
193554359Sroberto			}
193682505Sroberto			indx[i + 2] = nl3;
193754359Sroberto			endpoint[nl3].type = 0;
193854359Sroberto			endpoint[nl3++].val = e;
193954359Sroberto
194054359Sroberto			e = e - f;		/* Lower end */
1941132454Sroberto			for (; i >= 0; i--) {
194282505Sroberto				if (e >= endpoint[indx[i]].val)
194354359Sroberto					break;
1944182007Sroberto
194582505Sroberto				indx[i + 1] = indx[i];
194654359Sroberto			}
194782505Sroberto			indx[i + 1] = nl3;
194854359Sroberto			endpoint[nl3].type = -1;
194954359Sroberto			endpoint[nl3++].val = e;
195054359Sroberto		}
195154359Sroberto	}
195254359Sroberto#ifdef DEBUG
195382505Sroberto	if (debug > 2)
195454359Sroberto		for (i = 0; i < nl3; i++)
195582505Sroberto			printf("select: endpoint %2d %.6f\n",
195682505Sroberto			   endpoint[indx[i]].type,
195782505Sroberto			   endpoint[indx[i]].val);
195854359Sroberto#endif
1959132454Sroberto	/*
1960132454Sroberto	 * This is the actual algorithm that cleaves the truechimers
1961132454Sroberto	 * from the falsetickers. The original algorithm was described
1962132454Sroberto	 * in Keith Marzullo's dissertation, but has been modified for
1963132454Sroberto	 * better accuracy.
1964132454Sroberto	 *
1965132454Sroberto	 * Briefly put, we first assume there are no falsetickers, then
1966132454Sroberto	 * scan the candidate list first from the low end upwards and
1967132454Sroberto	 * then from the high end downwards. The scans stop when the
1968132454Sroberto	 * number of intersections equals the number of candidates less
1969132454Sroberto	 * the number of falsetickers. If this doesn't happen for a
1970132454Sroberto	 * given number of falsetickers, we bump the number of
1971132454Sroberto	 * falsetickers and try again. If the number of falsetickers
1972132454Sroberto	 * becomes equal to or greater than half the number of
1973132454Sroberto	 * candidates, the Albanians have won the Byzantine wars and
1974132454Sroberto	 * correct synchronization is not possible.
1975132454Sroberto	 *
1976132454Sroberto	 * Here, nlist is the number of candidates and allow is the
1977182007Sroberto	 * number of falsetickers. Upon exit, the truechimers are the
1978182007Sroberto	 * susvivors with offsets not less than low and not greater than
1979182007Sroberto	 * high. There may be none of them.
1980132454Sroberto	 */
1981132454Sroberto	low = 1e9;
1982132454Sroberto	high = -1e9;
1983132454Sroberto	for (allow = 0; 2 * allow < nlist; allow++) {
1984132454Sroberto		int	found;
1985132454Sroberto
1986132454Sroberto		/*
1987132454Sroberto		 * Bound the interval (low, high) as the largest
1988132454Sroberto		 * interval containing points from presumed truechimers.
1989132454Sroberto		 */
1990132454Sroberto		found = 0;
1991132454Sroberto		n = 0;
1992132454Sroberto		for (i = 0; i < nl3; i++) {
1993132454Sroberto			low = endpoint[indx[i]].val;
1994132454Sroberto			n -= endpoint[indx[i]].type;
1995132454Sroberto			if (n >= nlist - allow)
199654359Sroberto				break;
199782505Sroberto			if (endpoint[indx[i]].type == 0)
199854359Sroberto				found++;
199954359Sroberto		}
2000132454Sroberto		n = 0;
2001132454Sroberto		for (j = nl3 - 1; j >= 0; j--) {
2002132454Sroberto			high = endpoint[indx[j]].val;
200382505Sroberto			n += endpoint[indx[j]].type;
2004132454Sroberto			if (n >= nlist - allow)
200554359Sroberto				break;
200682505Sroberto			if (endpoint[indx[j]].type == 0)
200754359Sroberto				found++;
200854359Sroberto		}
2009132454Sroberto
2010132454Sroberto		/*
2011132454Sroberto		 * If the number of candidates found outside the
2012132454Sroberto		 * interval is greater than the number of falsetickers,
2013132454Sroberto		 * then at least one truechimer is outside the interval,
2014132454Sroberto		 * so go around again. This is what makes this algorithm
2015132454Sroberto		 * different than Marzullo's.
2016132454Sroberto		 */
201754359Sroberto		if (found > allow)
2018132454Sroberto			continue;
2019132454Sroberto
2020132454Sroberto		/*
2021132454Sroberto		 * If an interval containing truechimers is found, stop.
2022132454Sroberto		 * If not, increase the number of falsetickers and go
2023132454Sroberto		 * around again.
2024132454Sroberto		 */
2025132454Sroberto		if (high > low)
202654359Sroberto			break;
202754359Sroberto	}
202854359Sroberto
202954359Sroberto	/*
2030182007Sroberto	 * Clustering algorithm. Construct candidate list in order first
2031182007Sroberto	 * by stratum then by root distance, but keep only the best
2032182007Sroberto	 * NTP_MAXASSOC of them. Scan the list to find falsetickers, who
2033182007Sroberto	 * leave the island immediately. The TRUE peer is always a
2034182007Sroberto	 * truechimer. We must leave at least one peer to collect the
2035182007Sroberto	 * million bucks. If in orphan mode, rascals found with lower
2036182007Sroberto	 * stratum are guaranteed a seat on the bus.
2037182007Sroberto	 */
2038182007Sroberto	j = 0;
2039182007Sroberto	for (i = 0; i < nlist; i++) {
2040182007Sroberto		peer = peer_list[i];
2041182007Sroberto		if (nlist > 1 && (peer->offset <= low || peer->offset >=
2042182007Sroberto		    high) && !(peer->flags & FLAG_TRUE) &&
2043182007Sroberto		    !(sys_stratum >= sys_orphan && peer->stratum <
2044182007Sroberto		    sys_orphan))
2045182007Sroberto			continue;
2046182007Sroberto
2047182007Sroberto		peer->status = CTL_PST_SEL_DISTSYSPEER;
2048182007Sroberto
2049182007Sroberto		/*
2050182007Sroberto		 * The order metric is formed from the stratum times
2051182007Sroberto		 * max distance (1.) plus the root distance. It strongly
2052182007Sroberto		 * favors the lowest stratum, but a higher stratum peer
2053182007Sroberto		 * can capture the clock if the low stratum dominant
2054182007Sroberto		 * hasn't been heard for awhile.
2055182007Sroberto		 */
2056182007Sroberto		d = root_distance(peer) + peer->stratum * sys_maxdist;
2057182007Sroberto		if (j >= NTP_MAXASSOC) {
2058182007Sroberto			if (d >= synch[j - 1])
2059182007Sroberto				continue;
2060182007Sroberto			else
2061182007Sroberto				j--;
2062182007Sroberto		}
2063182007Sroberto		for (k = j; k > 0; k--) {
2064182007Sroberto			if (d >= synch[k - 1])
2065182007Sroberto				break;
2066182007Sroberto
2067182007Sroberto			peer_list[k] = peer_list[k - 1];
2068182007Sroberto			error[k] = error[k - 1];
2069182007Sroberto			synch[k] = synch[k - 1];
2070182007Sroberto		}
2071182007Sroberto		peer_list[k] = peer;
2072182007Sroberto		error[k] = peer->jitter;
2073182007Sroberto		synch[k] = d;
2074182007Sroberto		j++;
2075182007Sroberto	}
2076182007Sroberto	nlist = j;
2077182007Sroberto
2078182007Sroberto	/*
207982505Sroberto	 * If no survivors remain at this point, check if the local
208082505Sroberto	 * clock or modem drivers have been found. If so, nominate one
2081132454Sroberto	 * of them as the only survivor. Otherwise, give up and leave
2082132454Sroberto	 * the island to the rats.
208354359Sroberto	 */
2084182007Sroberto	if (nlist == 0) {
208554359Sroberto		if (typeacts != 0) {
2086182007Sroberto			typeacts->status = CTL_PST_SEL_DISTSYSPEER;
208754359Sroberto			peer_list[0] = typeacts;
208854359Sroberto			nlist = 1;
208954359Sroberto		} else if (typelocal != 0) {
2090182007Sroberto			typelocal->status = CTL_PST_SEL_DISTSYSPEER;
209154359Sroberto			peer_list[0] = typelocal;
209254359Sroberto			nlist = 1;
209354359Sroberto		} else {
209482505Sroberto			if (osys_peer != NULL) {
209582505Sroberto				NLOG(NLOG_SYNCSTATUS)
209682505Sroberto				    msyslog(LOG_INFO,
2097132454Sroberto				    "no servers reachable");
2098132454Sroberto				report_event(EVNT_PEERSTCHG, NULL);
209954359Sroberto			}
210054359Sroberto		}
210154359Sroberto	}
210254359Sroberto
210354359Sroberto	/*
2104132454Sroberto	 * We can only trust the survivors if the number of candidates
2105132454Sroberto	 * sys_minsane is at least the number required to detect and
2106132454Sroberto	 * cast out one falsticker. For the Byzantine agreement
2107132454Sroberto	 * algorithm used here, that number is 4; however, the default
2108132454Sroberto	 * sys_minsane is 1 to speed initial synchronization. Careful
2109182007Sroberto	 * operators will tinker a higher value and use at least that
2110132454Sroberto	 * number of synchronization sources.
2111132454Sroberto	 */
2112132454Sroberto	if (nlist < sys_minsane)
2113132454Sroberto		return;
2114132454Sroberto
2115182007Sroberto	for (i = 0; i < nlist; i++)
211682505Sroberto		peer_list[i]->status = CTL_PST_SEL_SELCAND;
211754359Sroberto
211854359Sroberto	/*
211982505Sroberto	 * Now, vote outlyers off the island by select jitter weighted
2120182007Sroberto	 * by root distance. Continue voting as long as there are more
2121182007Sroberto	 * than sys_minclock survivors and the minimum select jitter is
2122182007Sroberto	 * greater than the maximum peer jitter. Stop if we are about to
2123182007Sroberto	 * discard a TRUE or PREFER  peer, who of course has the
2124182007Sroberto	 * immunity idol.
212554359Sroberto	 */
212654359Sroberto	while (1) {
212782505Sroberto		d = 1e9;
212882505Sroberto		e = -1e9;
2129182007Sroberto		f = g = 0;
213082505Sroberto		k = 0;
213182505Sroberto		for (i = 0; i < nlist; i++) {
213282505Sroberto			if (error[i] < d)
213382505Sroberto				d = error[i];
213482505Sroberto			f = 0;
213582505Sroberto			if (nlist > 1) {
213682505Sroberto				for (j = 0; j < nlist; j++)
213782505Sroberto					f += DIFF(peer_list[j]->offset,
213882505Sroberto					    peer_list[i]->offset);
2139182007Sroberto				f = SQRT(f / (nlist - 1));
214054359Sroberto			}
214182505Sroberto			if (f * synch[i] > e) {
2142182007Sroberto				g = f;
214382505Sroberto				e = f * synch[i];
214454359Sroberto				k = i;
214554359Sroberto			}
214654359Sroberto		}
2147182007Sroberto		f = max(f, LOGTOD(sys_precision));
2148132454Sroberto		if (nlist <= sys_minclock || f <= d ||
2149182007Sroberto		    peer_list[k]->flags & (FLAG_TRUE | FLAG_PREFER))
2150132454Sroberto			break;
215154359Sroberto#ifdef DEBUG
215282505Sroberto		if (debug > 2)
215354359Sroberto			printf(
2154132454Sroberto			    "select: drop %s select %.6f jitter %.6f\n",
2155182007Sroberto			    ntoa(&peer_list[k]->srcadr), g, d);
215654359Sroberto#endif
215754359Sroberto		for (j = k + 1; j < nlist; j++) {
215854359Sroberto			peer_list[j - 1] = peer_list[j];
215954359Sroberto			error[j - 1] = error[j];
216054359Sroberto		}
216154359Sroberto		nlist--;
216254359Sroberto	}
216382505Sroberto
216482505Sroberto	/*
2165132454Sroberto	 * What remains is a list usually not greater than sys_minclock
216654359Sroberto	 * peers. We want only a peer at the lowest stratum to become
216754359Sroberto	 * the system peer, although all survivors are eligible for the
2168182007Sroberto	 * combining algorithm. Consider each peer in turn and OR the
2169182007Sroberto	 * leap bits on the assumption that, if some of them honk
2170182007Sroberto	 * nonzero bits, they must know what they are doing. Check for
2171182007Sroberto	 * prefer and pps peers at any stratum. Note that the head of
2172182007Sroberto	 * the list is at the lowest stratum and that unsynchronized
2173182007Sroberto	 * peers cannot survive this far.
217454359Sroberto	 */
2175182007Sroberto	leap_next = 0;
2176182007Sroberto	for (i = 0; i < nlist; i++) {
217782505Sroberto		peer = peer_list[i];
2178182007Sroberto		sys_survivors++;
2179182007Sroberto		leap_next |= peer->leap;
218082505Sroberto		peer->status = CTL_PST_SEL_SYNCCAND;
2181132454Sroberto		if (peer->flags & FLAG_PREFER)
2182132454Sroberto			sys_prefer = peer;
2183182007Sroberto		if (peer == osys_peer)
2184132454Sroberto			typesystem = peer;
2185182007Sroberto#ifdef REFCLOCK
2186182007Sroberto		if (peer->refclktype == REFCLK_ATOM_PPS)
2187182007Sroberto			sys_pps = peer;
2188182007Sroberto#endif /* REFCLOCK */
2189182007Sroberto#if DEBUG
2190182007Sroberto		if (debug > 1)
2191182007Sroberto			printf("cluster: survivor %s metric %.6f\n",
2192182007Sroberto			    ntoa(&peer_list[i]->srcadr), synch[i]);
2193182007Sroberto#endif
219454359Sroberto	}
219554359Sroberto
219654359Sroberto	/*
2197182007Sroberto	 * Anticlockhop provision. Keep the current system peer if it is
2198182007Sroberto	 * a survivor but not first in the list. But do that only HOPPER
2199182007Sroberto	 * times.
2200132454Sroberto	 */
2201182007Sroberto	if (osys_peer == NULL || typesystem == NULL || typesystem ==
2202182007Sroberto	    peer_list[0] || sys_hopper > sys_maxhop) {
2203182007Sroberto		typesystem = peer_list[0];
2204182007Sroberto		sys_hopper = 0;
2205182007Sroberto	} else {
2206182007Sroberto		peer->selbroken++;
2207182007Sroberto	}
2208132454Sroberto
2209132454Sroberto	/*
221054359Sroberto	 * Mitigation rules of the game. There are several types of
2211182007Sroberto	 * peers that can be selected here: (1) orphan, (2) prefer peer
2212182007Sroberto	 * (flag FLAG_PREFER) (3) pps peers (type REFCLK_ATOM_PPS), (4)
2213182007Sroberto	 * the existing system peer, if any, and (5) the head of the
2214182007Sroberto	 * survivor list.
221554359Sroberto	 */
2216182007Sroberto	if (typesystem->stratum >= sys_orphan) {
2217182007Sroberto
2218182007Sroberto		/*
2219182007Sroberto		 * If in orphan mode, choose the system peer. If the
2220182007Sroberto		 * lowest distance, we are the orphan parent and the
2221182007Sroberto		 * offset is zero.
2222182007Sroberto		 */
2223182007Sroberto		sys_peer = typesystem;
222454359Sroberto		sys_peer->status = CTL_PST_SEL_SYSPEER;
2225182007Sroberto		if (sys_orphandelay < sys_peer->rootdelay) {
2226182007Sroberto			sys_offset = 0;
2227182007Sroberto			sys_refid = htonl(LOOPBACKADR);
2228182007Sroberto		} else {
2229182007Sroberto			sys_offset = sys_peer->offset;
2230182007Sroberto			sys_refid = addr2refid(&sys_peer->srcadr);
2231182007Sroberto		}
2232182007Sroberto		sys_jitter = LOGTOD(sys_precision);
223354359Sroberto#ifdef DEBUG
223454359Sroberto		if (debug > 1)
2235182007Sroberto			printf("select: orphan offset %.6f\n",
223656749Sroberto			    sys_offset);
223754359Sroberto#endif
2238182007Sroberto	} else if (sys_prefer) {
2239182007Sroberto
2240182007Sroberto		/*
2241182007Sroberto		 * If a pps peer is present, choose it; otherwise,
2242182007Sroberto		 * choose the prefer peer.
2243182007Sroberto		 */
2244182007Sroberto		if (sys_pps) {
2245182007Sroberto			sys_peer = sys_pps;
2246182007Sroberto			sys_peer->status = CTL_PST_SEL_PPS;
2247182007Sroberto			sys_offset = sys_peer->offset;
2248182007Sroberto			if (!pps_control)
2249182007Sroberto				NLOG(NLOG_SYSEVENT)
2250182007Sroberto				    msyslog(LOG_INFO,
2251182007Sroberto				    "pps sync enabled");
2252182007Sroberto			pps_control = current_time;
225354359Sroberto#ifdef DEBUG
2254182007Sroberto			if (debug > 1)
2255182007Sroberto				printf("select: pps offset %.6f\n",
2256182007Sroberto				    sys_offset);
225754359Sroberto#endif
2258182007Sroberto		} else {
2259182007Sroberto			sys_peer = sys_prefer;
2260182007Sroberto			sys_peer->status = CTL_PST_SEL_SYSPEER;
2261182007Sroberto			sys_offset = sys_peer->offset;
2262182007Sroberto#ifdef DEBUG
2263182007Sroberto			if (debug > 1)
2264182007Sroberto				printf("select: prefer offset %.6f\n",
2265182007Sroberto				    sys_offset);
2266182007Sroberto#endif
2267182007Sroberto		}
2268182007Sroberto		if (sys_peer->stratum == STRATUM_REFCLOCK ||
2269182007Sroberto		    sys_peer->stratum == STRATUM_UNSPEC)
2270182007Sroberto			sys_refid = sys_peer->refid;
2271182007Sroberto		else
2272182007Sroberto			sys_refid = addr2refid(&sys_peer->srcadr);
2273182007Sroberto		sys_jitter = sys_peer->jitter;
227454359Sroberto	} else {
2275182007Sroberto
2276182007Sroberto		/*
2277182007Sroberto		 * Otherwise, choose the anticlockhopper.
2278182007Sroberto		 */
2279182007Sroberto		sys_peer = typesystem;
2280182007Sroberto		sys_peer->status = CTL_PST_SEL_SYSPEER;
2281182007Sroberto		clock_combine(peer_list, nlist);
2282182007Sroberto		if (sys_peer->stratum == STRATUM_REFCLOCK ||
2283182007Sroberto		    sys_peer->stratum == STRATUM_UNSPEC)
2284182007Sroberto			sys_refid = sys_peer->refid;
228582505Sroberto		else
2286182007Sroberto			sys_refid = addr2refid(&sys_peer->srcadr);
2287182007Sroberto		sys_jitter = SQRT(SQUARE(sys_peer->jitter) +
2288182007Sroberto		    SQUARE(sys_jitter));
228954359Sroberto#ifdef DEBUG
229054359Sroberto		if (debug > 1)
229154359Sroberto			printf("select: combine offset %.6f\n",
229254359Sroberto			   sys_offset);
229354359Sroberto#endif
229454359Sroberto	}
2295182007Sroberto
2296182007Sroberto	/*
2297182007Sroberto	 * We have found the alpha male.
2298182007Sroberto	 */
2299182007Sroberto	sys_peer->flags |= FLAG_SYSPEER;
2300132454Sroberto	if (osys_peer != sys_peer) {
2301132454Sroberto		char *src;
2302132454Sroberto
2303132454Sroberto		report_event(EVNT_PEERSTCHG, NULL);
2304132454Sroberto
2305132454Sroberto#ifdef REFCLOCK
2306182007Sroberto                if (sys_peer->flags & FLAG_REFCLOCK)
2307132454Sroberto                        src = refnumtoa(&sys_peer->srcadr);
2308132454Sroberto                else
2309182007Sroberto#endif /* REFCLOCK */
2310132454Sroberto                        src = ntoa(&sys_peer->srcadr);
2311132454Sroberto		NLOG(NLOG_SYNCSTATUS)
2312182007Sroberto		    msyslog(LOG_INFO, "synchronized to %s, stratum %d",
2313182007Sroberto			src, sys_peer->stratum);
2314132454Sroberto	}
231554359Sroberto	clock_update();
231654359Sroberto}
231754359Sroberto
2318182007Sroberto
231954359Sroberto/*
2320182007Sroberto * clock_combine - compute system offset and jitter from selected peers
232154359Sroberto */
2322182007Srobertostatic void
232354359Srobertoclock_combine(
2324182007Sroberto	struct peer **peers,		/* survivor list */
2325182007Sroberto	int	npeers			/* number of survivors */
232654359Sroberto	)
232754359Sroberto{
2328132454Sroberto	int	i;
2329182007Sroberto	double	x, y, z, w;
2330132454Sroberto
2331182007Sroberto	y = z = w = 0;
233254359Sroberto	for (i = 0; i < npeers; i++) {
233354359Sroberto		x = root_distance(peers[i]);
233454359Sroberto		y += 1. / x;
233554359Sroberto		z += peers[i]->offset / x;
2336182007Sroberto		w += SQUARE(peers[i]->offset - peers[0]->offset) / x;
233754359Sroberto	}
2338182007Sroberto	sys_offset = z / y;
2339182007Sroberto	sys_jitter = SQRT(w / y);
234054359Sroberto}
234154359Sroberto
234254359Sroberto/*
234354359Sroberto * root_distance - compute synchronization distance from peer to root
234454359Sroberto */
234554359Srobertostatic double
234654359Srobertoroot_distance(
234754359Sroberto	struct peer *peer
234854359Sroberto	)
234954359Sroberto{
2350182007Sroberto	double	dist;
2351182007Sroberto
235282505Sroberto	/*
235382505Sroberto	 * Careful squeak here. The value returned must be greater than
2354182007Sroberto	 * the minimum root dispersion in order to avoid clockhop with
2355182007Sroberto	 * highly precise reference clocks. In orphan mode lose the peer
2356182007Sroberto	 * root delay, as that is used by the election algorithm.
235782505Sroberto	 */
2358182007Sroberto	if (peer->stratum >= sys_orphan)
2359182007Sroberto		dist = 0;
2360182007Sroberto	else
2361182007Sroberto		dist = peer->rootdelay;
2362182007Sroberto	dist += max(sys_mindisp, dist + peer->delay) / 2 +
236382505Sroberto	    peer->rootdispersion + peer->disp + clock_phi *
2364182007Sroberto	    (current_time - peer->update) + peer->jitter;
2365182007Sroberto	return (dist);
236654359Sroberto}
236754359Sroberto
236854359Sroberto/*
236954359Sroberto * peer_xmit - send packet for persistent association.
237054359Sroberto */
237154359Srobertostatic void
237254359Srobertopeer_xmit(
237354359Sroberto	struct peer *peer	/* peer structure pointer */
237454359Sroberto	)
237554359Sroberto{
237682505Sroberto	struct pkt xpkt;	/* transmit packet */
2377132454Sroberto	int	sendlen, authlen;
2378182007Sroberto	keyid_t	xkeyid = 0;	/* transmit key ID */
2379132454Sroberto	l_fp	xmt_tx;
238054359Sroberto
2381182007Sroberto	if (!peer->dstadr)	/* don't bother with peers without interface */
2382182007Sroberto		return;
2383182007Sroberto
238454359Sroberto	/*
2385182007Sroberto	 * This is deliciously complicated. There are three cases.
2386182007Sroberto	 *
2387182007Sroberto	 * case		leap	stratum	refid	delay	dispersion
2388182007Sroberto	 *
2389182007Sroberto	 * normal	system	system	system	system	system
2390182007Sroberto	 * orphan child	00	orphan	system	orphan	system
2391182007Sroberto	 * orphan parent 00	orphan	loopbk	0	0
239254359Sroberto	 */
2393182007Sroberto	/*
2394182007Sroberto	 * This is a normal packet. Use the system variables.
2395182007Sroberto	 */
2396182007Sroberto	if (sys_stratum < sys_orphan) {
2397182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
2398182007Sroberto		    peer->version, peer->hmode);
2399182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
2400182007Sroberto		xpkt.refid = sys_refid;
2401182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
2402182007Sroberto		xpkt.rootdispersion =
2403182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2404182007Sroberto
2405182007Sroberto	/*
2406182007Sroberto	 * This is a orphan child packet. The host is synchronized to an
2407182007Sroberto	 * orphan parent. Show leap synchronized, orphan stratum, system
2408182007Sroberto	 * reference ID, orphan root delay and system root dispersion.
2409182007Sroberto	 */
2410182007Sroberto	} else if (sys_peer != NULL) {
2411182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2412182007Sroberto		    peer->version, peer->hmode);
2413182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2414182007Sroberto		xpkt.refid = htonl(LOOPBACKADR);
2415182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay));
2416182007Sroberto		xpkt.rootdispersion =
2417182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2418182007Sroberto
2419182007Sroberto	/*
2420182007Sroberto	 * This is an orphan parent. Show leap synchronized, orphan
2421182007Sroberto	 * stratum, loopack reference ID and zero root delay and root
2422182007Sroberto	 * dispersion.
2423182007Sroberto	 */
2424182007Sroberto	} else {
2425182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2426182007Sroberto		    peer->version, peer->hmode);
2427182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2428182007Sroberto		xpkt.refid = sys_refid;
2429182007Sroberto		xpkt.rootdelay = 0;
2430182007Sroberto		xpkt.rootdispersion = 0;
2431182007Sroberto	}
243254359Sroberto	xpkt.ppoll = peer->hpoll;
243354359Sroberto	xpkt.precision = sys_precision;
243454359Sroberto	HTONL_FP(&sys_reftime, &xpkt.reftime);
243554359Sroberto	HTONL_FP(&peer->org, &xpkt.org);
243654359Sroberto	HTONL_FP(&peer->rec, &xpkt.rec);
243754359Sroberto
243854359Sroberto	/*
243982505Sroberto	 * If the received packet contains a MAC, the transmitted packet
244082505Sroberto	 * is authenticated and contains a MAC. If not, the transmitted
244182505Sroberto	 * packet is not authenticated.
244282505Sroberto	 *
2443182007Sroberto	 * It is most important when autokey is in use that the local
2444182007Sroberto	 * interface IP address be known before the first packet is
2445182007Sroberto	 * sent. Otherwise, it is not possible to compute a correct MAC
2446182007Sroberto	 * the recipient will accept. Thus, the I/O semantics have to do
2447182007Sroberto	 * a little more work. In particular, the wildcard interface
2448182007Sroberto	 * might not be usable.
244954359Sroberto	 */
245054359Sroberto	sendlen = LEN_PKT_NOMAC;
245182505Sroberto	if (!(peer->flags & FLAG_AUTHENABLE)) {
245282505Sroberto		get_systime(&peer->xmt);
245382505Sroberto		HTONL_FP(&peer->xmt, &xpkt.xmt);
2454132454Sroberto		sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl],
2455182007Sroberto			&xpkt, sendlen);
245682505Sroberto		peer->sent++;
245782505Sroberto#ifdef DEBUG
245882505Sroberto		if (debug)
245982505Sroberto			printf("transmit: at %ld %s->%s mode %d\n",
2460182007Sroberto			       current_time, peer->dstadr ? stoa(&peer->dstadr->sin) : "-",
2461182007Sroberto			       stoa(&peer->srcadr), peer->hmode);
246282505Sroberto#endif
246382505Sroberto		return;
246482505Sroberto	}
246554359Sroberto
246682505Sroberto	/*
246782505Sroberto	 * The received packet contains a MAC, so the transmitted packet
246882505Sroberto	 * must be authenticated. If autokey is enabled, fuss with the
2469182007Sroberto	 * various modes; otherwise, symmetric key cryptography is used.
247082505Sroberto	 */
2471132454Sroberto#ifdef OPENSSL
2472132454Sroberto	if (crypto_flags && (peer->flags & FLAG_SKEY)) {
2473132454Sroberto		struct exten *exten;	/* extension field */
247482505Sroberto
247554359Sroberto		/*
247682505Sroberto		 * The Public Key Dance (PKD): Cryptographic credentials
247782505Sroberto		 * are contained in extension fields, each including a
247882505Sroberto		 * 4-octet length/code word followed by a 4-octet
247982505Sroberto		 * association ID and optional additional data. Optional
248082505Sroberto		 * data includes a 4-octet data length field followed by
248182505Sroberto		 * the data itself. Request messages are sent from a
248282505Sroberto		 * configured association; response messages can be sent
248382505Sroberto		 * from a configured association or can take the fast
248482505Sroberto		 * path without ever matching an association. Response
248582505Sroberto		 * messages have the same code as the request, but have
248682505Sroberto		 * a response bit and possibly an error bit set. In this
248782505Sroberto		 * implementation, a message may contain no more than
248882505Sroberto		 * one command and no more than one response.
248982505Sroberto		 *
249082505Sroberto		 * Cryptographic session keys include both a public and
249182505Sroberto		 * a private componet. Request and response messages
249282505Sroberto		 * using extension fields are always sent with the
249382505Sroberto		 * private component set to zero. Packets without
249482505Sroberto		 * extension fields indlude the private component when
249582505Sroberto		 * the session key is generated.
249654359Sroberto		 */
249782505Sroberto		while (1) {
249882505Sroberto
249954359Sroberto			/*
250082505Sroberto			 * Allocate and initialize a keylist if not
250182505Sroberto			 * already done. Then, use the list in inverse
250282505Sroberto			 * order, discarding keys once used. Keep the
250382505Sroberto			 * latest key around until the next one, so
250482505Sroberto			 * clients can use client/server packets to
250582505Sroberto			 * compute propagation delay.
250682505Sroberto			 *
250782505Sroberto			 * Note that once a key is used from the list,
250882505Sroberto			 * it is retained in the key cache until the
250982505Sroberto			 * next key is used. This is to allow a client
251082505Sroberto			 * to retrieve the encrypted session key
251182505Sroberto			 * identifier to verify authenticity.
251282505Sroberto			 *
251382505Sroberto			 * If for some reason a key is no longer in the
251482505Sroberto			 * key cache, a birthday has happened and the
251582505Sroberto			 * pseudo-random sequence is probably broken. In
251682505Sroberto			 * that case, purge the keylist and regenerate
251782505Sroberto			 * it.
251854359Sroberto			 */
251982505Sroberto			if (peer->keynumber == 0)
252082505Sroberto				make_keylist(peer, peer->dstadr);
252182505Sroberto			else
252282505Sroberto				peer->keynumber--;
252382505Sroberto			xkeyid = peer->keylist[peer->keynumber];
252482505Sroberto			if (authistrusted(xkeyid))
252582505Sroberto				break;
252682505Sroberto			else
252782505Sroberto				key_expire(peer);
252854359Sroberto		}
252982505Sroberto		peer->keyid = xkeyid;
2530182007Sroberto		exten = NULL;
253182505Sroberto		switch (peer->hmode) {
253254359Sroberto
2533182007Sroberto			/*
2534182007Sroberto			 * In broadcast server mode the autokey values are
2535182007Sroberto			 * required by the broadcast clients. Push them when a
2536182007Sroberto			 * new keylist is generated; otherwise, push the
2537182007Sroberto			 * association message so the client can request them at
2538182007Sroberto			 * other times.
2539182007Sroberto			 */
254082505Sroberto		case MODE_BROADCAST:
254182505Sroberto			if (peer->flags & FLAG_ASSOC)
2542132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO |
2543182007Sroberto						    CRYPTO_RESP, NULL);
254482505Sroberto			else
2545132454Sroberto				exten = crypto_args(peer, CRYPTO_ASSOC |
2546182007Sroberto						    CRYPTO_RESP, NULL);
254782505Sroberto			break;
254882505Sroberto
254954359Sroberto		/*
2550132454Sroberto		 * In symmetric modes the digest, certificate, agreement
2551132454Sroberto		 * parameters, cookie and autokey values are required.
2552132454Sroberto		 * The leapsecond table is optional. But, a passive peer
2553132454Sroberto		 * will not believe the active peer until the latter has
2554132454Sroberto		 * synchronized, so the agreement must be postponed
2555132454Sroberto		 * until then. In any case, if a new keylist is
2556132454Sroberto		 * generated, the autokey values are pushed.
2557182007Sroberto		 *
2558182007Sroberto		 * If the crypto bit is lit, don't send requests.
255954359Sroberto		 */
256082505Sroberto		case MODE_ACTIVE:
256182505Sroberto		case MODE_PASSIVE:
2562182007Sroberto			if (peer->flash & TEST9)
2563182007Sroberto				break;
2564182007Sroberto			/*
2565182007Sroberto			 * Parameter and certificate.
2566182007Sroberto			 */
256782505Sroberto			if (!peer->crypto)
2568132454Sroberto				exten = crypto_args(peer, CRYPTO_ASSOC,
2569182007Sroberto						    sys_hostname);
2570132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VALID))
2571132454Sroberto				exten = crypto_args(peer, CRYPTO_CERT,
2572182007Sroberto						    peer->issuer);
2573132454Sroberto
2574132454Sroberto			/*
2575132454Sroberto			 * Identity. Note we have to sign the
2576132454Sroberto			 * certificate before the cookie to avoid a
2577132454Sroberto			 * deadlock when the passive peer is walking the
2578132454Sroberto			 * certificate trail. Awesome.
2579132454Sroberto			 */
2580182007Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VRFY))
2581182007Sroberto				exten = crypto_args(peer,
2582182007Sroberto						    crypto_ident(peer), NULL);
2583132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2584182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_SIGN))
2585132454Sroberto				exten = crypto_args(peer, CRYPTO_SIGN,
2586182007Sroberto						    sys_hostname);
2587132454Sroberto
2588132454Sroberto			/*
2589132454Sroberto			 * Autokey. We request the cookie only when the
2590132454Sroberto			 * server and client are synchronized and
2591132454Sroberto			 * signatures work both ways. On the other hand,
2592132454Sroberto			 * the active peer needs the autokey values
2593132454Sroberto			 * before then and when the passive peer is
2594132454Sroberto			 * waiting for the active peer to synchronize.
2595132454Sroberto			 * Any time we regenerate the key list, we offer
2596132454Sroberto			 * the autokey values without being asked.
2597132454Sroberto			 */
2598132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2599182007Sroberto				 peer->leap != LEAP_NOTINSYNC &&
2600182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_AGREE))
2601132454Sroberto				exten = crypto_args(peer, CRYPTO_COOK,
2602182007Sroberto						    NULL);
2603132454Sroberto			else if (peer->flags & FLAG_ASSOC)
2604132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO |
2605182007Sroberto						    CRYPTO_RESP, NULL);
2606132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_AUTO))
2607132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO,
2608182007Sroberto						    NULL);
2609132454Sroberto
2610132454Sroberto			/*
2611132454Sroberto			 * Postamble. We trade leapseconds only when the
2612132454Sroberto			 * server and client are synchronized.
2613132454Sroberto			 */
2614132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2615182007Sroberto				 peer->leap != LEAP_NOTINSYNC &&
2616182007Sroberto				 peer->crypto & CRYPTO_FLAG_TAI &&
2617182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_LEAP))
2618132454Sroberto				exten = crypto_args(peer, CRYPTO_TAI,
2619182007Sroberto						    NULL);
262082505Sroberto			break;
262182505Sroberto
262282505Sroberto		/*
2623132454Sroberto		 * In client mode the digest, certificate, agreement
2624132454Sroberto		 * parameters and cookie are required. The leapsecond
2625132454Sroberto		 * table is optional. If broadcast client mode, the
2626132454Sroberto		 * autokey values are required as well. In broadcast
2627132454Sroberto		 * client mode, these values must be acquired during the
262882505Sroberto		 * client/server exchange to avoid having to wait until
262982505Sroberto		 * the next key list regeneration. Otherwise, the poor
263082505Sroberto		 * dude may die a lingering death until becoming
2631132454Sroberto		 * unreachable and attempting rebirth.
2632132454Sroberto		 *
2633132454Sroberto		 * If neither the server or client have the agreement
2634132454Sroberto		 * parameters, the protocol transmits the cookie in the
2635132454Sroberto		 * clear. If the server has the parameters, the client
2636132454Sroberto		 * requests them and the protocol blinds it using the
2637132454Sroberto		 * agreed key. It is a protocol error if the client has
2638132454Sroberto		 * the parameters but the server does not.
2639182007Sroberto		 *
2640182007Sroberto		 * If the crypto bit is lit, don't send requests.
264182505Sroberto		 */
264282505Sroberto		case MODE_CLIENT:
2643182007Sroberto			if (peer->flash & TEST9)
2644182007Sroberto				break;
2645182007Sroberto			/*
2646182007Sroberto			 * Parameter and certificate.
2647182007Sroberto			 */
264882505Sroberto			if (!peer->crypto)
2649132454Sroberto				exten = crypto_args(peer, CRYPTO_ASSOC,
2650182007Sroberto						    sys_hostname);
2651132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VALID))
2652132454Sroberto				exten = crypto_args(peer, CRYPTO_CERT,
2653182007Sroberto						    peer->issuer);
2654132454Sroberto
2655132454Sroberto			/*
2656182007Sroberto			 * Identity
2657132454Sroberto			 */
2658182007Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_VRFY))
2659182007Sroberto				exten = crypto_args(peer,
2660182007Sroberto						    crypto_ident(peer), NULL);
2661132454Sroberto
2662132454Sroberto			/*
2663132454Sroberto			 * Autokey
2664132454Sroberto			 */
2665132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_AGREE))
2666132454Sroberto				exten = crypto_args(peer, CRYPTO_COOK,
2667182007Sroberto						    NULL);
2668132454Sroberto			else if (!(peer->crypto & CRYPTO_FLAG_AUTO) &&
2669182007Sroberto				 (peer->cast_flags & MDF_BCLNT))
2670132454Sroberto				exten = crypto_args(peer, CRYPTO_AUTO,
2671182007Sroberto						    NULL);
2672132454Sroberto
2673132454Sroberto			/*
2674132454Sroberto			 * Postamble. We can sign the certificate here,
2675132454Sroberto			 * since there is no chance of deadlock.
2676132454Sroberto			 */
2677132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2678182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_SIGN))
2679132454Sroberto				exten = crypto_args(peer, CRYPTO_SIGN,
2680182007Sroberto						    sys_hostname);
2681132454Sroberto			else if (sys_leap != LEAP_NOTINSYNC &&
2682182007Sroberto				 peer->crypto & CRYPTO_FLAG_TAI &&
2683182007Sroberto				 !(peer->crypto & CRYPTO_FLAG_LEAP))
2684132454Sroberto				exten = crypto_args(peer, CRYPTO_TAI,
2685182007Sroberto						    NULL);
268682505Sroberto			break;
268782505Sroberto		}
268882505Sroberto
268982505Sroberto		/*
2690182007Sroberto		 * Build the extension fields as directed. A response to
2691182007Sroberto		 * a request is always sent, even if an error. If an
2692182007Sroberto		 * error occurs when sending a request, the crypto
2693182007Sroberto		 * machinery broke or was misconfigured. In that case
2694182007Sroberto		 * light the crypto bit to suppress further requests.
2695182007Sroberto		 */
2696182007Sroberto		if (peer->cmmd != NULL) {
2697182007Sroberto			peer->cmmd->associd = htonl(peer->associd);
2698182007Sroberto			sendlen += crypto_xmit(&xpkt, &peer->srcadr,
2699182007Sroberto					       sendlen, peer->cmmd, 0);
2700182007Sroberto			free(peer->cmmd);
2701182007Sroberto			peer->cmmd = NULL;
2702182007Sroberto		}
2703182007Sroberto		if (exten != NULL) {
2704182007Sroberto			int ltemp = 0;
2705182007Sroberto
2706182007Sroberto			if (exten->opcode != 0) {
2707182007Sroberto				ltemp = crypto_xmit(&xpkt,
2708182007Sroberto						       &peer->srcadr, sendlen, exten, 0);
2709182007Sroberto				if (ltemp == 0) {
2710182007Sroberto					peer->flash |= TEST9; /* crypto error */
2711182007Sroberto					free(exten);
2712182007Sroberto					return;
2713182007Sroberto				}
2714182007Sroberto			}
2715182007Sroberto			sendlen += ltemp;
2716182007Sroberto			free(exten);
2717182007Sroberto		}
2718182007Sroberto
2719182007Sroberto		/*
272082505Sroberto		 * If extension fields are present, we must use a
2721182007Sroberto		 * private cookie value of zero. Don't send if the
2722182007Sroberto		 * crypto bit is set and no extension field is present,
2723182007Sroberto		 * but in that case give back the key. Most intricate.
272482505Sroberto		 */
2725182007Sroberto		if (sendlen > LEN_PKT_NOMAC) {
272682505Sroberto			session_key(&peer->dstadr->sin, &peer->srcadr,
272782505Sroberto			    xkeyid, 0, 2);
2728182007Sroberto		} else if (peer->flash & TEST9) {
2729182007Sroberto			authtrust(xkeyid, 0);
2730182007Sroberto			return;
2731182007Sroberto		}
273282505Sroberto	}
2733132454Sroberto#endif /* OPENSSL */
2734182007Sroberto
2735182007Sroberto	/*
2736182007Sroberto	 * Stash the transmit timestamp corrected for the encryption
2737182007Sroberto	 * delay. If autokey, give back the key, as we use keys only
2738182007Sroberto	 * once. Check for errors such as missing keys, buffer overflow,
2739182007Sroberto	 * etc.
2740182007Sroberto	 */
274182505Sroberto	xkeyid = peer->keyid;
274282505Sroberto	get_systime(&peer->xmt);
274382505Sroberto	L_ADD(&peer->xmt, &sys_authdelay);
274482505Sroberto	HTONL_FP(&peer->xmt, &xpkt.xmt);
274582505Sroberto	authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen);
274682505Sroberto	if (authlen == 0) {
2747182007Sroberto		msyslog(LOG_INFO, "transmit: %s key %u not found",
2748182007Sroberto		    stoa(&peer->srcadr), xkeyid);
2749182007Sroberto		peer->flash |= TEST9;		/* no key found */
275082505Sroberto		return;
275182505Sroberto	}
275282505Sroberto	sendlen += authlen;
2753132454Sroberto#ifdef OPENSSL
275482505Sroberto	if (xkeyid > NTP_MAXKEY)
275582505Sroberto		authtrust(xkeyid, 0);
2756132454Sroberto#endif /* OPENSSL */
275782505Sroberto	get_systime(&xmt_tx);
275882505Sroberto	if (sendlen > sizeof(xpkt)) {
275982505Sroberto		msyslog(LOG_ERR, "buffer overflow %u", sendlen);
2760132454Sroberto		exit (-1);
276182505Sroberto	}
2762132454Sroberto	sendpkt(&peer->srcadr, peer->dstadr, sys_ttl[peer->ttl], &xpkt,
2763182007Sroberto		sendlen);
276482505Sroberto
276582505Sroberto	/*
276682505Sroberto	 * Calculate the encryption delay. Keep the minimum over
276782505Sroberto	 * the latest two samples.
276882505Sroberto	 */
276982505Sroberto	L_SUB(&xmt_tx, &peer->xmt);
277082505Sroberto	L_ADD(&xmt_tx, &sys_authdelay);
277182505Sroberto	sys_authdly[1] = sys_authdly[0];
277282505Sroberto	sys_authdly[0] = xmt_tx.l_uf;
277382505Sroberto	if (sys_authdly[0] < sys_authdly[1])
277482505Sroberto		sys_authdelay.l_uf = sys_authdly[0];
277582505Sroberto	else
277682505Sroberto		sys_authdelay.l_uf = sys_authdly[1];
277782505Sroberto	peer->sent++;
2778132454Sroberto#ifdef OPENSSL
277954359Sroberto#ifdef DEBUG
278082505Sroberto	if (debug)
278182505Sroberto		printf(
2782182007Sroberto			"transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d index %d\n",
2783182007Sroberto			current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-",
2784182007Sroberto			ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen -
2785182007Sroberto			authlen, authlen, peer->keynumber);
278654359Sroberto#endif
278782505Sroberto#else
278882505Sroberto#ifdef DEBUG
278982505Sroberto	if (debug)
279082505Sroberto		printf(
2791182007Sroberto			"transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n",
2792182007Sroberto			current_time, peer->dstadr ? ntoa(&peer->dstadr->sin) : "-",
2793182007Sroberto			ntoa(&peer->srcadr), peer->hmode, xkeyid, sendlen -
2794182007Sroberto			authlen, authlen);
279582505Sroberto#endif
2796132454Sroberto#endif /* OPENSSL */
279754359Sroberto}
279854359Sroberto
279982505Sroberto
280054359Sroberto/*
280182505Sroberto * fast_xmit - Send packet for nonpersistent association. Note that
280282505Sroberto * neither the source or destination can be a broadcast address.
280354359Sroberto */
280454359Srobertostatic void
280554359Srobertofast_xmit(
280654359Sroberto	struct recvbuf *rbufp,	/* receive packet pointer */
2807132454Sroberto	int	xmode,		/* transmit mode */
2808132454Sroberto	keyid_t	xkeyid,		/* transmit key ID */
2809132454Sroberto	int	mask		/* restrict mask */
281054359Sroberto	)
281154359Sroberto{
2812132454Sroberto	struct pkt xpkt;		/* transmit packet structure */
2813132454Sroberto	struct pkt *rpkt;		/* receive packet structure */
2814132454Sroberto	l_fp	xmt_ts;			/* timestamp */
2815132454Sroberto	l_fp	xmt_tx;			/* timestamp after authent */
2816132454Sroberto	int	sendlen, authlen;
2817132454Sroberto#ifdef OPENSSL
2818132454Sroberto	u_int32	temp32;
2819132454Sroberto#endif
282054359Sroberto
282154359Sroberto	/*
282282505Sroberto	 * Initialize transmit packet header fields from the receive
282382505Sroberto	 * buffer provided. We leave some fields intact as received. If
2824182007Sroberto	 * the gazinta was from a multicast address, the gazoutta must
2825182007Sroberto	 * go out another way.
2826182007Sroberto	 *
2827182007Sroberto	 * The root delay field is special. If the system stratum is
2828182007Sroberto	 * less than the orphan stratum, send the real root delay.
2829182007Sroberto	 * Otherwise, if there is no system peer, send the orphan delay.
2830182007Sroberto	 * Otherwise, we must be an orphan parent, so send zero.
283154359Sroberto	 */
283254359Sroberto	rpkt = &rbufp->recv_pkt;
2833182007Sroberto	if (rbufp->dstadr->flags & INT_MCASTOPEN)
283482505Sroberto		rbufp->dstadr = findinterface(&rbufp->recv_srcadr);
283582505Sroberto
283682505Sroberto	/*
2837182007Sroberto	 * This is deliciously complicated. There are four cases.
2838182007Sroberto	 *
2839182007Sroberto	 * case		leap	stratum	refid	delay	dispersion
2840182007Sroberto	 *
2841182007Sroberto	 * KoD		11	16	KISS	system	system
2842182007Sroberto	 * normal	system	system	system	system	system
2843182007Sroberto	 * orphan child	00	orphan	system	orphan	system
2844182007Sroberto	 * orphan parent 00	orphan	loopbk	0	0
284582505Sroberto	 */
2846182007Sroberto	/*
2847182007Sroberto	 * This is a kiss-of-death (KoD) packet. Show leap
2848182007Sroberto	 * unsynchronized, stratum zero, reference ID the four-character
2849182007Sroberto	 * kiss code and system root delay. Note the rate limit on these
2850182007Sroberto	 * packets. Once a second initialize a bucket counter. Every
2851182007Sroberto	 * packet sent decrements the counter until reaching zero. If
2852182007Sroberto	 * the counter is zero, drop the kiss.
2853182007Sroberto	 */
2854182007Sroberto	if (mask & RES_LIMITED) {
2855182007Sroberto		sys_limitrejected++;
2856132454Sroberto		if (sys_kod == 0 || !(mask & RES_DEMOBILIZE))
285782505Sroberto			return;
2858132454Sroberto
2859132454Sroberto		sys_kod--;
2860132454Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
2861132454Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
2862132454Sroberto		xpkt.stratum = STRATUM_UNSPEC;
2863182007Sroberto		memcpy(&xpkt.refid, "RATE", 4);
2864182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
2865182007Sroberto		xpkt.rootdispersion =
2866182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2867182007Sroberto
2868182007Sroberto	/*
2869182007Sroberto	 * This is a normal packet. Use the system variables.
2870182007Sroberto	 */
2871182007Sroberto	} else if (sys_stratum < sys_orphan) {
287282505Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(sys_leap,
287382505Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
287482505Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_stratum);
287582505Sroberto		xpkt.refid = sys_refid;
2876182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_rootdelay));
2877182007Sroberto		xpkt.rootdispersion =
2878182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2879182007Sroberto
2880182007Sroberto	/*
2881182007Sroberto	 * This is a orphan child packet. The host is synchronized to an
2882182007Sroberto	 * orphan parent. Show leap synchronized, orphan stratum, system
2883182007Sroberto	 * reference ID and orphan root delay.
2884182007Sroberto	 */
2885182007Sroberto	} else if (sys_peer != NULL) {
2886182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2887182007Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
2888182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2889182007Sroberto		xpkt.refid = sys_refid;
2890182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(sys_orphandelay));
2891182007Sroberto		xpkt.rootdispersion =
2892182007Sroberto		    HTONS_FP(DTOUFP(sys_rootdispersion));
2893182007Sroberto
2894182007Sroberto	/*
2895182007Sroberto	 * This is an orphan parent. Show leap synchronized, orphan
2896182007Sroberto	 * stratum, loopack reference ID and zero root delay.
2897182007Sroberto	 */
2898182007Sroberto	} else {
2899182007Sroberto		xpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
2900182007Sroberto		    PKT_VERSION(rpkt->li_vn_mode), xmode);
2901182007Sroberto		xpkt.stratum = STRATUM_TO_PKT(sys_orphan);
2902182007Sroberto		xpkt.refid = htonl(LOOPBACKADR);
2903182007Sroberto		xpkt.rootdelay = HTONS_FP(DTOFP(0));
2904182007Sroberto		xpkt.rootdispersion = HTONS_FP(DTOFP(0));
290582505Sroberto	}
290654359Sroberto	xpkt.ppoll = rpkt->ppoll;
290754359Sroberto	xpkt.precision = sys_precision;
2908182007Sroberto	xpkt.rootdispersion = HTONS_FP(DTOUFP(sys_rootdispersion));
290954359Sroberto	HTONL_FP(&sys_reftime, &xpkt.reftime);
291054359Sroberto	xpkt.org = rpkt->xmt;
291154359Sroberto	HTONL_FP(&rbufp->recv_time, &xpkt.rec);
291282505Sroberto
291382505Sroberto	/*
291482505Sroberto	 * If the received packet contains a MAC, the transmitted packet
291582505Sroberto	 * is authenticated and contains a MAC. If not, the transmitted
291682505Sroberto	 * packet is not authenticated.
291782505Sroberto	 */
291854359Sroberto	sendlen = LEN_PKT_NOMAC;
291982505Sroberto	if (rbufp->recv_length == sendlen) {
292054359Sroberto		get_systime(&xmt_ts);
292154359Sroberto		HTONL_FP(&xmt_ts, &xpkt.xmt);
292282505Sroberto		sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt,
292356749Sroberto		    sendlen);
292454359Sroberto#ifdef DEBUG
292554359Sroberto		if (debug)
292682505Sroberto			printf("transmit: at %ld %s->%s mode %d\n",
2927132454Sroberto			    current_time, stoa(&rbufp->dstadr->sin),
2928132454Sroberto			    stoa(&rbufp->recv_srcadr), xmode);
292954359Sroberto#endif
293082505Sroberto		return;
293182505Sroberto	}
293254359Sroberto
293382505Sroberto	/*
293482505Sroberto	 * The received packet contains a MAC, so the transmitted packet
2935182007Sroberto	 * must be authenticated. For symmetric key cryptography, use
2936182007Sroberto	 * the predefined and trusted symmetric keys to generate the
2937182007Sroberto	 * cryptosum. For autokey cryptography, use the server private
2938182007Sroberto	 * value to generate the cookie, which is unique for every
2939182007Sroberto	 * source-destination-key ID combination.
294082505Sroberto	 */
2941132454Sroberto#ifdef OPENSSL
294282505Sroberto	if (xkeyid > NTP_MAXKEY) {
294382505Sroberto		keyid_t cookie;
294482505Sroberto
294554359Sroberto		/*
294682505Sroberto		 * The only way to get here is a reply to a legitimate
294782505Sroberto		 * client request message, so the mode must be
294882505Sroberto		 * MODE_SERVER. If an extension field is present, there
294982505Sroberto		 * can be only one and that must be a command. Do what
295082505Sroberto		 * needs, but with private value of zero so the poor
295182505Sroberto		 * jerk can decode it. If no extension field is present,
295282505Sroberto		 * use the cookie to generate the session key.
295354359Sroberto		 */
295482505Sroberto		cookie = session_key(&rbufp->recv_srcadr,
295582505Sroberto		    &rbufp->dstadr->sin, 0, sys_private, 0);
2956182007Sroberto		if (rbufp->recv_length >= (int)(sendlen + MAX_MAC_LEN +
2957182007Sroberto		    2 * sizeof(u_int32))) {
295882505Sroberto			session_key(&rbufp->dstadr->sin,
295982505Sroberto			    &rbufp->recv_srcadr, xkeyid, 0, 2);
2960132454Sroberto			temp32 = CRYPTO_RESP;
2961132454Sroberto			rpkt->exten[0] |= htonl(temp32);
2962132454Sroberto			sendlen += crypto_xmit(&xpkt,
2963132454Sroberto			    &rbufp->recv_srcadr, sendlen,
2964132454Sroberto			    (struct exten *)rpkt->exten, cookie);
296582505Sroberto		} else {
296682505Sroberto			session_key(&rbufp->dstadr->sin,
296782505Sroberto			    &rbufp->recv_srcadr, xkeyid, cookie, 2);
296882505Sroberto		}
296982505Sroberto	}
2970132454Sroberto#endif /* OPENSSL */
297182505Sroberto	get_systime(&xmt_ts);
297282505Sroberto	L_ADD(&xmt_ts, &sys_authdelay);
297382505Sroberto	HTONL_FP(&xmt_ts, &xpkt.xmt);
297482505Sroberto	authlen = authencrypt(xkeyid, (u_int32 *)&xpkt, sendlen);
297582505Sroberto	sendlen += authlen;
2976132454Sroberto#ifdef OPENSSL
297782505Sroberto	if (xkeyid > NTP_MAXKEY)
297882505Sroberto		authtrust(xkeyid, 0);
2979132454Sroberto#endif /* OPENSSL */
298082505Sroberto	get_systime(&xmt_tx);
298182505Sroberto	if (sendlen > sizeof(xpkt)) {
298282505Sroberto		msyslog(LOG_ERR, "buffer overflow %u", sendlen);
2983132454Sroberto		exit (-1);
298482505Sroberto	}
298582505Sroberto	sendpkt(&rbufp->recv_srcadr, rbufp->dstadr, 0, &xpkt, sendlen);
298682505Sroberto
298782505Sroberto	/*
298882505Sroberto	 * Calculate the encryption delay. Keep the minimum over the
298982505Sroberto	 * latest two samples.
299082505Sroberto	 */
299182505Sroberto	L_SUB(&xmt_tx, &xmt_ts);
299282505Sroberto	L_ADD(&xmt_tx, &sys_authdelay);
299382505Sroberto	sys_authdly[1] = sys_authdly[0];
299482505Sroberto	sys_authdly[0] = xmt_tx.l_uf;
299582505Sroberto	if (sys_authdly[0] < sys_authdly[1])
299682505Sroberto		sys_authdelay.l_uf = sys_authdly[0];
299782505Sroberto	else
299882505Sroberto		sys_authdelay.l_uf = sys_authdly[1];
299954359Sroberto#ifdef DEBUG
300082505Sroberto	if (debug)
300182505Sroberto		printf(
300282505Sroberto		    "transmit: at %ld %s->%s mode %d keyid %08x len %d mac %d\n",
300382505Sroberto		    current_time, ntoa(&rbufp->dstadr->sin),
3004132454Sroberto		    ntoa(&rbufp->recv_srcadr), xmode, xkeyid, sendlen -
3005132454Sroberto		    authlen, authlen);
300654359Sroberto#endif
300754359Sroberto}
300854359Sroberto
300982505Sroberto
3010132454Sroberto#ifdef OPENSSL
301154359Sroberto/*
301282505Sroberto * key_expire - purge the key list
301354359Sroberto */
301482505Srobertovoid
301582505Srobertokey_expire(
301682505Sroberto	struct peer *peer	/* peer structure pointer */
301754359Sroberto	)
301854359Sroberto{
301954359Sroberto	int i;
302054359Sroberto
3021132454Sroberto	if (peer->keylist != NULL) {
302282505Sroberto		for (i = 0; i <= peer->keynumber; i++)
302382505Sroberto			authtrust(peer->keylist[i], 0);
302482505Sroberto		free(peer->keylist);
302582505Sroberto		peer->keylist = NULL;
302654359Sroberto	}
3027132454Sroberto	value_free(&peer->sndval);
3028132454Sroberto	peer->keynumber = 0;
302982505Sroberto#ifdef DEBUG
303082505Sroberto	if (debug)
303182505Sroberto		printf("key_expire: at %lu\n", current_time);
303282505Sroberto#endif
303354359Sroberto}
3034132454Sroberto#endif /* OPENSSL */
303554359Sroberto
3036132454Sroberto
303754359Sroberto/*
3038132454Sroberto * Determine if the peer is unfit for synchronization
3039132454Sroberto *
3040132454Sroberto * A peer is unfit for synchronization if
3041182007Sroberto * > TEST10 bad leap or stratum below floor or at or above ceiling
3042182007Sroberto * > TEST11 root distance exceeded
3043182007Sroberto * > TEST12 a direct or indirect synchronization loop would form
3044182007Sroberto * > TEST13 unreachable or noselect
3045132454Sroberto */
3046182007Srobertoint				/* FALSE if fit, TRUE if unfit */
3047132454Srobertopeer_unfit(
3048132454Sroberto	struct peer *peer	/* peer structure pointer */
3049132454Sroberto	)
3050132454Sroberto{
3051182007Sroberto	int	rval = 0;
3052182007Sroberto
3053182007Sroberto	/*
3054182007Sroberto	 * A stratum error occurs if (1) the server has never been
3055182007Sroberto	 * synchronized, (2) the server stratum is below the floor or
3056182007Sroberto	 * greater than or equal to the ceiling, (3) the system stratum
3057182007Sroberto	 * is below the orphan stratum and the server stratum is greater
3058182007Sroberto	 * than or equal to the orphan stratum.
3059182007Sroberto	 */
3060182007Sroberto	if (peer->leap == LEAP_NOTINSYNC || peer->stratum < sys_floor ||
3061182007Sroberto	    peer->stratum >= sys_ceiling || (sys_stratum < sys_orphan &&
3062182007Sroberto	    peer->stratum >= sys_orphan))
3063182007Sroberto		rval |= TEST10;		/* stratum out of bounds */
3064182007Sroberto
3065182007Sroberto	/*
3066182007Sroberto	 * A distance error occurs if the root distance is greater than
3067182007Sroberto	 * or equal to the distance threshold plus the increment due to
3068182007Sroberto	 * one poll interval.
3069182007Sroberto	 */
3070182007Sroberto	if (root_distance(peer) >= sys_maxdist + clock_phi *
3071182007Sroberto	    ULOGTOD(sys_poll))
3072182007Sroberto		rval |= TEST11;		/* distance exceeded */
3073182007Sroberto
3074182007Sroberto	/*
3075182007Sroberto	 * A loop error occurs if the remote peer is synchronized to the
3076182007Sroberto	 * local peer of if the remote peer is synchronized to the same
3077182007Sroberto	 * server as the local peer, but only if the remote peer is not
3078182007Sroberto	 * the orphan parent.
3079182007Sroberto	 */
3080182007Sroberto	if (peer->stratum > 1 && peer->refid != htonl(LOOPBACKADR) &&
3081182007Sroberto	    ((!peer->dstadr || peer->refid == peer->dstadr->addr_refid) ||
3082182007Sroberto	    peer->refid == sys_refid))
3083182007Sroberto		rval |= TEST12;		/* synch loop */
3084182007Sroberto
3085182007Sroberto	/*
3086182007Sroberto	 * An unreachable error occurs if the server is unreachable or
3087182007Sroberto	 * the noselect bit is set.
3088182007Sroberto	 */
3089182007Sroberto	if (!peer->reach || peer->flags & FLAG_NOSELECT)
3090182007Sroberto		rval |= TEST13;		/* unreachable */
3091182007Sroberto
3092182007Sroberto	peer->flash &= ~PEER_TEST_MASK;
3093182007Sroberto	peer->flash |= rval;
3094182007Sroberto	return (rval);
3095132454Sroberto}
3096132454Sroberto
3097132454Sroberto
3098132454Sroberto/*
309954359Sroberto * Find the precision of this particular machine
310054359Sroberto */
3101132454Sroberto#define MINSTEP 100e-9		/* minimum clock increment (s) */
3102132454Sroberto#define MAXSTEP 20e-3		/* maximum clock increment (s) */
3103132454Sroberto#define MINLOOPS 5		/* minimum number of step samples */
310454359Sroberto
310554359Sroberto/*
3106132454Sroberto * This routine calculates the system precision, defined as the minimum
3107182007Sroberto * of a sequence of differences between successive readings of the
3108132454Sroberto * system clock. However, if the system clock can be read more than once
3109132454Sroberto * during a tick interval, the difference can be zero or one LSB unit,
3110132454Sroberto * where the LSB corresponds to one nanosecond or one microsecond.
3111132454Sroberto * Conceivably, if some other process preempts this one and reads the
3112132454Sroberto * clock, the difference can be more than one LSB unit.
3113132454Sroberto *
3114132454Sroberto * For hardware clock frequencies of 10 MHz or less, we assume the
3115132454Sroberto * logical clock advances only at the hardware clock tick. For higher
3116132454Sroberto * frequencies, we assume the logical clock can advance no more than 100
3117132454Sroberto * nanoseconds between ticks.
311854359Sroberto */
311954359Srobertoint
312054359Srobertodefault_get_precision(void)
312154359Sroberto{
3122132454Sroberto	l_fp	val;		/* current seconds fraction */
3123132454Sroberto	l_fp	last;		/* last seconds fraction */
3124132454Sroberto	l_fp	diff;		/* difference */
3125132454Sroberto	double	tick;		/* computed tick value */
3126132454Sroberto	double	dtemp;		/* scratch */
3127132454Sroberto	int	i;		/* log2 precision */
312854359Sroberto
3129132454Sroberto	/*
3130132454Sroberto	 * Loop to find tick value in nanoseconds. Toss out outlyer
3131132454Sroberto	 * values less than the minimun tick value. In wacky cases, use
3132132454Sroberto	 * the default maximum value.
313354359Sroberto	 */
3134132454Sroberto	get_systime(&last);
3135132454Sroberto	tick = MAXSTEP;
3136132454Sroberto	for (i = 0; i < MINLOOPS;) {
3137132454Sroberto		get_systime(&val);
3138132454Sroberto		diff = val;
3139132454Sroberto		L_SUB(&diff, &last);
3140132454Sroberto		last = val;
3141132454Sroberto		LFPTOD(&diff, dtemp);
3142132454Sroberto		if (dtemp < MINSTEP)
3143132454Sroberto			continue;
3144132454Sroberto		i++;
3145132454Sroberto		if (dtemp < tick)
3146132454Sroberto			tick = dtemp;
314754359Sroberto	}
3148132454Sroberto
3149132454Sroberto	/*
3150132454Sroberto	 * Find the nearest power of two.
3151132454Sroberto	 */
3152132454Sroberto	NLOG(NLOG_SYSEVENT)
3153132454Sroberto	    msyslog(LOG_INFO, "precision = %.3f usec", tick * 1e6);
3154132454Sroberto	for (i = 0; tick <= 1; i++)
3155132454Sroberto		tick *= 2;
3156132454Sroberto	if (tick - 1. > 1. - tick / 2)
3157132454Sroberto		i--;
3158132454Sroberto	return (-i);
315954359Sroberto}
316054359Sroberto
3161132454Sroberto
316254359Sroberto/*
3163132454Sroberto * kod_proto - called once per second to limit kiss-of-death packets
3164132454Sroberto */
3165132454Srobertovoid
3166132454Srobertokod_proto(void)
3167132454Sroberto{
3168132454Sroberto	sys_kod = sys_kod_rate;
3169132454Sroberto}
3170132454Sroberto
3171132454Sroberto
3172132454Sroberto/*
317354359Sroberto * init_proto - initialize the protocol module's data
317454359Sroberto */
317554359Srobertovoid
317654359Srobertoinit_proto(void)
317754359Sroberto{
3178132454Sroberto	l_fp	dummy;
3179132454Sroberto	int	i;
318054359Sroberto
318154359Sroberto	/*
318254359Sroberto	 * Fill in the sys_* stuff.  Default is don't listen to
318354359Sroberto	 * broadcasting, authenticate.
318454359Sroberto	 */
318554359Sroberto	sys_leap = LEAP_NOTINSYNC;
318654359Sroberto	sys_stratum = STRATUM_UNSPEC;
3187132454Sroberto	memcpy(&sys_refid, "INIT", 4);
318854359Sroberto	sys_precision = (s_char)default_get_precision();
318982505Sroberto	sys_jitter = LOGTOD(sys_precision);
319054359Sroberto	sys_rootdelay = 0;
3191182007Sroberto	sys_orphandelay = (double)(ntp_random() & 0xffff) / 65536. *
3192182007Sroberto	    sys_maxdist;
319354359Sroberto	sys_rootdispersion = 0;
319454359Sroberto	L_CLR(&sys_reftime);
319582505Sroberto	sys_peer = NULL;
319682505Sroberto	sys_survivors = 0;
319754359Sroberto	get_systime(&dummy);
3198132454Sroberto	sys_manycastserver = 0;
319954359Sroberto	sys_bclient = 0;
320054359Sroberto	sys_bdelay = DEFBROADDELAY;
3201132454Sroberto	sys_calldelay = BURST_DELAY;
320254359Sroberto	sys_authenticate = 1;
320354359Sroberto	L_CLR(&sys_authdelay);
320454359Sroberto	sys_authdly[0] = sys_authdly[1] = 0;
320554359Sroberto	sys_stattime = 0;
3206132454Sroberto	proto_clr_stats();
3207132454Sroberto	for (i = 0; i < MAX_TTL; i++) {
3208132454Sroberto		sys_ttl[i] = (u_char)((i * 256) / MAX_TTL);
3209132454Sroberto		sys_ttlmax = i;
3210132454Sroberto	}
3211132454Sroberto#ifdef OPENSSL
321254359Sroberto	sys_automax = 1 << NTP_AUTOMAX;
3213132454Sroberto#endif /* OPENSSL */
321454359Sroberto
321554359Sroberto	/*
321654359Sroberto	 * Default these to enable
321754359Sroberto	 */
321854359Sroberto	ntp_enable = 1;
321954359Sroberto#ifndef KERNEL_FLL_BUG
322054359Sroberto	kern_enable = 1;
322154359Sroberto#endif
322282505Sroberto	pps_enable = 0;
322354359Sroberto	stats_control = 1;
322454359Sroberto}
322554359Sroberto
322654359Sroberto
322754359Sroberto/*
322854359Sroberto * proto_config - configure the protocol module
322954359Sroberto */
323054359Srobertovoid
323154359Srobertoproto_config(
3232132454Sroberto	int	item,
3233132454Sroberto	u_long	value,
3234132454Sroberto	double	dvalue,
3235132454Sroberto	struct sockaddr_storage* svalue
323654359Sroberto	)
323754359Sroberto{
323854359Sroberto	/*
323954359Sroberto	 * Figure out what he wants to change, then do it
324054359Sroberto	 */
324154359Sroberto	switch (item) {
3242132454Sroberto
3243132454Sroberto	/*
3244132454Sroberto	 * Turn on/off kernel discipline.
3245132454Sroberto	 */
324656749Sroberto	case PROTO_KERNEL:
324754359Sroberto		kern_enable = (int)value;
324854359Sroberto		break;
324954359Sroberto
3250132454Sroberto	/*
3251132454Sroberto	 * Turn on/off clock discipline.
3252132454Sroberto	 */
325356749Sroberto	case PROTO_NTP:
325454359Sroberto		ntp_enable = (int)value;
325554359Sroberto		break;
325654359Sroberto
3257132454Sroberto	/*
3258132454Sroberto	 * Turn on/off monitoring.
3259132454Sroberto	 */
326056749Sroberto	case PROTO_MONITOR:
326154359Sroberto		if (value)
326254359Sroberto			mon_start(MON_ON);
326354359Sroberto		else
326454359Sroberto			mon_stop(MON_ON);
326554359Sroberto		break;
326654359Sroberto
3267132454Sroberto	/*
3268132454Sroberto	 * Turn on/off statistics.
3269132454Sroberto	 */
327056749Sroberto	case PROTO_FILEGEN:
327154359Sroberto		stats_control = (int)value;
327254359Sroberto		break;
327354359Sroberto
3274132454Sroberto	/*
3275182007Sroberto	 * Turn on/off enable broadcasts.
3276132454Sroberto	 */
327756749Sroberto	case PROTO_BROADCLIENT:
327854359Sroberto		sys_bclient = (int)value;
3279182007Sroberto		if (sys_bclient == 0)
3280182007Sroberto			io_unsetbclient();
3281182007Sroberto		else
328254359Sroberto			io_setbclient();
328354359Sroberto		break;
328454359Sroberto
3285132454Sroberto	/*
3286182007Sroberto	 * Turn on/off PPS discipline.
3287182007Sroberto	 */
3288182007Sroberto	case PROTO_PPS:
3289182007Sroberto		pps_enable = (int)value;
3290182007Sroberto		break;
3291182007Sroberto
3292182007Sroberto	/*
3293132454Sroberto	 * Add muliticast group address.
3294132454Sroberto	 */
329556749Sroberto	case PROTO_MULTICAST_ADD:
3296132454Sroberto		if (svalue)
3297132454Sroberto		    io_multicast_add(*svalue);
3298182007Sroberto		sys_bclient = 1;
329954359Sroberto		break;
330054359Sroberto
3301132454Sroberto	/*
3302132454Sroberto	 * Delete multicast group address.
3303132454Sroberto	 */
330456749Sroberto	case PROTO_MULTICAST_DEL:
3305132454Sroberto		if (svalue)
3306132454Sroberto		    io_multicast_del(*svalue);
330754359Sroberto		break;
330854359Sroberto
3309132454Sroberto	/*
3310132454Sroberto	 * Set default broadcast delay.
3311132454Sroberto	 */
331256749Sroberto	case PROTO_BROADDELAY:
331354359Sroberto		sys_bdelay = dvalue;
331454359Sroberto		break;
331554359Sroberto
3316132454Sroberto	/*
3317132454Sroberto	 * Set modem call delay.
3318132454Sroberto	 */
3319132454Sroberto	case PROTO_CALLDELAY:
3320132454Sroberto		sys_calldelay = (int)value;
3321132454Sroberto		break;
3322132454Sroberto
3323132454Sroberto	/*
3324182007Sroberto	 * Turn on/off authentication to mobilize ephemeral
3325182007Sroberto	 * associations.
3326132454Sroberto	 */
332756749Sroberto	case PROTO_AUTHENTICATE:
332854359Sroberto		sys_authenticate = (int)value;
332954359Sroberto		break;
333054359Sroberto
3331132454Sroberto	/*
3332182007Sroberto	 * Set minimum number of survivors.
3333132454Sroberto	 */
3334182007Sroberto	case PROTO_MINCLOCK:
3335182007Sroberto		sys_minclock = (int)dvalue;
333682505Sroberto		break;
333782505Sroberto
3338132454Sroberto	/*
3339182007Sroberto	 * Set maximum number of preemptable associations.
3340132454Sroberto	 */
3341182007Sroberto	case PROTO_MAXCLOCK:
3342182007Sroberto		sys_maxclock = (int)dvalue;
3343132454Sroberto		break;
3344132454Sroberto
3345132454Sroberto	/*
3346182007Sroberto	 * Set minimum number of survivors.
3347132454Sroberto	 */
3348132454Sroberto	case PROTO_MINSANE:
3349132454Sroberto		sys_minsane = (int)dvalue;
3350132454Sroberto		break;
3351132454Sroberto
3352132454Sroberto	/*
3353182007Sroberto	 * Set stratum floor.
3354132454Sroberto	 */
3355132454Sroberto	case PROTO_FLOOR:
3356132454Sroberto		sys_floor = (int)dvalue;
3357132454Sroberto		break;
3358132454Sroberto
3359132454Sroberto	/*
3360182007Sroberto	 * Set stratum ceiling.
3361132454Sroberto	 */
3362132454Sroberto	case PROTO_CEILING:
3363132454Sroberto		sys_ceiling = (int)dvalue;
3364132454Sroberto		break;
3365132454Sroberto
3366132454Sroberto	/*
3367182007Sroberto	 * Set orphan stratum.
3368132454Sroberto	 */
3369182007Sroberto	case PROTO_ORPHAN:
3370182007Sroberto		sys_orphan = (int)dvalue;
3371182007Sroberto		break;
3372182007Sroberto
3373182007Sroberto	/*
3374182007Sroberto	 * Set cohort switch.
3375182007Sroberto	 */
3376132454Sroberto	case PROTO_COHORT:
3377182007Sroberto		sys_cohort = (int)dvalue;
3378132454Sroberto		break;
3379182007Sroberto
3380132454Sroberto	/*
3381182007Sroberto	 * Set minimum dispersion increment.
3382132454Sroberto	 */
3383182007Sroberto	case PROTO_MINDISP:
3384182007Sroberto		sys_mindisp = dvalue;
3385182007Sroberto		break;
3386182007Sroberto
3387182007Sroberto	/*
3388182007Sroberto	 * Set maximum distance (select threshold).
3389182007Sroberto	 */
3390182007Sroberto	case PROTO_MAXDIST:
3391182007Sroberto		sys_maxdist = dvalue;
3392182007Sroberto		break;
3393182007Sroberto
3394182007Sroberto	/*
3395182007Sroberto	 * Set anticlockhop threshold.
3396182007Sroberto	 */
3397182007Sroberto	case PROTO_MAXHOP:
3398182007Sroberto		sys_maxhop = (int)dvalue;
3399182007Sroberto		break;
3400182007Sroberto
3401182007Sroberto	/*
3402182007Sroberto	 * Set adjtime() resolution (s).
3403182007Sroberto	 */
3404132454Sroberto	case PROTO_ADJ:
3405132454Sroberto		sys_tick = dvalue;
3406132454Sroberto		break;
3407132454Sroberto
3408182007Sroberto	/*
3409182007Sroberto	 * Set manycast beacon interval.
3410182007Sroberto	 */
3411182007Sroberto	case PROTO_BEACON:
3412182007Sroberto		sys_beacon = (int)dvalue;
3413182007Sroberto		break;
3414182007Sroberto
341582505Sroberto#ifdef REFCLOCK
3416132454Sroberto	/*
3417132454Sroberto	 * Turn on/off refclock calibrate
3418132454Sroberto	 */
341982505Sroberto	case PROTO_CAL:
342082505Sroberto		cal_enable = (int)value;
342182505Sroberto		break;
3422182007Sroberto#endif /* REFCLOCK */
342356749Sroberto	default:
342456749Sroberto
342554359Sroberto		/*
3426132454Sroberto		 * Log this error.
342754359Sroberto		 */
3428132454Sroberto		msyslog(LOG_INFO,
3429182007Sroberto		    "proto_config: illegal item %d, value %ld", item,
3430182007Sroberto		    value);
343154359Sroberto	}
343254359Sroberto}
343354359Sroberto
343454359Sroberto
343554359Sroberto/*
343654359Sroberto * proto_clr_stats - clear protocol stat counters
343754359Sroberto */
343854359Srobertovoid
343954359Srobertoproto_clr_stats(void)
344054359Sroberto{
3441132454Sroberto	sys_stattime = current_time;
3442132454Sroberto	sys_received = 0;
3443132454Sroberto	sys_processed = 0;
3444132454Sroberto	sys_newversionpkt = 0;
344554359Sroberto	sys_oldversionpkt = 0;
344654359Sroberto	sys_unknownversion = 0;
3447132454Sroberto	sys_restricted = 0;
344854359Sroberto	sys_badlength = 0;
344954359Sroberto	sys_badauth = 0;
345054359Sroberto	sys_limitrejected = 0;
345154359Sroberto}
3452