Patrick Welche <prlw1@cam.ac.uk>
[netbsd-mini2440.git] / external / bsd / ntp / dist / ntpd / ntp_peer.c
blobf54c84882535b026bcd8d2c04eca6b982074f614
1 /* $NetBSD$ */
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_lists.h"
15 #include "ntp_stdlib.h"
16 #include "ntp_control.h"
17 #include <ntp_random.h>
18 #ifdef OPENSSL
19 #include "openssl/rand.h"
20 #endif /* OPENSSL */
22 #ifdef SYS_WINNT
23 extern int accept_wildcard_if_for_winnt;
24 #endif
27 * Table of valid association combinations
28 * ---------------------------------------
30 * packet->mode
31 * peer->mode | UNSPEC ACTIVE PASSIVE CLIENT SERVER BCAST
32 * ---------- | ---------------------------------------------
33 * NO_PEER | e 1 0 1 1 1
34 * ACTIVE | e 1 1 0 0 0
35 * PASSIVE | e 1 e 0 0 0
36 * CLIENT | e 0 0 0 1 0
37 * SERVER | e 0 0 0 0 0
38 * BCAST | e 0 0 0 0 0
39 * BCLIENT | e 0 0 0 e 1
41 * One point to note here: a packet in BCAST mode can potentially match
42 * a peer in CLIENT mode, but we that is a special case and we check for
43 * that early in the decision process. This avoids having to keep track
44 * of what kind of associations are possible etc... We actually
45 * circumvent that problem by requiring that the first b(m)roadcast
46 * received after the change back to BCLIENT mode sets the clock.
48 #define AM_MODES 7 /* number of rows and columns */
49 #define NO_PEER 0 /* action when no peer is found */
51 int AM[AM_MODES][AM_MODES] = {
52 /* { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */
54 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT, AM_MANYCAST, AM_NEWBCL},
56 /*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
58 /*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
60 /*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_NOMATCH},
62 /*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
64 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
66 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT},
69 #define MATCH_ASSOC(x, y) AM[(x)][(y)]
72 * These routines manage the allocation of memory to peer structures
73 * and the maintenance of the peer hash table. The three main entry
74 * points are findpeer(), which looks for matching peer structures in
75 * the peer list, newpeer(), which allocates a new peer structure and
76 * adds it to the list, and unpeer(), which demobilizes the association
77 * and deallocates the structure.
80 * Peer hash tables
82 struct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */
83 int peer_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
84 struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
85 int assoc_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */
86 static struct peer *peer_free; /* peer structures free list */
87 int peer_free_count; /* count of free structures */
90 * Association ID. We initialize this value randomly, then assign a new
91 * value every time the peer structure is incremented.
93 static associd_t current_association_ID; /* association ID */
96 * Memory allocation watermarks.
98 #define INIT_PEER_ALLOC 15 /* initialize for 15 peers */
99 #define INC_PEER_ALLOC 5 /* when run out, add 5 more */
102 * Miscellaneous statistic counters which may be queried.
104 u_long peer_timereset; /* time stat counters zeroed */
105 u_long findpeer_calls; /* calls to findpeer */
106 u_long assocpeer_calls; /* calls to findpeerbyassoc */
107 u_long peer_allocations; /* allocations from free list */
108 u_long peer_demobilizations; /* structs freed to free list */
109 int total_peer_structs; /* peer structs */
110 int peer_associations; /* mobilized associations */
111 int peer_preempt; /* preemptable associations */
112 static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
114 static void getmorepeermem (void);
115 static struct interface *select_peerinterface (struct peer *, sockaddr_u *, struct interface *, u_char);
117 static int score(struct peer *);
120 * init_peer - initialize peer data structures and counters
122 * N.B. We use the random number routine in here. It had better be
123 * initialized prior to getting here.
125 void
126 init_peer(void)
128 register int i;
131 * Clear hash tables and counters.
133 memset(peer_hash, 0, sizeof(peer_hash));
134 memset(peer_hash_count, 0, sizeof(peer_hash_count));
135 memset(assoc_hash, 0, sizeof(assoc_hash));
136 memset(assoc_hash_count, 0, sizeof(assoc_hash_count));
139 * Clear stat counters
141 findpeer_calls = peer_allocations = 0;
142 assocpeer_calls = peer_demobilizations = 0;
145 * Initialize peer memory.
147 peer_free = NULL;
148 for (i = 0; i < INIT_PEER_ALLOC; i++)
149 LINK_SLIST(peer_free, &init_peer_alloc[i], next);
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 LINK_SLIST(peer_free, peer, next);
173 peer++;
176 total_peer_structs += INC_PEER_ALLOC;
177 peer_free_count += INC_PEER_ALLOC;
182 * findexistingpeer - return a pointer to a peer in the hash table
184 struct peer *
185 findexistingpeer(
186 sockaddr_u *addr,
187 struct peer *start_peer,
188 int mode
191 register struct peer *peer;
194 * start_peer is included so we can locate instances of the
195 * same peer through different interfaces in the hash table.
197 if (NULL == start_peer)
198 peer = peer_hash[NTP_HASH_ADDR(addr)];
199 else
200 peer = start_peer->next;
202 while (peer != NULL) {
203 if (SOCK_EQ(addr, &peer->srcadr)
204 && NSRCPORT(addr) == NSRCPORT(&peer->srcadr)
205 && (-1 == mode || peer->hmode == mode))
206 break;
207 peer = peer->next;
209 return (peer);
214 * findpeer - find and return a peer in the hash table.
216 struct peer *
217 findpeer(
218 sockaddr_u *srcadr,
219 struct interface *dstadr,
220 int pkt_mode,
221 int *action
224 register struct peer *peer;
225 u_int hash;
227 findpeer_calls++;
228 hash = NTP_HASH_ADDR(srcadr);
229 for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) {
230 if (SOCK_EQ(srcadr, &peer->srcadr) &&
231 NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) {
234 * if the association matching rules determine
235 * that this is not a valid combination, then
236 * look for the next valid peer association.
238 *action = MATCH_ASSOC(peer->hmode, pkt_mode);
241 * if an error was returned, exit back right
242 * here.
244 if (*action == AM_ERR)
245 return ((struct peer *)0);
248 * if a match is found, we stop our search.
250 if (*action != AM_NOMATCH)
251 break;
256 * If no matching association is found
258 if (peer == 0) {
259 *action = MATCH_ASSOC(NO_PEER, pkt_mode);
260 return ((struct peer *)0);
262 set_peerdstadr(peer, dstadr);
263 return (peer);
267 * findpeerbyassocid - find and return a peer using his association ID
269 struct peer *
270 findpeerbyassoc(
271 u_int assoc
274 register struct peer *peer;
275 u_int hash;
277 assocpeer_calls++;
279 hash = assoc & NTP_HASH_MASK;
280 for (peer = assoc_hash[hash]; peer != 0; peer =
281 peer->ass_next) {
282 if (assoc == peer->associd)
283 return (peer);
285 return (NULL);
290 * clear_all - flush all time values for all associations
292 void
293 clear_all(void)
295 struct peer *peer, *next_peer;
296 int n;
299 * This routine is called when the clock is stepped, and so all
300 * previously saved time values are untrusted.
302 for (n = 0; n < NTP_HASH_SIZE; n++) {
303 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
304 next_peer = peer->next;
305 if (!(peer->cast_flags & (MDF_ACAST |
306 MDF_MCAST | MDF_BCAST))) {
307 peer_clear(peer, "STEP");
311 #ifdef DEBUG
312 if (debug)
313 printf("clear_all: at %lu\n", current_time);
314 #endif
319 * score_all() - determine if an association can be demobilized
322 score_all(
323 struct peer *peer /* peer structure pointer */
326 struct peer *speer, *next_peer;
327 int n;
328 int temp, tamp;
331 * This routine finds the minimum score for all ephemeral
332 * assocations and returns > 0 if the association can be
333 * demobilized.
335 tamp = score(peer);
336 temp = 100;
337 for (n = 0; n < NTP_HASH_SIZE; n++) {
338 for (speer = peer_hash[n]; speer != 0; speer =
339 next_peer) {
340 int x;
342 next_peer = speer->next;
343 if ((x = score(speer)) < temp && (peer->flags &
344 FLAG_PREEMPT))
345 temp = x;
348 #ifdef DEBUG
349 if (debug)
350 printf("score_all: at %lu score %d min %d\n",
351 current_time, tamp, temp);
352 #endif
353 if (tamp != temp)
354 temp = 0;
355 return (temp);
360 * score() - calculate preemption score
362 static int
363 score(
364 struct peer *peer /* peer structure pointer */
367 int temp;
370 * This routine calculates the premption score from the peer
371 * error bits and status. Increasing values are more cherished.
373 temp = 0;
374 if (!(peer->flash & TEST10))
375 temp++; /* 1 good synch and stratum */
376 if (!(peer->flash & TEST13))
377 temp++; /* 2 reachable */
378 if (!(peer->flash & TEST12))
379 temp++; /* 3 no loop */
380 if (!(peer->flash & TEST11))
381 temp++; /* 4 good distance */
382 if (peer->status >= CTL_PST_SEL_SELCAND)
383 temp++; /* 5 in the hunt */
384 if (peer->status != CTL_PST_SEL_EXCESS)
385 temp++; /* 6 not spare tire */
386 return (temp); /* selection status */
391 * unpeer - remove peer structure from hash table and free structure
393 void
394 unpeer(
395 struct peer *peer_to_remove
398 register struct peer *unlinked;
399 int hash;
400 char tbuf[80];
402 snprintf(tbuf, sizeof(tbuf), "assoc %d",
403 peer_to_remove->associd);
404 report_event(PEVNT_DEMOBIL, peer_to_remove, tbuf);
405 set_peerdstadr(peer_to_remove, NULL);
406 hash = NTP_HASH_ADDR(&peer_to_remove->srcadr);
407 peer_hash_count[hash]--;
408 peer_demobilizations++;
409 peer_associations--;
410 if (peer_to_remove->flags & FLAG_PREEMPT)
411 peer_preempt--;
412 #ifdef REFCLOCK
414 * If this peer is actually a clock, shut it down first
416 if (peer_to_remove->flags & FLAG_REFCLOCK)
417 refclock_unpeer(peer_to_remove);
418 #endif
419 peer_to_remove->action = 0; /* disable timeout actions */
421 UNLINK_SLIST(unlinked, peer_hash[hash], peer_to_remove, next,
422 struct peer);
424 if (NULL == unlinked) {
425 peer_hash_count[hash]++;
426 msyslog(LOG_ERR, "peer struct for %s not in table!",
427 stoa(&peer_to_remove->srcadr));
431 * Remove him from the association hash as well.
433 hash = peer_to_remove->associd & NTP_HASH_MASK;
434 assoc_hash_count[hash]--;
436 UNLINK_SLIST(unlinked, assoc_hash[hash], peer_to_remove,
437 ass_next, struct peer);
439 if (NULL == unlinked) {
440 assoc_hash_count[hash]++;
441 msyslog(LOG_ERR,
442 "peer struct for %s not in association table!",
443 stoa(&peer_to_remove->srcadr));
446 LINK_SLIST(peer_free, peer_to_remove, next);
447 peer_free_count++;
452 * peer_config - configure a new association
454 struct peer *
455 peer_config(
456 sockaddr_u *srcadr,
457 struct interface *dstadr,
458 int hmode,
459 int version,
460 int minpoll,
461 int maxpoll,
462 u_int flags,
463 int ttl,
464 keyid_t key,
465 u_char *keystr
468 u_char cast_flags;
471 * We do a dirty little jig to figure the cast flags. This is
472 * probably not the best place to do this, at least until the
473 * configure code is rebuilt. Note only one flag can be set.
475 switch (hmode) {
476 case MODE_BROADCAST:
477 if (IS_MCAST(srcadr))
478 cast_flags = MDF_MCAST;
479 else
480 cast_flags = MDF_BCAST;
481 break;
483 case MODE_CLIENT:
484 if (IS_MCAST(srcadr))
485 cast_flags = MDF_ACAST;
486 else
487 cast_flags = MDF_UCAST;
488 break;
490 default:
491 cast_flags = MDF_UCAST;
495 * Mobilize the association and initialize its variables. If
496 * emulating ntpdate, force iburst.
498 if (mode_ntpdate)
499 flags |= FLAG_IBURST;
500 return(newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
501 flags | FLAG_CONFIG, cast_flags, ttl, key));
505 * setup peer dstadr field keeping it in sync with the interface
506 * structures
508 void
509 set_peerdstadr(
510 struct peer *peer,
511 struct interface *interface
514 struct peer *unlinked;
516 if (peer->dstadr != interface) {
517 if (interface != NULL && (peer->cast_flags &
518 MDF_BCLNT) && (interface->flags & INT_MCASTIF) &&
519 peer->burst) {
522 * don't accept updates to a true multicast
523 * reception interface while a BCLNT peer is
524 * running it's unicast protocol
526 return;
528 if (peer->dstadr != NULL) {
529 peer->dstadr->peercnt--;
530 UNLINK_SLIST(unlinked, peer->dstadr->peers,
531 peer, ilink, struct peer);
532 msyslog(LOG_INFO,
533 "%s interface %s -> %s",
534 stoa(&peer->srcadr),
535 stoa(&peer->dstadr->sin),
536 (interface != NULL)
537 ? stoa(&interface->sin)
538 : "(null)");
540 peer->dstadr = interface;
541 if (peer->dstadr != NULL) {
542 LINK_SLIST(peer->dstadr->peers, peer, ilink);
543 peer->dstadr->peercnt++;
549 * attempt to re-rebind interface if necessary
551 static void
552 peer_refresh_interface(
553 struct peer *peer
556 struct interface *niface, *piface;
558 niface = select_peerinterface(peer, &peer->srcadr, NULL,
559 peer->cast_flags);
561 #ifdef DEBUG
562 if (debug > 3)
564 printf(
565 "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x: new interface: ",
566 peer->dstadr == NULL ? "<null>" :
567 stoa(&peer->dstadr->sin), stoa(&peer->srcadr),
568 peer->hmode, peer->version, peer->minpoll,
569 peer->maxpoll, peer->flags, peer->cast_flags,
570 peer->ttl, peer->keyid);
571 if (niface != NULL) {
572 printf(
573 "fd=%d, bfd=%d, name=%.16s, flags=0x%x, scope=%d, ",
574 niface->fd, niface->bfd, niface->name,
575 niface->flags, niface->scopeid);
576 printf(", sin=%s", stoa((&niface->sin)));
577 if (niface->flags & INT_BROADCAST)
578 printf(", bcast=%s,",
579 stoa((&niface->bcast)));
580 printf(", mask=%s\n", stoa((&niface->mask)));
581 } else {
582 printf("<NONE>\n");
585 #endif
587 piface = peer->dstadr;
588 set_peerdstadr(peer, niface);
589 if (peer->dstadr) {
591 * clear crypto if we change the local address
593 if (peer->dstadr != piface && !(peer->cast_flags &
594 MDF_ACAST) && peer->pmode != MODE_BROADCAST)
595 peer_clear(peer, "XFAC");
598 * Broadcast needs the socket enabled for broadcast
600 if (peer->cast_flags & MDF_BCAST) {
601 enable_broadcast(peer->dstadr, &peer->srcadr);
605 * Multicast needs the socket interface enabled for
606 * multicast
608 if (peer->cast_flags & MDF_MCAST) {
609 enable_multicast_if(peer->dstadr,
610 &peer->srcadr);
616 * refresh_all_peerinterfaces - see that all interface bindings are up
617 * to date
619 void
620 refresh_all_peerinterfaces(void)
622 struct peer *peer, *next_peer;
623 int n;
626 * this is called when the interface list has changed
627 * give all peers a chance to find a better interface
629 for (n = 0; n < NTP_HASH_SIZE; n++) {
630 for (peer = peer_hash[n]; peer != 0; peer = next_peer) {
631 next_peer = peer->next;
632 peer_refresh_interface(peer);
639 * find an interface suitable for the src address
641 static struct interface *
642 select_peerinterface(
643 struct peer * peer,
644 sockaddr_u * srcadr,
645 struct interface * dstadr,
646 u_char cast_flags
649 struct interface *interface;
652 * Initialize the peer structure and dance the interface jig.
653 * Reference clocks step the loopback waltz, the others
654 * squaredance around the interface list looking for a buddy. If
655 * the dance peters out, there is always the wildcard interface.
656 * This might happen in some systems and would preclude proper
657 * operation with public key cryptography.
659 if (ISREFCLOCKADR(srcadr))
660 interface = loopback_interface;
661 else
662 if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) {
663 interface = findbcastinter(srcadr);
664 #ifdef DEBUG
665 if (debug > 3) {
666 if (interface != NULL)
667 printf("Found *-cast interface address %s, for address %s\n",
668 stoa(&(interface)->sin), stoa(srcadr));
669 else
670 printf("No *-cast local address found for address %s\n",
671 stoa(srcadr));
673 #endif
675 * If it was a multicast packet,
676 * findbcastinter() may not find it, so try a
677 * little harder.
679 if (interface == ANY_INTERFACE_CHOOSE(srcadr))
680 interface = findinterface(srcadr);
682 else if (dstadr != NULL && dstadr !=
683 ANY_INTERFACE_CHOOSE(srcadr))
684 interface = dstadr;
685 else
686 interface = findinterface(srcadr);
689 * we do not bind to the wildcard interfaces for output
690 * as our (network) source address would be undefined and
691 * crypto will not work without knowing the own transmit address
693 if (interface != NULL && interface->flags & INT_WILDCARD)
694 #ifdef SYS_WINNT
695 if ( !accept_wildcard_if_for_winnt )
696 #endif
697 interface = NULL;
700 return interface;
704 * newpeer - initialize a new peer association
706 struct peer *
707 newpeer(
708 sockaddr_u *srcadr,
709 struct interface *dstadr,
710 int hmode,
711 int version,
712 int minpoll,
713 int maxpoll,
714 u_int flags,
715 u_char cast_flags,
716 int ttl,
717 keyid_t key
720 struct peer *peer;
721 u_int hash;
722 char tbuf[80];
724 #ifdef OPENSSL
726 * If Autokey is requested but not configured, complain loudly.
728 if (!crypto_flags) {
729 if (key > NTP_MAXKEY) {
730 return (NULL);
732 } else if (flags & FLAG_SKEY) {
733 msyslog(LOG_ERR, "Autokey not configured");
734 return (NULL);
737 #endif /* OPENSSL */
740 * First search from the beginning for an association with given
741 * remote address and mode. If an interface is given, search
742 * from there to find the association which matches that
743 * destination. If the given interface is "any", track down the
744 * actual interface, because that's what gets put into the peer
745 * structure.
747 peer = findexistingpeer(srcadr, NULL, hmode);
748 if (dstadr != NULL) {
749 while (peer != NULL) {
750 if (peer->dstadr == dstadr)
751 break;
753 if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
754 peer->dstadr == findinterface(srcadr))
755 break;
757 peer = findexistingpeer(srcadr, peer, hmode);
762 * If a peer is found, this would be a duplicate and we don't
763 * allow that. This is mostly to avoid duplicate pool
764 * associations.
766 if (peer != NULL)
767 return (NULL);
770 * Allocate a new peer structure. Some dirt here, since some of
771 * the initialization requires knowlege of our system state.
773 if (peer_free_count == 0)
774 getmorepeermem();
775 UNLINK_HEAD_SLIST(peer, peer_free, next);
776 peer_free_count--;
777 peer_associations++;
778 if (flags & FLAG_PREEMPT)
779 peer_preempt++;
780 memset(peer, 0, sizeof(*peer));
783 * Assign an association ID and increment the system variable.
785 peer->associd = current_association_ID;
786 if (++current_association_ID == 0)
787 ++current_association_ID;
789 DPRINTF(3, ("newpeer: cast flags: 0x%x for address: %s\n",
790 cast_flags, stoa(srcadr)));
792 peer->srcadr = *srcadr;
793 set_peerdstadr(peer, select_peerinterface(peer, srcadr, dstadr,
794 cast_flags));
795 peer->hmode = (u_char)hmode;
796 peer->version = (u_char)version;
797 peer->flags = flags;
800 * It is an error to set minpoll less than NTP_MINPOLL or to
801 * set maxpoll greater than NTP_MAXPOLL. However, minpoll is
802 * clamped not greater than NTP_MAXPOLL and maxpoll is clamped
803 * not less than NTP_MINPOLL without complaint. Finally,
804 * minpoll is clamped not greater than maxpoll.
806 if (minpoll == 0)
807 peer->minpoll = NTP_MINDPOLL;
808 else
809 peer->minpoll = (u_char)min(minpoll, NTP_MAXPOLL);
810 if (maxpoll == 0)
811 peer->maxpoll = NTP_MAXDPOLL;
812 else
813 peer->maxpoll = (u_char)max(maxpoll, NTP_MINPOLL);
814 if (peer->minpoll > peer->maxpoll)
815 peer->minpoll = peer->maxpoll;
817 if (peer->dstadr)
818 DPRINTF(3, ("newpeer: using fd %d and our addr %s\n",
819 peer->dstadr->fd, stoa(&peer->dstadr->sin)));
820 else
821 DPRINTF(3, ("newpeer: local interface currently not bound\n"));
824 * Broadcast needs the socket enabled for broadcast
826 if ((cast_flags & MDF_BCAST) && peer->dstadr)
827 enable_broadcast(peer->dstadr, srcadr);
830 * Multicast needs the socket interface enabled for multicast
832 if ((cast_flags & MDF_MCAST) && peer->dstadr)
833 enable_multicast_if(peer->dstadr, srcadr);
835 #ifdef OPENSSL
836 if (key > NTP_MAXKEY)
837 peer->flags |= FLAG_SKEY;
838 #endif /* OPENSSL */
839 peer->cast_flags = cast_flags;
840 peer->ttl = (u_char)ttl;
841 peer->keyid = key;
842 peer->precision = sys_precision;
843 peer->hpoll = peer->minpoll;
844 if (cast_flags & MDF_ACAST)
845 peer_clear(peer, "ACST");
846 else if (cast_flags & MDF_MCAST)
847 peer_clear(peer, "MCST");
848 else if (cast_flags & MDF_BCAST)
849 peer_clear(peer, "BCST");
850 else
851 peer_clear(peer, "INIT");
852 if (mode_ntpdate)
853 peer_ntpdate++;
856 * Note time on statistics timers.
858 peer->timereset = current_time;
859 peer->timereachable = current_time;
860 peer->timereceived = current_time;
862 #ifdef REFCLOCK
863 if (ISREFCLOCKADR(&peer->srcadr)) {
866 * We let the reference clock support do clock
867 * dependent initialization. This includes setting
868 * the peer timer, since the clock may have requirements
869 * for this.
871 if (maxpoll == 0)
872 peer->maxpoll = peer->minpoll;
873 if (!refclock_newpeer(peer)) {
875 * Dump it, something screwed up
877 set_peerdstadr(peer, NULL);
878 LINK_SLIST(peer_free, peer, next);
879 peer_free_count++;
880 return (NULL);
883 #endif
886 * Put the new peer in the hash tables.
888 hash = NTP_HASH_ADDR(&peer->srcadr);
889 LINK_SLIST(peer_hash[hash], peer, next);
890 peer_hash_count[hash]++;
891 hash = peer->associd & NTP_HASH_MASK;
892 LINK_SLIST(assoc_hash[hash], peer, ass_next);
893 assoc_hash_count[hash]++;
894 snprintf(tbuf, sizeof(tbuf), "assoc %d", peer->associd);
895 report_event(PEVNT_MOBIL, peer, tbuf);
896 DPRINTF(1, ("newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n",
897 peer->dstadr == NULL ? "<null>" : stoa(&peer->dstadr->sin),
898 stoa(&peer->srcadr), peer->hmode, peer->version,
899 peer->minpoll, peer->maxpoll, peer->flags, peer->cast_flags,
900 peer->ttl, peer->keyid));
901 return (peer);
906 * peer_clr_stats - clear peer module statiistics counters
908 void
909 peer_clr_stats(void)
911 findpeer_calls = 0;
912 assocpeer_calls = 0;
913 peer_allocations = 0;
914 peer_demobilizations = 0;
915 peer_timereset = current_time;
919 * peer_reset - reset statistics counters
921 void
922 peer_reset(
923 struct peer *peer
926 if (peer == NULL)
927 return;
929 peer->timereset = current_time;
930 peer->sent = 0;
931 peer->received = 0;
932 peer->processed = 0;
933 peer->badauth = 0;
934 peer->bogusorg = 0;
935 peer->oldpkt = 0;
936 peer->seldisptoolarge = 0;
937 peer->selbroken = 0;
942 * peer_all_reset - reset all peer statistics counters
944 void
945 peer_all_reset(void)
947 struct peer *peer;
948 int hash;
950 for (hash = 0; hash < NTP_HASH_SIZE; hash++)
951 for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
952 peer_reset(peer);
957 * findmanycastpeer - find and return a manycast peer
959 struct peer *
960 findmanycastpeer(
961 struct recvbuf *rbufp /* receive buffer pointer */
964 register struct peer *peer;
965 struct pkt *pkt;
966 l_fp p_org;
967 int i;
970 * This routine is called upon arrival of a server-mode message
971 * from a manycast client. Search the peer list for a manycast
972 * client association where the last transmit timestamp matches
973 * the originate timestamp. This assumes the transmit timestamps
974 * for possibly more than one manycast association are unique.
976 pkt = &rbufp->recv_pkt;
977 for (i = 0; i < NTP_HASH_SIZE; i++) {
978 if (peer_hash_count[i] == 0)
979 continue;
981 for (peer = peer_hash[i]; peer != 0; peer =
982 peer->next) {
983 if (peer->cast_flags & MDF_ACAST) {
984 NTOHL_FP(&pkt->org, &p_org);
985 if (L_ISEQU(&p_org, &peer->aorg))
986 return (peer);
990 return (NULL);