1 /* dnsmasq is Copyright (c) 2000-2009 Simon Kelley 2 3 This program is free software; you can redistribute it and/or modify 4 it under the terms of the GNU General Public License as published by 5 the Free Software Foundation; version 2 dated June, 1991, or 6 (at your option) version 3 dated 29 June, 2007. 7 8 This program is distributed in the hope that it will be useful, 9 but WITHOUT ANY WARRANTY; without even the implied warranty of 10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 GNU General Public License for more details. 12 13 You should have received a copy of the GNU General Public License 14 along with this program. If not, see <http://www.gnu.org/licenses/>. 15 */ 16 17 #include "dnsmasq.h" 18 19 static struct crec *cache_head = NULL, *cache_tail = NULL, **hash_table = NULL; 20 #ifdef HAVE_DHCP 21 static struct crec *dhcp_spare = NULL; 22 #endif 23 static struct crec *new_chain = NULL; 24 static int cache_inserted = 0, cache_live_freed = 0, insert_error; 25 static union bigname *big_free = NULL; 26 static int bignames_left, hash_size; 27 static int uid = 0; 28 static char *addrbuff = NULL; 29 30 /* type->string mapping: this is also used by the name-hash function as a mixing table. */ 31 static const struct { 32 unsigned int type; 33 const char * const name; 34 } typestr[] = { 35 { 1, "A" }, 36 { 2, "NS" }, 37 { 5, "CNAME" }, 38 { 6, "SOA" }, 39 { 10, "NULL" }, 40 { 11, "WKS" }, 41 { 12, "PTR" }, 42 { 13, "HINFO" }, 43 { 15, "MX" }, 44 { 16, "TXT" }, 45 { 22, "NSAP" }, 46 { 23, "NSAP_PTR" }, 47 { 24, "SIG" }, 48 { 25, "KEY" }, 49 { 28, "AAAA" }, 50 { 33, "SRV" }, 51 { 35, "NAPTR" }, 52 { 36, "KX" }, 53 { 37, "CERT" }, 54 { 38, "A6" }, 55 { 39, "DNAME" }, 56 { 41, "OPT" }, 57 { 48, "DNSKEY" }, 58 { 249, "TKEY" }, 59 { 250, "TSIG" }, 60 { 251, "IXFR" }, 61 { 252, "AXFR" }, 62 { 253, "MAILB" }, 63 { 254, "MAILA" }, 64 { 255, "ANY" } 65 }; 66 67 static void cache_free(struct crec *crecp); 68 static void cache_unlink(struct crec *crecp); 69 static void cache_link(struct crec *crecp); 70 static void rehash(int size); 71 static void cache_hash(struct crec *crecp); 72 73 void cache_init(void) 74 { 75 struct crec *crecp; 76 int i; 77 78 if (daemon->options & OPT_LOG) 79 addrbuff = safe_malloc(ADDRSTRLEN); 80 81 bignames_left = daemon->cachesize/10; 82 83 if (daemon->cachesize > 0) 84 { 85 crecp = safe_malloc(daemon->cachesize*sizeof(struct crec)); 86 87 for (i=0; i < daemon->cachesize; i++, crecp++) 88 { 89 cache_link(crecp); 90 crecp->flags = 0; 91 crecp->uid = uid++; 92 } 93 } 94 95 /* create initial hash table*/ 96 rehash(daemon->cachesize); 97 } 98 99 /* In most cases, we create the hash table once here by calling this with (hash_table == NULL) 100 but if the hosts file(s) are big (some people have 50000 ad-block entries), the table 101 will be much too small, so the hosts reading code calls rehash every 1000 addresses, to 102 expand the table. */ 103 static void rehash(int size) 104 { 105 struct crec **new, **old, *p, *tmp; 106 int i, new_size, old_size; 107 108 /* hash_size is a power of two. */ 109 for (new_size = 64; new_size < size/10; new_size = new_size << 1); 110 111 /* must succeed in getting first instance, failure later is non-fatal */ 112 if (!hash_table) 113 new = safe_malloc(new_size * sizeof(struct crec *)); 114 else if (new_size <= hash_size || !(new = whine_malloc(new_size * sizeof(struct crec *)))) 115 return; 116 117 for(i = 0; i < new_size; i++) 118 new[i] = NULL; 119 120 old = hash_table; 121 old_size = hash_size; 122 hash_table = new; 123 hash_size = new_size; 124 125 if (old) 126 { 127 for (i = 0; i < old_size; i++) 128 for (p = old[i]; p ; p = tmp) 129 { 130 tmp = p->hash_next; 131 cache_hash(p); 132 } 133 free(old); 134 } 135 } 136 137 static struct crec **hash_bucket(char *name) 138 { 139 unsigned int c, val = 017465; /* Barker code - minimum self-correlation in cyclic shift */ 140 const unsigned char *mix_tab = (const unsigned char*)typestr; 141 142 while((c = (unsigned char) *name++)) 143 { 144 /* don't use tolower and friends here - they may be messed up by LOCALE */ 145 if (c >= 'A' && c <= 'Z') 146 c += 'a' - 'A'; 147 val = ((val << 7) | (val >> (32 - 7))) + (mix_tab[(val + c) & 0x3F] ^ c); 148 } 149 150 /* hash_size is a power of two */ 151 return hash_table + ((val ^ (val >> 16)) & (hash_size - 1)); 152 } 153 154 static void cache_hash(struct crec *crecp) 155 { 156 /* maintain an invariant that all entries with F_REVERSE set 157 are at the start of the hash-chain and all non-reverse 158 immortal entries are at the end of the hash-chain. 159 This allows reverse searches and garbage collection to be optimised */ 160 161 struct crec **up = hash_bucket(cache_get_name(crecp)); 162 163 if (!(crecp->flags & F_REVERSE)) 164 { 165 while (*up && ((*up)->flags & F_REVERSE)) 166 up = &((*up)->hash_next); 167 168 if (crecp->flags & F_IMMORTAL) 169 while (*up && !((*up)->flags & F_IMMORTAL)) 170 up = &((*up)->hash_next); 171 } 172 crecp->hash_next = *up; 173 *up = crecp; 174 } 175 176 static void cache_free(struct crec *crecp) 177 { 178 crecp->flags &= ~F_FORWARD; 179 crecp->flags &= ~F_REVERSE; 180 crecp->uid = uid++; /* invalidate CNAMES pointing to this. */ 181 182 if (cache_tail) 183 cache_tail->next = crecp; 184 else 185 cache_head = crecp; 186 crecp->prev = cache_tail; 187 crecp->next = NULL; 188 cache_tail = crecp; 189 190 /* retrieve big name for further use. */ 191 if (crecp->flags & F_BIGNAME) 192 { 193 crecp->name.bname->next = big_free; 194 big_free = crecp->name.bname; 195 crecp->flags &= ~F_BIGNAME; 196 } 197 } 198 199 /* insert a new cache entry at the head of the list (youngest entry) */ 200 static void cache_link(struct crec *crecp) 201 { 202 if (cache_head) /* check needed for init code */ 203 cache_head->prev = crecp; 204 crecp->next = cache_head; 205 crecp->prev = NULL; 206 cache_head = crecp; 207 if (!cache_tail) 208 cache_tail = crecp; 209 } 210 211 /* remove an arbitrary cache entry for promotion */ 212 static void cache_unlink (struct crec *crecp) 213 { 214 if (crecp->prev) 215 crecp->prev->next = crecp->next; 216 else 217 cache_head = crecp->next; 218 219 if (crecp->next) 220 crecp->next->prev = crecp->prev; 221 else 222 cache_tail = crecp->prev; 223 } 224 225 char *cache_get_name(struct crec *crecp) 226 { 227 if (crecp->flags & F_BIGNAME) 228 return crecp->name.bname->name; 229 else if (crecp->flags & (F_DHCP | F_CONFIG)) 230 return crecp->name.namep; 231 232 return crecp->name.sname; 233 } 234 235 static int is_outdated_cname_pointer(struct crec *crecp) 236 { 237 if (!(crecp->flags & F_CNAME)) 238 return 0; 239 240 if (crecp->addr.cname.cache && crecp->addr.cname.uid == crecp->addr.cname.cache->uid) 241 return 0; 242 243 return 1; 244 } 245 246 static int is_expired(time_t now, struct crec *crecp) 247 { 248 if (crecp->flags & F_IMMORTAL) 249 return 0; 250 251 if (difftime(now, crecp->ttd) < 0) 252 return 0; 253 254 return 1; 255 } 256 257 static int cache_scan_free(char *name, struct all_addr *addr, time_t now, unsigned short flags) 258 { 259 /* Scan and remove old entries. 260 If (flags & F_FORWARD) then remove any forward entries for name and any expired 261 entries but only in the same hash bucket as name. 262 If (flags & F_REVERSE) then remove any reverse entries for addr and any expired 263 entries in the whole cache. 264 If (flags == 0) remove any expired entries in the whole cache. 265 266 In the flags & F_FORWARD case, the return code is valid, and returns zero if the 267 name exists in the cache as a HOSTS or DHCP entry (these are never deleted) 268 269 We take advantage of the fact that hash chains have stuff in the order <reverse>,<other>,<immortal> 270 so that when we hit an entry which isn't reverse and is immortal, we're done. */ 271 272 struct crec *crecp, **up; 273 274 if (flags & F_FORWARD) 275 { 276 for (up = hash_bucket(name), crecp = *up; crecp; crecp = crecp->hash_next) 277 if (is_expired(now, crecp) || is_outdated_cname_pointer(crecp)) 278 { 279 *up = crecp->hash_next; 280 if (!(crecp->flags & (F_HOSTS | F_DHCP))) 281 { 282 cache_unlink(crecp); 283 cache_free(crecp); 284 } 285 } 286 else if ((crecp->flags & F_FORWARD) && 287 ((flags & crecp->flags & (F_IPV4 | F_IPV6)) || ((crecp->flags | flags) & F_CNAME)) && 288 hostname_isequal(cache_get_name(crecp), name)) 289 { 290 if (crecp->flags & (F_HOSTS | F_DHCP)) 291 return 0; 292 *up = crecp->hash_next; 293 cache_unlink(crecp); 294 cache_free(crecp); 295 } 296 else 297 up = &crecp->hash_next; 298 } 299 else 300 { 301 int i; 302 #ifdef HAVE_IPV6 303 int addrlen = (flags & F_IPV6) ? IN6ADDRSZ : INADDRSZ; 304 #else 305 int addrlen = INADDRSZ; 306 #endif 307 for (i = 0; i < hash_size; i++) 308 for (crecp = hash_table[i], up = &hash_table[i]; 309 crecp && ((crecp->flags & F_REVERSE) || !(crecp->flags & F_IMMORTAL)); 310 crecp = crecp->hash_next) 311 if (is_expired(now, crecp)) 312 { 313 *up = crecp->hash_next; 314 if (!(crecp->flags & (F_HOSTS | F_DHCP))) 315 { 316 cache_unlink(crecp); 317 cache_free(crecp); 318 } 319 } 320 else if (!(crecp->flags & (F_HOSTS | F_DHCP)) && 321 (flags & crecp->flags & F_REVERSE) && 322 (flags & crecp->flags & (F_IPV4 | F_IPV6)) && 323 memcmp(&crecp->addr.addr, addr, addrlen) == 0) 324 { 325 *up = crecp->hash_next; 326 cache_unlink(crecp); 327 cache_free(crecp); 328 } 329 else 330 up = &crecp->hash_next; 331 } 332 333 return 1; 334 } 335 336 /* Note: The normal calling sequence is 337 cache_start_insert 338 cache_insert * n 339 cache_end_insert 340 341 but an abort can cause the cache_end_insert to be missed 342 in which can the next cache_start_insert cleans things up. */ 343 344 void cache_start_insert(void) 345 { 346 /* Free any entries which didn't get committed during the last 347 insert due to error. 348 */ 349 while (new_chain) 350 { 351 struct crec *tmp = new_chain->next; 352 cache_free(new_chain); 353 new_chain = tmp; 354 } 355 new_chain = NULL; 356 insert_error = 0; 357 } 358 359 struct crec *cache_insert(char *name, struct all_addr *addr, 360 time_t now, unsigned long ttl, unsigned short flags) 361 { 362 struct crec *new; 363 union bigname *big_name = NULL; 364 int freed_all = flags & F_REVERSE; 365 int free_avail = 0; 366 367 log_query(flags | F_UPSTREAM, name, addr, NULL); 368 369 /* CONFIG bit means something else when stored in cache entries */ 370 flags &= ~F_CONFIG; 371 372 /* if previous insertion failed give up now. */ 373 if (insert_error) 374 return NULL; 375 376 /* First remove any expired entries and entries for the name/address we 377 are currently inserting. Fail is we attempt to delete a name from 378 /etc/hosts or DHCP. */ 379 if (!cache_scan_free(name, addr, now, flags)) 380 { 381 insert_error = 1; 382 return NULL; 383 } 384 385 /* Now get a cache entry from the end of the LRU list */ 386 while (1) { 387 if (!(new = cache_tail)) /* no entries left - cache is too small, bail */ 388 { 389 insert_error = 1; 390 return NULL; 391 } 392 393 /* End of LRU list is still in use: if we didn't scan all the hash 394 chains for expired entries do that now. If we already tried that 395 then it's time to start spilling things. */ 396 397 if (new->flags & (F_FORWARD | F_REVERSE)) 398 { 399 /* If free_avail set, we believe that an entry has been freed. 400 Bugs have been known to make this not true, resulting in 401 a tight loop here. If that happens, abandon the 402 insert. Once in this state, all inserts will probably fail. */ 403 if (free_avail) 404 { 405 insert_error = 1; 406 return NULL; 407 } 408 409 if (freed_all) 410 { 411 free_avail = 1; /* Must be free space now. */ 412 cache_scan_free(cache_get_name(new), &new->addr.addr, now, new->flags); 413 cache_live_freed++; 414 } 415 else 416 { 417 cache_scan_free(NULL, NULL, now, 0); 418 freed_all = 1; 419 } 420 continue; 421 } 422 423 /* Check if we need to and can allocate extra memory for a long name. 424 If that fails, give up now. */ 425 if (name && (strlen(name) > SMALLDNAME-1)) 426 { 427 if (big_free) 428 { 429 big_name = big_free; 430 big_free = big_free->next; 431 } 432 else if (!bignames_left || 433 !(big_name = (union bigname *)whine_malloc(sizeof(union bigname)))) 434 { 435 insert_error = 1; 436 return NULL; 437 } 438 else 439 bignames_left--; 440 441 } 442 443 /* Got the rest: finally grab entry. */ 444 cache_unlink(new); 445 break; 446 } 447 448 new->flags = flags; 449 if (big_name) 450 { 451 new->name.bname = big_name; 452 new->flags |= F_BIGNAME; 453 } 454 455 if (name) 456 strcpy(cache_get_name(new), name); 457 else 458 *cache_get_name(new) = 0; 459 460 if (addr) 461 new->addr.addr = *addr; 462 else 463 new->addr.cname.cache = NULL; 464 465 new->ttd = now + (time_t)ttl; 466 new->next = new_chain; 467 new_chain = new; 468 469 return new; 470 } 471 472 /* after end of insertion, commit the new entries */ 473 void cache_end_insert(void) 474 { 475 if (insert_error) 476 return; 477 478 while (new_chain) 479 { 480 struct crec *tmp = new_chain->next; 481 /* drop CNAMEs which didn't find a target. */ 482 if (is_outdated_cname_pointer(new_chain)) 483 cache_free(new_chain); 484 else 485 { 486 cache_hash(new_chain); 487 cache_link(new_chain); 488 cache_inserted++; 489 } 490 new_chain = tmp; 491 } 492 new_chain = NULL; 493 } 494 495 struct crec *cache_find_by_name(struct crec *crecp, char *name, time_t now, unsigned short prot) 496 { 497 struct crec *ans; 498 499 if (crecp) /* iterating */ 500 ans = crecp->next; 501 else 502 { 503 /* first search, look for relevant entries and push to top of list 504 also free anything which has expired */ 505 struct crec *next, **up, **insert = NULL, **chainp = &ans; 506 int ins_flags = 0; 507 508 for (up = hash_bucket(name), crecp = *up; crecp; crecp = next) 509 { 510 next = crecp->hash_next; 511 512 if (!is_expired(now, crecp) && !is_outdated_cname_pointer(crecp)) 513 { 514 if ((crecp->flags & F_FORWARD) && 515 (crecp->flags & prot) && 516 hostname_isequal(cache_get_name(crecp), name)) 517 { 518 if (crecp->flags & (F_HOSTS | F_DHCP)) 519 { 520 *chainp = crecp; 521 chainp = &crecp->next; 522 } 523 else 524 { 525 cache_unlink(crecp); 526 cache_link(crecp); 527 } 528 529 /* Move all but the first entry up the hash chain 530 this implements round-robin. 531 Make sure that re-ordering doesn't break the hash-chain 532 order invariants. 533 */ 534 if (insert && (crecp->flags & (F_REVERSE | F_IMMORTAL)) == ins_flags) 535 { 536 *up = crecp->hash_next; 537 crecp->hash_next = *insert; 538 *insert = crecp; 539 insert = &crecp->hash_next; 540 } 541 else 542 { 543 if (!insert) 544 { 545 insert = up; 546 ins_flags = crecp->flags & (F_REVERSE | F_IMMORTAL); 547 } 548 up = &crecp->hash_next; 549 } 550 } 551 else 552 /* case : not expired, incorrect entry. */ 553 up = &crecp->hash_next; 554 } 555 else 556 { 557 /* expired entry, free it */ 558 *up = crecp->hash_next; 559 if (!(crecp->flags & (F_HOSTS | F_DHCP))) 560 { 561 cache_unlink(crecp); 562 cache_free(crecp); 563 } 564 } 565 } 566 567 *chainp = cache_head; 568 } 569 570 if (ans && 571 (ans->flags & F_FORWARD) && 572 (ans->flags & prot) && 573 hostname_isequal(cache_get_name(ans), name)) 574 return ans; 575 576 return NULL; 577 } 578 579 struct crec *cache_find_by_addr(struct crec *crecp, struct all_addr *addr, 580 time_t now, unsigned short prot) 581 { 582 struct crec *ans; 583 #ifdef HAVE_IPV6 584 int addrlen = (prot == F_IPV6) ? IN6ADDRSZ : INADDRSZ; 585 #else 586 int addrlen = INADDRSZ; 587 #endif 588 589 if (crecp) /* iterating */ 590 ans = crecp->next; 591 else 592 { 593 /* first search, look for relevant entries and push to top of list 594 also free anything which has expired. All the reverse entries are at the 595 start of the hash chain, so we can give up when we find the first 596 non-REVERSE one. */ 597 int i; 598 struct crec **up, **chainp = &ans; 599 600 for (i=0; i<hash_size; i++) 601 for (crecp = hash_table[i], up = &hash_table[i]; 602 crecp && (crecp->flags & F_REVERSE); 603 crecp = crecp->hash_next) 604 if (!is_expired(now, crecp)) 605 { 606 if ((crecp->flags & prot) && 607 memcmp(&crecp->addr.addr, addr, addrlen) == 0) 608 { 609 if (crecp->flags & (F_HOSTS | F_DHCP)) 610 { 611 *chainp = crecp; 612 chainp = &crecp->next; 613 } 614 else 615 { 616 cache_unlink(crecp); 617 cache_link(crecp); 618 } 619 } 620 up = &crecp->hash_next; 621 } 622 else 623 { 624 *up = crecp->hash_next; 625 if (!(crecp->flags & (F_HOSTS | F_DHCP))) 626 { 627 cache_unlink(crecp); 628 cache_free(crecp); 629 } 630 } 631 632 *chainp = cache_head; 633 } 634 635 if (ans && 636 (ans->flags & F_REVERSE) && 637 (ans->flags & prot) && 638 memcmp(&ans->addr.addr, addr, addrlen) == 0) 639 return ans; 640 641 return NULL; 642 } 643 644 static void add_hosts_entry(struct crec *cache, struct all_addr *addr, int addrlen, 645 unsigned short flags, int index, int addr_dup) 646 { 647 struct crec *lookup = cache_find_by_name(NULL, cache->name.sname, 0, flags & (F_IPV4 | F_IPV6)); 648 int i, nameexists = 0; 649 struct cname *a; 650 651 /* Remove duplicates in hosts files. */ 652 if (lookup && (lookup->flags & F_HOSTS)) 653 { 654 nameexists = 1; 655 if (memcmp(&lookup->addr.addr, addr, addrlen) == 0) 656 { 657 free(cache); 658 return; 659 } 660 } 661 662 /* Ensure there is only one address -> name mapping (first one trumps) 663 We do this by steam here, first we see if the address is the same as 664 the last one we saw, which eliminates most in the case of an ad-block 665 file with thousands of entries for the same address. 666 Then we search and bail at the first matching address that came from 667 a HOSTS file. Since the first host entry gets reverse, we know 668 then that it must exist without searching exhaustively for it. */ 669 670 if (addr_dup) 671 flags &= ~F_REVERSE; 672 else 673 for (i=0; i<hash_size; i++) 674 { 675 for (lookup = hash_table[i]; lookup; lookup = lookup->hash_next) 676 if ((lookup->flags & F_HOSTS) && 677 (lookup->flags & flags & (F_IPV4 | F_IPV6)) && 678 memcmp(&lookup->addr.addr, addr, addrlen) == 0) 679 { 680 flags &= ~F_REVERSE; 681 break; 682 } 683 if (lookup) 684 break; 685 } 686 687 cache->flags = flags; 688 cache->uid = index; 689 memcpy(&cache->addr.addr, addr, addrlen); 690 cache_hash(cache); 691 692 /* don't need to do alias stuff for second and subsequent addresses. */ 693 if (!nameexists) 694 for (a = daemon->cnames; a; a = a->next) 695 if (hostname_isequal(cache->name.sname, a->target) && 696 (lookup = whine_malloc(sizeof(struct crec)))) 697 { 698 lookup->flags = F_FORWARD | F_IMMORTAL | F_CONFIG | F_HOSTS | F_CNAME; 699 lookup->name.namep = a->alias; 700 lookup->addr.cname.cache = cache; 701 lookup->addr.cname.uid = index; 702 cache_hash(lookup); 703 } 704 } 705 706 static int eatspace(FILE *f) 707 { 708 int c, nl = 0; 709 710 while (1) 711 { 712 if ((c = getc(f)) == '#') 713 while (c != '\n' && c != EOF) 714 c = getc(f); 715 716 if (c == EOF) 717 return 1; 718 719 if (!isspace(c)) 720 { 721 ungetc(c, f); 722 return nl; 723 } 724 725 if (c == '\n') 726 nl = 1; 727 } 728 } 729 730 static int gettok(FILE *f, char *token) 731 { 732 int c, count = 0; 733 734 while (1) 735 { 736 if ((c = getc(f)) == EOF) 737 return (count == 0) ? EOF : 1; 738 739 if (isspace(c) || c == '#') 740 { 741 ungetc(c, f); 742 return eatspace(f); 743 } 744 745 if (count < (MAXDNAME - 1)) 746 { 747 token[count++] = c; 748 token[count] = 0; 749 } 750 } 751 } 752 753 static int read_hostsfile(char *filename, int index, int cache_size) 754 { 755 FILE *f = fopen(filename, "r"); 756 char *token = daemon->namebuff, *domain_suffix = NULL; 757 int addr_count = 0, name_count = cache_size, lineno = 0; 758 unsigned short flags = 0, saved_flags = 0; 759 struct all_addr addr, saved_addr; 760 int atnl, addrlen = 0, addr_dup; 761 762 if (!f) 763 { 764 my_syslog(LOG_ERR, _("failed to load names from %s: %s"), filename, strerror(errno)); 765 return 0; 766 } 767 768 eatspace(f); 769 770 while ((atnl = gettok(f, token)) != EOF) 771 { 772 addr_dup = 0; 773 lineno++; 774 775 #ifdef HAVE_IPV6 776 if (inet_pton(AF_INET, token, &addr) > 0) 777 { 778 flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4; 779 addrlen = INADDRSZ; 780 domain_suffix = get_domain(addr.addr.addr4); 781 } 782 else if (inet_pton(AF_INET6, token, &addr) > 0) 783 { 784 flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV6; 785 addrlen = IN6ADDRSZ; 786 domain_suffix = daemon->domain_suffix; 787 } 788 #else 789 if ((addr.addr.addr4.s_addr = inet_addr(token)) != (in_addr_t) -1) 790 { 791 flags = F_HOSTS | F_IMMORTAL | F_FORWARD | F_REVERSE | F_IPV4; 792 addrlen = INADDRSZ; 793 domain_suffix = get_domain(addr.addr.addr4); 794 } 795 #endif 796 else 797 { 798 my_syslog(LOG_ERR, _("bad address at %s line %d"), filename, lineno); 799 while (atnl == 0) 800 atnl = gettok(f, token); 801 continue; 802 } 803 804 if (saved_flags == flags && memcmp(&addr, &saved_addr, addrlen) == 0) 805 addr_dup = 1; 806 else 807 { 808 saved_flags = flags; 809 saved_addr = addr; 810 } 811 812 addr_count++; 813 814 /* rehash every 1000 names. */ 815 if ((name_count - cache_size) > 1000) 816 { 817 rehash(name_count); 818 cache_size = name_count; 819 } 820 821 while (atnl == 0) 822 { 823 struct crec *cache; 824 int fqdn, nomem; 825 char *canon; 826 827 if ((atnl = gettok(f, token)) == EOF) 828 break; 829 830 fqdn = !!strchr(token, '.'); 831 832 if ((canon = canonicalise(token, &nomem))) 833 { 834 /* If set, add a version of the name with a default domain appended */ 835 if ((daemon->options & OPT_EXPAND) && domain_suffix && !fqdn && 836 (cache = whine_malloc(sizeof(struct crec) + 837 strlen(canon)+2+strlen(domain_suffix)-SMALLDNAME))) 838 { 839 strcpy(cache->name.sname, canon); 840 strcat(cache->name.sname, "."); 841 strcat(cache->name.sname, domain_suffix); 842 add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup); 843 addr_dup = 1; 844 name_count++; 845 } 846 if ((cache = whine_malloc(sizeof(struct crec) + strlen(canon)+1-SMALLDNAME))) 847 { 848 strcpy(cache->name.sname, canon); 849 add_hosts_entry(cache, &addr, addrlen, flags, index, addr_dup); 850 name_count++; 851 } 852 free(canon); 853 854 } 855 else if (!nomem) 856 my_syslog(LOG_ERR, _("bad name at %s line %d"), filename, lineno); 857 } 858 } 859 860 fclose(f); 861 rehash(name_count); 862 863 my_syslog(LOG_INFO, _("read %s - %d addresses"), filename, addr_count); 864 865 return name_count; 866 } 867 868 void cache_reload(void) 869 { 870 struct crec *cache, **up, *tmp; 871 int i, total_size = daemon->cachesize; 872 struct hostsfile *ah; 873 874 cache_inserted = cache_live_freed = 0; 875 876 for (i=0; i<hash_size; i++) 877 for (cache = hash_table[i], up = &hash_table[i]; cache; cache = tmp) 878 { 879 tmp = cache->hash_next; 880 if (cache->flags & F_HOSTS) 881 { 882 *up = cache->hash_next; 883 free(cache); 884 } 885 else if (!(cache->flags & F_DHCP)) 886 { 887 *up = cache->hash_next; 888 if (cache->flags & F_BIGNAME) 889 { 890 cache->name.bname->next = big_free; 891 big_free = cache->name.bname; 892 } 893 cache->flags = 0; 894 } 895 else 896 up = &cache->hash_next; 897 } 898 899 if ((daemon->options & OPT_NO_HOSTS) && !daemon->addn_hosts) 900 { 901 if (daemon->cachesize > 0) 902 my_syslog(LOG_INFO, _("cleared cache")); 903 return; 904 } 905 906 if (!(daemon->options & OPT_NO_HOSTS)) 907 total_size = read_hostsfile(HOSTSFILE, 0, total_size); 908 909 for (i = 0, ah = daemon->addn_hosts; ah; ah = ah->next) 910 { 911 if (i <= ah->index) 912 i = ah->index + 1; 913 914 if (ah->flags & AH_DIR) 915 ah->flags |= AH_INACTIVE; 916 else 917 ah->flags &= ~AH_INACTIVE; 918 } 919 920 for (ah = daemon->addn_hosts; ah; ah = ah->next) 921 if (!(ah->flags & AH_INACTIVE)) 922 { 923 struct stat buf; 924 if (stat(ah->fname, &buf) != -1 && S_ISDIR(buf.st_mode)) 925 { 926 DIR *dir_stream; 927 struct dirent *ent; 928 929 /* don't read this as a file */ 930 ah->flags |= AH_INACTIVE; 931 932 if (!(dir_stream = opendir(ah->fname))) 933 my_syslog(LOG_ERR, _("cannot access directory %s: %s"), 934 ah->fname, strerror(errno)); 935 else 936 { 937 while ((ent = readdir(dir_stream))) 938 { 939 size_t lendir = strlen(ah->fname); 940 size_t lenfile = strlen(ent->d_name); 941 struct hostsfile *ah1; 942 char *path; 943 944 /* ignore emacs backups and dotfiles */ 945 if (lenfile == 0 || 946 ent->d_name[lenfile - 1] == '~' || 947 (ent->d_name[0] == '#' && ent->d_name[lenfile - 1] == '#') || 948 ent->d_name[0] == '.') 949 continue; 950 951 /* see if we have an existing record. 952 dir is ah->fname 953 file is ent->d_name 954 path to match is ah1->fname */ 955 956 for (ah1 = daemon->addn_hosts; ah1; ah1 = ah1->next) 957 { 958 if (lendir < strlen(ah1->fname) && 959 strstr(ah1->fname, ah->fname) == ah1->fname && 960 ah1->fname[lendir] == '/' && 961 strcmp(ah1->fname + lendir + 1, ent->d_name) == 0) 962 { 963 ah1->flags &= ~AH_INACTIVE; 964 break; 965 } 966 } 967 968 /* make new record */ 969 if (!ah1) 970 { 971 if (!(ah1 = whine_malloc(sizeof(struct hostsfile)))) 972 continue; 973 974 if (!(path = whine_malloc(lendir + lenfile + 2))) 975 { 976 free(ah1); 977 continue; 978 } 979 980 strcpy(path, ah->fname); 981 strcat(path, "/"); 982 strcat(path, ent->d_name); 983 ah1->fname = path; 984 ah1->index = i++; 985 ah1->flags = AH_DIR; 986 ah1->next = daemon->addn_hosts; 987 daemon->addn_hosts = ah1; 988 } 989 990 /* inactivate record if not regular file */ 991 if ((ah1->flags & AH_DIR) && stat(ah1->fname, &buf) != -1 && !S_ISREG(buf.st_mode)) 992 ah1->flags |= AH_INACTIVE; 993 994 } 995 closedir(dir_stream); 996 } 997 } 998 } 999 1000 for (ah = daemon->addn_hosts; ah; ah = ah->next) 1001 if (!(ah->flags & AH_INACTIVE)) 1002 total_size = read_hostsfile(ah->fname, ah->index, total_size); 1003 } 1004 1005 char *get_domain(struct in_addr addr) 1006 { 1007 struct cond_domain *c; 1008 1009 for (c = daemon->cond_domain; c; c = c->next) 1010 if (ntohl(addr.s_addr) >= ntohl(c->start.s_addr) && 1011 ntohl(addr.s_addr) <= ntohl(c->end.s_addr)) 1012 return c->domain; 1013 1014 return daemon->domain_suffix; 1015 } 1016 1017 #ifdef HAVE_DHCP 1018 void cache_unhash_dhcp(void) 1019 { 1020 struct crec *cache, **up; 1021 int i; 1022 1023 for (i=0; i<hash_size; i++) 1024 for (cache = hash_table[i], up = &hash_table[i]; cache; cache = cache->hash_next) 1025 if (cache->flags & F_DHCP) 1026 { 1027 *up = cache->hash_next; 1028 cache->next = dhcp_spare; 1029 dhcp_spare = cache; 1030 } 1031 else 1032 up = &cache->hash_next; 1033 } 1034 1035 void cache_add_dhcp_entry(char *host_name, 1036 struct in_addr *host_address, time_t ttd) 1037 { 1038 struct crec *crec = NULL, *aliasc; 1039 unsigned short flags = F_DHCP | F_FORWARD | F_IPV4 | F_REVERSE; 1040 int in_hosts = 0; 1041 struct cname *a; 1042 1043 while ((crec = cache_find_by_name(crec, host_name, 0, F_IPV4 | F_CNAME))) 1044 { 1045 /* check all addresses associated with name */ 1046 if (crec->flags & F_HOSTS) 1047 { 1048 if (crec->addr.addr.addr.addr4.s_addr != host_address->s_addr) 1049 { 1050 strcpy(daemon->namebuff, inet_ntoa(crec->addr.addr.addr.addr4)); 1051 my_syslog(LOG_WARNING, 1052 _("not giving name %s to the DHCP lease of %s because " 1053 "the name exists in %s with address %s"), 1054 host_name, inet_ntoa(*host_address), 1055 record_source(crec->uid), daemon->namebuff); 1056 return; 1057 } 1058 else 1059 /* if in hosts, don't need DHCP record */ 1060 in_hosts = 1; 1061 } 1062 else if (!(crec->flags & F_DHCP)) 1063 { 1064 cache_scan_free(host_name, NULL, 0, crec->flags & (F_IPV4 | F_CNAME | F_FORWARD)); 1065 /* scan_free deletes all addresses associated with name */ 1066 break; 1067 } 1068 } 1069 1070 if (in_hosts) 1071 return; 1072 1073 if ((crec = cache_find_by_addr(NULL, (struct all_addr *)host_address, 0, F_IPV4))) 1074 { 1075 if (crec->flags & F_NEG) 1076 cache_scan_free(NULL, (struct all_addr *)host_address, 0, F_IPV4 | F_REVERSE); 1077 else 1078 /* avoid multiple reverse mappings */ 1079 flags &= ~F_REVERSE; 1080 } 1081 1082 if ((crec = dhcp_spare)) 1083 dhcp_spare = dhcp_spare->next; 1084 else /* need new one */ 1085 crec = whine_malloc(sizeof(struct crec)); 1086 1087 if (crec) /* malloc may fail */ 1088 { 1089 crec->flags = flags; 1090 if (ttd == 0) 1091 crec->flags |= F_IMMORTAL; 1092 else 1093 crec->ttd = ttd; 1094 crec->addr.addr.addr.addr4 = *host_address; 1095 crec->name.namep = host_name; 1096 crec->uid = uid++; 1097 cache_hash(crec); 1098 1099 for (a = daemon->cnames; a; a = a->next) 1100 if (hostname_isequal(host_name, a->target)) 1101 { 1102 if ((aliasc = dhcp_spare)) 1103 dhcp_spare = dhcp_spare->next; 1104 else /* need new one */ 1105 aliasc = whine_malloc(sizeof(struct crec)); 1106 1107 if (aliasc) 1108 { 1109 aliasc->flags = F_FORWARD | F_CONFIG | F_DHCP | F_CNAME; 1110 if (ttd == 0) 1111 aliasc->flags |= F_IMMORTAL; 1112 else 1113 aliasc->ttd = ttd; 1114 aliasc->name.namep = a->alias; 1115 aliasc->addr.cname.cache = crec; 1116 aliasc->addr.cname.uid = crec->uid; 1117 cache_hash(aliasc); 1118 } 1119 } 1120 } 1121 } 1122 #endif 1123 1124 1125 void dump_cache(time_t now) 1126 { 1127 struct server *serv, *serv1; 1128 1129 my_syslog(LOG_INFO, _("time %lu"), (unsigned long)now); 1130 my_syslog(LOG_INFO, _("cache size %d, %d/%d cache insertions re-used unexpired cache entries."), 1131 daemon->cachesize, cache_live_freed, cache_inserted); 1132 my_syslog(LOG_INFO, _("queries forwarded %u, queries answered locally %u"), 1133 daemon->queries_forwarded, daemon->local_answer); 1134 1135 if (!addrbuff && !(addrbuff = whine_malloc(ADDRSTRLEN))) 1136 return; 1137 1138 /* sum counts from different records for same server */ 1139 for (serv = daemon->servers; serv; serv = serv->next) 1140 serv->flags &= ~SERV_COUNTED; 1141 1142 for (serv = daemon->servers; serv; serv = serv->next) 1143 if (!(serv->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED))) 1144 { 1145 int port; 1146 unsigned int queries = 0, failed_queries = 0; 1147 for (serv1 = serv; serv1; serv1 = serv1->next) 1148 if (!(serv1->flags & (SERV_NO_ADDR | SERV_LITERAL_ADDRESS | SERV_COUNTED)) && sockaddr_isequal(&serv->addr, &serv1->addr)) 1149 { 1150 serv1->flags |= SERV_COUNTED; 1151 queries += serv1->queries; 1152 failed_queries += serv1->failed_queries; 1153 } 1154 port = prettyprint_addr(&serv->addr, addrbuff); 1155 my_syslog(LOG_INFO, _("server %s#%d: queries sent %u, retried or failed %u"), addrbuff, port, queries, failed_queries); 1156 } 1157 1158 if ((daemon->options & (OPT_DEBUG | OPT_LOG))) 1159 { 1160 struct crec *cache ; 1161 int i; 1162 my_syslog(LOG_DEBUG, "Host Address Flags Expires"); 1163 1164 for (i=0; i<hash_size; i++) 1165 for (cache = hash_table[i]; cache; cache = cache->hash_next) 1166 { 1167 char *a, *p = daemon->namebuff; 1168 p += sprintf(p, "%-40.40s ", cache_get_name(cache)); 1169 if ((cache->flags & F_NEG) && (cache->flags & F_FORWARD)) 1170 a = ""; 1171 else if (cache->flags & F_CNAME) 1172 { 1173 a = ""; 1174 if (!is_outdated_cname_pointer(cache)) 1175 a = cache_get_name(cache->addr.cname.cache); 1176 } 1177 #ifdef HAVE_IPV6 1178 else 1179 { 1180 a = addrbuff; 1181 if (cache->flags & F_IPV4) 1182 inet_ntop(AF_INET, &cache->addr.addr, addrbuff, ADDRSTRLEN); 1183 else if (cache->flags & F_IPV6) 1184 inet_ntop(AF_INET6, &cache->addr.addr, addrbuff, ADDRSTRLEN); 1185 } 1186 #else 1187 else 1188 a = inet_ntoa(cache->addr.addr.addr.addr4); 1189 #endif 1190 p += sprintf(p, "%-30.30s %s%s%s%s%s%s%s%s%s%s ", a, 1191 cache->flags & F_IPV4 ? "4" : "", 1192 cache->flags & F_IPV6 ? "6" : "", 1193 cache->flags & F_CNAME ? "C" : "", 1194 cache->flags & F_FORWARD ? "F" : " ", 1195 cache->flags & F_REVERSE ? "R" : " ", 1196 cache->flags & F_IMMORTAL ? "I" : " ", 1197 cache->flags & F_DHCP ? "D" : " ", 1198 cache->flags & F_NEG ? "N" : " ", 1199 cache->flags & F_NXDOMAIN ? "X" : " ", 1200 cache->flags & F_HOSTS ? "H" : " "); 1201 #ifdef HAVE_BROKEN_RTC 1202 p += sprintf(p, "%lu", cache->flags & F_IMMORTAL ? 0: (unsigned long)(cache->ttd - now)); 1203 #else 1204 p += sprintf(p, "%s", cache->flags & F_IMMORTAL ? "\n" : ctime(&(cache->ttd))); 1205 /* ctime includes trailing \n - eat it */ 1206 *(p-1) = 0; 1207 #endif 1208 my_syslog(LOG_DEBUG, daemon->namebuff); 1209 } 1210 } 1211 } 1212 1213 char *record_source(int index) 1214 { 1215 struct hostsfile *ah; 1216 1217 if (index == 0) 1218 return HOSTSFILE; 1219 1220 for (ah = daemon->addn_hosts; ah; ah = ah->next) 1221 if (ah->index == index) 1222 return ah->fname; 1223 1224 return "<unknown>"; 1225 } 1226 1227 void querystr(char *str, unsigned short type) 1228 { 1229 unsigned int i; 1230 1231 sprintf(str, "query[type=%d]", type); 1232 for (i = 0; i < (sizeof(typestr)/sizeof(typestr[0])); i++) 1233 if (typestr[i].type == type) 1234 sprintf(str,"query[%s]", typestr[i].name); 1235 } 1236 1237 void log_query(unsigned short flags, char *name, struct all_addr *addr, char *arg) 1238 { 1239 char *source, *dest = addrbuff; 1240 char *verb = "is"; 1241 1242 if (!(daemon->options & OPT_LOG)) 1243 return; 1244 1245 if (addr) 1246 { 1247 #ifdef HAVE_IPV6 1248 inet_ntop(flags & F_IPV4 ? AF_INET : AF_INET6, 1249 addr, addrbuff, ADDRSTRLEN); 1250 #else 1251 strncpy(addrbuff, inet_ntoa(addr->addr.addr4), ADDRSTRLEN); 1252 #endif 1253 } 1254 1255 if (flags & F_REVERSE) 1256 { 1257 dest = name; 1258 name = addrbuff; 1259 } 1260 1261 if (flags & F_NEG) 1262 { 1263 if (flags & F_NXDOMAIN) 1264 { 1265 if (flags & F_IPV4) 1266 dest = "NXDOMAIN-IPv4"; 1267 else if (flags & F_IPV6) 1268 dest = "NXDOMAIN-IPv6"; 1269 else 1270 dest = "NXDOMAIN"; 1271 } 1272 else 1273 { 1274 if (flags & F_IPV4) 1275 dest = "NODATA-IPv4"; 1276 else if (flags & F_IPV6) 1277 dest = "NODATA-IPv6"; 1278 else 1279 dest = "NODATA"; 1280 } 1281 } 1282 else if (flags & F_CNAME) 1283 { 1284 /* nasty abuse of NXDOMAIN and CNAME flags */ 1285 if (flags & F_NXDOMAIN) 1286 dest = arg; 1287 else 1288 dest = "<CNAME>"; 1289 } 1290 1291 if (flags & F_CONFIG) 1292 source = "config"; 1293 else if (flags & F_DHCP) 1294 source = "DHCP"; 1295 else if (flags & F_HOSTS) 1296 source = arg; 1297 else if (flags & F_UPSTREAM) 1298 source = "reply"; 1299 else if (flags & F_SERVER) 1300 { 1301 source = "forwarded"; 1302 verb = "to"; 1303 } 1304 else if (flags & F_QUERY) 1305 { 1306 source = arg; 1307 verb = "from"; 1308 } 1309 else 1310 source = "cached"; 1311 1312 if (strlen(name) == 0) 1313 name = "."; 1314 1315 my_syslog(LOG_DEBUG, "%s %s %s %s", source, name, verb, dest); 1316 } 1317 1318