ntp_peer.c revision 289999
11541Srgrimes/* 21541Srgrimes * ntp_peer.c - management of data maintained for peer associations 31541Srgrimes */ 41541Srgrimes#ifdef HAVE_CONFIG_H 551138Salfred#include <config.h> 6127484Smtm#endif 71541Srgrimes 81541Srgrimes#include <stdio.h> 91541Srgrimes#include <sys/types.h> 1064002Speter 111541Srgrimes#include "ntpd.h" 121541Srgrimes#include "ntp_lists.h" 131541Srgrimes#include "ntp_stdlib.h" 141541Srgrimes#include "ntp_control.h" 151541Srgrimes#include <ntp_random.h> 161541Srgrimes 171541Srgrimes/* 181541Srgrimes * Table of valid association combinations 191541Srgrimes * --------------------------------------- 201541Srgrimes * 211541Srgrimes * packet->mode 221541Srgrimes * peer->mode | UNSPEC ACTIVE PASSIVE CLIENT SERVER BCAST 231541Srgrimes * ---------- | --------------------------------------------- 241541Srgrimes * NO_PEER | e 1 0 1 1 1 251541Srgrimes * ACTIVE | e 1 1 0 0 0 261541Srgrimes * PASSIVE | e 1 e 0 0 0 27122540Smckusick * CLIENT | e 0 0 0 1 0 281541Srgrimes * SERVER | e 0 0 0 0 0 291541Srgrimes * BCAST | e 0 0 0 0 0 301541Srgrimes * BCLIENT | e 0 0 0 e 1 311541Srgrimes * 321541Srgrimes * One point to note here: a packet in BCAST mode can potentially match 331541Srgrimes * a peer in CLIENT mode, but we that is a special case and we check for 341541Srgrimes * that early in the decision process. This avoids having to keep track 351541Srgrimes * of what kind of associations are possible etc... We actually 361541Srgrimes * circumvent that problem by requiring that the first b(m)roadcast 371541Srgrimes * received after the change back to BCLIENT mode sets the clock. 381541Srgrimes */ 391541Srgrimes#define AM_MODES 7 /* number of rows and columns */ 401541Srgrimes#define NO_PEER 0 /* action when no peer is found */ 411541Srgrimes 421541Srgrimesint AM[AM_MODES][AM_MODES] = { 431541Srgrimes/* packet->mode */ 441541Srgrimes/* peer { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */ 451541Srgrimes/* mode */ 461541Srgrimes/*NONE*/{ AM_ERR, AM_NEWPASS, AM_NOMATCH, AM_FXMIT, AM_MANYCAST, AM_NEWBCL}, 471541Srgrimes 481541Srgrimes/*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 491541Srgrimes 501541Srgrimes/*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 511541Srgrimes 521541Srgrimes/*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_NOMATCH}, 531541Srgrimes 541541Srgrimes/*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 5552150Smarcel 561541Srgrimes/*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 5752150Smarcel 581541Srgrimes/*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT}, 591541Srgrimes}; 601541Srgrimes 6152150Smarcel#define MATCH_ASSOC(x, y) AM[(x)][(y)] 621541Srgrimes 631541Srgrimes/* 641541Srgrimes * These routines manage the allocation of memory to peer structures 651541Srgrimes * and the maintenance of three data structures involving all peers: 661541Srgrimes * 671541Srgrimes * - peer_list is a single list with all peers, suitable for scanning 681541Srgrimes * operations over all peers. 691541Srgrimes * - peer_adr_hash is an array of lists indexed by hashed peer address. 701541Srgrimes * - peer_aid_hash is an array of lists indexed by hashed associd. 711541Srgrimes * 721541Srgrimes * They also maintain a free list of peer structures, peer_free. 731541Srgrimes * 741541Srgrimes * The three main entry points are findpeer(), which looks for matching 751541Srgrimes * peer structures in the peer list, newpeer(), which allocates a new 761541Srgrimes * peer structure and adds it to the list, and unpeer(), which 771541Srgrimes * demobilizes the association and deallocates the structure. 781541Srgrimes */ 791541Srgrimes/* 801541Srgrimes * Peer hash tables 811541Srgrimes */ 821541Srgrimesstruct peer *peer_hash[NTP_HASH_SIZE]; /* peer hash table */ 831541Srgrimesint peer_hash_count[NTP_HASH_SIZE]; /* peers in each bucket */ 841541Srgrimesstruct peer *assoc_hash[NTP_HASH_SIZE]; /* association ID hash table */ 851541Srgrimesint assoc_hash_count[NTP_HASH_SIZE];/* peers in each bucket */ 861541Srgrimesstruct peer *peer_list; /* peer structures list */ 871541Srgrimesstatic struct peer *peer_free; /* peer structures free list */ 881541Srgrimesint peer_free_count; /* count of free structures */ 891541Srgrimes 901541Srgrimes/* 911541Srgrimes * Association ID. We initialize this value randomly, then assign a new 921541Srgrimes * value every time an association is mobilized. 931541Srgrimes */ 941541Srgrimesstatic associd_t current_association_ID; /* association ID */ 951541Srgrimesstatic associd_t initial_association_ID; /* association ID */ 961541Srgrimes 971541Srgrimes/* 981541Srgrimes * Memory allocation watermarks. 991541Srgrimes */ 1001541Srgrimes#define INIT_PEER_ALLOC 8 /* static preallocation */ 1011541Srgrimes#define INC_PEER_ALLOC 4 /* add N more when empty */ 1021541Srgrimes 1031541Srgrimes/* 1041541Srgrimes * Miscellaneous statistic counters which may be queried. 1051541Srgrimes */ 1061541Srgrimesu_long peer_timereset; /* time stat counters zeroed */ 1071541Srgrimesu_long findpeer_calls; /* calls to findpeer */ 1081541Srgrimesu_long assocpeer_calls; /* calls to findpeerbyassoc */ 1091541Srgrimesu_long peer_allocations; /* allocations from free list */ 110105950Speteru_long peer_demobilizations; /* structs freed to free list */ 1111541Srgrimesint total_peer_structs; /* peer structs */ 1121541Srgrimesint peer_associations; /* mobilized associations */ 1131541Srgrimesint peer_preempt; /* preemptable associations */ 1141541Srgrimesstatic struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */ 1151541Srgrimes 1161541Srgrimesstatic struct peer * findexistingpeer_name(const char *, u_short, 1171541Srgrimes struct peer *, int); 11852150Smarcelstatic struct peer * findexistingpeer_addr(sockaddr_u *, 1191541Srgrimes struct peer *, int, 1201541Srgrimes u_char); 1211541Srgrimesstatic void free_peer(struct peer *, int); 1221541Srgrimesstatic void getmorepeermem(void); 1231541Srgrimesstatic int score(struct peer *); 1241541Srgrimes 1251541Srgrimes 1261541Srgrimes/* 1271541Srgrimes * init_peer - initialize peer data structures and counters 1281541Srgrimes * 1291541Srgrimes * N.B. We use the random number routine in here. It had better be 1301541Srgrimes * initialized prior to getting here. 1311541Srgrimes */ 1328019Sachevoid 1338019Sacheinit_peer(void) 1341541Srgrimes{ 1351541Srgrimes int i; 1361541Srgrimes 1371541Srgrimes /* 1381541Srgrimes * Initialize peer free list from static allocation. 1391541Srgrimes */ 1401541Srgrimes for (i = COUNTOF(init_peer_alloc) - 1; i >= 0; i--) 1411541Srgrimes LINK_SLIST(peer_free, &init_peer_alloc[i], p_link); 1421541Srgrimes total_peer_structs = COUNTOF(init_peer_alloc); 1431541Srgrimes peer_free_count = COUNTOF(init_peer_alloc); 1441541Srgrimes 1451541Srgrimes /* 1461541Srgrimes * Initialize our first association ID 1471541Srgrimes */ 1481541Srgrimes do 1491541Srgrimes current_association_ID = ntp_random() & ASSOCID_MAX; 1501541Srgrimes while (!current_association_ID); 1511541Srgrimes initial_association_ID = current_association_ID; 1521541Srgrimes} 1531541Srgrimes 1541541Srgrimes 1551541Srgrimes/* 1561541Srgrimes * getmorepeermem - add more peer structures to the free list 1571541Srgrimes */ 1581541Srgrimesstatic void 159122540Smckusickgetmorepeermem(void) 160122540Smckusick{ 1611541Srgrimes int i; 1621549Srgrimes struct peer *peers; 1631549Srgrimes 1641549Srgrimes peers = emalloc_zero(INC_PEER_ALLOC * sizeof(*peers)); 1651549Srgrimes 1662442Sdg for (i = INC_PEER_ALLOC - 1; i >= 0; i--) 1672729Sdfr LINK_SLIST(peer_free, &peers[i], p_link); 1682729Sdfr 1691541Srgrimes total_peer_structs += INC_PEER_ALLOC; 17045065Salc peer_free_count += INC_PEER_ALLOC; 17145065Salc} 1722297Swollman 1731541Srgrimes 1741541Srgrimesstatic struct peer * 1751541Srgrimesfindexistingpeer_name( 1761541Srgrimes const char * hostname, 1771541Srgrimes u_short hname_fam, 1781541Srgrimes struct peer * start_peer, 1791541Srgrimes int mode 1801541Srgrimes ) 1811541Srgrimes{ 1821541Srgrimes struct peer *p; 1831541Srgrimes 1841541Srgrimes if (NULL == start_peer) 1851541Srgrimes p = peer_list; 1861541Srgrimes else 1871541Srgrimes p = start_peer->p_link; 1881541Srgrimes for (; p != NULL; p = p->p_link) 1891541Srgrimes if (p->hostname != NULL 1901541Srgrimes && (-1 == mode || p->hmode == mode) 1911541Srgrimes && (AF_UNSPEC == hname_fam 19235938Sdyson || AF_UNSPEC == AF(&p->srcadr) 19335938Sdyson || hname_fam == AF(&p->srcadr)) 19428400Speter && !strcasecmp(p->hostname, hostname)) 19529349Speter break; 19612865Speter return p; 19712865Speter} 19812865Speter 19912865Speter 20012865Speterstatic 20112865Speterstruct peer * 20212865Speterfindexistingpeer_addr( 20312865Speter sockaddr_u * addr, 20412865Speter struct peer * start_peer, 20512865Speter int mode, 20612865Speter u_char cast_flags 20725582Speter ) 20825582Speter{ 20925582Speter struct peer *peer; 21025582Speter 21114220Speter DPRINTF(2, ("findexistingpeer_addr(%s, %s, %d, 0x%x)\n", 21214220Speter sptoa(addr), 21329349Speter (start_peer) 21424452Speter ? sptoa(&start_peer->srcadr) 21524440Speter : "NULL", 21635938Sdyson mode, (u_int)cast_flags)); 21735938Sdyson 21835938Sdyson /* 21935938Sdyson * start_peer is included so we can locate instances of the 22035938Sdyson * same peer through different interfaces in the hash table. 22135938Sdyson * Without MDF_BCLNT, a match requires the same mode and remote 22235938Sdyson * address. MDF_BCLNT associations start out as MODE_CLIENT 22335938Sdyson * if broadcastdelay is not specified, and switch to 224122540Smckusick * MODE_BCLIENT after estimating the one-way delay. Duplicate 22551138Salfred * associations are expanded in definition to match any other 22651138Salfred * MDF_BCLNT with the same srcadr (remote, unicast address). 22725537Sdfr */ 22825537Sdfr if (NULL == start_peer) 22925537Sdfr peer = peer_hash[NTP_HASH_ADDR(addr)]; 23025537Sdfr else 23125537Sdfr peer = start_peer->adr_link; 23225537Sdfr 23325537Sdfr while (peer != NULL) { 23425537Sdfr DPRINTF(3, ("%s %s %d %d 0x%x 0x%x ", sptoa(addr), 23525537Sdfr sptoa(&peer->srcadr), mode, peer->hmode, 23625537Sdfr (u_int)cast_flags, (u_int)peer->cast_flags)); 23728400Speter if ((-1 == mode || peer->hmode == mode || 23856115Speter ((MDF_BCLNT & peer->cast_flags) && 23956115Speter (MDF_BCLNT & cast_flags))) && 24036034Speter ADDR_PORT_EQ(addr, &peer->srcadr)) { 24126671Sdyson DPRINTF(3, ("found.\n")); 24226671Sdyson break; 24326671Sdyson } 24426671Sdyson DPRINTF(3, ("\n")); 24526671Sdyson peer = peer->adr_link; 24626671Sdyson } 24726671Sdyson 24826671Sdyson return peer; 24969514Sjake} 25069514Sjake 25126671Sdyson 25226671Sdyson/* 25329391Sphk * findexistingpeer - search by address and return a pointer to a peer. 25434925Sdufault */ 25534925Sdufaultstruct peer * 25634925Sdufaultfindexistingpeer( 25734925Sdufault sockaddr_u * addr, 25834925Sdufault const char * hostname, 25934925Sdufault struct peer * start_peer, 26034925Sdufault int mode, 26134925Sdufault u_char cast_flags 26235938Sdyson ) 26399856Salfred{ 26441089Speter if (hostname != NULL) 26546155Sphk return findexistingpeer_name(hostname, AF(addr), 26651791Smarcel start_peer, mode); 26751791Smarcel else 268105950Speter return findexistingpeer_addr(addr, start_peer, mode, 26951791Smarcel cast_flags); 270105950Speter} 271112895Sjeff 272112895Sjeff 27356271Srwatson/* 27456271Srwatson * findpeer - find and return a peer match for a received datagram in 27556271Srwatson * the peer_hash table. 27656271Srwatson */ 27756271Srwatsonstruct peer * 27856271Srwatsonfindpeer( 27956271Srwatson struct recvbuf *rbufp, 28056271Srwatson int pkt_mode, 28154803Srwatson int * action 28254803Srwatson ) 28354803Srwatson{ 28454803Srwatson struct peer * p; 28555943Sjasone sockaddr_u * srcadr; 28656115Speter u_int hash; 28756115Speter struct pkt * pkt; 28859288Sjlemon l_fp pkt_org; 28959288Sjlemon 29075039Srwatson findpeer_calls++; 29175039Srwatson srcadr = &rbufp->recv_srcadr; 29275039Srwatson hash = NTP_HASH_ADDR(srcadr); 29375427Srwatson for (p = peer_hash[hash]; p != NULL; p = p->adr_link) { 29483652Speter if (ADDR_PORT_EQ(srcadr, &p->srcadr)) { 29583796Srwatson 29685891Sphk /* 29790889Sjulian * if the association matching rules determine 29890889Sjulian * that this is not a valid combination, then 299103972Sarchie * look for the next valid peer association. 300103972Sarchie */ 301103972Sarchie *action = MATCH_ASSOC(p->hmode, pkt_mode); 302100897Srwatson 303100897Srwatson /* 304100897Srwatson * A response to our manycastclient solicitation 305100897Srwatson * might be misassociated with an ephemeral peer 306100897Srwatson * already spun for the server. If the packet's 307100897Srwatson * org timestamp doesn't match the peer's, check 30894936Smux * if it matches the ACST prototype peer's. If 30996084Smux * so it is a redundant solicitation response, 31097372Smarcel * return AM_ERR to discard it. [Bug 1762] 31199856Salfred */ 312101426Srwatson if (MODE_SERVER == pkt_mode && 313122540Smckusick AM_PROCPKT == *action) { 314122540Smckusick pkt = &rbufp->recv_pkt; 315122540Smckusick NTOHL_FP(&pkt->org, &pkt_org); 316122540Smckusick if (!L_ISEQU(&p->aorg, &pkt_org) && 317103575Salfred findmanycastpeer(rbufp)) 318103575Salfred *action = AM_ERR; 319103575Salfred } 320103575Salfred 321103575Salfred /* 322103575Salfred * if an error was returned, exit back right 323103575Salfred * here. 324103575Salfred */ 325103575Salfred if (*action == AM_ERR) 326105692Srwatson return NULL; 327105692Srwatson 328105692Srwatson /* 329104731Srwatson * if a match is found, we stop our search. 330104731Srwatson */ 331104731Srwatson if (*action != AM_NOMATCH) 332106467Srwatson break; 333105950Speter } 334105950Speter } 335106978Sdeischen 336106978Sdeischen /* 337106978Sdeischen * If no matching association is found 338107914Sdillon */ 339108406Srwatson if (NULL == p) { 340108406Srwatson *action = MATCH_ASSOC(NO_PEER, pkt_mode); 341108406Srwatson } else if (p->dstadr != rbufp->dstadr) { 342108406Srwatson set_peerdstadr(p, rbufp->dstadr); 343112895Sjeff if (p->dstadr == rbufp->dstadr) { 344112902Sjeff DPRINTF(1, ("Changed %s local address to match response\n", 345112902Sjeff stoa(&p->srcadr))); 346112902Sjeff return findpeer(rbufp, pkt_mode, action); 347112902Sjeff } 348112909Sjeff } 349112909Sjeff return p; 350113276Smike} 351115800Srwatson 352115800Srwatson/* 353115800Srwatson * findpeerbyassoc - find and return a peer using his association ID 354123253Smarcel */ 355125369Sdeischenstruct peer * 356127484Smtmfindpeerbyassoc( 357127484Smtm associd_t assoc 358127484Smtm ) 359{ 360 struct peer *p; 361 u_int hash; 362 363 assocpeer_calls++; 364 hash = assoc & NTP_HASH_MASK; 365 for (p = assoc_hash[hash]; p != NULL; p = p->aid_link) 366 if (assoc == p->associd) 367 break; 368 return p; 369} 370 371 372/* 373 * clear_all - flush all time values for all associations 374 */ 375void 376clear_all(void) 377{ 378 struct peer *p; 379 380 /* 381 * This routine is called when the clock is stepped, and so all 382 * previously saved time values are untrusted. 383 */ 384 for (p = peer_list; p != NULL; p = p->p_link) 385 if (!(MDF_TXONLY_MASK & p->cast_flags)) 386 peer_clear(p, "STEP"); 387 388 DPRINTF(1, ("clear_all: at %lu\n", current_time)); 389} 390 391 392/* 393 * score_all() - determine if an association can be demobilized 394 */ 395int 396score_all( 397 struct peer *peer /* peer structure pointer */ 398 ) 399{ 400 struct peer *speer; 401 int temp, tamp; 402 int x; 403 404 /* 405 * This routine finds the minimum score for all preemptible 406 * associations and returns > 0 if the association can be 407 * demobilized. 408 */ 409 tamp = score(peer); 410 temp = 100; 411 for (speer = peer_list; speer != NULL; speer = speer->p_link) 412 if (speer->flags & FLAG_PREEMPT) { 413 x = score(speer); 414 if (x < temp) 415 temp = x; 416 } 417 DPRINTF(1, ("score_all: at %lu score %d min %d\n", 418 current_time, tamp, temp)); 419 420 if (tamp != temp) 421 temp = 0; 422 423 return temp; 424} 425 426 427/* 428 * score() - calculate preemption score 429 */ 430static int 431score( 432 struct peer *peer /* peer structure pointer */ 433 ) 434{ 435 int temp; 436 437 /* 438 * This routine calculates the premption score from the peer 439 * error bits and status. Increasing values are more cherished. 440 */ 441 temp = 0; 442 if (!(peer->flash & TEST10)) 443 temp++; /* 1 good synch and stratum */ 444 if (!(peer->flash & TEST13)) 445 temp++; /* 2 reachable */ 446 if (!(peer->flash & TEST12)) 447 temp++; /* 3 no loop */ 448 if (!(peer->flash & TEST11)) 449 temp++; /* 4 good distance */ 450 if (peer->status >= CTL_PST_SEL_SELCAND) 451 temp++; /* 5 in the hunt */ 452 if (peer->status != CTL_PST_SEL_EXCESS) 453 temp++; /* 6 not spare tire */ 454 return (temp); /* selection status */ 455} 456 457 458/* 459 * free_peer - internal routine to free memory referred to by a struct 460 * peer and return it to the peer free list. If unlink is 461 * nonzero, unlink from the various lists. 462 */ 463static void 464free_peer( 465 struct peer * p, 466 int unlink_peer 467 ) 468{ 469 struct peer * unlinked; 470 int hash; 471 472 if (unlink_peer) { 473 hash = NTP_HASH_ADDR(&p->srcadr); 474 peer_hash_count[hash]--; 475 476 UNLINK_SLIST(unlinked, peer_hash[hash], p, adr_link, 477 struct peer); 478 if (NULL == unlinked) { 479 peer_hash_count[hash]++; 480 msyslog(LOG_ERR, "peer %s not in address table!", 481 stoa(&p->srcadr)); 482 } 483 484 /* 485 * Remove him from the association hash as well. 486 */ 487 hash = p->associd & NTP_HASH_MASK; 488 assoc_hash_count[hash]--; 489 490 UNLINK_SLIST(unlinked, assoc_hash[hash], p, aid_link, 491 struct peer); 492 if (NULL == unlinked) { 493 assoc_hash_count[hash]++; 494 msyslog(LOG_ERR, 495 "peer %s not in association ID table!", 496 stoa(&p->srcadr)); 497 } 498 499 /* Remove him from the overall list. */ 500 UNLINK_SLIST(unlinked, peer_list, p, p_link, 501 struct peer); 502 if (NULL == unlinked) 503 msyslog(LOG_ERR, "%s not in peer list!", 504 stoa(&p->srcadr)); 505 } 506 507 if (p->hostname != NULL) 508 free(p->hostname); 509 510 if (p->ident != NULL) 511 free(p->ident); 512 513 if (p->addrs != NULL) 514 free(p->addrs); /* from copy_addrinfo_list() */ 515 516 /* Add his corporeal form to peer free list */ 517 ZERO(*p); 518 LINK_SLIST(peer_free, p, p_link); 519 peer_free_count++; 520} 521 522 523/* 524 * unpeer - remove peer structure from hash table and free structure 525 */ 526void 527unpeer( 528 struct peer *peer 529 ) 530{ 531 mprintf_event(PEVNT_DEMOBIL, peer, "assoc %u", peer->associd); 532 restrict_source(&peer->srcadr, 1, 0); 533 set_peerdstadr(peer, NULL); 534 peer_demobilizations++; 535 peer_associations--; 536 if (FLAG_PREEMPT & peer->flags) 537 peer_preempt--; 538#ifdef REFCLOCK 539 /* 540 * If this peer is actually a clock, shut it down first 541 */ 542 if (FLAG_REFCLOCK & peer->flags) 543 refclock_unpeer(peer); 544#endif 545 546 free_peer(peer, TRUE); 547} 548 549 550/* 551 * peer_config - configure a new association 552 */ 553struct peer * 554peer_config( 555 sockaddr_u * srcadr, 556 const char * hostname, 557 endpt * dstadr, 558 u_char hmode, 559 u_char version, 560 u_char minpoll, 561 u_char maxpoll, 562 u_int flags, 563 u_int32 ttl, 564 keyid_t key, 565 const char * ident /* autokey group */ 566 ) 567{ 568 u_char cast_flags; 569 570 /* 571 * We do a dirty little jig to figure the cast flags. This is 572 * probably not the best place to do this, at least until the 573 * configure code is rebuilt. Note only one flag can be set. 574 */ 575 switch (hmode) { 576 case MODE_BROADCAST: 577 if (IS_MCAST(srcadr)) 578 cast_flags = MDF_MCAST; 579 else 580 cast_flags = MDF_BCAST; 581 break; 582 583 case MODE_CLIENT: 584 if (hostname != NULL && SOCK_UNSPEC(srcadr)) 585 cast_flags = MDF_POOL; 586 else if (IS_MCAST(srcadr)) 587 cast_flags = MDF_ACAST; 588 else 589 cast_flags = MDF_UCAST; 590 break; 591 592 default: 593 cast_flags = MDF_UCAST; 594 } 595 596 /* 597 * Mobilize the association and initialize its variables. If 598 * emulating ntpdate, force iburst. For pool and manycastclient 599 * strip FLAG_PREEMPT as the prototype associations are not 600 * themselves preemptible, though the resulting associations 601 * are. 602 */ 603 flags |= FLAG_CONFIG; 604 if (mode_ntpdate) 605 flags |= FLAG_IBURST; 606 if ((MDF_ACAST | MDF_POOL) & cast_flags) 607 flags &= ~FLAG_PREEMPT; 608 return newpeer(srcadr, hostname, dstadr, hmode, version, 609 minpoll, maxpoll, flags, cast_flags, ttl, key, ident); 610} 611 612/* 613 * setup peer dstadr field keeping it in sync with the interface 614 * structures 615 */ 616void 617set_peerdstadr( 618 struct peer * p, 619 endpt * dstadr 620 ) 621{ 622 struct peer * unlinked; 623 624 if (p->dstadr == dstadr) 625 return; 626 627 /* 628 * Don't accept updates to a separate multicast receive-only 629 * endpt while a BCLNT peer is running its unicast protocol. 630 */ 631 if (dstadr != NULL && (FLAG_BC_VOL & p->flags) && 632 (INT_MCASTIF & dstadr->flags) && MODE_CLIENT == p->hmode) { 633 return; 634 } 635 if (p->dstadr != NULL) { 636 p->dstadr->peercnt--; 637 UNLINK_SLIST(unlinked, p->dstadr->peers, p, ilink, 638 struct peer); 639 msyslog(LOG_INFO, "%s local addr %s -> %s", 640 stoa(&p->srcadr), latoa(p->dstadr), 641 latoa(dstadr)); 642 } 643 p->dstadr = dstadr; 644 if (dstadr != NULL) { 645 LINK_SLIST(dstadr->peers, p, ilink); 646 dstadr->peercnt++; 647 } 648} 649 650/* 651 * attempt to re-rebind interface if necessary 652 */ 653static void 654peer_refresh_interface( 655 struct peer *p 656 ) 657{ 658 endpt * niface; 659 endpt * piface; 660 661 niface = select_peerinterface(p, &p->srcadr, NULL); 662 663 DPRINTF(4, ( 664 "peer_refresh_interface: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %u key %08x: new interface: ", 665 p->dstadr == NULL ? "<null>" : 666 stoa(&p->dstadr->sin), stoa(&p->srcadr), p->hmode, 667 p->version, p->minpoll, p->maxpoll, p->flags, p->cast_flags, 668 p->ttl, p->keyid)); 669 if (niface != NULL) { 670 DPRINTF(4, ( 671 "fd=%d, bfd=%d, name=%.16s, flags=0x%x, ifindex=%u, sin=%s", 672 niface->fd, niface->bfd, niface->name, 673 niface->flags, niface->ifindex, 674 stoa(&niface->sin))); 675 if (niface->flags & INT_BROADCAST) 676 DPRINTF(4, (", bcast=%s", 677 stoa(&niface->bcast))); 678 DPRINTF(4, (", mask=%s\n", stoa(&niface->mask))); 679 } else { 680 DPRINTF(4, ("<NONE>\n")); 681 } 682 683 piface = p->dstadr; 684 set_peerdstadr(p, niface); 685 if (p->dstadr != NULL) { 686 /* 687 * clear crypto if we change the local address 688 */ 689 if (p->dstadr != piface && !(MDF_ACAST & p->cast_flags) 690 && MODE_BROADCAST != p->pmode) 691 peer_clear(p, "XFAC"); 692 693 /* 694 * Broadcast needs the socket enabled for broadcast 695 */ 696 if (MDF_BCAST & p->cast_flags) 697 enable_broadcast(p->dstadr, &p->srcadr); 698 699 /* 700 * Multicast needs the socket interface enabled for 701 * multicast 702 */ 703 if (MDF_MCAST & p->cast_flags) 704 enable_multicast_if(p->dstadr, &p->srcadr); 705 } 706} 707 708 709/* 710 * refresh_all_peerinterfaces - see that all interface bindings are up 711 * to date 712 */ 713void 714refresh_all_peerinterfaces(void) 715{ 716 struct peer *p; 717 718 /* 719 * this is called when the interface list has changed 720 * give all peers a chance to find a better interface 721 * but only if either they don't have an address already 722 * or if the one they have hasn't worked for a while. 723 */ 724 for (p = peer_list; p != NULL; p = p->p_link) { 725 if (!(p->dstadr && (p->reach & 0x3))) // Bug 2849 XOR 2043 726 peer_refresh_interface(p); 727 } 728} 729 730 731/* 732 * newpeer - initialize a new peer association 733 */ 734struct peer * 735newpeer( 736 sockaddr_u * srcadr, 737 const char * hostname, 738 endpt * dstadr, 739 u_char hmode, 740 u_char version, 741 u_char minpoll, 742 u_char maxpoll, 743 u_int flags, 744 u_char cast_flags, 745 u_int32 ttl, 746 keyid_t key, 747 const char * ident 748 ) 749{ 750 struct peer * peer; 751 u_int hash; 752 753 DEBUG_REQUIRE(srcadr); 754 755#ifdef AUTOKEY 756 /* 757 * If Autokey is requested but not configured, complain loudly. 758 */ 759 if (!crypto_flags) { 760 if (key > NTP_MAXKEY) { 761 return (NULL); 762 763 } else if (flags & FLAG_SKEY) { 764 msyslog(LOG_ERR, "Autokey not configured"); 765 return (NULL); 766 } 767 } 768#endif /* AUTOKEY */ 769 770 /* 771 * For now only pool associations have a hostname. 772 */ 773 INSIST(NULL == hostname || (MDF_POOL & cast_flags)); 774 775 /* 776 * First search from the beginning for an association with given 777 * remote address and mode. If an interface is given, search 778 * from there to find the association which matches that 779 * destination. If the given interface is "any", track down the 780 * actual interface, because that's what gets put into the peer 781 * structure. 782 */ 783 if (dstadr != NULL) { 784 peer = findexistingpeer(srcadr, hostname, NULL, hmode, 785 cast_flags); 786 while (peer != NULL) { 787 if (peer->dstadr == dstadr || 788 ((MDF_BCLNT & cast_flags) && 789 (MDF_BCLNT & peer->cast_flags))) 790 break; 791 792 if (dstadr == ANY_INTERFACE_CHOOSE(srcadr) && 793 peer->dstadr == findinterface(srcadr)) 794 break; 795 796 peer = findexistingpeer(srcadr, hostname, peer, 797 hmode, cast_flags); 798 } 799 } else { 800 /* no endpt address given */ 801 peer = findexistingpeer(srcadr, hostname, NULL, hmode, 802 cast_flags); 803 } 804 805 /* 806 * If a peer is found, this would be a duplicate and we don't 807 * allow that. This avoids duplicate ephemeral (broadcast/ 808 * multicast) and preemptible (manycast and pool) client 809 * associations. 810 */ 811 if (peer != NULL) { 812 DPRINTF(2, ("newpeer(%s) found existing association\n", 813 (hostname) 814 ? hostname 815 : stoa(srcadr))); 816 return NULL; 817 } 818 819 /* 820 * Allocate a new peer structure. Some dirt here, since some of 821 * the initialization requires knowlege of our system state. 822 */ 823 if (peer_free_count == 0) 824 getmorepeermem(); 825 UNLINK_HEAD_SLIST(peer, peer_free, p_link); 826 INSIST(peer != NULL); 827 peer_free_count--; 828 peer_associations++; 829 if (FLAG_PREEMPT & flags) 830 peer_preempt++; 831 832 /* 833 * Assign an association ID and increment the system variable. 834 */ 835 peer->associd = current_association_ID; 836 if (++current_association_ID == 0) 837 ++current_association_ID; 838 839 peer->srcadr = *srcadr; 840 if (hostname != NULL) 841 peer->hostname = estrdup(hostname); 842 peer->hmode = hmode; 843 peer->version = version; 844 peer->flags = flags; 845 peer->cast_flags = cast_flags; 846 set_peerdstadr(peer, 847 select_peerinterface(peer, srcadr, dstadr)); 848 849 /* 850 * It is an error to set minpoll less than NTP_MINPOLL or to 851 * set maxpoll greater than NTP_MAXPOLL. However, minpoll is 852 * clamped not greater than NTP_MAXPOLL and maxpoll is clamped 853 * not less than NTP_MINPOLL without complaint. Finally, 854 * minpoll is clamped not greater than maxpoll. 855 */ 856 if (minpoll == 0) 857 peer->minpoll = NTP_MINDPOLL; 858 else 859 peer->minpoll = min(minpoll, NTP_MAXPOLL); 860 if (maxpoll == 0) 861 peer->maxpoll = NTP_MAXDPOLL; 862 else 863 peer->maxpoll = max(maxpoll, NTP_MINPOLL); 864 if (peer->minpoll > peer->maxpoll) 865 peer->minpoll = peer->maxpoll; 866 867 if (peer->dstadr != NULL) 868 DPRINTF(3, ("newpeer(%s): using fd %d and our addr %s\n", 869 stoa(srcadr), peer->dstadr->fd, 870 stoa(&peer->dstadr->sin))); 871 else 872 DPRINTF(3, ("newpeer(%s): local interface currently not bound\n", 873 stoa(srcadr))); 874 875 /* 876 * Broadcast needs the socket enabled for broadcast 877 */ 878 if ((MDF_BCAST & cast_flags) && peer->dstadr != NULL) 879 enable_broadcast(peer->dstadr, srcadr); 880 881 /* 882 * Multicast needs the socket interface enabled for multicast 883 */ 884 if ((MDF_MCAST & cast_flags) && peer->dstadr != NULL) 885 enable_multicast_if(peer->dstadr, srcadr); 886 887#ifdef AUTOKEY 888 if (key > NTP_MAXKEY) 889 peer->flags |= FLAG_SKEY; 890#endif /* AUTOKEY */ 891 peer->ttl = ttl; 892 peer->keyid = key; 893 if (ident != NULL) 894 peer->ident = estrdup(ident); 895 peer->precision = sys_precision; 896 peer->hpoll = peer->minpoll; 897 if (cast_flags & MDF_ACAST) 898 peer_clear(peer, "ACST"); 899 else if (cast_flags & MDF_POOL) 900 peer_clear(peer, "POOL"); 901 else if (cast_flags & MDF_MCAST) 902 peer_clear(peer, "MCST"); 903 else if (cast_flags & MDF_BCAST) 904 peer_clear(peer, "BCST"); 905 else 906 peer_clear(peer, "INIT"); 907 if (mode_ntpdate) 908 peer_ntpdate++; 909 910 /* 911 * Note time on statistics timers. 912 */ 913 peer->timereset = current_time; 914 peer->timereachable = current_time; 915 peer->timereceived = current_time; 916 917 if (ISREFCLOCKADR(&peer->srcadr)) { 918#ifdef REFCLOCK 919 /* 920 * We let the reference clock support do clock 921 * dependent initialization. This includes setting 922 * the peer timer, since the clock may have requirements 923 * for this. 924 */ 925 if (maxpoll == 0) 926 peer->maxpoll = peer->minpoll; 927 if (!refclock_newpeer(peer)) { 928 /* 929 * Dump it, something screwed up 930 */ 931 set_peerdstadr(peer, NULL); 932 free_peer(peer, 0); 933 return NULL; 934 } 935#else /* REFCLOCK */ 936 msyslog(LOG_ERR, "refclock %s isn't supported. ntpd was compiled without refclock support.", 937 stoa(&peer->srcadr)); 938 set_peerdstadr(peer, NULL); 939 free_peer(peer, 0); 940 return NULL; 941#endif /* REFCLOCK */ 942 } 943 944 /* 945 * Put the new peer in the hash tables. 946 */ 947 hash = NTP_HASH_ADDR(&peer->srcadr); 948 LINK_SLIST(peer_hash[hash], peer, adr_link); 949 peer_hash_count[hash]++; 950 hash = peer->associd & NTP_HASH_MASK; 951 LINK_SLIST(assoc_hash[hash], peer, aid_link); 952 assoc_hash_count[hash]++; 953 LINK_SLIST(peer_list, peer, p_link); 954 955 restrict_source(&peer->srcadr, 0, 0); 956 mprintf_event(PEVNT_MOBIL, peer, "assoc %d", peer->associd); 957 DPRINTF(1, ("newpeer: %s->%s mode %u vers %u poll %u %u flags 0x%x 0x%x ttl %u key %08x\n", 958 latoa(peer->dstadr), stoa(&peer->srcadr), peer->hmode, 959 peer->version, peer->minpoll, peer->maxpoll, peer->flags, 960 peer->cast_flags, peer->ttl, peer->keyid)); 961 return peer; 962} 963 964 965/* 966 * peer_clr_stats - clear peer module statistics counters 967 */ 968void 969peer_clr_stats(void) 970{ 971 findpeer_calls = 0; 972 assocpeer_calls = 0; 973 peer_allocations = 0; 974 peer_demobilizations = 0; 975 peer_timereset = current_time; 976} 977 978 979/* 980 * peer_reset - reset statistics counters 981 */ 982void 983peer_reset( 984 struct peer *peer 985 ) 986{ 987 if (peer == NULL) 988 return; 989 990 peer->timereset = current_time; 991 peer->sent = 0; 992 peer->received = 0; 993 peer->processed = 0; 994 peer->badauth = 0; 995 peer->bogusorg = 0; 996 peer->oldpkt = 0; 997 peer->seldisptoolarge = 0; 998 peer->selbroken = 0; 999} 1000 1001 1002/* 1003 * peer_all_reset - reset all peer statistics counters 1004 */ 1005void 1006peer_all_reset(void) 1007{ 1008 struct peer *peer; 1009 1010 for (peer = peer_list; peer != NULL; peer = peer->p_link) 1011 peer_reset(peer); 1012} 1013 1014 1015/* 1016 * findmanycastpeer - find and return a manycastclient or pool 1017 * association matching a received response. 1018 */ 1019struct peer * 1020findmanycastpeer( 1021 struct recvbuf *rbufp /* receive buffer pointer */ 1022 ) 1023{ 1024 struct peer *peer; 1025 struct pkt *pkt; 1026 l_fp p_org; 1027 1028 /* 1029 * This routine is called upon arrival of a server-mode response 1030 * to a manycastclient multicast solicitation, or to a pool 1031 * server unicast solicitation. Search the peer list for a 1032 * manycastclient association where the last transmit timestamp 1033 * matches the response packet's originate timestamp. There can 1034 * be multiple manycastclient associations, or multiple pool 1035 * solicitation assocations, so this assumes the transmit 1036 * timestamps are unique for such. 1037 */ 1038 pkt = &rbufp->recv_pkt; 1039 for (peer = peer_list; peer != NULL; peer = peer->p_link) 1040 if (MDF_SOLICIT_MASK & peer->cast_flags) { 1041 NTOHL_FP(&pkt->org, &p_org); 1042 if (L_ISEQU(&p_org, &peer->aorg)) 1043 break; 1044 } 1045 1046 return peer; 1047} 1048 1049/* peer_cleanup - clean peer list prior to shutdown */ 1050void peer_cleanup(void) 1051{ 1052 struct peer *peer; 1053 associd_t assoc; 1054 1055 for (assoc = initial_association_ID; assoc != current_association_ID; assoc++) { 1056 if (assoc != 0U) { 1057 peer = findpeerbyassoc(assoc); 1058 if (peer != NULL) 1059 unpeer(peer); 1060 } 1061 } 1062 peer = findpeerbyassoc(current_association_ID); 1063 if (peer != NULL) 1064 unpeer(peer); 1065} 1066