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_source(const ldns_resolver
*r
)
36 ldns_resolver_edns_udp_size(const ldns_resolver
*r
)
38 return r
->_edns_udp_size
;
42 ldns_resolver_retry(const ldns_resolver
*r
)
48 ldns_resolver_retrans(const ldns_resolver
*r
)
54 ldns_resolver_fallback(const ldns_resolver
*r
)
60 ldns_resolver_ip6(const ldns_resolver
*r
)
66 ldns_resolver_recursive(const ldns_resolver
*r
)
72 ldns_resolver_debug(const ldns_resolver
*r
)
78 ldns_resolver_dnsrch(const ldns_resolver
*r
)
84 ldns_resolver_fail(const ldns_resolver
*r
)
90 ldns_resolver_defnames(const ldns_resolver
*r
)
96 ldns_resolver_domain(const ldns_resolver
*r
)
102 ldns_resolver_searchlist(const ldns_resolver
*r
)
104 return r
->_searchlist
;
108 ldns_resolver_nameservers(const ldns_resolver
*r
)
110 return r
->_nameservers
;
114 ldns_resolver_nameserver_count(const ldns_resolver
*r
)
116 return r
->_nameserver_count
;
120 ldns_resolver_dnssec(const ldns_resolver
*r
)
126 ldns_resolver_dnssec_cd(const ldns_resolver
*r
)
128 return r
->_dnssec_cd
;
132 ldns_resolver_dnssec_anchors(const ldns_resolver
*r
)
134 return r
->_dnssec_anchors
;
138 ldns_resolver_trusted_key(const ldns_resolver
*r
, ldns_rr_list
* keys
, ldns_rr_list
* trusted_keys
)
143 ldns_rr_list
* trust_anchors
;
146 if (!r
|| !keys
) { return false; }
148 trust_anchors
= ldns_resolver_dnssec_anchors(r
);
150 if (!trust_anchors
) { return false; }
152 for (i
= 0; i
< ldns_rr_list_rr_count(keys
); i
++) {
154 cur_rr
= ldns_rr_list_rr(keys
, i
);
155 if (ldns_rr_list_contains_rr(trust_anchors
, cur_rr
)) {
156 if (trusted_keys
) { ldns_rr_list_push_rr(trusted_keys
, cur_rr
); }
165 ldns_resolver_igntc(const ldns_resolver
*r
)
171 ldns_resolver_usevc(const ldns_resolver
*r
)
177 ldns_resolver_rtt(const ldns_resolver
*r
)
183 ldns_resolver_nameserver_rtt(const ldns_resolver
*r
, size_t pos
)
189 rtt
= ldns_resolver_rtt(r
);
191 if (pos
>= ldns_resolver_nameserver_count(r
)) {
201 ldns_resolver_timeout(const ldns_resolver
*r
)
207 ldns_resolver_tsig_keyname(const ldns_resolver
*r
)
209 return r
->_tsig_keyname
;
213 ldns_resolver_tsig_algorithm(const ldns_resolver
*r
)
215 return r
->_tsig_algorithm
;
219 ldns_resolver_tsig_keydata(const ldns_resolver
*r
)
221 return r
->_tsig_keydata
;
225 ldns_resolver_random(const ldns_resolver
*r
)
231 ldns_resolver_searchlist_count(const ldns_resolver
*r
)
233 return r
->_searchlist_count
;
238 ldns_resolver_set_port(ldns_resolver
*r
, uint16_t p
)
244 ldns_resolver_set_source(ldns_resolver
*r
, ldns_rdf
*s
)
250 ldns_resolver_pop_nameserver(ldns_resolver
*r
)
252 ldns_rdf
**nameservers
;
259 ns_count
= ldns_resolver_nameserver_count(r
);
260 nameservers
= ldns_resolver_nameservers(r
);
261 rtt
= ldns_resolver_rtt(r
);
262 if (ns_count
== 0 || !nameservers
) {
266 pop
= nameservers
[ns_count
- 1];
269 LDNS_FREE(nameservers
);
272 ldns_resolver_set_nameservers(r
, NULL
);
273 ldns_resolver_set_rtt(r
, NULL
);
275 nameservers
= LDNS_XREALLOC(nameservers
, ldns_rdf
*,
277 rtt
= LDNS_XREALLOC(rtt
, size_t, (ns_count
- 1));
279 ldns_resolver_set_nameservers(r
, nameservers
);
280 ldns_resolver_set_rtt(r
, rtt
);
283 ldns_resolver_dec_nameserver_count(r
);
288 ldns_resolver_push_nameserver(ldns_resolver
*r
, const ldns_rdf
*n
)
290 ldns_rdf
**nameservers
;
294 if (ldns_rdf_get_type(n
) != LDNS_RDF_TYPE_A
&&
295 ldns_rdf_get_type(n
) != LDNS_RDF_TYPE_AAAA
) {
296 return LDNS_STATUS_ERR
;
299 ns_count
= ldns_resolver_nameserver_count(r
);
300 nameservers
= ldns_resolver_nameservers(r
);
301 rtt
= ldns_resolver_rtt(r
);
303 /* make room for the next one */
305 nameservers
= LDNS_XMALLOC(ldns_rdf
*, 1);
307 nameservers
= LDNS_XREALLOC(nameservers
, ldns_rdf
*, (ns_count
+ 1));
310 return LDNS_STATUS_MEM_ERR
;
312 /* set the new value in the resolver */
313 ldns_resolver_set_nameservers(r
, nameservers
);
315 /* don't forget the rtt */
317 rtt
= LDNS_XMALLOC(size_t, 1);
319 rtt
= LDNS_XREALLOC(rtt
, size_t, (ns_count
+ 1));
322 return LDNS_STATUS_MEM_ERR
;
324 /* slide n in its slot. */
325 /* we clone it here, because then we can free the original
326 * rr's where it stood */
327 nameservers
[ns_count
] = ldns_rdf_clone(n
);
328 rtt
[ns_count
] = LDNS_RESOLV_RTT_MIN
;
329 ldns_resolver_incr_nameserver_count(r
);
330 ldns_resolver_set_rtt(r
, rtt
);
331 return LDNS_STATUS_OK
;
335 ldns_resolver_push_nameserver_rr(ldns_resolver
*r
, const ldns_rr
*rr
)
338 if ((!rr
) || (ldns_rr_get_type(rr
) != LDNS_RR_TYPE_A
&&
339 ldns_rr_get_type(rr
) != LDNS_RR_TYPE_AAAA
)) {
340 return LDNS_STATUS_ERR
;
342 address
= ldns_rr_rdf(rr
, 0); /* extract the ip number */
344 return ldns_resolver_push_nameserver(r
, address
);
346 return LDNS_STATUS_ERR
;
351 ldns_resolver_push_nameserver_rr_list(ldns_resolver
*r
, const ldns_rr_list
*rrlist
)
357 stat
= LDNS_STATUS_OK
;
359 for(i
= 0; i
< ldns_rr_list_rr_count(rrlist
); i
++) {
360 rr
= ldns_rr_list_rr(rrlist
, i
);
361 if (ldns_resolver_push_nameserver_rr(r
, rr
) != LDNS_STATUS_OK
) {
362 stat
= LDNS_STATUS_ERR
;
368 return LDNS_STATUS_ERR
;
373 ldns_resolver_set_edns_udp_size(ldns_resolver
*r
, uint16_t s
)
375 r
->_edns_udp_size
= s
;
379 ldns_resolver_set_recursive(ldns_resolver
*r
, bool re
)
385 ldns_resolver_set_dnssec(ldns_resolver
*r
, bool d
)
391 ldns_resolver_set_dnssec_cd(ldns_resolver
*r
, bool d
)
397 ldns_resolver_set_dnssec_anchors(ldns_resolver
*r
, ldns_rr_list
* l
)
399 r
->_dnssec_anchors
= l
;
403 ldns_resolver_push_dnssec_anchor(ldns_resolver
*r
, ldns_rr
*rr
)
405 ldns_rr_list
* trust_anchors
;
407 if ((!rr
) || (ldns_rr_get_type(rr
) != LDNS_RR_TYPE_DNSKEY
&&
408 ldns_rr_get_type(rr
) != LDNS_RR_TYPE_DS
)) {
410 return LDNS_STATUS_ERR
;
413 if (!(trust_anchors
= ldns_resolver_dnssec_anchors(r
))) { /* Initialize */
414 trust_anchors
= ldns_rr_list_new();
415 ldns_resolver_set_dnssec_anchors(r
, trust_anchors
);
418 return (ldns_rr_list_push_rr(trust_anchors
, ldns_rr_clone(rr
))) ? LDNS_STATUS_OK
: LDNS_STATUS_ERR
;
422 ldns_resolver_set_igntc(ldns_resolver
*r
, bool i
)
428 ldns_resolver_set_usevc(ldns_resolver
*r
, bool vc
)
434 ldns_resolver_set_debug(ldns_resolver
*r
, bool d
)
440 ldns_resolver_set_ip6(ldns_resolver
*r
, uint8_t ip6
)
446 ldns_resolver_set_fail(ldns_resolver
*r
, bool f
)
452 ldns_resolver_set_searchlist_count(ldns_resolver
*r
, size_t c
)
454 r
->_searchlist_count
= c
;
458 ldns_resolver_set_nameserver_count(ldns_resolver
*r
, size_t c
)
460 r
->_nameserver_count
= c
;
464 ldns_resolver_set_dnsrch(ldns_resolver
*r
, bool d
)
470 ldns_resolver_set_retry(ldns_resolver
*r
, uint8_t retry
)
476 ldns_resolver_set_retrans(ldns_resolver
*r
, uint8_t retrans
)
478 r
->_retrans
= retrans
;
482 ldns_resolver_set_fallback(ldns_resolver
*r
, bool fallback
)
484 r
->_fallback
= fallback
;
488 ldns_resolver_set_nameservers(ldns_resolver
*r
, ldns_rdf
**n
)
494 ldns_resolver_set_defnames(ldns_resolver
*r
, bool d
)
500 ldns_resolver_set_rtt(ldns_resolver
*r
, size_t *rtt
)
506 ldns_resolver_set_nameserver_rtt(ldns_resolver
*r
, size_t pos
, size_t value
)
512 rtt
= ldns_resolver_rtt(r
);
514 if (pos
>= ldns_resolver_nameserver_count(r
)) {
523 ldns_resolver_incr_nameserver_count(ldns_resolver
*r
)
527 c
= ldns_resolver_nameserver_count(r
);
528 ldns_resolver_set_nameserver_count(r
, ++c
);
532 ldns_resolver_dec_nameserver_count(ldns_resolver
*r
)
536 c
= ldns_resolver_nameserver_count(r
);
540 ldns_resolver_set_nameserver_count(r
, --c
);
545 ldns_resolver_set_domain(ldns_resolver
*r
, ldns_rdf
*d
)
551 ldns_resolver_set_timeout(ldns_resolver
*r
, struct timeval timeout
)
553 r
->_timeout
.tv_sec
= timeout
.tv_sec
;
554 r
->_timeout
.tv_usec
= timeout
.tv_usec
;
558 ldns_resolver_push_searchlist(ldns_resolver
*r
, ldns_rdf
*d
)
560 ldns_rdf
**searchlist
;
563 if (ldns_rdf_get_type(d
) != LDNS_RDF_TYPE_DNAME
) {
567 list_count
= ldns_resolver_searchlist_count(r
);
568 searchlist
= ldns_resolver_searchlist(r
);
570 searchlist
= LDNS_XREALLOC(searchlist
, ldns_rdf
*, (list_count
+ 1));
572 r
->_searchlist
= searchlist
;
574 searchlist
[list_count
] = ldns_rdf_clone(d
);
575 ldns_resolver_set_searchlist_count(r
, list_count
+ 1);
576 } /* no way to report mem err */
580 ldns_resolver_set_tsig_keyname(ldns_resolver
*r
, const char *tsig_keyname
)
582 LDNS_FREE(r
->_tsig_keyname
);
583 r
->_tsig_keyname
= strdup(tsig_keyname
);
587 ldns_resolver_set_tsig_algorithm(ldns_resolver
*r
, const char *tsig_algorithm
)
589 LDNS_FREE(r
->_tsig_algorithm
);
590 r
->_tsig_algorithm
= strdup(tsig_algorithm
);
594 ldns_resolver_set_tsig_keydata(ldns_resolver
*r
, const char *tsig_keydata
)
596 LDNS_FREE(r
->_tsig_keydata
);
597 r
->_tsig_keydata
= strdup(tsig_keydata
);
601 ldns_resolver_set_random(ldns_resolver
*r
, bool b
)
606 /* more sophisticated functions */
608 ldns_resolver_new(void)
612 r
= LDNS_MALLOC(ldns_resolver
);
617 r
->_searchlist
= NULL
;
618 r
->_nameservers
= NULL
;
621 /* defaults are filled out */
622 ldns_resolver_set_searchlist_count(r
, 0);
623 ldns_resolver_set_nameserver_count(r
, 0);
624 ldns_resolver_set_usevc(r
, 0);
625 ldns_resolver_set_port(r
, LDNS_PORT
);
626 ldns_resolver_set_domain(r
, NULL
);
627 ldns_resolver_set_defnames(r
, false);
628 ldns_resolver_set_retry(r
, 3);
629 ldns_resolver_set_retrans(r
, 2);
630 ldns_resolver_set_fallback(r
, true);
631 ldns_resolver_set_fail(r
, false);
632 ldns_resolver_set_edns_udp_size(r
, 0);
633 ldns_resolver_set_dnssec(r
, false);
634 ldns_resolver_set_dnssec_cd(r
, false);
635 ldns_resolver_set_dnssec_anchors(r
, NULL
);
636 ldns_resolver_set_ip6(r
, LDNS_RESOLV_INETANY
);
637 ldns_resolver_set_igntc(r
, false);
638 ldns_resolver_set_recursive(r
, false);
639 ldns_resolver_set_dnsrch(r
, true);
640 ldns_resolver_set_source(r
, NULL
);
641 ldns_resolver_set_ixfr_serial(r
, 0);
643 /* randomize the nameserver to be queried
644 * when there are multiple
646 ldns_resolver_set_random(r
, true);
648 ldns_resolver_set_debug(r
, 0);
650 r
->_timeout
.tv_sec
= LDNS_DEFAULT_TIMEOUT_SEC
;
651 r
->_timeout
.tv_usec
= LDNS_DEFAULT_TIMEOUT_USEC
;
654 r
->_axfr_soa_count
= 0;
656 r
->_cur_axfr_pkt
= NULL
;
658 r
->_tsig_keyname
= NULL
;
659 r
->_tsig_keydata
= NULL
;
660 r
->_tsig_algorithm
= NULL
;
665 ldns_resolver_clone(ldns_resolver
*src
)
672 if (!(dst
= LDNS_MALLOC(ldns_resolver
))) return NULL
;
673 (void) memcpy(dst
, src
, sizeof(ldns_resolver
));
675 if (dst
->_searchlist_count
== 0)
676 dst
->_searchlist
= NULL
;
678 if (!(dst
->_searchlist
=
679 LDNS_XMALLOC(ldns_rdf
*, dst
->_searchlist_count
)))
681 for (i
= 0; i
< dst
->_searchlist_count
; i
++)
682 if (!(dst
->_searchlist
[i
] =
683 ldns_rdf_clone(src
->_searchlist
[i
]))) {
684 dst
->_searchlist_count
= i
;
685 goto error_searchlist
;
688 if (dst
->_nameserver_count
== 0) {
689 dst
->_nameservers
= NULL
;
692 if (!(dst
->_nameservers
=
693 LDNS_XMALLOC(ldns_rdf
*, dst
->_nameserver_count
)))
694 goto error_searchlist
;
695 for (i
= 0; i
< dst
->_nameserver_count
; i
++)
696 if (!(dst
->_nameservers
[i
] =
697 ldns_rdf_clone(src
->_nameservers
[i
]))) {
698 dst
->_nameserver_count
= i
;
699 goto error_nameservers
;
702 LDNS_XMALLOC(size_t, dst
->_nameserver_count
)))
703 goto error_nameservers
;
704 (void) memcpy(dst
->_rtt
, src
->_rtt
,
705 sizeof(size_t) * dst
->_nameserver_count
);
707 if (dst
->_domain
&& (!(dst
->_domain
= ldns_rdf_clone(src
->_domain
))))
710 if (dst
->_tsig_keyname
&&
711 (!(dst
->_tsig_keyname
= strdup(src
->_tsig_keyname
))))
714 if (dst
->_tsig_keydata
&&
715 (!(dst
->_tsig_keydata
= strdup(src
->_tsig_keydata
))))
716 goto error_tsig_keyname
;
718 if (dst
->_tsig_algorithm
&&
719 (!(dst
->_tsig_algorithm
= strdup(src
->_tsig_algorithm
))))
720 goto error_tsig_keydata
;
722 if (dst
->_cur_axfr_pkt
&&
723 (!(dst
->_cur_axfr_pkt
= ldns_pkt_clone(src
->_cur_axfr_pkt
))))
724 goto error_tsig_algorithm
;
726 if (dst
->_dnssec_anchors
&&
727 (!(dst
->_dnssec_anchors
=ldns_rr_list_clone(src
->_dnssec_anchors
))))
728 goto error_cur_axfr_pkt
;
733 ldns_pkt_free(dst
->_cur_axfr_pkt
);
734 error_tsig_algorithm
:
735 LDNS_FREE(dst
->_tsig_algorithm
);
737 LDNS_FREE(dst
->_tsig_keydata
);
739 LDNS_FREE(dst
->_tsig_keyname
);
741 ldns_rdf_deep_free(dst
->_domain
);
743 LDNS_FREE(dst
->_rtt
);
745 for (i
= 0; i
< dst
->_nameserver_count
; i
++)
746 ldns_rdf_deep_free(dst
->_nameservers
[i
]);
747 LDNS_FREE(dst
->_nameservers
);
749 for (i
= 0; i
< dst
->_searchlist_count
; i
++)
750 ldns_rdf_deep_free(dst
->_searchlist
[i
]);
751 LDNS_FREE(dst
->_searchlist
);
759 ldns_resolver_new_frm_fp(ldns_resolver
**res
, FILE *fp
)
761 return ldns_resolver_new_frm_fp_l(res
, fp
, NULL
);
765 ldns_resolver_new_frm_fp_l(ldns_resolver
**res
, FILE *fp
, int *line_nr
)
767 ldns_resolver
*r
= NULL
;
768 const char *keyword
[LDNS_RESOLV_KEYWORDS
];
769 char word
[LDNS_MAX_LINELEN
+ 1];
778 int lnr
= 0, oldline
;
780 if(!line_nr
) line_nr
= &lnr
;
783 myfp
= fopen(LDNS_RESOLV_CONF
, "r");
785 return LDNS_STATUS_FILE_ERR
;
791 * 1: default domain dname
792 * 2: NS aaaa or a record
795 /* recognized keywords */
796 keyword
[LDNS_RESOLV_NAMESERVER
] = "nameserver";
797 keyword
[LDNS_RESOLV_DEFDOMAIN
] = "domain";
798 keyword
[LDNS_RESOLV_SEARCH
] = "search";
799 /* these two are read but not used atm TODO */
800 keyword
[LDNS_RESOLV_SORTLIST
] = "sortlist";
801 keyword
[LDNS_RESOLV_OPTIONS
] = "options";
802 keyword
[LDNS_RESOLV_ANCHOR
] = "anchor";
804 r
= ldns_resolver_new();
806 if(!fp
) fclose(myfp
);
807 return LDNS_STATUS_MEM_ERR
;
813 expect
= LDNS_RESOLV_KEYWORD
;
816 if (word
[0] == '#') {
818 if(oldline
== *line_nr
) {
819 /* skip until end of line */
823 } while(c
!= EOF
&& c
!= '\n');
824 if(c
=='\n') (*line_nr
)++;
826 /* and read next to prepare for further parsing */
832 case LDNS_RESOLV_KEYWORD
:
834 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
836 if(word
[0] == '#') continue;
837 for(i
= 0; i
< LDNS_RESOLV_KEYWORDS
; i
++) {
838 if (strcasecmp(keyword
[i
], word
) == 0) {
839 /* chosen the keyword and
840 * expect values carefully
846 /* no keyword recognized */
847 if (expect
== LDNS_RESOLV_KEYWORD
) {
850 ldns_resolver_deep_free(r);
851 if(!fp) fclose(myfp);
852 return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
857 case LDNS_RESOLV_DEFDOMAIN
:
858 /* default domain dname */
859 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
861 if(!fp
) fclose(myfp
);
862 ldns_resolver_deep_free(r
);
863 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
;
866 expect
= LDNS_RESOLV_KEYWORD
;
869 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME
, word
);
871 if(!fp
) fclose(myfp
);
872 ldns_resolver_deep_free(r
);
873 return LDNS_STATUS_SYNTAX_DNAME_ERR
;
876 /* DOn't free, because we copy the pointer */
877 ldns_resolver_set_domain(r
, tmp
);
878 expect
= LDNS_RESOLV_KEYWORD
;
880 case LDNS_RESOLV_NAMESERVER
:
881 /* NS aaaa or a record */
882 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
884 if(!fp
) fclose(myfp
);
885 ldns_resolver_deep_free(r
);
886 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
;
889 expect
= LDNS_RESOLV_KEYWORD
;
892 if(strchr(word
, '%')) {
893 /* snip off interface labels,
894 * fe80::222:19ff:fe31:4222%eth0 */
895 strchr(word
, '%')[0]=0;
897 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA
, word
);
900 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A
, word
);
902 /* could not parse it, exit */
904 ldns_resolver_deep_free(r
);
905 if(!fp
) fclose(myfp
);
906 return LDNS_STATUS_SYNTAX_ERR
;
908 (void)ldns_resolver_push_nameserver(r
, tmp
);
909 ldns_rdf_deep_free(tmp
);
910 expect
= LDNS_RESOLV_KEYWORD
;
912 case LDNS_RESOLV_SEARCH
:
913 /* search list domain dname */
914 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_SKIP_SPACE
, 0, line_nr
);
915 b
= LDNS_MALLOC(ldns_buffer
);
917 ldns_resolver_deep_free(r
);
918 if(!fp
) fclose(myfp
);
919 return LDNS_STATUS_MEM_ERR
;
922 ldns_buffer_new_frm_data(b
, word
, (size_t) gtr
);
923 if(ldns_buffer_status(b
) != LDNS_STATUS_OK
) {
925 ldns_resolver_deep_free(r
);
926 if(!fp
) fclose(myfp
);
927 return LDNS_STATUS_MEM_ERR
;
929 bgtr
= ldns_bget_token(b
, word
, LDNS_PARSE_NORMAL
, (size_t) gtr
+ 1);
933 expect
= LDNS_RESOLV_KEYWORD
;
936 tmp
= ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME
, word
);
938 ldns_resolver_deep_free(r
);
940 if(!fp
) fclose(myfp
);
941 return LDNS_STATUS_SYNTAX_DNAME_ERR
;
944 ldns_resolver_push_searchlist(r
, tmp
);
946 ldns_rdf_deep_free(tmp
);
947 bgtr
= ldns_bget_token(b
, word
, LDNS_PARSE_NORMAL
,
951 if (expect
!= LDNS_RESOLV_KEYWORD
) {
953 expect
= LDNS_RESOLV_KEYWORD
;
956 case LDNS_RESOLV_SORTLIST
:
957 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_SKIP_SPACE
, 0, line_nr
);
958 /* sortlist not implemented atm */
959 expect
= LDNS_RESOLV_KEYWORD
;
961 case LDNS_RESOLV_OPTIONS
:
962 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_SKIP_SPACE
, 0, line_nr
);
963 /* options not implemented atm */
964 expect
= LDNS_RESOLV_KEYWORD
;
966 case LDNS_RESOLV_ANCHOR
:
967 /* a file containing a DNSSEC trust anchor */
968 gtr
= ldns_fget_token_l(myfp
, word
, LDNS_PARSE_NORMAL
, 0, line_nr
);
970 ldns_resolver_deep_free(r
);
971 if(!fp
) fclose(myfp
);
972 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
;
975 expect
= LDNS_RESOLV_KEYWORD
;
980 tmp_rr
= ldns_read_anchor_file(word
);
981 (void) ldns_resolver_push_dnssec_anchor(r
, tmp_rr
);
982 ldns_rr_free(tmp_rr
);
984 expect
= LDNS_RESOLV_KEYWORD
;
994 return LDNS_STATUS_OK
;
996 ldns_resolver_deep_free(r
);
997 return LDNS_STATUS_NULL
;
1002 ldns_resolver_new_frm_file(ldns_resolver
**res
, const char *filename
)
1009 fp
= fopen(LDNS_RESOLV_CONF
, "r");
1012 fp
= fopen(filename
, "r");
1015 return LDNS_STATUS_FILE_ERR
;
1018 s
= ldns_resolver_new_frm_fp(&r
, fp
);
1020 if (s
== LDNS_STATUS_OK
) {
1023 return LDNS_STATUS_OK
;
1025 ldns_resolver_free(r
);
1026 return LDNS_STATUS_NULL
;
1033 ldns_resolver_free(ldns_resolver
*res
)
1039 ldns_resolver_deep_free(ldns_resolver
*res
)
1044 close_socket(res
->_socket
);
1046 if (res
->_searchlist
) {
1047 for (i
= 0; i
< ldns_resolver_searchlist_count(res
); i
++) {
1048 ldns_rdf_deep_free(res
->_searchlist
[i
]);
1050 LDNS_FREE(res
->_searchlist
);
1052 if (res
->_nameservers
) {
1053 for (i
= 0; i
< res
->_nameserver_count
; i
++) {
1054 ldns_rdf_deep_free(res
->_nameservers
[i
]);
1056 LDNS_FREE(res
->_nameservers
);
1058 if (ldns_resolver_domain(res
)) {
1059 ldns_rdf_deep_free(ldns_resolver_domain(res
));
1061 if (res
->_tsig_keyname
) {
1062 LDNS_FREE(res
->_tsig_keyname
);
1064 if (res
->_tsig_keydata
) {
1065 LDNS_FREE(res
->_tsig_keydata
);
1067 if (res
->_tsig_algorithm
) {
1068 LDNS_FREE(res
->_tsig_algorithm
);
1071 if (res
->_cur_axfr_pkt
) {
1072 ldns_pkt_free(res
->_cur_axfr_pkt
);
1076 LDNS_FREE(res
->_rtt
);
1078 if (res
->_dnssec_anchors
) {
1079 ldns_rr_list_deep_free(res
->_dnssec_anchors
);
1086 ldns_resolver_search_status(ldns_pkt
** pkt
,
1087 ldns_resolver
*r
, const ldns_rdf
*name
,
1088 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
1091 ldns_rdf
**search_list
;
1093 ldns_status s
= LDNS_STATUS_OK
;
1094 ldns_rdf root_dname
= { 1, LDNS_RDF_TYPE_DNAME
, (void *)"" };
1096 if (ldns_dname_absolute(name
)) {
1098 return ldns_resolver_query_status(pkt
, r
, name
, t
, c
, flags
);
1099 } else if (ldns_resolver_dnsrch(r
)) {
1100 search_list
= ldns_resolver_searchlist(r
);
1101 for (i
= 0; i
<= ldns_resolver_searchlist_count(r
); i
++) {
1102 if (i
== ldns_resolver_searchlist_count(r
)) {
1103 new_name
= ldns_dname_cat_clone(name
,
1106 new_name
= ldns_dname_cat_clone(name
,
1110 s
= ldns_resolver_query_status(pkt
, r
,
1111 new_name
, t
, c
, flags
);
1112 ldns_rdf_deep_free(new_name
);
1115 if (s
== LDNS_STATUS_OK
&&
1116 ldns_pkt_get_rcode(*pkt
) ==
1117 LDNS_RCODE_NOERROR
) {
1119 return LDNS_STATUS_OK
;
1121 ldns_pkt_free(*pkt
);
1130 ldns_resolver_search(const ldns_resolver
*r
,const ldns_rdf
*name
,
1131 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
1133 ldns_pkt
* pkt
= NULL
;
1134 if (ldns_resolver_search_status(&pkt
, (ldns_resolver
*)r
,
1135 name
, t
, c
, flags
) != LDNS_STATUS_OK
) {
1143 ldns_resolver_query_status(ldns_pkt
** pkt
,
1144 ldns_resolver
*r
, const ldns_rdf
*name
,
1145 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
1150 if (!ldns_resolver_defnames(r
) || !ldns_resolver_domain(r
)) {
1151 return ldns_resolver_send(pkt
, r
, name
, t
, c
, flags
);
1154 newname
= ldns_dname_cat_clone(name
, ldns_resolver_domain(r
));
1156 return LDNS_STATUS_MEM_ERR
;
1158 status
= ldns_resolver_send(pkt
, r
, newname
, t
, c
, flags
);
1159 ldns_rdf_free(newname
);
1164 ldns_resolver_query(const ldns_resolver
*r
, const ldns_rdf
*name
,
1165 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
1167 ldns_pkt
* pkt
= NULL
;
1168 if (ldns_resolver_query_status(&pkt
, (ldns_resolver
*)r
,
1169 name
, t
, c
, flags
) != LDNS_STATUS_OK
) {
1177 ldns_resolver_backup_rtt(ldns_resolver
*r
)
1180 size_t *old_rtt
= ldns_resolver_rtt(r
);
1182 if (old_rtt
&& ldns_resolver_nameserver_count(r
)) {
1183 new_rtt
= LDNS_XMALLOC(size_t
1184 , ldns_resolver_nameserver_count(r
));
1185 if (!new_rtt
) return NULL
;
1186 memcpy(new_rtt
, old_rtt
, sizeof(size_t)
1187 * ldns_resolver_nameserver_count(r
));
1188 ldns_resolver_set_rtt(r
, new_rtt
);
1195 ldns_resolver_restore_rtt(ldns_resolver
*r
, size_t *old_rtt
)
1197 size_t *cur_rtt
= ldns_resolver_rtt(r
);
1202 ldns_resolver_set_rtt(r
, old_rtt
);
1206 ldns_resolver_send_pkt(ldns_pkt
**answer
, ldns_resolver
*r
,
1207 ldns_pkt
*query_pkt
)
1209 ldns_pkt
*answer_pkt
= NULL
;
1210 ldns_status stat
= LDNS_STATUS_OK
;
1213 stat
= ldns_send(&answer_pkt
, (ldns_resolver
*)r
, query_pkt
);
1214 if (stat
!= LDNS_STATUS_OK
) {
1216 ldns_pkt_free(answer_pkt
);
1220 /* if tc=1 fall back to EDNS and/or TCP */
1221 /* check for tcp first (otherwise we don't care about tc=1) */
1222 if (!ldns_resolver_usevc(r
) && ldns_resolver_fallback(r
)) {
1223 if (ldns_pkt_tc(answer_pkt
)) {
1224 /* was EDNS0 set? */
1225 if (ldns_pkt_edns_udp_size(query_pkt
) == 0) {
1226 ldns_pkt_set_edns_udp_size(query_pkt
1228 ldns_pkt_free(answer_pkt
);
1230 /* Nameservers should not become
1231 * unreachable because fragments are
1232 * dropped (network error). We might
1233 * still have success with TCP.
1234 * Therefore maintain reachability
1235 * statuses of the nameservers by
1236 * backup and restore the rtt list.
1238 rtt
= ldns_resolver_backup_rtt(r
);
1239 stat
= ldns_send(&answer_pkt
, r
1241 ldns_resolver_restore_rtt(r
, rtt
);
1243 /* either way, if it is still truncated, use TCP */
1244 if (stat
!= LDNS_STATUS_OK
||
1245 ldns_pkt_tc(answer_pkt
)) {
1246 ldns_resolver_set_usevc(r
, true);
1247 ldns_pkt_free(answer_pkt
);
1249 stat
= ldns_send(&answer_pkt
, r
, query_pkt
);
1250 ldns_resolver_set_usevc(r
, false);
1256 if (answer
&& answer_pkt
) {
1257 *answer
= answer_pkt
;
1264 ldns_resolver_prepare_query_pkt(ldns_pkt
**query_pkt
, ldns_resolver
*r
,
1265 const ldns_rdf
*name
, ldns_rr_type t
,
1266 ldns_rr_class c
, uint16_t flags
)
1269 ldns_rr
* soa
= NULL
;
1271 /* prepare a question pkt from the parameters
1272 * and then send this */
1273 if (t
== LDNS_RR_TYPE_IXFR
) {
1274 ldns_rdf
*owner_rdf
;
1275 ldns_rdf
*mname_rdf
;
1276 ldns_rdf
*rname_rdf
;
1277 ldns_rdf
*serial_rdf
;
1278 ldns_rdf
*refresh_rdf
;
1279 ldns_rdf
*retry_rdf
;
1280 ldns_rdf
*expire_rdf
;
1281 ldns_rdf
*minimum_rdf
;
1282 soa
= ldns_rr_new();
1285 return LDNS_STATUS_ERR
;
1287 owner_rdf
= ldns_rdf_clone(name
);
1290 return LDNS_STATUS_ERR
;
1292 ldns_rr_set_owner(soa
, owner_rdf
);
1293 ldns_rr_set_type(soa
, LDNS_RR_TYPE_SOA
);
1294 ldns_rr_set_class(soa
, c
);
1295 ldns_rr_set_question(soa
, false);
1296 if (ldns_str2rdf_dname(&mname_rdf
, ".") != LDNS_STATUS_OK
) {
1298 return LDNS_STATUS_ERR
;
1299 } else ldns_rr_push_rdf(soa
, mname_rdf
);
1300 if (ldns_str2rdf_dname(&rname_rdf
, ".") != LDNS_STATUS_OK
) {
1302 return LDNS_STATUS_ERR
;
1303 } else ldns_rr_push_rdf(soa
, rname_rdf
);
1304 serial_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, ldns_resolver_get_ixfr_serial(r
));
1307 return LDNS_STATUS_ERR
;
1308 } else ldns_rr_push_rdf(soa
, serial_rdf
);
1309 refresh_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
1312 return LDNS_STATUS_ERR
;
1313 } else ldns_rr_push_rdf(soa
, refresh_rdf
);
1314 retry_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
1317 return LDNS_STATUS_ERR
;
1318 } else ldns_rr_push_rdf(soa
, retry_rdf
);
1319 expire_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
1322 return LDNS_STATUS_ERR
;
1323 } else ldns_rr_push_rdf(soa
, expire_rdf
);
1324 minimum_rdf
= ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32
, 0);
1327 return LDNS_STATUS_ERR
;
1328 } else ldns_rr_push_rdf(soa
, minimum_rdf
);
1330 *query_pkt
= ldns_pkt_ixfr_request_new(ldns_rdf_clone(name
),
1333 *query_pkt
= ldns_pkt_query_new(ldns_rdf_clone(name
), t
, c
, flags
);
1337 return LDNS_STATUS_ERR
;
1340 /* set DO bit if necessary */
1341 if (ldns_resolver_dnssec(r
)) {
1342 if (ldns_resolver_edns_udp_size(r
) == 0) {
1343 ldns_resolver_set_edns_udp_size(r
, 4096);
1345 ldns_pkt_set_edns_do(*query_pkt
, true);
1346 if (ldns_resolver_dnssec_cd(r
) || (flags
& LDNS_CD
)) {
1347 ldns_pkt_set_cd(*query_pkt
, true);
1351 /* transfer the udp_edns_size from the resolver to the packet */
1352 if (ldns_resolver_edns_udp_size(r
) != 0) {
1353 ldns_pkt_set_edns_udp_size(*query_pkt
, ldns_resolver_edns_udp_size(r
));
1356 /* set the timestamp */
1357 now
.tv_sec
= time(NULL
);
1359 ldns_pkt_set_timestamp(*query_pkt
, now
);
1362 if (ldns_resolver_debug(r
)) {
1363 ldns_pkt_print(stdout
, *query_pkt
);
1366 /* only set the id if it is not set yet */
1367 if (ldns_pkt_id(*query_pkt
) == 0) {
1368 ldns_pkt_set_random_id(*query_pkt
);
1371 return LDNS_STATUS_OK
;
1375 ldns_resolver_send(ldns_pkt
**answer
, ldns_resolver
*r
, const ldns_rdf
*name
,
1376 ldns_rr_type t
, ldns_rr_class c
, uint16_t flags
)
1378 ldns_pkt
*query_pkt
;
1379 ldns_pkt
*answer_pkt
;
1383 assert(name
!= NULL
);
1387 /* do all the preprocessing here, then fire of an query to
1394 c
= LDNS_RR_CLASS_IN
;
1396 if (0 == ldns_resolver_nameserver_count(r
)) {
1397 return LDNS_STATUS_RES_NO_NS
;
1399 if (ldns_rdf_get_type(name
) != LDNS_RDF_TYPE_DNAME
) {
1400 return LDNS_STATUS_RES_QUERY
;
1403 status
= ldns_resolver_prepare_query_pkt(&query_pkt
, r
, name
,
1405 if (status
!= LDNS_STATUS_OK
) {
1409 /* if tsig values are set, tsign it */
1410 /* TODO: make last 3 arguments optional too? maybe make complete
1411 rr instead of separate values in resolver (and packet)
1413 should this go in pkt_prepare?
1415 if (ldns_resolver_tsig_keyname(r
) && ldns_resolver_tsig_keydata(r
)) {
1417 status
= ldns_pkt_tsig_sign(query_pkt
,
1418 ldns_resolver_tsig_keyname(r
),
1419 ldns_resolver_tsig_keydata(r
),
1420 300, ldns_resolver_tsig_algorithm(r
), NULL
);
1421 if (status
!= LDNS_STATUS_OK
) {
1422 ldns_pkt_free(query_pkt
);
1423 return LDNS_STATUS_CRYPTO_TSIG_ERR
;
1426 ldns_pkt_free(query_pkt
);
1427 return LDNS_STATUS_CRYPTO_TSIG_ERR
;
1428 #endif /* HAVE_SSL */
1431 status
= ldns_resolver_send_pkt(&answer_pkt
, r
, query_pkt
);
1432 ldns_pkt_free(query_pkt
);
1434 /* allows answer to be NULL when not interested in return value */
1436 *answer
= answer_pkt
;
1442 ldns_axfr_next(ldns_resolver
*resolver
)
1445 uint8_t *packet_wire
;
1446 size_t packet_wire_size
;
1449 /* check if start() has been called */
1450 if (!resolver
|| resolver
->_socket
== -1) {
1454 if (resolver
->_cur_axfr_pkt
) {
1455 if (resolver
->_axfr_i
== ldns_pkt_ancount(resolver
->_cur_axfr_pkt
)) {
1456 ldns_pkt_free(resolver
->_cur_axfr_pkt
);
1457 resolver
->_cur_axfr_pkt
= NULL
;
1458 return ldns_axfr_next(resolver
);
1460 cur_rr
= ldns_rr_clone(ldns_rr_list_rr(
1461 ldns_pkt_answer(resolver
->_cur_axfr_pkt
),
1462 resolver
->_axfr_i
));
1463 resolver
->_axfr_i
++;
1464 if (ldns_rr_get_type(cur_rr
) == LDNS_RR_TYPE_SOA
) {
1465 resolver
->_axfr_soa_count
++;
1466 if (resolver
->_axfr_soa_count
>= 2) {
1468 close_socket(resolver
->_socket
);
1470 ldns_pkt_free(resolver
->_cur_axfr_pkt
);
1471 resolver
->_cur_axfr_pkt
= NULL
;
1476 packet_wire
= ldns_tcp_read_wire_timeout(resolver
->_socket
, &packet_wire_size
, resolver
->_timeout
);
1480 status
= ldns_wire2pkt(&resolver
->_cur_axfr_pkt
, packet_wire
,
1482 LDNS_FREE(packet_wire
);
1484 resolver
->_axfr_i
= 0;
1485 if (status
!= LDNS_STATUS_OK
) {
1486 /* TODO: make status return type of this function (...api change) */
1488 fprintf(stderr
, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status
));
1491 /* we must now also close the socket, otherwise subsequent uses of the
1492 same resolver structure will fail because the link is still open or
1493 in an undefined state */
1495 close_socket(resolver
->_socket
);
1498 } else if (ldns_pkt_get_rcode(resolver
->_cur_axfr_pkt
) != 0) {
1500 ldns_lookup_table
*rcode
= ldns_lookup_by_id(
1501 ldns_rcodes
,(int) ldns_pkt_get_rcode(
1502 resolver
->_cur_axfr_pkt
));
1504 fprintf(stderr
, "Error in AXFR: %s\n",
1507 fprintf(stderr
, "Error in AXFR: %d\n",
1508 (int) ldns_pkt_get_rcode(
1509 resolver
->_cur_axfr_pkt
));
1513 /* we must now also close the socket, otherwise subsequent uses of the
1514 same resolver structure will fail because the link is still open or
1515 in an undefined state */
1517 close_socket(resolver
->_socket
);
1521 return ldns_axfr_next(resolver
);
1528 /* this function is needed to abort a transfer that is in progress;
1529 * without it an aborted transfer will lead to the AXFR code in the
1530 * library staying in an indetermined state because the socket for the
1531 * AXFR is never closed
1534 ldns_axfr_abort(ldns_resolver
*resolver
)
1536 /* Only abort if an actual AXFR is in progress */
1537 if (resolver
->_socket
!= -1)
1540 close(resolver
->_socket
);
1542 closesocket(resolver
->_socket
);
1544 resolver
->_socket
= -1;
1549 ldns_axfr_complete(const ldns_resolver
*res
)
1551 /* complete when soa count is 2? */
1552 return res
->_axfr_soa_count
== 2;
1556 ldns_axfr_last_pkt(const ldns_resolver
*res
)
1558 return res
->_cur_axfr_pkt
;
1562 ldns_resolver_set_ixfr_serial(ldns_resolver
*r
, uint32_t serial
)
1564 r
->_serial
= serial
;
1568 ldns_resolver_get_ixfr_serial(const ldns_resolver
*res
)
1570 return res
->_serial
;
1574 /* random isn't really that good */
1576 ldns_resolver_nameservers_randomize(ldns_resolver
*r
)
1579 ldns_rdf
**ns
, *tmpns
;
1580 size_t *rtt
, tmprtt
;
1582 /* should I check for ldns_resolver_random?? */
1585 ns
= ldns_resolver_nameservers(r
);
1586 rtt
= ldns_resolver_rtt(r
);
1587 for (i
= 0; i
< ldns_resolver_nameserver_count(r
); i
++) {
1588 j
= ldns_get_random() % ldns_resolver_nameserver_count(r
);
1596 ldns_resolver_set_nameservers(r
, ns
);