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