Obfuscate RCS ID matching so that CVS doesn't expand it.
[netbsd-mini2440.git] / dist / ntp / ntpd / ntp_peer.c
blob1df25186fc83e8ba26fcbc7a21d508ba777e3eb5
1 /* $NetBSD: ntp_peer.c,v 1.5 2007/06/24 16:55:14 kardel Exp $ */
3 /*
4 * ntp_peer.c - management of data maintained for peer associations
5 */
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
10 #include <stdio.h>
11 #include <sys/types.h>
13 #include "ntpd.h"
14 #include "ntp_stdlib.h"
15 #include <ntp_random.h>
16 #ifdef OPENSSL
17 #include "openssl/rand.h"
18 #endif /* OPENSSL */
20 #ifdef SYS_WINNT
21 extern int accept_wildcard_if_for_winnt;
22 #endif
25 * Table of valid association combinations
26 * ---------------------------------------
28 * packet->mode
29 * peer->mode | UNSPEC ACTIVE PASSIVE CLIENT SERVER BCAST
30 * ---------- | ---------------------------------------------
31 * NO_PEER | e 1 0 1 1 1
32 * ACTIVE | e 1 1 0 0 0
33 * PASSIVE | e 1 e 0 0 0
34 * CLIENT | e 0 0 0 1 1
35 * SERVER | e 0 0 0 0 0
36 * BCAST | e 0 0 0 0 0
37 * BCLIENT | e 0 0 0 e 1
39 * One point to note here: a packet in BCAST mode can potentially match
40 * a peer in CLIENT mode, but we that is a special case and we check for
41 * that early in the decision process. This avoids having to keep track
42 * of what kind of associations are possible etc... We actually
43 * circumvent that problem by requiring that the first b(m)roadcast
44 * received after the change back to BCLIENT mode sets the clock.
46 #define AM_MODES 7 /* number of rows and columns */
47 #define NO_PEER 0 /* action when no peer is found */
49 int AM[AM_MODES][AM_MODES] = {
50 /* { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */
52 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT, AM_MANYCAST, AM_NEWBCL},
54 /*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
56 /*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
58 /*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_POSSBCL},
60 /*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
62 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
64 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT},
67 #define MATCH_ASSOC(x,y) AM[(x)][(y)]
70 * These routines manage the allocation of memory to peer structures
71 * and the maintenance of the peer hash table. The two main entry
72 * points are findpeer(), which looks for matching peer sturctures in
73 * the peer list, newpeer(), which allocates a new peer structure and
74 * adds it to the list, and unpeer(), which demobilizes the association
75 * and deallocates the structure.
78 * Peer hash tables
80 struct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */
81 int peer_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
82 struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
83 int assoc_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
84 static struct peer *peer_free; /* peer structures free list */
85 int peer_free_count; /* count of free structures */
88 * Association ID. We initialize this value randomly, then assign a new
89 * value every time the peer structure is incremented.
91 static associd_t current_association_ID; /* association ID */
94 * Memory allocation watermarks.
96 #define INIT_PEER_ALLOC 15 /* initialize for 15 peers */
97 #define INC_PEER_ALLOC 5 /* when run out, add 5 more */
100 * Miscellaneous statistic counters which may be queried.
102 u_long peer_timereset; /* time stat counters zeroed */
103 u_long findpeer_calls; /* calls to findpeer */
104 u_long assocpeer_calls; /* calls to findpeerbyassoc */
105 u_long peer_allocations; /* allocations from free list */
106 u_long peer_demobilizations; /* structs freed to free list */
107 int total_peer_structs; /* peer structs */
108 int peer_associations; /* mobilized associations */
109 int peer_preempt; /* preemptable associations */
110 static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
112 static void getmorepeermem P((void));
113 static struct interface *select_peerinterface P((struct peer *, struct sockaddr_storage *, struct interface *, u_char));
116 * init_peer - initialize peer data structures and counters
118 * N.B. We use the random number routine in here. It had better be
119 * initialized prior to getting here.
121 void
122 init_peer(void)
124 register int i;
127 * Clear hash table and counters.
129 for (i = 0; i < NTP_HASH_SIZE; i++) {
130 peer_hash[i] = 0;
131 peer_hash_count[i] = 0;
132 assoc_hash[i] = 0;
133 assoc_hash_count[i] = 0;
137 * Clear stat counters
139 findpeer_calls = peer_allocations = 0;
140 assocpeer_calls = peer_demobilizations = 0;
143 * Initialize peer memory.
145 peer_free = 0;
146 for (i = 0; i < INIT_PEER_ALLOC; i++) {
147 init_peer_alloc[i].next = peer_free;
148 peer_free = &init_peer_alloc[i];
150 total_peer_structs = INIT_PEER_ALLOC;
151 peer_free_count = INIT_PEER_ALLOC;
154 * Initialize our first association ID
156 while ((current_association_ID = ntp_random() & 0xffff) == 0);
161 * getmorepeermem - add more peer structures to the free list
163 static void
164 getmorepeermem(void)
166 register int i;
167 register struct peer *peer;
169 peer = (struct peer *)emalloc(INC_PEER_ALLOC *
170 sizeof(struct peer));
171 for (i = 0; i < INC_PEER_ALLOC; i++) {
172 peer->next = peer_free;
173 peer_free = peer;
174 peer++;
177 total_peer_structs += INC_PEER_ALLOC;
178 peer_free_count += INC_PEER_ALLOC;
183 * findexistingpeer - return a pointer to a peer in the hash table
185 struct peer *
186 findexistingpeer(
187 struct sockaddr_storage *addr,
188 struct peer *start_peer,
189 int mode
192 register struct peer *peer;
195 * start_peer is included so we can locate instances of the
196 * same peer through different interfaces in the hash table.
198 if (start_peer == 0)
199 peer = peer_hash[NTP_HASH_ADDR(addr)];
200 else
201 peer = start_peer->next;
203 while (peer != 0) {
204 if (SOCKCMP(addr, &peer->srcadr)
205 && NSRCPORT(addr) == NSRCPORT(&peer->srcadr)) {
206 if (mode == -1)
207 return (peer);
208 else if (peer->hmode == mode)
209 break;
211 peer = peer->next;
213 return (peer);
218 * findpeer - find and return a peer in the hash table.
220 struct peer *
221 findpeer(
222 struct sockaddr_storage *srcadr,
223 struct interface *dstadr,
224 int pkt_mode,
225 int *action
228 register struct peer *peer;
229 int hash;
231 findpeer_calls++;
232 hash = NTP_HASH_ADDR(srcadr);
233 for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) {
234 if (SOCKCMP(srcadr, &peer->srcadr) &&
235 NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) {
238 * if the association matching rules determine
239 * that this is not a valid combination, then
240 * look for the next valid peer association.
242 *action = MATCH_ASSOC(peer->hmode, pkt_mode);
245 * if an error was returned, exit back right
246 * here.
248 if (*action == AM_ERR)
249 return ((struct peer *)0);
252 * if a match is found, we stop our search.
254 if (*action != AM_NOMATCH)
255 break;
260 * If no matching association is found
262 if (peer == 0) {
263 *action = MATCH_ASSOC(NO_PEER, pkt_mode);
264 return ((struct peer *)0);
267 set_peerdstadr(peer, dstadr);
269 return (peer);
273 * findpeerbyassocid - find and return a peer using his association ID
275 struct peer *
276 findpeerbyassoc(
277 u_int assoc
280 register struct peer *peer;
281 int hash;
283 assocpeer_calls++;
285 hash = assoc & NTP_HASH_MASK;
286 for (peer = assoc_hash[hash]; peer != 0; peer =
287 peer->ass_next) {
288 if (assoc == peer->associd)
289 return (peer);
291 return (NULL);
296 * clear_all - flush all time values for all associations
298 void
299 clear_all(void)
301 struct peer *peer, *next_peer;
302 int n;
305 * This routine is called when the clock is stepped, and so all
306 * previously saved time values are untrusted.
308 for (n = 0; n < NTP_HASH_SIZE; n++) {
309 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
310 next_peer = peer->next;
311 if (!(peer->cast_flags & (MDF_ACAST | MDF_MCAST |
312 MDF_BCAST))) {
313 peer->hpoll = peer->minpoll;
314 peer_clear(peer, "STEP");
318 #ifdef DEBUG
319 if (debug)
320 printf("clear_all: at %lu\n", current_time);
321 #endif
326 * unpeer - remove peer structure from hash table and free structure
328 void
329 unpeer(
330 struct peer *peer_to_remove
333 int hash;
334 #ifdef OPENSSL
335 char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
337 if (peer_to_remove->flags & FLAG_SKEY) {
338 sprintf(statstr, "unpeer %d flash %x reach %03o flags %04x",
339 peer_to_remove->associd, peer_to_remove->flash,
340 peer_to_remove->reach, peer_to_remove->flags);
341 record_crypto_stats(&peer_to_remove->srcadr, statstr);
342 #ifdef DEBUG
343 if (debug)
344 printf("peer: %s\n", statstr);
345 #endif
347 #endif /* OPENSSL */
348 #ifdef DEBUG
349 if (debug)
350 printf("demobilize %u %d %d\n", peer_to_remove->associd,
351 peer_associations, peer_preempt);
352 #endif
353 set_peerdstadr(peer_to_remove, NULL);
355 /* XXXMEMLEAK? peer_clear->crypto allocation */
357 hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
358 peer_hash_count[hash]--;
359 peer_demobilizations++;
360 peer_associations--;
361 if (peer_to_remove->flags & FLAG_PREEMPT)
362 peer_preempt--;
363 #ifdef REFCLOCK
365 * If this peer is actually a clock, shut it down first
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;
376 peer = peer_hash[hash];
377 while (peer != 0 && peer->next != peer_to_remove)
378 peer = peer->next;
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;
390 * Remove him from the association hash as well.
392 hash = peer_to_remove->associd & NTP_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;
399 peer = assoc_hash[hash];
400 while (peer != 0 && peer->ass_next != peer_to_remove)
401 peer = peer->ass_next;
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;
412 peer_to_remove->next = peer_free;
413 peer_free = peer_to_remove;
414 peer_free_count++;
419 * peer_config - configure a new association
421 struct peer *
422 peer_config(
423 struct sockaddr_storage *srcadr,
424 struct interface *dstadr,
425 int hmode,
426 int version,
427 int minpoll,
428 int maxpoll,
429 u_int flags,
430 int ttl,
431 keyid_t key,
432 u_char *keystr
435 register struct peer *peer;
436 u_char cast_flags;
439 * First search from the beginning for an association with given
440 * remote address and mode. If an interface is given, search
441 * from there to find the association which matches that
442 * destination. If the given interface is "any", track down
443 * the actual interface, because that's what gets put into the
444 * peer structure.
446 peer = findexistingpeer(srcadr, (struct peer *)0, hmode);
447 if (dstadr != 0) {
448 while (peer != 0) {
449 if (peer->dstadr == dstadr)
450 break;
451 if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
452 peer->dstadr == findinterface(srcadr))
453 break;
454 peer = findexistingpeer(srcadr, peer, hmode);
459 * We do a dirty little jig to figure the cast flags. This is
460 * probably not the best place to do this, at least until the
461 * configure code is rebuilt. Note only one flag can be set.
463 switch (hmode) {
465 case MODE_BROADCAST:
466 if(srcadr->ss_family == AF_INET) {
467 if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))
468 cast_flags = MDF_MCAST;
469 else
470 cast_flags = MDF_BCAST;
471 break;
473 else {
474 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
475 cast_flags = MDF_MCAST;
476 else
477 cast_flags = MDF_BCAST;
478 break;
481 case MODE_CLIENT:
482 if(srcadr->ss_family == AF_INET) {
483 if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr)))
484 cast_flags = MDF_ACAST;
485 else
486 cast_flags = MDF_UCAST;
487 break;
489 else {
490 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
491 cast_flags = MDF_ACAST;
492 else
493 cast_flags = MDF_UCAST;
494 break;
497 default:
498 cast_flags = MDF_UCAST;
502 * If the peer is already configured, some dope has a duplicate
503 * configureation entry or another dope is wiggling from afar.
505 if (peer != 0) {
506 peer->hmode = (u_char)hmode;
507 peer->version = (u_char) version;
508 peer->minpoll = (u_char) minpoll;
509 peer->maxpoll = (u_char) maxpoll;
510 peer->flags = flags | FLAG_CONFIG |
511 (peer->flags & FLAG_REFCLOCK);
512 peer->cast_flags = cast_flags;
513 peer->ttl = (u_char) ttl;
514 peer->keyid = key;
515 peer->precision = sys_precision;
516 peer_clear(peer, "RMOT");
517 return (peer);
521 * Here no match has been found, so presumably this is a new
522 * persistent association. Mobilize the thing and initialize its
523 * variables. If emulating ntpdate, force iburst.
525 if (mode_ntpdate)
526 flags |= FLAG_IBURST;
527 peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
528 flags | FLAG_CONFIG, cast_flags, ttl, key);
529 return (peer);
533 * setup peer dstadr field keeping it in sync with the interface structures
535 void
536 set_peerdstadr(struct peer *peer, struct interface *interface)
538 if (peer->dstadr != interface) {
539 if (interface != NULL &&
540 (peer->cast_flags & MDF_BCLNT) &&
541 (interface->flags & INT_MCASTIF) &&
542 peer->burst) {
544 * don't accept updates to a true multicast reception
545 * interface while a BCLNT peer is running it's
546 * unicast protocol
548 return;
551 if (peer->dstadr != NULL)
553 peer->dstadr->peercnt--;
554 ISC_LIST_UNLINK_TYPE(peer->dstadr->peers, peer, ilink, struct peer);
557 DPRINTF(4, ("set_peerdstadr(%s): change interface from %s to %s\n",
558 stoa(&peer->srcadr),
559 (peer->dstadr != NULL) ? stoa(&peer->dstadr->sin) : "<null>",
560 (interface != NULL) ? stoa(&interface->sin) : "<null>"));
562 peer->dstadr = interface;
564 if (peer->dstadr != NULL)
566 ISC_LIST_APPEND(peer->dstadr->peers, peer, ilink);
567 peer->dstadr->peercnt++;
573 * attempt to re-rebind interface if necessary
575 static void
576 peer_refresh_interface(struct peer *peer)
578 struct interface *niface, *piface;
580 niface = select_peerinterface(peer, &peer->srcadr, NULL, peer->cast_flags);
582 #ifdef DEBUG
583 if (debug > 3)
585 printf(
586 "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ",
587 peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
588 stoa(&peer->srcadr),
589 peer->hmode, peer->version, peer->minpoll,
590 peer->maxpoll, peer->flags, peer->cast_flags,
591 peer->ttl, peer->keyid);
592 if (niface != NULL)
594 printf("fd=%d, bfd=%d, name=%.16s, flags=0x%x, scope=%d, ",
595 niface->fd,
596 niface->bfd,
597 niface->name,
598 niface->flags,
599 niface->scopeid);
600 /* Leave these as three printf calls. */
601 printf(", sin=%s",
602 stoa((&niface->sin)));
603 if (niface->flags & INT_BROADCAST)
604 printf(", bcast=%s,",
605 stoa((&niface->bcast)));
606 printf(", mask=%s\n",
607 stoa((&niface->mask)));
609 else
611 printf("<NONE>\n");
614 #endif
616 piface = peer->dstadr;
618 set_peerdstadr(peer, niface);
620 if (peer->dstadr) {
622 * clear crypto if we change the local address
624 if (peer->dstadr != piface && !(peer->cast_flags & MDF_BCLNT)) {
625 peer_crypto_clear(peer);
629 * Broadcast needs the socket enabled for broadcast
631 if (peer->cast_flags & MDF_BCAST) {
632 enable_broadcast(peer->dstadr, &peer->srcadr);
636 * Multicast needs the socket interface enabled for multicast
638 if (peer->cast_flags & MDF_MCAST) {
639 enable_multicast_if(peer->dstadr, &peer->srcadr);
645 * refresh_all_peerinterfaces - see that all interface bindings are up to date
647 void
648 refresh_all_peerinterfaces(void)
650 struct peer *peer, *next_peer;
651 int n;
654 * this is called when the interface list has changed
655 * give all peers a chance to find a better interface
657 for (n = 0; n < NTP_HASH_SIZE; n++) {
658 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
659 next_peer = peer->next;
660 peer_refresh_interface(peer);
667 * find an interface suitable for the src address
669 static struct interface *
670 select_peerinterface(struct peer *peer, struct sockaddr_storage *srcadr, struct interface *dstadr, u_char cast_flags)
672 struct interface *interface;
675 * Initialize the peer structure and dance the interface jig.
676 * Reference clocks step the loopback waltz, the others
677 * squaredance around the interface list looking for a buddy. If
678 * the dance peters out, there is always the wildcard interface.
679 * This might happen in some systems and would preclude proper
680 * operation with public key cryptography.
682 if (ISREFCLOCKADR(srcadr))
683 interface = loopback_interface;
684 else
685 if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
686 interface = findbcastinter(srcadr);
687 #ifdef DEBUG
688 if (debug > 3) {
689 if (interface != NULL)
690 printf("Found *-cast interface address %s, for address %s\n",
691 stoa(&(interface)->sin), stoa(srcadr));
692 else
693 printf("No *-cast local address found for address %s\n",
694 stoa(srcadr));
696 #endif
698 * If it was a multicast packet, findbcastinter() may not
699 * find it, so try a little harder.
701 if (interface == ANY_INTERFACE_CHOOSE(srcadr))
702 interface = findinterface(srcadr);
704 else if (dstadr != NULL && dstadr != ANY_INTERFACE_CHOOSE(srcadr))
705 interface = dstadr;
706 else
707 interface = findinterface(srcadr);
710 * we do not bind to the wildcard interfaces for output
711 * as our (network) source address would be undefined and
712 * crypto will not work without knowing the own transmit address
714 if (interface != NULL && interface->flags & INT_WILDCARD)
715 #ifdef SYS_WINNT
716 if ( !accept_wildcard_if_for_winnt )
717 #endif
718 interface = NULL;
721 return interface;
725 * newpeer - initialize a new peer association
727 struct peer *
728 newpeer(
729 struct sockaddr_storage *srcadr,
730 struct interface *dstadr,
731 int hmode,
732 int version,
733 int minpoll,
734 int maxpoll,
735 u_int flags,
736 u_char cast_flags,
737 int ttl,
738 keyid_t key
741 register struct peer *peer;
742 register int i;
743 #ifdef OPENSSL
744 char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
745 #endif /* OPENSSL */
748 * Allocate a new peer structure. Some dirt here, since some of
749 * the initialization requires knowlege of our system state.
751 if (peer_free_count == 0)
752 getmorepeermem();
753 peer = peer_free;
754 peer_free = peer->next;
755 peer_free_count--;
756 peer_associations++;
757 if (flags & FLAG_PREEMPT)
758 peer_preempt++;
759 memset((char *)peer, 0, sizeof(struct peer));
762 * Assign an association ID and increment the system variable.
764 peer->associd = current_association_ID;
765 if (++current_association_ID == 0)
766 ++current_association_ID;
768 DPRINTF(3, ("newpeer: cast flags: 0x%x for address: %s\n",
769 cast_flags, stoa(srcadr)));
771 ISC_LINK_INIT(peer, ilink); /* set up interface link chain */
772 peer->srcadr = *srcadr;
773 set_peerdstadr(peer, select_peerinterface(peer, srcadr, dstadr,
774 cast_flags));
775 peer->hmode = (u_char)hmode;
776 peer->version = (u_char)version;
777 peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll);
778 peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll);
779 peer->flags = flags;
780 #ifdef DEBUG
781 if (debug > 2) {
782 if (peer->dstadr)
783 printf("newpeer: using fd %d and our addr %s\n",
784 peer->dstadr->fd,
785 stoa(&peer->dstadr->sin));
786 else
787 printf("newpeer: local interface currently not bound\n");
789 #endif
792 * Broadcast needs the socket enabled for broadcast
794 if (cast_flags & MDF_BCAST && peer->dstadr) {
795 enable_broadcast(peer->dstadr, srcadr);
798 * Multicast needs the socket interface enabled for multicast
800 if (cast_flags & MDF_MCAST && peer->dstadr) {
801 enable_multicast_if(peer->dstadr, srcadr);
803 if (key != 0)
804 peer->flags |= FLAG_AUTHENABLE;
805 if (key > NTP_MAXKEY)
806 peer->flags |= FLAG_SKEY;
807 peer->cast_flags = cast_flags;
808 peer->ttl = (u_char)ttl;
809 peer->keyid = key;
810 peer->precision = sys_precision;
811 peer->hpoll = peer->minpoll;
812 if (cast_flags & MDF_ACAST)
813 peer_clear(peer, "ACST");
814 else if (cast_flags & MDF_MCAST)
815 peer_clear(peer, "MCST");
816 else if (cast_flags & MDF_BCAST)
817 peer_clear(peer, "BCST");
818 else
819 peer_clear(peer, "INIT");
820 if (mode_ntpdate)
821 peer_ntpdate++;
824 * Note time on statistics timers.
826 peer->timereset = current_time;
827 peer->timereachable = current_time;
828 peer->timereceived = current_time;
830 #ifdef REFCLOCK
831 if (ISREFCLOCKADR(&peer->srcadr)) {
834 * We let the reference clock support do clock
835 * dependent initialization. This includes setting
836 * the peer timer, since the clock may have requirements
837 * for this.
839 if (!refclock_newpeer(peer)) {
841 * Dump it, something screwed up
843 set_peerdstadr(peer, NULL);
845 peer->next = peer_free;
846 peer_free = peer;
847 peer_free_count++;
848 return (NULL);
851 #endif
854 * Put the new peer in the hash tables.
856 i = NTP_HASH_ADDR(&peer->srcadr);
857 peer->next = peer_hash[i];
858 peer_hash[i] = peer;
859 peer_hash_count[i]++;
860 i = peer->associd & NTP_HASH_MASK;
861 peer->ass_next = assoc_hash[i];
862 assoc_hash[i] = peer;
863 assoc_hash_count[i]++;
865 #ifdef OPENSSL
866 if (peer->flags & FLAG_SKEY) {
867 sprintf(statstr, "newpeer %d", peer->associd);
868 record_crypto_stats(&peer->srcadr, statstr);
869 DPRINTF(1, ("peer: %s\n", statstr));
871 #endif /* OPENSSL */
873 DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
874 peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
875 stoa(&peer->srcadr),
876 peer->hmode, peer->version, peer->minpoll,
877 peer->maxpoll, peer->flags, peer->cast_flags,
878 peer->ttl, peer->keyid));
880 return (peer);
885 * peer_unconfig - remove the configuration bit from a peer
888 peer_unconfig(
889 struct sockaddr_storage *srcadr,
890 struct interface *dstadr,
891 int mode
894 register struct peer *peer;
895 int num_found;
897 num_found = 0;
898 peer = findexistingpeer(srcadr, (struct peer *)0, mode);
899 while (peer != 0) {
900 if (peer->flags & FLAG_CONFIG
901 && (dstadr == 0 || peer->dstadr == dstadr)) {
902 num_found++;
905 * Tricky stuff here. If the peer is polling us
906 * in active mode, turn off the configuration
907 * bit and make the mode passive. This allows us
908 * to avoid dumping a lot of history for peers
909 * we might choose to keep track of in passive
910 * mode. The protocol will eventually terminate
911 * undesirables on its own.
913 if (peer->hmode == MODE_ACTIVE
914 && peer->pmode == MODE_ACTIVE) {
915 peer->hmode = MODE_PASSIVE;
916 peer->flags &= ~FLAG_CONFIG;
917 } else {
918 unpeer(peer);
919 peer = 0;
922 peer = findexistingpeer(srcadr, peer, mode);
924 return (num_found);
928 * peer_clr_stats - clear peer module stat counters
930 void
931 peer_clr_stats(void)
933 findpeer_calls = 0;
934 assocpeer_calls = 0;
935 peer_allocations = 0;
936 peer_demobilizations = 0;
937 peer_timereset = current_time;
941 * peer_reset - reset stat counters in a peer structure
943 void
944 peer_reset(
945 struct peer *peer
948 if (peer == 0)
949 return;
950 peer->sent = 0;
951 peer->received = 0;
952 peer->processed = 0;
953 peer->badauth = 0;
954 peer->bogusorg = 0;
955 peer->oldpkt = 0;
956 peer->seldisptoolarge = 0;
957 peer->timereset = current_time;
962 * peer_all_reset - reset all peer stat counters
964 void
965 peer_all_reset(void)
967 struct peer *peer;
968 int hash;
970 for (hash = 0; hash < NTP_HASH_SIZE; hash++)
971 for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
972 peer_reset(peer);
976 #ifdef OPENSSL
978 * expire_all - flush all crypto data and update timestamps.
980 void
981 expire_all(void)
983 struct peer *peer, *next_peer;
984 int n;
987 * This routine is called about once per day from the timer
988 * routine and when the client is first synchronized. Search the
989 * peer list for all associations and flush only the key list
990 * and cookie. If a manycast client association, flush
991 * everything. Then, recompute and sign the agreement public
992 * value, if present.
994 if (!crypto_flags)
995 return;
997 for (n = 0; n < NTP_HASH_SIZE; n++) {
998 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
999 next_peer = peer->next;
1000 if (!(peer->flags & FLAG_SKEY)) {
1001 continue;
1003 } else if (peer->hmode == MODE_ACTIVE ||
1004 peer->hmode == MODE_PASSIVE) {
1005 key_expire(peer);
1006 peer->crypto &= ~(CRYPTO_FLAG_AUTO |
1007 CRYPTO_FLAG_AGREE);
1012 RAND_bytes((u_char *)&sys_private, 4);
1013 crypto_update();
1015 #endif /* OPENSSL */
1019 * findmanycastpeer - find and return a manycast peer
1021 struct peer *
1022 findmanycastpeer(
1023 struct recvbuf *rbufp
1026 register struct peer *peer;
1027 struct pkt *pkt;
1028 l_fp p_org;
1029 int i;
1032 * This routine is called upon arrival of a server-mode message
1033 * from a manycast client. Search the peer list for a manycast
1034 * client association where the last transmit timestamp matches
1035 * the originate timestamp. This assumes the transmit timestamps
1036 * for possibly more than one manycast association are unique.
1038 pkt = &rbufp->recv_pkt;
1039 for (i = 0; i < NTP_HASH_SIZE; i++) {
1040 if (peer_hash_count[i] == 0)
1041 continue;
1043 for (peer = peer_hash[i]; peer != 0; peer =
1044 peer->next) {
1045 if (peer->cast_flags & MDF_ACAST) {
1046 NTOHL_FP(&pkt->org, &p_org);
1047 if (L_ISEQU(&peer->xmt, &p_org))
1048 return (peer);
1052 return (NULL);