4 * resolver implementation
6 * a Net::DNS like library for C
8 * (c) NLnet Labs, 2004-2006
10 * See the file LICENSE for the license
13 #include <ldns/config.h>
15 #include <ldns/ldns.h>
18 /* Access function for reading
19 * and setting the different Resolver
24 ldns_resolver_port(const ldns_resolver
*r
)
30 ldns_resolver_edns_udp_size(const ldns_resolver
*r
)
32 return r
->_edns_udp_size
;
36 ldns_resolver_retry(const ldns_resolver
*r
)
42 ldns_resolver_retrans(const ldns_resolver
*r
)
48 ldns_resolver_fallback(const ldns_resolver
*r
)
54 ldns_resolver_ip6(const ldns_resolver
*r
)
60 ldns_resolver_recursive(const ldns_resolver
*r
)
66 ldns_resolver_debug(const ldns_resolver
*r
)
72 ldns_resolver_dnsrch(const ldns_resolver
*r
)
78 ldns_resolver_fail(const ldns_resolver
*r
)
84 ldns_resolver_defnames(const ldns_resolver
*r
)
90 ldns_resolver_domain(const ldns_resolver
*r
)
96 ldns_resolver_searchlist(const ldns_resolver
*r
)
98 return r
->_searchlist
;
102 ldns_resolver_nameservers(const ldns_resolver
*r
)
104 return r
->_nameservers
;
108 ldns_resolver_nameserver_count(const ldns_resolver
*r
)
110 return r
->_nameserver_count
;
114 ldns_resolver_dnssec(const ldns_resolver
*r
)
120 ldns_resolver_dnssec_cd(const ldns_resolver
*r
)
122 return r
->_dnssec_cd
;
126 ldns_resolver_dnssec_anchors(const ldns_resolver
*r
)
128 return r
->_dnssec_anchors
;
132 ldns_resolver_trusted_key(const ldns_resolver
*r
, ldns_rr_list
* keys
, ldns_rr_list
* trusted_keys
)
137 ldns_rr_list
* trust_anchors
;
140 if (!r
|| !keys
) { return false; }
142 trust_anchors
= ldns_resolver_dnssec_anchors(r
);
144 if (!trust_anchors
) { return false; }
146 for (i
= 0; i
< ldns_rr_list_rr_count(keys
); i
++) {
148 cur_rr
= ldns_rr_list_rr(keys
, i
);
149 if (ldns_rr_list_contains_rr(trust_anchors
, cur_rr
)) {
150 if (trusted_keys
) { ldns_rr_list_push_rr(trusted_keys
, cur_rr
); }
159 ldns_resolver_igntc(const ldns_resolver
*r
)
165 ldns_resolver_usevc(const ldns_resolver
*r
)
171 ldns_resolver_rtt(const ldns_resolver
*r
)
177 ldns_resolver_nameserver_rtt(const ldns_resolver
*r
, size_t pos
)
183 rtt
= ldns_resolver_rtt(r
);
185 if (pos
>= ldns_resolver_nameserver_count(r
)) {
195 ldns_resolver_timeout(const ldns_resolver
*r
)
201 ldns_resolver_tsig_keyname(const ldns_resolver
*r
)
203 return r
->_tsig_keyname
;
207 ldns_resolver_tsig_algorithm(const ldns_resolver
*r
)
209 return r
->_tsig_algorithm
;
213 ldns_resolver_tsig_keydata(const ldns_resolver
*r
)
215 return r
->_tsig_keydata
;
219 ldns_resolver_random(const ldns_resolver
*r
)
225 ldns_resolver_searchlist_count(const ldns_resolver
*r
)
227 return r
->_searchlist_count
;
232 ldns_resolver_set_port(ldns_resolver
*r
, uint16_t p
)
238 ldns_resolver_pop_nameserver(ldns_resolver
*r
)
240 ldns_rdf
**nameservers
;
247 ns_count
= ldns_resolver_nameserver_count(r
);
248 nameservers
= ldns_resolver_nameservers(r
);
249 rtt
= ldns_resolver_rtt(r
);
250 if (ns_count
== 0 || !nameservers
) {
254 pop
= nameservers
[ns_count
- 1];
257 LDNS_FREE(nameservers
);
260 ldns_resolver_set_nameservers(r
, NULL
);
261 ldns_resolver_set_rtt(r
, NULL
);
263 nameservers
= LDNS_XREALLOC(nameservers
, ldns_rdf
*,
265 rtt
= LDNS_XREALLOC(rtt
, size_t, (ns_count
- 1));
267 ldns_resolver_set_nameservers(r
, nameservers
);
268 ldns_resolver_set_rtt(r
, rtt
);
271 ldns_resolver_dec_nameserver_count(r
);
276 ldns_resolver_push_nameserver(ldns_resolver
*r
, ldns_rdf
*n
)
278 ldns_rdf
**nameservers
;
282 if (ldns_rdf_get_type(n
) != LDNS_RDF_TYPE_A
&&
283 ldns_rdf_get_type(n
) != LDNS_RDF_TYPE_AAAA
) {
284 return LDNS_STATUS_ERR
;
287 ns_count
= ldns_resolver_nameserver_count(r
);
288 nameservers
= ldns_resolver_nameservers(r
);
289 rtt
= ldns_resolver_rtt(r
);
291 /* make room for the next one */
293 nameservers
= LDNS_XMALLOC(ldns_rdf
*, 1);
295 nameservers
= LDNS_XREALLOC(nameservers
, ldns_rdf
*, (ns_count
+ 1));
298 return LDNS_STATUS_MEM_ERR
;
300 /* set the new value in the resolver */
301 ldns_resolver_set_nameservers(r
, nameservers
);
303 /* don't forget the rtt */
305 rtt
= LDNS_XMALLOC(size_t, 1);
307 rtt
= LDNS_XREALLOC(rtt
, size_t, (ns_count
+ 1));
310 return LDNS_STATUS_MEM_ERR
;
312 /* slide n in its slot. */
313 /* we clone it here, because then we can free the original
314 * rr's where it stood */
315 nameservers
[ns_count
] = ldns_rdf_clone(n
);
316 rtt
[ns_count
] = LDNS_RESOLV_RTT_MIN
;
317 ldns_resolver_incr_nameserver_count(r
);
318 ldns_resolver_set_rtt(r
, rtt
);
319 return LDNS_STATUS_OK
;
323 ldns_resolver_push_nameserver_rr(ldns_resolver
*r
, ldns_rr
*rr
)
326 if ((!rr
) || (ldns_rr_get_type(rr
) != LDNS_RR_TYPE_A
&&
327 ldns_rr_get_type(rr
) != LDNS_RR_TYPE_AAAA
)) {
328 return LDNS_STATUS_ERR
;
330 address
= ldns_rr_rdf(rr
, 0); /* extract the ip number */
332 return ldns_resolver_push_nameserver(r
, address
);
334 return LDNS_STATUS_ERR
;
339 ldns_resolver_push_nameserver_rr_list(ldns_resolver
*r
, ldns_rr_list
*rrlist
)
345 stat
= LDNS_STATUS_OK
;
347 for(i
= 0; i
< ldns_rr_list_rr_count(rrlist
); i
++) {
348 rr
= ldns_rr_list_rr(rrlist
, i
);
349 if (ldns_resolver_push_nameserver_rr(r
, rr
) != LDNS_STATUS_OK
) {
350 stat
= LDNS_STATUS_ERR
;
356 return LDNS_STATUS_ERR
;
361 ldns_resolver_set_edns_udp_size(ldns_resolver
*r
, uint16_t s
)
363 r
->_edns_udp_size
= s
;
367 ldns_resolver_set_recursive(ldns_resolver
*r
, bool re
)
373 ldns_resolver_set_dnssec(ldns_resolver
*r
, bool d
)
379 ldns_resolver_set_dnssec_cd(ldns_resolver
*r
, bool d
)
385 ldns_resolver_set_dnssec_anchors(ldns_resolver
*r
, ldns_rr_list
* l
)
387 r
->_dnssec_anchors
= l
;
391 ldns_resolver_push_dnssec_anchor(ldns_resolver
*r
, ldns_rr
*rr
)
393 ldns_rr_list
* trust_anchors
;
395 if ((!rr
) || (ldns_rr_get_type(rr
) != LDNS_RR_TYPE_DNSKEY
&&
396 ldns_rr_get_type(rr
) != LDNS_RR_TYPE_DS
)) {
398 return LDNS_STATUS_ERR
;
401 if (!(trust_anchors
= ldns_resolver_dnssec_anchors(r
))) { /* Initialize */
402 trust_anchors
= ldns_rr_list_new();
403 ldns_resolver_set_dnssec_anchors(r
, trust_anchors
);
406 return (ldns_rr_list_push_rr(trust_anchors
, ldns_rr_clone(rr
))) ? LDNS_STATUS_OK
: LDNS_STATUS_ERR
;
410 ldns_resolver_set_igntc(ldns_resolver
*r
, bool i
)
416 ldns_resolver_set_usevc(ldns_resolver
*r
, bool vc
)
422 ldns_resolver_set_debug(ldns_resolver
*r
, bool d
)
428 ldns_resolver_set_ip6(ldns_resolver
*r
, uint8_t ip6
)
434 ldns_resolver_set_fail(ldns_resolver
*r
, bool f
)
440 ldns_resolver_set_searchlist_count(ldns_resolver
*r
, size_t c
)
442 r
->_searchlist_count
= c
;
446 ldns_resolver_set_nameserver_count(ldns_resolver
*r
, size_t c
)
448 r
->_nameserver_count
= c
;
452 ldns_resolver_set_dnsrch(ldns_resolver
*r
, bool d
)
458 ldns_resolver_set_retry(ldns_resolver
*r
, uint8_t retry
)
464 ldns_resolver_set_retrans(ldns_resolver
*r
, uint8_t retrans
)
466 r
->_retrans
= retrans
;
470 ldns_resolver_set_fallback(ldns_resolver
*r
, bool fallback
)
472 r
->_fallback
= fallback
;
476 ldns_resolver_set_nameservers(ldns_resolver
*r
, ldns_rdf
**n
)
482 ldns_resolver_set_defnames(ldns_resolver
*r
, bool d
)
488 ldns_resolver_set_rtt(ldns_resolver
*r
, size_t *rtt
)
494 ldns_resolver_set_nameserver_rtt(ldns_resolver
*r
, size_t pos
, size_t value
)
500 rtt
= ldns_resolver_rtt(r
);
502 if (pos
>= ldns_resolver_nameserver_count(r
)) {
511 ldns_resolver_incr_nameserver_count(ldns_resolver
*r
)
515 c
= ldns_resolver_nameserver_count(r
);
516 ldns_resolver_set_nameserver_count(r
, ++c
);
520 ldns_resolver_dec_nameserver_count(ldns_resolver
*r
)
524 c
= ldns_resolver_nameserver_count(r
);
528 ldns_resolver_set_nameserver_count(r
, --c
);
533 ldns_resolver_set_domain(ldns_resolver
*r
, ldns_rdf
*d
)
539 ldns_resolver_set_timeout(ldns_resolver
*r
, struct timeval timeout
)
541 r
->_timeout
.tv_sec
= timeout
.tv_sec
;
542 r
->_timeout
.tv_usec
= timeout
.tv_usec
;
546 ldns_resolver_push_searchlist(ldns_resolver
*r
, ldns_rdf
*d
)
548 ldns_rdf
**searchlist
;
551 if (ldns_rdf_get_type(d
) != LDNS_RDF_TYPE_DNAME
) {
555 list_count
= ldns_resolver_searchlist_count(r
);
556 searchlist
= ldns_resolver_searchlist(r
);
558 searchlist
= LDNS_XREALLOC(searchlist
, ldns_rdf
*, (list_count
+ 1));
560 r
->_searchlist
= searchlist
;
562 searchlist
[list_count
] = ldns_rdf_clone(d
);
563 ldns_resolver_set_searchlist_count(r
, list_count
+ 1);
564 } /* no way to report mem err */
568 ldns_resolver_set_tsig_keyname(ldns_resolver
*r
, char *tsig_keyname
)
570 LDNS_FREE(r
->_tsig_keyname
);
571 r
->_tsig_keyname
= strdup(tsig_keyname
);
575 ldns_resolver_set_tsig_algorithm(ldns_resolver
*r
, char *tsig_algorithm
)
577 LDNS_FREE(r
->_tsig_algorithm
);
578 r
->_tsig_algorithm
= strdup(tsig_algorithm
);
582 ldns_resolver_set_tsig_keydata(ldns_resolver
*r
, char *tsig_keydata
)
584 LDNS_FREE(r
->_tsig_keydata
);
585 r
->_tsig_keydata
= strdup(tsig_keydata
);
589 ldns_resolver_set_random(ldns_resolver
*r
, bool b
)
594 /* more sophisticated functions */
596 ldns_resolver_new(void)
600 r
= LDNS_MALLOC(ldns_resolver
);
605 r
->_searchlist
= NULL
;
606 r
->_nameservers
= NULL
;
609 /* defaults are filled out */
610 ldns_resolver_set_searchlist_count(r
, 0);
611 ldns_resolver_set_nameserver_count(r
, 0);
612 ldns_resolver_set_usevc(r
, 0);
613 ldns_resolver_set_port(r
, LDNS_PORT
);
614 ldns_resolver_set_domain(r
, NULL
);
615 ldns_resolver_set_defnames(r
, false);
616 ldns_resolver_set_retry(r
, 3);
617 ldns_resolver_set_retrans(r
, 2);
618 ldns_resolver_set_fallback(r
, true);
619 ldns_resolver_set_fail(r
, false);
620 ldns_resolver_set_edns_udp_size(r
, 0);
621 ldns_resolver_set_dnssec(r
, false);
622 ldns_resolver_set_dnssec_cd(r
, false);
623 ldns_resolver_set_dnssec_anchors(r
, NULL
);
624 ldns_resolver_set_ip6(r
, LDNS_RESOLV_INETANY
);
625 ldns_resolver_set_igntc(r
, false);
626 ldns_resolver_set_recursive(r
, false);
627 ldns_resolver_set_dnsrch(r
, true);
629 /* randomize the nameserver to be queried
630 * when there are multiple
632 ldns_resolver_set_random(r
, true);
634 ldns_resolver_set_debug(r
, 0);
636 r
->_timeout
.tv_sec
= LDNS_DEFAULT_TIMEOUT_SEC
;
637 r
->_timeout
.tv_usec
= LDNS_DEFAULT_TIMEOUT_USEC
;
639 /* TODO: fd=0 is actually a valid socket (stdin),
642 r
->_axfr_soa_count
= 0;
644 r
->_cur_axfr_pkt
= NULL
;
646 r
->_tsig_keyname
= NULL
;
647 r
->_tsig_keydata
= NULL
;
648 r
->_tsig_algorithm
= NULL
;
653 ldns_resolver_new_frm_fp(ldns_resolver
**res
, FILE *fp
)
655 return ldns_resolver_new_frm_fp_l(res
, fp
, NULL
);
659 ldns_resolver_new_frm_fp_l(ldns_resolver
**res
, FILE *fp
, int *line_nr
)
662 const char *keyword
[LDNS_RESOLV_KEYWORDS
];
663 char word
[LDNS_MAX_LINELEN
+ 1];
672 int lnr
= 0, oldline
;
673 if(!line_nr
) line_nr
= &lnr
;
678 * 1: default domain dname
679 * 2: NS aaaa or a record
682 /* recognized keywords */
683 keyword
[LDNS_RESOLV_NAMESERVER
] = "nameserver";
684 keyword
[LDNS_RESOLV_DEFDOMAIN
] = "domain";
685 keyword
[LDNS_RESOLV_SEARCH
] = "search";
686 /* these two are read but not used atm TODO */
687 keyword
[LDNS_RESOLV_SORTLIST
] = "sortlist";
688 keyword
[LDNS_RESOLV_OPTIONS
] = "options";
689 keyword
[LDNS_RESOLV_ANCHOR
] = "anchor";
690 expect
= LDNS_RESOLV_KEYWORD
;
692 r
= ldns_resolver_new();
694 return LDNS_STATUS_MEM_ERR
;
700 expect
= LDNS_RESOLV_KEYWORD
;
703 if (word
[0] == '#') {
705 if(oldline
== *line_nr
) {
706 /* skip until end of line */
710 } while(c
!= EOF
&& c
!= '\n');
711 if(c
=='\n' && line_nr
) (*line_nr
)++;
713 /* and read next to prepare for further parsing */
719 case LDNS_RESOLV_KEYWORD
:
721 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
723 if(word
[0] == '#') continue;
724 for(i
= 0; i
< LDNS_RESOLV_KEYWORDS
; i
++) {
725 if (strcasecmp(keyword
[i
], word
) == 0) {
726 /* chosen the keyword and
727 * expect values carefully
733 /* no keyword recognized */
734 if (expect
== LDNS_RESOLV_KEYWORD
) {
737 ldns_resolver_deep_free(r);
738 return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
743 case LDNS_RESOLV_DEFDOMAIN
:
744 /* default domain dname */
745 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
747 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
;
750 expect
= LDNS_RESOLV_KEYWORD
;
753 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME
, word
);
755 ldns_resolver_deep_free(r
);
756 return LDNS_STATUS_SYNTAX_DNAME_ERR
;
759 /* DOn't free, because we copy the pointer */
760 ldns_resolver_set_domain(r
, tmp
);
761 expect
= LDNS_RESOLV_KEYWORD
;
763 case LDNS_RESOLV_NAMESERVER
:
764 /* NS aaaa or a record */
765 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
767 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
;
770 expect
= LDNS_RESOLV_KEYWORD
;
773 if(strchr(word
, '%')) {
774 /* snip off interface labels,
775 * fe80::222:19ff:fe31:4222%eth0 */
776 strchr(word
, '%')[0]=0;
778 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA
, word
);
781 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A
, word
);
783 /* could not parse it, exit */
785 ldns_resolver_deep_free(r
);
786 return LDNS_STATUS_SYNTAX_ERR
;
788 (void)ldns_resolver_push_nameserver(r
, tmp
);
789 ldns_rdf_deep_free(tmp
);
790 expect
= LDNS_RESOLV_KEYWORD
;
792 case LDNS_RESOLV_SEARCH
:
793 /* search list domain dname */
794 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_SKIP_SPACE
, 0, line_nr
);
795 b
= LDNS_MALLOC(ldns_buffer
);
797 ldns_resolver_deep_free(r
);
798 return LDNS_STATUS_MEM_ERR
;
801 ldns_buffer_new_frm_data(b
, word
, (size_t) gtr
);
802 if(ldns_buffer_status(b
) != LDNS_STATUS_OK
) {
804 ldns_resolver_deep_free(r
);
805 return LDNS_STATUS_MEM_ERR
;
807 bgtr
= ldns_bget_token(b
, word
, LDNS_PARSE_NORMAL
, (size_t) gtr
+ 1);
811 expect
= LDNS_RESOLV_KEYWORD
;
814 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME
, word
);
816 ldns_resolver_deep_free(r
);
818 return LDNS_STATUS_SYNTAX_DNAME_ERR
;
821 ldns_resolver_push_searchlist(r
, tmp
);
823 ldns_rdf_deep_free(tmp
);
824 bgtr
= ldns_bget_token(b
, word
, LDNS_PARSE_NORMAL
,
828 if (expect
!= LDNS_RESOLV_KEYWORD
) {
830 expect
= LDNS_RESOLV_KEYWORD
;
833 case LDNS_RESOLV_SORTLIST
:
834 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_SKIP_SPACE
, 0, line_nr
);
835 /* sortlist not implemented atm */
836 expect
= LDNS_RESOLV_KEYWORD
;
838 case LDNS_RESOLV_OPTIONS
:
839 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_SKIP_SPACE
, 0, line_nr
);
840 /* options not implemented atm */
841 expect
= LDNS_RESOLV_KEYWORD
;
843 case LDNS_RESOLV_ANCHOR
:
844 /* a file containing a DNSSEC trust anchor */
845 gtr
= ldns_fget_token_l(fp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
847 ldns_resolver_deep_free(r
);
848 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
;
851 expect
= LDNS_RESOLV_KEYWORD
;
856 tmp_rr
= ldns_read_anchor_file(word
);
857 (void) ldns_resolver_push_dnssec_anchor(r
, tmp_rr
);
858 ldns_rr_free(tmp_rr
);
860 expect
= LDNS_RESOLV_KEYWORD
;
867 return LDNS_STATUS_OK
;
869 ldns_resolver_deep_free(r
);
870 return LDNS_STATUS_NULL
;
875 ldns_resolver_new_frm_file(ldns_resolver
**res
, const char *filename
)
882 fp
= fopen(LDNS_RESOLV_CONF
, "r");
885 fp
= fopen(filename
, "r");
888 return LDNS_STATUS_FILE_ERR
;
891 s
= ldns_resolver_new_frm_fp(&r
, fp
);
893 if (s
== LDNS_STATUS_OK
) {
896 return LDNS_STATUS_OK
;
898 ldns_resolver_free(r
);
899 return LDNS_STATUS_NULL
;
906 ldns_resolver_free(ldns_resolver
*res
)
912 ldns_resolver_deep_free(ldns_resolver
*res
)
917 if (res
->_searchlist
) {
918 for (i
= 0; i
< ldns_resolver_searchlist_count(res
); i
++) {
919 ldns_rdf_deep_free(res
->_searchlist
[i
]);
921 LDNS_FREE(res
->_searchlist
);
923 if (res
->_nameservers
) {
924 for (i
= 0; i
< res
->_nameserver_count
; i
++) {
925 ldns_rdf_deep_free(res
->_nameservers
[i
]);
927 LDNS_FREE(res
->_nameservers
);
929 if (ldns_resolver_domain(res
)) {
930 ldns_rdf_deep_free(ldns_resolver_domain(res
));
932 if (res
->_tsig_keyname
) {
933 LDNS_FREE(res
->_tsig_keyname
);
935 if (res
->_tsig_keydata
) {
936 LDNS_FREE(res
->_tsig_keydata
);
938 if (res
->_tsig_algorithm
) {
939 LDNS_FREE(res
->_tsig_algorithm
);
942 if (res
->_cur_axfr_pkt
) {
943 ldns_pkt_free(res
->_cur_axfr_pkt
);
947 LDNS_FREE(res
->_rtt
);
949 if (res
->_dnssec_anchors
) {
950 ldns_rr_list_deep_free(res
->_dnssec_anchors
);
957 ldns_resolver_search(const ldns_resolver
*r
,const ldns_rdf
*name
,
958 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
962 ldns_rdf
**search_list
;
966 if (ldns_dname_absolute(name
)) {
968 return ldns_resolver_query(r
, name
, t
, c
, flags
);
969 } else if (ldns_resolver_dnsrch(r
)) {
970 search_list
= ldns_resolver_searchlist(r
);
971 for (i
= 0; i
< ldns_resolver_searchlist_count(r
); i
++) {
972 new_name
= ldns_dname_cat_clone(name
, search_list
[i
]);
974 p
= ldns_resolver_query(r
, new_name
, t
, c
, flags
);
975 ldns_rdf_free(new_name
);
977 if (ldns_pkt_get_rcode(p
) == LDNS_RCODE_NOERROR
) {
990 ldns_resolver_query(const ldns_resolver
*r
, const ldns_rdf
*name
,
991 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
999 if (!ldns_resolver_defnames(r
)) {
1000 status
= ldns_resolver_send(&pkt
, (ldns_resolver
*)r
, name
,
1002 if (status
== LDNS_STATUS_OK
) {
1012 if (!ldns_resolver_domain(r
)) {
1013 /* _defnames is set, but the domain is not....?? */
1014 status
= ldns_resolver_send(&pkt
, (ldns_resolver
*)r
, name
,
1016 if (status
== LDNS_STATUS_OK
) {
1026 newname
= ldns_dname_cat_clone((const ldns_rdf
*)name
, ldns_resolver_domain(r
));
1031 (void)ldns_resolver_send(&pkt
, (ldns_resolver
*)r
, newname
, t
, c
,
1034 ldns_rdf_free(newname
);
1040 ldns_resolver_backup_rtt(ldns_resolver
*r
)
1043 size_t *old_rtt
= ldns_resolver_rtt(r
);
1045 if (old_rtt
&& ldns_resolver_nameserver_count(r
)) {
1046 new_rtt
= LDNS_XMALLOC(size_t
1047 , ldns_resolver_nameserver_count(r
));
1048 memcpy(new_rtt
, old_rtt
, sizeof(size_t)
1049 * ldns_resolver_nameserver_count(r
));
1050 ldns_resolver_set_rtt(r
, new_rtt
);
1057 ldns_resolver_restore_rtt(ldns_resolver
*r
, size_t *old_rtt
)
1059 size_t *cur_rtt
= ldns_resolver_rtt(r
);
1064 ldns_resolver_set_rtt(r
, old_rtt
);
1068 ldns_resolver_send_pkt(ldns_pkt
**answer
, ldns_resolver
*r
,
1069 ldns_pkt
*query_pkt
)
1071 ldns_pkt
*answer_pkt
= NULL
;
1072 ldns_status stat
= LDNS_STATUS_OK
;
1075 stat
= ldns_send(&answer_pkt
, (ldns_resolver
*)r
, query_pkt
);
1076 if (stat
!= LDNS_STATUS_OK
) {
1078 ldns_pkt_free(answer_pkt
);
1082 /* if tc=1 fall back to EDNS and/or TCP */
1083 /* check for tcp first (otherwise we don't care about tc=1) */
1084 if (!ldns_resolver_usevc(r
) && ldns_resolver_fallback(r
)) {
1085 if (ldns_pkt_tc(answer_pkt
)) {
1086 /* was EDNS0 set? */
1087 if (ldns_pkt_edns_udp_size(query_pkt
) == 0) {
1088 ldns_pkt_set_edns_udp_size(query_pkt
1090 ldns_pkt_free(answer_pkt
);
1091 /* Nameservers should not become
1092 * unreachable because fragments are
1093 * dropped (network error). We might
1094 * still have success with TCP.
1095 * Therefore maintain reachability
1096 * statuses of the nameservers by
1097 * backup and restore the rtt list.
1099 rtt
= ldns_resolver_backup_rtt(r
);
1100 stat
= ldns_send(&answer_pkt
, r
1102 ldns_resolver_restore_rtt(r
, rtt
);
1104 /* either way, if it is still truncated, use TCP */
1105 if (stat
!= LDNS_STATUS_OK
||
1106 ldns_pkt_tc(answer_pkt
)) {
1107 ldns_resolver_set_usevc(r
, true);
1108 ldns_pkt_free(answer_pkt
);
1109 stat
= ldns_send(&answer_pkt
, r
, query_pkt
);
1110 ldns_resolver_set_usevc(r
, false);
1117 *answer
= answer_pkt
;
1124 ldns_resolver_prepare_query_pkt(ldns_pkt
**query_pkt
, ldns_resolver
*r
,
1125 const ldns_rdf
*name
, ldns_rr_type t
,
1126 ldns_rr_class c
, uint16_t flags
)
1130 /* prepare a question pkt from the parameters
1131 * and then send this */
1132 *query_pkt
= ldns_pkt_query_new(ldns_rdf_clone(name
), t
, c
, flags
);
1134 return LDNS_STATUS_ERR
;
1137 /* set DO bit if necessary */
1138 if (ldns_resolver_dnssec(r
)) {
1139 if (ldns_resolver_edns_udp_size(r
) == 0) {
1140 ldns_resolver_set_edns_udp_size(r
, 4096);
1142 ldns_pkt_set_edns_do(*query_pkt
, true);
1143 if (ldns_resolver_dnssec_cd(r
) || (flags
& LDNS_CD
)) {
1144 ldns_pkt_set_cd(*query_pkt
, true);
1148 /* transfer the udp_edns_size from the resolver to the packet */
1149 if (ldns_resolver_edns_udp_size(r
) != 0) {
1150 ldns_pkt_set_edns_udp_size(*query_pkt
, ldns_resolver_edns_udp_size(r
));
1153 /* set the timestamp */
1154 now
.tv_sec
= time(NULL
);
1156 ldns_pkt_set_timestamp(*query_pkt
, now
);
1159 if (ldns_resolver_debug(r
)) {
1160 ldns_pkt_print(stdout
, *query_pkt
);
1163 /* only set the id if it is not set yet */
1164 if (ldns_pkt_id(*query_pkt
) == 0) {
1165 ldns_pkt_set_random_id(*query_pkt
);
1168 return LDNS_STATUS_OK
;
1173 ldns_resolver_send(ldns_pkt
**answer
, ldns_resolver
*r
, const ldns_rdf
*name
,
1174 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
1176 ldns_pkt
*query_pkt
;
1177 ldns_pkt
*answer_pkt
;
1181 assert(name
!= NULL
);
1185 /* do all the preprocessing here, then fire of an query to
1192 c
= LDNS_RR_CLASS_IN
;
1194 if (0 == ldns_resolver_nameserver_count(r
)) {
1195 return LDNS_STATUS_RES_NO_NS
;
1197 if (ldns_rdf_get_type(name
) != LDNS_RDF_TYPE_DNAME
) {
1198 return LDNS_STATUS_RES_QUERY
;
1201 status
= ldns_resolver_prepare_query_pkt(&query_pkt
, r
, name
,
1203 if (status
!= LDNS_STATUS_OK
) {
1207 /* if tsig values are set, tsign it */
1208 /* TODO: make last 3 arguments optional too? maybe make complete
1209 rr instead of seperate values in resolver (and packet)
1211 should this go in pkt_prepare?
1213 if (ldns_resolver_tsig_keyname(r
) && ldns_resolver_tsig_keydata(r
)) {
1215 status
= ldns_pkt_tsig_sign(query_pkt
,
1216 ldns_resolver_tsig_keyname(r
),
1217 ldns_resolver_tsig_keydata(r
),
1218 300, ldns_resolver_tsig_algorithm(r
), NULL
);
1219 if (status
!= LDNS_STATUS_OK
) {
1220 ldns_pkt_free(query_pkt
);
1221 return LDNS_STATUS_CRYPTO_TSIG_ERR
;
1224 ldns_pkt_free(query_pkt
);
1225 return LDNS_STATUS_CRYPTO_TSIG_ERR
;
1226 #endif /* HAVE_SSL */
1229 status
= ldns_resolver_send_pkt(&answer_pkt
, r
, query_pkt
);
1230 ldns_pkt_free(query_pkt
);
1232 /* allows answer to be NULL when not interested in return value */
1234 *answer
= answer_pkt
;
1240 ldns_axfr_next(ldns_resolver
*resolver
)
1243 uint8_t *packet_wire
;
1244 size_t packet_wire_size
;
1245 ldns_lookup_table
*rcode
;
1248 /* check if start() has been called */
1249 if (!resolver
|| resolver
->_socket
== 0) {
1253 if (resolver
->_cur_axfr_pkt
) {
1254 if (resolver
->_axfr_i
== ldns_pkt_ancount(resolver
->_cur_axfr_pkt
)) {
1255 ldns_pkt_free(resolver
->_cur_axfr_pkt
);
1256 resolver
->_cur_axfr_pkt
= NULL
;
1257 return ldns_axfr_next(resolver
);
1259 cur_rr
= ldns_rr_clone(ldns_rr_list_rr(
1260 ldns_pkt_answer(resolver
->_cur_axfr_pkt
),
1261 resolver
->_axfr_i
));
1262 resolver
->_axfr_i
++;
1263 if (ldns_rr_get_type(cur_rr
) == LDNS_RR_TYPE_SOA
) {
1264 resolver
->_axfr_soa_count
++;
1265 if (resolver
->_axfr_soa_count
>= 2) {
1267 close(resolver
->_socket
);
1269 closesocket(resolver
->_socket
);
1271 resolver
->_socket
= 0;
1272 ldns_pkt_free(resolver
->_cur_axfr_pkt
);
1273 resolver
->_cur_axfr_pkt
= NULL
;
1278 packet_wire
= ldns_tcp_read_wire(resolver
->_socket
, &packet_wire_size
);
1282 status
= ldns_wire2pkt(&resolver
->_cur_axfr_pkt
, packet_wire
,
1284 LDNS_FREE(packet_wire
);
1286 resolver
->_axfr_i
= 0;
1287 if (status
!= LDNS_STATUS_OK
) {
1288 /* TODO: make status return type of this function (...api change) */
1289 fprintf(stderr
, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status
));
1291 /* RoRi: we must now also close the socket, otherwise subsequent uses of the
1292 same resolver structure will fail because the link is still open or
1293 in an undefined state */
1295 close(resolver
->_socket
);
1297 closesocket(resolver
->_socket
);
1299 resolver
->_socket
= 0;
1302 } else if (ldns_pkt_get_rcode(resolver
->_cur_axfr_pkt
) != 0) {
1303 rcode
= ldns_lookup_by_id(ldns_rcodes
, (int) ldns_pkt_get_rcode(resolver
->_cur_axfr_pkt
));
1305 fprintf(stderr
, "Error in AXFR: %s\n",
1308 fprintf(stderr
, "Error in AXFR: %d\n",
1309 (int) ldns_pkt_get_rcode(
1310 resolver
->_cur_axfr_pkt
));
1313 /* RoRi: we must now also close the socket, otherwise subsequent uses of the
1314 same resolver structure will fail because the link is still open or
1315 in an undefined state */
1317 close(resolver
->_socket
);
1319 closesocket(resolver
->_socket
);
1321 resolver
->_socket
= 0;
1325 return ldns_axfr_next(resolver
);
1333 ldns_axfr_complete(const ldns_resolver
*res
)
1335 /* complete when soa count is 2? */
1336 return res
->_axfr_soa_count
== 2;
1340 ldns_axfr_last_pkt(const ldns_resolver
*res
)
1342 return res
->_cur_axfr_pkt
;
1345 /* random isn't really that good */
1347 ldns_resolver_nameservers_randomize(ldns_resolver
*r
)
1350 ldns_rdf
**ns
, *tmpns
;
1351 size_t *rtt
, tmprtt
;
1353 /* should I check for ldns_resolver_random?? */
1356 ns
= ldns_resolver_nameservers(r
);
1357 rtt
= ldns_resolver_rtt(r
);
1358 for (i
= 0; i
< ldns_resolver_nameserver_count(r
); i
++) {
1359 j
= ldns_get_random() % ldns_resolver_nameserver_count(r
);
1367 ldns_resolver_set_nameservers(r
, ns
);