1 #include <u.h> 2 #include <libc.h> 3 #include <ip.h> 4 #include <pool.h> 5 #include <ctype.h> 6 #include "dns.h" 7 8 /* 9 * this comment used to say `our target is 4000 names cached, this should 10 * be larger on large servers'. dns at Bell Labs starts off with 11 * about 1780 names. 12 * 13 * aging seems to corrupt the cache, so raise the trigger from 4000 until we 14 * figure it out. 15 */ 16 enum { 17 Deftarget = 1<<30, /* effectively disable aging */ 18 Minage = 1<<30, 19 Defagefreq = 1<<30, /* age names this often (seconds) */ 20 Restartmins = 600, 21 22 /* these settings will trigger frequent aging */ 23 // Deftarget = 4000, 24 // Minage = 5*60, 25 // Defagefreq = 15*60, /* age names this often (seconds) */ 26 }; 27 28 /* 29 * Hash table for domain names. The hash is based only on the 30 * first element of the domain name. 31 */ 32 DN *ht[HTLEN]; 33 34 static struct { 35 Lock; 36 ulong names; /* names allocated */ 37 ulong oldest; /* longest we'll leave a name around */ 38 int active; 39 int mutex; 40 ushort id; /* same size as in packet */ 41 } dnvars; 42 43 /* names of RR types */ 44 char *rrtname[] = 45 { 46 [Ta] "ip", 47 [Tns] "ns", 48 [Tmd] "md", 49 [Tmf] "mf", 50 [Tcname] "cname", 51 [Tsoa] "soa", 52 [Tmb] "mb", 53 [Tmg] "mg", 54 [Tmr] "mr", 55 [Tnull] "null", 56 [Twks] "wks", 57 [Tptr] "ptr", 58 [Thinfo] "hinfo", 59 [Tminfo] "minfo", 60 [Tmx] "mx", 61 [Ttxt] "txt", 62 [Trp] "rp", 63 [Tafsdb] "afsdb", 64 [Tx25] "x.25", 65 [Tisdn] "isdn", 66 [Trt] "rt", 67 [Tnsap] "nsap", 68 [Tnsapptr] "nsap-ptr", 69 [Tsig] "sig", 70 [Tkey] "key", 71 [Tpx] "px", 72 [Tgpos] "gpos", 73 [Taaaa] "ipv6", 74 [Tloc] "loc", 75 [Tnxt] "nxt", 76 [Teid] "eid", 77 [Tnimloc] "nimrod", 78 [Tsrv] "srv", 79 [Tatma] "atma", 80 [Tnaptr] "naptr", 81 [Tkx] "kx", 82 [Tcert] "cert", 83 [Ta6] "a6", 84 [Tdname] "dname", 85 [Tsink] "sink", 86 [Topt] "opt", 87 [Tapl] "apl", 88 [Tds] "ds", 89 [Tsshfp] "sshfp", 90 [Tipseckey] "ipseckey", 91 [Trrsig] "rrsig", 92 [Tnsec] "nsec", 93 [Tdnskey] "dnskey", 94 [Tspf] "spf", 95 [Tuinfo] "uinfo", 96 [Tuid] "uid", 97 [Tgid] "gid", 98 [Tunspec] "unspec", 99 [Ttkey] "tkey", 100 [Ttsig] "tsig", 101 [Tixfr] "ixfr", 102 [Taxfr] "axfr", 103 [Tmailb] "mailb", 104 [Tmaila] "maila", 105 [Tall] "all", 106 0, 107 }; 108 109 /* names of response codes */ 110 char *rname[Rmask+1] = 111 { 112 [Rok] "ok", 113 [Rformat] "format error", 114 [Rserver] "server failure", 115 [Rname] "bad name", 116 [Runimplimented] "unimplemented", 117 [Rrefused] "we don't like you", 118 [Ryxdomain] "name should not exist", 119 [Ryxrrset] "rr set should not exist", 120 [Rnxrrset] "rr set should exist", 121 [Rnotauth] "not authorative", 122 [Rnotzone] "not in zone", 123 [Rbadvers] "bad opt version", 124 /* [Rbadsig] "bad signature", */ 125 [Rbadkey] "bad key", 126 [Rbadtime] "bad signature time", 127 [Rbadmode] "bad mode", 128 [Rbadname] "duplicate key name", 129 [Rbadalg] "bad algorithm", 130 }; 131 unsigned nrname = nelem(rname); 132 133 /* names of op codes */ 134 char *opname[] = 135 { 136 [Oquery] "query", 137 [Oinverse] "inverse query (retired)", 138 [Ostatus] "status", 139 [Oupdate] "update", 140 }; 141 142 ulong target = Deftarget; 143 ulong start; 144 Lock dnlock; 145 146 static ulong agefreq = Defagefreq; 147 148 static int rrequiv(RR *r1, RR *r2); 149 static int sencodefmt(Fmt*); 150 151 static void 152 ding(void*, char *msg) 153 { 154 if(strstr(msg, "alarm") != nil) { 155 stats.alarms++; 156 noted(NCONT); /* resume with system call error */ 157 } else 158 noted(NDFLT); /* die */ 159 } 160 161 void 162 dninit(void) 163 { 164 fmtinstall('E', eipfmt); 165 fmtinstall('I', eipfmt); 166 fmtinstall('V', eipfmt); 167 fmtinstall('R', rrfmt); 168 fmtinstall('Q', rravfmt); 169 fmtinstall('H', sencodefmt); 170 171 dnvars.oldest = maxage; 172 dnvars.names = 0; 173 dnvars.id = truerand(); /* don't start with same id every time */ 174 175 notify(ding); 176 } 177 178 /* 179 * hash for a domain name 180 */ 181 static ulong 182 dnhash(char *name) 183 { 184 ulong hash; 185 uchar *val = (uchar*)name; 186 187 for(hash = 0; *val; val++) 188 hash = hash*13 + tolower(*val)-'a'; 189 return hash % HTLEN; 190 } 191 192 /* 193 * lookup a symbol. if enter is not zero and the name is 194 * not found, create it. 195 */ 196 DN* 197 dnlookup(char *name, int class, int enter) 198 { 199 DN **l; 200 DN *dp; 201 202 l = &ht[dnhash(name)]; 203 lock(&dnlock); 204 for(dp = *l; dp; dp = dp->next) { 205 assert(dp->magic == DNmagic); 206 if(dp->class == class && cistrcmp(dp->name, name) == 0){ 207 dp->referenced = now; 208 unlock(&dnlock); 209 return dp; 210 } 211 l = &dp->next; 212 } 213 214 if(!enter){ 215 unlock(&dnlock); 216 return 0; 217 } 218 dnvars.names++; 219 dp = emalloc(sizeof(*dp)); 220 dp->magic = DNmagic; 221 dp->name = estrdup(name); 222 assert(dp->name != nil); 223 dp->class = class; 224 dp->rr = 0; 225 dp->referenced = now; 226 /* add new DN to tail of the hash list. *l points to last next ptr. */ 227 dp->next = nil; 228 *l = dp; 229 unlock(&dnlock); 230 231 return dp; 232 } 233 234 static int 235 rrsame(RR *rr1, RR *rr2) 236 { 237 return rr1 == rr2 || rr2 && rrequiv(rr1, rr2) && 238 rr1->db == rr2->db && rr1->auth == rr2->auth; 239 } 240 241 static int 242 rronlist(RR *rp, RR *lp) 243 { 244 for(; lp; lp = lp->next) 245 if (rrsame(lp, rp)) 246 return 1; 247 return 0; 248 } 249 250 /* 251 * dump the stats 252 */ 253 void 254 dnstats(char *file) 255 { 256 int i, fd; 257 258 fd = create(file, OWRITE, 0666); 259 if(fd < 0) 260 return; 261 262 qlock(&stats); 263 fprint(fd, "# system %s\n", sysname()); 264 fprint(fd, "# slave procs high-water mark\t%lud\n", stats.slavehiwat); 265 fprint(fd, "# queries received by 9p\t%lud\n", stats.qrecvd9p); 266 fprint(fd, "# queries received by udp\t%lud\n", stats.qrecvdudp); 267 fprint(fd, "# queries answered from memory\t%lud\n", stats.answinmem); 268 fprint(fd, "# queries sent by udp\t%lud\n", stats.qsent); 269 for (i = 0; i < nelem(stats.under10ths); i++) 270 if (stats.under10ths[i] || i == nelem(stats.under10ths) - 1) 271 fprint(fd, "# responses arriving within %.1f s.\t%lud\n", 272 (double)(i+1)/10, stats.under10ths[i]); 273 fprint(fd, "\n# queries sent & timed-out\t%lud\n", stats.tmout); 274 fprint(fd, "# cname queries timed-out\t%lud\n", stats.tmoutcname); 275 fprint(fd, "# ipv6 queries timed-out\t%lud\n", stats.tmoutv6); 276 fprint(fd, "\n# negative answers received\t%lud\n", stats.negans); 277 fprint(fd, "# negative answers w Rserver set\t%lud\n", stats.negserver); 278 fprint(fd, "# negative answers w bad delegation\t%lud\n", 279 stats.negbaddeleg); 280 fprint(fd, "# negative answers w bad delegation & no answers\t%lud\n", 281 stats.negbdnoans); 282 fprint(fd, "# negative answers w no Rname set\t%lud\n", stats.negnorname); 283 fprint(fd, "# negative answers cached\t%lud\n", stats.negcached); 284 qunlock(&stats); 285 286 lock(&dnlock); 287 fprint(fd, "\n# domain names %lud target %lud\n", dnvars.names, target); 288 unlock(&dnlock); 289 close(fd); 290 } 291 292 /* 293 * dump the cache 294 */ 295 void 296 dndump(char *file) 297 { 298 int i, fd; 299 DN *dp; 300 RR *rp; 301 302 fd = create(file, OWRITE, 0666); 303 if(fd < 0) 304 return; 305 306 lock(&dnlock); 307 for(i = 0; i < HTLEN; i++) 308 for(dp = ht[i]; dp; dp = dp->next){ 309 fprint(fd, "%s\n", dp->name); 310 for(rp = dp->rr; rp; rp = rp->next) { 311 fprint(fd, "\t%R %c%c %lud/%lud\n", 312 rp, rp->auth? 'A': 'U', 313 rp->db? 'D': 'N', rp->expire, rp->ttl); 314 if (rronlist(rp, rp->next)) 315 fprint(fd, "*** duplicate:\n"); 316 } 317 } 318 unlock(&dnlock); 319 close(fd); 320 } 321 322 /* 323 * purge all records 324 */ 325 void 326 dnpurge(void) 327 { 328 DN *dp; 329 RR *rp, *srp; 330 int i; 331 332 lock(&dnlock); 333 334 for(i = 0; i < HTLEN; i++) 335 for(dp = ht[i]; dp; dp = dp->next){ 336 srp = rp = dp->rr; 337 dp->rr = nil; 338 for(; rp != nil; rp = rp->next) 339 rp->cached = 0; 340 rrfreelist(srp); 341 } 342 343 unlock(&dnlock); 344 } 345 346 /* 347 * delete head of *l and free the old head. 348 * call with dnlock held. 349 */ 350 static void 351 rrdelhead(RR **l) 352 { 353 RR *rp; 354 355 if (canlock(&dnlock)) 356 abort(); /* rrdelhead called with dnlock not held */ 357 rp = *l; 358 if(rp == nil) 359 return; 360 *l = rp->next; /* unlink head */ 361 rp->cached = 0; /* avoid blowing an assertion in rrfree */ 362 rrfree(rp); 363 } 364 365 /* 366 * check the age of resource records, free any that have timed out. 367 * call with dnlock held. 368 */ 369 void 370 dnage(DN *dp) 371 { 372 RR **l; 373 RR *rp, *next; 374 ulong diff; 375 376 if (canlock(&dnlock)) 377 abort(); /* dnage called with dnlock not held */ 378 diff = now - dp->referenced; 379 if(diff < Reserved || dp->keep) 380 return; 381 382 l = &dp->rr; 383 for(rp = dp->rr; rp; rp = next){ 384 assert(rp->magic == RRmagic && rp->cached); 385 next = rp->next; 386 if(!rp->db && (rp->expire < now || diff > dnvars.oldest)) 387 rrdelhead(l); /* rp == *l before; *l == rp->next after */ 388 else 389 l = &rp->next; 390 } 391 } 392 393 #define MARK(dp) { if (dp) (dp)->keep = 1; } 394 395 /* mark a domain name and those in its RRs as never to be aged */ 396 void 397 dnagenever(DN *dp, int dolock) 398 { 399 RR *rp; 400 401 if (dolock) 402 lock(&dnlock); 403 404 /* mark all referenced domain names */ 405 MARK(dp); 406 for(rp = dp->rr; rp; rp = rp->next){ 407 MARK(rp->owner); 408 if(rp->negative){ 409 MARK(rp->negsoaowner); 410 continue; 411 } 412 switch(rp->type){ 413 case Thinfo: 414 MARK(rp->cpu); 415 MARK(rp->os); 416 break; 417 case Ttxt: 418 break; 419 case Tcname: 420 case Tmb: 421 case Tmd: 422 case Tmf: 423 case Tns: 424 case Tmx: 425 case Tsrv: 426 MARK(rp->host); 427 break; 428 case Tmg: 429 case Tmr: 430 MARK(rp->mb); 431 break; 432 case Tminfo: 433 MARK(rp->rmb); 434 MARK(rp->mb); 435 break; 436 case Trp: 437 MARK(rp->rmb); 438 MARK(rp->rp); 439 break; 440 case Ta: 441 case Taaaa: 442 MARK(rp->ip); 443 break; 444 case Tptr: 445 MARK(rp->ptr); 446 break; 447 case Tsoa: 448 MARK(rp->host); 449 MARK(rp->rmb); 450 break; 451 } 452 } 453 454 if (dolock) 455 unlock(&dnlock); 456 } 457 458 /* mark all current domain names as never to be aged */ 459 void 460 dnageallnever(void) 461 { 462 int i; 463 DN *dp; 464 465 lock(&dnlock); 466 467 /* mark all referenced domain names */ 468 for(i = 0; i < HTLEN; i++) 469 for(dp = ht[i]; dp; dp = dp->next) 470 dnagenever(dp, 0); 471 472 unlock(&dnlock); 473 474 dnslog("%ld initial domain names; target is %ld", dnvars.names, target); 475 if(dnvars.names >= target) 476 dnslog("more initial domain names (%ld) than target (%ld)", 477 dnvars.names, target); 478 } 479 480 #define REF(dp) { if (dp) (dp)->refs++; } 481 482 /* 483 * periodicly sweep for old records and remove unreferenced domain names 484 * 485 * only called when all other threads are locked out 486 */ 487 void 488 dnageall(int doit) 489 { 490 DN *dp, **l; 491 int i; 492 RR *rp; 493 static ulong nextage; 494 495 if(dnvars.names < target || (now < nextage && !doit)){ 496 dnvars.oldest = maxage; 497 return; 498 } 499 500 if(dnvars.names >= target) { 501 dnslog("more names (%lud) than target (%lud)", dnvars.names, 502 target); 503 dnvars.oldest /= 2; 504 if (dnvars.oldest < Minage) 505 dnvars.oldest = Minage; /* don't be silly */ 506 } 507 if (agefreq > dnvars.oldest / 2) 508 nextage = now + dnvars.oldest / 2; 509 else 510 nextage = now + agefreq; 511 512 lock(&dnlock); 513 514 /* time out all old entries (and set refs to 0) */ 515 for(i = 0; i < HTLEN; i++) 516 for(dp = ht[i]; dp; dp = dp->next){ 517 dp->refs = 0; 518 dnage(dp); 519 } 520 521 /* mark all referenced domain names */ 522 for(i = 0; i < HTLEN; i++) 523 for(dp = ht[i]; dp; dp = dp->next) 524 for(rp = dp->rr; rp; rp = rp->next){ 525 REF(rp->owner); 526 if(rp->negative){ 527 REF(rp->negsoaowner); 528 continue; 529 } 530 switch(rp->type){ 531 case Thinfo: 532 REF(rp->cpu); 533 REF(rp->os); 534 break; 535 case Ttxt: 536 break; 537 case Tcname: 538 case Tmb: 539 case Tmd: 540 case Tmf: 541 case Tns: 542 case Tmx: 543 case Tsrv: 544 REF(rp->host); 545 break; 546 case Tmg: 547 case Tmr: 548 REF(rp->mb); 549 break; 550 case Tminfo: 551 REF(rp->rmb); 552 REF(rp->mb); 553 break; 554 case Trp: 555 REF(rp->rmb); 556 REF(rp->rp); 557 break; 558 case Ta: 559 case Taaaa: 560 REF(rp->ip); 561 break; 562 case Tptr: 563 REF(rp->ptr); 564 break; 565 case Tsoa: 566 REF(rp->host); 567 REF(rp->rmb); 568 break; 569 } 570 } 571 572 /* sweep and remove unreferenced domain names */ 573 for(i = 0; i < HTLEN; i++){ 574 l = &ht[i]; 575 for(dp = *l; dp; dp = *l){ 576 if(dp->rr == 0 && dp->refs == 0 && !dp->keep){ 577 assert(dp->magic == DNmagic); 578 *l = dp->next; 579 580 if(dp->name) 581 free(dp->name); 582 dp->magic = ~dp->magic; 583 dnvars.names--; 584 memset(dp, 0, sizeof *dp); /* cause trouble */ 585 free(dp); 586 587 continue; 588 } 589 l = &dp->next; 590 } 591 } 592 593 unlock(&dnlock); 594 } 595 596 /* 597 * timeout all database records (used when rereading db) 598 */ 599 void 600 dnagedb(void) 601 { 602 DN *dp; 603 int i; 604 RR *rp; 605 606 lock(&dnlock); 607 608 /* time out all database entries */ 609 for(i = 0; i < HTLEN; i++) 610 for(dp = ht[i]; dp; dp = dp->next) { 611 dp->keep = 0; 612 for(rp = dp->rr; rp; rp = rp->next) 613 if(rp->db) 614 rp->expire = 0; 615 } 616 617 unlock(&dnlock); 618 } 619 620 /* 621 * mark all local db records about my area as authoritative, 622 * time out any others 623 */ 624 void 625 dnauthdb(void) 626 { 627 int i; 628 ulong minttl; 629 Area *area; 630 DN *dp; 631 RR *rp; 632 633 lock(&dnlock); 634 635 /* time out all database entries */ 636 for(i = 0; i < HTLEN; i++) 637 for(dp = ht[i]; dp; dp = dp->next){ 638 area = inmyarea(dp->name); 639 for(rp = dp->rr; rp; rp = rp->next) 640 if(rp->db){ 641 if(area){ 642 minttl = area->soarr->soa->minttl; 643 if(rp->ttl < minttl) 644 rp->ttl = minttl; 645 rp->auth = 1; 646 } 647 if(rp->expire == 0){ 648 rp->db = 0; 649 dp->referenced = now-Reserved-1; 650 } 651 } 652 } 653 654 unlock(&dnlock); 655 } 656 657 /* 658 * keep track of other processes to know if we can 659 * garbage collect. block while garbage collecting. 660 */ 661 int 662 getactivity(Request *req, int recursive) 663 { 664 int rv; 665 666 if(traceactivity) 667 dnslog("get: %d active by pid %d from %p", 668 dnvars.active, getpid(), getcallerpc(&req)); 669 lock(&dnvars); 670 /* 671 * can't block here if we're already holding one 672 * of the dnvars.active (recursive). will deadlock. 673 */ 674 while(!recursive && dnvars.mutex){ 675 unlock(&dnvars); 676 sleep(100); /* tune; was 200 */ 677 lock(&dnvars); 678 } 679 rv = ++dnvars.active; 680 now = time(nil); 681 nowns = nsec(); 682 req->id = ++dnvars.id; 683 unlock(&dnvars); 684 685 return rv; 686 } 687 void 688 putactivity(int recursive) 689 { 690 static ulong lastclean; 691 692 if(traceactivity) 693 dnslog("put: %d active by pid %d", 694 dnvars.active, getpid()); 695 lock(&dnvars); 696 dnvars.active--; 697 assert(dnvars.active >= 0); /* "dnvars.active %d", dnvars.active */ 698 699 /* 700 * clean out old entries and check for new db periodicly 701 * can't block here if being called to let go a "recursive" lock 702 * or we'll deadlock waiting for ourselves to give up the dnvars.active. 703 */ 704 if (recursive || dnvars.mutex || 705 (needrefresh == 0 && dnvars.active > 0)){ 706 unlock(&dnvars); 707 return; 708 } 709 710 /* wait till we're alone */ 711 dnvars.mutex = 1; 712 while(dnvars.active > 0){ 713 unlock(&dnvars); 714 sleep(100); /* tune; was 100 */ 715 lock(&dnvars); 716 } 717 unlock(&dnvars); 718 719 db2cache(needrefresh); 720 721 /* if we've been running for long enough, restart */ 722 if(start == 0) 723 start = time(nil); 724 if(0 && time(nil) - start > Restartmins*60){ // TODO 725 dnslog("killing all dns procs for timed restart"); 726 postnote(PNGROUP, getpid(), "die"); 727 dnvars.mutex = 0; 728 exits("restart"); 729 } 730 731 dnageall(0); 732 733 /* let others back in */ 734 lastclean = now; 735 needrefresh = 0; 736 dnvars.mutex = 0; 737 } 738 739 int 740 rrlistlen(RR *rp) 741 { 742 int n; 743 744 n = 0; 745 for(; rp; rp = rp->next) 746 ++n; 747 return n; 748 } 749 750 /* 751 * Attach a single resource record to a domain name (new->owner). 752 * - Avoid duplicates with already present RR's 753 * - Chain all RR's of the same type adjacent to one another 754 * - chain authoritative RR's ahead of non-authoritative ones 755 * - remove any expired RR's 756 * If new is a stale duplicate, rrfree it. 757 * Must be called with dnlock held. 758 */ 759 static void 760 rrattach1(RR *new, int auth) 761 { 762 RR **l; 763 RR *rp; 764 DN *dp; 765 766 assert(new->magic == RRmagic && !new->cached); 767 768 // dnslog("rrattach1: %s", new->owner->name); 769 if(!new->db) { 770 /* 771 * try not to let responses expire before we 772 * can use them to complete this query, by extending 773 * past (or nearly past) expiration time. 774 */ 775 new->expire = new->ttl > now + Min? new->ttl: now + 10*Min; 776 } else 777 new->expire = now + Year; 778 dp = new->owner; 779 assert(dp->magic == DNmagic); 780 new->auth |= auth; 781 new->next = 0; 782 783 /* 784 * find first rr of the right type 785 */ 786 l = &dp->rr; 787 for(rp = *l; rp; rp = *l){ 788 assert(rp->magic == RRmagic && rp->cached); 789 if(rp->type == new->type) 790 break; 791 l = &rp->next; 792 } 793 794 /* 795 * negative entries replace positive entries 796 * positive entries replace negative entries 797 * newer entries replace older entries with the same fields 798 * 799 * look farther ahead than just the next entry when looking 800 * for duplicates; RRs of a given type can have different rdata 801 * fields (e.g. multiple NS servers). 802 */ 803 while ((rp = *l) != nil){ 804 assert(rp->magic == RRmagic && rp->cached); 805 if(rp->type != new->type) 806 break; 807 808 if(rp->db == new->db && rp->auth == new->auth){ 809 /* negative drives out positive and vice versa */ 810 if(rp->negative != new->negative) { 811 /* rp == *l before; *l == rp->next after */ 812 rrdelhead(l); 813 continue; 814 } 815 /* all things equal, pick the newer one */ 816 else if(rp->arg0 == new->arg0 && rp->arg1 == new->arg1){ 817 /* new drives out old */ 818 if (new->ttl <= rp->ttl && 819 new->expire <= rp->expire) { 820 rrfree(new); 821 return; 822 } 823 /* rp == *l before; *l == rp->next after */ 824 rrdelhead(l); 825 continue; 826 } 827 /* 828 * Hack for pointer records. This makes sure 829 * the ordering in the list reflects the ordering 830 * received or read from the database 831 */ 832 else if(rp->type == Tptr && 833 !rp->negative && !new->negative && 834 rp->ptr->ordinal > new->ptr->ordinal) 835 break; 836 } 837 l = &rp->next; 838 } 839 840 if (rronlist(new, rp)) { 841 /* should not happen; duplicates were processed above */ 842 dnslog("adding duplicate %R to list of %R; aborting", new, rp); 843 abort(); 844 } 845 /* 846 * add to chain 847 */ 848 new->cached = 1; 849 new->next = rp; 850 *l = new; 851 } 852 853 /* 854 * Attach a list of resource records to a domain name. 855 * May rrfree any stale duplicate RRs; dismembers the list. 856 * Upon return, every RR in the list will have been rrfree-d 857 * or attached to its domain name. 858 * See rrattach1 for properties preserved. 859 */ 860 void 861 rrattach(RR *rp, int auth) 862 { 863 RR *next, *tp; 864 DN *dp; 865 866 lock(&dnlock); 867 for(; rp; rp = next){ 868 next = rp->next; 869 rp->next = nil; 870 dp = rp->owner; 871 872 // dnslog("rrattach: %s", rp->owner->name); 873 /* avoid any outside spoofing; leave keepers alone */ 874 if(cfg.cachedb && !rp->db && inmyarea(rp->owner->name) 875 // || dp->keep /* TODO: make this work */ 876 ) 877 rrfree(rp); 878 else { 879 /* ameliorate the memory leak (someday delete this) */ 880 if (0 && rrlistlen(dp->rr) > 50 && !dp->keep) { 881 dnslog("rrattach(%s): rr list too long; " 882 "freeing it", dp->name); 883 tp = dp->rr; 884 dp->rr = nil; 885 rrfreelist(tp); 886 } else 887 USED(dp); 888 rrattach1(rp, auth); 889 } 890 } 891 unlock(&dnlock); 892 } 893 894 /* should be called with dnlock held */ 895 RR** 896 rrcopy(RR *rp, RR **last) 897 { 898 Cert *cert; 899 Key *key; 900 Null *null; 901 RR *nrp; 902 SOA *soa; 903 Sig *sig; 904 Txt *t, *nt, **l; 905 906 if (canlock(&dnlock)) 907 abort(); /* rrcopy called with dnlock not held */ 908 nrp = rralloc(rp->type); 909 setmalloctag(nrp, getcallerpc(&rp)); 910 switch(rp->type){ 911 case Ttxt: 912 *nrp = *rp; 913 l = &nrp->txt; 914 *l = nil; 915 for(t = rp->txt; t != nil; t = t->next){ 916 nt = emalloc(sizeof(*nt)); 917 nt->p = estrdup(t->p); 918 nt->next = nil; 919 *l = nt; 920 l = &nt->next; 921 } 922 break; 923 case Tsoa: 924 soa = nrp->soa; 925 *nrp = *rp; 926 nrp->soa = soa; 927 *nrp->soa = *rp->soa; 928 nrp->soa->slaves = copyserverlist(rp->soa->slaves); 929 break; 930 case Tsrv: 931 *nrp = *rp; 932 nrp->srv = emalloc(sizeof *nrp->srv); 933 *nrp->srv = *rp->srv; 934 break; 935 case Tkey: 936 key = nrp->key; 937 *nrp = *rp; 938 nrp->key = key; 939 *key = *rp->key; 940 key->data = emalloc(key->dlen); 941 memmove(key->data, rp->key->data, rp->key->dlen); 942 break; 943 case Tsig: 944 sig = nrp->sig; 945 *nrp = *rp; 946 nrp->sig = sig; 947 *sig = *rp->sig; 948 sig->data = emalloc(sig->dlen); 949 memmove(sig->data, rp->sig->data, rp->sig->dlen); 950 break; 951 case Tcert: 952 cert = nrp->cert; 953 *nrp = *rp; 954 nrp->cert = cert; 955 *cert = *rp->cert; 956 cert->data = emalloc(cert->dlen); 957 memmove(cert->data, rp->cert->data, rp->cert->dlen); 958 break; 959 case Tnull: 960 null = nrp->null; 961 *nrp = *rp; 962 nrp->null = null; 963 *null = *rp->null; 964 null->data = emalloc(null->dlen); 965 memmove(null->data, rp->null->data, rp->null->dlen); 966 break; 967 default: 968 *nrp = *rp; 969 break; 970 } 971 nrp->cached = 0; 972 nrp->next = 0; 973 *last = nrp; 974 return &nrp->next; 975 } 976 977 /* 978 * lookup a resource record of a particular type and 979 * class attached to a domain name. Return copies. 980 * 981 * Priority ordering is: 982 * db authoritative 983 * not timed out network authoritative 984 * not timed out network unauthoritative 985 * unauthoritative db 986 * 987 * if flag NOneg is set, don't return negative cached entries. 988 * return nothing instead. 989 */ 990 RR* 991 rrlookup(DN *dp, int type, int flag) 992 { 993 RR *rp, *first, **last; 994 995 assert(dp->magic == DNmagic); 996 997 first = 0; 998 last = &first; 999 lock(&dnlock); 1000 1001 /* try for an authoritative db entry */ 1002 for(rp = dp->rr; rp; rp = rp->next){ 1003 assert(rp->magic == RRmagic && rp->cached); 1004 if(rp->db) 1005 if(rp->auth) 1006 if(tsame(type, rp->type)) { 1007 last = rrcopy(rp, last); 1008 // setmalloctag(*last, getcallerpc(&dp)); 1009 } 1010 } 1011 if(first) 1012 goto out; 1013 1014 /* try for a living authoritative network entry */ 1015 for(rp = dp->rr; rp; rp = rp->next){ 1016 if(!rp->db) 1017 if(rp->auth) 1018 if(rp->ttl + 60 > now) 1019 if(tsame(type, rp->type)){ 1020 if(flag == NOneg && rp->negative) 1021 goto out; 1022 last = rrcopy(rp, last); 1023 } 1024 } 1025 if(first) 1026 goto out; 1027 1028 /* try for a living unauthoritative network entry */ 1029 for(rp = dp->rr; rp; rp = rp->next){ 1030 if(!rp->db) 1031 if(rp->ttl + 60 > now) 1032 if(tsame(type, rp->type)){ 1033 if(flag == NOneg && rp->negative) 1034 goto out; 1035 last = rrcopy(rp, last); 1036 } 1037 } 1038 if(first) 1039 goto out; 1040 1041 /* try for an unauthoritative db entry */ 1042 for(rp = dp->rr; rp; rp = rp->next){ 1043 if(rp->db) 1044 if(tsame(type, rp->type)) 1045 last = rrcopy(rp, last); 1046 } 1047 if(first) 1048 goto out; 1049 1050 /* otherwise, settle for anything we got (except for negative caches) */ 1051 for(rp = dp->rr; rp; rp = rp->next) 1052 if(tsame(type, rp->type)){ 1053 if(rp->negative) 1054 goto out; 1055 last = rrcopy(rp, last); 1056 } 1057 1058 out: 1059 unique(first); 1060 unlock(&dnlock); 1061 // dnslog("rrlookup(%s) -> %#p\t# in-core only", dp->name, first); 1062 // if (first) 1063 // setmalloctag(first, getcallerpc(&dp)); 1064 return first; 1065 } 1066 1067 /* 1068 * convert an ascii RR type name to its integer representation 1069 */ 1070 int 1071 rrtype(char *atype) 1072 { 1073 int i; 1074 1075 for(i = 0; i <= Tall; i++) 1076 if(rrtname[i] && strcmp(rrtname[i], atype) == 0) 1077 return i; 1078 1079 /* make any a synonym for all */ 1080 if(strcmp(atype, "any") == 0) 1081 return Tall; 1082 else if(isascii(atype[0]) && isdigit(atype[0])) 1083 return atoi(atype); 1084 else 1085 return -1; 1086 } 1087 1088 /* 1089 * return 0 if not a supported rr type 1090 */ 1091 int 1092 rrsupported(int type) 1093 { 1094 if(type < 0 || type >Tall) 1095 return 0; 1096 return rrtname[type] != nil; 1097 } 1098 1099 /* 1100 * compare 2 types 1101 */ 1102 int 1103 tsame(int t1, int t2) 1104 { 1105 return t1 == t2 || t1 == Tall; 1106 } 1107 1108 /* 1109 * Add resource records to a list, duplicate them if they are cached 1110 * RR's since these are shared. should be called with dnlock held 1111 * to avoid racing down the start chain. 1112 */ 1113 RR* 1114 rrcat(RR **start, RR *rp) 1115 { 1116 RR *olp, *nlp; 1117 RR **last; 1118 1119 if (canlock(&dnlock)) 1120 abort(); /* rrcat called with dnlock not held */ 1121 /* check for duplicates */ 1122 for (olp = *start; 0 && olp; olp = olp->next) 1123 for (nlp = rp; nlp; nlp = nlp->next) 1124 if (rrsame(nlp, olp)) 1125 dnslog("rrcat: duplicate RR: %R", nlp); 1126 USED(olp); 1127 1128 last = start; 1129 while(*last != nil) 1130 last = &(*last)->next; 1131 1132 *last = rp; 1133 return *start; 1134 } 1135 1136 /* 1137 * remove negative cache rr's from an rr list 1138 */ 1139 RR* 1140 rrremneg(RR **l) 1141 { 1142 RR **nl, *rp; 1143 RR *first; 1144 1145 if (canlock(&dnlock)) 1146 abort(); /* rrremneg called with dnlock not held */ 1147 first = nil; 1148 nl = &first; 1149 while(*l != nil){ 1150 rp = *l; 1151 if(rp->negative){ 1152 *l = rp->next; 1153 *nl = rp; 1154 nl = &rp->next; 1155 *nl = nil; 1156 } else 1157 l = &rp->next; 1158 } 1159 1160 return first; 1161 } 1162 1163 /* 1164 * remove rr's of a particular type from an rr list 1165 */ 1166 RR* 1167 rrremtype(RR **l, int type) 1168 { 1169 RR *first, *rp; 1170 RR **nl; 1171 1172 first = nil; 1173 nl = &first; 1174 while(*l != nil){ 1175 rp = *l; 1176 if(rp->type == type){ 1177 *l = rp->next; 1178 *nl = rp; 1179 nl = &rp->next; 1180 *nl = nil; 1181 } else 1182 l = &(*l)->next; 1183 } 1184 1185 return first; 1186 } 1187 1188 static char * 1189 dnname(DN *dn) 1190 { 1191 return dn? dn->name: "<null>"; 1192 } 1193 1194 /* 1195 * print conversion for rr records 1196 */ 1197 int 1198 rrfmt(Fmt *f) 1199 { 1200 int rv; 1201 char *strp; 1202 char buf[Domlen]; 1203 Fmt fstr; 1204 RR *rp; 1205 Server *s; 1206 SOA *soa; 1207 Srv *srv; 1208 Txt *t; 1209 1210 fmtstrinit(&fstr); 1211 1212 rp = va_arg(f->args, RR*); 1213 if(rp == nil){ 1214 fmtprint(&fstr, "<null>"); 1215 goto out; 1216 } 1217 1218 fmtprint(&fstr, "%s %s", dnname(rp->owner), 1219 rrname(rp->type, buf, sizeof buf)); 1220 1221 if(rp->negative){ 1222 fmtprint(&fstr, "\tnegative - rcode %d", rp->negrcode); 1223 goto out; 1224 } 1225 1226 switch(rp->type){ 1227 case Thinfo: 1228 fmtprint(&fstr, "\t%s %s", dnname(rp->cpu), dnname(rp->os)); 1229 break; 1230 case Tcname: 1231 case Tmb: 1232 case Tmd: 1233 case Tmf: 1234 case Tns: 1235 fmtprint(&fstr, "\t%s", dnname(rp->host)); 1236 break; 1237 case Tmg: 1238 case Tmr: 1239 fmtprint(&fstr, "\t%s", dnname(rp->mb)); 1240 break; 1241 case Tminfo: 1242 fmtprint(&fstr, "\t%s %s", dnname(rp->mb), dnname(rp->rmb)); 1243 break; 1244 case Tmx: 1245 fmtprint(&fstr, "\t%lud %s", rp->pref, dnname(rp->host)); 1246 break; 1247 case Ta: 1248 case Taaaa: 1249 fmtprint(&fstr, "\t%s", dnname(rp->ip)); 1250 break; 1251 case Tptr: 1252 // fmtprint(&fstr, "\t%s(%lud)", dnname(rp->ptr), 1253 // rp->ptr? rp->ptr->ordinal: "<null>"); 1254 fmtprint(&fstr, "\t%s", dnname(rp->ptr)); 1255 break; 1256 case Tsoa: 1257 soa = rp->soa; 1258 fmtprint(&fstr, "\t%s %s %lud %lud %lud %lud %lud", 1259 dnname(rp->host), dnname(rp->rmb), 1260 (soa? soa->serial: 0), 1261 (soa? soa->refresh: 0), (soa? soa->retry: 0), 1262 (soa? soa->expire: 0), (soa? soa->minttl: 0)); 1263 if (soa) 1264 for(s = soa->slaves; s != nil; s = s->next) 1265 fmtprint(&fstr, " %s", s->name); 1266 break; 1267 case Tsrv: 1268 srv = rp->srv; 1269 fmtprint(&fstr, "\t%ud %ud %ud %s", 1270 (srv? srv->pri: 0), (srv? srv->weight: 0), 1271 rp->port, dnname(rp->host)); 1272 break; 1273 case Tnull: 1274 if (rp->null == nil) 1275 fmtprint(&fstr, "\t<null>"); 1276 else 1277 fmtprint(&fstr, "\t%.*H", rp->null->dlen, 1278 rp->null->data); 1279 break; 1280 case Ttxt: 1281 fmtprint(&fstr, "\t"); 1282 for(t = rp->txt; t != nil; t = t->next) 1283 fmtprint(&fstr, "%s", t->p); 1284 break; 1285 case Trp: 1286 fmtprint(&fstr, "\t%s %s", dnname(rp->rmb), dnname(rp->rp)); 1287 break; 1288 case Tkey: 1289 if (rp->key == nil) 1290 fmtprint(&fstr, "\t<null> <null> <null>"); 1291 else 1292 fmtprint(&fstr, "\t%d %d %d", rp->key->flags, 1293 rp->key->proto, rp->key->alg); 1294 break; 1295 case Tsig: 1296 if (rp->sig == nil) 1297 fmtprint(&fstr, 1298 "\t<null> <null> <null> <null> <null> <null> <null> <null>"); 1299 else 1300 fmtprint(&fstr, "\t%d %d %d %lud %lud %lud %d %s", 1301 rp->sig->type, rp->sig->alg, rp->sig->labels, 1302 rp->sig->ttl, rp->sig->exp, rp->sig->incep, 1303 rp->sig->tag, dnname(rp->sig->signer)); 1304 break; 1305 case Tcert: 1306 if (rp->cert == nil) 1307 fmtprint(&fstr, "\t<null> <null> <null>"); 1308 else 1309 fmtprint(&fstr, "\t%d %d %d", 1310 rp->cert->type, rp->cert->tag, rp->cert->alg); 1311 break; 1312 } 1313 out: 1314 strp = fmtstrflush(&fstr); 1315 rv = fmtstrcpy(f, strp); 1316 free(strp); 1317 return rv; 1318 } 1319 1320 /* 1321 * print conversion for rr records in attribute value form 1322 */ 1323 int 1324 rravfmt(Fmt *f) 1325 { 1326 int rv, quote; 1327 char *strp; 1328 Fmt fstr; 1329 RR *rp; 1330 Server *s; 1331 SOA *soa; 1332 Srv *srv; 1333 Txt *t; 1334 1335 fmtstrinit(&fstr); 1336 1337 rp = va_arg(f->args, RR*); 1338 if(rp == nil){ 1339 fmtprint(&fstr, "<null>"); 1340 goto out; 1341 } 1342 1343 if(rp->type == Tptr) 1344 fmtprint(&fstr, "ptr=%s", dnname(rp->owner)); 1345 else 1346 fmtprint(&fstr, "dom=%s", dnname(rp->owner)); 1347 1348 switch(rp->type){ 1349 case Thinfo: 1350 fmtprint(&fstr, " cpu=%s os=%s", 1351 dnname(rp->cpu), dnname(rp->os)); 1352 break; 1353 case Tcname: 1354 fmtprint(&fstr, " cname=%s", dnname(rp->host)); 1355 break; 1356 case Tmb: 1357 case Tmd: 1358 case Tmf: 1359 fmtprint(&fstr, " mbox=%s", dnname(rp->host)); 1360 break; 1361 case Tns: 1362 fmtprint(&fstr, " ns=%s", dnname(rp->host)); 1363 break; 1364 case Tmg: 1365 case Tmr: 1366 fmtprint(&fstr, " mbox=%s", dnname(rp->mb)); 1367 break; 1368 case Tminfo: 1369 fmtprint(&fstr, " mbox=%s mbox=%s", 1370 dnname(rp->mb), dnname(rp->rmb)); 1371 break; 1372 case Tmx: 1373 fmtprint(&fstr, " pref=%lud mx=%s", rp->pref, dnname(rp->host)); 1374 break; 1375 case Ta: 1376 case Taaaa: 1377 fmtprint(&fstr, " ip=%s", dnname(rp->ip)); 1378 break; 1379 case Tptr: 1380 fmtprint(&fstr, " dom=%s", dnname(rp->ptr)); 1381 break; 1382 case Tsoa: 1383 soa = rp->soa; 1384 fmtprint(&fstr, 1385 " ns=%s mbox=%s serial=%lud refresh=%lud retry=%lud expire=%lud ttl=%lud", 1386 dnname(rp->host), dnname(rp->rmb), 1387 (soa? soa->serial: 0), 1388 (soa? soa->refresh: 0), (soa? soa->retry: 0), 1389 (soa? soa->expire: 0), (soa? soa->minttl: 0)); 1390 for(s = soa->slaves; s != nil; s = s->next) 1391 fmtprint(&fstr, " dnsslave=%s", s->name); 1392 break; 1393 case Tsrv: 1394 srv = rp->srv; 1395 fmtprint(&fstr, " pri=%ud weight=%ud port=%ud target=%s", 1396 (srv? srv->pri: 0), (srv? srv->weight: 0), 1397 rp->port, dnname(rp->host)); 1398 break; 1399 case Tnull: 1400 if (rp->null == nil) 1401 fmtprint(&fstr, " null=<null>"); 1402 else 1403 fmtprint(&fstr, " null=%.*H", rp->null->dlen, 1404 rp->null->data); 1405 break; 1406 case Ttxt: 1407 fmtprint(&fstr, " txt="); 1408 quote = 0; 1409 for(t = rp->txt; t != nil; t = t->next) 1410 if(strchr(t->p, ' ')) 1411 quote = 1; 1412 if(quote) 1413 fmtprint(&fstr, "\""); 1414 for(t = rp->txt; t != nil; t = t->next) 1415 fmtprint(&fstr, "%s", t->p); 1416 if(quote) 1417 fmtprint(&fstr, "\""); 1418 break; 1419 case Trp: 1420 fmtprint(&fstr, " rp=%s txt=%s", 1421 dnname(rp->rmb), dnname(rp->rp)); 1422 break; 1423 case Tkey: 1424 if (rp->key == nil) 1425 fmtprint(&fstr, " flags=<null> proto=<null> alg=<null>"); 1426 else 1427 fmtprint(&fstr, " flags=%d proto=%d alg=%d", 1428 rp->key->flags, rp->key->proto, rp->key->alg); 1429 break; 1430 case Tsig: 1431 if (rp->sig == nil) 1432 fmtprint(&fstr, 1433 " type=<null> alg=<null> labels=<null> ttl=<null> exp=<null> incep=<null> tag=<null> signer=<null>"); 1434 else 1435 fmtprint(&fstr, 1436 " type=%d alg=%d labels=%d ttl=%lud exp=%lud incep=%lud tag=%d signer=%s", 1437 rp->sig->type, rp->sig->alg, rp->sig->labels, 1438 rp->sig->ttl, rp->sig->exp, rp->sig->incep, 1439 rp->sig->tag, dnname(rp->sig->signer)); 1440 break; 1441 case Tcert: 1442 if (rp->cert == nil) 1443 fmtprint(&fstr, " type=<null> tag=<null> alg=<null>"); 1444 else 1445 fmtprint(&fstr, " type=%d tag=%d alg=%d", 1446 rp->cert->type, rp->cert->tag, rp->cert->alg); 1447 break; 1448 } 1449 out: 1450 strp = fmtstrflush(&fstr); 1451 rv = fmtstrcpy(f, strp); 1452 free(strp); 1453 return rv; 1454 } 1455 1456 void 1457 warning(char *fmt, ...) 1458 { 1459 char dnserr[256]; 1460 va_list arg; 1461 1462 va_start(arg, fmt); 1463 vseprint(dnserr, dnserr+sizeof(dnserr), fmt, arg); 1464 va_end(arg); 1465 syslog(1, logfile, dnserr); /* on console too */ 1466 } 1467 1468 void 1469 dnslog(char *fmt, ...) 1470 { 1471 char dnserr[256]; 1472 va_list arg; 1473 1474 va_start(arg, fmt); 1475 vseprint(dnserr, dnserr+sizeof(dnserr), fmt, arg); 1476 va_end(arg); 1477 syslog(0, logfile, dnserr); 1478 } 1479 1480 /* 1481 * based on libthread's threadsetname, but drags in less library code. 1482 * actually just sets the arguments displayed. 1483 */ 1484 void 1485 procsetname(char *fmt, ...) 1486 { 1487 int fd; 1488 char *cmdname; 1489 char buf[128]; 1490 va_list arg; 1491 1492 va_start(arg, fmt); 1493 cmdname = vsmprint(fmt, arg); 1494 va_end(arg); 1495 if (cmdname == nil) 1496 return; 1497 snprint(buf, sizeof buf, "#p/%d/args", getpid()); 1498 if((fd = open(buf, OWRITE)) >= 0){ 1499 write(fd, cmdname, strlen(cmdname)+1); 1500 close(fd); 1501 } 1502 free(cmdname); 1503 } 1504 1505 /* 1506 * create a slave process to handle a request to avoid one request blocking 1507 * another 1508 */ 1509 void 1510 slave(Request *req) 1511 { 1512 int ppid, procs; 1513 1514 if(req->isslave) 1515 return; /* we're already a slave process */ 1516 1517 /* 1518 * These calls to putactivity cannot block. 1519 * After getactivity(), the current process is counted 1520 * twice in dnvars.active (one will pass to the child). 1521 * If putactivity tries to wait for dnvars.active == 0, 1522 * it will never happen. 1523 */ 1524 1525 /* limit parallelism */ 1526 procs = getactivity(req, 1); 1527 if (procs > stats.slavehiwat) 1528 stats.slavehiwat = procs; 1529 if(procs > Maxactive){ 1530 if(traceactivity) 1531 dnslog("[%d] too much activity", getpid()); 1532 putactivity(1); 1533 return; 1534 } 1535 1536 /* 1537 * parent returns to main loop, child does the work. 1538 * don't change note group. 1539 */ 1540 ppid = getpid(); 1541 switch(rfork(RFPROC|RFMEM|RFNOWAIT)){ 1542 case -1: 1543 putactivity(1); 1544 break; 1545 case 0: 1546 procsetname("request slave of pid %d", ppid); 1547 if(traceactivity) 1548 dnslog("[%d] take activity from %d", getpid(), ppid); 1549 req->isslave = 1; /* why not `= getpid()'? */ 1550 break; 1551 default: 1552 /* 1553 * this relies on rfork producing separate, initially-identical 1554 * stacks, thus giving us two copies of `req', one in each 1555 * process. 1556 */ 1557 alarm(0); 1558 longjmp(req->mret, 1); 1559 } 1560 } 1561 1562 /* 1563 * chasing down double free's 1564 */ 1565 void 1566 dncheck(void *p, int dolock) 1567 { 1568 int i; 1569 DN *dp; 1570 RR *rp; 1571 1572 if(p != nil){ 1573 dp = p; 1574 assert(dp->magic == DNmagic); 1575 } 1576 1577 if(!testing) 1578 return; 1579 1580 if(dolock) 1581 lock(&dnlock); 1582 poolcheck(mainmem); 1583 for(i = 0; i < HTLEN; i++) 1584 for(dp = ht[i]; dp; dp = dp->next){ 1585 assert(dp != p); 1586 assert(dp->magic == DNmagic); 1587 for(rp = dp->rr; rp; rp = rp->next){ 1588 assert(rp->magic == RRmagic); 1589 assert(rp->cached); 1590 assert(rp->owner == dp); 1591 /* also check for duplicate rrs */ 1592 if (dolock && rronlist(rp, rp->next)) { 1593 dnslog("%R duplicates its next chain " 1594 "(%R); aborting", rp, rp->next); 1595 abort(); 1596 } 1597 } 1598 } 1599 if(dolock) 1600 unlock(&dnlock); 1601 } 1602 1603 static int 1604 rrequiv(RR *r1, RR *r2) 1605 { 1606 return r1->owner == r2->owner 1607 && r1->type == r2->type 1608 && r1->arg0 == r2->arg0 1609 && r1->arg1 == r2->arg1; 1610 } 1611 1612 /* called with dnlock held */ 1613 void 1614 unique(RR *rp) 1615 { 1616 RR **l, *nrp; 1617 1618 for(; rp; rp = rp->next){ 1619 l = &rp->next; 1620 for(nrp = *l; nrp; nrp = *l) 1621 if(rrequiv(rp, nrp)){ 1622 *l = nrp->next; 1623 rrfree(nrp); 1624 } else 1625 l = &nrp->next; 1626 } 1627 } 1628 1629 /* 1630 * true if second domain is subsumed by the first 1631 */ 1632 int 1633 subsume(char *higher, char *lower) 1634 { 1635 int hn, ln; 1636 1637 ln = strlen(lower); 1638 hn = strlen(higher); 1639 if (ln < hn || cistrcmp(lower + ln - hn, higher) != 0 || 1640 ln > hn && hn != 0 && lower[ln - hn - 1] != '.') 1641 return 0; 1642 return 1; 1643 } 1644 1645 /* 1646 * randomize the order we return items to provide some 1647 * load balancing for servers. 1648 * 1649 * only randomize the first class of entries 1650 */ 1651 RR* 1652 randomize(RR *rp) 1653 { 1654 RR *first, *last, *x, *base; 1655 ulong n; 1656 1657 if(rp == nil || rp->next == nil) 1658 return rp; 1659 1660 /* just randomize addresses, mx's and ns's */ 1661 for(x = rp; x; x = x->next) 1662 if(x->type != Ta && x->type != Taaaa && 1663 x->type != Tmx && x->type != Tns) 1664 return rp; 1665 1666 base = rp; 1667 1668 n = rand(); 1669 last = first = nil; 1670 while(rp != nil){ 1671 /* stop randomizing if we've moved past our class */ 1672 if(base->auth != rp->auth || base->db != rp->db){ 1673 last->next = rp; 1674 break; 1675 } 1676 1677 /* unchain */ 1678 x = rp; 1679 rp = x->next; 1680 x->next = nil; 1681 1682 if(n&1){ 1683 /* add to tail */ 1684 if(last == nil) 1685 first = x; 1686 else 1687 last->next = x; 1688 last = x; 1689 } else { 1690 /* add to head */ 1691 if(last == nil) 1692 last = x; 1693 x->next = first; 1694 first = x; 1695 } 1696 1697 /* reroll the dice */ 1698 n >>= 1; 1699 } 1700 1701 return first; 1702 } 1703 1704 static int 1705 sencodefmt(Fmt *f) 1706 { 1707 int i, len, ilen, rv; 1708 char *out, *buf; 1709 uchar *b; 1710 char obuf[64]; /* rsc optimization */ 1711 1712 if(!(f->flags&FmtPrec) || f->prec < 1) 1713 goto error; 1714 1715 b = va_arg(f->args, uchar*); 1716 if(b == nil) 1717 goto error; 1718 1719 /* if it's a printable, go for it */ 1720 len = f->prec; 1721 for(i = 0; i < len; i++) 1722 if(!isprint(b[i])) 1723 break; 1724 if(i == len){ 1725 if(len >= sizeof obuf) 1726 len = sizeof(obuf)-1; 1727 memmove(obuf, b, len); 1728 obuf[len] = 0; 1729 fmtstrcpy(f, obuf); 1730 return 0; 1731 } 1732 1733 ilen = f->prec; 1734 f->prec = 0; 1735 f->flags &= ~FmtPrec; 1736 switch(f->r){ 1737 case '<': 1738 len = (8*ilen+4)/5 + 3; 1739 break; 1740 case '[': 1741 len = (8*ilen+5)/6 + 4; 1742 break; 1743 case 'H': 1744 len = 2*ilen + 1; 1745 break; 1746 default: 1747 goto error; 1748 } 1749 1750 if(len > sizeof(obuf)){ 1751 buf = malloc(len); 1752 if(buf == nil) 1753 goto error; 1754 } else 1755 buf = obuf; 1756 1757 /* convert */ 1758 out = buf; 1759 switch(f->r){ 1760 case '<': 1761 rv = enc32(out, len, b, ilen); 1762 break; 1763 case '[': 1764 rv = enc64(out, len, b, ilen); 1765 break; 1766 case 'H': 1767 rv = enc16(out, len, b, ilen); 1768 break; 1769 default: 1770 rv = -1; 1771 break; 1772 } 1773 if(rv < 0) 1774 goto error; 1775 1776 fmtstrcpy(f, buf); 1777 if(buf != obuf) 1778 free(buf); 1779 return 0; 1780 1781 error: 1782 return fmtstrcpy(f, "<encodefmt>"); 1783 } 1784 1785 void* 1786 emalloc(int size) 1787 { 1788 char *x; 1789 1790 x = mallocz(size, 1); 1791 if(x == nil) 1792 abort(); 1793 setmalloctag(x, getcallerpc(&size)); 1794 return x; 1795 } 1796 1797 char* 1798 estrdup(char *s) 1799 { 1800 int size; 1801 char *p; 1802 1803 size = strlen(s)+1; 1804 p = mallocz(size, 0); 1805 if(p == nil) 1806 abort(); 1807 memmove(p, s, size); 1808 setmalloctag(p, getcallerpc(&s)); 1809 return p; 1810 } 1811 1812 /* 1813 * create a pointer record 1814 */ 1815 static RR* 1816 mkptr(DN *dp, char *ptr, ulong ttl) 1817 { 1818 DN *ipdp; 1819 RR *rp; 1820 1821 ipdp = dnlookup(ptr, Cin, 1); 1822 1823 rp = rralloc(Tptr); 1824 rp->ptr = dp; 1825 rp->owner = ipdp; 1826 rp->db = 1; 1827 if(ttl) 1828 rp->ttl = ttl; 1829 return rp; 1830 } 1831 1832 void bytes2nibbles(uchar *nibbles, uchar *bytes, int nbytes); 1833 1834 /* 1835 * look for all ip addresses in this network and make 1836 * pointer records for them. 1837 */ 1838 void 1839 dnptr(uchar *net, uchar *mask, char *dom, int forwtype, int subdoms, int ttl) 1840 { 1841 int i, j, len; 1842 char *p, *e; 1843 char ptr[Domlen]; 1844 uchar *ipp; 1845 uchar ip[IPaddrlen], nnet[IPaddrlen]; 1846 uchar nibip[IPaddrlen*2]; 1847 DN *dp; 1848 RR *rp, *nrp, *first, **l; 1849 1850 l = &first; 1851 first = nil; 1852 for(i = 0; i < HTLEN; i++) 1853 for(dp = ht[i]; dp; dp = dp->next) 1854 for(rp = dp->rr; rp; rp = rp->next){ 1855 if(rp->type != forwtype || rp->negative) 1856 continue; 1857 parseip(ip, rp->ip->name); 1858 maskip(ip, mask, nnet); 1859 if(ipcmp(net, nnet) != 0) 1860 continue; 1861 1862 ipp = ip; 1863 len = IPaddrlen; 1864 if (forwtype == Taaaa) { 1865 bytes2nibbles(nibip, ip, IPaddrlen); 1866 ipp = nibip; 1867 len = 2*IPaddrlen; 1868 } 1869 1870 p = ptr; 1871 e = ptr+sizeof(ptr); 1872 for(j = len - 1; j >= len - subdoms; j--) 1873 p = seprint(p, e, (forwtype == Ta? 1874 "%d.": "%x."), ipp[j]); 1875 seprint(p, e, "%s", dom); 1876 1877 nrp = mkptr(dp, ptr, ttl); 1878 *l = nrp; 1879 l = &nrp->next; 1880 } 1881 1882 for(rp = first; rp != nil; rp = nrp){ 1883 nrp = rp->next; 1884 rp->next = nil; 1885 rrattach(rp, Authoritative); 1886 } 1887 } 1888 1889 void 1890 addserver(Server **l, char *name) 1891 { 1892 Server *s; 1893 1894 while(*l) 1895 l = &(*l)->next; 1896 s = malloc(sizeof(Server)+strlen(name)+1); 1897 if(s == nil) 1898 return; 1899 s->name = (char*)(s+1); 1900 strcpy(s->name, name); 1901 s->next = nil; 1902 *l = s; 1903 } 1904 1905 Server* 1906 copyserverlist(Server *s) 1907 { 1908 Server *ns; 1909 1910 for(ns = nil; s != nil; s = s->next) 1911 addserver(&ns, s->name); 1912 return ns; 1913 } 1914 1915 1916 /* from here down is copied to ip/snoopy/dns.c periodically to update it */ 1917 1918 /* 1919 * convert an integer RR type to it's ascii name 1920 */ 1921 char* 1922 rrname(int type, char *buf, int len) 1923 { 1924 char *t; 1925 1926 t = nil; 1927 if(type >= 0 && type <= Tall) 1928 t = rrtname[type]; 1929 if(t==nil){ 1930 snprint(buf, len, "%d", type); 1931 t = buf; 1932 } 1933 return t; 1934 } 1935 1936 /* 1937 * free a list of resource records and any related structs 1938 */ 1939 void 1940 rrfreelist(RR *rp) 1941 { 1942 RR *next; 1943 1944 for(; rp; rp = next){ 1945 next = rp->next; 1946 rrfree(rp); 1947 } 1948 } 1949 1950 void 1951 freeserverlist(Server *s) 1952 { 1953 Server *next; 1954 1955 for(; s != nil; s = next){ 1956 next = s->next; 1957 free(s); 1958 } 1959 } 1960 1961 /* 1962 * allocate a resource record of a given type 1963 */ 1964 RR* 1965 rralloc(int type) 1966 { 1967 RR *rp; 1968 1969 rp = emalloc(sizeof(*rp)); 1970 rp->magic = RRmagic; 1971 rp->pc = getcallerpc(&type); 1972 rp->type = type; 1973 if (rp->type != type) 1974 dnslog("rralloc: bogus type %d", type); 1975 setmalloctag(rp, rp->pc); 1976 switch(type){ 1977 case Tsoa: 1978 rp->soa = emalloc(sizeof(*rp->soa)); 1979 rp->soa->slaves = nil; 1980 setmalloctag(rp->soa, rp->pc); 1981 break; 1982 case Tsrv: 1983 rp->srv = emalloc(sizeof(*rp->srv)); 1984 setmalloctag(rp->srv, rp->pc); 1985 break; 1986 case Tkey: 1987 rp->key = emalloc(sizeof(*rp->key)); 1988 setmalloctag(rp->key, rp->pc); 1989 break; 1990 case Tcert: 1991 rp->cert = emalloc(sizeof(*rp->cert)); 1992 setmalloctag(rp->cert, rp->pc); 1993 break; 1994 case Tsig: 1995 rp->sig = emalloc(sizeof(*rp->sig)); 1996 setmalloctag(rp->sig, rp->pc); 1997 break; 1998 case Tnull: 1999 rp->null = emalloc(sizeof(*rp->null)); 2000 setmalloctag(rp->null, rp->pc); 2001 break; 2002 } 2003 rp->ttl = 0; 2004 rp->expire = 0; 2005 rp->next = 0; 2006 return rp; 2007 } 2008 2009 /* 2010 * free a resource record and any related structs 2011 */ 2012 void 2013 rrfree(RR *rp) 2014 { 2015 DN *dp; 2016 RR *nrp; 2017 Txt *t; 2018 2019 assert(rp->magic == RRmagic); 2020 assert(!rp->cached); 2021 2022 /* our callers often hold dnlock. it's needed to examine dp safely. */ 2023 dp = rp->owner; 2024 if(dp){ 2025 /* if someone else holds dnlock, skip the sanity check. */ 2026 if (canlock(&dnlock)) { 2027 assert(dp->magic == DNmagic); 2028 for(nrp = dp->rr; nrp; nrp = nrp->next) 2029 assert(nrp != rp); /* "rrfree of live rr" */ 2030 unlock(&dnlock); 2031 } 2032 } 2033 2034 switch(rp->type){ 2035 case Tsoa: 2036 freeserverlist(rp->soa->slaves); 2037 memset(rp->soa, 0, sizeof *rp->soa); /* cause trouble */ 2038 free(rp->soa); 2039 break; 2040 case Tsrv: 2041 memset(rp->srv, 0, sizeof *rp->srv); /* cause trouble */ 2042 free(rp->srv); 2043 break; 2044 case Tkey: 2045 free(rp->key->data); 2046 memset(rp->key, 0, sizeof *rp->key); /* cause trouble */ 2047 free(rp->key); 2048 break; 2049 case Tcert: 2050 free(rp->cert->data); 2051 memset(rp->cert, 0, sizeof *rp->cert); /* cause trouble */ 2052 free(rp->cert); 2053 break; 2054 case Tsig: 2055 free(rp->sig->data); 2056 memset(rp->sig, 0, sizeof *rp->sig); /* cause trouble */ 2057 free(rp->sig); 2058 break; 2059 case Tnull: 2060 free(rp->null->data); 2061 memset(rp->null, 0, sizeof *rp->null); /* cause trouble */ 2062 free(rp->null); 2063 break; 2064 case Ttxt: 2065 while(rp->txt != nil){ 2066 t = rp->txt; 2067 rp->txt = t->next; 2068 free(t->p); 2069 memset(t, 0, sizeof *t); /* cause trouble */ 2070 free(t); 2071 } 2072 break; 2073 } 2074 2075 rp->magic = ~rp->magic; 2076 memset(rp, 0, sizeof *rp); /* cause trouble */ 2077 free(rp); 2078 } 2079