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