1 /*        $NetBSD: ntp_peer.c,v 1.14 2024/08/18 20:47:17 christos Exp $         */
2 
3 /*
4  * ntp_peer.c - management of data maintained for peer associations
5  */
6 #ifdef HAVE_CONFIG_H
7 #include <config.h>
8 #endif
9 
10 #include <stdio.h>
11 #include <sys/types.h>
12 
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 
19 /*
20  *                      Table of valid association combinations
21  *                      ---------------------------------------
22  *
23  *                             packet->mode
24  * peer->mode      | UNSPEC  ACTIVE PASSIVE  CLIENT  SERVER  BCAST
25  * ----------      | ---------------------------------------------
26  * NO_PEER         |   e       1       0       1       1       1
27  * ACTIVE          |   e       1       1       0       0       0
28  * PASSIVE         |   e       1       e       0       0       0
29  * CLIENT          |   e       0       0       0       1       0
30  * SERVER          |   e       0       0       0       0       0
31  * BCAST           |   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 #define AM_MODES    7         /* number of rows and columns */
42 #define NO_PEER               0         /* action when no peer is found */
43 
44 const s_char AM[AM_MODES][AM_MODES] = {
45 /*                            packet->mode                                                    */
46 /* peer { UNSPEC,   ACTIVE,     PASSIVE,    CLIENT,     SERVER,     BCAST } */
47 /* mode */
48 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT,   AM_MANYCAST, AM_NEWBCL},
49 
50 /*A*/     { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
51 
52 /*P*/     { AM_ERR, AM_PROCPKT, AM_ERR,     AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
53 
54 /*C*/     { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT,  AM_NOMATCH},
55 
56 /*S*/     { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
57 
58 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_NOMATCH},
59 
60 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH,  AM_PROCPKT},
61 };
62 
63 #define MATCH_ASSOC(x, y) (AM[CLAMP((x), 0, AM_MODES)][CLAMP((y), 0, AM_MODES)])
64 
65 /*
66  * These routines manage the allocation of memory to peer structures
67  * and the maintenance of three data structures involving all peers:
68  *
69  * - peer_list is a single list with all peers, suitable for scanning
70  *   operations over all peers.
71  * - peer_adr_hash is an array of lists indexed by hashed peer address.
72  * - peer_aid_hash is an array of lists indexed by hashed associd.
73  *
74  * They also maintain a free list of peer structures, peer_free.
75  *
76  * The three main entry points are findpeer(), which looks for matching
77  * peer structures in the peer list, newpeer(), which allocates a new
78  * peer structure and adds it to the list, and unpeer(), which
79  * demobilizes the association and deallocates the structure.
80  */
81 /*
82  * Peer hash tables
83  */
84 struct peer *peer_hash[NTP_HASH_SIZE];  /* peer hash table */
85 int       peer_hash_count[NTP_HASH_SIZE];         /* peers in each bucket */
86 struct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */
87 int       assoc_hash_count[NTP_HASH_SIZE];/* peers in each bucket */
88 struct peer *peer_list;                           /* peer structures list */
89 static struct peer *peer_free;                    /* peer structures free list */
90 int       peer_free_count;              /* count of free structures */
91 
92 /*
93  * Association ID.  We initialize this value randomly, then assign a new
94  * value every time an association is mobilized.
95  */
96 static associd_t current_association_ID; /* actually next poss. ID */
97 static associd_t initial_association_ID;
98 
99 /*
100  * Memory allocation watermarks.
101  */
102 #define   INIT_PEER_ALLOC               8         /* static preallocation */
103 #define   INC_PEER_ALLOC                4         /* add N more when empty */
104 
105 /*
106  * Miscellaneous statistic counters which may be queried.
107  */
108 u_long    peer_timereset;                         /* time stat counters zeroed */
109 u_long    findpeer_calls;                         /* calls to findpeer */
110 u_long    assocpeer_calls;              /* calls to findpeerbyassoc */
111 u_long    peer_allocations;             /* allocations from free list */
112 u_long    peer_demobilizations;                   /* structs freed to free list */
113 int       total_peer_structs;           /* peer structs */
114 int       peer_associations;            /* mobilized associations */
115 int       peer_preempt;                           /* preemptable associations */
116 static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */
117 
118 static struct peer *          findexistingpeer_name(const char *, u_short,
119                                                         struct peer *, int);
120 static struct peer *          findexistingpeer_addr(sockaddr_u *,
121                                                         struct peer *, int,
122                                                         u_char, int *);
123 static void                   free_peer(struct peer *, int);
124 static void                   getmorepeermem(void);
125 static int                    score(struct peer *);
126 
127 
128 /*
129  * init_peer - initialize peer data structures and counters
130  *
131  * N.B. We use the random number routine in here. It had better be
132  * initialized prior to getting here.
133  */
134 void
init_peer(void)135 init_peer(void)
136 {
137           int i;
138 
139           /*
140            * Initialize peer free list from static allocation.
141            */
142           for (i = COUNTOF(init_peer_alloc) - 1; i >= 0; i--)
143                     LINK_SLIST(peer_free, &init_peer_alloc[i], p_link);
144           total_peer_structs = COUNTOF(init_peer_alloc);
145           peer_free_count = COUNTOF(init_peer_alloc);
146 
147           /*
148            * Initialize our first association ID
149            */
150           do
151                     current_association_ID = ntp_random() & ASSOCID_MAX;
152           while (!current_association_ID);
153           initial_association_ID = current_association_ID;
154 }
155 
156 
157 /*
158  * getmorepeermem - add more peer structures to the free list
159  */
160 static void
getmorepeermem(void)161 getmorepeermem(void)
162 {
163           int i;
164           struct peer *peers;
165 
166           peers = eallocarray(INC_PEER_ALLOC, sizeof(*peers));
167 
168           for (i = INC_PEER_ALLOC - 1; i >= 0; i--)
169                     LINK_SLIST(peer_free, &peers[i], p_link);
170 
171           total_peer_structs += INC_PEER_ALLOC;
172           peer_free_count += INC_PEER_ALLOC;
173 }
174 
175 
176 static struct peer *
findexistingpeer_name(const char * hostname,u_short hname_fam,struct peer * start_peer,int mode)177 findexistingpeer_name(
178           const char *        hostname,
179           u_short             hname_fam,
180           struct peer *       start_peer,
181           int                 mode
182           )
183 {
184           struct peer *p;
185 
186           if (NULL == start_peer)
187                     p = peer_list;
188           else
189                     p = start_peer->p_link;
190           for (; p != NULL; p = p->p_link)
191                     if (p->hostname != NULL
192                         && (-1 == mode || p->hmode == mode)
193                         && (AF_UNSPEC == hname_fam
194                               || AF_UNSPEC == AF(&p->srcadr)
195                               || hname_fam == AF(&p->srcadr))
196                         && !strcasecmp(p->hostname, hostname))
197                               break;
198           return p;
199 }
200 
201 
202 static
203 struct peer *
findexistingpeer_addr(sockaddr_u * addr,struct peer * start_peer,int mode,u_char cast_flags,int * ip_count)204 findexistingpeer_addr(
205           sockaddr_u *        addr,
206           struct peer *       start_peer,
207           int                 mode,
208           u_char              cast_flags,
209           int *               ip_count
210           )
211 {
212           struct peer *peer;
213 
214           DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x, %p)\n",
215                     sptoa(addr),
216                     (start_peer)
217                         ? sptoa(&start_peer->srcadr)
218                         : "NULL",
219                     mode, (u_int)cast_flags, ip_count));
220 
221           /*
222            * start_peer is included so we can locate instances of the
223            * same peer through different interfaces in the hash table.
224            * Without MDF_BCLNT, a match requires the same mode and remote
225            * address.  MDF_BCLNT associations start out as MODE_CLIENT
226            * if broadcastdelay is not specified, and switch to
227            * MODE_BCLIENT after estimating the one-way delay.  Duplicate
228            * associations are expanded in definition to match any other
229            * MDF_BCLNT with the same srcadr (remote, unicast address).
230            */
231           if (NULL == start_peer)
232                     peer = peer_hash[NTP_HASH_ADDR(addr)];
233           else
234                     peer = start_peer->adr_link;
235 
236           while (peer != NULL) {
237                     DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr),
238                               sptoa(&peer->srcadr), mode, peer->hmode,
239                               (u_int)cast_flags, (u_int)peer->cast_flags));
240                     if (ip_count) {
241                               if (SOCK_EQ(addr, &peer->srcadr)) {
242                                         (*ip_count)++;
243                               }
244                     }
245                     if ((-1 == mode || peer->hmode == mode ||
246                          ((MDF_BCLNT & peer->cast_flags) &&
247                           (MDF_BCLNT & cast_flags))) &&
248                         ADDR_PORT_EQ(addr, &peer->srcadr)) {
249                               DPRINTF(3, ("found.\n"));
250                               break;
251                     }
252                     DPRINTF(3, ("\n"));
253                     peer = peer->adr_link;
254           }
255 
256           return peer;
257 }
258 
259 
260 /*
261  * findexistingpeer - search by name+family or address.
262  */
263 struct peer *
findexistingpeer(sockaddr_u * addr,const char * hostname,struct peer * start_peer,int mode,u_char cast_flags,int * ip_count)264 findexistingpeer(
265           sockaddr_u *        addr,
266           const char *        hostname,
267           struct peer *       start_peer,
268           int                 mode,
269           u_char              cast_flags,
270           int *               ip_count
271           )
272 {
273           if (hostname != NULL)
274                     return findexistingpeer_name(hostname, AF(addr),
275                                                        start_peer, mode);
276           else
277                     return findexistingpeer_addr(addr, start_peer, mode,
278                                                        cast_flags, ip_count);
279 }
280 
281 
282 /*
283  * findpeer - find and return a peer match for a received datagram in
284  *              the peer_hash table.
285  *
286  * [Bug 3072] To faciliate a faster reorganisation after routing changes
287  * the original code re-assigned the peer address to be the destination
288  * of the received packet and initiated another round on a mismatch.
289  * Unfortunately this leaves us wide open for a DoS attack where the
290  * attacker directs a packet with forged destination address to us --
291  * this results in a wrong interface assignment, actually creating a DoS
292  * situation.
293  *
294  * This condition would persist until the next update of the interface
295  * list, but a continued attack would put us out of business again soon
296  * enough. Authentication alone does not help here, since it does not
297  * protect the UDP layer and leaves us open for a replay attack.
298  *
299  * So we do not update the addresses and wait until the next interface
300  * list update does the right thing for us.
301  */
302 struct peer *
findpeer(struct recvbuf * rbufp,int pkt_mode,int * action)303 findpeer(
304           struct recvbuf *rbufp,
305           int                 pkt_mode,
306           int *               action
307           )
308 {
309           struct peer *       p;
310           sockaddr_u *        srcadr;
311           u_int               hash;
312           struct pkt *        pkt;
313           l_fp                pkt_org;
314 
315           findpeer_calls++;
316           srcadr = &rbufp->recv_srcadr;
317           hash = NTP_HASH_ADDR(srcadr);
318           for (p = peer_hash[hash]; p != NULL; p = p->adr_link) {
319 
320                     /* [Bug 3072] ensure interface of peer matches */
321                     /* [Bug 3356] ... if NOT a broadcast peer!     */
322                     if (p->hmode != MODE_BCLIENT && p->dstadr != rbufp->dstadr)
323                               continue;
324 
325                     /* ensure peer source address matches */
326                     if ( ! ADDR_PORT_EQ(srcadr, &p->srcadr))
327                               continue;
328 
329                     /* If the association matching rules determine that this
330                      * is not a valid combination, then look for the next
331                      * valid peer association.
332                      */
333                     *action = MATCH_ASSOC(p->hmode, pkt_mode);
334 
335                     /* A response to our manycastclient solicitation might
336                      * be misassociated with an ephemeral peer already spun
337                      * for the server.  If the packet's org timestamp
338                      * doesn't match the peer's, check if it matches the
339                      * ACST prototype peer's.  If so it is a redundant
340                      * solicitation response, return AM_ERR to discard it.
341                      * [Bug 1762]
342                      */
343                     if (MODE_SERVER == pkt_mode && AM_PROCPKT == *action) {
344                               pkt = &rbufp->recv_pkt;
345                               NTOHL_FP(&pkt->org, &pkt_org);
346                               if (!L_ISEQU(&p->aorg, &pkt_org) &&
347                                   findmanycastpeer(rbufp))
348                                         *action = AM_ERR;
349                     }
350 
351                     /* if an error was returned, exit back right here. */
352                     if (*action == AM_ERR) {
353                               return NULL;
354                     }
355 
356                     /* if a match is found, we stop our search. */
357                     if (*action != AM_NOMATCH) {
358                               break;
359                     }
360           }
361 
362           /* If no matching association is found... */
363           if (NULL == p) {
364                     *action = MATCH_ASSOC(NO_PEER, pkt_mode);
365           }
366           return p;
367 }
368 
369 /*
370  * findpeerbyassoc - find and return a peer using his association ID
371  */
372 struct peer *
findpeerbyassoc(associd_t assoc)373 findpeerbyassoc(
374           associd_t assoc
375           )
376 {
377           struct peer *p;
378           u_int hash;
379 
380           assocpeer_calls++;
381           hash = assoc & NTP_HASH_MASK;
382           for (p = assoc_hash[hash]; p != NULL; p = p->aid_link)
383                     if (assoc == p->associd)
384                               break;
385           return p;
386 }
387 
388 
389 /*
390  * clear_all - flush all time values for all associations
391  */
392 void
clear_all(void)393 clear_all(void)
394 {
395           struct peer *p;
396 
397           /*
398            * This routine is called when the clock is stepped, and so all
399            * previously saved time values are untrusted.
400            */
401           for (p = peer_list; p != NULL; p = p->p_link)
402                     if (!(MDF_TXONLY_MASK & p->cast_flags))
403                               peer_clear(p, "STEP");
404 
405           DPRINTF(1, ("clear_all: at %lu\n", current_time));
406 }
407 
408 
409 /*
410  * score_all() - determine if an association can be demobilized
411  */
412 int
score_all(struct peer * peer)413 score_all(
414           struct peer *peer   /* peer structure pointer */
415           )
416 {
417           struct peer *speer;
418           int       temp, tamp;
419           int       x;
420 
421           /*
422            * This routine finds the minimum score for all preemptible
423            * associations and returns > 0 if the association can be
424            * demobilized.
425            */
426           tamp = score(peer);
427           temp = 100;
428           for (speer = peer_list; speer != NULL; speer = speer->p_link)
429                     if (speer->flags & FLAG_PREEMPT) {
430                               x = score(speer);
431                               if (x < temp)
432                                         temp = x;
433                     }
434           DPRINTF(1, ("score_all: at %lu score %d min %d\n",
435                         current_time, tamp, temp));
436 
437           if (tamp != temp)
438                     temp = 0;
439 
440           return temp;
441 }
442 
443 
444 /*
445  * score() - calculate preemption score
446  */
447 static int
score(struct peer * peer)448 score(
449           struct peer *peer   /* peer structure pointer */
450           )
451 {
452           int       temp;
453 
454           /*
455            * This routine calculates the premption score from the peer
456            * error bits and status. Increasing values are more cherished.
457            */
458           temp = 0;
459           if (!(peer->flash & TEST10))
460                     temp++;                       /* 1 good synch and stratum */
461           if (!(peer->flash & TEST13))
462                     temp++;                       /* 2 reachable */
463           if (!(peer->flash & TEST12))
464                     temp++;                       /* 3 no loop */
465           if (!(peer->flash & TEST11))
466                     temp++;                       /* 4 good distance */
467           if (peer->status >= CTL_PST_SEL_SELCAND)
468                     temp++;                       /* 5 in the hunt */
469           if (peer->status != CTL_PST_SEL_EXCESS)
470                     temp++;                       /* 6 not spare tire */
471           return (temp);                          /* selection status */
472 }
473 
474 
475 /*
476  * free_peer - internal routine to free memory referred to by a struct
477  *               peer and return it to the peer free list.  If unlink is
478  *               nonzero, unlink from the various lists.
479  */
480 static void
free_peer(struct peer * p,int unlink_peer)481 free_peer(
482           struct peer *       p,
483           int                 unlink_peer
484           )
485 {
486           struct peer *       unlinked;
487           int                 hash;
488 
489           if (unlink_peer) {
490                     hash = NTP_HASH_ADDR(&p->srcadr);
491                     peer_hash_count[hash]--;
492 
493                     UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link,
494                                    struct peer);
495                     if (NULL == unlinked) {
496                               peer_hash_count[hash]++;
497                               msyslog(LOG_ERR, "peer %s not in address table!",
498                                         stoa(&p->srcadr));
499                     }
500 
501                     /*
502                      * Remove him from the association hash as well.
503                      */
504                     hash = p->associd & NTP_HASH_MASK;
505                     assoc_hash_count[hash]--;
506 
507                     UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link,
508                                    struct peer);
509                     if (NULL == unlinked) {
510                               assoc_hash_count[hash]++;
511                               msyslog(LOG_ERR,
512                                         "peer %s not in association ID table!",
513                                         stoa(&p->srcadr));
514                     }
515 
516                     /* Remove him from the overall list. */
517                     UNLINK_SLIST(unlinked, peer_list, p, p_link,
518                                    struct peer);
519                     if (NULL == unlinked)
520                               msyslog(LOG_ERR, "%s not in peer list!",
521                                         stoa(&p->srcadr));
522           }
523 
524           if (p->hostname != NULL)
525                     free(p->hostname);
526 
527           if (p->ident != NULL)
528                     free(p->ident);
529 
530           if (p->addrs != NULL)
531                     free(p->addrs);               /* from copy_addrinfo_list() */
532 
533           /* Add his corporeal form to peer free list */
534           ZERO(*p);
535           LINK_SLIST(peer_free, p, p_link);
536           peer_free_count++;
537 }
538 
539 
540 /*
541  * unpeer - remove peer structure from hash table and free structure
542  */
543 void
unpeer(struct peer * peer)544 unpeer(
545           struct peer *peer
546           )
547 {
548           mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd);
549           restrict_source(&peer->srcadr, TRUE, 0);
550           peer->flags |= FLAG_DISABLED;
551           set_peerdstadr(peer, NULL);
552           peer_demobilizations++;
553           peer_associations--;
554           if (FLAG_PREEMPT & peer->flags)
555                     peer_preempt--;
556 #ifdef REFCLOCK
557           /*
558            * If this peer is actually a clock, shut it down first
559            */
560           if (FLAG_REFCLOCK & peer->flags)
561                     refclock_unpeer(peer);
562 #endif
563 
564           free_peer(peer, TRUE);
565 }
566 
567 
568 /*
569  * peer_config - configure a new association
570  */
571 struct peer *
peer_config(sockaddr_u * srcadr,const char * hostname,endpt * dstadr,int ippeerlimit,u_char hmode,u_char version,u_char minpoll,u_char maxpoll,u_int flags,u_int32 ttl,keyid_t key,const char * ident)572 peer_config(
573           sockaddr_u *        srcadr,
574           const char *        hostname,
575           endpt *             dstadr,
576           int                 ippeerlimit,
577           u_char              hmode,
578           u_char              version,
579           u_char              minpoll,
580           u_char              maxpoll,
581           u_int               flags,
582           u_int32             ttl,
583           keyid_t             key,
584           const char *        ident               /* autokey group */
585           )
586 {
587           u_char cast_flags;
588 
589           /*
590            * We do a dirty little jig to figure the cast flags. This is
591            * probably not the best place to do this, at least until the
592            * configure code is rebuilt. Note only one flag can be set.
593            */
594           switch (hmode) {
595           case MODE_BROADCAST:
596                     if (IS_MCAST(srcadr))
597                               cast_flags = MDF_MCAST;
598                     else
599                               cast_flags = MDF_BCAST;
600                     break;
601 
602           case MODE_CLIENT:
603                     if (hostname != NULL && SOCK_UNSPEC(srcadr))
604                               cast_flags = MDF_POOL;
605                     else if (IS_MCAST(srcadr))
606                               cast_flags = MDF_ACAST;
607                     else
608                               cast_flags = MDF_UCAST;
609                     break;
610 
611           default:
612                     cast_flags = MDF_UCAST;
613           }
614 
615           /*
616            * Mobilize the association and initialize its variables. If
617            * emulating ntpdate, force iburst.  For pool and manycastclient
618            * strip FLAG_PREEMPT as the prototype associations are not
619            * themselves preemptible, though the resulting associations
620            * are.
621            */
622           flags |= FLAG_CONFIG;
623           if (mode_ntpdate)
624                     flags |= FLAG_IBURST;
625           if ((MDF_ACAST | MDF_POOL) & cast_flags)
626                     flags &= ~FLAG_PREEMPT;
627           return newpeer(srcadr, hostname, dstadr, ippeerlimit, hmode, version,
628               minpoll, maxpoll, flags, cast_flags, ttl, key, ident);
629 }
630 
631 /*
632  * setup peer dstadr field keeping it in sync with the interface
633  * structures
634  */
635 void
set_peerdstadr(struct peer * p,endpt * dstadr)636 set_peerdstadr(
637           struct peer *       p,
638           endpt *             dstadr
639           )
640 {
641           struct peer *       unlinked;
642 
643           DEBUG_INSIST(p != NULL);
644 
645           if (p == NULL)
646                     return;
647 
648           /* check for impossible or identical assignment */
649           if (p->dstadr == dstadr)
650                     return;
651 
652           /*
653            * Do not change the local address of a link-local
654            * peer address.
655            */
656           if (   p->dstadr != NULL && is_linklocal(&p->dstadr->sin)
657               && dstadr != NULL) {
658                     return;
659           }
660 
661           /*
662            * Do not set the local address for a link-local IPv6 peer
663            * to one with a different scope ID.
664            */
665           if (   dstadr != NULL && IS_IPV6(&p->srcadr)
666               && SCOPE(&dstadr->sin) != SCOPE(&p->srcadr)) {
667                     return;
668           }
669 
670           /*
671            * Don't accept updates to a separate multicast receive-only
672            * endpt while a BCLNT peer is running its unicast protocol.
673            */
674           if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
675               (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
676                     return;
677           }
678 
679           /* unlink from list if we have an address prior to assignment */
680           if (p->dstadr != NULL) {
681                     p->dstadr->peercnt--;
682                     UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
683                                    struct peer);
684           }
685           if (   !IS_MCAST(&p->srcadr) && !(FLAG_DISABLED & p->flags)
686               && !initializing) {
687                     msyslog(LOG_INFO, "%s local addr %s -> %s",
688                               stoa(&p->srcadr), eptoa(p->dstadr),
689                               eptoa(dstadr));
690           }
691 
692           p->dstadr = dstadr;
693 
694           /* link to list if we have an address after assignment */
695           if (p->dstadr != NULL) {
696                     LINK_SLIST(dstadr->peers, p, ilink);
697                     dstadr->peercnt++;
698           }
699 }
700 
701 /*
702  * attempt to re-rebind interface if necessary
703  */
704 static void
peer_refresh_interface(struct peer * p)705 peer_refresh_interface(
706           struct peer *p
707           )
708 {
709           endpt *   niface;
710           endpt *   piface;
711 
712           niface = select_peerinterface(p, &p->srcadr, NULL);
713 
714           DPRINTF(4, (
715               "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %u key %08x: new interface: ",
716               p->dstadr == NULL ? "<null>" :
717               stoa(&p->dstadr->sin), stoa(&p->srcadr), p->hmode,
718               p->version, p->minpoll, p->maxpoll, p->flags, p->cast_flags,
719               p->ttl, p->keyid));
720           if (niface != NULL) {
721                     DPRINTF(4, (
722                         "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s",
723                         niface->fd,  niface->bfd, niface->name,
724                         niface->flags, niface->ifindex,
725                         stoa(&niface->sin)));
726                     if (niface->flags & INT_BROADCAST)
727                               DPRINTF(4, (", bcast=%s",
728                                         stoa(&niface->bcast)));
729                     DPRINTF(4, (", mask=%s\n", stoa(&niface->mask)));
730           } else {
731                     DPRINTF(4, ("<NONE>\n"));
732           }
733 
734           piface = p->dstadr;
735           set_peerdstadr(p, niface);
736           if (p->dstadr != NULL) {
737                     /*
738                      * clear crypto if we change the local address
739                      */
740                     if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags)
741                         && MODE_BROADCAST != p->pmode)
742                               peer_clear(p, "XFAC");
743 
744                     /*
745                      * Broadcast needs the socket enabled for broadcast
746                      */
747                     if (MDF_BCAST & p->cast_flags)
748                               enable_broadcast(p->dstadr, &p->srcadr);
749 
750                     /*
751                      * Multicast needs the socket interface enabled for
752                      * multicast
753                      */
754                     if (MDF_MCAST & p->cast_flags)
755                               enable_multicast_if(p->dstadr, &p->srcadr);
756           }
757 }
758 
759 
760 /*
761  * refresh_all_peerinterfaces - see that all interface bindings are up
762  * to date
763  */
764 void
refresh_all_peerinterfaces(void)765 refresh_all_peerinterfaces(void)
766 {
767           struct peer *p;
768 
769           /*
770            * This is called when the interface list has changed.
771            * Give peers a chance to find a better interface.
772            */
773           for (p = peer_list; p != NULL; p = p->p_link) {
774                     /*
775                      * Bug 2849 XOR 2043
776                      * Change local address only if the peer doesn't
777                      * have a local address already or if the one
778                      * they have hasn't worked for a while.
779                      */
780                     if (p->dstadr != NULL && (p->reach & 0x3)) {
781                               continue;
782                     }
783                     peer_refresh_interface(p);
784           }
785 }
786 
787 
788 /*
789  * newpeer - initialize a new peer association
790  */
791 struct peer *
newpeer(sockaddr_u * srcadr,const char * hostname,endpt * dstadr,int ippeerlimit,u_char hmode,u_char version,u_char minpoll,u_char maxpoll,u_int flags,u_char cast_flags,u_int32 ttl,keyid_t key,const char * ident)792 newpeer(
793           sockaddr_u *        srcadr,
794           const char *        hostname,
795           endpt *             dstadr,
796           int                 ippeerlimit,
797           u_char              hmode,
798           u_char              version,
799           u_char              minpoll,
800           u_char              maxpoll,
801           u_int               flags,
802           u_char              cast_flags,
803           u_int32             ttl,
804           keyid_t             key,
805           const char *        ident
806           )
807 {
808           struct peer *       peer;
809           u_int               hash;
810           int                 ip_count = 0;
811 
812           DEBUG_REQUIRE(srcadr);
813 
814 #ifdef AUTOKEY
815           /*
816            * If Autokey is requested but not configured, complain loudly.
817            */
818           if (!crypto_flags) {
819                     if (key > NTP_MAXKEY) {
820                               return (NULL);
821 
822                     } else if (flags & FLAG_SKEY) {
823                               msyslog(LOG_ERR, "Rejecting Autokey with %s,"
824                                                    " built without support.",
825                                                    stoa(srcadr));
826                               return (NULL);
827                     }
828           }
829 #endif    /* AUTOKEY */
830 
831           /*
832            * For now only pool associations have a hostname.
833            */
834           INSIST(NULL == hostname || (MDF_POOL & cast_flags));
835 
836           /*
837            * First search from the beginning for an association with given
838            * remote address and mode. If an interface is given, search
839            * from there to find the association which matches that
840            * destination. If the given interface is "any", track down the
841            * actual interface, because that's what gets put into the peer
842            * structure.
843            */
844           if (dstadr != NULL) {
845                     peer = findexistingpeer(srcadr, hostname, NULL, hmode,
846                                                   cast_flags, &ip_count);
847                     while (peer != NULL) {
848                               if (   peer->dstadr == dstadr
849                                   || (   (MDF_BCLNT & cast_flags)
850                                         && (MDF_BCLNT & peer->cast_flags)))
851                                         break;
852 
853                               if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
854                                   peer->dstadr == findinterface(srcadr))
855                                         break;
856 
857                               peer = findexistingpeer(srcadr, hostname, peer,
858                                                             hmode, cast_flags, &ip_count);
859                     }
860           } else {
861                     /* no endpt address given */
862                     peer = findexistingpeer(srcadr, hostname, NULL, hmode,
863                                                   cast_flags, &ip_count);
864           }
865 
866           /*
867            * In any case, do not create an association with a duplicate
868            * remote address (srcadr) except for undefined (zero) address.
869            * Arguably this should be part of the logic above but
870            * [Bug 3888] exposed a situation with manycastclient where
871            * duplicate associations happened.
872            */
873           if (NULL == peer) {
874                     for (peer = peer_list;
875                          peer != NULL;
876                          peer = peer->p_link) {
877                               if (   SOCK_EQ(srcadr, &peer->srcadr)
878                                   && !SOCK_UNSPEC(srcadr)
879                                   && !SOCK_UNSPEC(&peer->srcadr)) {
880                                         /* leave peer non-NULL */
881                                         break;
882                               }
883                     }
884           }
885 
886           /*
887            * If a peer is found, this would be a duplicate and we don't
888            * allow that. This avoids duplicate ephemeral (broadcast/
889            * multicast) and preemptible (manycast and pool) client
890            * associations.
891            */
892           if (peer != NULL) {
893                     DPRINTF(2, ("%s(%s) found existing association\n",
894                               __func__,
895                               (hostname)
896                                   ? hostname
897                                   : stoa(srcadr)));
898                     return NULL;
899           }
900 
901 #if 0
902           DPRINTF(1, ("newpeer(%s) found no existing and %d other associations\n",
903                     (hostname)
904                         ? hostname
905                         : stoa(srcadr),
906                     ip_count));
907 #endif
908 
909           /* Check ippeerlimit wrt ip_count */
910           if (ippeerlimit > -1) {
911                     if (ip_count + 1 > ippeerlimit) {
912                               DPRINTF(2, ("newpeer(%s) denied - ippeerlimit %d\n",
913                                         (hostname)
914                                             ? hostname
915                                             : stoa(srcadr),
916                                         ippeerlimit));
917                               return NULL;
918                     }
919           } else {
920                     DPRINTF(1, ("newpeer(%s) - ippeerlimit %d ignored\n",
921                               (hostname)
922                                   ? hostname
923                                   : stoa(srcadr),
924                               ippeerlimit));
925           }
926 
927           /*
928            * Allocate a new peer structure. Some dirt here, since some of
929            * the initialization requires knowlege of our system state.
930            */
931           if (peer_free_count == 0)
932                     getmorepeermem();
933           UNLINK_HEAD_SLIST(peer, peer_free, p_link);
934           INSIST(peer != NULL);
935           peer_free_count--;
936           peer_associations++;
937           if (FLAG_PREEMPT & flags)
938                     peer_preempt++;
939 
940           /*
941            * Assign an available association ID.  Zero is reserved.
942            */
943           do {
944                     while (0 == ++current_association_ID) {
945                               /* EMPTY */
946                     }
947           } while (NULL != findpeerbyassoc(current_association_ID));
948           peer->associd = current_association_ID;
949 
950           peer->srcadr = *srcadr;
951           if (hostname != NULL) {
952                     peer->hostname = estrdup(hostname);
953           }
954           peer->hmode = hmode;
955           peer->version = version;
956           peer->flags = flags;
957           peer->cast_flags = cast_flags;
958           set_peerdstadr(peer,
959                            select_peerinterface(peer, srcadr, dstadr));
960 
961           /*
962            * Zero for minpoll or maxpoll means use defaults.
963            */
964           peer->maxpoll = (0 == maxpoll)
965                                   ? NTP_MAXDPOLL
966                                   : maxpoll;
967           peer->minpoll = (0 == minpoll)
968                                   ? NTP_MINDPOLL
969                                   : minpoll;
970 
971           /*
972            * Clamp maxpoll and minpoll within NTP_MINPOLL and NTP_MAXPOLL,
973            * and further clamp minpoll less than or equal maxpoll.
974            */
975           peer->maxpoll = CLAMP(peer->maxpoll, NTP_MINPOLL, NTP_MAXPOLL);
976           peer->minpoll = CLAMP(peer->minpoll, NTP_MINPOLL, peer->maxpoll);
977 
978           if (peer->dstadr != NULL) {
979                     DPRINTF(3, ("newpeer(%s): using fd %d and our addr %s\n",
980                               stoa(srcadr), peer->dstadr->fd,
981                               stoa(&peer->dstadr->sin)));
982           } else {
983                     DPRINTF(3, ("newpeer(%s): local addr unavailable\n",
984                               stoa(srcadr)));
985           }
986           /*
987            * Broadcast needs the socket enabled for broadcast
988            */
989           if ((MDF_BCAST & cast_flags) && peer->dstadr != NULL) {
990                     enable_broadcast(peer->dstadr, srcadr);
991           }
992           /*
993            * Multicast needs the socket interface enabled for multicast
994            */
995           if ((MDF_MCAST & cast_flags) && peer->dstadr != NULL) {
996                     enable_multicast_if(peer->dstadr, srcadr);
997           }
998 #ifdef AUTOKEY
999           if (key > NTP_MAXKEY)
1000                     peer->flags |= FLAG_SKEY;
1001 #endif    /* AUTOKEY */
1002           peer->ttl = ttl;
1003           peer->keyid = key;
1004           if (ident != NULL) {
1005                     peer->ident = estrdup(ident);
1006           }
1007           peer->precision = sys_precision;
1008           peer->hpoll = peer->minpoll;
1009           if (cast_flags & MDF_ACAST) {
1010                     peer_clear(peer, "ACST");
1011           } else if (cast_flags & MDF_POOL) {
1012                     peer_clear(peer, "POOL");
1013           } else if (cast_flags & MDF_MCAST) {
1014                     peer_clear(peer, "MCST");
1015           } else if (cast_flags & MDF_BCAST) {
1016                     peer_clear(peer, "BCST");
1017           } else {
1018                     peer_clear(peer, "INIT");
1019           }
1020           if (mode_ntpdate) {
1021                     peer_ntpdate++;
1022           }
1023           /*
1024            * Note time on statistics timers.
1025            */
1026           peer->timereset = current_time;
1027           peer->timereachable = current_time;
1028           peer->timereceived = current_time;
1029 
1030           if (ISREFCLOCKADR(&peer->srcadr)) {
1031 #ifdef REFCLOCK
1032                     /*
1033                      * We let the reference clock support do clock
1034                      * dependent initialization.  This includes setting
1035                      * the peer timer, since the clock may have requirements
1036                      * for this.
1037                      */
1038                     if (!refclock_newpeer(peer)) {
1039                               /*
1040                                * Dump it, something screwed up
1041                                */
1042                               set_peerdstadr(peer, NULL);
1043                               free_peer(peer, 0);
1044                               return NULL;
1045                     }
1046 #else /* REFCLOCK */
1047                     msyslog(LOG_ERR, "refclock %s isn't supported. ntpd was compiled without refclock support.",
1048                               stoa(&peer->srcadr));
1049                     set_peerdstadr(peer, NULL);
1050                     free_peer(peer, 0);
1051                     return NULL;
1052 #endif /* REFCLOCK */
1053           }
1054 
1055           /*
1056            * Put the new peer in the hash tables.
1057            */
1058           hash = NTP_HASH_ADDR(&peer->srcadr);
1059           LINK_SLIST(peer_hash[hash], peer, adr_link);
1060           peer_hash_count[hash]++;
1061           hash = peer->associd & NTP_HASH_MASK;
1062           LINK_SLIST(assoc_hash[hash], peer, aid_link);
1063           assoc_hash_count[hash]++;
1064           LINK_SLIST(peer_list, peer, p_link);
1065 
1066           restrict_source(&peer->srcadr, FALSE, 0);
1067           mprintf_event(PEVNT_MOBIL, peer, "assoc %d", peer->associd);
1068           DPRINTF(1, ("newpeer: %s->%s mode %u vers %u poll %u %u flags 0x%x 0x%x ttl %u key %08x\n",
1069               latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode,
1070               peer->version, peer->minpoll, peer->maxpoll, peer->flags,
1071               peer->cast_flags, peer->ttl, peer->keyid));
1072           return peer;
1073 }
1074 
1075 
1076 /*
1077  * peer_clr_stats - clear peer module statistics counters
1078  */
1079 void
peer_clr_stats(void)1080 peer_clr_stats(void)
1081 {
1082           findpeer_calls = 0;
1083           assocpeer_calls = 0;
1084           peer_allocations = 0;
1085           peer_demobilizations = 0;
1086           peer_timereset = current_time;
1087 }
1088 
1089 
1090 /*
1091  * peer_reset - reset statistics counters
1092  */
1093 void
peer_reset(struct peer * peer)1094 peer_reset(
1095           struct peer *peer
1096           )
1097 {
1098           if (peer == NULL)
1099                     return;
1100 
1101           peer->timereset = current_time;
1102           peer->sent = 0;
1103           peer->received = 0;
1104           peer->processed = 0;
1105           peer->badauth = 0;
1106           peer->bogusorg = 0;
1107           peer->oldpkt = 0;
1108           peer->seldisptoolarge = 0;
1109           peer->selbroken = 0;
1110 }
1111 
1112 
1113 /*
1114  * peer_all_reset - reset all peer statistics counters
1115  */
1116 void
peer_all_reset(void)1117 peer_all_reset(void)
1118 {
1119           struct peer *peer;
1120 
1121           for (peer = peer_list; peer != NULL; peer = peer->p_link)
1122                     peer_reset(peer);
1123 }
1124 
1125 
1126 /*
1127  * findmanycastpeer - find and return a manycastclient or pool
1128  *                        association matching a received response.
1129  */
1130 struct peer *
findmanycastpeer(struct recvbuf * rbufp)1131 findmanycastpeer(
1132           struct recvbuf *rbufp         /* receive buffer pointer */
1133           )
1134 {
1135           struct peer *peer;
1136           struct pkt *pkt;
1137           l_fp p_org;
1138 
1139           /*
1140            * This routine is called upon arrival of a server-mode response
1141            * to a manycastclient multicast solicitation, or to a pool
1142            * server unicast solicitation.  Search the peer list for a
1143            * manycastclient association where the last transmit timestamp
1144            * matches the response packet's originate timestamp.  There can
1145            * be multiple manycastclient associations, or multiple pool
1146            * solicitation assocations, so this assumes the transmit
1147            * timestamps are unique for such.
1148            */
1149           pkt = &rbufp->recv_pkt;
1150           for (peer = peer_list; peer != NULL; peer = peer->p_link)
1151                     if (MDF_SOLICIT_MASK & peer->cast_flags) {
1152                               NTOHL_FP(&pkt->org, &p_org);
1153                               if (L_ISEQU(&p_org, &peer->aorg)) {
1154                                         break;
1155                               }
1156                     }
1157 
1158           return peer;
1159 }
1160 
1161 /* peer_cleanup - clean peer list prior to shutdown */
peer_cleanup(void)1162 void peer_cleanup(void)
1163 {
1164           struct peer *peer;
1165           struct peer *nextpeer;
1166 
1167           for (peer = peer_list; peer != NULL; peer = nextpeer) {
1168                     nextpeer = peer->p_link;
1169                     unpeer(peer);
1170           }
1171 }
1172