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 AUTOKEY 14 #include "ntp_crypto.h" 15 #endif /* AUTOKEY */ 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_in *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 (NSRCADR(addr) == NSRCADR(&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_in *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 != 0; peer = peer->next) { 232 if (NSRCADR(srcadr) == NSRCADR(&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 peer_clear(peer); 316 } 317 } 318 #ifdef DEBUG 319 if (debug) 320 printf("clear_all: at %lu\n", current_time); 321 #endif 322 } 323 324 325 /* 326 * unpeer - remove peer structure from hash table and free structure 327 */ 328 void 329 unpeer( 330 struct peer *peer_to_remove 331 ) 332 { 333 int hash; 334 335 peer_associations--; 336 #ifdef DEBUG 337 if (debug) 338 printf("demobilize %u %d\n", peer_to_remove->associd, 339 peer_associations); 340 #endif 341 peer_clear(peer_to_remove); 342 hash = HASH_ADDR(&peer_to_remove->srcadr); 343 peer_hash_count[hash]--; 344 peer_demobilizations++; 345 #ifdef REFCLOCK 346 /* 347 * If this peer is actually a clock, shut it down first 348 */ 349 if (peer_to_remove->flags & FLAG_REFCLOCK) 350 refclock_unpeer(peer_to_remove); 351 #endif 352 peer_to_remove->action = 0; /* disable timeout actions */ 353 if (peer_hash[hash] == peer_to_remove) 354 peer_hash[hash] = peer_to_remove->next; 355 else { 356 register struct peer *peer; 357 358 peer = peer_hash[hash]; 359 while (peer != 0 && peer->next != peer_to_remove) 360 peer = peer->next; 361 362 if (peer == 0) { 363 peer_hash_count[hash]++; 364 msyslog(LOG_ERR, "peer struct for %s not in table!", 365 ntoa(&peer->srcadr)); 366 } else { 367 peer->next = peer_to_remove->next; 368 } 369 } 370 371 /* 372 * Remove him from the association hash as well. 373 */ 374 hash = peer_to_remove->associd & HASH_MASK; 375 assoc_hash_count[hash]--; 376 if (assoc_hash[hash] == peer_to_remove) 377 assoc_hash[hash] = peer_to_remove->ass_next; 378 else { 379 register struct peer *peer; 380 381 peer = assoc_hash[hash]; 382 while (peer != 0 && peer->ass_next != peer_to_remove) 383 peer = peer->ass_next; 384 385 if (peer == 0) { 386 assoc_hash_count[hash]++; 387 msyslog(LOG_ERR, 388 "peer struct for %s not in association table!", 389 ntoa(&peer->srcadr)); 390 } else { 391 peer->ass_next = peer_to_remove->ass_next; 392 } 393 } 394 peer_to_remove->next = peer_free; 395 peer_free = peer_to_remove; 396 peer_free_count++; 397 } 398 399 400 /* 401 * peer_config - configure a new association 402 */ 403 struct peer * 404 peer_config( 405 struct sockaddr_in *srcadr, 406 struct interface *dstadr, 407 int hmode, 408 int version, 409 int minpoll, 410 int maxpoll, 411 u_int flags, 412 int ttl, 413 keyid_t key, 414 u_char *keystr 415 ) 416 { 417 register struct peer *peer; 418 u_int cast_flags; 419 420 /* 421 * First search from the beginning for an association with given 422 * remote address and mode. If an interface is given, search 423 * from there to find the association which matches that 424 * destination. 425 */ 426 peer = findexistingpeer(srcadr, (struct peer *)0, hmode); 427 if (dstadr != 0) { 428 while (peer != 0) { 429 if (peer->dstadr == dstadr) 430 break; 431 peer = findexistingpeer(srcadr, peer, hmode); 432 } 433 } 434 435 /* 436 * We do a dirty little jig to figure the cast flags. This is 437 * probably not the best place to do this, at least until the 438 * configure code is rebuilt. Note only one flag can be set. 439 */ 440 switch (hmode) { 441 442 case MODE_BROADCAST: 443 if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr))) 444 cast_flags = MDF_MCAST; 445 else 446 cast_flags = MDF_BCAST; 447 break; 448 449 case MODE_CLIENT: 450 if (IN_CLASSD(ntohl(srcadr->sin_addr.s_addr))) 451 cast_flags = MDF_ACAST; 452 else 453 cast_flags = MDF_UCAST; 454 break; 455 456 default: 457 cast_flags = MDF_UCAST; 458 break; 459 } 460 461 /* 462 * If the peer is already configured, some dope has a duplicate 463 * configureation entry or another dope is wiggling from afar. 464 */ 465 if (peer != 0) { 466 peer->hmode = (u_char)hmode; 467 peer->version = (u_char)version; 468 peer->minpoll = (u_char)minpoll; 469 peer->maxpoll = (u_char)maxpoll; 470 peer->hpoll = peer->kpoll = peer->minpoll; 471 peer->ppoll = peer->maxpoll; 472 peer->flags = flags | FLAG_CONFIG | 473 (peer->flags & FLAG_REFCLOCK); 474 peer->cast_flags = cast_flags; 475 peer->ttlmax = ttl; 476 peer->keyid = key; 477 return (peer); 478 } 479 480 /* 481 * Here no match has been found, so presumably this is a new 482 * persistent association. Mobilize the thing and initialize its 483 * variables. 484 */ 485 peer = newpeer(srcadr, dstadr, hmode, version, minpoll, maxpoll, 486 flags | FLAG_CONFIG, cast_flags, ttl, key); 487 return (peer); 488 } 489 490 491 /* 492 * newpeer - initialize a new peer association 493 */ 494 struct peer * 495 newpeer( 496 struct sockaddr_in *srcadr, 497 struct interface *dstadr, 498 int hmode, 499 int version, 500 int minpoll, 501 int maxpoll, 502 u_int flags, 503 u_int cast_flags, 504 int ttl, 505 keyid_t key 506 ) 507 { 508 register struct peer *peer; 509 register int i; 510 511 /* 512 * Allocate a new peer structure. Some dirt here, since some of 513 * the initialization requires knowlege of our system state. 514 */ 515 if (peer_free_count == 0) 516 getmorepeermem(); 517 peer = peer_free; 518 peer_free = peer->next; 519 peer_free_count--; 520 peer_associations++; 521 memset((char *)peer, 0, sizeof(struct peer)); 522 523 /* 524 * Initialize the peer structure and dance the interface jig. 525 * Reference clocks step the loopback waltz, the others 526 * squaredance around the interface list looking for a buddy. If 527 * the dance peters out, there is always the wildcard interface. 528 * This might happen in some systems and would preclude proper 529 * operation with public key cryptography. 530 */ 531 if (ISREFCLOCKADR(srcadr)) 532 peer->dstadr = loopback_interface; 533 else if (cast_flags & MDF_BCLNT) 534 peer->dstadr = findbcastinter(srcadr); 535 else if (dstadr != any_interface) 536 peer->dstadr = dstadr; 537 else 538 peer->dstadr = findinterface(srcadr); 539 peer->srcadr = *srcadr; 540 peer->hmode = (u_char)hmode; 541 peer->version = (u_char)version; 542 peer->minpoll = (u_char)max(NTP_MINPOLL, minpoll); 543 peer->maxpoll = (u_char)min(NTP_MAXPOLL, maxpoll); 544 peer->flags = flags | (key > NTP_MAXKEY ? FLAG_SKEY : 0); 545 peer->cast_flags = cast_flags; 546 peer->ttlmax = ttl; 547 peer->keyid = key; 548 peer->precision = sys_precision; 549 peer_clear(peer); 550 if (mode_ntpdate) 551 peer_ntpdate++; 552 553 /* 554 * Assign an association ID and increment the system variable. 555 */ 556 peer->associd = current_association_ID; 557 if (++current_association_ID == 0) 558 ++current_association_ID; 559 560 /* 561 * Note time on statistics timers. 562 */ 563 peer->timereset = current_time; 564 peer->timereachable = current_time; 565 peer->timereceived = current_time; 566 #ifdef REFCLOCK 567 if (ISREFCLOCKADR(&peer->srcadr)) { 568 /* 569 * We let the reference clock support do clock 570 * dependent initialization. This includes setting 571 * the peer timer, since the clock may have requirements 572 * for this. 573 */ 574 if (!refclock_newpeer(peer)) { 575 /* 576 * Dump it, something screwed up 577 */ 578 peer->next = peer_free; 579 peer_free = peer; 580 peer_free_count++; 581 return (NULL); 582 } 583 } 584 #endif 585 586 /* 587 * Put the new peer in the hash tables. 588 */ 589 i = HASH_ADDR(&peer->srcadr); 590 peer->next = peer_hash[i]; 591 peer_hash[i] = peer; 592 peer_hash_count[i]++; 593 i = peer->associd & HASH_MASK; 594 peer->ass_next = assoc_hash[i]; 595 assoc_hash[i] = peer; 596 assoc_hash_count[i]++; 597 #ifdef DEBUG 598 if (debug) 599 printf( 600 "newpeer: %s->%s mode %d vers %d poll %d %d flags %x %x ttl %d key %08x\n", 601 ntoa(&peer->dstadr->sin), ntoa(&peer->srcadr), 602 peer->hmode, peer->version, peer->minpoll, 603 peer->maxpoll, peer->flags, peer->cast_flags, 604 peer->ttlmax, peer->keyid); 605 #endif 606 return (peer); 607 } 608 609 610 /* 611 * peer_unconfig - remove the configuration bit from a peer 612 */ 613 int 614 peer_unconfig( 615 struct sockaddr_in *srcadr, 616 struct interface *dstadr, 617 int mode 618 ) 619 { 620 register struct peer *peer; 621 int num_found; 622 623 num_found = 0; 624 peer = findexistingpeer(srcadr, (struct peer *)0, mode); 625 while (peer != 0) { 626 if (peer->flags & FLAG_CONFIG 627 && (dstadr == 0 || peer->dstadr == dstadr)) { 628 num_found++; 629 630 /* 631 * Tricky stuff here. If the peer is polling us 632 * in active mode, turn off the configuration 633 * bit and make the mode passive. This allows us 634 * to avoid dumping a lot of history for peers 635 * we might choose to keep track of in passive 636 * mode. The protocol will eventually terminate 637 * undesirables on its own. 638 */ 639 if (peer->hmode == MODE_ACTIVE 640 && peer->pmode == MODE_ACTIVE) { 641 peer->hmode = MODE_PASSIVE; 642 peer->flags &= ~FLAG_CONFIG; 643 } else { 644 unpeer(peer); 645 peer = 0; 646 } 647 } 648 peer = findexistingpeer(srcadr, peer, mode); 649 } 650 return (num_found); 651 } 652 653 /* 654 * peer_clr_stats - clear peer module stat counters 655 */ 656 void 657 peer_clr_stats(void) 658 { 659 findpeer_calls = 0; 660 assocpeer_calls = 0; 661 peer_allocations = 0; 662 peer_demobilizations = 0; 663 peer_timereset = current_time; 664 } 665 666 /* 667 * peer_reset - reset stat counters in a peer structure 668 */ 669 void 670 peer_reset( 671 struct peer *peer 672 ) 673 { 674 if (peer == 0) 675 return; 676 peer->sent = 0; 677 peer->received = 0; 678 peer->processed = 0; 679 peer->badauth = 0; 680 peer->bogusorg = 0; 681 peer->oldpkt = 0; 682 peer->seldisptoolarge = 0; 683 peer->selbroken = 0; 684 peer->timereset = current_time; 685 } 686 687 688 /* 689 * peer_all_reset - reset all peer stat counters 690 */ 691 void 692 peer_all_reset(void) 693 { 694 struct peer *peer; 695 int hash; 696 697 for (hash = 0; hash < HASH_SIZE; hash++) 698 for (peer = peer_hash[hash]; peer != 0; peer = peer->next) 699 peer_reset(peer); 700 } 701 702 703 #ifdef AUTOKEY 704 /* 705 * expire_all - flush all crypto data and update timestamps. 706 */ 707 void 708 expire_all(void) 709 { 710 struct peer *peer, *next_peer; 711 int n; 712 713 /* 714 * This routine is called about once per day from the timer 715 * routine and when the client is first synchronized. Search the 716 * peer list for all associations and flush only the key list 717 * and cookie. If a manycast client association, flush 718 * everything. Then, recompute and sign the agreement public 719 * value, if present. 720 */ 721 for (n = 0; n < HASH_SIZE; n++) { 722 for (peer = peer_hash[n]; peer != 0; peer = next_peer) { 723 next_peer = peer->next; 724 if (peer->cast_flags & MDF_ACAST) { 725 peer_clear(peer); 726 #ifdef AUTOKEY 727 } else { 728 key_expire(peer); 729 peer->pcookie.tstamp = 0; 730 #endif /* AUTOKEY */ 731 } 732 733 } 734 } 735 sys_private = (u_int32)RANDOM & 0xffffffff; 736 #ifdef PUBKEY 737 crypto_agree(); 738 #endif /* PUBKEY */ 739 #ifdef DEBUG 740 if (debug) 741 printf("expire_all: at %lu\n", current_time); 742 #endif 743 } 744 #endif /* AUTOKEY */ 745 746 747 /* 748 * findmanycastpeer - find and return a manycast peer 749 */ 750 struct peer * 751 findmanycastpeer( 752 struct recvbuf *rbufp 753 ) 754 { 755 register struct peer *peer; 756 struct pkt *pkt; 757 l_fp p_org; 758 int i; 759 760 /* 761 * This routine is called upon arrival of a client-mode message 762 * from a manycast server. Search the peer list for a manycast 763 * client association where the last transmit timestamp matches 764 * the originate timestamp. This assumes the transmit timestamps 765 * for possibly more than one manycast association are unique. 766 */ 767 pkt = &rbufp->recv_pkt; 768 for (i = 0; i < HASH_SIZE; i++) { 769 if (peer_hash_count[i] == 0) 770 continue; 771 772 for (peer = peer_hash[i]; peer != 0; peer = 773 peer->next) { 774 if (peer->cast_flags & MDF_ACAST) { 775 NTOHL_FP(&pkt->org, &p_org); 776 if (L_ISEQU(&peer->xmt, &p_org)) 777 return (peer); 778 } 779 } 780 } 781 return (NULL); 782 } 783 784 785 /* 786 * resetmanycast - reset all manycast clients 787 */ 788 void 789 resetmanycast(void) 790 { 791 register struct peer *peer; 792 int i; 793 794 /* 795 * This routine is called when the number of client associations 796 * falls below the minimum. Search the peer list for manycast 797 * client associations and reset the ttl and poll interval. 798 */ 799 for (i = 0; i < HASH_SIZE; i++) { 800 if (peer_hash_count[i] == 0) 801 continue; 802 803 for (peer = peer_hash[i]; peer != 0; peer = 804 peer->next) { 805 if (peer->cast_flags & MDF_ACAST) { 806 peer->ttl = 0; 807 poll_update(peer, peer->hpoll); 808 } 809 } 810 } 811 } 812