xref: /freebsd/contrib/ntp/ntpd/ntp_peer.c (revision 9336e0699bda8a301cd2bfa37106b6ec5e32012e)
1 /*
2  * ntp_peer.c - management of data maintained for peer associations
3  */
4 #ifdef HAVE_CONFIG_H
5 #include <config.h>
6 #endif
7 
8 #include <stdio.h>
9 #include <sys/types.h>
10 
11 #include "ntpd.h"
12 #include "ntp_stdlib.h"
13 #ifdef OPENSSL
14 #include "openssl/rand.h"
15 #endif /* OPENSSL */
16 
17 /*
18  *                  Table of valid association combinations
19  *                  ---------------------------------------
20  *
21  *                             packet->mode
22  * peer->mode      | UNSPEC  ACTIVE PASSIVE  CLIENT  SERVER  BCAST
23  * ----------      | ---------------------------------------------
24  * NO_PEER         |   e       1       e       1       1       1
25  * ACTIVE          |   e       1       1       0       0       0
26  * PASSIVE         |   e       1       e       0       0       0
27  * CLIENT          |   e       0       0       0       1       1
28  * SERVER          |   e       0       0       0       0       0
29  * BCAST	   |   e       0       0       0       0       0
30  * CONTROL	   |   e       0       0       0       0       0
31  * PRIVATE	   |   e       0       0       0       0       0
32  * BCLIENT         |   e       0       0       0       e       1
33  *
34  * One point to note here: a packet in BCAST mode can potentially match
35  * a peer in CLIENT mode, but we that is a special case and we check for
36  * that early in the decision process.  This avoids having to keep track
37  * of what kind of associations are possible etc...  We actually
38  * circumvent that problem by requiring that the first b(m)roadcast
39  * received after the change back to BCLIENT mode sets the clock.
40  */
41 
42 int AM[AM_MODES][AM_MODES] = {
43 /*	{ UNSPEC,   ACTIVE,     PASSIVE,    CLIENT,     SERVER,     BCAST } */
44 
45 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_ERR,     AM_FXMIT,   AM_MANYCAST, AM_NEWBCL},
46 
47 /*A*/	{ AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
48 
49 /*P*/	{ AM_ERR, AM_PROCPKT, AM_ERR,     AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
50 
51 /*C*/	{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT,  AM_POSSBCL},
52 
53 /*S*/	{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
54 
55 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
56 
57 /*CNTL*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
58 
59 /*PRIV*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
60 
61 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_ERR,      AM_PROCPKT},
62 };
63 
64 #define MATCH_ASSOC(x,y)	AM[(x)][(y)]
65 
66 /*
67  * These routines manage the allocation of memory to peer structures
68  * and the maintenance of the peer hash table. The two main entry
69  * points are findpeer(), which looks for matching peer sturctures in
70  * the peer list, newpeer(), which allocates a new peer structure and
71  * adds it to the list, and unpeer(), which demobilizes the association
72  * and deallocates the structure.
73  */
74 /*
75  * Peer hash tables
76  */
77 struct peer *peer_hash[HASH_SIZE];	/* peer hash table */
78 int peer_hash_count[HASH_SIZE];		/* peers in each bucket */
79 struct peer *assoc_hash[HASH_SIZE];	/* association ID hash table */
80 int assoc_hash_count[HASH_SIZE];	/* peers in each bucket */
81 static struct peer *peer_free;		/* peer structures free list */
82 int peer_free_count;			/* count of free structures */
83 
84 /*
85  * Association ID.  We initialize this value randomly, then assign a new
86  * value every time the peer structure is incremented.
87  */
88 static associd_t current_association_ID; /* association ID */
89 
90 /*
91  * Memory allocation watermarks.
92  */
93 #define	INIT_PEER_ALLOC		15	/* initialize for 15 peers */
94 #define	INC_PEER_ALLOC		5	/* when run out, add 5 more */
95 
96 /*
97  * Miscellaneous statistic counters which may be queried.
98  */
99 u_long peer_timereset;			/* time stat counters zeroed */
100 u_long findpeer_calls;			/* calls to findpeer */
101 u_long assocpeer_calls;			/* calls to findpeerbyassoc */
102 u_long peer_allocations;		/* allocations from free list */
103 u_long peer_demobilizations;		/* structs freed to free list */
104 int total_peer_structs;			/* peer structs */
105 int peer_associations;			/* active associations */
106 static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
107 
108 static	void	getmorepeermem	P((void));
109 
110 /*
111  * init_peer - initialize peer data structures and counters
112  *
113  * N.B. We use the random number routine in here. It had better be
114  * initialized prior to getting here.
115  */
116 void
117 init_peer(void)
118 {
119 	register int i;
120 
121 	/*
122 	 * Clear hash table and counters.
123 	 */
124 	for (i = 0; i < HASH_SIZE; i++) {
125 		peer_hash[i] = 0;
126 		peer_hash_count[i] = 0;
127 		assoc_hash[i] = 0;
128 		assoc_hash_count[i] = 0;
129 	}
130 
131 	/*
132 	 * Clear stat counters
133 	 */
134 	findpeer_calls = peer_allocations = 0;
135 	assocpeer_calls = peer_demobilizations = 0;
136 
137 	/*
138 	 * Initialize peer memory.
139 	 */
140 	peer_free = 0;
141 	for (i = 0; i < INIT_PEER_ALLOC; i++) {
142 		init_peer_alloc[i].next = peer_free;
143 		peer_free = &init_peer_alloc[i];
144 	}
145 	total_peer_structs = INIT_PEER_ALLOC;
146 	peer_free_count = INIT_PEER_ALLOC;
147 
148 	/*
149 	 * Initialize our first association ID
150 	 */
151 	current_association_ID = (associd_t)ranp2(16);
152 	if (current_association_ID == 0)
153 	    current_association_ID = 1;
154 }
155 
156 
157 /*
158  * getmorepeermem - add more peer structures to the free list
159  */
160 static void
161 getmorepeermem(void)
162 {
163 	register int i;
164 	register struct peer *peer;
165 
166 	peer = (struct peer *)emalloc(INC_PEER_ALLOC *
167 	    sizeof(struct peer));
168 	for (i = 0; i < INC_PEER_ALLOC; i++) {
169 		peer->next = peer_free;
170 		peer_free = peer;
171 		peer++;
172 	}
173 
174 	total_peer_structs += INC_PEER_ALLOC;
175 	peer_free_count += INC_PEER_ALLOC;
176 }
177 
178 
179 /*
180  * findexistingpeer - return a pointer to a peer in the hash table
181  */
182 struct peer *
183 findexistingpeer(
184 	struct sockaddr_storage *addr,
185 	struct peer *start_peer,
186 	int mode
187 	)
188 {
189 	register struct peer *peer;
190 
191 	/*
192 	 * start_peer is included so we can locate instances of the
193 	 * same peer through different interfaces in the hash table.
194 	 */
195 	if (start_peer == 0)
196 		peer = peer_hash[HASH_ADDR(addr)];
197 	else
198 		peer = start_peer->next;
199 
200 	while (peer != 0) {
201 		if (SOCKCMP(addr, &peer->srcadr)
202 		    && NSRCPORT(addr) == NSRCPORT(&peer->srcadr)) {
203 			if (mode == -1)
204 				return (peer);
205 			else if (peer->hmode == mode)
206 				break;
207 		}
208 		peer = peer->next;
209 	}
210 	return (peer);
211 }
212 
213 
214 /*
215  * findpeer - find and return a peer in the hash table.
216  */
217 struct peer *
218 findpeer(
219 	struct sockaddr_storage *srcadr,
220 	struct interface *dstadr,
221 	int fd,
222 	int pkt_mode,
223 	int *action
224 	)
225 {
226 	register struct peer *peer;
227 	int hash;
228 
229 	findpeer_calls++;
230 	hash = HASH_ADDR(srcadr);
231 	for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) {
232 		if (SOCKCMP(srcadr, &peer->srcadr)
233 		    && NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) {
234 
235 			/*
236 			 * if the association matching rules determine
237 			 * that this is not a valid combination, then
238 			 * look for the next valid peer association.
239 			 */
240 			*action = MATCH_ASSOC(peer->hmode, pkt_mode);
241 
242 			/*
243 			 * Sigh!  Check if BCLIENT peer in client
244 			 * server mode, else return error.
245 			 */
246 			if ((*action == AM_POSSBCL) && !(peer->flags &
247 			    FLAG_MCAST))
248 				*action = AM_ERR;
249 
250 			/*
251 			 * if an error was returned, exit back right
252 			 * here.
253 			 */
254 			if (*action == AM_ERR)
255 				return ((struct peer *)0);
256 
257 			/*
258 			 * if a match is found, we stop our search.
259 			 */
260 			if (*action != AM_NOMATCH)
261 				break;
262 		}
263 	}
264 
265 	/*
266 	 * If no matching association is found
267 	 */
268 	if (peer == 0) {
269 		*action = MATCH_ASSOC(NO_PEER, pkt_mode);
270 		return ((struct peer *)0);
271 	}
272 	peer->dstadr = dstadr;
273 	return (peer);
274 }
275 
276 /*
277  * findpeerbyassocid - find and return a peer using his association ID
278  */
279 struct peer *
280 findpeerbyassoc(
281 	u_int assoc
282 	)
283 {
284 	register struct peer *peer;
285 	int hash;
286 
287 	assocpeer_calls++;
288 
289 	hash = assoc & HASH_MASK;
290 	for (peer = assoc_hash[hash]; peer != 0; peer =
291 	    peer->ass_next) {
292 		if (assoc == peer->associd)
293 		    return (peer);
294 	}
295 	return (NULL);
296 }
297 
298 
299 /*
300  * clear_all - flush all time values for all associations
301  */
302 void
303 clear_all(void)
304 {
305 	struct peer *peer, *next_peer;
306 	int n;
307 
308 	/*
309 	 * This routine is called when the clock is stepped, and so all
310 	 * previously saved time values are untrusted.
311 	 */
312 	for (n = 0; n < HASH_SIZE; n++) {
313 		for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
314 			next_peer = peer->next;
315 			if (peer->flags & FLAG_CONFIG) {
316 				if (!(peer->cast_flags & (MDF_ACAST |
317 				     MDF_MCAST | MDF_BCAST)))
318 					peer_clear(peer, "STEP");
319 			} else {
320 				unpeer(peer);
321 			}
322 		}
323 	}
324 #ifdef DEBUG
325 	if (debug)
326 		printf("clear_all: at %lu\n", current_time);
327 #endif
328 }
329 
330 
331 /*
332  * unpeer - remove peer structure from hash table and free structure
333  */
334 void
335 unpeer(
336 	struct peer *peer_to_remove
337 	)
338 {
339 	int hash;
340 #ifdef OPENSSL
341 	char	statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
342 
343 	if (peer_to_remove->flags & FLAG_SKEY) {
344 		sprintf(statstr, "unpeer %d flash %x reach %03o flags %04x",
345 		    peer_to_remove->associd, peer_to_remove->flash,
346 		    peer_to_remove->reach, peer_to_remove->flags);
347 		record_crypto_stats(&peer_to_remove->srcadr, statstr);
348 #ifdef DEBUG
349 		if (debug)
350 			printf("peer: %s\n", statstr);
351 #endif
352 	}
353 #endif /* OPENSSL */
354 #ifdef DEBUG
355 	if (debug)
356 		printf("demobilize %u %d\n", peer_to_remove->associd,
357 		    peer_associations);
358 #endif
359 	peer_clear(peer_to_remove, "NULL");
360 	hash = HASH_ADDR(&peer_to_remove->srcadr);
361 	peer_hash_count[hash]--;
362 	peer_demobilizations++;
363 #ifdef REFCLOCK
364 	/*
365 	 * If this peer is actually a clock, shut it down first
366 	 */
367 	if (peer_to_remove->flags & FLAG_REFCLOCK)
368 		refclock_unpeer(peer_to_remove);
369 #endif
370 	peer_to_remove->action = 0;	/* disable timeout actions */
371 	if (peer_hash[hash] == peer_to_remove)
372 		peer_hash[hash] = peer_to_remove->next;
373 	else {
374 		register struct peer *peer;
375 
376 		peer = peer_hash[hash];
377 		while (peer != 0 && peer->next != peer_to_remove)
378 		    peer = peer->next;
379 
380 		if (peer == 0) {
381 			peer_hash_count[hash]++;
382 			msyslog(LOG_ERR, "peer struct for %s not in table!",
383 				stoa(&peer->srcadr));
384 		} else {
385 			peer->next = peer_to_remove->next;
386 		}
387 	}
388 
389 	/*
390 	 * Remove him from the association hash as well.
391 	 */
392 	hash = peer_to_remove->associd & HASH_MASK;
393 	assoc_hash_count[hash]--;
394 	if (assoc_hash[hash] == peer_to_remove)
395 		assoc_hash[hash] = peer_to_remove->ass_next;
396 	else {
397 		register struct peer *peer;
398 
399 		peer = assoc_hash[hash];
400 		while (peer != 0 && peer->ass_next != peer_to_remove)
401 		    peer = peer->ass_next;
402 
403 		if (peer == 0) {
404 			assoc_hash_count[hash]++;
405 			msyslog(LOG_ERR,
406 				"peer struct for %s not in association table!",
407 				stoa(&peer->srcadr));
408 		} else {
409 			peer->ass_next = peer_to_remove->ass_next;
410 		}
411 	}
412 	peer_to_remove->next = peer_free;
413 	peer_free = peer_to_remove;
414 	peer_free_count++;
415 	peer_associations--;
416 }
417 
418 
419 /*
420  * peer_config - configure a new association
421  */
422 struct peer *
423 peer_config(
424 	struct sockaddr_storage *srcadr,
425 	struct interface *dstadr,
426 	int hmode,
427 	int version,
428 	int minpoll,
429 	int maxpoll,
430 	u_int flags,
431 	int ttl,
432 	keyid_t key,
433 	u_char *keystr
434 	)
435 {
436 	register struct peer *peer;
437 	u_char cast_flags;
438 
439 	/*
440 	 * First search from the beginning for an association with given
441 	 * remote address and mode. If an interface is given, search
442 	 * from there to find the association which matches that
443 	 * destination.
444 	 */
445 	peer = findexistingpeer(srcadr, (struct peer *)0, hmode);
446 	if (dstadr != 0) {
447 		while (peer != 0) {
448 			if (peer->dstadr == dstadr)
449 				break;
450 			peer = findexistingpeer(srcadr, peer, hmode);
451 		}
452 	}
453 
454 	/*
455 	 * We do a dirty little jig to figure the cast flags. This is
456 	 * probably not the best place to do this, at least until the
457 	 * configure code is rebuilt. Note only one flag can be set.
458 	 */
459 	switch (hmode) {
460 
461 	case MODE_BROADCAST:
462 		if(srcadr->ss_family == AF_INET) {
463 			if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))
464 				cast_flags = MDF_MCAST;
465 			else
466 				cast_flags = MDF_BCAST;
467 			break;
468 		}
469 		else {
470                         if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
471         	                cast_flags = MDF_MCAST;
472 	        	else
473                         	cast_flags = MDF_BCAST;
474                 	break;
475                 }
476 
477 	case MODE_CLIENT:
478 		if(srcadr->ss_family == AF_INET) {
479 			if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))
480 				cast_flags = MDF_ACAST;
481 			else
482 				cast_flags = MDF_UCAST;
483 			break;
484 		}
485 		else {
486 			if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
487 				cast_flags = MDF_ACAST;
488 			else
489 				cast_flags = MDF_UCAST;
490 			break;
491 		}
492 
493 	default:
494 		cast_flags = MDF_UCAST;
495 	}
496 
497 	/*
498 	 * If the peer is already configured, some dope has a duplicate
499 	 * configureation entry or another dope is wiggling from afar.
500 	 */
501 	if (peer != 0) {
502 		peer->hmode = (u_char)hmode;
503 		peer->version = (u_char) version;
504 		peer->minpoll = (u_char) minpoll;
505 		peer->maxpoll = (u_char) maxpoll;
506 		peer->flags = flags | FLAG_CONFIG |
507 			(peer->flags & FLAG_REFCLOCK);
508 		peer->cast_flags = cast_flags;
509 		peer->ttl = (u_char) ttl;
510 		peer->keyid = key;
511 		peer->precision = sys_precision;
512 		peer_clear(peer, "RMOT");
513 		return (peer);
514 	}
515 
516 	/*
517 	 * Here no match has been found, so presumably this is a new
518 	 * persistent association. Mobilize the thing and initialize its
519 	 * variables. If emulating ntpdate, force iburst.
520 	 */
521 	if (mode_ntpdate)
522 		flags |= FLAG_IBURST;
523 	peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
524 	    flags | FLAG_CONFIG, cast_flags, ttl, key);
525 	return (peer);
526 }
527 
528 
529 /*
530  * newpeer - initialize a new peer association
531  */
532 struct peer *
533 newpeer(
534 	struct sockaddr_storage *srcadr,
535 	struct interface *dstadr,
536 	int hmode,
537 	int version,
538 	int minpoll,
539 	int maxpoll,
540 	u_int flags,
541 	u_char cast_flags,
542 	int ttl,
543 	keyid_t key
544 	)
545 {
546 	register struct peer *peer;
547 	register int i;
548 #ifdef OPENSSL
549 	char	statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
550 #endif /* OPENSSL */
551 
552 	/*
553 	 * Allocate a new peer structure. Some dirt here, since some of
554 	 * the initialization requires knowlege of our system state.
555 	 */
556 	if (peer_free_count == 0)
557 		getmorepeermem();
558 	peer = peer_free;
559 	peer_free = peer->next;
560 	peer_free_count--;
561 	peer_associations++;
562 	memset((char *)peer, 0, sizeof(struct peer));
563 
564 	/*
565 	 * Assign an association ID and increment the system variable.
566 	 */
567 	peer->associd = current_association_ID;
568 	if (++current_association_ID == 0)
569 		++current_association_ID;
570 
571 	/*
572 	 * Initialize the peer structure and dance the interface jig.
573 	 * Reference clocks step the loopback waltz, the others
574 	 * squaredance around the interface list looking for a buddy. If
575 	 * the dance peters out, there is always the wildcard interface.
576 	 * This might happen in some systems and would preclude proper
577 	 * operation with public key cryptography.
578 	 */
579 	if (ISREFCLOCKADR(srcadr))
580 		peer->dstadr = loopback_interface;
581 	else if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
582 		peer->dstadr = findbcastinter(srcadr);
583 		/*
584 		 * If it was a multicast packet, findbcastinter() may not
585 		 * find it, so try a little harder.
586 		 */
587 		if (peer->dstadr == ANY_INTERFACE_CHOOSE(srcadr))
588 			peer->dstadr = findinterface(srcadr);
589 	} else if (dstadr != NULL && dstadr != ANY_INTERFACE_CHOOSE(srcadr))
590 		peer->dstadr = dstadr;
591 	else
592 		peer->dstadr = findinterface(srcadr);
593 	peer->srcadr = *srcadr;
594 	peer->hmode = (u_char)hmode;
595 	peer->version = (u_char)version;
596 	peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);
597 	peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);
598 	peer->flags = flags;
599 	if (key != 0)
600 		peer->flags |= FLAG_AUTHENABLE;
601 	if (key > NTP_MAXKEY)
602 		peer->flags |= FLAG_SKEY;
603 	peer->cast_flags = cast_flags;
604 	peer->ttl = (u_char)ttl;
605 	peer->keyid = key;
606 	peer->precision = sys_precision;
607 	if (cast_flags & MDF_ACAST)
608 		peer_clear(peer, "ACST");
609 	else if (cast_flags & MDF_MCAST)
610 		peer_clear(peer, "MCST");
611 	else if (cast_flags & MDF_BCAST)
612 		peer_clear(peer, "BCST");
613 	else
614 		peer_clear(peer, "INIT");
615 	if (mode_ntpdate)
616 		peer_ntpdate++;
617 
618 	/*
619 	 * Note time on statistics timers.
620 	 */
621 	peer->timereset = current_time;
622 	peer->timereachable = current_time;
623 	peer->timereceived = current_time;
624 #ifdef REFCLOCK
625 	if (ISREFCLOCKADR(&peer->srcadr)) {
626 		/*
627 		 * We let the reference clock support do clock
628 		 * dependent initialization.  This includes setting
629 		 * the peer timer, since the clock may have requirements
630 		 * for this.
631 		 */
632 		if (!refclock_newpeer(peer)) {
633 			/*
634 			 * Dump it, something screwed up
635 			 */
636 			peer->next = peer_free;
637 			peer_free = peer;
638 			peer_free_count++;
639 			return (NULL);
640 		}
641 	}
642 #endif
643 
644 	/*
645 	 * Put the new peer in the hash tables.
646 	 */
647 	i = HASH_ADDR(&peer->srcadr);
648 	peer->next = peer_hash[i];
649 	peer_hash[i] = peer;
650 	peer_hash_count[i]++;
651 	i = peer->associd & HASH_MASK;
652 	peer->ass_next = assoc_hash[i];
653 	assoc_hash[i] = peer;
654 	assoc_hash_count[i]++;
655 #ifdef OPENSSL
656 	if (peer->flags & FLAG_SKEY) {
657 		sprintf(statstr, "newpeer %d", peer->associd);
658 		record_crypto_stats(&peer->srcadr, statstr);
659 #ifdef DEBUG
660 		if (debug)
661 			printf("peer: %s\n", statstr);
662 #endif
663 	}
664 #endif /* OPENSSL */
665 #ifdef DEBUG
666 	if (debug)
667 		printf(
668 		    "newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
669 		    peer->dstadr == NULL ? "null" : stoa(&peer->dstadr->sin),
670 		    stoa(&peer->srcadr),
671 		    peer->hmode, peer->version, peer->minpoll,
672 		    peer->maxpoll, peer->flags, peer->cast_flags,
673 		    peer->ttl, peer->keyid);
674 #endif
675 	return (peer);
676 }
677 
678 
679 /*
680  * peer_unconfig - remove the configuration bit from a peer
681  */
682 int
683 peer_unconfig(
684 	struct sockaddr_storage *srcadr,
685 	struct interface *dstadr,
686 	int mode
687 	)
688 {
689 	register struct peer *peer;
690 	int num_found;
691 
692 	num_found = 0;
693 	peer = findexistingpeer(srcadr, (struct peer *)0, mode);
694 	while (peer != 0) {
695 		if (peer->flags & FLAG_CONFIG
696 		    && (dstadr == 0 || peer->dstadr == dstadr)) {
697 			num_found++;
698 
699 			/*
700 			 * Tricky stuff here. If the peer is polling us
701 			 * in active mode, turn off the configuration
702 			 * bit and make the mode passive. This allows us
703 			 * to avoid dumping a lot of history for peers
704 			 * we might choose to keep track of in passive
705 			 * mode. The protocol will eventually terminate
706 			 * undesirables on its own.
707 			 */
708 			if (peer->hmode == MODE_ACTIVE
709 			    && peer->pmode == MODE_ACTIVE) {
710 				peer->hmode = MODE_PASSIVE;
711 				peer->flags &= ~FLAG_CONFIG;
712 			} else {
713 				unpeer(peer);
714 				peer = 0;
715 			}
716 		}
717 		peer = findexistingpeer(srcadr, peer, mode);
718 	}
719 	return (num_found);
720 }
721 
722 /*
723  * peer_clr_stats - clear peer module stat counters
724  */
725 void
726 peer_clr_stats(void)
727 {
728 	findpeer_calls = 0;
729 	assocpeer_calls = 0;
730 	peer_allocations = 0;
731 	peer_demobilizations = 0;
732 	peer_timereset = current_time;
733 }
734 
735 /*
736  * peer_reset - reset stat counters in a peer structure
737  */
738 void
739 peer_reset(
740 	struct peer *peer
741 	)
742 {
743 	if (peer == 0)
744 	    return;
745 	peer->sent = 0;
746 	peer->received = 0;
747 	peer->processed = 0;
748 	peer->badauth = 0;
749 	peer->bogusorg = 0;
750 	peer->oldpkt = 0;
751 	peer->seldisptoolarge = 0;
752 	peer->selbroken = 0;
753 	peer->rank = 0;
754 	peer->timereset = current_time;
755 }
756 
757 
758 /*
759  * peer_all_reset - reset all peer stat counters
760  */
761 void
762 peer_all_reset(void)
763 {
764 	struct peer *peer;
765 	int hash;
766 
767 	for (hash = 0; hash < HASH_SIZE; hash++)
768 	    for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
769 		peer_reset(peer);
770 }
771 
772 
773 #ifdef OPENSSL
774 /*
775  * expire_all - flush all crypto data and update timestamps.
776  */
777 void
778 expire_all(void)
779 {
780 	struct peer *peer, *next_peer;
781 	int n;
782 
783 	/*
784 	 * This routine is called about once per day from the timer
785 	 * routine and when the client is first synchronized. Search the
786 	 * peer list for all associations and flush only the key list
787 	 * and cookie. If a manycast client association, flush
788 	 * everything. Then, recompute and sign the agreement public
789 	 * value, if present.
790 	 */
791 	if (!crypto_flags)
792 		return;
793 	for (n = 0; n < HASH_SIZE; n++) {
794 		for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
795 			next_peer = peer->next;
796 			if (!(peer->flags & FLAG_SKEY)) {
797 				continue;
798 			} else if (peer->cast_flags & MDF_ACAST) {
799 				peer_clear(peer, "ACST");
800 			} else if (peer->hmode == MODE_ACTIVE ||
801 			    peer->hmode == MODE_PASSIVE) {
802 				key_expire(peer);
803 				peer->crypto &= ~(CRYPTO_FLAG_AUTO |
804 				    CRYPTO_FLAG_AGREE);
805 			}
806 
807 		}
808 	}
809 	RAND_bytes((u_char *)&sys_private, 4);
810 	crypto_update();
811 	resetmanycast();
812 }
813 #endif /* OPENSSL */
814 
815 
816 /*
817  * findmanycastpeer - find and return a manycast peer
818  */
819 struct peer *
820 findmanycastpeer(
821 	struct recvbuf *rbufp
822 	)
823 {
824 	register struct peer *peer;
825 	struct pkt *pkt;
826 	l_fp p_org;
827 	int i;
828 
829  	/*
830  	 * This routine is called upon arrival of a client-mode message
831 	 * from a manycast server. Search the peer list for a manycast
832 	 * client association where the last transmit timestamp matches
833 	 * the originate timestamp. This assumes the transmit timestamps
834 	 * for possibly more than one manycast association are unique.
835 	 */
836 	pkt = &rbufp->recv_pkt;
837 	for (i = 0; i < HASH_SIZE; i++) {
838 		if (peer_hash_count[i] == 0)
839 			continue;
840 
841 		for (peer = peer_hash[i]; peer != 0; peer =
842 		    peer->next) {
843 			if (peer->cast_flags & MDF_ACAST) {
844 				NTOHL_FP(&pkt->org, &p_org);
845 				if (L_ISEQU(&peer->xmt, &p_org))
846 					return (peer);
847 			}
848 		}
849 	}
850 	return (NULL);
851 }
852 
853 
854 /*
855  * resetmanycast - reset all manycast clients
856  */
857 void
858 resetmanycast(void)
859 {
860 	register struct peer *peer;
861 	int i;
862 
863 	/*
864 	 * This routine is called when the number of client associations
865 	 * falls below the minimum. Search the peer list for manycast
866 	 * client associations and reset the ttl and poll interval.
867 	 */
868 	for (i = 0; i < HASH_SIZE; i++) {
869 		if (peer_hash_count[i] == 0)
870 			continue;
871 
872 		for (peer = peer_hash[i]; peer != 0; peer =
873 		    peer->next) {
874 			if (peer->cast_flags & MDF_ACAST) {
875 				peer->ttl = 0;
876 				poll_update(peer, 0);
877 			}
878 		}
879 	}
880 }
881