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