ntp_peer.c revision 289999
11541Srgrimes/*
21541Srgrimes * ntp_peer.c - management of data maintained for peer associations
31541Srgrimes */
41541Srgrimes#ifdef HAVE_CONFIG_H
551138Salfred#include <config.h>
6127484Smtm#endif
71541Srgrimes
81541Srgrimes#include <stdio.h>
91541Srgrimes#include <sys/types.h>
1064002Speter
111541Srgrimes#include "ntpd.h"
121541Srgrimes#include "ntp_lists.h"
131541Srgrimes#include "ntp_stdlib.h"
141541Srgrimes#include "ntp_control.h"
151541Srgrimes#include <ntp_random.h>
161541Srgrimes
171541Srgrimes/*
181541Srgrimes *		    Table of valid association combinations
191541Srgrimes *		    ---------------------------------------
201541Srgrimes *
211541Srgrimes *                             packet->mode
221541Srgrimes * peer->mode      | UNSPEC  ACTIVE PASSIVE  CLIENT  SERVER  BCAST
231541Srgrimes * ----------      | ---------------------------------------------
241541Srgrimes * NO_PEER         |   e       1       0       1       1       1
251541Srgrimes * ACTIVE          |   e       1       1       0       0       0
261541Srgrimes * PASSIVE         |   e       1       e       0       0       0
27122540Smckusick * CLIENT          |   e       0       0       0       1       0
281541Srgrimes * SERVER          |   e       0       0       0       0       0
291541Srgrimes * BCAST           |   e       0       0       0       0       0
301541Srgrimes * BCLIENT         |   e       0       0       0       e       1
311541Srgrimes *
321541Srgrimes * One point to note here: a packet in BCAST mode can potentially match
331541Srgrimes * a peer in CLIENT mode, but we that is a special case and we check for
341541Srgrimes * that early in the decision process.  This avoids having to keep track
351541Srgrimes * of what kind of associations are possible etc...  We actually
361541Srgrimes * circumvent that problem by requiring that the first b(m)roadcast
371541Srgrimes * received after the change back to BCLIENT mode sets the clock.
381541Srgrimes */
391541Srgrimes#define AM_MODES	7	/* number of rows and columns */
401541Srgrimes#define NO_PEER		0	/* action when no peer is found */
411541Srgrimes
421541Srgrimesint AM[AM_MODES][AM_MODES] = {
431541Srgrimes/*			packet->mode					    */
441541Srgrimes/* peer { UNSPEC,   ACTIVE,     PASSIVE,    CLIENT,     SERVER,     BCAST } */
451541Srgrimes/* mode */
461541Srgrimes/*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT,   AM_MANYCAST, AM_NEWBCL},
471541Srgrimes
481541Srgrimes/*A*/	{ AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
491541Srgrimes
501541Srgrimes/*P*/	{ AM_ERR, AM_PROCPKT, AM_ERR,     AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
511541Srgrimes
521541Srgrimes/*C*/	{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT,  AM_NOMATCH},
531541Srgrimes
541541Srgrimes/*S*/	{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
5552150Smarcel
561541Srgrimes/*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
5752150Smarcel
581541Srgrimes/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_PROCPKT},
591541Srgrimes};
601541Srgrimes
6152150Smarcel#define MATCH_ASSOC(x, y)	AM[(x)][(y)]
621541Srgrimes
631541Srgrimes/*
641541Srgrimes * These routines manage the allocation of memory to peer structures
651541Srgrimes * and the maintenance of three data structures involving all peers:
661541Srgrimes *
671541Srgrimes * - peer_list is a single list with all peers, suitable for scanning
681541Srgrimes *   operations over all peers.
691541Srgrimes * - peer_adr_hash is an array of lists indexed by hashed peer address.
701541Srgrimes * - peer_aid_hash is an array of lists indexed by hashed associd.
711541Srgrimes *
721541Srgrimes * They also maintain a free list of peer structures, peer_free.
731541Srgrimes *
741541Srgrimes * The three main entry points are findpeer(), which looks for matching
751541Srgrimes * peer structures in the peer list, newpeer(), which allocates a new
761541Srgrimes * peer structure and adds it to the list, and unpeer(), which
771541Srgrimes * demobilizes the association and deallocates the structure.
781541Srgrimes */
791541Srgrimes/*
801541Srgrimes * Peer hash tables
811541Srgrimes */
821541Srgrimesstruct peer *peer_hash[NTP_HASH_SIZE];	/* peer hash table */
831541Srgrimesint	peer_hash_count[NTP_HASH_SIZE];	/* peers in each bucket */
841541Srgrimesstruct peer *assoc_hash[NTP_HASH_SIZE];	/* association ID hash table */
851541Srgrimesint	assoc_hash_count[NTP_HASH_SIZE];/* peers in each bucket */
861541Srgrimesstruct peer *peer_list;			/* peer structures list */
871541Srgrimesstatic struct peer *peer_free;		/* peer structures free list */
881541Srgrimesint	peer_free_count;		/* count of free structures */
891541Srgrimes
901541Srgrimes/*
911541Srgrimes * Association ID.  We initialize this value randomly, then assign a new
921541Srgrimes * value every time an association is mobilized.
931541Srgrimes */
941541Srgrimesstatic associd_t current_association_ID; /* association ID */
951541Srgrimesstatic associd_t initial_association_ID; /* association ID */
961541Srgrimes
971541Srgrimes/*
981541Srgrimes * Memory allocation watermarks.
991541Srgrimes */
1001541Srgrimes#define	INIT_PEER_ALLOC		8	/* static preallocation */
1011541Srgrimes#define	INC_PEER_ALLOC		4	/* add N more when empty */
1021541Srgrimes
1031541Srgrimes/*
1041541Srgrimes * Miscellaneous statistic counters which may be queried.
1051541Srgrimes */
1061541Srgrimesu_long	peer_timereset;			/* time stat counters zeroed */
1071541Srgrimesu_long	findpeer_calls;			/* calls to findpeer */
1081541Srgrimesu_long	assocpeer_calls;		/* calls to findpeerbyassoc */
1091541Srgrimesu_long	peer_allocations;		/* allocations from free list */
110105950Speteru_long	peer_demobilizations;		/* structs freed to free list */
1111541Srgrimesint	total_peer_structs;		/* peer structs */
1121541Srgrimesint	peer_associations;		/* mobilized associations */
1131541Srgrimesint	peer_preempt;			/* preemptable associations */
1141541Srgrimesstatic struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
1151541Srgrimes
1161541Srgrimesstatic struct peer *	findexistingpeer_name(const char *, u_short,
1171541Srgrimes					      struct peer *, int);
11852150Smarcelstatic struct peer *	findexistingpeer_addr(sockaddr_u *,
1191541Srgrimes					      struct peer *, int,
1201541Srgrimes					      u_char);
1211541Srgrimesstatic void		free_peer(struct peer *, int);
1221541Srgrimesstatic void		getmorepeermem(void);
1231541Srgrimesstatic int		score(struct peer *);
1241541Srgrimes
1251541Srgrimes
1261541Srgrimes/*
1271541Srgrimes * init_peer - initialize peer data structures and counters
1281541Srgrimes *
1291541Srgrimes * N.B. We use the random number routine in here. It had better be
1301541Srgrimes * initialized prior to getting here.
1311541Srgrimes */
1328019Sachevoid
1338019Sacheinit_peer(void)
1341541Srgrimes{
1351541Srgrimes	int i;
1361541Srgrimes
1371541Srgrimes	/*
1381541Srgrimes	 * Initialize peer free list from static allocation.
1391541Srgrimes	 */
1401541Srgrimes	for (i = COUNTOF(init_peer_alloc) - 1; i >= 0; i--)
1411541Srgrimes		LINK_SLIST(peer_free, &init_peer_alloc[i], p_link);
1421541Srgrimes	total_peer_structs = COUNTOF(init_peer_alloc);
1431541Srgrimes	peer_free_count = COUNTOF(init_peer_alloc);
1441541Srgrimes
1451541Srgrimes	/*
1461541Srgrimes	 * Initialize our first association ID
1471541Srgrimes	 */
1481541Srgrimes	do
1491541Srgrimes		current_association_ID = ntp_random() & ASSOCID_MAX;
1501541Srgrimes	while (!current_association_ID);
1511541Srgrimes	initial_association_ID = current_association_ID;
1521541Srgrimes}
1531541Srgrimes
1541541Srgrimes
1551541Srgrimes/*
1561541Srgrimes * getmorepeermem - add more peer structures to the free list
1571541Srgrimes */
1581541Srgrimesstatic void
159122540Smckusickgetmorepeermem(void)
160122540Smckusick{
1611541Srgrimes	int i;
1621549Srgrimes	struct peer *peers;
1631549Srgrimes
1641549Srgrimes	peers = emalloc_zero(INC_PEER_ALLOC * sizeof(*peers));
1651549Srgrimes
1662442Sdg	for (i = INC_PEER_ALLOC - 1; i >= 0; i--)
1672729Sdfr		LINK_SLIST(peer_free, &peers[i], p_link);
1682729Sdfr
1691541Srgrimes	total_peer_structs += INC_PEER_ALLOC;
17045065Salc	peer_free_count += INC_PEER_ALLOC;
17145065Salc}
1722297Swollman
1731541Srgrimes
1741541Srgrimesstatic struct peer *
1751541Srgrimesfindexistingpeer_name(
1761541Srgrimes	const char *	hostname,
1771541Srgrimes	u_short		hname_fam,
1781541Srgrimes	struct peer *	start_peer,
1791541Srgrimes	int		mode
1801541Srgrimes	)
1811541Srgrimes{
1821541Srgrimes	struct peer *p;
1831541Srgrimes
1841541Srgrimes	if (NULL == start_peer)
1851541Srgrimes		p = peer_list;
1861541Srgrimes	else
1871541Srgrimes		p = start_peer->p_link;
1881541Srgrimes	for (; p != NULL; p = p->p_link)
1891541Srgrimes		if (p->hostname != NULL
1901541Srgrimes		    && (-1 == mode || p->hmode == mode)
1911541Srgrimes		    && (AF_UNSPEC == hname_fam
19235938Sdyson			|| AF_UNSPEC == AF(&p->srcadr)
19335938Sdyson			|| hname_fam == AF(&p->srcadr))
19428400Speter		    && !strcasecmp(p->hostname, hostname))
19529349Speter			break;
19612865Speter	return p;
19712865Speter}
19812865Speter
19912865Speter
20012865Speterstatic
20112865Speterstruct peer *
20212865Speterfindexistingpeer_addr(
20312865Speter	sockaddr_u *	addr,
20412865Speter	struct peer *	start_peer,
20512865Speter	int		mode,
20612865Speter	u_char		cast_flags
20725582Speter	)
20825582Speter{
20925582Speter	struct peer *peer;
21025582Speter
21114220Speter	DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x)\n",
21214220Speter		sptoa(addr),
21329349Speter		(start_peer)
21424452Speter		    ? sptoa(&start_peer->srcadr)
21524440Speter		    : "NULL",
21635938Sdyson		mode, (u_int)cast_flags));
21735938Sdyson
21835938Sdyson	/*
21935938Sdyson	 * start_peer is included so we can locate instances of the
22035938Sdyson	 * same peer through different interfaces in the hash table.
22135938Sdyson	 * Without MDF_BCLNT, a match requires the same mode and remote
22235938Sdyson	 * address.  MDF_BCLNT associations start out as MODE_CLIENT
22335938Sdyson	 * if broadcastdelay is not specified, and switch to
224122540Smckusick	 * MODE_BCLIENT after estimating the one-way delay.  Duplicate
22551138Salfred	 * associations are expanded in definition to match any other
22651138Salfred	 * MDF_BCLNT with the same srcadr (remote, unicast address).
22725537Sdfr	 */
22825537Sdfr	if (NULL == start_peer)
22925537Sdfr		peer = peer_hash[NTP_HASH_ADDR(addr)];
23025537Sdfr	else
23125537Sdfr		peer = start_peer->adr_link;
23225537Sdfr
23325537Sdfr	while (peer != NULL) {
23425537Sdfr		DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr),
23525537Sdfr			sptoa(&peer->srcadr), mode, peer->hmode,
23625537Sdfr			(u_int)cast_flags, (u_int)peer->cast_flags));
23728400Speter 		if ((-1 == mode || peer->hmode == mode ||
23856115Speter		     ((MDF_BCLNT & peer->cast_flags) &&
23956115Speter		      (MDF_BCLNT & cast_flags))) &&
24036034Speter		    ADDR_PORT_EQ(addr, &peer->srcadr)) {
24126671Sdyson			DPRINTF(3, ("found.\n"));
24226671Sdyson			break;
24326671Sdyson		}
24426671Sdyson		DPRINTF(3, ("\n"));
24526671Sdyson		peer = peer->adr_link;
24626671Sdyson	}
24726671Sdyson
24826671Sdyson	return peer;
24969514Sjake}
25069514Sjake
25126671Sdyson
25226671Sdyson/*
25329391Sphk * findexistingpeer - search by address and return a pointer to a peer.
25434925Sdufault */
25534925Sdufaultstruct peer *
25634925Sdufaultfindexistingpeer(
25734925Sdufault	sockaddr_u *	addr,
25834925Sdufault	const char *	hostname,
25934925Sdufault	struct peer *	start_peer,
26034925Sdufault	int		mode,
26134925Sdufault	u_char		cast_flags
26235938Sdyson	)
26399856Salfred{
26441089Speter	if (hostname != NULL)
26546155Sphk		return findexistingpeer_name(hostname, AF(addr),
26651791Smarcel					     start_peer, mode);
26751791Smarcel	else
268105950Speter		return findexistingpeer_addr(addr, start_peer, mode,
26951791Smarcel					     cast_flags);
270105950Speter}
271112895Sjeff
272112895Sjeff
27356271Srwatson/*
27456271Srwatson * findpeer - find and return a peer match for a received datagram in
27556271Srwatson *	      the peer_hash table.
27656271Srwatson */
27756271Srwatsonstruct peer *
27856271Srwatsonfindpeer(
27956271Srwatson	struct recvbuf *rbufp,
28056271Srwatson	int		pkt_mode,
28154803Srwatson	int *		action
28254803Srwatson	)
28354803Srwatson{
28454803Srwatson	struct peer *	p;
28555943Sjasone	sockaddr_u *	srcadr;
28656115Speter	u_int		hash;
28756115Speter	struct pkt *	pkt;
28859288Sjlemon	l_fp		pkt_org;
28959288Sjlemon
29075039Srwatson	findpeer_calls++;
29175039Srwatson	srcadr = &rbufp->recv_srcadr;
29275039Srwatson	hash = NTP_HASH_ADDR(srcadr);
29375427Srwatson	for (p = peer_hash[hash]; p != NULL; p = p->adr_link) {
29483652Speter		if (ADDR_PORT_EQ(srcadr, &p->srcadr)) {
29583796Srwatson
29685891Sphk			/*
29790889Sjulian			 * if the association matching rules determine
29890889Sjulian			 * that this is not a valid combination, then
299103972Sarchie			 * look for the next valid peer association.
300103972Sarchie			 */
301103972Sarchie			*action = MATCH_ASSOC(p->hmode, pkt_mode);
302100897Srwatson
303100897Srwatson			/*
304100897Srwatson			 * A response to our manycastclient solicitation
305100897Srwatson			 * might be misassociated with an ephemeral peer
306100897Srwatson			 * already spun for the server.  If the packet's
307100897Srwatson			 * org timestamp doesn't match the peer's, check
30894936Smux			 * if it matches the ACST prototype peer's.  If
30996084Smux			 * so it is a redundant solicitation response,
31097372Smarcel			 * return AM_ERR to discard it.  [Bug 1762]
31199856Salfred			 */
312101426Srwatson			if (MODE_SERVER == pkt_mode &&
313122540Smckusick			    AM_PROCPKT == *action) {
314122540Smckusick				pkt = &rbufp->recv_pkt;
315122540Smckusick				NTOHL_FP(&pkt->org, &pkt_org);
316122540Smckusick				if (!L_ISEQU(&p->aorg, &pkt_org) &&
317103575Salfred				    findmanycastpeer(rbufp))
318103575Salfred					*action = AM_ERR;
319103575Salfred			}
320103575Salfred
321103575Salfred			/*
322103575Salfred			 * if an error was returned, exit back right
323103575Salfred			 * here.
324103575Salfred			 */
325103575Salfred			if (*action == AM_ERR)
326105692Srwatson				return NULL;
327105692Srwatson
328105692Srwatson			/*
329104731Srwatson			 * if a match is found, we stop our search.
330104731Srwatson			 */
331104731Srwatson			if (*action != AM_NOMATCH)
332106467Srwatson				break;
333105950Speter		}
334105950Speter	}
335106978Sdeischen
336106978Sdeischen	/*
337106978Sdeischen	 * If no matching association is found
338107914Sdillon	 */
339108406Srwatson	if (NULL == p) {
340108406Srwatson		*action = MATCH_ASSOC(NO_PEER, pkt_mode);
341108406Srwatson	} else if (p->dstadr != rbufp->dstadr) {
342108406Srwatson		set_peerdstadr(p, rbufp->dstadr);
343112895Sjeff		if (p->dstadr == rbufp->dstadr) {
344112902Sjeff			DPRINTF(1, ("Changed %s local address to match response\n",
345112902Sjeff				    stoa(&p->srcadr)));
346112902Sjeff			return findpeer(rbufp, pkt_mode, action);
347112902Sjeff		}
348112909Sjeff	}
349112909Sjeff	return p;
350113276Smike}
351115800Srwatson
352115800Srwatson/*
353115800Srwatson * findpeerbyassoc - find and return a peer using his association ID
354123253Smarcel */
355125369Sdeischenstruct peer *
356127484Smtmfindpeerbyassoc(
357127484Smtm	associd_t assoc
358127484Smtm	)
359{
360	struct peer *p;
361	u_int hash;
362
363	assocpeer_calls++;
364	hash = assoc & NTP_HASH_MASK;
365	for (p = assoc_hash[hash]; p != NULL; p = p->aid_link)
366		if (assoc == p->associd)
367			break;
368	return p;
369}
370
371
372/*
373 * clear_all - flush all time values for all associations
374 */
375void
376clear_all(void)
377{
378	struct peer *p;
379
380	/*
381	 * This routine is called when the clock is stepped, and so all
382	 * previously saved time values are untrusted.
383	 */
384	for (p = peer_list; p != NULL; p = p->p_link)
385		if (!(MDF_TXONLY_MASK & p->cast_flags))
386			peer_clear(p, "STEP");
387
388	DPRINTF(1, ("clear_all: at %lu\n", current_time));
389}
390
391
392/*
393 * score_all() - determine if an association can be demobilized
394 */
395int
396score_all(
397	struct peer *peer	/* peer structure pointer */
398	)
399{
400	struct peer *speer;
401	int	temp, tamp;
402	int	x;
403
404	/*
405	 * This routine finds the minimum score for all preemptible
406	 * associations and returns > 0 if the association can be
407	 * demobilized.
408	 */
409	tamp = score(peer);
410	temp = 100;
411	for (speer = peer_list; speer != NULL; speer = speer->p_link)
412		if (speer->flags & FLAG_PREEMPT) {
413			x = score(speer);
414			if (x < temp)
415				temp = x;
416		}
417	DPRINTF(1, ("score_all: at %lu score %d min %d\n",
418		    current_time, tamp, temp));
419
420	if (tamp != temp)
421		temp = 0;
422
423	return temp;
424}
425
426
427/*
428 * score() - calculate preemption score
429 */
430static int
431score(
432	struct peer *peer	/* peer structure pointer */
433	)
434{
435	int	temp;
436
437	/*
438	 * This routine calculates the premption score from the peer
439	 * error bits and status. Increasing values are more cherished.
440	 */
441	temp = 0;
442	if (!(peer->flash & TEST10))
443		temp++;			/* 1 good synch and stratum */
444	if (!(peer->flash & TEST13))
445		temp++;			/* 2 reachable */
446	if (!(peer->flash & TEST12))
447		temp++;			/* 3 no loop */
448	if (!(peer->flash & TEST11))
449		temp++;			/* 4 good distance */
450	if (peer->status >= CTL_PST_SEL_SELCAND)
451		temp++;			/* 5 in the hunt */
452	if (peer->status != CTL_PST_SEL_EXCESS)
453		temp++;			/* 6 not spare tire */
454	return (temp);			/* selection status */
455}
456
457
458/*
459 * free_peer - internal routine to free memory referred to by a struct
460 *	       peer and return it to the peer free list.  If unlink is
461 *	       nonzero, unlink from the various lists.
462 */
463static void
464free_peer(
465	struct peer *	p,
466	int		unlink_peer
467	)
468{
469	struct peer *	unlinked;
470	int		hash;
471
472	if (unlink_peer) {
473		hash = NTP_HASH_ADDR(&p->srcadr);
474		peer_hash_count[hash]--;
475
476		UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link,
477			     struct peer);
478		if (NULL == unlinked) {
479			peer_hash_count[hash]++;
480			msyslog(LOG_ERR, "peer %s not in address table!",
481				stoa(&p->srcadr));
482		}
483
484		/*
485		 * Remove him from the association hash as well.
486		 */
487		hash = p->associd & NTP_HASH_MASK;
488		assoc_hash_count[hash]--;
489
490		UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link,
491			     struct peer);
492		if (NULL == unlinked) {
493			assoc_hash_count[hash]++;
494			msyslog(LOG_ERR,
495				"peer %s not in association ID table!",
496				stoa(&p->srcadr));
497		}
498
499		/* Remove him from the overall list. */
500		UNLINK_SLIST(unlinked, peer_list, p, p_link,
501			     struct peer);
502		if (NULL == unlinked)
503			msyslog(LOG_ERR, "%s not in peer list!",
504				stoa(&p->srcadr));
505	}
506
507	if (p->hostname != NULL)
508		free(p->hostname);
509
510	if (p->ident != NULL)
511		free(p->ident);
512
513	if (p->addrs != NULL)
514		free(p->addrs);		/* from copy_addrinfo_list() */
515
516	/* Add his corporeal form to peer free list */
517	ZERO(*p);
518	LINK_SLIST(peer_free, p, p_link);
519	peer_free_count++;
520}
521
522
523/*
524 * unpeer - remove peer structure from hash table and free structure
525 */
526void
527unpeer(
528	struct peer *peer
529	)
530{
531	mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd);
532	restrict_source(&peer->srcadr, 1, 0);
533	set_peerdstadr(peer, NULL);
534	peer_demobilizations++;
535	peer_associations--;
536	if (FLAG_PREEMPT & peer->flags)
537		peer_preempt--;
538#ifdef REFCLOCK
539	/*
540	 * If this peer is actually a clock, shut it down first
541	 */
542	if (FLAG_REFCLOCK & peer->flags)
543		refclock_unpeer(peer);
544#endif
545
546	free_peer(peer, TRUE);
547}
548
549
550/*
551 * peer_config - configure a new association
552 */
553struct peer *
554peer_config(
555	sockaddr_u *	srcadr,
556	const char *	hostname,
557	endpt *		dstadr,
558	u_char		hmode,
559	u_char		version,
560	u_char		minpoll,
561	u_char		maxpoll,
562	u_int		flags,
563	u_int32		ttl,
564	keyid_t		key,
565	const char *	ident		/* autokey group */
566	)
567{
568	u_char cast_flags;
569
570	/*
571	 * We do a dirty little jig to figure the cast flags. This is
572	 * probably not the best place to do this, at least until the
573	 * configure code is rebuilt. Note only one flag can be set.
574	 */
575	switch (hmode) {
576	case MODE_BROADCAST:
577		if (IS_MCAST(srcadr))
578			cast_flags = MDF_MCAST;
579		else
580			cast_flags = MDF_BCAST;
581		break;
582
583	case MODE_CLIENT:
584		if (hostname != NULL && SOCK_UNSPEC(srcadr))
585			cast_flags = MDF_POOL;
586		else if (IS_MCAST(srcadr))
587			cast_flags = MDF_ACAST;
588		else
589			cast_flags = MDF_UCAST;
590		break;
591
592	default:
593		cast_flags = MDF_UCAST;
594	}
595
596	/*
597	 * Mobilize the association and initialize its variables. If
598	 * emulating ntpdate, force iburst.  For pool and manycastclient
599	 * strip FLAG_PREEMPT as the prototype associations are not
600	 * themselves preemptible, though the resulting associations
601	 * are.
602	 */
603	flags |= FLAG_CONFIG;
604	if (mode_ntpdate)
605		flags |= FLAG_IBURST;
606	if ((MDF_ACAST | MDF_POOL) & cast_flags)
607		flags &= ~FLAG_PREEMPT;
608	return newpeer(srcadr, hostname, dstadr, hmode, version,
609	    minpoll, maxpoll, flags, cast_flags, ttl, key, ident);
610}
611
612/*
613 * setup peer dstadr field keeping it in sync with the interface
614 * structures
615 */
616void
617set_peerdstadr(
618	struct peer *	p,
619	endpt *		dstadr
620	)
621{
622	struct peer *	unlinked;
623
624	if (p->dstadr == dstadr)
625		return;
626
627	/*
628	 * Don't accept updates to a separate multicast receive-only
629	 * endpt while a BCLNT peer is running its unicast protocol.
630	 */
631	if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
632	    (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
633		return;
634	}
635	if (p->dstadr != NULL) {
636		p->dstadr->peercnt--;
637		UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
638			     struct peer);
639		msyslog(LOG_INFO, "%s local addr %s -> %s",
640			stoa(&p->srcadr), latoa(p->dstadr),
641			latoa(dstadr));
642	}
643	p->dstadr = dstadr;
644	if (dstadr != NULL) {
645		LINK_SLIST(dstadr->peers, p, ilink);
646		dstadr->peercnt++;
647	}
648}
649
650/*
651 * attempt to re-rebind interface if necessary
652 */
653static void
654peer_refresh_interface(
655	struct peer *p
656	)
657{
658	endpt *	niface;
659	endpt *	piface;
660
661	niface = select_peerinterface(p, &p->srcadr, NULL);
662
663	DPRINTF(4, (
664	    "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %u key %08x: new interface: ",
665	    p->dstadr == NULL ? "<null>" :
666	    stoa(&p->dstadr->sin), stoa(&p->srcadr), p->hmode,
667	    p->version, p->minpoll, p->maxpoll, p->flags, p->cast_flags,
668	    p->ttl, p->keyid));
669	if (niface != NULL) {
670		DPRINTF(4, (
671		    "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s",
672		    niface->fd,  niface->bfd, niface->name,
673		    niface->flags, niface->ifindex,
674		    stoa(&niface->sin)));
675		if (niface->flags & INT_BROADCAST)
676			DPRINTF(4, (", bcast=%s",
677				stoa(&niface->bcast)));
678		DPRINTF(4, (", mask=%s\n", stoa(&niface->mask)));
679	} else {
680		DPRINTF(4, ("<NONE>\n"));
681	}
682
683	piface = p->dstadr;
684	set_peerdstadr(p, niface);
685	if (p->dstadr != NULL) {
686		/*
687		 * clear crypto if we change the local address
688		 */
689		if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags)
690		    && MODE_BROADCAST != p->pmode)
691			peer_clear(p, "XFAC");
692
693		/*
694	 	 * Broadcast needs the socket enabled for broadcast
695	 	 */
696		if (MDF_BCAST & p->cast_flags)
697			enable_broadcast(p->dstadr, &p->srcadr);
698
699		/*
700	 	 * Multicast needs the socket interface enabled for
701		 * multicast
702	 	 */
703		if (MDF_MCAST & p->cast_flags)
704			enable_multicast_if(p->dstadr, &p->srcadr);
705	}
706}
707
708
709/*
710 * refresh_all_peerinterfaces - see that all interface bindings are up
711 * to date
712 */
713void
714refresh_all_peerinterfaces(void)
715{
716	struct peer *p;
717
718	/*
719	 * this is called when the interface list has changed
720	 * give all peers a chance to find a better interface
721	 * but only if either they don't have an address already
722	 * or if the one they have hasn't worked for a while.
723	 */
724	for (p = peer_list; p != NULL; p = p->p_link) {
725		if (!(p->dstadr && (p->reach & 0x3)))	// Bug 2849 XOR 2043
726			peer_refresh_interface(p);
727	}
728}
729
730
731/*
732 * newpeer - initialize a new peer association
733 */
734struct peer *
735newpeer(
736	sockaddr_u *	srcadr,
737	const char *	hostname,
738	endpt *		dstadr,
739	u_char		hmode,
740	u_char		version,
741	u_char		minpoll,
742	u_char		maxpoll,
743	u_int		flags,
744	u_char		cast_flags,
745	u_int32		ttl,
746	keyid_t		key,
747	const char *	ident
748	)
749{
750	struct peer *	peer;
751	u_int		hash;
752
753	DEBUG_REQUIRE(srcadr);
754
755#ifdef AUTOKEY
756	/*
757	 * If Autokey is requested but not configured, complain loudly.
758	 */
759	if (!crypto_flags) {
760		if (key > NTP_MAXKEY) {
761			return (NULL);
762
763		} else if (flags & FLAG_SKEY) {
764			msyslog(LOG_ERR, "Autokey not configured");
765			return (NULL);
766		}
767	}
768#endif	/* AUTOKEY */
769
770	/*
771	 * For now only pool associations have a hostname.
772	 */
773	INSIST(NULL == hostname || (MDF_POOL & cast_flags));
774
775	/*
776	 * First search from the beginning for an association with given
777	 * remote address and mode. If an interface is given, search
778	 * from there to find the association which matches that
779	 * destination. If the given interface is "any", track down the
780	 * actual interface, because that's what gets put into the peer
781	 * structure.
782	 */
783	if (dstadr != NULL) {
784		peer = findexistingpeer(srcadr, hostname, NULL, hmode,
785					cast_flags);
786		while (peer != NULL) {
787			if (peer->dstadr == dstadr ||
788			    ((MDF_BCLNT & cast_flags) &&
789			     (MDF_BCLNT & peer->cast_flags)))
790				break;
791
792			if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
793			    peer->dstadr == findinterface(srcadr))
794				break;
795
796			peer = findexistingpeer(srcadr, hostname, peer,
797						hmode, cast_flags);
798		}
799	} else {
800		/* no endpt address given */
801		peer = findexistingpeer(srcadr, hostname, NULL, hmode,
802					cast_flags);
803	}
804
805	/*
806	 * If a peer is found, this would be a duplicate and we don't
807	 * allow that. This avoids duplicate ephemeral (broadcast/
808	 * multicast) and preemptible (manycast and pool) client
809	 * associations.
810	 */
811	if (peer != NULL) {
812		DPRINTF(2, ("newpeer(%s) found existing association\n",
813			(hostname)
814			    ? hostname
815			    : stoa(srcadr)));
816		return NULL;
817	}
818
819	/*
820	 * Allocate a new peer structure. Some dirt here, since some of
821	 * the initialization requires knowlege of our system state.
822	 */
823	if (peer_free_count == 0)
824		getmorepeermem();
825	UNLINK_HEAD_SLIST(peer, peer_free, p_link);
826	INSIST(peer != NULL);
827	peer_free_count--;
828	peer_associations++;
829	if (FLAG_PREEMPT & flags)
830		peer_preempt++;
831
832	/*
833	 * Assign an association ID and increment the system variable.
834	 */
835	peer->associd = current_association_ID;
836	if (++current_association_ID == 0)
837		++current_association_ID;
838
839	peer->srcadr = *srcadr;
840	if (hostname != NULL)
841		peer->hostname = estrdup(hostname);
842	peer->hmode = hmode;
843	peer->version = version;
844	peer->flags = flags;
845	peer->cast_flags = cast_flags;
846	set_peerdstadr(peer,
847		       select_peerinterface(peer, srcadr, dstadr));
848
849	/*
850	 * It is an error to set minpoll less than NTP_MINPOLL or to
851	 * set maxpoll greater than NTP_MAXPOLL. However, minpoll is
852	 * clamped not greater than NTP_MAXPOLL and maxpoll is clamped
853	 * not less than NTP_MINPOLL without complaint. Finally,
854	 * minpoll is clamped not greater than maxpoll.
855	 */
856	if (minpoll == 0)
857		peer->minpoll = NTP_MINDPOLL;
858	else
859		peer->minpoll = min(minpoll, NTP_MAXPOLL);
860	if (maxpoll == 0)
861		peer->maxpoll = NTP_MAXDPOLL;
862	else
863		peer->maxpoll = max(maxpoll, NTP_MINPOLL);
864	if (peer->minpoll > peer->maxpoll)
865		peer->minpoll = peer->maxpoll;
866
867	if (peer->dstadr != NULL)
868		DPRINTF(3, ("newpeer(%s): using fd %d and our addr %s\n",
869			stoa(srcadr), peer->dstadr->fd,
870			stoa(&peer->dstadr->sin)));
871	else
872		DPRINTF(3, ("newpeer(%s): local interface currently not bound\n",
873			stoa(srcadr)));
874
875	/*
876	 * Broadcast needs the socket enabled for broadcast
877	 */
878	if ((MDF_BCAST & cast_flags) && peer->dstadr != NULL)
879		enable_broadcast(peer->dstadr, srcadr);
880
881	/*
882	 * Multicast needs the socket interface enabled for multicast
883	 */
884	if ((MDF_MCAST & cast_flags) && peer->dstadr != NULL)
885		enable_multicast_if(peer->dstadr, srcadr);
886
887#ifdef AUTOKEY
888	if (key > NTP_MAXKEY)
889		peer->flags |= FLAG_SKEY;
890#endif	/* AUTOKEY */
891	peer->ttl = ttl;
892	peer->keyid = key;
893	if (ident != NULL)
894		peer->ident = estrdup(ident);
895	peer->precision = sys_precision;
896	peer->hpoll = peer->minpoll;
897	if (cast_flags & MDF_ACAST)
898		peer_clear(peer, "ACST");
899	else if (cast_flags & MDF_POOL)
900		peer_clear(peer, "POOL");
901	else if (cast_flags & MDF_MCAST)
902		peer_clear(peer, "MCST");
903	else if (cast_flags & MDF_BCAST)
904		peer_clear(peer, "BCST");
905	else
906		peer_clear(peer, "INIT");
907	if (mode_ntpdate)
908		peer_ntpdate++;
909
910	/*
911	 * Note time on statistics timers.
912	 */
913	peer->timereset = current_time;
914	peer->timereachable = current_time;
915	peer->timereceived = current_time;
916
917	if (ISREFCLOCKADR(&peer->srcadr)) {
918#ifdef REFCLOCK
919		/*
920		 * We let the reference clock support do clock
921		 * dependent initialization.  This includes setting
922		 * the peer timer, since the clock may have requirements
923		 * for this.
924		 */
925		if (maxpoll == 0)
926			peer->maxpoll = peer->minpoll;
927		if (!refclock_newpeer(peer)) {
928			/*
929			 * Dump it, something screwed up
930			 */
931			set_peerdstadr(peer, NULL);
932			free_peer(peer, 0);
933			return NULL;
934		}
935#else /* REFCLOCK */
936		msyslog(LOG_ERR, "refclock %s isn't supported. ntpd was compiled without refclock support.",
937			stoa(&peer->srcadr));
938		set_peerdstadr(peer, NULL);
939		free_peer(peer, 0);
940		return NULL;
941#endif /* REFCLOCK */
942	}
943
944	/*
945	 * Put the new peer in the hash tables.
946	 */
947	hash = NTP_HASH_ADDR(&peer->srcadr);
948	LINK_SLIST(peer_hash[hash], peer, adr_link);
949	peer_hash_count[hash]++;
950	hash = peer->associd & NTP_HASH_MASK;
951	LINK_SLIST(assoc_hash[hash], peer, aid_link);
952	assoc_hash_count[hash]++;
953	LINK_SLIST(peer_list, peer, p_link);
954
955	restrict_source(&peer->srcadr, 0, 0);
956	mprintf_event(PEVNT_MOBIL, peer, "assoc %d", peer->associd);
957	DPRINTF(1, ("newpeer: %s->%s mode %u vers %u poll %u %u flags 0x%x 0x%x ttl %u key %08x\n",
958	    latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode,
959	    peer->version, peer->minpoll, peer->maxpoll, peer->flags,
960	    peer->cast_flags, peer->ttl, peer->keyid));
961	return peer;
962}
963
964
965/*
966 * peer_clr_stats - clear peer module statistics counters
967 */
968void
969peer_clr_stats(void)
970{
971	findpeer_calls = 0;
972	assocpeer_calls = 0;
973	peer_allocations = 0;
974	peer_demobilizations = 0;
975	peer_timereset = current_time;
976}
977
978
979/*
980 * peer_reset - reset statistics counters
981 */
982void
983peer_reset(
984	struct peer *peer
985	)
986{
987	if (peer == NULL)
988		return;
989
990	peer->timereset = current_time;
991	peer->sent = 0;
992	peer->received = 0;
993	peer->processed = 0;
994	peer->badauth = 0;
995	peer->bogusorg = 0;
996	peer->oldpkt = 0;
997	peer->seldisptoolarge = 0;
998	peer->selbroken = 0;
999}
1000
1001
1002/*
1003 * peer_all_reset - reset all peer statistics counters
1004 */
1005void
1006peer_all_reset(void)
1007{
1008	struct peer *peer;
1009
1010	for (peer = peer_list; peer != NULL; peer = peer->p_link)
1011		peer_reset(peer);
1012}
1013
1014
1015/*
1016 * findmanycastpeer - find and return a manycastclient or pool
1017 *		      association matching a received response.
1018 */
1019struct peer *
1020findmanycastpeer(
1021	struct recvbuf *rbufp	/* receive buffer pointer */
1022	)
1023{
1024	struct peer *peer;
1025	struct pkt *pkt;
1026	l_fp p_org;
1027
1028 	/*
1029 	 * This routine is called upon arrival of a server-mode response
1030	 * to a manycastclient multicast solicitation, or to a pool
1031	 * server unicast solicitation.  Search the peer list for a
1032	 * manycastclient association where the last transmit timestamp
1033	 * matches the response packet's originate timestamp.  There can
1034	 * be multiple manycastclient associations, or multiple pool
1035	 * solicitation assocations, so this assumes the transmit
1036	 * timestamps are unique for such.
1037	 */
1038	pkt = &rbufp->recv_pkt;
1039	for (peer = peer_list; peer != NULL; peer = peer->p_link)
1040		if (MDF_SOLICIT_MASK & peer->cast_flags) {
1041			NTOHL_FP(&pkt->org, &p_org);
1042			if (L_ISEQU(&p_org, &peer->aorg))
1043				break;
1044		}
1045
1046	return peer;
1047}
1048
1049/* peer_cleanup - clean peer list prior to shutdown */
1050void peer_cleanup(void)
1051{
1052        struct peer *peer;
1053        associd_t assoc;
1054
1055        for (assoc = initial_association_ID; assoc != current_association_ID; assoc++) {
1056            if (assoc != 0U) {
1057                peer = findpeerbyassoc(assoc);
1058                if (peer != NULL)
1059                    unpeer(peer);
1060            }
1061        }
1062        peer = findpeerbyassoc(current_association_ID);
1063        if (peer != NULL)
1064            unpeer(peer);
1065}
1066