2 * ntp_peer.c - management of data maintained for peer associations
12 #include "ntp_stdlib.h"
14 #include "openssl/rand.h"
18 * Table of valid association combinations
19 * ---------------------------------------
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
30 * CONTROL | e 0 0 0 0 0
31 * PRIVATE | e 0 0 0 0 0
32 * BCLIENT | e 0 0 0 e 1
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.
42 int AM[AM_MODES][AM_MODES] = {
43 /* { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */
45 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_ERR, AM_FXMIT, AM_MANYCAST, AM_NEWBCL},
47 /*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
49 /*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
51 /*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_POSSBCL},
53 /*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
55 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
57 /*CNTL*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
59 /*PRIV*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH},
61 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_ERR, AM_PROCPKT},
64 #define MATCH_ASSOC(x,y) AM[(x)][(y)]
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.
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 */
85 * Association ID. We initialize this value randomly, then assign a new
86 * value every time the peer structure is incremented.
88 static associd_t current_association_ID; /* association ID */
91 * Memory allocation watermarks.
93 #define INIT_PEER_ALLOC 15 /* initialize for 15 peers */
94 #define INC_PEER_ALLOC 5 /* when run out, add 5 more */
97 * Miscellaneous statistic counters which may be queried.
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 */
108 static void getmorepeermem P((void));
111 * init_peer - initialize peer data structures and counters
113 * N.B. We use the random number routine in here. It had better be
114 * initialized prior to getting here.
122 * Clear hash table and counters.
124 for (i = 0; i < HASH_SIZE; i++) {
126 peer_hash_count[i] = 0;
128 assoc_hash_count[i] = 0;
132 * Clear stat counters
134 findpeer_calls = peer_allocations = 0;
135 assocpeer_calls = peer_demobilizations = 0;
138 * Initialize peer memory.
141 for (i = 0; i < INIT_PEER_ALLOC; i++) {
142 init_peer_alloc[i].next = peer_free;
143 peer_free = &init_peer_alloc[i];
145 total_peer_structs = INIT_PEER_ALLOC;
146 peer_free_count = INIT_PEER_ALLOC;
149 * Initialize our first association ID
151 current_association_ID = (associd_t)ranp2(16);
152 if (current_association_ID == 0)
153 current_association_ID = 1;
158 * getmorepeermem - add more peer structures to the free list
164 register struct peer *peer;
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;
174 total_peer_structs += INC_PEER_ALLOC;
175 peer_free_count += INC_PEER_ALLOC;
180 * findexistingpeer - return a pointer to a peer in the hash table
184 struct sockaddr_storage *addr,
185 struct peer *start_peer,
189 register struct peer *peer;
192 * start_peer is included so we can locate instances of the
193 * same peer through different interfaces in the hash table.
196 peer = peer_hash[HASH_ADDR(addr)];
198 peer = start_peer->next;
201 if (SOCKCMP(addr, &peer->srcadr)
202 && NSRCPORT(addr) == NSRCPORT(&peer->srcadr)) {
205 else if (peer->hmode == mode)
215 * findpeer - find and return a peer in the hash table.
219 struct sockaddr_storage *srcadr,
220 struct interface *dstadr,
226 register struct peer *peer;
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)) {
236 * if the association matching rules determine
237 * that this is not a valid combination, then
238 * look for the next valid peer association.
240 *action = MATCH_ASSOC(peer->hmode, pkt_mode);
243 * Sigh! Check if BCLIENT peer in client
244 * server mode, else return error.
246 if ((*action == AM_POSSBCL) && !(peer->flags &
251 * if an error was returned, exit back right
254 if (*action == AM_ERR)
255 return ((struct peer *)0);
258 * if a match is found, we stop our search.
260 if (*action != AM_NOMATCH)
266 * If no matching association is found
269 *action = MATCH_ASSOC(NO_PEER, pkt_mode);
270 return ((struct peer *)0);
272 peer->dstadr = dstadr;
277 * findpeerbyassocid - find and return a peer using his association ID
284 register struct peer *peer;
289 hash = assoc & HASH_MASK;
290 for (peer = assoc_hash[hash]; peer != 0; peer =
292 if (assoc == peer->associd)
300 * clear_all - flush all time values for all associations
305 struct peer *peer, *next_peer;
309 * This routine is called when the clock is stepped, and so all
310 * previously saved time values are untrusted.
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");
326 printf("clear_all: at %lu\n", current_time);
332 * unpeer - remove peer structure from hash table and free structure
336 struct peer *peer_to_remove
341 char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
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);
350 printf("peer: %s\n", statstr);
356 printf("demobilize %u %d\n", peer_to_remove->associd,
359 peer_clear(peer_to_remove, "NULL");
360 hash = HASH_ADDR(&peer_to_remove->srcadr);
361 peer_hash_count[hash]--;
362 peer_demobilizations++;
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);
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;
374 register struct peer *peer;
376 peer = peer_hash[hash];
377 while (peer != 0 && peer->next != peer_to_remove)
381 peer_hash_count[hash]++;
382 msyslog(LOG_ERR, "peer struct for %s not in table!",
383 stoa(&peer->srcadr));
385 peer->next = peer_to_remove->next;
390 * Remove him from the association hash as well.
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;
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;
404 assoc_hash_count[hash]++;
406 "peer struct for %s not in association table!",
407 stoa(&peer->srcadr));
409 peer->ass_next = peer_to_remove->ass_next;
412 peer_to_remove->next = peer_free;
413 peer_free = peer_to_remove;
420 * peer_config - configure a new association
424 struct sockaddr_storage *srcadr,
425 struct interface *dstadr,
436 register struct peer *peer;
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
445 peer = findexistingpeer(srcadr, (struct peer *)0, hmode);
448 if (peer->dstadr == dstadr)
450 peer = findexistingpeer(srcadr, peer, hmode);
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.
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;
466 cast_flags = MDF_BCAST;
470 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
471 cast_flags = MDF_MCAST;
473 cast_flags = MDF_BCAST;
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;
482 cast_flags = MDF_UCAST;
486 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr))
487 cast_flags = MDF_ACAST;
489 cast_flags = MDF_UCAST;
494 cast_flags = MDF_UCAST;
498 * If the peer is already configured, some dope has a duplicate
499 * configureation entry or another dope is wiggling from afar.
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;
511 peer->precision = sys_precision;
512 peer_clear(peer, "RMOT");
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.
522 flags |= FLAG_IBURST;
523 peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll,
524 flags | FLAG_CONFIG, cast_flags, ttl, key);
530 * newpeer - initialize a new peer association
534 struct sockaddr_storage *srcadr,
535 struct interface *dstadr,
546 register struct peer *peer;
549 char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */
553 * Allocate a new peer structure. Some dirt here, since some of
554 * the initialization requires knowlege of our system state.
556 if (peer_free_count == 0)
559 peer_free = peer->next;
562 memset((char *)peer, 0, sizeof(struct peer));
565 * Assign an association ID and increment the system variable.
567 peer->associd = current_association_ID;
568 if (++current_association_ID == 0)
569 ++current_association_ID;
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.
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);
584 * If it was a multicast packet, findbcastinter() may not
585 * find it, so try a little harder.
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;
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);
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;
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");
614 peer_clear(peer, "INIT");
619 * Note time on statistics timers.
621 peer->timereset = current_time;
622 peer->timereachable = current_time;
623 peer->timereceived = current_time;
625 if (ISREFCLOCKADR(&peer->srcadr)) {
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
632 if (!refclock_newpeer(peer)) {
634 * Dump it, something screwed up
636 peer->next = peer_free;
645 * Put the new peer in the hash tables.
647 i = HASH_ADDR(&peer->srcadr);
648 peer->next = peer_hash[i];
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]++;
656 if (peer->flags & FLAG_SKEY) {
657 sprintf(statstr, "newpeer %d", peer->associd);
658 record_crypto_stats(&peer->srcadr, statstr);
661 printf("peer: %s\n", statstr);
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),
671 peer->hmode, peer->version, peer->minpoll,
672 peer->maxpoll, peer->flags, peer->cast_flags,
673 peer->ttl, peer->keyid);
680 * peer_unconfig - remove the configuration bit from a peer
684 struct sockaddr_storage *srcadr,
685 struct interface *dstadr,
689 register struct peer *peer;
693 peer = findexistingpeer(srcadr, (struct peer *)0, mode);
695 if (peer->flags & FLAG_CONFIG
696 && (dstadr == 0 || peer->dstadr == dstadr)) {
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.
708 if (peer->hmode == MODE_ACTIVE
709 && peer->pmode == MODE_ACTIVE) {
710 peer->hmode = MODE_PASSIVE;
711 peer->flags &= ~FLAG_CONFIG;
717 peer = findexistingpeer(srcadr, peer, mode);
723 * peer_clr_stats - clear peer module stat counters
730 peer_allocations = 0;
731 peer_demobilizations = 0;
732 peer_timereset = current_time;
736 * peer_reset - reset stat counters in a peer structure
751 peer->seldisptoolarge = 0;
754 peer->timereset = current_time;
759 * peer_all_reset - reset all peer stat counters
767 for (hash = 0; hash < HASH_SIZE; hash++)
768 for (peer = peer_hash[hash]; peer != 0; peer = peer->next)
775 * expire_all - flush all crypto data and update timestamps.
780 struct peer *peer, *next_peer;
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
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)) {
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) {
803 peer->crypto &= ~(CRYPTO_FLAG_AUTO |
809 RAND_bytes((u_char *)&sys_private, 4);
817 * findmanycastpeer - find and return a manycast peer
821 struct recvbuf *rbufp
824 register struct peer *peer;
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.
836 pkt = &rbufp->recv_pkt;
837 for (i = 0; i < HASH_SIZE; i++) {
838 if (peer_hash_count[i] == 0)
841 for (peer = peer_hash[i]; peer != 0; peer =
843 if (peer->cast_flags & MDF_ACAST) {
844 NTOHL_FP(&pkt->org, &p_org);
845 if (L_ISEQU(&peer->xmt, &p_org))
855 * resetmanycast - reset all manycast clients
860 register struct peer *peer;
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.
868 for (i = 0; i < HASH_SIZE; i++) {
869 if (peer_hash_count[i] == 0)
872 for (peer = peer_hash[i]; peer != 0; peer =
874 if (peer->cast_flags & MDF_ACAST) {
876 poll_update(peer, 0);