1 #include <thread.h> /* for Ref */
3 #define NS2MS(ns) ((ns) / 1000000L)
4 #define S2MS(s) ((s) * 1000LL)
6 #define timems() NS2MS(nsec())
8 typedef struct Ndbtuple Ndbtuple;
12 /* RR types; see: http://www.iana.org/assignments/dns-parameters */
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 */
78 Csym= 0, /* internal symbols */
79 Cin= 1, /* internet */
80 Ccs, /* CSNET (obsolete) */
84 /* class queries (all class types are also queries) */
85 Call= 255, /* all classes */
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 */
93 Omask= 0xf<<11, /* mask for opcode */
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) */
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 */
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) */
128 /* time to live values (in seconds) */
131 Day= 24*Hour, /* Ta, Tmx */
132 Week= 7*Day, /* Tsoa, Tns */
136 /* reserved time (can't be timed out earlier) */
140 Maxudp= 512, /* maximum bytes per udp message sent */
141 Maxudpin= 2048, /* maximum bytes per udp message rcv'd */
143 /* length of domain name hash table */
146 Maxpath= 128, /* size of mntpt */
147 Maxlcks= 10, /* max. query-type locks per domain name */
152 /* parallelism: tune; was 32; allow lots */
155 /* tune; was 60*1000; keep it short */
156 Maxreqtm= 8*1000, /* max. ms to process a request */
158 Notauthoritative = 0,
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;
178 * a structure to track a request and any slave process handling it
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 */
186 char *from; /* who asked us? */
189 typedef struct Querylck Querylck;
202 DN *next; /* hash collision list */
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 */
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];
265 * an unpacked resource record
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 */
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 */
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 */
302 union { /* discriminated by type */
303 SOA *soa; /* soa timers - soa */
323 * timers for a start-of-authority record. all ulongs are in seconds.
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 */
333 Server *slaves; /* slave servers */
337 * srv (service location) record (rfc2782):
338 * _service._proto.name ttl class(IN) 'SRV' priority weight port target
346 typedef struct Rrlist Rrlist;
360 int qdcount; /* questions */
362 int ancount; /* answers */
364 int nscount; /* name servers */
366 int arcount; /* hints */
371 * definition of local area for dblookup
377 int len; /* strlen(area->soarr->owner->name) */
378 RR *soarr; /* soa defining this area */
383 typedef struct Cfg Cfg;
387 int justforw; /* flag: pure resolver, just forward queries */
388 int serve; /* flag: serve udp queries */
393 /* (udp) query stats */
396 ulong slavehiwat; /* procs */
397 ulong qrecvd9p; /* query counts */
400 ulong qrecvd9prpc; /* packet count */
402 /* reply times by count */
403 ulong under10ths[3*10+2]; /* under n*0.1 seconds, n is index */
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 */
430 extern Area *delegated;
431 extern char *logfile;
432 extern int maxage; /* age of oldest entry in cache (secs) */
434 extern int needrefresh;
435 extern int norecursion;
436 extern ulong now; /* time base */
439 extern int sendnotifies;
441 extern int testing; /* test cache whenever removing a DN */
443 extern int traceactivity;
444 extern char *zonerefreshprogram;
446 #pragma varargck type "R" RR*
447 #pragma varargck type "Q" RR*
451 extern char *rrtname[];
452 extern char *rname[];
453 extern unsigned nrname;
454 extern char *opname[];
457 void abort(); /* char*, ... */;
458 void addserver(Server**, char*);
459 Server* copyserverlist(Server*);
464 void dnageallnever(void);
465 void dnagenever(DN *, int);
467 void dncheck(void*, int);
471 DN* dnlookup(char*, int, int);
472 void dnptr(uchar*, uchar*, char*, int, int, int);
475 void dnslog(char*, ...);
476 void dnstats(char *file);
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);
486 void rrattach(RR*, int);
488 RR* rrcat(RR**, RR*);
489 RR** rrcopy(RR*, RR**);
492 void rrfreelist(RR*);
493 RR* rrlookup(DN*, int, int);
494 char* rrname(int, char*, int);
496 RR* rrremtype(RR**, int);
497 int rrsupported(int);
499 void slave(Request*);
500 int subsume(char*, char*);
503 void warning(char*, ...);
506 void refresh_areas(Area*);
507 void freearea(Area**);
508 void addarea(DN *dp, RR *rp, Ndbtuple *t);
511 int baddelegation(RR*, RR*, uchar*);
512 RR* dbinaddr(DN*, int);
513 RR* dblookup(char*, int, int, int, int);
514 void dnforceage(void);
517 int insideaddr(char *dom);
518 int insidens(uchar *ip);
519 int myaddr(char *addr);
520 int opendatabase(void);
521 uchar* outsidens(int);
525 RR* getdnsservers(int);
526 void logreply(int, uchar*, DNSmsg*);
527 void logsend(int, int, uchar*, char*, char*, int);
528 void procsetname(char *fmt, ...);
531 RR* dnresolve(char*, int, int, Request*, RR**, int, int, int, int*);
533 int mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno);
535 void initdnsmsg(DNSmsg *mp, RR *rp, int flags, ushort reqno);
538 void dnserver(DNSmsg*, DNSmsg*, Request*, uchar *, int);
539 void dnudpserver(char*);
540 void dntcpserver(char*);
543 void dnnotify(DNSmsg*, DNSmsg*, Request*);
544 void notifyproc(void);
547 int convDNS2M(DNSmsg*, uchar*, int);
550 char* convM2DNS(uchar*, int, DNSmsg*, int*);
552 #pragma varargck argpos dnslog 1