xref: /plan9/sys/src/cmd/ndb/dns.h (revision 98813beef1db23409911a4b339e6bb9c03d0a5c0)
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