]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/ndb/dns.h
dns: fix rr->srv memory leak in rrcopy, mark rr->sig->signer, dn aging, cleanup
[plan9front.git] / sys / src / cmd / ndb / dns.h
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                 Srv     *srv;
305                 Key     *key;
306                 Cert    *cert;
307                 Sig     *sig;
308                 Null    *null;
309                 Txt     *txt;
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
537 /* dnserver.c */
538 void    dnserver(DNSmsg*, DNSmsg*, Request*, uchar *, int);
539 void    dnudpserver(char*);
540 void    dntcpserver(char*);
541
542 /* dnnotify.c */
543 void    dnnotify(DNSmsg*, DNSmsg*, Request*);
544 void    notifyproc(void);
545
546 /* convDNS2M.c */
547 int     convDNS2M(DNSmsg*, uchar*, int);
548
549 /* convM2DNS.c */
550 char*   convM2DNS(uchar*, int, DNSmsg*, int*);
551
552 #pragma varargck argpos dnslog 1