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 /* packet sizes */ 140 Maxudp= 512, /* maximum bytes per udp message sent */ 141 Maxudpin= 2048, /* maximum bytes per udp message rcv'd */ 142 143 /* length of domain name hash table */ 144 HTLEN= 4*1024, 145 146 Maxpath= 128, /* size of mntpt */ 147 Maxlcks= 10, /* max. query-type locks per domain name */ 148 149 RRmagic= 0xdeadbabe, 150 DNmagic= 0xa110a110, 151 152 /* parallelism: tune; was 32; allow lots */ 153 Maxactive= 250, 154 155 /* tune; was 60*1000; keep it short */ 156 Maxreqtm= 8*1000, /* max. ms to process a request */ 157 158 Notauthoritative = 0, 159 Authoritative, 160 }; 161 162 typedef struct Area Area; 163 typedef struct Block Block; 164 typedef struct Cert Cert; 165 typedef struct DN DN; 166 typedef struct DNSmsg DNSmsg; 167 typedef struct Key Key; 168 typedef struct Null Null; 169 typedef struct RR RR; 170 typedef struct Request Request; 171 typedef struct SOA SOA; 172 typedef struct Server Server; 173 typedef struct Sig Sig; 174 typedef struct Srv Srv; 175 typedef struct Txt Txt; 176 177 /* 178 * a structure to track a request and any slave process handling it 179 */ 180 struct Request 181 { 182 int isslave; /* pid of slave */ 183 uvlong aborttime; /* time in ms at which we give up */ 184 jmp_buf mret; /* where master jumps to after starting a slave */ 185 int id; 186 char *from; /* who asked us? */ 187 }; 188 189 typedef struct Querylck Querylck; 190 struct Querylck 191 { 192 QLock; 193 // Rendez; 194 Ref; 195 }; 196 197 /* 198 * a domain name 199 */ 200 struct DN 201 { 202 DN *next; /* hash collision list */ 203 ulong magic; 204 char *name; /* owner */ 205 RR *rr; /* resource records off this name */ 206 ulong referenced; /* time last referenced */ 207 ulong lookuptime; /* last time we tried to get a better value */ 208 /* refs was `char' but we've seen refs > 120, so go whole hog */ 209 ulong refs; /* for mark and sweep */ 210 ulong ordinal; 211 ushort class; /* RR class */ 212 uchar keep; /* flag: never age this name */ 213 uchar respcode; /* response code */ 214 /* was: char nonexistent; /* true if we get an authoritative nx for this domain */ 215 /* permit only 1 query per (domain name, type) at a time */ 216 Querylck querylck[Maxlcks]; 217 }; 218 219 /* 220 * security info 221 */ 222 struct Block 223 { 224 int dlen; 225 uchar *data; 226 }; 227 struct Key 228 { 229 int flags; 230 int proto; 231 int alg; 232 Block; 233 }; 234 struct Cert 235 { 236 int type; 237 int tag; 238 int alg; 239 Block; 240 }; 241 struct Sig 242 { 243 Cert; 244 int labels; 245 ulong ttl; 246 ulong exp; 247 ulong incep; 248 DN *signer; 249 }; 250 struct Null 251 { 252 Block; 253 }; 254 255 /* 256 * text strings 257 */ 258 struct Txt 259 { 260 Txt *next; 261 char *p; 262 }; 263 264 /* 265 * an unpacked resource record 266 */ 267 struct RR 268 { 269 RR *next; 270 ulong magic; 271 DN *owner; /* domain that owns this resource record */ 272 uintptr pc; /* for tracking memory allocation */ 273 ulong ttl; /* time to live to be passed on */ 274 ulong expire; /* time this entry expires locally */ 275 ulong marker; /* used locally when scanning rrlists */ 276 ushort type; /* RR type */ 277 ushort query; /* query type is in response to */ 278 uchar auth; /* flag: authoritative */ 279 uchar db; /* flag: from database */ 280 uchar cached; /* flag: rr in cache */ 281 uchar negative; /* flag: this is a cached negative response */ 282 283 union { /* discriminated by negative & type */ 284 DN *negsoaowner; /* soa for cached negative response */ 285 DN *host; /* hostname - soa, cname, mb, md, mf, mx, ns, srv */ 286 DN *cpu; /* cpu type - hinfo */ 287 DN *mb; /* mailbox - mg, minfo */ 288 DN *ip; /* ip address - a, aaaa */ 289 DN *rp; /* rp arg - rp */ 290 uintptr arg0; /* arg[01] are compared to find dups in dn.c */ 291 }; 292 union { /* discriminated by negative & type */ 293 int negrcode; /* response code for cached negative resp. */ 294 DN *rmb; /* responsible maibox - minfo, soa, rp */ 295 DN *ptr; /* pointer to domain name - ptr */ 296 DN *os; /* operating system - hinfo */ 297 ulong pref; /* preference value - mx */ 298 ulong local; /* ns served from local database - ns */ 299 ushort port; /* - srv */ 300 uintptr arg1; /* arg[01] are compared to find dups in dn.c */ 301 }; 302 union { /* discriminated by type */ 303 SOA *soa; /* soa timers - soa */ 304 Key *key; 305 Cert *cert; 306 Sig *sig; 307 Null *null; 308 Txt *txt; 309 Srv *srv; 310 }; 311 }; 312 313 /* 314 * list of servers 315 */ 316 struct Server 317 { 318 Server *next; 319 char *name; 320 }; 321 322 /* 323 * timers for a start-of-authority record. all ulongs are in seconds. 324 */ 325 struct SOA 326 { 327 ulong serial; /* zone serial # */ 328 ulong refresh; /* zone refresh interval */ 329 ulong retry; /* zone retry interval */ 330 ulong expire; /* time to expiration */ 331 ulong minttl; /* min. time to live for any entry */ 332 333 Server *slaves; /* slave servers */ 334 }; 335 336 /* 337 * srv (service location) record (rfc2782): 338 * _service._proto.name ttl class(IN) 'SRV' priority weight port target 339 */ 340 struct Srv 341 { 342 ushort pri; 343 ushort weight; 344 }; 345 346 typedef struct Rrlist Rrlist; 347 struct Rrlist 348 { 349 int count; 350 RR *rrs; 351 }; 352 353 /* 354 * domain messages 355 */ 356 struct DNSmsg 357 { 358 ushort id; 359 int flags; 360 int qdcount; /* questions */ 361 RR *qd; 362 int ancount; /* answers */ 363 RR *an; 364 int nscount; /* name servers */ 365 RR *ns; 366 int arcount; /* hints */ 367 RR *ar; 368 }; 369 370 /* 371 * definition of local area for dblookup 372 */ 373 struct Area 374 { 375 Area *next; 376 377 int len; /* strlen(area->soarr->owner->name) */ 378 RR *soarr; /* soa defining this area */ 379 int neednotify; 380 int needrefresh; 381 }; 382 383 typedef struct Cfg Cfg; 384 struct Cfg { 385 int cachedb; 386 int resolver; 387 int justforw; /* flag: pure resolver, just forward queries */ 388 int serve; /* flag: serve udp queries */ 389 int inside; 390 int straddle; 391 }; 392 393 /* (udp) query stats */ 394 typedef struct { 395 QLock; 396 ulong slavehiwat; /* procs */ 397 ulong qrecvd9p; /* query counts */ 398 ulong qrecvdudp; 399 ulong qsent; 400 ulong qrecvd9prpc; /* packet count */ 401 ulong alarms; 402 /* reply times by count */ 403 ulong under10ths[3*10+2]; /* under n*0.1 seconds, n is index */ 404 ulong tmout; 405 ulong tmoutcname; 406 ulong tmoutv6; 407 408 ulong answinmem; /* answers in memory */ 409 ulong negans; /* negative answers received */ 410 ulong negserver; /* neg ans with Rserver set */ 411 ulong negbaddeleg; /* neg ans with bad delegations */ 412 ulong negbdnoans; /* ⋯ and no answers */ 413 ulong negnorname; /* neg ans with no Rname set */ 414 ulong negcached; /* neg ans cached */ 415 } Stats; 416 417 Stats stats; 418 419 enum 420 { 421 Recurse, 422 Dontrecurse, 423 NOneg, 424 OKneg, 425 }; 426 427 extern Cfg cfg; 428 extern char *dbfile; 429 extern int debug; 430 extern Area *delegated; 431 extern char *logfile; 432 extern int maxage; /* age of oldest entry in cache (secs) */ 433 extern char mntpt[]; 434 extern int needrefresh; 435 extern int norecursion; 436 extern ulong now; /* time base */ 437 extern vlong nowns; 438 extern Area *owned; 439 extern int sendnotifies; 440 extern ulong target; 441 extern int testing; /* test cache whenever removing a DN */ 442 extern char *trace; 443 extern int traceactivity; 444 extern char *zonerefreshprogram; 445 446 #pragma varargck type "R" RR* 447 #pragma varargck type "Q" RR* 448 449 450 /* dn.c */ 451 extern char *rrtname[]; 452 extern char *rname[]; 453 extern unsigned nrname; 454 extern char *opname[]; 455 extern Lock dnlock; 456 457 void abort(); /* char*, ... */; 458 void addserver(Server**, char*); 459 Server* copyserverlist(Server*); 460 void db2cache(int); 461 void dnage(DN*); 462 void dnageall(int); 463 void dnagedb(void); 464 void dnageallnever(void); 465 void dnagenever(DN *, int); 466 void dnauthdb(void); 467 void dncheck(void*, int); 468 void dndump(char*); 469 void dnget(void); 470 void dninit(void); 471 DN* dnlookup(char*, int, int); 472 void dnptr(uchar*, uchar*, char*, int, int, int); 473 void dnpurge(void); 474 void dnput(void); 475 void dnslog(char*, ...); 476 void dnstats(char *file); 477 void* emalloc(int); 478 char* estrdup(char*); 479 void freeanswers(DNSmsg *mp); 480 void freeserverlist(Server*); 481 int getactivity(Request*, int); 482 Area* inmyarea(char*); 483 void putactivity(int); 484 RR* randomize(RR*); 485 RR* rralloc(int); 486 void rrattach(RR*, int); 487 int rravfmt(Fmt*); 488 RR* rrcat(RR**, RR*); 489 RR** rrcopy(RR*, RR**); 490 int rrfmt(Fmt*); 491 void rrfree(RR*); 492 void rrfreelist(RR*); 493 RR* rrlookup(DN*, int, int); 494 char* rrname(int, char*, int); 495 RR* rrremneg(RR**); 496 RR* rrremtype(RR**, int); 497 int rrsupported(int); 498 int rrtype(char*); 499 void slave(Request*); 500 int subsume(char*, char*); 501 int tsame(int, int); 502 void unique(RR*); 503 void warning(char*, ...); 504 505 /* dnarea.c */ 506 void refresh_areas(Area*); 507 void freearea(Area**); 508 void addarea(DN *dp, RR *rp, Ndbtuple *t); 509 510 /* dblookup.c */ 511 int baddelegation(RR*, RR*, uchar*); 512 RR* dbinaddr(DN*, int); 513 RR* dblookup(char*, int, int, int, int); 514 void dnforceage(void); 515 RR* dnsservers(int); 516 RR* domainlist(int); 517 int insideaddr(char *dom); 518 int insidens(uchar *ip); 519 int myaddr(char *addr); 520 int opendatabase(void); 521 uchar* outsidens(int); 522 523 /* dns.c */ 524 char* walkup(char*); 525 RR* getdnsservers(int); 526 void logreply(int, uchar*, DNSmsg*); 527 void logsend(int, int, uchar*, char*, char*, int); 528 void procsetname(char *fmt, ...); 529 530 /* dnresolve.c */ 531 RR* dnresolve(char*, int, int, Request*, RR**, int, int, int, int*); 532 int udpport(char *); 533 int mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno); 534 int seerootns(void); 535 void initdnsmsg(DNSmsg *mp, RR *rp, int flags, ushort reqno); 536 DNSmsg* newdnsmsg(RR *rp, int flags, ushort reqno); 537 538 /* dnserver.c */ 539 void dnserver(DNSmsg*, DNSmsg*, Request*, uchar *, int); 540 void dnudpserver(char*); 541 void dntcpserver(char*); 542 543 /* dnnotify.c */ 544 void dnnotify(DNSmsg*, DNSmsg*, Request*); 545 void notifyproc(void); 546 547 /* convDNS2M.c */ 548 int convDNS2M(DNSmsg*, uchar*, int); 549 550 /* convM2DNS.c */ 551 char* convM2DNS(uchar*, int, DNSmsg*, int*); 552 553 #pragma varargck argpos dnslog 1 554