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 int 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[(x)][(y)]
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; /* association ID */
95 static associd_t initial_association_ID; /* 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);
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 = emalloc_zero(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)202 findexistingpeer_addr(
203 sockaddr_u * addr,
204 struct peer * start_peer,
205 int mode,
206 u_char cast_flags
207 )
208 {
209 struct peer *peer;
210
211 DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x)\n",
212 sptoa(addr),
213 (start_peer)
214 ? sptoa(&start_peer->srcadr)
215 : "NULL",
216 mode, (u_int)cast_flags));
217
218 /*
219 * start_peer is included so we can locate instances of the
220 * same peer through different interfaces in the hash table.
221 * Without MDF_BCLNT, a match requires the same mode and remote
222 * address. MDF_BCLNT associations start out as MODE_CLIENT
223 * if broadcastdelay is not specified, and switch to
224 * MODE_BCLIENT after estimating the one-way delay. Duplicate
225 * associations are expanded in definition to match any other
226 * MDF_BCLNT with the same srcadr (remote, unicast address).
227 */
228 if (NULL == start_peer)
229 peer = peer_hash[NTP_HASH_ADDR(addr)];
230 else
231 peer = start_peer->adr_link;
232
233 while (peer != NULL) {
234 DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr),
235 sptoa(&peer->srcadr), mode, peer->hmode,
236 (u_int)cast_flags, (u_int)peer->cast_flags));
237 if ((-1 == mode || peer->hmode == mode ||
238 ((MDF_BCLNT & peer->cast_flags) &&
239 (MDF_BCLNT & cast_flags))) &&
240 ADDR_PORT_EQ(addr, &peer->srcadr)) {
241 DPRINTF(3, ("found.\n"));
242 break;
243 }
244 DPRINTF(3, ("\n"));
245 peer = peer->adr_link;
246 }
247
248 return peer;
249 }
250
251
252 /*
253 * findexistingpeer - search by address and return a pointer to a peer.
254 */
255 struct peer *
findexistingpeer(sockaddr_u * addr,const char * hostname,struct peer * start_peer,int mode,u_char cast_flags)256 findexistingpeer(
257 sockaddr_u * addr,
258 const char * hostname,
259 struct peer * start_peer,
260 int mode,
261 u_char cast_flags
262 )
263 {
264 if (hostname != NULL)
265 return findexistingpeer_name(hostname, AF(addr),
266 start_peer, mode);
267 else
268 return findexistingpeer_addr(addr, start_peer, mode,
269 cast_flags);
270 }
271
272
273 /*
274 * findpeer - find and return a peer match for a received datagram in
275 * the peer_hash table.
276 *
277 * [Bug 3072] To faciliate a faster reorganisation after routing changes
278 * the original code re-assigned the peer address to be the destination
279 * of the received packet and initiated another round on a mismatch.
280 * Unfortunately this leaves us wide open for a DoS attack where the
281 * attacker directs a packet with forged destination address to us --
282 * this results in a wrong interface assignment, actually creating a DoS
283 * situation.
284 *
285 * This condition would persist until the next update of the interface
286 * list, but a continued attack would put us out of business again soon
287 * enough. Authentication alone does not help here, since it does not
288 * protect the UDP layer and leaves us open for a replay attack.
289 *
290 * So we do not update the adresses and wait until the next interface
291 * list update does the right thing for us.
292 */
293 struct peer *
findpeer(struct recvbuf * rbufp,int pkt_mode,int * action)294 findpeer(
295 struct recvbuf *rbufp,
296 int pkt_mode,
297 int * action
298 )
299 {
300 struct peer * p;
301 sockaddr_u * srcadr;
302 u_int hash;
303 struct pkt * pkt;
304 l_fp pkt_org;
305
306 findpeer_calls++;
307 srcadr = &rbufp->recv_srcadr;
308 hash = NTP_HASH_ADDR(srcadr);
309 for (p = peer_hash[hash]; p != NULL; p = p->adr_link) {
310
311 /* [Bug 3072] ensure interface of peer matches */
312 if (p->dstadr != rbufp->dstadr)
313 continue;
314
315 /* ensure peer source address matches */
316 if ( ! ADDR_PORT_EQ(srcadr, &p->srcadr))
317 continue;
318
319 /* If the association matching rules determine that this
320 * is not a valid combination, then look for the next
321 * valid peer association.
322 */
323 *action = MATCH_ASSOC(p->hmode, pkt_mode);
324
325 /* A response to our manycastclient solicitation might
326 * be misassociated with an ephemeral peer already spun
327 * for the server. If the packet's org timestamp
328 * doesn't match the peer's, check if it matches the
329 * ACST prototype peer's. If so it is a redundant
330 * solicitation response, return AM_ERR to discard it.
331 * [Bug 1762]
332 */
333 if (MODE_SERVER == pkt_mode && AM_PROCPKT == *action) {
334 pkt = &rbufp->recv_pkt;
335 NTOHL_FP(&pkt->org, &pkt_org);
336 if (!L_ISEQU(&p->aorg, &pkt_org) &&
337 findmanycastpeer(rbufp))
338 *action = AM_ERR;
339 }
340
341 /* if an error was returned, exit back right here. */
342 if (*action == AM_ERR)
343 return NULL;
344
345 /* if a match is found, we stop our search. */
346 if (*action != AM_NOMATCH)
347 break;
348 }
349
350 /* If no matching association is found... */
351 if (NULL == p)
352 *action = MATCH_ASSOC(NO_PEER, pkt_mode);
353
354 return p;
355 }
356
357 /*
358 * findpeerbyassoc - find and return a peer using his association ID
359 */
360 struct peer *
findpeerbyassoc(associd_t assoc)361 findpeerbyassoc(
362 associd_t assoc
363 )
364 {
365 struct peer *p;
366 u_int hash;
367
368 assocpeer_calls++;
369 hash = assoc & NTP_HASH_MASK;
370 for (p = assoc_hash[hash]; p != NULL; p = p->aid_link)
371 if (assoc == p->associd)
372 break;
373 return p;
374 }
375
376
377 /*
378 * clear_all - flush all time values for all associations
379 */
380 void
clear_all(void)381 clear_all(void)
382 {
383 struct peer *p;
384
385 /*
386 * This routine is called when the clock is stepped, and so all
387 * previously saved time values are untrusted.
388 */
389 for (p = peer_list; p != NULL; p = p->p_link)
390 if (!(MDF_TXONLY_MASK & p->cast_flags))
391 peer_clear(p, "STEP");
392
393 DPRINTF(1, ("clear_all: at %lu\n", current_time));
394 }
395
396
397 /*
398 * score_all() - determine if an association can be demobilized
399 */
400 int
score_all(struct peer * peer)401 score_all(
402 struct peer *peer /* peer structure pointer */
403 )
404 {
405 struct peer *speer;
406 int temp, tamp;
407 int x;
408
409 /*
410 * This routine finds the minimum score for all preemptible
411 * associations and returns > 0 if the association can be
412 * demobilized.
413 */
414 tamp = score(peer);
415 temp = 100;
416 for (speer = peer_list; speer != NULL; speer = speer->p_link)
417 if (speer->flags & FLAG_PREEMPT) {
418 x = score(speer);
419 if (x < temp)
420 temp = x;
421 }
422 DPRINTF(1, ("score_all: at %lu score %d min %d\n",
423 current_time, tamp, temp));
424
425 if (tamp != temp)
426 temp = 0;
427
428 return temp;
429 }
430
431
432 /*
433 * score() - calculate preemption score
434 */
435 static int
score(struct peer * peer)436 score(
437 struct peer *peer /* peer structure pointer */
438 )
439 {
440 int temp;
441
442 /*
443 * This routine calculates the premption score from the peer
444 * error bits and status. Increasing values are more cherished.
445 */
446 temp = 0;
447 if (!(peer->flash & TEST10))
448 temp++; /* 1 good synch and stratum */
449 if (!(peer->flash & TEST13))
450 temp++; /* 2 reachable */
451 if (!(peer->flash & TEST12))
452 temp++; /* 3 no loop */
453 if (!(peer->flash & TEST11))
454 temp++; /* 4 good distance */
455 if (peer->status >= CTL_PST_SEL_SELCAND)
456 temp++; /* 5 in the hunt */
457 if (peer->status != CTL_PST_SEL_EXCESS)
458 temp++; /* 6 not spare tire */
459 return (temp); /* selection status */
460 }
461
462
463 /*
464 * free_peer - internal routine to free memory referred to by a struct
465 * peer and return it to the peer free list. If unlink is
466 * nonzero, unlink from the various lists.
467 */
468 static void
free_peer(struct peer * p,int unlink_peer)469 free_peer(
470 struct peer * p,
471 int unlink_peer
472 )
473 {
474 struct peer * unlinked;
475 int hash;
476
477 if (unlink_peer) {
478 hash = NTP_HASH_ADDR(&p->srcadr);
479 peer_hash_count[hash]--;
480
481 UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link,
482 struct peer);
483 if (NULL == unlinked) {
484 peer_hash_count[hash]++;
485 msyslog(LOG_ERR, "peer %s not in address table!",
486 stoa(&p->srcadr));
487 }
488
489 /*
490 * Remove him from the association hash as well.
491 */
492 hash = p->associd & NTP_HASH_MASK;
493 assoc_hash_count[hash]--;
494
495 UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link,
496 struct peer);
497 if (NULL == unlinked) {
498 assoc_hash_count[hash]++;
499 msyslog(LOG_ERR,
500 "peer %s not in association ID table!",
501 stoa(&p->srcadr));
502 }
503
504 /* Remove him from the overall list. */
505 UNLINK_SLIST(unlinked, peer_list, p, p_link,
506 struct peer);
507 if (NULL == unlinked)
508 msyslog(LOG_ERR, "%s not in peer list!",
509 stoa(&p->srcadr));
510 }
511
512 if (p->hostname != NULL)
513 free(p->hostname);
514
515 if (p->ident != NULL)
516 free(p->ident);
517
518 if (p->addrs != NULL)
519 free(p->addrs); /* from copy_addrinfo_list() */
520
521 /* Add his corporeal form to peer free list */
522 ZERO(*p);
523 LINK_SLIST(peer_free, p, p_link);
524 peer_free_count++;
525 }
526
527
528 /*
529 * unpeer - remove peer structure from hash table and free structure
530 */
531 void
unpeer(struct peer * peer)532 unpeer(
533 struct peer *peer
534 )
535 {
536 mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd);
537 restrict_source(&peer->srcadr, 1, 0);
538 set_peerdstadr(peer, NULL);
539 peer_demobilizations++;
540 peer_associations--;
541 if (FLAG_PREEMPT & peer->flags)
542 peer_preempt--;
543 #ifdef REFCLOCK
544 /*
545 * If this peer is actually a clock, shut it down first
546 */
547 if (FLAG_REFCLOCK & peer->flags)
548 refclock_unpeer(peer);
549 #endif
550
551 free_peer(peer, TRUE);
552 }
553
554
555 /*
556 * peer_config - configure a new association
557 */
558 struct peer *
peer_config(sockaddr_u * srcadr,const char * hostname,endpt * dstadr,u_char hmode,u_char version,u_char minpoll,u_char maxpoll,u_int flags,u_int32 ttl,keyid_t key,const char * ident)559 peer_config(
560 sockaddr_u * srcadr,
561 const char * hostname,
562 endpt * dstadr,
563 u_char hmode,
564 u_char version,
565 u_char minpoll,
566 u_char maxpoll,
567 u_int flags,
568 u_int32 ttl,
569 keyid_t key,
570 const char * ident /* autokey group */
571 )
572 {
573 u_char cast_flags;
574
575 /*
576 * We do a dirty little jig to figure the cast flags. This is
577 * probably not the best place to do this, at least until the
578 * configure code is rebuilt. Note only one flag can be set.
579 */
580 switch (hmode) {
581 case MODE_BROADCAST:
582 if (IS_MCAST(srcadr))
583 cast_flags = MDF_MCAST;
584 else
585 cast_flags = MDF_BCAST;
586 break;
587
588 case MODE_CLIENT:
589 if (hostname != NULL && SOCK_UNSPEC(srcadr))
590 cast_flags = MDF_POOL;
591 else if (IS_MCAST(srcadr))
592 cast_flags = MDF_ACAST;
593 else
594 cast_flags = MDF_UCAST;
595 break;
596
597 default:
598 cast_flags = MDF_UCAST;
599 }
600
601 /*
602 * Mobilize the association and initialize its variables. If
603 * emulating ntpdate, force iburst. For pool and manycastclient
604 * strip FLAG_PREEMPT as the prototype associations are not
605 * themselves preemptible, though the resulting associations
606 * are.
607 */
608 flags |= FLAG_CONFIG;
609 if (mode_ntpdate)
610 flags |= FLAG_IBURST;
611 if ((MDF_ACAST | MDF_POOL) & cast_flags)
612 flags &= ~FLAG_PREEMPT;
613 return newpeer(srcadr, hostname, dstadr, hmode, version,
614 minpoll, maxpoll, flags, cast_flags, ttl, key, ident);
615 }
616
617 /*
618 * setup peer dstadr field keeping it in sync with the interface
619 * structures
620 */
621 void
set_peerdstadr(struct peer * p,endpt * dstadr)622 set_peerdstadr(
623 struct peer * p,
624 endpt * dstadr
625 )
626 {
627 struct peer * unlinked;
628
629 DEBUG_INSIST(p != NULL);
630
631 if (p == NULL)
632 return;
633
634 /* check for impossible or identical assignment */
635 if (p->dstadr == dstadr)
636 return;
637
638 /*
639 * Don't accept updates to a separate multicast receive-only
640 * endpt while a BCLNT peer is running its unicast protocol.
641 */
642 if (dstadr != NULL && (FLAG_BC_VOL & p->flags) &&
643 (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) {
644 return;
645 }
646
647 /* unlink from list if we have an address prior to assignment */
648 if (p->dstadr != NULL) {
649 p->dstadr->peercnt--;
650 UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink,
651 struct peer);
652 msyslog(LOG_INFO, "%s local addr %s -> %s",
653 stoa(&p->srcadr), latoa(p->dstadr),
654 latoa(dstadr));
655 }
656
657 p->dstadr = dstadr;
658
659 /* link to list if we have an address after assignment */
660 if (p->dstadr != NULL) {
661 LINK_SLIST(dstadr->peers, p, ilink);
662 dstadr->peercnt++;
663 }
664 }
665
666 /*
667 * attempt to re-rebind interface if necessary
668 */
669 static void
peer_refresh_interface(struct peer * p)670 peer_refresh_interface(
671 struct peer *p
672 )
673 {
674 endpt * niface;
675 endpt * piface;
676
677 niface = select_peerinterface(p, &p->srcadr, NULL);
678
679 DPRINTF(4, (
680 "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %u key %08x: new interface: ",
681 p->dstadr == NULL ? "<null>" :
682 stoa(&p->dstadr->sin), stoa(&p->srcadr), p->hmode,
683 p->version, p->minpoll, p->maxpoll, p->flags, p->cast_flags,
684 p->ttl, p->keyid));
685 if (niface != NULL) {
686 DPRINTF(4, (
687 "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s",
688 niface->fd, niface->bfd, niface->name,
689 niface->flags, niface->ifindex,
690 stoa(&niface->sin)));
691 if (niface->flags & INT_BROADCAST)
692 DPRINTF(4, (", bcast=%s",
693 stoa(&niface->bcast)));
694 DPRINTF(4, (", mask=%s\n", stoa(&niface->mask)));
695 } else {
696 DPRINTF(4, ("<NONE>\n"));
697 }
698
699 piface = p->dstadr;
700 set_peerdstadr(p, niface);
701 if (p->dstadr != NULL) {
702 /*
703 * clear crypto if we change the local address
704 */
705 if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags)
706 && MODE_BROADCAST != p->pmode)
707 peer_clear(p, "XFAC");
708
709 /*
710 * Broadcast needs the socket enabled for broadcast
711 */
712 if (MDF_BCAST & p->cast_flags)
713 enable_broadcast(p->dstadr, &p->srcadr);
714
715 /*
716 * Multicast needs the socket interface enabled for
717 * multicast
718 */
719 if (MDF_MCAST & p->cast_flags)
720 enable_multicast_if(p->dstadr, &p->srcadr);
721 }
722 }
723
724
725 /*
726 * refresh_all_peerinterfaces - see that all interface bindings are up
727 * to date
728 */
729 void
refresh_all_peerinterfaces(void)730 refresh_all_peerinterfaces(void)
731 {
732 struct peer *p;
733
734 /*
735 * this is called when the interface list has changed
736 * give all peers a chance to find a better interface
737 * but only if either they don't have an address already
738 * or if the one they have hasn't worked for a while.
739 */
740 for (p = peer_list; p != NULL; p = p->p_link) {
741 if (!(p->dstadr && (p->reach & 0x3))) // Bug 2849 XOR 2043
742 peer_refresh_interface(p);
743 }
744 }
745
746
747 /*
748 * newpeer - initialize a new peer association
749 */
750 struct peer *
newpeer(sockaddr_u * srcadr,const char * hostname,endpt * dstadr,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)751 newpeer(
752 sockaddr_u * srcadr,
753 const char * hostname,
754 endpt * dstadr,
755 u_char hmode,
756 u_char version,
757 u_char minpoll,
758 u_char maxpoll,
759 u_int flags,
760 u_char cast_flags,
761 u_int32 ttl,
762 keyid_t key,
763 const char * ident
764 )
765 {
766 struct peer * peer;
767 u_int hash;
768
769 DEBUG_REQUIRE(srcadr);
770
771 #ifdef AUTOKEY
772 /*
773 * If Autokey is requested but not configured, complain loudly.
774 */
775 if (!crypto_flags) {
776 if (key > NTP_MAXKEY) {
777 return (NULL);
778
779 } else if (flags & FLAG_SKEY) {
780 msyslog(LOG_ERR, "Autokey not configured");
781 return (NULL);
782 }
783 }
784 #endif /* AUTOKEY */
785
786 /*
787 * For now only pool associations have a hostname.
788 */
789 INSIST(NULL == hostname || (MDF_POOL & cast_flags));
790
791 /*
792 * First search from the beginning for an association with given
793 * remote address and mode. If an interface is given, search
794 * from there to find the association which matches that
795 * destination. If the given interface is "any", track down the
796 * actual interface, because that's what gets put into the peer
797 * structure.
798 */
799 if (dstadr != NULL) {
800 peer = findexistingpeer(srcadr, hostname, NULL, hmode,
801 cast_flags);
802 while (peer != NULL) {
803 if (peer->dstadr == dstadr ||
804 ((MDF_BCLNT & cast_flags) &&
805 (MDF_BCLNT & peer->cast_flags)))
806 break;
807
808 if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) &&
809 peer->dstadr == findinterface(srcadr))
810 break;
811
812 peer = findexistingpeer(srcadr, hostname, peer,
813 hmode, cast_flags);
814 }
815 } else {
816 /* no endpt address given */
817 peer = findexistingpeer(srcadr, hostname, NULL, hmode,
818 cast_flags);
819 }
820
821 /*
822 * If a peer is found, this would be a duplicate and we don't
823 * allow that. This avoids duplicate ephemeral (broadcast/
824 * multicast) and preemptible (manycast and pool) client
825 * associations.
826 */
827 if (peer != NULL) {
828 DPRINTF(2, ("newpeer(%s) found existing association\n",
829 (hostname)
830 ? hostname
831 : stoa(srcadr)));
832 return NULL;
833 }
834
835 /*
836 * Allocate a new peer structure. Some dirt here, since some of
837 * the initialization requires knowlege of our system state.
838 */
839 if (peer_free_count == 0)
840 getmorepeermem();
841 UNLINK_HEAD_SLIST(peer, peer_free, p_link);
842 INSIST(peer != NULL);
843 peer_free_count--;
844 peer_associations++;
845 if (FLAG_PREEMPT & flags)
846 peer_preempt++;
847
848 /*
849 * Assign an association ID and increment the system variable.
850 */
851 peer->associd = current_association_ID;
852 if (++current_association_ID == 0)
853 ++current_association_ID;
854
855 peer->srcadr = *srcadr;
856 if (hostname != NULL)
857 peer->hostname = estrdup(hostname);
858 peer->hmode = hmode;
859 peer->version = version;
860 peer->flags = flags;
861 peer->cast_flags = cast_flags;
862 set_peerdstadr(peer,
863 select_peerinterface(peer, srcadr, dstadr));
864
865 /*
866 * It is an error to set minpoll less than NTP_MINPOLL or to
867 * set maxpoll greater than NTP_MAXPOLL. However, minpoll is
868 * clamped not greater than NTP_MAXPOLL and maxpoll is clamped
869 * not less than NTP_MINPOLL without complaint. Finally,
870 * minpoll is clamped not greater than maxpoll.
871 */
872 if (minpoll == 0)
873 peer->minpoll = NTP_MINDPOLL;
874 else
875 peer->minpoll = min(minpoll, NTP_MAXPOLL);
876 if (maxpoll == 0)
877 peer->maxpoll = NTP_MAXDPOLL;
878 else
879 peer->maxpoll = max(maxpoll, NTP_MINPOLL);
880 if (peer->minpoll > peer->maxpoll)
881 peer->minpoll = peer->maxpoll;
882
883 if (peer->dstadr != NULL)
884 DPRINTF(3, ("newpeer(%s): using fd %d and our addr %s\n",
885 stoa(srcadr), peer->dstadr->fd,
886 stoa(&peer->dstadr->sin)));
887 else
888 DPRINTF(3, ("newpeer(%s): local interface currently not bound\n",
889 stoa(srcadr)));
890
891 /*
892 * Broadcast needs the socket enabled for broadcast
893 */
894 if ((MDF_BCAST & cast_flags) && peer->dstadr != NULL)
895 enable_broadcast(peer->dstadr, srcadr);
896
897 /*
898 * Multicast needs the socket interface enabled for multicast
899 */
900 if ((MDF_MCAST & cast_flags) && peer->dstadr != NULL)
901 enable_multicast_if(peer->dstadr, srcadr);
902
903 #ifdef AUTOKEY
904 if (key > NTP_MAXKEY)
905 peer->flags |= FLAG_SKEY;
906 #endif /* AUTOKEY */
907 peer->ttl = ttl;
908 peer->keyid = key;
909 if (ident != NULL)
910 peer->ident = estrdup(ident);
911 peer->precision = sys_precision;
912 peer->hpoll = peer->minpoll;
913 if (cast_flags & MDF_ACAST)
914 peer_clear(peer, "ACST");
915 else if (cast_flags & MDF_POOL)
916 peer_clear(peer, "POOL");
917 else if (cast_flags & MDF_MCAST)
918 peer_clear(peer, "MCST");
919 else if (cast_flags & MDF_BCAST)
920 peer_clear(peer, "BCST");
921 else
922 peer_clear(peer, "INIT");
923 if (mode_ntpdate)
924 peer_ntpdate++;
925
926 /*
927 * Note time on statistics timers.
928 */
929 peer->timereset = current_time;
930 peer->timereachable = current_time;
931 peer->timereceived = current_time;
932
933 if (ISREFCLOCKADR(&peer->srcadr)) {
934 #ifdef REFCLOCK
935 /*
936 * We let the reference clock support do clock
937 * dependent initialization. This includes setting
938 * the peer timer, since the clock may have requirements
939 * for this.
940 */
941 if (maxpoll == 0)
942 peer->maxpoll = peer->minpoll;
943 if (!refclock_newpeer(peer)) {
944 /*
945 * Dump it, something screwed up
946 */
947 set_peerdstadr(peer, NULL);
948 free_peer(peer, 0);
949 return NULL;
950 }
951 #else /* REFCLOCK */
952 msyslog(LOG_ERR, "refclock %s isn't supported. ntpd was compiled without refclock support.",
953 stoa(&peer->srcadr));
954 set_peerdstadr(peer, NULL);
955 free_peer(peer, 0);
956 return NULL;
957 #endif /* REFCLOCK */
958 }
959
960 /*
961 * Put the new peer in the hash tables.
962 */
963 hash = NTP_HASH_ADDR(&peer->srcadr);
964 LINK_SLIST(peer_hash[hash], peer, adr_link);
965 peer_hash_count[hash]++;
966 hash = peer->associd & NTP_HASH_MASK;
967 LINK_SLIST(assoc_hash[hash], peer, aid_link);
968 assoc_hash_count[hash]++;
969 LINK_SLIST(peer_list, peer, p_link);
970
971 restrict_source(&peer->srcadr, 0, 0);
972 mprintf_event(PEVNT_MOBIL, peer, "assoc %d", peer->associd);
973 DPRINTF(1, ("newpeer: %s->%s mode %u vers %u poll %u %u flags 0x%x 0x%x ttl %u key %08x\n",
974 latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode,
975 peer->version, peer->minpoll, peer->maxpoll, peer->flags,
976 peer->cast_flags, peer->ttl, peer->keyid));
977 return peer;
978 }
979
980
981 /*
982 * peer_clr_stats - clear peer module statistics counters
983 */
984 void
peer_clr_stats(void)985 peer_clr_stats(void)
986 {
987 findpeer_calls = 0;
988 assocpeer_calls = 0;
989 peer_allocations = 0;
990 peer_demobilizations = 0;
991 peer_timereset = current_time;
992 }
993
994
995 /*
996 * peer_reset - reset statistics counters
997 */
998 void
peer_reset(struct peer * peer)999 peer_reset(
1000 struct peer *peer
1001 )
1002 {
1003 if (peer == NULL)
1004 return;
1005
1006 peer->timereset = current_time;
1007 peer->sent = 0;
1008 peer->received = 0;
1009 peer->processed = 0;
1010 peer->badauth = 0;
1011 peer->bogusorg = 0;
1012 peer->oldpkt = 0;
1013 peer->seldisptoolarge = 0;
1014 peer->selbroken = 0;
1015 }
1016
1017
1018 /*
1019 * peer_all_reset - reset all peer statistics counters
1020 */
1021 void
peer_all_reset(void)1022 peer_all_reset(void)
1023 {
1024 struct peer *peer;
1025
1026 for (peer = peer_list; peer != NULL; peer = peer->p_link)
1027 peer_reset(peer);
1028 }
1029
1030
1031 /*
1032 * findmanycastpeer - find and return a manycastclient or pool
1033 * association matching a received response.
1034 */
1035 struct peer *
findmanycastpeer(struct recvbuf * rbufp)1036 findmanycastpeer(
1037 struct recvbuf *rbufp /* receive buffer pointer */
1038 )
1039 {
1040 struct peer *peer;
1041 struct pkt *pkt;
1042 l_fp p_org;
1043
1044 /*
1045 * This routine is called upon arrival of a server-mode response
1046 * to a manycastclient multicast solicitation, or to a pool
1047 * server unicast solicitation. Search the peer list for a
1048 * manycastclient association where the last transmit timestamp
1049 * matches the response packet's originate timestamp. There can
1050 * be multiple manycastclient associations, or multiple pool
1051 * solicitation assocations, so this assumes the transmit
1052 * timestamps are unique for such.
1053 */
1054 pkt = &rbufp->recv_pkt;
1055 for (peer = peer_list; peer != NULL; peer = peer->p_link)
1056 if (MDF_SOLICIT_MASK & peer->cast_flags) {
1057 NTOHL_FP(&pkt->org, &p_org);
1058 if (L_ISEQU(&p_org, &peer->aorg))
1059 break;
1060 }
1061
1062 return peer;
1063 }
1064
1065 /* peer_cleanup - clean peer list prior to shutdown */
peer_cleanup(void)1066 void peer_cleanup(void)
1067 {
1068 struct peer *peer;
1069 associd_t assoc;
1070
1071 for (assoc = initial_association_ID; assoc != current_association_ID; assoc++) {
1072 if (assoc != 0U) {
1073 peer = findpeerbyassoc(assoc);
1074 if (peer != NULL)
1075 unpeer(peer);
1076 }
1077 }
1078 peer = findpeerbyassoc(current_association_ID);
1079 if (peer != NULL)
1080 unpeer(peer);
1081 }
1082