16 static int flagforwardonly
= 0;
18 void query_forwardonly(void)
23 static void cachegeneric(const char type
[2],const char *d
,const char *data
,unsigned int datalen
,uint32 ttl
)
28 len
= dns_domain_length(d
);
29 if (len
> 255) return;
31 byte_copy(key
,2,type
);
32 byte_copy(key
+ 2,len
,d
);
33 case_lowerb(key
+ 2,len
);
35 cache_set(key
,len
+ 2,data
,datalen
,ttl
);
38 static char save_buf
[8192];
39 static unsigned int save_len
;
40 static unsigned int save_ok
;
42 static void save_start(void)
48 static void save_data(const char *buf
,unsigned int len
)
51 if (len
> (sizeof save_buf
) - save_len
) { save_ok
= 0; return; }
52 byte_copy(save_buf
+ save_len
,len
,buf
);
56 static void save_finish(const char type
[2],const char *d
,uint32 ttl
)
59 cachegeneric(type
,d
,save_buf
,save_len
,ttl
);
63 static int typematch(const char rtype
[2],const char qtype
[2])
65 return byte_equal(qtype
,2,rtype
) || byte_equal(qtype
,2,DNS_T_ANY
);
68 static uint32
ttlget(char buf
[4])
72 uint32_unpack_big(buf
,&ttl
);
73 if (ttl
> 1000000000) return 0;
74 if (ttl
> 604800) return 604800;
79 static void cleanup(struct query
*z
)
84 dns_transmit_free(&z
->dt
);
85 for (j
= 0;j
< QUERY_MAXALIAS
;++j
)
86 dns_domain_free(&z
->alias
[j
]);
87 for (j
= 0;j
< QUERY_MAXLEVEL
;++j
) {
88 dns_domain_free(&z
->name
[j
]);
89 for (k
= 0;k
< QUERY_MAXNS
;++k
)
90 dns_domain_free(&z
->ns
[j
][k
]);
94 static int rqa(struct query
*z
)
98 for (i
= QUERY_MAXALIAS
- 1;i
>= 0;--i
)
100 if (!response_query(z
->alias
[i
],z
->type
,z
->class)) return 0;
102 if (!response_cname(z
->alias
[i
],z
->alias
[i
- 1],z
->aliasttl
[i
])) return 0;
105 if (!response_cname(z
->alias
[0],z
->name
[0],z
->aliasttl
[0])) return 0;
109 if (!response_query(z
->name
[0],z
->type
,z
->class)) return 0;
113 static int globalip(char *d
,char ip
[4])
115 if (dns_domain_equal(d
,"\011localhost\0")) {
116 byte_copy(ip
,4,"\177\0\0\1");
119 if (dd(d
,"",ip
) == 4) return 1;
126 static char *cname
= 0;
127 static char *referral
= 0;
128 static unsigned int *records
= 0;
130 static int smaller(char *buf
,unsigned int len
,unsigned int pos1
,unsigned int pos2
)
138 pos1
= dns_packet_getname(buf
,len
,pos1
,&t1
);
139 dns_packet_copy(buf
,len
,pos1
,header1
,10);
140 pos2
= dns_packet_getname(buf
,len
,pos2
,&t2
);
141 dns_packet_copy(buf
,len
,pos2
,header2
,10);
143 r
= byte_diff(header1
,4,header2
);
147 len1
= dns_domain_length(t1
);
148 len2
= dns_domain_length(t2
);
149 if (len1
< len2
) return 1;
150 if (len1
> len2
) return 0;
152 r
= case_diffb(t1
,len1
,t2
);
156 if (pos1
< pos2
) return 1;
160 static int doit(struct query
*z
,int state
)
164 unsigned int cachedlen
;
167 const char *whichserver
;
171 unsigned int posanswers
;
173 unsigned int posauthority
;
175 unsigned int posglue
;
198 if (state
== 1) goto HAVEPACKET
;
200 log_servfail(z
->name
[z
->level
]);
206 if (++z
->loop
== 100) goto DIE
;
207 d
= z
->name
[z
->level
];
208 dtype
= z
->level
? DNS_T_A
: z
->type
;
209 dlen
= dns_domain_length(d
);
211 if (globalip(d
,misc
)) {
213 for (k
= 0;k
< 64;k
+= 4)
214 if (byte_equal(z
->servers
[z
->level
- 1] + k
,4,"\0\0\0\0")) {
215 byte_copy(z
->servers
[z
->level
- 1] + k
,4,misc
);
220 if (!rqa(z
)) goto DIE
;
221 if (typematch(DNS_T_A
,dtype
)) {
222 if (!response_rstart(d
,DNS_T_A
,655360)) goto DIE
;
223 if (!response_addbytes(misc
,4)) goto DIE
;
224 response_rfinish(RESPONSE_ANSWER
);
230 if (dns_domain_equal(d
,"\0011\0010\0010\003127\7in-addr\4arpa\0")) {
231 if (z
->level
) goto LOWERLEVEL
;
232 if (!rqa(z
)) goto DIE
;
233 if (typematch(DNS_T_PTR
,dtype
)) {
234 if (!response_rstart(d
,DNS_T_PTR
,655360)) goto DIE
;
235 if (!response_addname("\011localhost\0")) goto DIE
;
236 response_rfinish(RESPONSE_ANSWER
);
244 byte_copy(key
,2,DNS_T_ANY
);
245 byte_copy(key
+ 2,dlen
,d
);
246 case_lowerb(key
+ 2,dlen
);
247 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
249 log_cachednxdomain(d
);
253 byte_copy(key
,2,DNS_T_CNAME
);
254 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
256 if (typematch(DNS_T_CNAME
,dtype
)) {
257 log_cachedanswer(d
,DNS_T_CNAME
);
258 if (!rqa(z
)) goto DIE
;
259 if (!response_cname(z
->name
[0],cached
,ttl
)) goto DIE
;
263 log_cachedcname(d
,cached
);
264 if (!dns_domain_copy(&cname
,cached
)) goto DIE
;
268 if (typematch(DNS_T_NS
,dtype
)) {
269 byte_copy(key
,2,DNS_T_NS
);
270 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
271 if (cached
&& (cachedlen
|| byte_diff(dtype
,2,DNS_T_ANY
))) {
272 log_cachedanswer(d
,DNS_T_NS
);
273 if (!rqa(z
)) goto DIE
;
275 while (pos
= dns_packet_getname(cached
,cachedlen
,pos
,&t2
)) {
276 if (!response_rstart(d
,DNS_T_NS
,ttl
)) goto DIE
;
277 if (!response_addname(t2
)) goto DIE
;
278 response_rfinish(RESPONSE_ANSWER
);
285 if (typematch(DNS_T_PTR
,dtype
)) {
286 byte_copy(key
,2,DNS_T_PTR
);
287 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
288 if (cached
&& (cachedlen
|| byte_diff(dtype
,2,DNS_T_ANY
))) {
289 log_cachedanswer(d
,DNS_T_PTR
);
290 if (!rqa(z
)) goto DIE
;
292 while (pos
= dns_packet_getname(cached
,cachedlen
,pos
,&t2
)) {
293 if (!response_rstart(d
,DNS_T_PTR
,ttl
)) goto DIE
;
294 if (!response_addname(t2
)) goto DIE
;
295 response_rfinish(RESPONSE_ANSWER
);
302 if (typematch(DNS_T_MX
,dtype
)) {
303 byte_copy(key
,2,DNS_T_MX
);
304 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
305 if (cached
&& (cachedlen
|| byte_diff(dtype
,2,DNS_T_ANY
))) {
306 log_cachedanswer(d
,DNS_T_MX
);
307 if (!rqa(z
)) goto DIE
;
309 while (pos
= dns_packet_copy(cached
,cachedlen
,pos
,misc
,2)) {
310 pos
= dns_packet_getname(cached
,cachedlen
,pos
,&t2
);
312 if (!response_rstart(d
,DNS_T_MX
,ttl
)) goto DIE
;
313 if (!response_addbytes(misc
,2)) goto DIE
;
314 if (!response_addname(t2
)) goto DIE
;
315 response_rfinish(RESPONSE_ANSWER
);
322 if (typematch(DNS_T_A
,dtype
)) {
323 byte_copy(key
,2,DNS_T_A
);
324 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
325 if (cached
&& (cachedlen
|| byte_diff(dtype
,2,DNS_T_ANY
))) {
327 log_cachedanswer(d
,DNS_T_A
);
328 while (cachedlen
>= 4) {
329 for (k
= 0;k
< 64;k
+= 4)
330 if (byte_equal(z
->servers
[z
->level
- 1] + k
,4,"\0\0\0\0")) {
331 byte_copy(z
->servers
[z
->level
- 1] + k
,4,cached
);
340 log_cachedanswer(d
,DNS_T_A
);
341 if (!rqa(z
)) goto DIE
;
342 while (cachedlen
>= 4) {
343 if (!response_rstart(d
,DNS_T_A
,ttl
)) goto DIE
;
344 if (!response_addbytes(cached
,4)) goto DIE
;
345 response_rfinish(RESPONSE_ANSWER
);
354 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
)) {
355 byte_copy(key
,2,dtype
);
356 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
357 if (cached
&& (cachedlen
|| byte_diff(dtype
,2,DNS_T_ANY
))) {
358 log_cachedanswer(d
,dtype
);
359 if (!rqa(z
)) goto DIE
;
360 while (cachedlen
>= 2) {
361 uint16_unpack_big(cached
,&datalen
);
364 if (datalen
> cachedlen
) goto DIE
;
365 if (!response_rstart(d
,dtype
,ttl
)) goto DIE
;
366 if (!response_addbytes(cached
,datalen
)) goto DIE
;
367 response_rfinish(RESPONSE_ANSWER
);
369 cachedlen
-= datalen
;
378 if (roots(z
->servers
[z
->level
],d
)) {
379 for (j
= 0;j
< QUERY_MAXNS
;++j
)
380 dns_domain_free(&z
->ns
[z
->level
][j
]);
381 z
->control
[z
->level
] = d
;
385 if (!flagforwardonly
&& (z
->level
< 2))
387 byte_copy(key
,2,DNS_T_NS
);
388 byte_copy(key
+ 2,dlen
,d
);
389 case_lowerb(key
+ 2,dlen
);
390 cached
= cache_get(key
,dlen
+ 2,&cachedlen
,&ttl
);
391 if (cached
&& cachedlen
) {
392 z
->control
[z
->level
] = d
;
393 byte_zero(z
->servers
[z
->level
],64);
394 for (j
= 0;j
< QUERY_MAXNS
;++j
)
395 dns_domain_free(&z
->ns
[z
->level
][j
]);
398 while (pos
= dns_packet_getname(cached
,cachedlen
,pos
,&t1
)) {
401 if (!dns_domain_copy(&z
->ns
[z
->level
][j
++],t1
)) goto DIE
;
408 j
= 1 + (unsigned int) (unsigned char) *d
;
415 for (j
= 0;j
< QUERY_MAXNS
;++j
)
416 if (z
->ns
[z
->level
][j
]) {
417 if (z
->level
+ 1 < QUERY_MAXLEVEL
) {
418 if (!dns_domain_copy(&z
->name
[z
->level
+ 1],z
->ns
[z
->level
][j
])) goto DIE
;
419 dns_domain_free(&z
->ns
[z
->level
][j
]);
423 dns_domain_free(&z
->ns
[z
->level
][j
]);
426 for (j
= 0;j
< 64;j
+= 4)
427 if (byte_diff(z
->servers
[z
->level
] + j
,4,"\0\0\0\0"))
429 if (j
== 64) goto SERVFAIL
;
431 dns_sortip(z
->servers
[z
->level
],64);
433 log_tx(z
->name
[z
->level
],DNS_T_A
,z
->control
[z
->level
],z
->servers
[z
->level
],z
->level
);
434 if (dns_transmit_start(&z
->dt
,z
->servers
[z
->level
],flagforwardonly
,z
->name
[z
->level
],DNS_T_A
,z
->localip
) == -1) goto DIE
;
437 log_tx(z
->name
[0],z
->type
,z
->control
[0],z
->servers
[0],0);
438 if (dns_transmit_start(&z
->dt
,z
->servers
[0],flagforwardonly
,z
->name
[0],z
->type
,z
->localip
) == -1) goto DIE
;
444 dns_domain_free(&z
->name
[z
->level
]);
445 for (j
= 0;j
< QUERY_MAXNS
;++j
)
446 dns_domain_free(&z
->ns
[z
->level
][j
]);
452 if (++z
->loop
== 100) goto DIE
;
454 len
= z
->dt
.packetlen
;
456 whichserver
= z
->dt
.servers
+ 4 * z
->dt
.curserver
;
457 control
= z
->control
[z
->level
];
458 d
= z
->name
[z
->level
];
459 dtype
= z
->level
? DNS_T_A
: z
->type
;
461 pos
= dns_packet_copy(buf
,len
,0,header
,12); if (!pos
) goto DIE
;
462 pos
= dns_packet_skipname(buf
,len
,pos
); if (!pos
) goto DIE
;
466 uint16_unpack_big(header
+ 6,&numanswers
);
467 uint16_unpack_big(header
+ 8,&numauthority
);
468 uint16_unpack_big(header
+ 10,&numglue
);
470 rcode
= header
[3] & 15;
471 if (rcode
&& (rcode
!= 3)) goto DIE
; /* impossible; see irrelevant() */
479 for (j
= 0;j
< numanswers
;++j
) {
480 pos
= dns_packet_getname(buf
,len
,pos
,&t1
); if (!pos
) goto DIE
;
481 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
483 if (dns_domain_equal(t1
,d
))
484 if (byte_equal(header
+ 2,2,DNS_C_IN
)) { /* should always be true */
485 if (typematch(header
,dtype
))
487 else if (typematch(header
,DNS_T_CNAME
)) {
488 if (!dns_packet_getname(buf
,len
,pos
,&cname
)) goto DIE
;
490 cnamettl
= ttlget(header
+ 4);
494 uint16_unpack_big(header
+ 8,&datalen
);
499 for (j
= 0;j
< numauthority
;++j
) {
500 pos
= dns_packet_getname(buf
,len
,pos
,&t1
); if (!pos
) goto DIE
;
501 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
503 if (typematch(header
,DNS_T_SOA
)) {
505 soattl
= ttlget(header
+ 4);
506 if (soattl
> 3600) soattl
= 3600;
508 else if (typematch(header
,DNS_T_NS
)) {
510 if (!dns_domain_copy(&referral
,t1
)) goto DIE
;
513 uint16_unpack_big(header
+ 8,&datalen
);
519 if (!flagcname
&& !rcode
&& !flagout
&& flagreferral
&& !flagsoa
)
520 if (dns_domain_equal(referral
,control
) || !dns_domain_suffix(referral
,control
)) {
521 log_lame(whichserver
,control
,referral
);
522 byte_zero(whichserver
,4);
527 if (records
) { alloc_free(records
); records
= 0; }
529 k
= numanswers
+ numauthority
+ numglue
;
530 records
= (unsigned int *) alloc(k
* sizeof(unsigned int));
531 if (!records
) goto DIE
;
534 for (j
= 0;j
< k
;++j
) {
536 pos
= dns_packet_getname(buf
,len
,pos
,&t1
); if (!pos
) goto DIE
;
537 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
538 uint16_unpack_big(header
+ 8,&datalen
);
544 if (i
> 1) { --i
; pos
= records
[i
- 1]; }
545 else { pos
= records
[j
- 1]; records
[j
- 1] = records
[i
- 1]; --j
; }
548 while ((p
= q
* 2) < j
) {
549 if (!smaller(buf
,len
,records
[p
],records
[p
- 1])) ++p
;
550 records
[q
- 1] = records
[p
- 1]; q
= p
;
553 records
[q
- 1] = records
[p
- 1]; q
= p
;
555 while ((q
> i
) && smaller(buf
,len
,records
[(p
= q
/2) - 1],pos
)) {
556 records
[q
- 1] = records
[p
- 1]; q
= p
;
558 records
[q
- 1] = pos
;
565 pos
= dns_packet_getname(buf
,len
,records
[i
],&t1
); if (!pos
) goto DIE
;
566 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
567 ttl
= ttlget(header
+ 4);
569 byte_copy(type
,2,header
);
570 if (byte_diff(header
+ 2,2,DNS_C_IN
)) { ++i
; continue; }
572 for (j
= i
+ 1;j
< k
;++j
) {
573 pos
= dns_packet_getname(buf
,len
,records
[j
],&t2
); if (!pos
) goto DIE
;
574 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
575 if (!dns_domain_equal(t1
,t2
)) break;
576 if (byte_diff(header
,2,type
)) break;
577 if (byte_diff(header
+ 2,2,DNS_C_IN
)) break;
580 if (!dns_domain_suffix(t1
,control
)) { i
= j
; continue; }
581 if (!roots_same(t1
,control
)) { i
= j
; continue; }
583 if (byte_equal(type
,2,DNS_T_ANY
))
585 else if (byte_equal(type
,2,DNS_T_AXFR
))
587 else if (byte_equal(type
,2,DNS_T_SOA
)) {
589 pos
= dns_packet_skipname(buf
,len
,records
[i
]); if (!pos
) goto DIE
;
590 pos
= dns_packet_getname(buf
,len
,pos
+ 10,&t2
); if (!pos
) goto DIE
;
591 pos
= dns_packet_getname(buf
,len
,pos
,&t3
); if (!pos
) goto DIE
;
592 pos
= dns_packet_copy(buf
,len
,pos
,misc
,20); if (!pos
) goto DIE
;
593 if (records
[i
] < posauthority
)
594 log_rrsoa(whichserver
,t1
,t2
,t3
,misc
,ttl
);
598 else if (byte_equal(type
,2,DNS_T_CNAME
)) {
599 pos
= dns_packet_skipname(buf
,len
,records
[j
- 1]); if (!pos
) goto DIE
;
600 pos
= dns_packet_getname(buf
,len
,pos
+ 10,&t2
); if (!pos
) goto DIE
;
601 log_rrcname(whichserver
,t1
,t2
,ttl
);
602 cachegeneric(DNS_T_CNAME
,t1
,t2
,dns_domain_length(t2
),ttl
);
604 else if (byte_equal(type
,2,DNS_T_PTR
)) {
607 pos
= dns_packet_skipname(buf
,len
,records
[i
]); if (!pos
) goto DIE
;
608 pos
= dns_packet_getname(buf
,len
,pos
+ 10,&t2
); if (!pos
) goto DIE
;
609 log_rrptr(whichserver
,t1
,t2
,ttl
);
610 save_data(t2
,dns_domain_length(t2
));
613 save_finish(DNS_T_PTR
,t1
,ttl
);
615 else if (byte_equal(type
,2,DNS_T_NS
)) {
618 pos
= dns_packet_skipname(buf
,len
,records
[i
]); if (!pos
) goto DIE
;
619 pos
= dns_packet_getname(buf
,len
,pos
+ 10,&t2
); if (!pos
) goto DIE
;
620 log_rrns(whichserver
,t1
,t2
,ttl
);
621 save_data(t2
,dns_domain_length(t2
));
624 save_finish(DNS_T_NS
,t1
,ttl
);
626 else if (byte_equal(type
,2,DNS_T_MX
)) {
629 pos
= dns_packet_skipname(buf
,len
,records
[i
]); if (!pos
) goto DIE
;
630 pos
= dns_packet_copy(buf
,len
,pos
+ 10,misc
,2); if (!pos
) goto DIE
;
631 pos
= dns_packet_getname(buf
,len
,pos
,&t2
); if (!pos
) goto DIE
;
632 log_rrmx(whichserver
,t1
,t2
,misc
,ttl
);
634 save_data(t2
,dns_domain_length(t2
));
637 save_finish(DNS_T_MX
,t1
,ttl
);
639 else if (byte_equal(type
,2,DNS_T_A
)) {
642 pos
= dns_packet_skipname(buf
,len
,records
[i
]); if (!pos
) goto DIE
;
643 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
644 if (byte_equal(header
+ 8,2,"\0\4")) {
645 pos
= dns_packet_copy(buf
,len
,pos
,header
,4); if (!pos
) goto DIE
;
647 log_rr(whichserver
,t1
,DNS_T_A
,header
,4,ttl
);
651 save_finish(DNS_T_A
,t1
,ttl
);
656 pos
= dns_packet_skipname(buf
,len
,records
[i
]); if (!pos
) goto DIE
;
657 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
658 uint16_unpack_big(header
+ 8,&datalen
);
659 if (datalen
> len
- pos
) goto DIE
;
660 save_data(header
+ 8,2);
661 save_data(buf
+ pos
,datalen
);
662 log_rr(whichserver
,t1
,type
,buf
+ pos
,datalen
,ttl
);
665 save_finish(type
,t1
,ttl
);
671 alloc_free(records
); records
= 0;
678 if (z
->alias
[QUERY_MAXALIAS
- 1]) goto DIE
;
679 for (j
= QUERY_MAXALIAS
- 1;j
> 0;--j
)
680 z
->alias
[j
] = z
->alias
[j
- 1];
681 for (j
= QUERY_MAXALIAS
- 1;j
> 0;--j
)
682 z
->aliasttl
[j
] = z
->aliasttl
[j
- 1];
683 z
->alias
[0] = z
->name
[0];
684 z
->aliasttl
[0] = ttl
;
687 if (!dns_domain_copy(&z
->name
[z
->level
],cname
)) goto DIE
;
692 log_nxdomain(whichserver
,d
,soattl
);
693 cachegeneric(DNS_T_ANY
,d
,"",0,soattl
);
696 if (z
->level
) goto LOWERLEVEL
;
697 if (!rqa(z
)) goto DIE
;
703 if (!flagout
&& flagsoa
)
704 if (byte_diff(DNS_T_ANY
,2,dtype
))
705 if (byte_diff(DNS_T_AXFR
,2,dtype
))
706 if (byte_diff(DNS_T_CNAME
,2,dtype
)) {
708 save_finish(dtype
,d
,soattl
);
709 log_nodata(whichserver
,d
,dtype
,soattl
);
715 if (flagout
|| flagsoa
|| !flagreferral
) {
718 for (j
= 0;j
< numanswers
;++j
) {
719 pos
= dns_packet_getname(buf
,len
,pos
,&t1
); if (!pos
) goto DIE
;
720 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
721 uint16_unpack_big(header
+ 8,&datalen
);
722 if (dns_domain_equal(t1
,d
))
723 if (typematch(header
,DNS_T_A
))
724 if (byte_equal(header
+ 2,2,DNS_C_IN
)) /* should always be true */
726 for (k
= 0;k
< 64;k
+= 4)
727 if (byte_equal(z
->servers
[z
->level
- 1] + k
,4,"\0\0\0\0")) {
728 if (!dns_packet_copy(buf
,len
,pos
,z
->servers
[z
->level
- 1] + k
,4)) goto DIE
;
736 if (!rqa(z
)) goto DIE
;
739 for (j
= 0;j
< numanswers
;++j
) {
740 pos
= dns_packet_getname(buf
,len
,pos
,&t1
); if (!pos
) goto DIE
;
741 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
742 ttl
= ttlget(header
+ 4);
743 uint16_unpack_big(header
+ 8,&datalen
);
744 if (dns_domain_equal(t1
,d
))
745 if (byte_equal(header
+ 2,2,DNS_C_IN
)) /* should always be true */
746 if (typematch(header
,dtype
)) {
747 if (!response_rstart(t1
,header
,ttl
)) goto DIE
;
749 if (typematch(header
,DNS_T_NS
) || typematch(header
,DNS_T_CNAME
) || typematch(header
,DNS_T_PTR
)) {
750 if (!dns_packet_getname(buf
,len
,pos
,&t2
)) goto DIE
;
751 if (!response_addname(t2
)) goto DIE
;
753 else if (typematch(header
,DNS_T_MX
)) {
754 pos2
= dns_packet_copy(buf
,len
,pos
,misc
,2); if (!pos2
) goto DIE
;
755 if (!response_addbytes(misc
,2)) goto DIE
;
756 if (!dns_packet_getname(buf
,len
,pos2
,&t2
)) goto DIE
;
757 if (!response_addname(t2
)) goto DIE
;
759 else if (typematch(header
,DNS_T_SOA
)) {
760 pos2
= dns_packet_getname(buf
,len
,pos
,&t2
); if (!pos2
) goto DIE
;
761 if (!response_addname(t2
)) goto DIE
;
762 pos2
= dns_packet_getname(buf
,len
,pos2
,&t3
); if (!pos2
) goto DIE
;
763 if (!response_addname(t3
)) goto DIE
;
764 pos2
= dns_packet_copy(buf
,len
,pos2
,misc
,20); if (!pos2
) goto DIE
;
765 if (!response_addbytes(misc
,20)) goto DIE
;
768 if (pos
+ datalen
> len
) goto DIE
;
769 if (!response_addbytes(buf
+ pos
,datalen
)) goto DIE
;
772 response_rfinish(RESPONSE_ANSWER
);
783 if (!dns_domain_suffix(d
,referral
)) goto DIE
;
784 control
= d
+ dns_domain_suffixpos(d
,referral
);
785 z
->control
[z
->level
] = control
;
786 byte_zero(z
->servers
[z
->level
],64);
787 for (j
= 0;j
< QUERY_MAXNS
;++j
)
788 dns_domain_free(&z
->ns
[z
->level
][j
]);
792 for (j
= 0;j
< numauthority
;++j
) {
793 pos
= dns_packet_getname(buf
,len
,pos
,&t1
); if (!pos
) goto DIE
;
794 pos
= dns_packet_copy(buf
,len
,pos
,header
,10); if (!pos
) goto DIE
;
795 uint16_unpack_big(header
+ 8,&datalen
);
796 if (dns_domain_equal(referral
,t1
)) /* should always be true */
797 if (typematch(header
,DNS_T_NS
)) /* should always be true */
798 if (byte_equal(header
+ 2,2,DNS_C_IN
)) /* should always be true */
800 if (!dns_packet_getname(buf
,len
,pos
,&z
->ns
[z
->level
][k
++])) goto DIE
;
808 if (z
->level
) goto LOWERLEVEL
;
809 if (!rqa(z
)) goto DIE
;
817 if (records
) { alloc_free(records
); records
= 0; }
821 int query_start(struct query
*z
,char *dn
,char type
[2],char class[2],char localip
[4])
823 if (byte_equal(type
,2,DNS_T_AXFR
)) { errno
= error_perm
; return -1; }
829 if (!dns_domain_copy(&z
->name
[0],dn
)) return -1;
830 byte_copy(z
->type
,2,type
);
831 byte_copy(z
->class,2,class);
832 byte_copy(z
->localip
,4,localip
);
837 int query_get(struct query
*z
,iopause_fd
*x
,struct taia
*stamp
)
839 switch(dns_transmit_get(&z
->dt
,x
,stamp
)) {
848 void query_io(struct query
*z
,iopause_fd
*x
,struct taia
*deadline
)
850 dns_transmit_io(&z
->dt
,x
,deadline
);