xref: /plan9/sys/src/cmd/ndb/dns.h (revision 98813beef1db23409911a4b339e6bb9c03d0a5c0)
1225077b0SDavid du Colombier #include <thread.h>		/* for Ref */
2225077b0SDavid du Colombier 
3e02f7f02SDavid du Colombier #define NS2MS(ns) ((ns) / 1000000L)
4e02f7f02SDavid du Colombier #define S2MS(s)   ((s)  * 1000LL)
5e02f7f02SDavid du Colombier 
6e02f7f02SDavid du Colombier #define timems()	NS2MS(nsec())
7e02f7f02SDavid du Colombier 
87dd7cddfSDavid du Colombier typedef struct Ndbtuple Ndbtuple;
97dd7cddfSDavid du Colombier 
103e12c5d1SDavid du Colombier enum
113e12c5d1SDavid du Colombier {
12ab3dc52fSDavid du Colombier 	/* RR types; see: http://www.iana.org/assignments/dns-parameters */
133e12c5d1SDavid du Colombier 	Ta=		1,
143e12c5d1SDavid du Colombier 	Tns=		2,
153e12c5d1SDavid du Colombier 	Tmd=		3,
163e12c5d1SDavid du Colombier 	Tmf=		4,
173e12c5d1SDavid du Colombier 	Tcname=		5,
183e12c5d1SDavid du Colombier 	Tsoa=		6,
193e12c5d1SDavid du Colombier 	Tmb=		7,
203e12c5d1SDavid du Colombier 	Tmg=		8,
213e12c5d1SDavid du Colombier 	Tmr=		9,
223e12c5d1SDavid du Colombier 	Tnull=		10,
233e12c5d1SDavid du Colombier 	Twks=		11,
243e12c5d1SDavid du Colombier 	Tptr=		12,
253e12c5d1SDavid du Colombier 	Thinfo=		13,
263e12c5d1SDavid du Colombier 	Tminfo=		14,
273e12c5d1SDavid du Colombier 	Tmx=		15,
283e12c5d1SDavid du Colombier 	Ttxt=		16,
297dd7cddfSDavid du Colombier 	Trp=		17,
30ab3dc52fSDavid du Colombier 	Tafsdb=		18,
31ab3dc52fSDavid du Colombier 	Tx25=		19,
32ab3dc52fSDavid du Colombier 	Tisdn=		20,
33ab3dc52fSDavid du Colombier 	Trt=		21,
34ab3dc52fSDavid du Colombier 	Tnsap=		22,
35ab3dc52fSDavid du Colombier 	Tnsapptr=	23,
367dd7cddfSDavid du Colombier 	Tsig=		24,
377dd7cddfSDavid du Colombier 	Tkey=		25,
38ab3dc52fSDavid du Colombier 	Tpx=		26,
39ab3dc52fSDavid du Colombier 	Tgpos=		27,
405d459b5aSDavid du Colombier 	Taaaa=		28,
41ab3dc52fSDavid du Colombier 	Tloc=		29,
42ab3dc52fSDavid du Colombier 	Tnxt=		30,
43ab3dc52fSDavid du Colombier 	Teid=		31,
44ab3dc52fSDavid du Colombier 	Tnimloc=	32,
45ab3dc52fSDavid du Colombier 	Tsrv=		33,
46ab3dc52fSDavid du Colombier 	Tatma=		34,
47ab3dc52fSDavid du Colombier 	Tnaptr=		35,
48ab3dc52fSDavid du Colombier 	Tkx=		36,
497dd7cddfSDavid du Colombier 	Tcert=		37,
50ab3dc52fSDavid du Colombier 	Ta6=		38,
51ab3dc52fSDavid du Colombier 	Tdname=		39,
52ab3dc52fSDavid du Colombier 	Tsink=		40,
53ab3dc52fSDavid du Colombier 	Topt=		41,
54ab3dc52fSDavid du Colombier 	Tapl=		42,
55ab3dc52fSDavid du Colombier 	Tds=		43,
56ab3dc52fSDavid du Colombier 	Tsshfp=		44,
57ab3dc52fSDavid du Colombier 	Tipseckey=	45,
58ab3dc52fSDavid du Colombier 	Trrsig=		46,
59ab3dc52fSDavid du Colombier 	Tnsec=		47,
60ab3dc52fSDavid du Colombier 	Tdnskey=	48,
61ab3dc52fSDavid du Colombier 
62ab3dc52fSDavid du Colombier 	Tspf=		99,
63ab3dc52fSDavid du Colombier 	Tuinfo=		100,
64ab3dc52fSDavid du Colombier 	Tuid=		101,
65ab3dc52fSDavid du Colombier 	Tgid=		102,
66ab3dc52fSDavid du Colombier 	Tunspec=	103,
673e12c5d1SDavid du Colombier 
683e12c5d1SDavid du Colombier 	/* query types (all RR types are also queries) */
69ab3dc52fSDavid du Colombier 	Ttkey=	249,	/* transaction key */
70ab3dc52fSDavid du Colombier 	Ttsig=	250,	/* transaction signature */
717dd7cddfSDavid du Colombier 	Tixfr=	251,	/* incremental zone transfer */
723e12c5d1SDavid du Colombier 	Taxfr=	252,	/* zone transfer */
733e12c5d1SDavid du Colombier 	Tmailb=	253,	/* { Tmb, Tmg, Tmr } */
74ab3dc52fSDavid du Colombier 	Tmaila= 254,	/* obsolete */
753e12c5d1SDavid du Colombier 	Tall=	255,	/* all records */
763e12c5d1SDavid du Colombier 
773e12c5d1SDavid du Colombier 	/* classes */
783e12c5d1SDavid du Colombier 	Csym=	0,	/* internal symbols */
793e12c5d1SDavid du Colombier 	Cin=	1,	/* internet */
803e12c5d1SDavid du Colombier 	Ccs,		/* CSNET (obsolete) */
813e12c5d1SDavid du Colombier 	Cch,		/* Chaos net */
823e12c5d1SDavid du Colombier 	Chs,		/* Hesiod (?) */
833e12c5d1SDavid du Colombier 
843e12c5d1SDavid du Colombier 	/* class queries (all class types are also queries) */
853e12c5d1SDavid du Colombier 	Call=	255,	/* all classes */
863e12c5d1SDavid du Colombier 
873e12c5d1SDavid du Colombier 	/* opcodes */
883e12c5d1SDavid du Colombier 	Oquery=		0<<11,		/* normal query */
89ab3dc52fSDavid du Colombier 	Oinverse=	1<<11,		/* inverse query (retired) */
903e12c5d1SDavid du Colombier 	Ostatus=	2<<11,		/* status request */
91dc5a79c1SDavid du Colombier 	Onotify=	4<<11,		/* notify slaves of updates */
92ab3dc52fSDavid du Colombier 	Oupdate=	5<<11,
933e12c5d1SDavid du Colombier 	Omask=		0xf<<11,	/* mask for opcode */
943e12c5d1SDavid du Colombier 
953e12c5d1SDavid du Colombier 	/* response codes */
963e12c5d1SDavid du Colombier 	Rok=		0,
973e12c5d1SDavid du Colombier 	Rformat=	1,	/* format error */
987dd7cddfSDavid du Colombier 	Rserver=	2,	/* server failure (e.g. no answer from something) */
993e12c5d1SDavid du Colombier 	Rname=		3,	/* bad name */
1003e12c5d1SDavid du Colombier 	Runimplimented=	4,	/* unimplemented */
1013e12c5d1SDavid du Colombier 	Rrefused=	5,	/* we don't like you */
102ab3dc52fSDavid du Colombier 	Ryxdomain=	6,	/* name exists when it should not */
103ab3dc52fSDavid du Colombier 	Ryxrrset=	7,	/* rr set exists when it should not */
104ab3dc52fSDavid du Colombier 	Rnxrrset=	8,	/* rr set that should exist does not */
105ab3dc52fSDavid du Colombier 	Rnotauth=	9,	/* not authoritative */
106ab3dc52fSDavid du Colombier 	Rnotzone=	10,	/* name not in zone */
107ab3dc52fSDavid du Colombier 	Rbadvers=	16,	/* bad opt version */
108ab3dc52fSDavid du Colombier /*	Rbadsig=	16, */	/* also tsig signature failure */
109ab3dc52fSDavid du Colombier 	Rbadkey=	17,		/* key not recognized */
110ab3dc52fSDavid du Colombier 	Rbadtime=	18,		/* signature out of time window */
111ab3dc52fSDavid du Colombier 	Rbadmode=	19,		/* bad tkey mode */
112ab3dc52fSDavid du Colombier 	Rbadname=	20,		/* duplicate key name */
113ab3dc52fSDavid du Colombier 	Rbadalg=	21,		/* algorithm not supported */
114ab3dc52fSDavid du Colombier 	Rmask=		0x1f,	/* mask for response */
1154f8f669cSDavid du Colombier 	Rtimeout=	1<<5,	/* timeout sending (for internal use only) */
1163e12c5d1SDavid du Colombier 
1173e12c5d1SDavid du Colombier 	/* bits in flag word (other than opcode and response) */
1183e12c5d1SDavid du Colombier 	Fresp=		1<<15,	/* message is a response */
1193e12c5d1SDavid du Colombier 	Fauth=		1<<10,	/* true if an authoritative response */
1203e12c5d1SDavid du Colombier 	Ftrunc=		1<<9,	/* truncated message */
1213e12c5d1SDavid du Colombier 	Frecurse=	1<<8,	/* request recursion */
1223e12c5d1SDavid du Colombier 	Fcanrec=	1<<7,	/* server can recurse */
1233e12c5d1SDavid du Colombier 
1243e12c5d1SDavid du Colombier 	Domlen=		256,	/* max domain name length (with NULL) */
12576783259SDavid du Colombier 	Labellen=	64,	/* max domain label length (with NULL) */
1263e12c5d1SDavid du Colombier 	Strlen=		256,	/* max string length (with NULL) */
1273e12c5d1SDavid du Colombier 
1287dd7cddfSDavid du Colombier 	/* time to live values (in seconds) */
1293e12c5d1SDavid du Colombier 	Min=		60,
1303e12c5d1SDavid du Colombier 	Hour=		60*Min,		/* */
1313e12c5d1SDavid du Colombier 	Day=		24*Hour,	/* Ta, Tmx */
1323e12c5d1SDavid du Colombier 	Week=		7*Day,		/* Tsoa, Tns */
1337dd7cddfSDavid du Colombier 	Year=		52*Week,
1347dd7cddfSDavid du Colombier 	DEFTTL=		Day,
1357dd7cddfSDavid du Colombier 
1367dd7cddfSDavid du Colombier 	/* reserved time (can't be timed out earlier) */
1377dd7cddfSDavid du Colombier 	Reserved=	5*Min,
1383e12c5d1SDavid du Colombier 
139*98813beeSDavid du Colombier 	/* tcp & udp port number */
140*98813beeSDavid du Colombier 	Dnsport=	53,
141*98813beeSDavid du Colombier 
142*98813beeSDavid du Colombier 	/*
143*98813beeSDavid du Colombier 	 * payload size.  originally, 512 bytes was the upper bound, to
144*98813beeSDavid du Colombier 	 * eliminate fragmentation when using udp transport.
145*98813beeSDavid du Colombier 	 * with edns (rfc 6891), that has been raised to 4096.
146*98813beeSDavid du Colombier 	 * we don't currently generate edns, but we might be sent edns packets.
147*98813beeSDavid du Colombier 	 */
148*98813beeSDavid du Colombier 	Maxdnspayload=	512,
149*98813beeSDavid du Colombier 	Maxpayload=	4096,
1507dd7cddfSDavid du Colombier 
1517dd7cddfSDavid du Colombier 	/* length of domain name hash table */
1527dd7cddfSDavid du Colombier 	HTLEN= 		4*1024,
1537dd7cddfSDavid du Colombier 
1544f8f669cSDavid du Colombier 	Maxpath=	128,	/* size of mntpt */
155f46c709fSDavid du Colombier 	Maxlcks=	10,	/* max. query-type locks per domain name */
1564f8f669cSDavid du Colombier 
1577dd7cddfSDavid du Colombier 	RRmagic=	0xdeadbabe,
1587dd7cddfSDavid du Colombier 	DNmagic=	0xa110a110,
1597dd7cddfSDavid du Colombier 
1605d34ce99SDavid du Colombier 	/* parallelism: tune; was 32; allow lots */
1615d34ce99SDavid du Colombier 	Maxactive=	250,
1624f8f669cSDavid du Colombier 
163e02f7f02SDavid du Colombier 	/* tune; was 60*1000; keep it short */
164e02f7f02SDavid du Colombier 	Maxreqtm=	8*1000,	/* max. ms to process a request */
1656dc4800dSDavid du Colombier 
1666dc4800dSDavid du Colombier 	Notauthoritative = 0,
1676dc4800dSDavid du Colombier 	Authoritative,
1683e12c5d1SDavid du Colombier };
1693e12c5d1SDavid du Colombier 
1704f8f669cSDavid du Colombier typedef struct Area	Area;
1714f8f669cSDavid du Colombier typedef struct Block	Block;
1724f8f669cSDavid du Colombier typedef struct Cert	Cert;
1733e12c5d1SDavid du Colombier typedef struct DN	DN;
1743e12c5d1SDavid du Colombier typedef struct DNSmsg	DNSmsg;
1756b0d5c8bSDavid du Colombier typedef struct Key	Key;
1766b0d5c8bSDavid du Colombier typedef struct Null	Null;
1774f8f669cSDavid du Colombier typedef struct RR	RR;
1784f8f669cSDavid du Colombier typedef struct Request	Request;
1794f8f669cSDavid du Colombier typedef struct SOA	SOA;
1806b0d5c8bSDavid du Colombier typedef struct Server	Server;
1814f8f669cSDavid du Colombier typedef struct Sig	Sig;
1824f8f669cSDavid du Colombier typedef struct Srv	Srv;
18360845620SDavid du Colombier typedef struct Txt	Txt;
1843e12c5d1SDavid du Colombier 
1853e12c5d1SDavid du Colombier /*
1863e12c5d1SDavid du Colombier  *  a structure to track a request and any slave process handling it
1873e12c5d1SDavid du Colombier  */
1883e12c5d1SDavid du Colombier struct Request
1893e12c5d1SDavid du Colombier {
1903e12c5d1SDavid du Colombier 	int	isslave;	/* pid of slave */
191e02f7f02SDavid du Colombier 	uvlong	aborttime;	/* time in ms at which we give up */
1923e12c5d1SDavid du Colombier 	jmp_buf	mret;		/* where master jumps to after starting a slave */
1937dd7cddfSDavid du Colombier 	int	id;
194f46c709fSDavid du Colombier 	char	*from;		/* who asked us? */
1953e12c5d1SDavid du Colombier };
1963e12c5d1SDavid du Colombier 
197225077b0SDavid du Colombier typedef struct Querylck Querylck;
198225077b0SDavid du Colombier struct Querylck
199225077b0SDavid du Colombier {
200225077b0SDavid du Colombier 	QLock;
201225077b0SDavid du Colombier //	Rendez;
202225077b0SDavid du Colombier 	Ref;
203225077b0SDavid du Colombier };
204225077b0SDavid du Colombier 
2053e12c5d1SDavid du Colombier /*
2063e12c5d1SDavid du Colombier  *  a domain name
2073e12c5d1SDavid du Colombier  */
2083e12c5d1SDavid du Colombier struct DN
2093e12c5d1SDavid du Colombier {
2103e12c5d1SDavid du Colombier 	DN	*next;		/* hash collision list */
21134f77ae3SDavid du Colombier 	ulong	magic;
2123e12c5d1SDavid du Colombier 	char	*name;		/* owner */
2133e12c5d1SDavid du Colombier 	RR	*rr;		/* resource records off this name */
2147dd7cddfSDavid du Colombier 	ulong	referenced;	/* time last referenced */
2157dd7cddfSDavid du Colombier 	ulong	lookuptime;	/* last time we tried to get a better value */
216d3907fe5SDavid du Colombier 	/* refs was `char' but we've seen refs > 120, so go whole hog */
217d3907fe5SDavid du Colombier 	ulong	refs;		/* for mark and sweep */
2185d34ce99SDavid du Colombier 	ulong	ordinal;
2197dd7cddfSDavid du Colombier 	ushort	class;		/* RR class */
2205d34ce99SDavid du Colombier 	uchar	keep;		/* flag: never age this name */
2214f8f669cSDavid du Colombier 	uchar	respcode;	/* response code */
2224f8f669cSDavid du Colombier /* was:	char	nonexistent; /* true if we get an authoritative nx for this domain */
223f46c709fSDavid du Colombier 	/* permit only 1 query per (domain name, type) at a time */
224225077b0SDavid du Colombier 	Querylck querylck[Maxlcks];
2257dd7cddfSDavid du Colombier };
2267dd7cddfSDavid du Colombier 
2277dd7cddfSDavid du Colombier /*
2287dd7cddfSDavid du Colombier  *  security info
2297dd7cddfSDavid du Colombier  */
2304f8f669cSDavid du Colombier struct Block
2314f8f669cSDavid du Colombier {
2324f8f669cSDavid du Colombier 	int	dlen;
2334f8f669cSDavid du Colombier 	uchar	*data;
2344f8f669cSDavid du Colombier };
2357dd7cddfSDavid du Colombier struct Key
2367dd7cddfSDavid du Colombier {
2377dd7cddfSDavid du Colombier 	int	flags;
2387dd7cddfSDavid du Colombier 	int	proto;
2397dd7cddfSDavid du Colombier 	int	alg;
2404f8f669cSDavid du Colombier 	Block;
2417dd7cddfSDavid du Colombier };
2427dd7cddfSDavid du Colombier struct Cert
2437dd7cddfSDavid du Colombier {
2447dd7cddfSDavid du Colombier 	int	type;
2457dd7cddfSDavid du Colombier 	int	tag;
2467dd7cddfSDavid du Colombier 	int	alg;
2474f8f669cSDavid du Colombier 	Block;
2487dd7cddfSDavid du Colombier };
2497dd7cddfSDavid du Colombier struct Sig
2507dd7cddfSDavid du Colombier {
2514f8f669cSDavid du Colombier 	Cert;
2527dd7cddfSDavid du Colombier 	int	labels;
2537dd7cddfSDavid du Colombier 	ulong	ttl;
2547dd7cddfSDavid du Colombier 	ulong	exp;
2557dd7cddfSDavid du Colombier 	ulong	incep;
2567dd7cddfSDavid du Colombier 	DN	*signer;
2573e12c5d1SDavid du Colombier };
2589a747e4fSDavid du Colombier struct Null
2599a747e4fSDavid du Colombier {
2604f8f669cSDavid du Colombier 	Block;
2619a747e4fSDavid du Colombier };
2623e12c5d1SDavid du Colombier 
2633e12c5d1SDavid du Colombier /*
26460845620SDavid du Colombier  *  text strings
26560845620SDavid du Colombier  */
26660845620SDavid du Colombier struct Txt
26760845620SDavid du Colombier {
26860845620SDavid du Colombier 	Txt	*next;
26960845620SDavid du Colombier 	char	*p;
27060845620SDavid du Colombier };
27160845620SDavid du Colombier 
27260845620SDavid du Colombier /*
2733e12c5d1SDavid du Colombier  *  an unpacked resource record
2743e12c5d1SDavid du Colombier  */
2753e12c5d1SDavid du Colombier struct RR
2763e12c5d1SDavid du Colombier {
2773e12c5d1SDavid du Colombier 	RR	*next;
27834f77ae3SDavid du Colombier 	ulong	magic;
2793e12c5d1SDavid du Colombier 	DN	*owner;		/* domain that owns this resource record */
280225077b0SDavid du Colombier 	uintptr	pc;		/* for tracking memory allocation */
2817dd7cddfSDavid du Colombier 	ulong	ttl;		/* time to live to be passed on */
2827dd7cddfSDavid du Colombier 	ulong	expire;		/* time this entry expires locally */
2836b0d5c8bSDavid du Colombier 	ulong	marker;		/* used locally when scanning rrlists */
2844f8f669cSDavid du Colombier 	ushort	type;		/* RR type */
2854f8f669cSDavid du Colombier 	ushort	query;		/* query type is in response to */
2864f8f669cSDavid du Colombier 	uchar	auth;		/* flag: authoritative */
2874f8f669cSDavid du Colombier 	uchar	db;		/* flag: from database */
2884f8f669cSDavid du Colombier 	uchar	cached;		/* flag: rr in cache */
2894f8f669cSDavid du Colombier 	uchar	negative;	/* flag: this is a cached negative response */
2904f8f669cSDavid du Colombier 
2916dc4800dSDavid du Colombier 	union {			/* discriminated by negative & type */
2927dd7cddfSDavid du Colombier 		DN	*negsoaowner;	/* soa for cached negative response */
293225077b0SDavid du Colombier 		DN	*host;	/* hostname - soa, cname, mb, md, mf, mx, ns, srv */
2943e12c5d1SDavid du Colombier 		DN	*cpu;	/* cpu type - hinfo */
2953e12c5d1SDavid du Colombier 		DN	*mb;	/* mailbox - mg, minfo */
29653874d13SDavid du Colombier 		DN	*ip;	/* ip address - a, aaaa */
29760845620SDavid du Colombier 		DN	*rp;	/* rp arg - rp */
29876783259SDavid du Colombier 		uintptr	arg0;	/* arg[01] are compared to find dups in dn.c */
2993e12c5d1SDavid du Colombier 	};
3006dc4800dSDavid du Colombier 	union {			/* discriminated by negative & type */
30176783259SDavid du Colombier 		int	negrcode; /* response code for cached negative resp. */
3027dd7cddfSDavid du Colombier 		DN	*rmb;	/* responsible maibox - minfo, soa, rp */
3037dd7cddfSDavid du Colombier 		DN	*ptr;	/* pointer to domain name - ptr */
3043e12c5d1SDavid du Colombier 		DN	*os;	/* operating system - hinfo */
3053e12c5d1SDavid du Colombier 		ulong	pref;	/* preference value - mx */
3063e12c5d1SDavid du Colombier 		ulong	local;	/* ns served from local database - ns */
307225077b0SDavid du Colombier 		ushort	port;	/* - srv */
30876783259SDavid du Colombier 		uintptr	arg1;	/* arg[01] are compared to find dups in dn.c */
3093e12c5d1SDavid du Colombier 	};
3104f8f669cSDavid du Colombier 	union {			/* discriminated by type */
3113e12c5d1SDavid du Colombier 		SOA	*soa;	/* soa timers - soa */
3127dd7cddfSDavid du Colombier 		Key	*key;
3137dd7cddfSDavid du Colombier 		Cert	*cert;
3147dd7cddfSDavid du Colombier 		Sig	*sig;
3159a747e4fSDavid du Colombier 		Null	*null;
31660845620SDavid du Colombier 		Txt	*txt;
3174f8f669cSDavid du Colombier 		Srv	*srv;
3187dd7cddfSDavid du Colombier 	};
3193e12c5d1SDavid du Colombier };
3203e12c5d1SDavid du Colombier 
3213e12c5d1SDavid du Colombier /*
322dc5a79c1SDavid du Colombier  *  list of servers
323dc5a79c1SDavid du Colombier  */
324dc5a79c1SDavid du Colombier struct Server
325dc5a79c1SDavid du Colombier {
326dc5a79c1SDavid du Colombier 	Server	*next;
327dc5a79c1SDavid du Colombier 	char	*name;
328dc5a79c1SDavid du Colombier };
329dc5a79c1SDavid du Colombier 
330dc5a79c1SDavid du Colombier /*
3314f8f669cSDavid du Colombier  *  timers for a start-of-authority record.  all ulongs are in seconds.
3323e12c5d1SDavid du Colombier  */
3333e12c5d1SDavid du Colombier struct SOA
3343e12c5d1SDavid du Colombier {
3354f8f669cSDavid du Colombier 	ulong	serial;		/* zone serial # */
3364f8f669cSDavid du Colombier 	ulong	refresh;	/* zone refresh interval */
3374f8f669cSDavid du Colombier 	ulong	retry;		/* zone retry interval */
3384f8f669cSDavid du Colombier 	ulong	expire;		/* time to expiration */
3394f8f669cSDavid du Colombier 	ulong	minttl;		/* min. time to live for any entry */
3404f8f669cSDavid du Colombier 
341dc5a79c1SDavid du Colombier 	Server	*slaves;	/* slave servers */
3423e12c5d1SDavid du Colombier };
3433e12c5d1SDavid du Colombier 
3443e12c5d1SDavid du Colombier /*
3454f8f669cSDavid du Colombier  * srv (service location) record (rfc2782):
3464f8f669cSDavid du Colombier  * _service._proto.name ttl class(IN) 'SRV' priority weight port target
3474f8f669cSDavid du Colombier  */
3484f8f669cSDavid du Colombier struct Srv
3494f8f669cSDavid du Colombier {
3504f8f669cSDavid du Colombier 	ushort	pri;
3514f8f669cSDavid du Colombier 	ushort	weight;
3524f8f669cSDavid du Colombier };
3534f8f669cSDavid du Colombier 
354f2714ceaSDavid du Colombier typedef struct Rrlist Rrlist;
35576783259SDavid du Colombier struct Rrlist
35676783259SDavid du Colombier {
35776783259SDavid du Colombier 	int	count;
35876783259SDavid du Colombier 	RR	*rrs;
35976783259SDavid du Colombier };
36076783259SDavid du Colombier 
3614f8f669cSDavid du Colombier /*
3623e12c5d1SDavid du Colombier  *  domain messages
3633e12c5d1SDavid du Colombier  */
3643e12c5d1SDavid du Colombier struct DNSmsg
3653e12c5d1SDavid du Colombier {
3667dd7cddfSDavid du Colombier 	ushort	id;
3673e12c5d1SDavid du Colombier 	int	flags;
3683e12c5d1SDavid du Colombier 	int	qdcount;	/* questions */
3693e12c5d1SDavid du Colombier 	RR 	*qd;
3703e12c5d1SDavid du Colombier 	int	ancount;	/* answers */
3713e12c5d1SDavid du Colombier 	RR	*an;
3723e12c5d1SDavid du Colombier 	int	nscount;	/* name servers */
3733e12c5d1SDavid du Colombier 	RR	*ns;
3743e12c5d1SDavid du Colombier 	int	arcount;	/* hints */
3753e12c5d1SDavid du Colombier 	RR	*ar;
3763e12c5d1SDavid du Colombier };
3773e12c5d1SDavid du Colombier 
3787dd7cddfSDavid du Colombier /*
3797dd7cddfSDavid du Colombier  *  definition of local area for dblookup
3807dd7cddfSDavid du Colombier  */
3817dd7cddfSDavid du Colombier struct Area
3827dd7cddfSDavid du Colombier {
3837dd7cddfSDavid du Colombier 	Area	*next;
3847dd7cddfSDavid du Colombier 
3857dd7cddfSDavid du Colombier 	int	len;		/* strlen(area->soarr->owner->name) */
3867dd7cddfSDavid du Colombier 	RR	*soarr;		/* soa defining this area */
387dc5a79c1SDavid du Colombier 	int	neednotify;
388dc5a79c1SDavid du Colombier 	int	needrefresh;
3897dd7cddfSDavid du Colombier };
3907dd7cddfSDavid du Colombier 
3914f8f669cSDavid du Colombier typedef struct Cfg Cfg;
3924f8f669cSDavid du Colombier struct Cfg {
3934f8f669cSDavid du Colombier 	int	cachedb;
3944f8f669cSDavid du Colombier 	int	resolver;
3955d34ce99SDavid du Colombier 	int	justforw;	/* flag: pure resolver, just forward queries */
3965d34ce99SDavid du Colombier 	int	serve;		/* flag: serve udp queries */
3974f8f669cSDavid du Colombier 	int	inside;
3984f8f669cSDavid du Colombier 	int	straddle;
3994f8f669cSDavid du Colombier };
4004f8f669cSDavid du Colombier 
4015d34ce99SDavid du Colombier /* (udp) query stats */
4025d34ce99SDavid du Colombier typedef struct {
4035d34ce99SDavid du Colombier 	QLock;
4045d34ce99SDavid du Colombier 	ulong	slavehiwat;	/* procs */
405a41547ffSDavid du Colombier 	ulong	qrecvd9p;	/* query counts */
406a41547ffSDavid du Colombier 	ulong	qrecvdudp;
4075d34ce99SDavid du Colombier 	ulong	qsent;
4086aaebd7dSDavid du Colombier 	ulong	qrecvd9prpc;	/* packet count */
4096aaebd7dSDavid du Colombier 	ulong	alarms;
4105d34ce99SDavid du Colombier 	/* reply times by count */
4116d8e4566SDavid du Colombier 	ulong	under10ths[3*10+2];	/* under n*0.1 seconds, n is index */
4125d34ce99SDavid du Colombier 	ulong	tmout;
4135d34ce99SDavid du Colombier 	ulong	tmoutcname;
4145d34ce99SDavid du Colombier 	ulong	tmoutv6;
4155d34ce99SDavid du Colombier 
416f46c709fSDavid du Colombier 	ulong	answinmem;	/* answers in memory */
417f46c709fSDavid du Colombier 	ulong	negans;		/* negative answers received */
4180319257bSDavid du Colombier 	ulong	negserver;	/* neg ans with Rserver set */
4190319257bSDavid du Colombier 	ulong	negbaddeleg;	/* neg ans with bad delegations */
4200319257bSDavid du Colombier 	ulong	negbdnoans;	/* ⋯ and no answers */
4210319257bSDavid du Colombier 	ulong	negnorname;	/* neg ans with no Rname set */
4220319257bSDavid du Colombier 	ulong	negcached;	/* neg ans cached */
4235d34ce99SDavid du Colombier } Stats;
4245d34ce99SDavid du Colombier 
4255d34ce99SDavid du Colombier Stats stats;
4265d34ce99SDavid du Colombier 
4277dd7cddfSDavid du Colombier enum
4287dd7cddfSDavid du Colombier {
4297dd7cddfSDavid du Colombier 	Recurse,
4307dd7cddfSDavid du Colombier 	Dontrecurse,
4317dd7cddfSDavid du Colombier 	NOneg,
4327dd7cddfSDavid du Colombier 	OKneg,
4337dd7cddfSDavid du Colombier };
4347dd7cddfSDavid du Colombier 
4354f8f669cSDavid du Colombier extern Cfg	cfg;
4366b0d5c8bSDavid du Colombier extern char	*dbfile;
4374f8f669cSDavid du Colombier extern int	debug;
4384f8f669cSDavid du Colombier extern Area	*delegated;
4396b0d5c8bSDavid du Colombier extern char	*logfile;
4406b0d5c8bSDavid du Colombier extern int	maxage;		/* age of oldest entry in cache (secs) */
4414f8f669cSDavid du Colombier extern char	mntpt[];
4424f8f669cSDavid du Colombier extern int	needrefresh;
4434f8f669cSDavid du Colombier extern int	norecursion;
444dc5a79c1SDavid du Colombier extern ulong	now;		/* time base */
445a41547ffSDavid du Colombier extern vlong	nowns;
446dc5a79c1SDavid du Colombier extern Area	*owned;
4474f8f669cSDavid du Colombier extern int	sendnotifies;
4484f8f669cSDavid du Colombier extern ulong	target;
4494f8f669cSDavid du Colombier extern int	testing;	/* test cache whenever removing a DN */
4504f8f669cSDavid du Colombier extern char	*trace;
4514f8f669cSDavid du Colombier extern int	traceactivity;
4524f8f669cSDavid du Colombier extern char	*zonerefreshprogram;
4537dd7cddfSDavid du Colombier 
4547dd7cddfSDavid du Colombier #pragma	varargck	type	"R"	RR*
4557dd7cddfSDavid du Colombier #pragma	varargck	type	"Q"	RR*
4567dd7cddfSDavid du Colombier 
4574f8f669cSDavid du Colombier 
4584f8f669cSDavid du Colombier /* dn.c */
4594f8f669cSDavid du Colombier extern char	*rrtname[];
4604f8f669cSDavid du Colombier extern char	*rname[];
4614f8f669cSDavid du Colombier extern unsigned	nrname;
4624f8f669cSDavid du Colombier extern char	*opname[];
463530fef66SDavid du Colombier extern Lock	dnlock;
4644f8f669cSDavid du Colombier 
4654f8f669cSDavid du Colombier void	abort(); /* char*, ... */;
4664f8f669cSDavid du Colombier void	addserver(Server**, char*);
4674f8f669cSDavid du Colombier Server*	copyserverlist(Server*);
4684f8f669cSDavid du Colombier void	db2cache(int);
4694f8f669cSDavid du Colombier void	dnage(DN*);
4704f8f669cSDavid du Colombier void	dnageall(int);
4714f8f669cSDavid du Colombier void	dnagedb(void);
472410ea80bSDavid du Colombier void	dnageallnever(void);
473410ea80bSDavid du Colombier void	dnagenever(DN *, int);
4744f8f669cSDavid du Colombier void	dnauthdb(void);
4754f8f669cSDavid du Colombier void	dncheck(void*, int);
4764f8f669cSDavid du Colombier void	dndump(char*);
4774f8f669cSDavid du Colombier void	dnget(void);
4784f8f669cSDavid du Colombier void	dninit(void);
4794f8f669cSDavid du Colombier DN*	dnlookup(char*, int, int);
48053874d13SDavid du Colombier void	dnptr(uchar*, uchar*, char*, int, int, int);
4814f8f669cSDavid du Colombier void	dnpurge(void);
4824f8f669cSDavid du Colombier void	dnput(void);
4834f8f669cSDavid du Colombier void	dnslog(char*, ...);
4844f927735SDavid du Colombier void	dnstats(char *file);
4854f8f669cSDavid du Colombier void*	emalloc(int);
4864f8f669cSDavid du Colombier char*	estrdup(char*);
487a41547ffSDavid du Colombier void	freeanswers(DNSmsg *mp);
4884f8f669cSDavid du Colombier void	freeserverlist(Server*);
4894f8f669cSDavid du Colombier int	getactivity(Request*, int);
4904f8f669cSDavid du Colombier Area*	inmyarea(char*);
4914f8f669cSDavid du Colombier void	putactivity(int);
4924f8f669cSDavid du Colombier RR*	randomize(RR*);
4934f8f669cSDavid du Colombier RR*	rralloc(int);
4944f8f669cSDavid du Colombier void	rrattach(RR*, int);
4954f8f669cSDavid du Colombier int	rravfmt(Fmt*);
4964f8f669cSDavid du Colombier RR*	rrcat(RR**, RR*);
4974f8f669cSDavid du Colombier RR**	rrcopy(RR*, RR**);
4984f8f669cSDavid du Colombier int	rrfmt(Fmt*);
4994f8f669cSDavid du Colombier void	rrfree(RR*);
5004f8f669cSDavid du Colombier void	rrfreelist(RR*);
5014f8f669cSDavid du Colombier RR*	rrlookup(DN*, int, int);
5024f8f669cSDavid du Colombier char*	rrname(int, char*, int);
5034f8f669cSDavid du Colombier RR*	rrremneg(RR**);
5044f8f669cSDavid du Colombier RR*	rrremtype(RR**, int);
5054f8f669cSDavid du Colombier int	rrsupported(int);
5064f8f669cSDavid du Colombier int	rrtype(char*);
5074f8f669cSDavid du Colombier void	slave(Request*);
5084f8f669cSDavid du Colombier int	subsume(char*, char*);
5094f8f669cSDavid du Colombier int	tsame(int, int);
5104f8f669cSDavid du Colombier void	unique(RR*);
5114f8f669cSDavid du Colombier void	warning(char*, ...);
5124f8f669cSDavid du Colombier 
5134f8f669cSDavid du Colombier /* dnarea.c */
5144f8f669cSDavid du Colombier void	refresh_areas(Area*);
5154f8f669cSDavid du Colombier void	freearea(Area**);
5164f8f669cSDavid du Colombier void	addarea(DN *dp, RR *rp, Ndbtuple *t);
5174f8f669cSDavid du Colombier 
5184f8f669cSDavid du Colombier /* dblookup.c */
5194f8f669cSDavid du Colombier int	baddelegation(RR*, RR*, uchar*);
5204f8f669cSDavid du Colombier RR*	dbinaddr(DN*, int);
5214f8f669cSDavid du Colombier RR*	dblookup(char*, int, int, int, int);
52221abd8f2SDavid du Colombier void	dnforceage(void);
5234f8f669cSDavid du Colombier RR*	dnsservers(int);
5244f8f669cSDavid du Colombier RR*	domainlist(int);
5254f8f669cSDavid du Colombier int	insideaddr(char *dom);
5264f8f669cSDavid du Colombier int	insidens(uchar *ip);
5274e153993SDavid du Colombier int	myaddr(char *addr);
5284f8f669cSDavid du Colombier int	opendatabase(void);
5294f8f669cSDavid du Colombier uchar*	outsidens(int);
5304f8f669cSDavid du Colombier 
5314f8f669cSDavid du Colombier /* dns.c */
5324f8f669cSDavid du Colombier char*	walkup(char*);
5334f8f669cSDavid du Colombier RR*	getdnsservers(int);
5344f8f669cSDavid du Colombier void	logreply(int, uchar*, DNSmsg*);
5354f8f669cSDavid du Colombier void	logsend(int, int, uchar*, char*, char*, int);
5364f8f669cSDavid du Colombier void	procsetname(char *fmt, ...);
5374f8f669cSDavid du Colombier 
5384f8f669cSDavid du Colombier /* dnresolve.c */
5394f8f669cSDavid du Colombier RR*	dnresolve(char*, int, int, Request*, RR**, int, int, int, int*);
5404f8f669cSDavid du Colombier int	udpport(char *);
5414f8f669cSDavid du Colombier int	mkreq(DN *dp, int type, uchar *buf, int flags, ushort reqno);
5424f8f669cSDavid du Colombier int	seerootns(void);
543d9924332SDavid du Colombier void	initdnsmsg(DNSmsg *mp, RR *rp, int flags, ushort reqno);
544d9924332SDavid du Colombier DNSmsg*	newdnsmsg(RR *rp, int flags, ushort reqno);
5454f8f669cSDavid du Colombier 
5464f8f669cSDavid du Colombier /* dnserver.c */
5474f8f669cSDavid du Colombier void	dnserver(DNSmsg*, DNSmsg*, Request*, uchar *, int);
5484f8f669cSDavid du Colombier void	dnudpserver(char*);
5494f8f669cSDavid du Colombier void	dntcpserver(char*);
5504f8f669cSDavid du Colombier 
5514f8f669cSDavid du Colombier /* dnnotify.c */
5524f8f669cSDavid du Colombier void	dnnotify(DNSmsg*, DNSmsg*, Request*);
5534f8f669cSDavid du Colombier void	notifyproc(void);
5544f8f669cSDavid du Colombier 
5554f8f669cSDavid du Colombier /* convDNS2M.c */
5564f8f669cSDavid du Colombier int	convDNS2M(DNSmsg*, uchar*, int);
5574f8f669cSDavid du Colombier 
5584f8f669cSDavid du Colombier /* convM2DNS.c */
5594f8f669cSDavid du Colombier char*	convM2DNS(uchar*, int, DNSmsg*, int*);
5604f8f669cSDavid du Colombier 
5614f8f669cSDavid du Colombier #pragma varargck argpos dnslog 1
562