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