djbdnscurve6 53
djbdnscurve6
Loading...
Searching...
No Matches
query.c
Go to the documentation of this file.
1#include "error.h"
2#include "roots.h"
3#include "log.h"
4#include "case.h"
5#include "sipcache.h"
6#include "byte.h"
7#include "dns.h"
8#include "uint_t.h"
9#include "dd.h"
10#include "alloc.h"
11#include "response.h"
12#include "query.h"
13#include "ip.h"
14#include "curvedns.h"
15
16extern int flagusetxtformat;
17extern unsigned int flagedns0;
18
19static char secretkey[KEY_LEN];
20static char publickey[KEY_LEN];
21
22void query_init(void)
23{
24 int k;
25
26 /* called after droproot(), can't use crypto_box_keypair (depends on /dev/urandom) */
27 for (k = 0; k < KEY_LEN; ++k)
28 secretkey[k] = dns_random(256);
29 crypto_scalarmult_base((unsigned char *) publickey,(unsigned char *) secretkey);
30
31}
32
33static int flagforwardonly = 0;
34
36{
37 flagforwardonly = 1;
38}
39
40static void cachegeneric(const char type[2],const char *d,const char *data,unsigned int datalen,uint32 ttl)
41{
42 unsigned int len;
43 char key[257];
44
46 if (len > FQDN_LEN) return;
47
48 byte_copy(key,2,type);
49 byte_copy(key + 2,len,d);
50 case_lowerb(key + 2,len);
51
52 cache_set(key,len + 2,data,datalen,ttl);
53}
54
55static char save_buf[8192];
56static unsigned int save_len;
57static unsigned int save_ok;
58
59static void save_start(void)
60{
61 save_len = 0;
62 save_ok = 1;
63}
64
65static void save_data(const char *buf,unsigned int len)
66{
67 if (!save_ok) return;
68 if (len > (sizeof(save_buf)) - save_len) { save_ok = 0; return; }
69 byte_copy(save_buf + save_len,len,buf);
70 save_len += len;
71}
72
73static void save_finish(const char type[2],const char *d,uint32 ttl)
74{
75 if (!save_ok) return;
76 cachegeneric(type,d,save_buf,save_len,ttl);
77}
78
79static int typematch(const char rtype[2],const char qtype[2])
80{
81 return byte_equal(qtype,2,rtype) || byte_equal(qtype,2,DNS_T_ANY);
82}
83
84static uint32 ttlget(char buf[4])
85{
86 uint32 ttl;
87
88 uint32_unpack_big(buf,&ttl);
89 if (ttl > 1000000000) return 0;
90 if (ttl > 604800) return 604800;
91 return ttl;
92}
93
94static void cleanup(struct query *z)
95{
96 int j;
97 int k;
98
99 dns_transmit_free(&z->dt);
100 for (j = 0; j < QUERY_MAXALIAS; ++j)
101 dns_domain_free(&z->alias[j]);
102 for (j = 0; j < QUERY_MAXLEVEL; ++j) {
103 dns_domain_free(&z->name[j]);
104 for (k = 0; k < QUERY_MAXNS; ++k)
105 dns_domain_free(&z->ns[j][k]);
106 }
107}
108
109static int rqa(struct query *z)
110{
111 int i;
112
113 for (i = QUERY_MAXALIAS - 1; i >= 0; --i)
114 if (z->alias[i]) {
115 if (!response_query(z->alias[i],z->type,z->class)) return 0;
116 while (i > 0) {
117 if (!response_cname(z->alias[i],z->alias[i - 1],z->aliasttl[i])) return 0;
118 --i;
119 }
120 if (!response_cname(z->alias[0],z->name[0],z->aliasttl[0])) return 0;
121 return 1;
122 }
123
124 if (!response_query(z->name[0],z->type,z->class)) return 0;
125 return 1;
126}
127
128static int globalip(char *d,char ip[16])
129{
130 if (dns_domain_equal(d,"\014ip6-loopback\0")) {
131 byte_copy(ip,16,IP6_LOOPBACK_OCTAL);
132 return 1;
133 }
134 if (dns_domain_equal(d,"\014ip4-loopback\0")) {
135 byte_copy(ip,12,V4mappedprefix);
136 byte_copy(ip + 12,4,IP4_LOOPBACK_OCTAL);
137 return 1;
138 }
139
140 /* Domain names may look like IPv4 addresses: 1.2.3.com; not for IPv6 */
141
142 if (dd4(d,"",ip) == 4) return 1;
143
144 return 0;
145}
146
147static char *t1 = 0;
148static char *t2 = 0;
149static char *t3 = 0;
150static char *cname = 0;
151static char *referral = 0;
152static unsigned int *records = 0;
153
154static int smaller(char *buf,unsigned int len,unsigned int pos1,unsigned int pos2)
155{
156 char header1[12];
157 char header2[12];
158 int r;
159 unsigned int len1;
160 unsigned int len2;
161
162 pos1 = dns_packet_getname(buf,len,pos1,&t1);
163 dns_packet_copy(buf,len,pos1,header1,10);
164 pos2 = dns_packet_getname(buf,len,pos2,&t2);
165 dns_packet_copy(buf,len,pos2,header2,10);
166
167 r = byte_diff(header1,4,header2);
168 if (r < 0) return 1;
169 if (r > 0) return 0;
170
171 len1 = dns_domain_length(t1);
172 len2 = dns_domain_length(t2);
173 if (len1 < len2) return 1;
174 if (len1 > len2) return 0;
175
176 r = case_diffb(t1,len1,t2);
177 if (r < 0) return 1;
178 if (r > 0) return 0;
179
180 if (pos1 < pos2) return 1;
181 return 0;
182}
183
184static int doit(struct query *z,int state)
185{
186 char key[257];
187 char *cached;
188 unsigned int cachedlen;
189 char *buf;
190 unsigned int len;
191 const char *whichserver;
192 char *whichkey;
193 char header[24];
194 char addr[16];
195 char misc[20];
196 char pubkey[KEY_LEN];
197 int flaghaskey;
198 int flagns;
199 int flagtx;
200 unsigned int rcode;
201 unsigned int posanswers;
202 uint16 numanswers;
203 unsigned int posauthority;
204 uint16 numauthority;
205 uint16 numglue;
206 unsigned int pos;
207 unsigned int pos2;
208 uint16 datalen;
209 char *control;
210 char *d;
211 const char *dtype;
212 unsigned int dlen;
213 int flagout;
214 int flagcname;
215 int flagreferral;
216 int flagsoa;
217 int flagedns;
218 const char *cnskey;
219 uint32 ttl;
220 uint32 soattl;
221 uint32 cachettl;
222 uint32 cnamettl;
223 int i;
224 int j;
225 int k;
226 int p;
227 int q;
228
229 errno = EIO;
230 if (state == 1) goto HAVEPACKET;
231 if (state == -1) {
232 log_servfail(z->name[z->level]);
233 goto SERVFAIL;
234 }
235
236
237 NEWNAME:
238 if (++z->loop == QUERY_MAXLOOP) goto DIE;
239 d = z->name[z->level];
240 dtype = z->level ? (z->ipv6[z->level] ? DNS_T_AAAA : DNS_T_A) : z->type;
242
243 if (globalip(d,misc)) {
244 if (z->level) {
245 flagns = cns_addns(z,misc,0,0); /* new; ok */
246 if (flagns) log_servflag(addr,flagns);
247 goto LOWERLEVEL;
248 }
249 if (!rqa(z)) goto DIE;
250 if (typematch(DNS_T_A,dtype)) {
251 if (!response_rstart(d,DNS_T_A,MAX_TTL)) goto DIE;
252 if (!response_addbytes(misc,4)) goto DIE;
254 }
255 if (typematch(DNS_T_AAAA,dtype)) {
256 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
257 if (!response_addbytes(misc,16)) goto DIE;
259 }
260 cleanup(z);
261 return 1;
262 }
263
264 /* common localhost and loopback handling (query.h) */
265
266 if (dns_domain_equal(d,"\011localhost\0") ||
267 dns_domain_equal(d,"\010loopback\0")) {
268 if (z->level) goto LOWERLEVEL;
269 if (!rqa(z)) goto DIE;
270 if (typematch(DNS_T_A,dtype)) {
271 if (!response_rstart(d,DNS_T_A,MAX_TTL)) goto DIE;
272 if (!response_addbytes(IP4_LOOPBACK_OCTAL,4)) goto DIE;
274 }
275 if (typematch(DNS_T_AAAA,dtype)) {
276 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
277 if (!response_addbytes(IP6_LOOPBACK_OCTAL,16)) goto DIE;
279 }
280 cleanup(z);
281 return 1;
282 }
283
284 /* IPv6 well-known names (query.h) RFC 4291 */
285
288 if (z->level) goto LOWERLEVEL;
289 if (!rqa(z)) goto DIE;
290 if (typematch(DNS_T_PTR,dtype)) {
291 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
292 if (!response_addname("\014ip6-loopback\0")) goto DIE;
294 }
295 cleanup(z);
296 return 1;
297 }
298
299 if (dns_domain_equal(d,IP6_LOCALNET_ARPA)) { /* unspecified IPv6 */
300 if (z->level) goto LOWERLEVEL;
301 if (!rqa(z)) goto DIE;
302 if (typematch(DNS_T_PTR,dtype)) {
303 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
304 if (!response_addname("\014ip6-localnet\0")) goto DIE;
306 }
307 cleanup(z);
308 return 1;
309 }
310
312 if (z->level) goto LOWERLEVEL;
313 if (!rqa(z)) goto DIE;
314 if (typematch(DNS_T_PTR,dtype)) {
315 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
316 if (!response_addname("\017ip6-mcastprefix\0")) goto DIE;
318 }
319 cleanup(z);
320 return 1;
321 }
322
324 if (z->level) goto LOWERLEVEL;
325 if (!rqa(z)) goto DIE;
326 if (typematch(DNS_T_PTR,dtype)) {
327 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
328 if (!response_addname("\016ip6-allnodes\0")) goto DIE;
330 }
331 cleanup(z);
332 return 1;
333 }
334
336 if (z->level) goto LOWERLEVEL;
337 if (!rqa(z)) goto DIE;
338 if (typematch(DNS_T_PTR,dtype)) {
339 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
340 if (!response_addname("\016ip6-allrouters\0")) goto DIE;
342 }
343 cleanup(z);
344 return 1;
345 }
346
347 if (dns_domain_equal(d,"\015ip6-localhost\0") ||
348 dns_domain_equal(d,"\014ip6-loopback\0")) {
349 if (z->level) goto LOWERLEVEL;
350 if (!rqa(z)) goto DIE;
351 if (typematch(DNS_T_AAAA,dtype)) {
352 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
353 if (!response_addbytes(IP6_LOOPBACK_OCTAL,16)) goto DIE;
355 }
356 cleanup(z);
357 return 1;
358 }
359
360 if (dns_domain_equal(d,"\014ip6-localnet\0")) {
361 if (z->level) goto LOWERLEVEL;
362 if (!rqa(z)) goto DIE;
363 if (typematch(DNS_T_AAAA,dtype)) {
364 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
365 if (!response_addbytes(IP6_LOCALNET,16)) goto DIE;
367 }
368 cleanup(z);
369 return 1;
370 }
371
372 if (dns_domain_equal(d,"\017ip6-mcastprefix\0")) {
373 if (z->level) goto LOWERLEVEL;
374 if (!rqa(z)) goto DIE;
375 if (typematch(DNS_T_AAAA,dtype)) {
376 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
377 if (!response_addbytes(IP6_MULTICASTPFX_OCTAL,16)) goto DIE;
379 }
380 cleanup(z);
381 return 1;
382 }
383
384 if (dns_domain_equal(d,"\14ip6-allnodes\0")) {
385 if (z->level) goto LOWERLEVEL;
386 if (!rqa(z)) goto DIE;
387 if (typematch(DNS_T_AAAA,dtype)) {
388 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
389 if (!response_addbytes(IP6_ALLNODES_OCTAL,16)) goto DIE;
391 }
392 cleanup(z);
393 return 1;
394 }
395
396 if (dns_domain_equal(d,"\16ip6-allrouters\0")) {
397 if (z->level) goto LOWERLEVEL;
398 if (!rqa(z)) goto DIE;
399 if (typematch(DNS_T_AAAA,dtype)) {
400 if (!response_rstart(d,DNS_T_AAAA,MAX_TTL)) goto DIE;
401 if (!response_addbytes(IP6_ALLROUTERS_OCTAL,16)) goto DIE;
403 }
404 cleanup(z);
405 return 1;
406 }
407
408 /* IPv4 well-known names (query.h) */
409
411 if (z->level) goto LOWERLEVEL;
412 if (!rqa(z)) goto DIE;
413 if (typematch(DNS_T_PTR,dtype)) {
414 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
415 if (!response_addname("\014ip4-loopback\0")) goto DIE;
417 }
418 cleanup(z);
419 return 1;
420 }
421
423 if (z->level) goto LOWERLEVEL;
424 if (!rqa(z)) goto DIE;
425 if (typematch(DNS_T_PTR,dtype)) {
426 if (!response_rstart(d,DNS_T_PTR,MAX_TTL)) goto DIE;
427 if (!response_addname("\015ip4-localhost\0")) goto DIE;
429 }
430 cleanup(z);
431 log_stats();
432 return 1;
433 }
434
435 if (dns_domain_equal(d,"\014ip4-localnet\0")) {
436 if (z->level) goto LOWERLEVEL;
437 if (!rqa(z)) goto DIE;
438 if (typematch(DNS_T_A,dtype)) {
439 if (!response_rstart(d,DNS_T_A,MAX_TTL)) goto DIE;
440 if (!response_addbytes(IP4_LOCALNET,4)) goto DIE;
442 }
443 cleanup(z);
444 return 1;
445 }
446
447 if (dns_domain_equal(d,"\015ip4-localhost\0") ||
448 dns_domain_equal(d,"\014ip4-loopback\0")) {
449 if (z->level) goto LOWERLEVEL;
450 if (!rqa(z)) goto DIE;
451 if (typematch(DNS_T_A,dtype)) {
452 if (!response_rstart(d,DNS_T_A,MAX_TTL)) goto DIE;
453 if (!response_addbytes(IP4_LOOPBACK_OCTAL,4)) goto DIE;
455 }
456 cleanup(z);
457 return 1;
458 }
459
460 /* .onion TLD RFC 7686 */
461
462 if (dns_domain_suffix(d,"\05onion\0"))
463 goto NXDOMAIN;
464
465 /* Reverse lookup for locally assigned IPv6 addresses (FD00::/8) RFC 4193 */
466
467 if (typematch(DNS_T_PTR,dtype) &&
468 dns_domain_suffix(d,"\01d\01f\03ip6\04arpa\0") &&
469 roots_same(d,"\0") &&
470 !flagforwardonly) // the cache we'll ask might know a proper NS
471 goto NXDOMAIN;
472
473 /* special names done */
474
475 if (dlen <= FQDN_LEN) {
476 byte_copy(key,2,DNS_T_ANY);
477 byte_copy(key + 2,dlen,d);
478 case_lowerb(key + 2,dlen);
479 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
480 if (cached) {
482 goto NXDOMAIN;
483 }
484
485 byte_copy(key,2,DNS_T_CNAME);
486 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
487
488 if (cached && cachedlen) {
489 if (typematch(DNS_T_CNAME,dtype)) {
491 if (!rqa(z)) goto DIE;
492 if (!response_cname(z->name[0],cached,ttl)) goto DIE;
493 cleanup(z);
494 return 1;
495 }
496 log_cachedcname(d,cached);
497
498 if (!dns_domain_copy(&cname,cached)) goto DIE;
499 goto CNAME;
500 }
501
502 if (typematch(DNS_T_NS,dtype)) {
503 byte_copy(key,2,DNS_T_NS);
504 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
505 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
506 if (z->level) {
507 flaghaskey = cns_pubkey(d,pubkey);
508 flagns = cns_addns(z,cached,flaghaskey,pubkey); /* ok */
509 if (flagns) log_servflag(addr,flagns);
511 }
512 if (!rqa(z)) goto DIE;
513 pos = 0;
514 while ((pos = dns_packet_getname(cached,cachedlen,pos,&t2))) {
515 if (!response_rstart(d,DNS_T_NS,ttl)) goto DIE;
516 if (!response_addname(t2)) goto DIE;
518 }
519 cleanup(z);
520 return 1;
521 }
522 }
523
524 if (typematch(DNS_T_PTR,dtype)) {
525 byte_copy(key,2,DNS_T_PTR);
526 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
527 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
529 if (!rqa(z)) goto DIE;
530 pos = 0;
531 while ((pos = dns_packet_getname(cached,cachedlen,pos,&t2))) {
532 if (!response_rstart(d,DNS_T_PTR,ttl)) goto DIE;
533 if (!response_addname(t2)) goto DIE;
535 }
536 cleanup(z);
537 return 1;
538 }
539 }
540
541 if (typematch(DNS_T_MX,dtype)) {
542 byte_copy(key,2,DNS_T_MX);
543 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
544 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
546 if (!rqa(z)) goto DIE;
547 pos = 0;
548 while ((pos = dns_packet_copy(cached,cachedlen,pos,misc,2))) {
549 pos = dns_packet_getname(cached,cachedlen,pos,&t2);
550 if (!pos) break;
551 if (!response_rstart(d,DNS_T_MX,ttl)) goto DIE;
552 if (!response_addbytes(misc,2)) goto DIE;
553 if (!response_addname(t2)) goto DIE;
555 }
556 cleanup(z);
557 return 1;
558 }
559 }
560
561 if (typematch(DNS_T_A,dtype)) {
562 byte_copy(key,2,DNS_T_A);
563 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
564 /* if we were looking the A record up to find an NS, try IPv6 too */
565 if (cached && !cachedlen && z->level) {
566 z->ipv6[z->level] = 1;
567 goto NEWNAME;
568 }
569 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
570 if (z->level) {
571 flaghaskey = cns_pubkey(d,pubkey);
573 while (cachedlen >= 4) {
574 for (k = 0; k < QUERY_MAXIPLEN; k += 16)
575 if (byte_equal(z->servers[z->level - 1] + k,16,V6localnet)) {
576 byte_copy(z->servers[z->level - 1] + k,12,V4mappedprefix);
577 byte_copy(z->servers[z->level - 1] + k + 12,4,cached);
578 break;
579 }
580 byte_copy(addr,12,V4mappedprefix);
581 byte_copy(addr + 12,4,cached);
582 flagns = cns_addns(z,addr,flaghaskey,pubkey);
583 if (flagns) log_servflag(addr,flagns);
584 cached += 4;
585 cachedlen -= 4;
586 }
587 goto LOWERLEVEL;
588 }
589
591 if (!rqa(z)) goto DIE;
592 while (cachedlen >= 4) {
593 if (!response_rstart(d,DNS_T_A,ttl)) goto DIE;
594 if (!response_addbytes(cached,4)) goto DIE;
596 cached += 4;
597 cachedlen -= 4;
598 }
599 cleanup(z);
600 return 1;
601 }
602 }
603
604 if (typematch(DNS_T_AAAA,dtype)) {
605 byte_copy(key,2,DNS_T_AAAA);
606 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
607 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
608 if (z->level) {
609 flaghaskey = cns_pubkey(d,pubkey);
611 while (cachedlen >= 16) {
612 flagns = cns_addns(z,cached,flaghaskey,pubkey);
613 if (flagns) log_servflag(addr,flagns);
614 cached += 16;
615 cachedlen -= 16;
616 }
617 goto LOWERLEVEL;
618 }
619
621 if (!rqa(z)) goto DIE;
622 while (cachedlen >= 16) {
623 if (!response_rstart(d,DNS_T_AAAA,ttl)) goto DIE;
624 if (!response_addbytes(cached,16)) goto DIE;
626 cached += 16;
627 cachedlen -= 16;
628 }
629 cleanup(z);
630 return 1;
631 }
632 }
633
634 if (!typematch(DNS_T_ANY,dtype) && !typematch(DNS_T_AXFR,dtype) &&
635 !typematch(DNS_T_NS,dtype) && !typematch(DNS_T_PTR,dtype) &&
636 !typematch(DNS_T_A,dtype) && !typematch(DNS_T_AAAA,dtype) &&
637 !typematch(DNS_T_MX,dtype)) {
638 byte_copy(key,2,dtype);
639 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
640 if (cached && (cachedlen || byte_diff(dtype,2,DNS_T_ANY))) {
641 log_cachedanswer(d,dtype);
642 if (!rqa(z)) goto DIE;
643 while (cachedlen >= 2) {
644 uint16_unpack_big(cached,&datalen);
645 cached += 2;
646 cachedlen -= 2;
647 if (datalen > cachedlen) goto DIE;
648 if (!response_rstart(d,dtype,ttl)) goto DIE;
649 if (!response_addbytes(cached,datalen)) goto DIE;
651 cached += datalen;
652 cachedlen -= datalen;
653 }
654 cleanup(z);
655 return 1;
656 }
657 }
658 } /* end of dlen if */
659
660 for (;;) {
661 /* XXX: allow roots() to provide keys */
662 if (roots(z->servers[z->level],d)) {
663 z->flagnskeys[z->level] = 0;
664 for (j = 0; j < QUERY_MAXNS; ++j)
665 dns_domain_free(&z->ns[z->level][j]);
666 z->control[z->level] = d;
667 break;
668 }
669
670 if (!flagforwardonly && (z->level < 2))
671 if (dlen < FQDN_LEN) {
672 byte_copy(key,2,DNS_T_NS);
673 byte_copy(key + 2,dlen,d);
674 case_lowerb(key + 2,dlen);
675 cached = cache_get(key,dlen + 2,&cachedlen,&ttl);
676 if (cached && cachedlen) {
677 z->control[z->level] = d;
678 byte_zero(z->servers[z->level],QUERY_MAXIPLEN);
679 z->flagnskeys[z->level] = 0; /* XXX */
680 for (j = 0; j < QUERY_MAXNS; ++j)
681 dns_domain_free(&z->ns[z->level][j]);
682 pos = 0;
683 j = 0;
684 while ((pos = dns_packet_getname(cached,cachedlen,pos,&t1))) {
685 log_cachedns(d,t1);
686 if (j < QUERY_MAXNS)
687 if (!dns_domain_copy(&z->ns[z->level][j++],t1)) goto DIE;
688 }
689 break;
690 }
691 }
692
693 if (!*d) goto DIE;
694 j = 1 + (unsigned int) (unsigned char) *d;
695 dlen -= j;
696 d += j;
697 }
698
699
700 HAVENS:
701 for (j = 0; j < QUERY_MAXNS; ++j)
702 if (z->ns[z->level][j]) {
703 if (z->level + 1 < QUERY_MAXLEVEL) {
704 if (!dns_domain_copy(&z->name[z->level + 1],z->ns[z->level][j])) goto DIE;
705 dns_domain_free(&z->ns[z->level][j]);
706 ++z->level;
707 z->ipv6[z->level] = 0;
708 goto NEWNAME;
709 }
710 dns_domain_free(&z->ns[z->level][j]);
711 }
712
713 for (j = 0; j < QUERY_MAXIPLEN; j += 16)
714 if (byte_diff(z->servers[z->level] + j,16,V6localnet)) break;
715 if (j == QUERY_MAXIPLEN) goto SERVFAIL;
716
717 /* fetch DNSCurve key per NS and use it */
718
719 if (z->flagnskeys[z->level]) {
720 byte_copy(key,2,DNS_T_AXFR);
721 for (j = 0; j < QUERY_MAXIPLEN; j += 16)
722 if (byte_diff(z->servers[z->level] + j,16,V6localnet)) {
723 whichkey = z->keys[z->level] + 2 * j;
724 byte_copy(key + 2,KEY_LEN,whichkey);
725 cached = cache_get(key,KEY_LEN + 2,&cachedlen,&ttl);
726 if (cached && (cachedlen == KEY_LEN)) {
727 byte_copy(whichkey,KEY_LEN,cached);
728 continue;
729 }
730 crypto_box_beforenm((unsigned char *)whichkey,(const unsigned char *)whichkey,(const unsigned char *)secretkey);
731 cache_set(key,KEY_LEN + 2,whichkey,KEY_LEN,MAX_TTL);
732 }
733 }
734
735 cns_sortns(z->servers[z->level],z->keys[z->level],QUERY_MAXNS);
736 dtype = z->level ? DNS_T_A : z->type;
737 control = flagusetxtformat ? z->control[z->level] : 0;
738 cnskey = z->flagnskeys[z->level] ? z->keys[z->level] : 0;
739
740 /* evaluate flaged server information */
741
742 flagedns = flagedns0;
743 for (i = 0; i < QUERY_MAXNS; ++i)
744 if (z->ctx[z->level][i] == 'd') { flagedns = 0; break; } // veto for all NS on that level
745
746 /* enhanced logging */
747
748 flagtx = flagedns;
749 if (cnskey) { flagtx = 3; if (control) flagtx = 4; }
750 log_tx(z->name[z->level],dtype,z->control[z->level],z->servers[z->level],flagtx,z->level);
751
752 /* go for query */
753
754 const char qflags[2] = { flagforwardonly, flagedns };
755 if (cns_transmit_start(&z->dt,z->servers[z->level],qflags,z->name[z->level],\
756 dtype,z->localip,cnskey,publickey,control) < 0) goto DIE;
757
758 return 0;
759
760
761 LOWERLEVEL:
762 dns_domain_free(&z->name[z->level]);
763 for (j = 0; j < QUERY_MAXNS; ++j)
764 dns_domain_free(&z->ns[z->level][j]);
765 --z->level;
766 goto HAVENS;
767
768
769 HAVEPACKET:
770 if (++z->loop == QUERY_MAXLOOP) goto DIE;
771 buf = z->dt.packet;
772 len = z->dt.packetlen;
773
774 whichserver = z->dt.servers + 16 * z->dt.curserver;
775 control = z->control[z->level];
776 d = z->name[z->level];
777 /* dtype = z->level ? DNS_T_A : z->type; */
778 dtype = z->level ? (z->ipv6[z->level] ? DNS_T_AAAA : DNS_T_A) : z->type;
779
780 pos = dns_packet_copy(buf,len,0,header,12); if (!pos) goto DIE;
781 pos = dns_packet_skipname(buf,len,pos); if (!pos) goto DIE;
782 pos += 4;
783 posanswers = pos;
784
785 uint16_unpack_big(header + 6,&numanswers);
786 uint16_unpack_big(header + 8,&numauthority);
787 uint16_unpack_big(header + 10,&numglue);
788
789 rcode = header[3] & 15;
790 if (rcode && (rcode != 3)) goto DIE; /* impossible; see irrelevant() */
791
792 flagout = 0;
793 flagcname = 0;
794 flagreferral = 0;
795 flagsoa = 0;
796 soattl = 0;
797 cachettl = 0;
798 cnamettl = 0;
799
800 for (j = 0; j < numanswers; ++j) {
801 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
802 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
803
804 if (dns_domain_equal(t1,d))
805 if (byte_equal(header + 2,2,DNS_C_IN)) { /* should always be true */
806 if (typematch(header,dtype))
807 flagout = 1;
808 else if (typematch(header,DNS_T_CNAME)) {
809 if (!dns_packet_getname(buf,len,pos,&cname)) goto DIE;
810 flagcname = 1;
811 cnamettl = ttlget(header + 4);
812 }
813 }
814
815 uint16_unpack_big(header + 8,&datalen);
816 pos += datalen;
817 }
818 posauthority = pos;
819
820 for (j = 0; j < numauthority; ++j) {
821 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
822 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
823
824 if (typematch(header,DNS_T_SOA)) {
825 flagsoa = 1;
826 soattl = ttlget(header + 4);
827 if (soattl > 3600) soattl = 3600;
828 }
829 else if (typematch(header,DNS_T_NS)) {
830 flagreferral = 1;
831 if (!dns_domain_copy(&referral,t1)) goto DIE;
832 }
833
834 uint16_unpack_big(header + 8,&datalen);
835 pos += datalen;
836 }
837
838 /* JBP Negative cache patch and record in log */
839
840 if (flagsoa && (pos <= len)) {
841 cachettl = ttlget(buf + pos - 4);
842 if (soattl < cachettl) cachettl = soattl;
843 }
844
845 if (!flagcname && !rcode && !flagout && flagreferral && !flagsoa)
846 if (dns_domain_equal(referral,control) || !dns_domain_suffix(referral,control)) {
847 log_lame(whichserver,control,referral);
848 byte_zero((char *)whichserver,4);
849 goto HAVENS;
850 }
851
852 if (records) { alloc_free(records); records = 0; }
853 flagedns = flagedns0;
854
855 k = numanswers + numauthority + numglue;
856 records = (unsigned int *)alloc(k * sizeof(unsigned int));
857 if (!records) goto DIE;
858
859 pos = posanswers;
860 for (j = 0; j < k; ++j) {
861 records[j] = pos;
862 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
863 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
864 uint16_unpack_big(header + 8,&datalen);
865 pos += datalen;
866 }
867
868 i = j = k;
869 while (j > 1) {
870 if (i > 1) { --i; pos = records[i - 1]; }
871 else { pos = records[j - 1]; records[j - 1] = records[i - 1]; --j; }
872
873 q = i;
874 while ((p = q * 2) < j) {
875 if (!smaller(buf,len,records[p],records[p - 1])) ++p;
876 records[q - 1] = records[p - 1]; q = p;
877 }
878 if (p == j) {
879 records[q - 1] = records[p - 1]; q = p;
880 }
881 while ((q > i) && smaller(buf,len,records[(p = q/2) - 1],pos)) {
882 records[q - 1] = records[p - 1]; q = p;
883 }
884 records[q - 1] = pos;
885 }
886
887 i = 0;
888 while (i < k) {
889 char type[2];
890
891 pos = dns_packet_getname(buf,len,records[i],&t1); if (!pos) goto DIE;
892 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
893 ttl = ttlget(header + 4);
894
895 byte_copy(type,2,header);
896 if (byte_diff(header + 2,2,DNS_C_IN)) { ++i; continue; }
897
898 for (j = i + 1; j < k; ++j) {
899 pos = dns_packet_getname(buf,len,records[j],&t2); if (!pos) goto DIE;
900 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
901 if (!dns_domain_equal(t1,t2)) break;
902 if (byte_diff(header,2,type)) break;
903 if (byte_diff(header + 2,2,DNS_C_IN)) break;
904 }
905
906 if (!dns_domain_suffix(t1,control)) { i = j; continue; }
907 if (!roots_same(t1,control)) { i = j; continue; }
908
909 if (byte_equal(type,2,DNS_T_ANY))
910 ;
911 else if (byte_equal(type,2,DNS_T_AXFR))
912 ;
913 else if (byte_equal(type,2,DNS_T_SOA)) {
914 while (i < j) {
915 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
916 pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
917 pos = dns_packet_getname(buf,len,pos,&t3); if (!pos) goto DIE;
918 pos = dns_packet_copy(buf,len,pos,misc,20); if (!pos) goto DIE;
919 if (records[i] < posauthority)
920 log_rrsoa(whichserver,t1,t2,t3,misc,ttl);
921 ++i;
922 }
923 }
924 else if (byte_equal(type,2,DNS_T_CNAME)) {
925 pos = dns_packet_skipname(buf,len,records[j - 1]); if (!pos) goto DIE;
926 pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
927 log_rrcname(whichserver,t1,t2,ttl);
928 cachegeneric(DNS_T_CNAME,t1,t2,dns_domain_length(t2),ttl);
929 }
930 else if (byte_equal(type,2,DNS_T_PTR)) {
931 save_start();
932 while (i < j) {
933 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
934 pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
935 log_rrptr(whichserver,t1,t2,ttl);
936 save_data(t2,dns_domain_length(t2));
937 ++i;
938 }
939 save_finish(DNS_T_PTR,t1,ttl);
940 }
941 else if (byte_equal(type,2,DNS_T_NS)) {
942 save_start();
943 while (i < j) {
944 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
945 pos = dns_packet_getname(buf,len,pos + 10,&t2); if (!pos) goto DIE;
946 log_rrns(whichserver,t1,t2,ttl);
947 save_data(t2,dns_domain_length(t2));
948 ++i;
949 }
950 save_finish(DNS_T_NS,t1,ttl);
951 }
952 else if (byte_equal(type,2,DNS_T_MX)) {
953 save_start();
954 while (i < j) {
955 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
956 pos = dns_packet_copy(buf,len,pos + 10,misc,2); if (!pos) goto DIE;
957 pos = dns_packet_getname(buf,len,pos,&t2); if (!pos) goto DIE;
958 log_rrmx(whichserver,t1,t2,misc,ttl);
959 save_data(misc,2);
960 save_data(t2,dns_domain_length(t2));
961 ++i;
962 }
963 save_finish(DNS_T_MX,t1,ttl);
964 }
965 else if (byte_equal(type,2,DNS_T_A)) {
966 save_start();
967 while (i < j) {
968 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
969 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
970 if (byte_equal(header + 8,2,"\0\4")) {
971 pos = dns_packet_copy(buf,len,pos,header,4); if (!pos) goto DIE;
972 save_data(header,4);
973 log_rr(whichserver,t1,DNS_T_A,header,4,ttl);
974 }
975 ++i;
976 }
977 save_finish(DNS_T_A,t1,ttl);
978 }
979 else if (byte_equal(type,2,DNS_T_AAAA)) {
980 save_start();
981 while (i < j) {
982 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
983 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
984 if (byte_equal(header + 8,2,"\0\20")) {
985 pos = dns_packet_copy(buf,len,pos,header,16); if (!pos) goto DIE;
986 save_data(header,16);
987 log_rr(whichserver,t1,DNS_T_AAAA,header,16,ttl);
988 }
989 ++i;
990 }
991 save_finish(DNS_T_AAAA,t1,ttl);
992 }
993 else {
994 save_start();
995 while (i < j) {
996 pos = dns_packet_skipname(buf,len,records[i]); if (!pos) goto DIE;
997 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
998 uint16_unpack_big(header + 8,&datalen);
999 if (datalen > len - pos) goto DIE;
1000 save_data(header + 8,2);
1001 save_data(buf + pos,datalen);
1002 log_rr(whichserver,t1,type,buf + pos,datalen,ttl);
1003 ++i;
1004 }
1005 save_finish(type,t1,ttl);
1006 }
1007
1008 i = j;
1009 }
1010
1011 alloc_free(records); records = 0;
1012
1013 /* Original DJB's CNAME handling instead of JBP;
1014 ** the latter does not work well under all given circumstances */
1015
1016 if (flagcname) {
1017 ttl = cnamettl;
1018 CNAME:
1019 if (!z->level) {
1020 if (z->alias[QUERY_MAXALIAS - 1]) goto DIE;
1021 for (j = QUERY_MAXALIAS - 1; j > 0; --j)
1022 z->alias[j] = z->alias[j - 1];
1023
1024 for (j = QUERY_MAXALIAS - 1; j > 0; --j)
1025 z->aliasttl[j] = z->aliasttl[j - 1];
1026
1027 z->alias[0] = z->name[0];
1028 z->aliasttl[0] = ttl;
1029 z->name[0] = 0;
1030 }
1031 if (!dns_domain_copy(&z->name[z->level],cname)) goto DIE;
1032 goto NEWNAME;
1033 }
1034
1035 if (rcode == 3) {
1036 log_nxdomain(whichserver,d,cachettl);
1037 cachegeneric(DNS_T_ANY,d,"",0,cachettl);
1038
1039 NXDOMAIN:
1040 if (z->level) goto LOWERLEVEL;
1041 if (!rqa(z)) goto DIE;
1043 cleanup(z);
1044 return 1;
1045 }
1046
1047 /* Don't save empty RRSets for those types that we use as special markers */
1048
1049 if (!flagout && flagsoa)
1050 if (byte_diff(DNS_T_ANY,2,dtype))
1051 if (byte_diff(DNS_T_AXFR,2,dtype)) {
1052 save_start();
1053 save_finish(dtype,d,soattl);
1054 log_nodata(whichserver,d,dtype,soattl);
1055 if (z->level && !byte_diff(DNS_T_A,2,dtype)) {
1056 d = z->name[z->level];
1057 z->ipv6[z->level] = 1;
1058 goto NEWNAME; /* retry, will ask for AAAA next */
1059 }
1060 }
1061
1062 log_stats();
1063
1064 if (flagout || flagsoa || !flagreferral) {
1065 if (z->level) {
1066 flaghaskey = cns_pubkey(d,pubkey);
1067 pos = posanswers;
1068 for (j = 0; j < numanswers; ++j) {
1069 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
1070 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1071 uint16_unpack_big(header + 8,&datalen);
1072 if (dns_domain_equal(t1,d)) {
1073 if (typematch(header,DNS_T_A))
1074 if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1075 if (datalen == 4) {
1076 if (!dns_packet_copy(buf,len,pos,misc,4)) goto DIE;
1077 byte_copy(addr,12,V4mappedprefix);
1078 byte_copy(addr + 12,4,misc);
1079 flagns = cns_addns(z,addr,flaghaskey,pubkey);
1080 if (flagns) log_servflag(addr,flagns);
1081 }
1082 if (typematch(header,DNS_T_AAAA))
1083 if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1084 if (datalen == 16) {
1085 if (!dns_packet_copy(buf,len,pos,misc,16)) goto DIE;
1086 flagns = cns_addns(z,misc,flaghaskey,pubkey);
1087 if (flagns) log_servflag(addr,flagns);
1088 }
1089 }
1090 pos += datalen;
1091 }
1092 goto LOWERLEVEL;
1093 }
1094
1095 if (!rqa(z)) goto DIE;
1096
1097 pos = posanswers;
1098 for (j = 0; j < numanswers; ++j) {
1099 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
1100 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1101 ttl = ttlget(header + 4);
1102 uint16_unpack_big(header + 8,&datalen);
1103 if (dns_domain_equal(t1,d))
1104 if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1105 if (typematch(header,dtype)) {
1106 if (!response_rstart(t1,header,ttl)) goto DIE;
1107
1108 if (typematch(header,DNS_T_NS) || typematch(header,DNS_T_CNAME) || typematch(header,DNS_T_PTR)) {
1109 if (!dns_packet_getname(buf,len,pos,&t2)) goto DIE;
1110 if (!response_addname(t2)) goto DIE;
1111 }
1112 else if (typematch(header,DNS_T_MX)) {
1113 pos2 = dns_packet_copy(buf,len,pos,misc,2); if (!pos2) goto DIE;
1114 if (!response_addbytes(misc,2)) goto DIE;
1115 if (!dns_packet_getname(buf,len,pos2,&t2)) goto DIE;
1116 if (!response_addname(t2)) goto DIE;
1117 }
1118 else if (typematch(header,DNS_T_SOA)) {
1119 pos2 = dns_packet_getname(buf,len,pos,&t2); if (!pos2) goto DIE;
1120 if (!response_addname(t2)) goto DIE;
1121 pos2 = dns_packet_getname(buf,len,pos2,&t3); if (!pos2) goto DIE;
1122 if (!response_addname(t3)) goto DIE;
1123 pos2 = dns_packet_copy(buf,len,pos2,misc,20); if (!pos2) goto DIE;
1124 if (!response_addbytes(misc,20)) goto DIE;
1125 }
1126 else {
1127 if (pos + datalen > len) goto DIE;
1128 if (!response_addbytes(buf + pos,datalen)) goto DIE;
1129 }
1130
1132 }
1133 pos += datalen;
1134 }
1135
1136 cleanup(z);
1137 return 1;
1138 }
1139
1140
1141 if (!dns_domain_suffix(d,referral)) goto DIE;
1142
1143 /* In strict "forwardonly" mode, we don't, as the manual states,
1144 ** contact a chain of servers according to "NS" resource records.
1145 ** We don't obey any referral responses, therefore. Instead, we
1146 ** eliminate the server from the list and try the next one. */
1147
1148 if (flagforwardonly) {
1149 log_ignore_referral(whichserver,control,referral);
1150 byte_zero((char *)whichserver,16);
1151 goto HAVENS;
1152 }
1153
1154 control = d + dns_domain_suffixpos(d,referral);
1155 z->control[z->level] = control;
1156 z->byzg = numauthority*100 + numglue;
1157 z->flagnskeys[z->level] = 0; /* XXX */
1158 byte_zero(z->servers[z->level],QUERY_MAXIPLEN);
1159 for (j = 0; j < QUERY_MAXNS; ++j)
1160 dns_domain_free(&z->ns[z->level][j]);
1161
1162 k = 0;
1163 pos = posauthority;
1164 for (j = 0; j < numauthority; ++j) {
1165 pos = dns_packet_getname(buf,len,pos,&t1); if (!pos) goto DIE;
1166 pos = dns_packet_copy(buf,len,pos,header,10); if (!pos) goto DIE;
1167 uint16_unpack_big(header + 8,&datalen);
1168 if (dns_domain_equal(referral,t1)) /* should always be true */
1169 if (typematch(header,DNS_T_NS)) /* should always be true */
1170 if (byte_equal(header + 2,2,DNS_C_IN)) /* should always be true */
1171 if (k < QUERY_MAXNS)
1172 if (!dns_packet_getname(buf,len,pos,&z->ns[z->level][k++])) goto DIE;
1173 pos += datalen;
1174 }
1175
1176 goto HAVENS;
1177
1178
1179 SERVFAIL:
1180 if (z->level) goto LOWERLEVEL;
1181 if (!rqa(z)) goto DIE;
1183 cleanup(z);
1184 return 1;
1185
1186
1187 DIE:
1188 cleanup(z);
1189 if (records) { alloc_free(records); records = 0; }
1190 return DNS_ERR;
1191}
1192
1193int query_start(struct query *z,char *dn,char type[2],char class[2],char localip[16],uint32 scope_id)
1194{
1195 if (byte_equal(type,2,DNS_T_AXFR)) { errno = EPERM; return DNS_ERR; }
1196
1197 cleanup(z);
1198 z->level = 0;
1199 z->loop = 0;
1200
1201 if (!dns_domain_copy(&z->name[0],dn)) return DNS_ERR;
1202 byte_copy(z->type,2,type);
1203 byte_copy(z->class,2,class);
1204 byte_copy(z->localip,16,localip);
1205 z->scope_id = scope_id;
1206 z->ipv6[0] = 0;
1207
1208 return doit(z,0);
1209}
1210
1211int query_get(struct query *z,iopause_fd *x,struct taia *stamp)
1212{
1213 switch (dns_transmit_get(&z->dt,x,stamp)) {
1214 case 1:
1215 return doit(z,1);
1216 case -1: case -2: case -3:
1217 return doit(z,-1);
1218 }
1219 return 0;
1220}
1221
1222void query_io(struct query *z,iopause_fd *x,struct taia *deadline)
1223{
1224 dns_transmit_io(&z->dt,x,deadline);
1225}
unsigned int doit(char *buf, unsigned int len, unsigned int pos)
Definition: axfr-get.c:131
char data[32767]
Definition: axfrdns.c:133
char ip[16]
Definition: axfrdns.c:128
uint16 len
Definition: axfrdns.c:322
char buf[MSGSIZE]
Definition: axfrdns.c:321
uint32 dlen
Definition: axfrdns.c:134
#define crypto_box_beforenm
Definition: curve.h:12
#define crypto_scalarmult_base
Definition: curve.h:10
#define KEY_LEN
int cns_transmit_start(struct dns_transmit *d, const char servers[QUERY_MAXIPLEN], char qflags[2], const char *q, const char qtype[2], const char localip[16], const char keys[QUERY_MAXNS *KEY_LEN], const char pubkey[KEY_LEN], const char *suffix)
Definition: curvedns.c:286
void cns_sortns(char *s, char *t, unsigned int n)
Definition: curvedns.c:222
int cns_pubkey(const char *dn, char *key)
Definition: curvedns.c:208
int cns_addns(struct query *z, const char *addr, int flagnskey, const char *key)
Definition: curvedns.c:241
int dd4(const char *q, const char *base, char ip[4])
Definition: dd.c:7
#define DNS_ERR
Definition: dns.h:41
#define DNS_T_A
Definition: dns.h:65
#define QUERY_MAXIPLEN
Definition: dns.h:55
#define DNS_T_AXFR
Definition: dns.h:95
#define DNS_C_IN
Definition: dns.h:62
#define DNS_T_ANY
Definition: dns.h:96
#define MAX_TTL
Definition: dns.h:51
#define DNS_T_PTR
Definition: dns.h:69
#define DNS_T_SOA
Definition: dns.h:68
#define DNS_T_NS
Definition: dns.h:66
#define QUERY_MAXNS
Definition: dns.h:54
#define DNS_T_CNAME
Definition: dns.h:67
#define DNS_T_AAAA
Definition: dns.h:76
#define DNS_T_MX
Definition: dns.h:71
#define FQDN_LEN
Definition: dns.h:57
int dns_domain_equal(const char *dn1, const char *dn2)
Definition: dns_domain.c:39
unsigned int dns_domain_length(const char *dn)
Definition: dns_domain.c:6
int dns_domain_copy(char **out, const char *in)
Definition: dns_domain.c:25
int dns_domain_suffix(const char *big, const char *little)
Definition: dns_domain.c:50
void dns_domain_free(char **out)
Definition: dns_domain.c:17
unsigned int dns_domain_suffixpos(const char *big, const char *little)
Definition: dns_domain.c:62
unsigned int dns_packet_getname(const char *buf, unsigned int len, unsigned int pos, char **d)
Definition: dns_packet.c:35
unsigned int dns_packet_copy(const char *buf, unsigned int len, unsigned int pos, char *out, unsigned int outlen)
Definition: dns_packet.c:8
unsigned int dns_packet_skipname(const char *buf, unsigned int len, unsigned int pos)
Definition: dns_packet.c:18
unsigned int dns_random(unsigned int n)
Definition: dns_random.c:55
void dns_transmit_io(struct dns_transmit *d, iopause_fd *x, struct taia *deadline)
Definition: dns_transmit.c:285
void dns_transmit_free(struct dns_transmit *d)
Definition: dns_transmit.c:95
int dns_transmit_get(struct dns_transmit *d, const iopause_fd *x, const struct taia *when)
Definition: dns_transmit.c:302
struct line * x
char type[2]
Definition: dnsq.c:60
void d(const char *home, const char *subdir, int uid, int gid, int mode)
void z(char *home, char *subdir, char *file, int len, int uid, int gid, int mode)
Definition: install.c:88
void p(char *home, char *fifo, int uid, int gid, int mode)
Definition: instcheck.c:45
void log_rrptr(const char[16], const char *, const char *, unsigned int)
Definition: log.c:293
void log_rr(const char[16], const char *, const char[2], const char *, unsigned int, unsigned int)
Definition: log.c:261
void log_lame(const char[16], const char *, const char *)
Definition: log.c:234
void log_tx(const char *, const char[2], const char *, char[QUERY_MAXIPLEN], int, unsigned int)
Definition: log.c:167
void log_rrmx(const char[16], const char *, const char *, const char[2], unsigned int)
Definition: log.c:301
void log_ignore_referral(const char[16], const char *, const char *)
Definition: log.c:144
void log_servfail(const char *)
Definition: log.c:252
void log_servflag(const char[16], int)
Definition: log.c:241
void log_nxdomain(const char[16], const char *, unsigned int)
Definition: log.c:220
void log_nodata(const char[16], const char *, const char[2], unsigned int)
Definition: log.c:227
void log_stats(void)
Definition: log.c:327
void log_rrns(const char[16], const char *, const char *, unsigned int)
Definition: log.c:278
void log_cachedcname(const char *, const char *)
Definition: log.c:202
void log_cachedanswer(const char *, const char[2])
Definition: log.c:195
void log_rrsoa(const char[16], const char *, const char *, const char *, const char[20], unsigned int)
Definition: log.c:312
void log_cachednxdomain(const char *)
Definition: log.c:214
void log_cachedns(const char *, const char *)
Definition: log.c:208
void log_rrcname(const char[16], const char *, const char *, unsigned int)
Definition: log.c:285
void query_init(void)
Definition: query.c:22
void query_io(struct query *z, iopause_fd *x, struct taia *deadline)
Definition: query.c:1222
unsigned int flagedns0
Definition: axfrdns.c:28
int query_get(struct query *z, iopause_fd *x, struct taia *stamp)
Definition: query.c:1211
int flagusetxtformat
Definition: curvedns.c:20
void query_forwardonly(void)
Definition: query.c:35
int query_start(struct query *z, char *dn, char type[2], char class[2], char localip[16], uint32 scope_id)
Definition: query.c:1193
#define QUERY_MAXALIAS
Definition: query.h:10
#define IP6_LOOPBACK_OCTAL
Definition: query.h:30
#define IP6_ALLROUTERS_OCTAL
Definition: query.h:38
#define IP6_MULTICASTPFX_OCTAL
Definition: query.h:34
#define IP6_MULTICAST_ARPA
Definition: query.h:23
#define QUERY_MAXLEVEL
Definition: query.h:9
#define IP6_ALLNODESMULTICAST_ARPA
Definition: query.h:25
#define QUERY_MAXLOOP
Definition: query.h:11
#define IP4_LOOPBACK_ARPA
Definition: query.h:46
#define IP4_LOCALHOST_ARPA
Definition: query.h:44
#define IP6_LOCALHOST_ARPA
Definition: query.h:58
#define IP6_LOOPBACK_ARPA
Definition: query.h:19
#define IP6_LOCALNET
Definition: query.h:56
#define IP4_LOOPBACK_OCTAL
Definition: query.h:49
#define IP6_ALLROUTERSMULTICAST_ARPA
Definition: query.h:27
#define IP6_LOCALNET_ARPA
Definition: query.h:21
#define IP4_LOCALNET
Definition: query.h:55
#define IP6_ALLNODES_OCTAL
Definition: query.h:36
int response_rstart(const char *, const char[2], uint32)
Definition: response.c:75
int response_addname(const char *)
Definition: response.c:25
void response_rfinish(int)
Definition: response.c:89
int response_addbytes(const char *, unsigned int)
Definition: response.c:17
int response_cname(const char *, const char *, uint32)
Definition: response.c:95
int response_query(const char *, const char[2], const char[2])
Definition: response.c:54
#define RESPONSE_ANSWER
Definition: response.h:23
void response_nxdomain(void)
Definition: response.c:103
void response_servfail(void)
Definition: response.c:109
int roots(char[QUERY_MAXIPLEN], char *)
Definition: roots.c:53
int roots_same(char *, char *)
Definition: roots.c:62
char * cache_get(const char *, unsigned int, unsigned int *, uint32 *)
Definition: sipcache.c:73
void cache_set(const char *, unsigned int, const char *, unsigned int, uint32)
Definition: sipcache.c:119
Definition: query.h:60