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