1 #include <thread.h> /* for Ref */ 2 3 #define NS2MS(ns) ((ns) / 1000000L) 4 #define S2MS(s) ((s) * 1000LL) 5 6 #define timems() NS2MS(nsec()) 7 8 typedef struct Ndbtuple Ndbtuple; 9 10 enum 11 { 12 /* RR types; see: http://www.iana.org/assignments/dns-parameters */ 13 Ta= 1, 14 Tns= 2, 15 Tmd= 3, 16 Tmf= 4, 17 Tcname= 5, 18 Tsoa= 6, 19 Tmb= 7, 20 Tmg= 8, 21 Tmr= 9, 22 Tnull= 10, 23 Twks= 11, 24 Tptr= 12, 25 Thinfo= 13, 26 Tminfo= 14, 27 Tmx= 15, 28 Ttxt= 16, 29 Trp= 17, 30 Tafsdb= 18, 31 Tx25= 19, 32 Tisdn= 20, 33 Trt= 21, 34 Tnsap= 22, 35 Tnsapptr= 23, 36 Tsig= 24, 37 Tkey= 25, 38 Tpx= 26, 39 Tgpos= 27, 40 Taaaa= 28, 41 Tloc= 29, 42 Tnxt= 30, 43 Teid= 31, 44 Tnimloc= 32, 45 Tsrv= 33, 46 Tatma= 34, 47 Tnaptr= 35, 48 Tkx= 36, 49 Tcert= 37, 50 Ta6= 38, 51 Tdname= 39, 52 Tsink= 40, 53 Topt= 41, 54 Tapl= 42, 55 Tds= 43, 56 Tsshfp= 44, 57 Tipseckey= 45, 58 Trrsig= 46, 59 Tnsec= 47, 60 Tdnskey= 48, 61 62 Tspf= 99, 63 Tuinfo= 100, 64 Tuid= 101, 65 Tgid= 102, 66 Tunspec= 103, 67 68 /* query types (all RR types are also queries) */ 69 Ttkey= 249, /* transaction key */ 70 Ttsig= 250, /* transaction signature */ 71 Tixfr= 251, /* incremental zone transfer */ 72 Taxfr= 252, /* zone transfer */ 73 Tmailb= 253, /* { Tmb, Tmg, Tmr } */ 74 Tmaila= 254, /* obsolete */ 75 Tall= 255, /* all records */ 76 77 /* classes */ 78 Csym= 0, /* internal symbols */ 79 Cin= 1, /* internet */ 80 Ccs, /* CSNET (obsolete) */ 81 Cch, /* Chaos net */ 82 Chs, /* Hesiod (?) */ 83 84 /* class queries (all class types are also queries) */ 85 Call= 255, /* all classes */ 86 87 /* opcodes */ 88 Oquery= 0<<11, /* normal query */ 89 Oinverse= 1<<11, /* inverse query (retired) */ 90 Ostatus= 2<<11, /* status request */ 91 Onotify= 4<<11, /* notify slaves of updates */ 92 Oupdate= 5<<11, 93 Omask= 0xf<<11, /* mask for opcode */ 94 95 /* response codes */ 96 Rok= 0, 97 Rformat= 1, /* format error */ 98 Rserver= 2, /* server failure (e.g. no answer from something) */ 99 Rname= 3, /* bad name */ 100 Runimplimented= 4, /* unimplemented */ 101 Rrefused= 5, /* we don't like you */ 102 Ryxdomain= 6, /* name exists when it should not */ 103 Ryxrrset= 7, /* rr set exists when it should not */ 104 Rnxrrset= 8, /* rr set that should exist does not */ 105 Rnotauth= 9, /* not authoritative */ 106 Rnotzone= 10, /* name not in zone */ 107 Rbadvers= 16, /* bad opt version */ 108 /* Rbadsig= 16, */ /* also tsig signature failure */ 109 Rbadkey= 17, /* key not recognized */ 110 Rbadtime= 18, /* signature out of time window */ 111 Rbadmode= 19, /* bad tkey mode */ 112 Rbadname= 20, /* duplicate key name */ 113 Rbadalg= 21, /* algorithm not supported */ 114 Rmask= 0x1f, /* mask for response */ 115 Rtimeout= 1<<5, /* timeout sending (for internal use only) */ 116 117 /* bits in flag word (other than opcode and response) */ 118 Fresp= 1<<15, /* message is a response */ 119 Fauth= 1<<10, /* true if an authoritative response */ 120 Ftrunc= 1<<9, /* truncated message */ 121 Frecurse= 1<<8, /* request recursion */ 122 Fcanrec= 1<<7, /* server can recurse */ 123 124 Domlen= 256, /* max domain name length (with NULL) */ 125 Labellen= 64, /* max domain label length (with NULL) */ 126 Strlen= 256, /* max string length (with NULL) */ 127 128 /* time to live values (in seconds) */ 129 Min= 60, 130 Hour= 60*Min, /* */ 131 Day= 24*Hour, /* Ta, Tmx */ 132 Week= 7*Day, /* Tsoa, Tns */ 133 Year= 52*Week, 134 DEFTTL= Day, 135 136 /* reserved time (can't be timed out earlier) */ 137 Reserved= 5*Min, 138 139 /* tcp & udp port number */ 140 Dnsport= 53, 141 142 /* 143 * payload size. originally, 512 bytes was the upper bound, to 144 * eliminate fragmentation when using udp transport. 145 * with edns (rfc 6891), that has been raised to 4096. 146 * we don't currently generate edns, but we might be sent edns packets. 147 */ 148 Maxdnspayload= 512, 149 Maxpayload= 4096, 150 151 /* length of domain name hash table */ 152 HTLEN= 4*1024, 153 154 Maxpath= 128, /* size of mntpt */ 155 Maxlcks= 10, /* max. query-type locks per domain name */ 156 157 RRmagic= 0xdeadbabe, 158 DNmagic= 0xa110a110, 159 160 /* parallelism: tune; was 32; allow lots */ 161 Maxactive= 250, 162 163 /* tune; was 60*1000; keep it short */ 164 Maxreqtm= 8*1000, /* max. ms to process a request */ 165 166 Notauthoritative = 0, 167 Authoritative, 168 }; 169 170 typedef struct Area Area; 171 typedef struct Block Block; 172 typedef struct Cert Cert; 173 typedef struct DN DN; 174 typedef struct DNSmsg DNSmsg; 175 typedef struct Key Key; 176 typedef struct Null Null; 177 typedef struct RR RR; 178 typedef struct Request Request; 179 typedef struct SOA SOA; 180 typedef struct Server Server; 181 typedef struct Sig Sig; 182 typedef struct Srv Srv; 183 typedef struct Txt Txt; 184 185 /* 186 * a structure to track a request and any slave process handling it 187 */ 188 struct Request 189 { 190 int isslave; /* pid of slave */ 191 uvlong aborttime; /* time in ms at which we give up */ 192 jmp_buf mret; /* where master jumps to after starting a slave */ 193 int id; 194 char *from; /* who asked us? */ 195 }; 196 197 typedef struct Querylck Querylck; 198 struct Querylck 199 { 200 QLock; 201 // Rendez; 202 Ref; 203 }; 204 205 /* 206 * a domain name 207 */ 208 struct DN 209 { 210 DN *next; /* hash collision list */ 211 ulong magic; 212 char *name; /* owner */ 213 RR *rr; /* resource records off this name */ 214 ulong referenced; /* time last referenced */ 215 ulong lookuptime; /* last time we tried to get a better value */ 216 /* refs was `char' but we've seen refs > 120, so go whole hog */ 217 ulong refs; /* for mark and sweep */ 218 ulong ordinal; 219 ushort class; /* RR class */ 220 uchar keep; /* flag: never age this name */ 221 uchar respcode; /* response code */ 222 /* was: char nonexistent; /* true if we get an authoritative nx for this domain */ 223 /* permit only 1 query per (domain name, type) at a time */ 224 Querylck querylck[Maxlcks]; 225 }; 226 227 /* 228 * security info 229 */ 230 struct Block 231 { 232 int dlen; 233 uchar *data; 234 }; 235 struct Key 236 { 237 int flags; 238 int proto; 239 int alg; 240 Block; 241 }; 242 struct Cert 243 { 244 int type; 245 int tag; 246 int alg; 247 Block; 248 }; 249 struct Sig 250 { 251 Cert; 252 int labels; 253 ulong ttl; 254 ulong exp; 255 ulong incep; 256 DN *signer; 257 }; 258 struct Null 259 { 260 Block; 261 }; 262 263 /* 264 * text strings 265 */ 266 struct Txt 267 { 268 Txt *next; 269 char *p; 270 }; 271 272 /* 273 * an unpacked resource record 274 */ 275 struct RR 276 { 277 RR *next; 278 ulong magic; 279 DN *owner; /* domain that owns this resource record */ 280 uintptr pc; /* for tracking memory allocation */ 281 ulong ttl; /* time to live to be passed on */ 282 ulong expire; /* time this entry expires locally */ 283 ulong marker; /* used locally when scanning rrlists */ 284 ushort type; /* RR type */ 285 ushort query; /* query type is in response to */ 286 uchar auth; /* flag: authoritative */ 287 uchar db; /* flag: from database */ 288 uchar cached; /* flag: rr in cache */ 289 uchar negative; /* flag: this is a cached negative response */ 290 291 union { /* discriminated by negative & type */ 292 DN *negsoaowner; /* soa for cached negative response */ 293 DN *host; /* hostname - soa, cname, mb, md, mf, mx, ns, srv */ 294 DN *cpu; /* cpu type - hinfo */ 295 DN *mb; /* mailbox - mg, minfo */ 296 DN *ip; /* ip address - a, aaaa */ 297 DN *rp; /* rp arg - rp */ 298 uintptr arg0; /* arg[01] are compared to find dups in dn.c */ 299 }; 300 union { /* discriminated by negative & type */ 301 int negrcode; /* response code for cached negative resp. */ 302 DN *rmb; /* responsible maibox - minfo, soa, rp */ 303 DN *ptr; /* pointer to domain name - ptr */ 304 DN *os; /* operating system - hinfo */ 305 ulong pref; /* preference value - mx */ 306 ulong local; /* ns served from local database - ns */ 307 ushort port; /* - srv */ 308 uintptr arg1; /* arg[01] are compared to find dups in dn.c */ 309 }; 310 union { /* discriminated by type */ 311 SOA *soa; /* soa timers - soa */ 312 Key *key; 313 Cert *cert; 314 Sig *sig; 315 Null *null; 316 Txt *txt; 317 Srv *srv; 318 }; 319 }; 320 321 /* 322 * list of servers 323 */ 324 struct Server 325 { 326 Server *next; 327 char *name; 328 }; 329 330 /* 331 * timers for a start-of-authority record. all ulongs are in seconds. 332 */ 333 struct SOA 334 { 335 ulong serial; /* zone serial # */ 336 ulong refresh; /* zone refresh interval */ 337 ulong retry; /* zone retry interval */ 338 ulong expire; /* time to expiration */ 339 ulong minttl; /* min. time to live for any entry */ 340 341 Server *slaves; /* slave servers */ 342 }; 343 344 /* 345 * srv (service location) record (rfc2782): 346 * _service._proto.name ttl class(IN) 'SRV' priority weight port target 347 */ 348 struct Srv 349 { 350 ushort pri; 351 ushort weight; 352 }; 353 354 typedef struct Rrlist Rrlist; 355 struct Rrlist 356 { 357 int count; 358 RR *rrs; 359 }; 360 361 /* 362 * domain messages 363 */ 364 struct DNSmsg 365 { 366 ushort id; 367 int flags; 368 int qdcount; /* questions */ 369 RR *qd; 370 int ancount; /* answers */ 371 RR *an; 372 int nscount; /* name servers */ 373 RR *ns; 374 int arcount; /* hints */ 375 RR *ar; 376 }; 377 378 /* 379 * definition of local area for dblookup 380 */ 381 struct Area 382 { 383 Area *next; 384 385 int len; /* strlen(area->soarr->owner->name) */ 386 RR *soarr; /* soa defining this area */ 387 int neednotify; 388 int needrefresh; 389 }; 390 391 typedef struct Cfg Cfg; 392 struct Cfg { 393 int cachedb; 394 int resolver; 395 int justforw; /* flag: pure resolver, just forward queries */ 396 int serve; /* flag: serve udp queries */ 397 int inside; 398 int straddle; 399 }; 400 401 /* (udp) query stats */ 402 typedef struct { 403 QLock; 404 ulong slavehiwat; /* procs */ 405 ulong qrecvd9p; /* query counts */ 406 ulong qrecvdudp; 407 ulong qsent; 408 ulong qrecvd9prpc; /* packet count */ 409 ulong alarms; 410 /* reply times by count */ 411 ulong under10ths[3*10+2]; /* under n*0.1 seconds, n is index */ 412 ulong tmout; 413 ulong tmoutcname; 414 ulong tmoutv6; 415 416 ulong answinmem; /* answers in memory */ 417 ulong negans; /* negative answers received */ 418 ulong negserver; /* neg ans with Rserver set */ 419 ulong negbaddeleg; /* neg ans with bad delegations */ 420 ulong negbdnoans; /* ⋯ and no answers */ 421 ulong negnorname; /* neg ans with no Rname set */ 422 ulong negcached; /* neg ans cached */ 423 } Stats; 424 425 Stats stats; 426 427 enum 428 { 429 Recurse, 430 Dontrecurse, 431 NOneg, 432 OKneg, 433 }; 434 435 extern Cfg cfg; 436 extern char *dbfile; 437 extern int debug; 438 extern Area *delegated; 439 extern char *logfile; 440 extern int maxage; /* age of oldest entry in cache (secs) */ 441 extern char mntpt[]; 442 extern int needrefresh; 443 extern int norecursion; 444 extern ulong now; /* time base */ 445 extern vlong nowns; 446 extern Area *owned; 447 extern int sendnotifies; 448 extern ulong target; 449 extern int testing; /* test cache whenever removing a DN */ 450 extern char *trace; 451 extern int traceactivity; 452 extern char *zonerefreshprogram; 453 454 #pragma varargck type "R" RR* 455 #pragma varargck type "Q" RR* 456 457 458 /* dn.c */ 459 extern char *rrtname[]; 460 extern char *rname[]; 461 extern unsigned nrname; 462 extern char *opname[]; 463 extern Lock dnlock; 464 465 void abort(); /* char*, ... */; 466 void addserver(Server**, char*); 467 Server* copyserverlist(Server*); 468 void db2cache(int); 469 void dnage(DN*); 470 void dnageall(int); 471 void dnagedb(void); 472 void dnageallnever(void); 473 void dnagenever(DN *, int); 474 void dnauthdb(void); 475 void dncheck(void*, int); 476 void dndump(char*); 477 void dnget(void); 478 void dninit(void); 479 DN* dnlookup(char*, int, int); 480 void dnptr(uchar*, uchar*, char*, int, int, int); 481 void dnpurge(void); 482 void dnput(void); 483 void dnslog(char*, ...); 484 void dnstats(char *file); 485 void* emalloc(int); 486 char* estrdup(char*); 487 void freeanswers(DNSmsg *mp); 488 void freeserverlist(Server*); 489 int getactivity(Request*, int); 490 Area* inmyarea(char*); 491 void putactivity(int); 492 RR* randomize(RR*); 493 RR* rralloc(int); 494 void rrattach(RR*, int); 495 int rravfmt(Fmt*); 496 RR* rrcat(RR**, RR*); 497 RR** rrcopy(RR*, RR**); 498 int rrfmt(Fmt*); 499 void rrfree(RR*); 500 void rrfreelist(RR*); 501 RR* rrlookup(DN*, int, int); 502 char* rrname(int, char*, int); 503 RR* rrremneg(RR**); 504 RR* rrremtype(RR**, int); 505 int rrsupported(int); 506 int rrtype(char*); 507 void slave(Request*); 508 int subsume(char*, char*); 509 int tsame(int, int); 510 void unique(RR*); 511 void warning(char*, ...); 512 513 /* dnarea.c */ 514 void refresh_areas(Area*); 515 void freearea(Area**); 516 void addarea(DN *dp, RR *rp, Ndbtuple *t); 517 518 /* dblookup.c */ 519 int baddelegation(RR*, RR*, uchar*); 520 RR* dbinaddr(DN*, int); 521 RR* dblookup(char*, int, int, int, int); 522 void dnforceage(void); 523 RR* dnsservers(int); 524 RR* domainlist(int); 525 int insideaddr(char *dom); 526 int insidens(uchar *ip); 527 int myaddr(char *addr); 528 int opendatabase(void); 529 uchar* outsidens(int); 530 531 /* dns.c */ 532 char* walkup(char*); 533 RR* getdnsservers(int); 534 void logreply(int, uchar*, DNSmsg*); 535 void logsend(int, int, uchar*, char*, char*, int); 536 void procsetname(char *fmt, ...); 537 538 /* dnresolve.c */ 539 RR* dnresolve(char*, int, int, Request*, RR**, int, int, int, int*); 540 int udpport(char *); 541 int mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno); 542 int seerootns(void); 543 void initdnsmsg(DNSmsg *mp, RR *rp, int flags, ushort reqno); 544 DNSmsg* newdnsmsg(RR *rp, int flags, ushort reqno); 545 546 /* dnserver.c */ 547 void dnserver(DNSmsg*, DNSmsg*, Request*, uchar *, int); 548 void dnudpserver(char*); 549 void dntcpserver(char*); 550 551 /* dnnotify.c */ 552 void dnnotify(DNSmsg*, DNSmsg*, Request*); 553 void notifyproc(void); 554 555 /* convDNS2M.c */ 556 int convDNS2M(DNSmsg*, uchar*, int); 557 558 /* convM2DNS.c */ 559 char* convM2DNS(uchar*, int, DNSmsg*, int*); 560 561 #pragma varargck argpos dnslog 1 562