1/*	$NetBSD: ntp_peer.c,v 1.3 2012/02/01 07:46:22 kardel Exp $	*/
2
3/*
4 * ntp_peer.c - management of data maintained for peer associations
5 */
6#ifdef HAVE_CONFIG_H
7#include <config.h>
8#endif
9
10#include <stdio.h>
11#include <sys/types.h>
12
13#include "ntpd.h"
14#include "ntp_lists.h"
15#include "ntp_stdlib.h"
16#include "ntp_control.h"
17#include <ntp_random.h>
18#ifdef OPENSSL
19#include "openssl/rand.h"
20#endif /* OPENSSL */
21
22#ifdef SYS_WINNT
23int accept_wildcard_if_for_winnt;
24#else
25const int accept_wildcard_if_for_winnt = FALSE;
26#endif
27
28/*
29 *                  Table of valid association combinations
30 *                  ---------------------------------------
31 *
32 *                             packet->mode
33 * peer->mode      | UNSPEC  ACTIVE PASSIVE  CLIENT  SERVER  BCAST
34 * ----------      | ---------------------------------------------
35 * NO_PEER         |   e       1       0       1       1       1
36 * ACTIVE          |   e       1       1       0       0       0
37 * PASSIVE         |   e       1       e       0       0       0
38 * CLIENT          |   e       0       0       0       1       0
39 * SERVER          |   e       0       0       0       0       0
40 * BCAST           |   e       0       0       0       0       0
41 * BCLIENT         |   e       0       0       0       e       1
42 *
43 * One point to note here: a packet in BCAST mode can potentially match
44 * a peer in CLIENT mode, but we that is a special case and we check for
45 * that early in the decision process.  This avoids having to keep track
46 * of what kind of associations are possible etc...  We actually
47 * circumvent that problem by requiring that the first b(m)roadcast
48 * received after the change back to BCLIENT mode sets the clock.
49 */
50#define AM_MODES	7	/* number of rows and columns */
51#define NO_PEER		0	/* action when no peer is found */
52
53int AM[AM_MODES][AM_MODES] = {
54/*	{ UNSPEC,   ACTIVE,     PASSIVE,    CLIENT,     SERVER,     BCAST } */
55
56/*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT,   AM_MANYCAST, AM_NEWBCL},
57
58/*A*/	{ AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
59
60/*P*/	{ AM_ERR, AM_PROCPKT, AM_ERR,     AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
61
62/*C*/	{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT,  AM_NOMATCH},
63
64/*S*/	{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
65
66/*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
67
68/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_PROCPKT},
69};
70
71#define MATCH_ASSOC(x, y)	AM[(x)][(y)]
72
73/*
74 * These routines manage the allocation of memory to peer structures
75 * and the maintenance of the peer hash table. The three main entry
76 * points are findpeer(), which looks for matching peer structures in
77 * the peer list, newpeer(), which allocates a new peer structure and
78 * adds it to the list, and unpeer(), which demobilizes the association
79 * and deallocates the structure.
80 */
81/*
82 * Peer hash tables
83 */
84struct peer *peer_hash[NTP_HASH_SIZE];	/* peer hash table */
85int	peer_hash_count[NTP_HASH_SIZE];	/* peers in each bucket */
86struct peer *assoc_hash[NTP_HASH_SIZE];	/* association ID hash table */
87int	assoc_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
88static struct peer *peer_free;		/* peer structures free list */
89int	peer_free_count;		/* count of free structures */
90
91/*
92 * Association ID.  We initialize this value randomly, then assign a new
93 * value every time the peer structure is incremented.
94 */
95static associd_t current_association_ID; /* association ID */
96
97/*
98 * Memory allocation watermarks.
99 */
100#define	INIT_PEER_ALLOC		15	/* initialize for 15 peers */
101#define	INC_PEER_ALLOC		5	/* when run out, add 5 more */
102
103/*
104 * Miscellaneous statistic counters which may be queried.
105 */
106u_long	peer_timereset;			/* time stat counters zeroed */
107u_long	findpeer_calls;			/* calls to findpeer */
108u_long	assocpeer_calls;		/* calls to findpeerbyassoc */
109u_long	peer_allocations;		/* allocations from free list */
110u_long	peer_demobilizations;		/* structs freed to free list */
111int	total_peer_structs;		/* peer structs */
112int	peer_associations;		/* mobilized associations */
113int	peer_preempt;			/* preemptable associations */
114static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
115
116static void	    getmorepeermem	 (void);
117static struct interface *select_peerinterface (struct peer *, sockaddr_u *, struct interface *, u_char);
118
119static int score(struct peer *);
120
121/*
122 * init_peer - initialize peer data structures and counters
123 *
124 * N.B. We use the random number routine in here. It had better be
125 * initialized prior to getting here.
126 */
127void
128init_peer(void)
129{
130	register int i;
131
132	/*
133	 * Clear hash tables and counters.
134	 */
135	memset(peer_hash, 0, sizeof(peer_hash));
136	memset(peer_hash_count, 0, sizeof(peer_hash_count));
137	memset(assoc_hash, 0, sizeof(assoc_hash));
138	memset(assoc_hash_count, 0, sizeof(assoc_hash_count));
139
140	/*
141	 * Clear stat counters
142	 */
143	findpeer_calls = peer_allocations = 0;
144	assocpeer_calls = peer_demobilizations = 0;
145
146	/*
147	 * Initialize peer memory.
148	 */
149	peer_free = NULL;
150	for (i = 0; i < INIT_PEER_ALLOC; i++)
151		LINK_SLIST(peer_free, &init_peer_alloc[i], next);
152	total_peer_structs = INIT_PEER_ALLOC;
153	peer_free_count = INIT_PEER_ALLOC;
154
155	/*
156	 * Initialize our first association ID
157	 */
158	while ((current_association_ID = ntp_random() & 0xffff) == 0);
159}
160
161
162/*
163 * getmorepeermem - add more peer structures to the free list
164 */
165static void
166getmorepeermem(void)
167{
168	register int i;
169	register struct peer *peer;
170
171	peer = (struct peer *)emalloc(INC_PEER_ALLOC *
172	    sizeof(struct peer));
173	for (i = 0; i < INC_PEER_ALLOC; i++) {
174		LINK_SLIST(peer_free, peer, next);
175		peer++;
176	}
177
178	total_peer_structs += INC_PEER_ALLOC;
179	peer_free_count += INC_PEER_ALLOC;
180}
181
182
183/*
184 * findexistingpeer - return a pointer to a peer in the hash table
185 */
186struct peer *
187findexistingpeer(
188	sockaddr_u *	addr,
189	struct peer *	start_peer,
190	int		mode,
191	u_char		cast_flags
192	)
193{
194	register struct peer *peer;
195
196	/*
197	 * start_peer is included so we can locate instances of the
198	 * same peer through different interfaces in the hash table.
199	 * Without MDF_BCLNT, a match requires the same mode and remote
200	 * address.  MDF_BCLNT associations start out as MODE_CLIENT
201	 * if broadcastdelay is not specified, and switch to
202	 * MODE_BCLIENT after estimating the one-way delay.  Duplicate
203	 * associations are expanded in definition to match any other
204	 * MDF_BCLNT with the same srcadr (remote, unicast address).
205	 */
206	if (NULL == start_peer)
207		peer = peer_hash[NTP_HASH_ADDR(addr)];
208	else
209		peer = start_peer->next;
210
211	while (peer != NULL) {
212 		if (ADDR_PORT_EQ(addr, &peer->srcadr)
213		    && (-1 == mode || peer->hmode == mode ||
214			((MDF_BCLNT & peer->cast_flags) &&
215			 (MDF_BCLNT & cast_flags))))
216			break;
217		peer = peer->next;
218	}
219
220	return peer;
221}
222
223
224/*
225 * findpeer - find and return a peer match for a received datagram in
226 *	      the peer_hash table.
227 */
228struct peer *
229findpeer(
230	struct recvbuf *rbufp,
231	int		pkt_mode,
232	int *		action
233	)
234{
235	struct peer *	p;
236	sockaddr_u *	srcadr;
237	u_int		hash;
238	struct pkt *	pkt;
239	l_fp		pkt_org;
240
241	findpeer_calls++;
242	srcadr = &rbufp->recv_srcadr;
243	hash = NTP_HASH_ADDR(srcadr);
244	for (p = peer_hash[hash]; p != NULL; p = p->next) {
245		if (SOCK_EQ(srcadr, &p->srcadr) &&
246		    NSRCPORT(srcadr) == NSRCPORT(&p->srcadr)) {
247
248			/*
249			 * if the association matching rules determine
250			 * that this is not a valid combination, then
251			 * look for the next valid peer association.
252			 */
253			*action = MATCH_ASSOC(p->hmode, pkt_mode);
254
255			/*
256			 * A response to our manycastclient solicitation
257			 * might be misassociated with an ephemeral peer
258			 * already spun for the server.  If the packet's
259			 * org timestamp doesn't match the peer's, check
260			 * if it matches the ACST prototype peer's.  If
261			 * so it is a redundant solicitation response,
262			 * return AM_ERR to discard it.  [Bug 1762]
263			 */
264			if (MODE_SERVER == pkt_mode &&
265			    AM_PROCPKT == *action) {
266				pkt = &rbufp->recv_pkt;
267				NTOHL_FP(&pkt->org, &pkt_org);
268				if (!L_ISEQU(&p->aorg, &pkt_org) &&
269				    findmanycastpeer(rbufp))
270					*action = AM_ERR;
271			}
272
273			/*
274			 * if an error was returned, exit back right
275			 * here.
276			 */
277			if (*action == AM_ERR)
278				return NULL;
279
280			/*
281			 * if a match is found, we stop our search.
282			 */
283			if (*action != AM_NOMATCH)
284				break;
285		}
286	}
287
288	/*
289	 * If no matching association is found
290	 */
291	if (NULL == p) {
292		*action = MATCH_ASSOC(NO_PEER, pkt_mode);
293	} else if (p->dstadr != rbufp->dstadr) {
294		set_peerdstadr(p, rbufp->dstadr);
295		if (p->dstadr == rbufp->dstadr) {
296			DPRINTF(1, ("Changed %s local address to match response\n",
297				    stoa(&p->srcadr)));
298			return findpeer(rbufp, pkt_mode, action);
299		}
300	}
301	return p;
302}
303
304/*
305 * findpeerbyassocid - find and return a peer using his association ID
306 */
307struct peer *
308findpeerbyassoc(
309	u_int assoc
310	)
311{
312	struct peer *p;
313	u_int hash;
314
315	assocpeer_calls++;
316
317	hash = assoc & NTP_HASH_MASK;
318	for (p = assoc_hash[hash]; p != NULL; p = p->ass_next) {
319		if (assoc == p->associd)
320			return p;
321	}
322	return NULL;
323}
324
325
326/*
327 * clear_all - flush all time values for all associations
328 */
329void
330clear_all(void)
331{
332	struct peer *peer, *next_peer;
333	int n;
334
335	/*
336	 * This routine is called when the clock is stepped, and so all
337	 * previously saved time values are untrusted.
338	 */
339	for (n = 0; n < NTP_HASH_SIZE; n++) {
340		for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
341			next_peer = peer->next;
342			if (!(peer->cast_flags & (MDF_ACAST |
343			    MDF_MCAST | MDF_BCAST))) {
344				peer_clear(peer, "STEP");
345			}
346		}
347	}
348#ifdef DEBUG
349	if (debug)
350		printf("clear_all: at %lu\n", current_time);
351#endif
352}
353
354
355/*
356 * score_all() - determine if an association can be demobilized
357 */
358int
359score_all(
360	struct peer *peer	/* peer structure pointer */
361	)
362{
363	struct peer *speer, *next_peer;
364	int	n;
365	int	temp, tamp;
366
367	/*
368	 * This routine finds the minimum score for all ephemeral
369	 * assocations and returns > 0 if the association can be
370	 * demobilized.
371	 */
372	tamp = score(peer);
373	temp = 100;
374	for (n = 0; n < NTP_HASH_SIZE; n++) {
375		for (speer = peer_hash[n]; speer != 0; speer =
376		    next_peer) {
377			int	x;
378
379			next_peer = speer->next;
380			if ((x = score(speer)) < temp && (peer->flags &
381			    FLAG_PREEMPT))
382				temp = x;
383		}
384	}
385#ifdef DEBUG
386	if (debug)
387		printf("score_all: at %lu score %d min %d\n",
388		    current_time, tamp, temp);
389#endif
390	if (tamp != temp)
391		temp = 0;
392	return (temp);
393}
394
395
396/*
397 * score() - calculate preemption score
398 */
399static int
400score(
401	struct peer *peer	/* peer structure pointer */
402	)
403{
404	int	temp;
405
406	/*
407	 * This routine calculates the premption score from the peer
408	 * error bits and status. Increasing values are more cherished.
409	 */
410	temp = 0;
411	if (!(peer->flash & TEST10))
412		temp++;			/* 1 good synch and stratum */
413	if (!(peer->flash & TEST13))
414		temp++;			/* 2 reachable */
415	if (!(peer->flash & TEST12))
416		temp++;			/* 3 no loop */
417	if (!(peer->flash & TEST11))
418		temp++;			/* 4 good distance */
419	if (peer->status >= CTL_PST_SEL_SELCAND)
420		temp++;			/* 5 in the hunt */
421	if (peer->status != CTL_PST_SEL_EXCESS)
422		temp++;			/* 6 not spare tire */
423	return (temp);			/* selection status */
424}
425
426
427/*
428 * unpeer - remove peer structure from hash table and free structure
429 */
430void
431unpeer(
432	struct peer *peer_to_remove
433	)
434{
435	register struct peer *unlinked;
436	int	hash;
437	char	tbuf[80];
438
439	snprintf(tbuf, sizeof(tbuf), "assoc %d",
440	    peer_to_remove->associd);
441	report_event(PEVNT_DEMOBIL, peer_to_remove, tbuf);
442	set_peerdstadr(peer_to_remove, NULL);
443	hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
444	peer_hash_count[hash]--;
445	peer_demobilizations++;
446	peer_associations--;
447	if (peer_to_remove->flags & FLAG_PREEMPT)
448		peer_preempt--;
449#ifdef REFCLOCK
450	/*
451	 * If this peer is actually a clock, shut it down first
452	 */
453	if (peer_to_remove->flags & FLAG_REFCLOCK)
454		refclock_unpeer(peer_to_remove);
455#endif
456	peer_to_remove->action = 0;	/* disable timeout actions */
457
458	UNLINK_SLIST(unlinked, peer_hash[hash], peer_to_remove, next,
459	    struct peer);
460
461	if (NULL == unlinked) {
462		peer_hash_count[hash]++;
463		msyslog(LOG_ERR, "peer struct for %s not in table!",
464		    stoa(&peer_to_remove->srcadr));
465	}
466
467	/*
468	 * Remove him from the association hash as well.
469	 */
470	hash = peer_to_remove->associd & NTP_HASH_MASK;
471	assoc_hash_count[hash]--;
472
473	UNLINK_SLIST(unlinked, assoc_hash[hash], peer_to_remove,
474	    ass_next, struct peer);
475
476	if (NULL == unlinked) {
477		assoc_hash_count[hash]++;
478		msyslog(LOG_ERR,
479		    "peer struct for %s not in association table!",
480		    stoa(&peer_to_remove->srcadr));
481	}
482
483	LINK_SLIST(peer_free, peer_to_remove, next);
484	peer_free_count++;
485}
486
487
488/*
489 * peer_config - configure a new association
490 */
491struct peer *
492peer_config(
493	sockaddr_u *srcadr,
494	struct interface *dstadr,
495	int hmode,
496	int version,
497	int minpoll,
498	int maxpoll,
499	u_int flags,
500	int ttl,
501	keyid_t key,
502	const u_char *keystr
503	)
504{
505	u_char cast_flags;
506
507	/*
508	 * We do a dirty little jig to figure the cast flags. This is
509	 * probably not the best place to do this, at least until the
510	 * configure code is rebuilt. Note only one flag can be set.
511	 */
512	switch (hmode) {
513	case MODE_BROADCAST:
514		if (IS_MCAST(srcadr))
515			cast_flags = MDF_MCAST;
516		else
517			cast_flags = MDF_BCAST;
518		break;
519
520	case MODE_CLIENT:
521		if (IS_MCAST(srcadr))
522			cast_flags = MDF_ACAST;
523		else
524			cast_flags = MDF_UCAST;
525		break;
526
527	default:
528		cast_flags = MDF_UCAST;
529	}
530
531	/*
532	 * Mobilize the association and initialize its variables. If
533	 * emulating ntpdate, force iburst.
534	 */
535	if (mode_ntpdate)
536		flags |= FLAG_IBURST;
537	return(newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
538	    flags | FLAG_CONFIG, cast_flags, ttl, key));
539}
540
541/*
542 * setup peer dstadr field keeping it in sync with the interface
543 * structures
544 */
545void
546set_peerdstadr(
547	struct peer *	p,
548	endpt *		dstadr
549	)
550{
551	struct peer *	unlinked;
552
553	if (p->dstadr == dstadr)
554		return;
555
556	/*
557	 * Don't accept updates to a separate multicast receive-only
558	 * endpt while a BCLNT peer is running its unicast protocol.
559	 */
560	if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
561	    (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
562		return;
563	}
564	if (p->dstadr != NULL) {
565		p->dstadr->peercnt--;
566		UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
567			     struct peer);
568		msyslog(LOG_INFO, "%s interface %s -> %s",
569			stoa(&p->srcadr), stoa(&p->dstadr->sin),
570			(dstadr != NULL)
571			    ? stoa(&dstadr->sin)
572			    : "(none)");
573	}
574	p->dstadr = dstadr;
575	if (dstadr != NULL) {
576		LINK_SLIST(dstadr->peers, p, ilink);
577		dstadr->peercnt++;
578	}
579}
580
581/*
582 * attempt to re-rebind interface if necessary
583 */
584static void
585peer_refresh_interface(
586	struct peer *peer
587	)
588{
589	endpt *	niface;
590	endpt *	piface;
591
592	niface = select_peerinterface(peer, &peer->srcadr, NULL,
593				      peer->cast_flags);
594
595	DPRINTF(4, (
596	    "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ",
597	    peer->dstadr == NULL ? "<null>" :
598	    stoa(&peer->dstadr->sin), stoa(&peer->srcadr),
599	    peer->hmode, peer->version, peer->minpoll,
600	    peer->maxpoll, peer->flags, peer->cast_flags,
601	    peer->ttl, peer->keyid));
602	if (niface != NULL) {
603		DPRINTF(4, (
604		    "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s",
605		    niface->fd,  niface->bfd, niface->name,
606		    niface->flags, niface->ifindex,
607		    stoa(&niface->sin)));
608		if (niface->flags & INT_BROADCAST)
609			DPRINTF(4, (", bcast=%s",
610				stoa(&niface->bcast)));
611		DPRINTF(4, (", mask=%s\n", stoa(&niface->mask)));
612	} else {
613		DPRINTF(4, ("<NONE>\n"));
614	}
615
616	piface = peer->dstadr;
617	set_peerdstadr(peer, niface);
618	if (peer->dstadr) {
619		/*
620		 * clear crypto if we change the local address
621		 */
622		if (peer->dstadr != piface && !(peer->cast_flags &
623		    MDF_ACAST) && peer->pmode != MODE_BROADCAST)
624			peer_clear(peer, "XFAC");
625
626		/*
627	 	 * Broadcast needs the socket enabled for broadcast
628	 	 */
629		if (peer->cast_flags & MDF_BCAST) {
630			enable_broadcast(peer->dstadr, &peer->srcadr);
631		}
632
633		/*
634	 	 * Multicast needs the socket interface enabled for
635		 * multicast
636	 	 */
637		if (peer->cast_flags & MDF_MCAST) {
638			enable_multicast_if(peer->dstadr,
639			    &peer->srcadr);
640		}
641	}
642}
643
644/*
645 * refresh_all_peerinterfaces - see that all interface bindings are up
646 * to date
647 */
648void
649refresh_all_peerinterfaces(void)
650{
651	struct peer *peer, *next_peer;
652	int n;
653
654	/*
655	 * this is called when the interface list has changed
656	 * give all peers a chance to find a better interface
657	 */
658	for (n = 0; n < NTP_HASH_SIZE; n++) {
659		for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
660			next_peer = peer->next;
661			peer_refresh_interface(peer);
662		}
663	}
664}
665
666
667/*
668 * find an interface suitable for the src address
669 */
670static endpt *
671select_peerinterface(
672	struct peer *	peer,
673	sockaddr_u *	srcadr,
674	endpt *		dstadr,
675	u_char		cast_flags
676	)
677{
678	endpt *ep;
679	endpt *wild;
680
681	wild = ANY_INTERFACE_CHOOSE(srcadr);
682
683	/*
684	 * Initialize the peer structure and dance the interface jig.
685	 * Reference clocks step the loopback waltz, the others
686	 * squaredance around the interface list looking for a buddy. If
687	 * the dance peters out, there is always the wildcard interface.
688	 * This might happen in some systems and would preclude proper
689	 * operation with public key cryptography.
690	 */
691	if (ISREFCLOCKADR(srcadr)) {
692		ep = loopback_interface;
693	} else if (cast_flags &
694		   (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
695		ep = findbcastinter(srcadr);
696		if (ep != NULL)
697			DPRINTF(4, ("Found *-cast interface %s for address %s\n",
698				stoa(&ep->sin), stoa(srcadr)));
699		else
700			DPRINTF(4, ("No *-cast local address found for address %s\n",
701				stoa(srcadr)));
702	} else {
703		ep = dstadr;
704		if (NULL == ep)
705			ep = wild;
706	}
707	/*
708	 * If it is a multicast address, findbcastinter() may not find
709	 * it.  For unicast, we get to find the interface when dstadr is
710	 * given to us as the wildcard (ANY_INTERFACE_CHOOSE).  Either
711	 * way, try a little harder.
712	 */
713	if (wild == ep)
714		ep = findinterface(srcadr);
715	/*
716	 * we do not bind to the wildcard interfaces for output
717	 * as our (network) source address would be undefined and
718	 * crypto will not work without knowing the own transmit address
719	 */
720	if (ep != NULL && INT_WILDCARD & ep->flags)
721		if (!accept_wildcard_if_for_winnt)
722			ep = NULL;
723
724	return ep;
725}
726
727/*
728 * newpeer - initialize a new peer association
729 */
730struct peer *
731newpeer(
732	sockaddr_u *srcadr,
733	struct interface *dstadr,
734	int	hmode,
735	int	version,
736	int	minpoll,
737	int	maxpoll,
738	u_int	flags,
739	u_char	cast_flags,
740	int	ttl,
741	keyid_t	key
742	)
743{
744	struct peer *peer;
745	u_int	hash;
746	char	tbuf[80];
747
748#ifdef OPENSSL
749	/*
750	 * If Autokey is requested but not configured, complain loudly.
751	 */
752	if (!crypto_flags) {
753		if (key > NTP_MAXKEY) {
754			return (NULL);
755
756		} else if (flags & FLAG_SKEY) {
757			msyslog(LOG_ERR, "Autokey not configured");
758			return (NULL);
759		}
760	}
761#endif /* OPENSSL */
762
763	/*
764	 * First search from the beginning for an association with given
765	 * remote address and mode. If an interface is given, search
766	 * from there to find the association which matches that
767	 * destination. If the given interface is "any", track down the
768	 * actual interface, because that's what gets put into the peer
769	 * structure.
770	 */
771	if (dstadr != NULL) {
772		peer = findexistingpeer(srcadr, NULL, hmode, cast_flags);
773		while (peer != NULL) {
774			if (peer->dstadr == dstadr ||
775			    ((MDF_BCLNT & cast_flags) &&
776			     (MDF_BCLNT & peer->cast_flags)))
777				break;
778
779			if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
780			    peer->dstadr == findinterface(srcadr))
781				break;
782
783			peer = findexistingpeer(srcadr, peer, hmode,
784						cast_flags);
785		}
786	} else {
787		/* no endpt address given */
788		peer = findexistingpeer(srcadr, NULL, hmode, cast_flags);
789	}
790
791	/*
792	 * If a peer is found, this would be a duplicate and we don't
793	 * allow that. This avoids duplicate ephemeral (broadcast/
794	 * multicast) and preemptible (manycast and pool) client
795	 * associations.
796	 */
797	if (peer != NULL)
798		return (NULL);
799
800	/*
801	 * Allocate a new peer structure. Some dirt here, since some of
802	 * the initialization requires knowlege of our system state.
803	 */
804	if (peer_free_count == 0)
805		getmorepeermem();
806	UNLINK_HEAD_SLIST(peer, peer_free, next);
807	peer_free_count--;
808	peer_associations++;
809	if (flags & FLAG_PREEMPT)
810		peer_preempt++;
811	memset(peer, 0, sizeof(*peer));
812
813	/*
814	 * Assign an association ID and increment the system variable.
815	 */
816	peer->associd = current_association_ID;
817	if (++current_association_ID == 0)
818		++current_association_ID;
819
820	DPRINTF(3, ("newpeer: cast flags: 0x%x for address: %s\n",
821		    cast_flags, stoa(srcadr)));
822
823	peer->srcadr = *srcadr;
824	set_peerdstadr(peer, select_peerinterface(peer, srcadr, dstadr,
825	    cast_flags));
826	peer->hmode = (u_char)hmode;
827	peer->version = (u_char)version;
828	peer->flags = flags;
829
830	/*
831	 * It is an error to set minpoll less than NTP_MINPOLL or to
832	 * set maxpoll greater than NTP_MAXPOLL. However, minpoll is
833	 * clamped not greater than NTP_MAXPOLL and maxpoll is clamped
834	 * not less than NTP_MINPOLL without complaint. Finally,
835	 * minpoll is clamped not greater than maxpoll.
836	 */
837	if (minpoll == 0)
838		peer->minpoll = NTP_MINDPOLL;
839	else
840		peer->minpoll = (u_char)min(minpoll, NTP_MAXPOLL);
841	if (maxpoll == 0)
842		peer->maxpoll = NTP_MAXDPOLL;
843	else
844		peer->maxpoll = (u_char)max(maxpoll, NTP_MINPOLL);
845	if (peer->minpoll > peer->maxpoll)
846		peer->minpoll = peer->maxpoll;
847
848	if (peer->dstadr)
849		DPRINTF(3, ("newpeer: using fd %d and our addr %s\n",
850			    peer->dstadr->fd, stoa(&peer->dstadr->sin)));
851	else
852		DPRINTF(3, ("newpeer: local interface currently not bound\n"));
853
854	/*
855	 * Broadcast needs the socket enabled for broadcast
856	 */
857	if ((cast_flags & MDF_BCAST) && peer->dstadr)
858		enable_broadcast(peer->dstadr, srcadr);
859
860	/*
861	 * Multicast needs the socket interface enabled for multicast
862	 */
863	if ((cast_flags & MDF_MCAST) && peer->dstadr)
864		enable_multicast_if(peer->dstadr, srcadr);
865
866#ifdef OPENSSL
867	if (key > NTP_MAXKEY)
868		peer->flags |= FLAG_SKEY;
869#endif /* OPENSSL */
870	peer->cast_flags = cast_flags;
871	peer->ttl = (u_char)ttl;
872	peer->keyid = key;
873	peer->precision = sys_precision;
874	peer->hpoll = peer->minpoll;
875	if (cast_flags & MDF_ACAST)
876		peer_clear(peer, "ACST");
877	else if (cast_flags & MDF_MCAST)
878		peer_clear(peer, "MCST");
879	else if (cast_flags & MDF_BCAST)
880		peer_clear(peer, "BCST");
881	else
882		peer_clear(peer, "INIT");
883	if (mode_ntpdate)
884		peer_ntpdate++;
885
886	/*
887	 * Note time on statistics timers.
888	 */
889	peer->timereset = current_time;
890	peer->timereachable = current_time;
891	peer->timereceived = current_time;
892
893#ifdef REFCLOCK
894	if (ISREFCLOCKADR(&peer->srcadr)) {
895
896		/*
897		 * We let the reference clock support do clock
898		 * dependent initialization.  This includes setting
899		 * the peer timer, since the clock may have requirements
900		 * for this.
901		 */
902		if (maxpoll == 0)
903			peer->maxpoll = peer->minpoll;
904		if (!refclock_newpeer(peer)) {
905			/*
906			 * Dump it, something screwed up
907			 */
908			set_peerdstadr(peer, NULL);
909			LINK_SLIST(peer_free, peer, next);
910			peer_free_count++;
911			return (NULL);
912		}
913	}
914#endif
915
916	/*
917	 * Put the new peer in the hash tables.
918	 */
919	hash = NTP_HASH_ADDR(&peer->srcadr);
920	LINK_SLIST(peer_hash[hash], peer, next);
921	peer_hash_count[hash]++;
922	hash = peer->associd & NTP_HASH_MASK;
923	LINK_SLIST(assoc_hash[hash], peer, ass_next);
924	assoc_hash_count[hash]++;
925	snprintf(tbuf, sizeof(tbuf), "assoc %d", peer->associd);
926	report_event(PEVNT_MOBIL, peer, tbuf);
927	DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
928	    peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
929	    stoa(&peer->srcadr), peer->hmode, peer->version,
930	    peer->minpoll, peer->maxpoll, peer->flags, peer->cast_flags,
931	    peer->ttl, peer->keyid));
932	return (peer);
933}
934
935
936/*
937 * peer_clr_stats - clear peer module statiistics counters
938 */
939void
940peer_clr_stats(void)
941{
942	findpeer_calls = 0;
943	assocpeer_calls = 0;
944	peer_allocations = 0;
945	peer_demobilizations = 0;
946	peer_timereset = current_time;
947}
948
949/*
950 * peer_reset - reset statistics counters
951 */
952void
953peer_reset(
954	struct peer *peer
955	)
956{
957	if (peer == NULL)
958		return;
959
960	peer->timereset = current_time;
961	peer->sent = 0;
962	peer->received = 0;
963	peer->processed = 0;
964	peer->badauth = 0;
965	peer->bogusorg = 0;
966	peer->oldpkt = 0;
967	peer->seldisptoolarge = 0;
968	peer->selbroken = 0;
969}
970
971
972/*
973 * peer_all_reset - reset all peer statistics counters
974 */
975void
976peer_all_reset(void)
977{
978	struct peer *peer;
979	int hash;
980
981	for (hash = 0; hash < NTP_HASH_SIZE; hash++)
982	    for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
983		peer_reset(peer);
984}
985
986
987/*
988 * findmanycastpeer - find and return a manycast peer
989 */
990struct peer *
991findmanycastpeer(
992	struct recvbuf *rbufp	/* receive buffer pointer */
993	)
994{
995	register struct peer *peer;
996	struct pkt *pkt;
997	l_fp p_org;
998	int i;
999
1000 	/*
1001 	 * This routine is called upon arrival of a server-mode message
1002	 * from a manycast client. Search the peer list for a manycast
1003	 * client association where the last transmit timestamp matches
1004	 * the originate timestamp. This assumes the transmit timestamps
1005	 * for possibly more than one manycast association are unique.
1006	 */
1007	pkt = &rbufp->recv_pkt;
1008	for (i = 0; i < NTP_HASH_SIZE; i++) {
1009		if (peer_hash_count[i] == 0)
1010			continue;
1011
1012		for (peer = peer_hash[i]; peer != 0; peer =
1013		    peer->next) {
1014			if (peer->cast_flags & MDF_ACAST) {
1015				NTOHL_FP(&pkt->org, &p_org);
1016				if (L_ISEQU(&p_org, &peer->aorg))
1017					return (peer);
1018			}
1019		}
1020	}
1021	return (NULL);
1022}
1023