~samiam/MaraDNS

MaraDNS/MaraDns.h -rw-r--r-- 16.2 KiB View raw
a2036189 — Sam Trenholme coLunacyDNS: Getting closer to IPv6 socket support 12 hours ago
                                                                                
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
/* Copyright (c) 2002-2020 Sam Trenholme
 *
 * TERMS
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 *
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * This software is provided 'as is' with no guarantees of correctness or
 * fitness for purpose.
 */

#ifndef MARADNSH_DEFINED
#define MARADNSH_DEFINED

/* Some constants that are fairly OS specific, concerning the amount of
 * memory threads can use.  These numbers should be higher than the
 * maximum possible thread overhead */
/* The amount of memory used to have threads at all */
#define THREAD_OVERHEAD 536870912
/* The amount of memory a single thread will use */
#define PER_THREAD_MEM 16777216

#include <stdint.h>

/* This is the root server list as of 2007/11/15; the root servers were
 * last changed 2007/11/01 */
/* 2020 update: No longer used; Deadwood has different root server list. 
 * Actually, these days Deadwood has an upstream server list, and only
 * has root servers in documentation examples */
#define ROOT_SERVERS "198.41.0.4"       /* a.root-servers.net (VeriSign) */ \
                     ",192.228.79.201"  /* b.root-servers.net (ISI) */ \
                     ",192.33.4.12"     /* c.root-servers.net (Cogent) */ \
                     ",128.8.10.90"     /* d.root-servers.net (UMaryland) */ \
                     ",192.203.230.10"  /* e.root-servers.net (NASA Ames) */ \
                     ",192.5.5.241"     /* f.root-servers.net (ISC) */ \
                     ",192.112.36.4"    /* g.root-servers.net (DOD NIC) */ \
                     ",128.63.2.53"     /* h.root-servers.net (ArmyRU) */ \
                     ",192.36.148.17"   /* i.root-servers.net (NORDUnet) */ \
                     ",192.58.128.30"   /* j.root-servers.net (VeriSign) */ \
                     ",193.0.14.129"    /* k.root-servers.net (Reseaux) */ \
                     ",199.7.83.42"     /* l.root-servers.net (IANA) */ \
                     ",202.12.27.33"    /* m.root-servers.net (WIDE) */

/* The default UID (User ID) that MaraDNS has; I put this here so packagers
   can change this easily.  This should be the 'nobody' user, or, optionally
   a special 'MaraDNS' user.  This user needs to be able to enter
   the /etc/maradns directory, and read all zone files in /etc/maradns

   If you change this from 707, please also change the mararc man page, 
   which states the default value for this is 707.  To change the 
   man page:

   * Enter the doc/en/source directory

   * Modify the mararc.ej file

   * Enter the doc/en/man directory

   * If you have a recent version of Perl on your system, you should be
     able to update the man page by typing in 'make'.

   * Enter the doc/en/tutorial directory

   * Enter the doc/en/tutorial/text directory

   * If Bash is at /bin, you should be able to update the text documentation
     by typing in make.  Otherwise, change the tools/ej/ej2txt file's first
     line to point to Bash
 */

#define MARADNS_DEFAULT_UID 707

/* The default GID (Group ID) that MaraDNS has; see the default UID notes
   above.  Again: CHANGE THE MARARC MAN PAGE IF YOU CHANGE THIS VALUE */
#define MARADNS_DEFAULT_GID 707

/* The UID that the Duende logging process uses.  CHANGE THE DUENDE MAN
   PAGE IF YOU CHANGE THIS VALUE (same general process as changing the
   mararc man page; the source file for the duende man page is duende.ej) */
#define DUENDE_LOGGER_UID 707

/* The directory that Duende runs in.  This directory has to exist for
   Duende to be able to run.  Again, IF YOU CHANGE THIS, CHANGE THE
   DUENDE MAN PAGE */
#define DUENDE_CHROOT_DIR "/etc/maradns/logger"

/* The default IP address that Askmara uses; this used to be 127.0.0.3
   but is now 127.0.0.1 because many non-Linux systems only use 127.0.0.1
   for the loopback interface.  IF YOU CHANGE THIS, CHANGE THE ASKMARA
   MAN PAGE (askmara.ej) */
#define ASKMARA_DEFAULT_SERVER "127.0.0.1"

/* The default port to bind the DNS server to, and the port that askmara uses
   to bind to.  Note that a lot of MaraDNS' messages are hard-coded
   to say that we are binding on port 53, so only change this for
   debugging purposes.  I use this so that I can debug MaraDNS on
   systems where I do not have root. */
#define DNS_PORT 53

/* The default port to use when contacting remove DNS servers; it may
 * be desirable to have two instances of MaraDNS on the same IP when
 * resolving the dangling CNAME issue on a machine with only one
 * loopback IP (You would * think, with an entire Class A of the IP
 * space reserved for loopback, * more systems would have at least
 * two loopback IPs.  You would be wrong)
 */
#define UPSTREAM_PORT 53

/* Whether we allow MaraDNS to run as a non root user; this is usually
 * disabled, but can be enabled by uncommenting the following line */
/* #define ALLOW_NON_ROOT */

/* The maximum allowed size of a zone name */
#define MAX_ZONE_SIZE 256

#ifndef JS_STRING_INCLUDED
#include "libs/JsStr.h"
#endif

/* The encoding for the strings in the configuration files (3: iso 8859-1) */
#define MARA_LOCALE 3

/* The data types for 32-bit signed and unsigned data */
#define int32 int32_t
#define uint32 uint32_t

/* These data types need to store at least 16 bits, and can store more */
#define int16 int16_t
#define uint16 uint16_t

#ifdef MINGW32
#define MSG_WAITALL 0
#define socklen_t int
#endif /* MINGW32 */

/* The data type used for storing "perm" bits (who gets to view a given
 * DNS record; based on IP) */
#define perm_t uint16

/* The timestamp which MaraDNS now uses; she is now Y2038-complient
   on (what will be by then) legacy systems with a 32-bit time_t
 */
#ifndef MINGW32
#define qual_timestamp int64_t
#else
#define qual_timestamp long long
#endif
/* The magic "Never expire" time */
#define NEVER_EXPIRE 0

/* Structure that holds the information about either a ipv4 or ipv6
 * connection */
typedef struct {
   unsigned char type; /* Type: 4 is ipv4; 6 is ipv6 */
   void *d; /* Data */
   int addrlen;
   } conn;

/* Structure that holds an IPV4 IP and netmask */
typedef struct {
    uint32 ip;
    uint32 mask;
    } ipv4pair;

/* Structure which is a bidirectional linked list which lists which RRs to axe
   next when the cache runs low on free spots */
typedef struct fila { /* Fila: Spanish for "line" */
    struct fila *siguiente; /* Spanish for "next" */
    struct fila *previous;
    unsigned char datatype; /* 0:rr 1:closer */
    void *record; /* This points to the record that this particular element
                     uses */
    js_string *hash_point; /* This points to the query which generates
                              the record in question */
    char nukable_hp; /* Whether the hash point string shold be destroyed
                        when we remove this fila element. 1: Yes, nuke
                        the hash_point string; 0: No, keep the hash
                        point string */
    } fila;

/* DNS server that is closer to the answer for a given request */
typedef struct closer {
    unsigned int num_elements; /* Number of elements in the linked list */
    qual_timestamp ttd; /* Time for this record to die */
    int datatype; /* This is the RR type of the data (RR_A [in which
                     case, the data is a pointer to a uint32] or RR_NS [which
                     makes the data point to a js_string object]) */
    void *data;
    fila *zap; /* So that we can determine in which order to zap RRs */
    struct closer *masked; /* If another record with a ttd after the
                              ttd for this record exists, we want to
                              access that data when this record expires */
    struct closer *next; } closer;

/* Structure which contains the data for a DNS record pointed to from
   the hash */
typedef struct rr {
    qual_timestamp expire; /* When this RR expires (0=authoritative/never) */
    uint32 ttl; /* The TTL for the record in question */
    uint32 authoritative; /* Are we authoritative for this zone */
    struct rr *next; /* Either the first NS for this zone _or_ the next copy
                        of the same record for the same data type */
    struct rr *ip; /* If this is a PTR, MX, or NS record, pointer to the
                      ip the rr domain name points to (if applicable) */
#ifdef IPV6
    struct rr *ip6; /* It's the 2010s and time to link to IPv6 glue */
#endif
    js_string *ptr; /* If this is a PTR request pointing to a CNAME,
                       we want to give them the PTR record along
                       with the CNAME record. */
    uint16 rr_type; /* Type of resource record this entry is */
    js_string *query; /* Pointer to the query one asks to get this answer */
    js_string *data; /* The actual raw binary data for this RR */
    fila *zap; /* Pointer to a structure used for deleting elements from
                  the cache when the cache starts to fill up */
    char seen; /* This is used by udpsuccess() to insure that a given
                  element in the hash is only visited once */
    perm_t perms; /* What IPs can view this element; making this zero
                     means that all IPs can view the element in question */
    struct rr_list *list; /* rr_list of all records this CNAME refers to */
    char rcode; /* This is used to store the rcode for a given DNS answer */
    } rr;

/* Structure for a linked list used in the ANY (and CNAME) rr type */
typedef struct rr_list {
    uint16 rr_type;
    rr *data;
    struct rr_list *next;
    } rr_list;

/* Structure which contains the header as described in Section 4.1.1 of
   RFC1035 */
typedef struct {
    uint16 id; /* 16-bit unsigned ID of Query */
    int qr; /* Boolean query-type (query or answer) */
    int opcode; /* 4-bit opcode flag */
    int aa; /* boolean Authoritative Answer */
    int tc; /* boolean truncation flag */
    int rd; /* boolean "recursion desired" flag */
    int ra; /* boolean "recursion available" flag */
    int z; /* 3-bit reserved "z" flags.  Keep 0 */
    int rcode; /* 4-bit rcode flag */
    uint16 qdcount; /* 16-bit unsigned # of questions */
    uint16 ancount; /* 16-bit unsigned # of answers */
    uint16 nscount; /* 16-bit unsigned # of NS answers */
    uint16 arcount; /* 16-bit unsigned # of additional records */
    } q_header;

/* DNS Question as described in Section 4.1.2 of RFC1035 */
typedef struct {
    js_string *qname; /* Special RFC1035 format of domain name */
    uint16 qtype; /* 16-bit query type */
    uint16 qclass; /* 16-bit query class */
    } q_question;

/* RR format as described in section 4.1.3 of RFC1035 */
typedef struct {
    js_string *name; /* Special RFC1035 format of domain name */
    uint16 type; /* 16-bit record type */
    uint16 class; /* 16-bit record class */
    uint32 ttl; /* 32-bit ttl */
    uint16 rdlength; /* 16-bit length of the RDATA field */
    js_string *rdata; /* variable length resource data */
    } q_rr;

/* This is, as of June 23 2006, a list of all DNS RRs over at
   http://www.iana.org/assignments/dns-parameters */
/* Some query types and their RFC1035 section 3.2.2 values */
/* A record: RFC1035 section 3.4.1 */
#define RR_A 1
/* NS record: RFC1035 section 3.3.11 */
#define RR_NS 2
/* Obsolete; RFC1035 */
#define RR_MD 3
/* Obsolete; RFC1035 */
#define RR_MF 4
/* CNAME: RFC1035 section 3.3.1 */
#define RR_CNAME 5
/* SOA: RFC1035 section 3.3.13 */
#define RR_SOA 6
/* EXPERIMENTAL RFC1035 RRs */
#define RR_MB 7
#define RR_MG 8
#define RR_MR 9
#define RR_NULL 10
/* Non-experimental RFC1035 RR */
#define RR_WKS 11
/* PTR: RFC1035 section 3.3.12 */
#define RR_PTR 12
/* Two more RFC1035 RRs */
#define RR_HINFO 13
#define RR_MINFO 14
/* MX: RFC1035 section 3.3.9 */
#define RR_MX 15
/* TXT: RFC1035 section 3.3.14 */
#define RR_TXT 16
/* RFC1183 RRs */
#define RR_RP 17
#define RR_AFSDB 18
#define RR_X25 19
#define RR_ISDN 20
#define RR_RT 21
/* RFC1706 RRs */
#define RR_NSAP 22
#define RR_NSAP_PTR 23
/* RFC2535, RFC3755, and RFC4034 RRs */
#define RR_SIG 24
#define RR_KEY 25
/* RFC2163 RR */
#define RR_PX 26
/* RFC1712 RR */
#define RR_GPOS 27
/* AAAA: ipv6 addresses (Not in an RFC) */
#define RR_AAAA 28
/* RFC1876 */
#define RR_LOC 29
/* Obsolete RFC2535 and RFC3755 RR */
#define RR_NXT 30
/* "Endpoint" (Not in an RFC) */
#define RR_EID 31
/* "Nimrod" (Not in an RFC) */
#define RR_NIMLOC 32
/* SRV: "service" records (RFC2782) */
#define RR_SRV 33
/* "ATM address" (Not in an RFC) */
#define RR_ATMA 34
/* RFC2168,RFC2915,RFC3403 */
#define RR_NAPTR 35
/* RFC2230 */
#define RR_KX 36
/* RFC2538 */
#define RR_CENT 37
/* DON'T USE THIS A6 RR; harmful RFC2874 */
#define RR_A6 38
/* Again, harmful for same reason A6 is harmful; RFC2672 */
#define RR_DNAME 39
/* Kitchen Sink RR (Not in an RFC; looks to be a joke but BIND supports it) */
#define RR_SINK 40
/* RFC2671 */
#define RR_OPT 41
/* RFC3123 */
#define RR_APL 42
/* RFC3658 */
#define RR_DS 43
/* RFC4255 */
#define RR_SSHFP 44
/* RFC4025 */
#define RR_IPSECKEY 45
/* 3 RFC3755 RRs */
#define RR_RRSIG 46
#define RR_NSEC 47
#define RR_DNSKEY 48
/* 49-98 are unassigned as of 2006/06/23 */
/* SPF: sender policy framework (stops forged email) record */
#define RR_SPF 99
/* Four RRs not in an RFC but are IANA-reserved */
#define RR_UINFO 100
#define RR_UID 101
#define RR_GID 102
#define RR_UNSPEC 103
/* 104-248 are unassigned as of 2006/06/23 */
/* RFC2930 */
#define RR_TKEY 249
/* RFC2845 */
#define RR_TSIG 250
/* RFC251 (treated as AXFR by zoneserver) */
#define RR_IXFR 251
/* AXFR: Special query that requests a zone transfer */
#define RR_AXFR 252
/* RFC1035; not officially obsolete but for all practical purposes
   obsolete */
#define RR_MAILB 253
/* MAILA is officially obsolete */
#define RR_MAILA 254
/* ANY: Special query for all of the records for a given hostname */
#define RR_ANY 255
/* This is not assigned by the IANA, but BIND uses this RR number */
#define RR_ZXFR 256
/* "DNSSEC Trust Authorities"; Not in an RFC */
#define RR_TA 32768
/* RFC4431 */
#define RR_DLV 32769
/* Some "magic" RR types used by askmara */
/* RR_MAGIC_SPACE: Make the character representing the RR a space */
#define RR_MAGIC_SPACE -300
/* RR_MAGIC_EMAIL: Make the character representing the RR a space, and
 * make the first "dot" an at */
#define RR_MAGIC_EMAIL -301

/* The following formats use a single domain name as the data:
   NS CNAME PTR (MB MD MF MG)
*/
#define rr_ns *js_string
#define rr_cname *js_string
#define rr_ptr *js_string

/* The A record is a single unsigned 32-bit integer */
#define rr_a uint32

/* The other supported types we make structures of */

/* SOA: RFC1035 3.3.13 */
typedef struct {
    js_string *mname; /* The name server with authoritative data */
    js_string *rname; /* Domain-name style data: email address */
    uint32 serial; /* 32-bit serial */
    int32 refresh; /* How often slave servers look at the serial to
                    see if it should be refreshed */
    int32 retry; /* How often slave servers should look at the serial when
                  the server is down */
    int32 expire; /* How long before the slave servers "give up" on looking
                   at data from the master server when the master server
                   dies */
    uint32 minimum; /* Default TTL for all RRs in the zone */
    } rr_soa;

/* MX: RFC1035 section 3.3.9 */
typedef struct {
    int16 preference; /* Lower preference MXs are tried before higher
                         preference MXs */
    js_string *exchange; /* Domain-name style data, the actual mail
                            exchanger */
    } rr_mx;

/* The TXT record is a single RFC1035-style character-string */
#define rr_txt *js_string;

/* The various error codes we place in the RCODE section of the header */
#define FORMAT_ERROR 1
#define SERVER_FAIL 2
#define NXDOMAIN_RCODE 3
#define NOT_IMPLEMENTED 4
#define REFUSED 5

/* The longest RRs which we allow to exist in csv1 zone files.
   Warning: If you make this longer, then there is a significant
   risk that the record will be longer than the 512 bytes allowed
   in a DNS packet.  MaraDNS does not current support DNS over TCP.
*/

#define MAX_RECORD_LENGTH 425

#endif /* MARADNSH_DEFINED */