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