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