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_stdlib.h" 13 #ifdef OPENSSL 14 #include "openssl/rand.h" 15 #endif /* OPENSSL */ 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 e 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 1 28 * SERVER | e 0 0 0 0 0 29 * BCAST | e 0 0 0 0 0 30 * CONTROL | e 0 0 0 0 0 31 * PRIVATE | e 0 0 0 0 0 32 * BCLIENT | e 0 0 0 e 1 33 * 34 * One point to note here: a packet in BCAST mode can potentially match 35 * a peer in CLIENT mode, but we that is a special case and we check for 36 * that early in the decision process. This avoids having to keep track 37 * of what kind of associations are possible etc... We actually 38 * circumvent that problem by requiring that the first b(m)roadcast 39 * received after the change back to BCLIENT mode sets the clock. 40 */ 41 42 int AM[AM_MODES][AM_MODES] = { 43 /* { UNSPEC, ACTIVE, PASSIVE, CLIENT, SERVER, BCAST } */ 44 45 /*NONE*/{ AM_ERR, AM_NEWPASS, AM_ERR, AM_FXMIT, AM_MANYCAST, AM_NEWBCL}, 46 47 /*A*/ { AM_ERR, AM_PROCPKT, AM_PROCPKT, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 48 49 /*P*/ { AM_ERR, AM_PROCPKT, AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 50 51 /*C*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_PROCPKT, AM_POSSBCL}, 52 53 /*S*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 54 55 /*BCST*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 56 57 /*CNTL*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 58 59 /*PRIV*/{ AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH}, 60 61 /*BCL*/ { AM_ERR, AM_NOMATCH, AM_NOMATCH, AM_NOMATCH, AM_ERR, AM_PROCPKT}, 62 }; 63 64 #define MATCH_ASSOC(x,y) AM[(x)][(y)] 65 66 /* 67 * These routines manage the allocation of memory to peer structures 68 * and the maintenance of the peer hash table. The two main entry 69 * points are findpeer(), which looks for matching peer sturctures in 70 * the peer list, newpeer(), which allocates a new peer structure and 71 * adds it to the list, and unpeer(), which demobilizes the association 72 * and deallocates the structure. 73 */ 74 /* 75 * Peer hash tables 76 */ 77 struct peer *peer_hash[HASH_SIZE]; /* peer hash table */ 78 int peer_hash_count[HASH_SIZE]; /* peers in each bucket */ 79 struct peer *assoc_hash[HASH_SIZE]; /* association ID hash table */ 80 int assoc_hash_count[HASH_SIZE]; /* peers in each bucket */ 81 static struct peer *peer_free; /* peer structures free list */ 82 int peer_free_count; /* count of free structures */ 83 84 /* 85 * Association ID. We initialize this value randomly, then assign a new 86 * value every time the peer structure is incremented. 87 */ 88 static associd_t current_association_ID; /* association ID */ 89 90 /* 91 * Memory allocation watermarks. 92 */ 93 #define INIT_PEER_ALLOC 15 /* initialize for 15 peers */ 94 #define INC_PEER_ALLOC 5 /* when run out, add 5 more */ 95 96 /* 97 * Miscellaneous statistic counters which may be queried. 98 */ 99 u_long peer_timereset; /* time stat counters zeroed */ 100 u_long findpeer_calls; /* calls to findpeer */ 101 u_long assocpeer_calls; /* calls to findpeerbyassoc */ 102 u_long peer_allocations; /* allocations from free list */ 103 u_long peer_demobilizations; /* structs freed to free list */ 104 int total_peer_structs; /* peer structs */ 105 int peer_associations; /* active associations */ 106 static struct peer init_peer_alloc[INIT_PEER_ALLOC]; /* init alloc */ 107 108 static void getmorepeermem P((void)); 109 110 /* 111 * init_peer - initialize peer data structures and counters 112 * 113 * N.B. We use the random number routine in here. It had better be 114 * initialized prior to getting here. 115 */ 116 void 117 init_peer(void) 118 { 119 register int i; 120 121 /* 122 * Clear hash table and counters. 123 */ 124 for (i = 0; i < HASH_SIZE; i++) { 125 peer_hash[i] = 0; 126 peer_hash_count[i] = 0; 127 assoc_hash[i] = 0; 128 assoc_hash_count[i] = 0; 129 } 130 131 /* 132 * Clear stat counters 133 */ 134 findpeer_calls = peer_allocations = 0; 135 assocpeer_calls = peer_demobilizations = 0; 136 137 /* 138 * Initialize peer memory. 139 */ 140 peer_free = 0; 141 for (i = 0; i < INIT_PEER_ALLOC; i++) { 142 init_peer_alloc[i].next = peer_free; 143 peer_free = &init_peer_alloc[i]; 144 } 145 total_peer_structs = INIT_PEER_ALLOC; 146 peer_free_count = INIT_PEER_ALLOC; 147 148 /* 149 * Initialize our first association ID 150 */ 151 current_association_ID = (associd_t)ranp2(16); 152 if (current_association_ID == 0) 153 current_association_ID = 1; 154 } 155 156 157 /* 158 * getmorepeermem - add more peer structures to the free list 159 */ 160 static void 161 getmorepeermem(void) 162 { 163 register int i; 164 register struct peer *peer; 165 166 peer = (struct peer *)emalloc(INC_PEER_ALLOC * 167 sizeof(struct peer)); 168 for (i = 0; i < INC_PEER_ALLOC; i++) { 169 peer->next = peer_free; 170 peer_free = peer; 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 */ 182 struct peer * 183 findexistingpeer( 184 struct sockaddr_storage *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 (start_peer == 0) 196 peer = peer_hash[HASH_ADDR(addr)]; 197 else 198 peer = start_peer->next; 199 200 while (peer != 0) { 201 if (SOCKCMP(addr, &peer->srcadr) 202 && NSRCPORT(addr) == NSRCPORT(&peer->srcadr)) { 203 if (mode == -1) 204 return (peer); 205 else if (peer->hmode == mode) 206 break; 207 } 208 peer = peer->next; 209 } 210 return (peer); 211 } 212 213 214 /* 215 * findpeer - find and return a peer in the hash table. 216 */ 217 struct peer * 218 findpeer( 219 struct sockaddr_storage *srcadr, 220 struct interface *dstadr, 221 int fd, 222 int pkt_mode, 223 int *action 224 ) 225 { 226 register struct peer *peer; 227 int hash; 228 229 findpeer_calls++; 230 hash = HASH_ADDR(srcadr); 231 for (peer = peer_hash[hash]; peer != NULL; peer = peer->next) { 232 if (SOCKCMP(srcadr, &peer->srcadr) 233 && NSRCPORT(srcadr) == NSRCPORT(&peer->srcadr)) { 234 235 /* 236 * if the association matching rules determine 237 * that this is not a valid combination, then 238 * look for the next valid peer association. 239 */ 240 *action = MATCH_ASSOC(peer->hmode, pkt_mode); 241 242 /* 243 * Sigh! Check if BCLIENT peer in client 244 * server mode, else return error. 245 */ 246 if ((*action == AM_POSSBCL) && !(peer->flags & 247 FLAG_MCAST)) 248 *action = AM_ERR; 249 250 /* 251 * if an error was returned, exit back right 252 * here. 253 */ 254 if (*action == AM_ERR) 255 return ((struct peer *)0); 256 257 /* 258 * if a match is found, we stop our search. 259 */ 260 if (*action != AM_NOMATCH) 261 break; 262 } 263 } 264 265 /* 266 * If no matching association is found 267 */ 268 if (peer == 0) { 269 *action = MATCH_ASSOC(NO_PEER, pkt_mode); 270 return ((struct peer *)0); 271 } 272 peer->dstadr = dstadr; 273 return (peer); 274 } 275 276 /* 277 * findpeerbyassocid - find and return a peer using his association ID 278 */ 279 struct peer * 280 findpeerbyassoc( 281 u_int assoc 282 ) 283 { 284 register struct peer *peer; 285 int hash; 286 287 assocpeer_calls++; 288 289 hash = assoc & HASH_MASK; 290 for (peer = assoc_hash[hash]; peer != 0; peer = 291 peer->ass_next) { 292 if (assoc == peer->associd) 293 return (peer); 294 } 295 return (NULL); 296 } 297 298 299 /* 300 * clear_all - flush all time values for all associations 301 */ 302 void 303 clear_all(void) 304 { 305 struct peer *peer, *next_peer; 306 int n; 307 308 /* 309 * This routine is called when the clock is stepped, and so all 310 * previously saved time values are untrusted. 311 */ 312 for (n = 0; n < HASH_SIZE; n++) { 313 for (peer = peer_hash[n]; peer != 0; peer = next_peer) { 314 next_peer = peer->next; 315 if (peer->flags & FLAG_CONFIG) { 316 if (!(peer->cast_flags & (MDF_ACAST | 317 MDF_MCAST | MDF_BCAST))) 318 peer_clear(peer, "STEP"); 319 } else { 320 unpeer(peer); 321 } 322 } 323 } 324 #ifdef DEBUG 325 if (debug) 326 printf("clear_all: at %lu\n", current_time); 327 #endif 328 } 329 330 331 /* 332 * unpeer - remove peer structure from hash table and free structure 333 */ 334 void 335 unpeer( 336 struct peer *peer_to_remove 337 ) 338 { 339 int hash; 340 #ifdef OPENSSL 341 char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ 342 343 if (peer_to_remove->flags & FLAG_SKEY) { 344 sprintf(statstr, "unpeer %d flash %x reach %03o flags %04x", 345 peer_to_remove->associd, peer_to_remove->flash, 346 peer_to_remove->reach, peer_to_remove->flags); 347 record_crypto_stats(&peer_to_remove->srcadr, statstr); 348 #ifdef DEBUG 349 if (debug) 350 printf("peer: %s\n", statstr); 351 #endif 352 } 353 #endif /* OPENSSL */ 354 #ifdef DEBUG 355 if (debug) 356 printf("demobilize %u %d\n", peer_to_remove->associd, 357 peer_associations); 358 #endif 359 peer_clear(peer_to_remove, "NULL"); 360 hash = HASH_ADDR(&peer_to_remove->srcadr); 361 peer_hash_count[hash]--; 362 peer_demobilizations++; 363 #ifdef REFCLOCK 364 /* 365 * If this peer is actually a clock, shut it down first 366 */ 367 if (peer_to_remove->flags & FLAG_REFCLOCK) 368 refclock_unpeer(peer_to_remove); 369 #endif 370 peer_to_remove->action = 0; /* disable timeout actions */ 371 if (peer_hash[hash] == peer_to_remove) 372 peer_hash[hash] = peer_to_remove->next; 373 else { 374 register struct peer *peer; 375 376 peer = peer_hash[hash]; 377 while (peer != 0 && peer->next != peer_to_remove) 378 peer = peer->next; 379 380 if (peer == 0) { 381 peer_hash_count[hash]++; 382 msyslog(LOG_ERR, "peer struct for %s not in table!", 383 stoa(&peer->srcadr)); 384 } else { 385 peer->next = peer_to_remove->next; 386 } 387 } 388 389 /* 390 * Remove him from the association hash as well. 391 */ 392 hash = peer_to_remove->associd & HASH_MASK; 393 assoc_hash_count[hash]--; 394 if (assoc_hash[hash] == peer_to_remove) 395 assoc_hash[hash] = peer_to_remove->ass_next; 396 else { 397 register struct peer *peer; 398 399 peer = assoc_hash[hash]; 400 while (peer != 0 && peer->ass_next != peer_to_remove) 401 peer = peer->ass_next; 402 403 if (peer == 0) { 404 assoc_hash_count[hash]++; 405 msyslog(LOG_ERR, 406 "peer struct for %s not in association table!", 407 stoa(&peer->srcadr)); 408 } else { 409 peer->ass_next = peer_to_remove->ass_next; 410 } 411 } 412 peer_to_remove->next = peer_free; 413 peer_free = peer_to_remove; 414 peer_free_count++; 415 peer_associations--; 416 } 417 418 419 /* 420 * peer_config - configure a new association 421 */ 422 struct peer * 423 peer_config( 424 struct sockaddr_storage *srcadr, 425 struct interface *dstadr, 426 int hmode, 427 int version, 428 int minpoll, 429 int maxpoll, 430 u_int flags, 431 int ttl, 432 keyid_t key, 433 u_char *keystr 434 ) 435 { 436 register struct peer *peer; 437 u_char cast_flags; 438 439 /* 440 * First search from the beginning for an association with given 441 * remote address and mode. If an interface is given, search 442 * from there to find the association which matches that 443 * destination. 444 */ 445 peer = findexistingpeer(srcadr, (struct peer *)0, hmode); 446 if (dstadr != 0) { 447 while (peer != 0) { 448 if (peer->dstadr == dstadr) 449 break; 450 peer = findexistingpeer(srcadr, peer, hmode); 451 } 452 } 453 454 /* 455 * We do a dirty little jig to figure the cast flags. This is 456 * probably not the best place to do this, at least until the 457 * configure code is rebuilt. Note only one flag can be set. 458 */ 459 switch (hmode) { 460 461 case MODE_BROADCAST: 462 if(srcadr->ss_family == AF_INET) { 463 if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr))) 464 cast_flags = MDF_MCAST; 465 else 466 cast_flags = MDF_BCAST; 467 break; 468 } 469 else { 470 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr)) 471 cast_flags = MDF_MCAST; 472 else 473 cast_flags = MDF_BCAST; 474 break; 475 } 476 477 case MODE_CLIENT: 478 if(srcadr->ss_family == AF_INET) { 479 if (IN_CLASSD(ntohl(((struct sockaddr_in*)srcadr)->sin_addr.s_addr))) 480 cast_flags = MDF_ACAST; 481 else 482 cast_flags = MDF_UCAST; 483 break; 484 } 485 else { 486 if (IN6_IS_ADDR_MULTICAST(&((struct sockaddr_in6*)srcadr)->sin6_addr)) 487 cast_flags = MDF_ACAST; 488 else 489 cast_flags = MDF_UCAST; 490 break; 491 } 492 493 default: 494 cast_flags = MDF_UCAST; 495 } 496 497 /* 498 * If the peer is already configured, some dope has a duplicate 499 * configureation entry or another dope is wiggling from afar. 500 */ 501 if (peer != 0) { 502 peer->hmode = (u_char)hmode; 503 peer->version = (u_char) version; 504 peer->minpoll = (u_char) minpoll; 505 peer->maxpoll = (u_char) maxpoll; 506 peer->flags = flags | FLAG_CONFIG | 507 (peer->flags & FLAG_REFCLOCK); 508 peer->cast_flags = cast_flags; 509 peer->ttl = (u_char) ttl; 510 peer->keyid = key; 511 peer->precision = sys_precision; 512 peer_clear(peer, "RMOT"); 513 return (peer); 514 } 515 516 /* 517 * Here no match has been found, so presumably this is a new 518 * persistent association. Mobilize the thing and initialize its 519 * variables. If emulating ntpdate, force iburst. 520 */ 521 if (mode_ntpdate) 522 flags |= FLAG_IBURST; 523 peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, 524 flags | FLAG_CONFIG, cast_flags, ttl, key); 525 return (peer); 526 } 527 528 529 /* 530 * newpeer - initialize a new peer association 531 */ 532 struct peer * 533 newpeer( 534 struct sockaddr_storage *srcadr, 535 struct interface *dstadr, 536 int hmode, 537 int version, 538 int minpoll, 539 int maxpoll, 540 u_int flags, 541 u_char cast_flags, 542 int ttl, 543 keyid_t key 544 ) 545 { 546 register struct peer *peer; 547 register int i; 548 #ifdef OPENSSL 549 char statstr[NTP_MAXSTRLEN]; /* statistics for filegen */ 550 #endif /* OPENSSL */ 551 552 /* 553 * Allocate a new peer structure. Some dirt here, since some of 554 * the initialization requires knowlege of our system state. 555 */ 556 if (peer_free_count == 0) 557 getmorepeermem(); 558 peer = peer_free; 559 peer_free = peer->next; 560 peer_free_count--; 561 peer_associations++; 562 memset((char *)peer, 0, sizeof(struct peer)); 563 564 /* 565 * Assign an association ID and increment the system variable. 566 */ 567 peer->associd = current_association_ID; 568 if (++current_association_ID == 0) 569 ++current_association_ID; 570 571 /* 572 * Initialize the peer structure and dance the interface jig. 573 * Reference clocks step the loopback waltz, the others 574 * squaredance around the interface list looking for a buddy. If 575 * the dance peters out, there is always the wildcard interface. 576 * This might happen in some systems and would preclude proper 577 * operation with public key cryptography. 578 */ 579 if (ISREFCLOCKADR(srcadr)) 580 peer->dstadr = loopback_interface; 581 else if (cast_flags & (MDF_BCLNT | MDF_ACAST | MDF_MCAST | MDF_BCAST)) { 582 peer->dstadr = findbcastinter(srcadr); 583 /* 584 * If it was a multicast packet, findbcastinter() may not 585 * find it, so try a little harder. 586 */ 587 if (peer->dstadr == ANY_INTERFACE_CHOOSE(srcadr)) 588 peer->dstadr = findinterface(srcadr); 589 } else if (dstadr != NULL && dstadr != ANY_INTERFACE_CHOOSE(srcadr)) 590 peer->dstadr = dstadr; 591 else 592 peer->dstadr = findinterface(srcadr); 593 peer->srcadr = *srcadr; 594 peer->hmode = (u_char)hmode; 595 peer->version = (u_char)version; 596 peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll); 597 peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll); 598 peer->flags = flags; 599 if (key != 0) 600 peer->flags |= FLAG_AUTHENABLE; 601 if (key > NTP_MAXKEY) 602 peer->flags |= FLAG_SKEY; 603 peer->cast_flags = cast_flags; 604 peer->ttl = (u_char)ttl; 605 peer->keyid = key; 606 peer->precision = sys_precision; 607 if (cast_flags & MDF_ACAST) 608 peer_clear(peer, "ACST"); 609 else if (cast_flags & MDF_MCAST) 610 peer_clear(peer, "MCST"); 611 else if (cast_flags & MDF_BCAST) 612 peer_clear(peer, "BCST"); 613 else 614 peer_clear(peer, "INIT"); 615 if (mode_ntpdate) 616 peer_ntpdate++; 617 618 /* 619 * Note time on statistics timers. 620 */ 621 peer->timereset = current_time; 622 peer->timereachable = current_time; 623 peer->timereceived = current_time; 624 #ifdef REFCLOCK 625 if (ISREFCLOCKADR(&peer->srcadr)) { 626 /* 627 * We let the reference clock support do clock 628 * dependent initialization. This includes setting 629 * the peer timer, since the clock may have requirements 630 * for this. 631 */ 632 if (!refclock_newpeer(peer)) { 633 /* 634 * Dump it, something screwed up 635 */ 636 peer->next = peer_free; 637 peer_free = peer; 638 peer_free_count++; 639 return (NULL); 640 } 641 } 642 #endif 643 644 /* 645 * Put the new peer in the hash tables. 646 */ 647 i = HASH_ADDR(&peer->srcadr); 648 peer->next = peer_hash[i]; 649 peer_hash[i] = peer; 650 peer_hash_count[i]++; 651 i = peer->associd & HASH_MASK; 652 peer->ass_next = assoc_hash[i]; 653 assoc_hash[i] = peer; 654 assoc_hash_count[i]++; 655 #ifdef OPENSSL 656 if (peer->flags & FLAG_SKEY) { 657 sprintf(statstr, "newpeer %d", peer->associd); 658 record_crypto_stats(&peer->srcadr, statstr); 659 #ifdef DEBUG 660 if (debug) 661 printf("peer: %s\n", statstr); 662 #endif 663 } 664 #endif /* OPENSSL */ 665 #ifdef DEBUG 666 if (debug) 667 printf( 668 "newpeer: %s->%s mode %d vers %d poll %d %d flags 0x%x 0x%x ttl %d key %08x\n", 669 peer->dstadr == NULL ? "null" : stoa(&peer->dstadr->sin), 670 stoa(&peer->srcadr), 671 peer->hmode, peer->version, peer->minpoll, 672 peer->maxpoll, peer->flags, peer->cast_flags, 673 peer->ttl, peer->keyid); 674 #endif 675 return (peer); 676 } 677 678 679 /* 680 * peer_unconfig - remove the configuration bit from a peer 681 */ 682 int 683 peer_unconfig( 684 struct sockaddr_storage *srcadr, 685 struct interface *dstadr, 686 int mode 687 ) 688 { 689 register struct peer *peer; 690 int num_found; 691 692 num_found = 0; 693 peer = findexistingpeer(srcadr, (struct peer *)0, mode); 694 while (peer != 0) { 695 if (peer->flags & FLAG_CONFIG 696 && (dstadr == 0 || peer->dstadr == dstadr)) { 697 num_found++; 698 699 /* 700 * Tricky stuff here. If the peer is polling us 701 * in active mode, turn off the configuration 702 * bit and make the mode passive. This allows us 703 * to avoid dumping a lot of history for peers 704 * we might choose to keep track of in passive 705 * mode. The protocol will eventually terminate 706 * undesirables on its own. 707 */ 708 if (peer->hmode == MODE_ACTIVE 709 && peer->pmode == MODE_ACTIVE) { 710 peer->hmode = MODE_PASSIVE; 711 peer->flags &= ~FLAG_CONFIG; 712 } else { 713 unpeer(peer); 714 peer = 0; 715 } 716 } 717 peer = findexistingpeer(srcadr, peer, mode); 718 } 719 return (num_found); 720 } 721 722 /* 723 * peer_clr_stats - clear peer module stat counters 724 */ 725 void 726 peer_clr_stats(void) 727 { 728 findpeer_calls = 0; 729 assocpeer_calls = 0; 730 peer_allocations = 0; 731 peer_demobilizations = 0; 732 peer_timereset = current_time; 733 } 734 735 /* 736 * peer_reset - reset stat counters in a peer structure 737 */ 738 void 739 peer_reset( 740 struct peer *peer 741 ) 742 { 743 if (peer == 0) 744 return; 745 peer->sent = 0; 746 peer->received = 0; 747 peer->processed = 0; 748 peer->badauth = 0; 749 peer->bogusorg = 0; 750 peer->oldpkt = 0; 751 peer->seldisptoolarge = 0; 752 peer->selbroken = 0; 753 peer->rank = 0; 754 peer->timereset = current_time; 755 } 756 757 758 /* 759 * peer_all_reset - reset all peer stat counters 760 */ 761 void 762 peer_all_reset(void) 763 { 764 struct peer *peer; 765 int hash; 766 767 for (hash = 0; hash < HASH_SIZE; hash++) 768 for (peer = peer_hash[hash]; peer != 0; peer = peer->next) 769 peer_reset(peer); 770 } 771 772 773 #ifdef OPENSSL 774 /* 775 * expire_all - flush all crypto data and update timestamps. 776 */ 777 void 778 expire_all(void) 779 { 780 struct peer *peer, *next_peer; 781 int n; 782 783 /* 784 * This routine is called about once per day from the timer 785 * routine and when the client is first synchronized. Search the 786 * peer list for all associations and flush only the key list 787 * and cookie. If a manycast client association, flush 788 * everything. Then, recompute and sign the agreement public 789 * value, if present. 790 */ 791 if (!crypto_flags) 792 return; 793 for (n = 0; n < HASH_SIZE; n++) { 794 for (peer = peer_hash[n]; peer != 0; peer = next_peer) { 795 next_peer = peer->next; 796 if (!(peer->flags & FLAG_SKEY)) { 797 continue; 798 } else if (peer->cast_flags & MDF_ACAST) { 799 peer_clear(peer, "ACST"); 800 } else if (peer->hmode == MODE_ACTIVE || 801 peer->hmode == MODE_PASSIVE) { 802 key_expire(peer); 803 peer->crypto &= ~(CRYPTO_FLAG_AUTO | 804 CRYPTO_FLAG_AGREE); 805 } 806 807 } 808 } 809 RAND_bytes((u_char *)&sys_private, 4); 810 crypto_update(); 811 resetmanycast(); 812 } 813 #endif /* OPENSSL */ 814 815 816 /* 817 * findmanycastpeer - find and return a manycast peer 818 */ 819 struct peer * 820 findmanycastpeer( 821 struct recvbuf *rbufp 822 ) 823 { 824 register struct peer *peer; 825 struct pkt *pkt; 826 l_fp p_org; 827 int i; 828 829 /* 830 * This routine is called upon arrival of a client-mode message 831 * from a manycast server. Search the peer list for a manycast 832 * client association where the last transmit timestamp matches 833 * the originate timestamp. This assumes the transmit timestamps 834 * for possibly more than one manycast association are unique. 835 */ 836 pkt = &rbufp->recv_pkt; 837 for (i = 0; i < HASH_SIZE; i++) { 838 if (peer_hash_count[i] == 0) 839 continue; 840 841 for (peer = peer_hash[i]; peer != 0; peer = 842 peer->next) { 843 if (peer->cast_flags & MDF_ACAST) { 844 NTOHL_FP(&pkt->org, &p_org); 845 if (L_ISEQU(&peer->xmt, &p_org)) 846 return (peer); 847 } 848 } 849 } 850 return (NULL); 851 } 852 853 854 /* 855 * resetmanycast - reset all manycast clients 856 */ 857 void 858 resetmanycast(void) 859 { 860 register struct peer *peer; 861 int i; 862 863 /* 864 * This routine is called when the number of client associations 865 * falls below the minimum. Search the peer list for manycast 866 * client associations and reset the ttl and poll interval. 867 */ 868 for (i = 0; i < HASH_SIZE; i++) { 869 if (peer_hash_count[i] == 0) 870 continue; 871 872 for (peer = peer_hash[i]; peer != 0; peer = 873 peer->next) { 874 if (peer->cast_flags & MDF_ACAST) { 875 peer->ttl = 0; 876 poll_update(peer, 0); 877 } 878 } 879 } 880 } 881