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