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];
256 nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count - 1));
257 rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
259 ldns_resolver_set_nameservers(r, nameservers);
260 ldns_resolver_set_rtt(r, rtt);
262 ldns_resolver_dec_nameserver_count(r);
267 ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n)
269 ldns_rdf **nameservers;
273 if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
274 ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
275 return LDNS_STATUS_ERR;
278 ns_count = ldns_resolver_nameserver_count(r);
279 nameservers = ldns_resolver_nameservers(r);
280 rtt = ldns_resolver_rtt(r);
282 /* make room for the next one */
283 nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
284 /* don't forget the rtt */
285 rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
287 /* set the new value in the resolver */
288 ldns_resolver_set_nameservers(r, nameservers);
290 /* slide n in its slot. */
291 /* we clone it here, because then we can free the original
292 * rr's where it stood */
293 nameservers[ns_count] = ldns_rdf_clone(n);
294 rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
295 ldns_resolver_incr_nameserver_count(r);
296 ldns_resolver_set_rtt(r, rtt);
297 return LDNS_STATUS_OK;
301 ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr)
304 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
305 ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
306 return LDNS_STATUS_ERR;
308 address = ldns_rr_rdf(rr, 0); /* extract the ip number */
310 return ldns_resolver_push_nameserver(r, address);
312 return LDNS_STATUS_ERR;
317 ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist)
323 stat = LDNS_STATUS_OK;
325 for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
326 rr = ldns_rr_list_rr(rrlist, i);
327 if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
328 stat = LDNS_STATUS_ERR;
333 return LDNS_STATUS_ERR;
338 ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
340 r->_edns_udp_size = s;
344 ldns_resolver_set_recursive(ldns_resolver *r, bool re)
350 ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
356 ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
362 ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
364 r->_dnssec_anchors = l;
368 ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
370 ldns_rr_list * trust_anchors;
372 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY)) {
373 return LDNS_STATUS_ERR;
376 if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
377 trust_anchors = ldns_rr_list_new();
378 ldns_resolver_set_dnssec_anchors(r, trust_anchors);
381 return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
385 ldns_resolver_set_igntc(ldns_resolver *r, bool i)
391 ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
397 ldns_resolver_set_debug(ldns_resolver *r, bool d)
403 ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
409 ldns_resolver_set_fail(ldns_resolver *r, bool f)
415 ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
417 r->_searchlist_count = c;
421 ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
423 r->_nameserver_count = c;
427 ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
433 ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
439 ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
441 r->_retrans = retrans;
445 ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
447 r->_fallback = fallback;
451 ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
457 ldns_resolver_set_defnames(ldns_resolver *r, bool d)
463 ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
469 ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
475 rtt = ldns_resolver_rtt(r);
477 if (pos >= ldns_resolver_nameserver_count(r)) {
486 ldns_resolver_incr_nameserver_count(ldns_resolver *r)
490 c = ldns_resolver_nameserver_count(r);
491 ldns_resolver_set_nameserver_count(r, ++c);
495 ldns_resolver_dec_nameserver_count(ldns_resolver *r)
499 c = ldns_resolver_nameserver_count(r);
503 ldns_resolver_set_nameserver_count(r, --c);
508 ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
514 ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
516 r->_timeout.tv_sec = timeout.tv_sec;
517 r->_timeout.tv_usec = timeout.tv_usec;
521 ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
523 ldns_rdf **searchlist;
526 if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
530 list_count = ldns_resolver_searchlist_count(r);
531 searchlist = ldns_resolver_searchlist(r);
533 searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
535 r->_searchlist = searchlist;
537 searchlist[list_count] = ldns_rdf_clone(d);
538 ldns_resolver_set_searchlist_count(r, list_count + 1);
543 ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname)
545 r->_tsig_keyname = tsig_keyname;
549 ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm)
551 r->_tsig_algorithm = tsig_algorithm;
555 ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata)
557 r->_tsig_keydata = tsig_keydata;
561 ldns_resolver_set_random(ldns_resolver *r, bool b)
566 /* more sophisticated functions */
568 ldns_resolver_new(void)
572 r = LDNS_MALLOC(ldns_resolver);
577 r->_searchlist = NULL;
578 r->_nameservers = NULL;
581 /* defaults are filled out */
582 ldns_resolver_set_searchlist_count(r, 0);
583 ldns_resolver_set_nameserver_count(r, 0);
584 ldns_resolver_set_usevc(r, 0);
585 ldns_resolver_set_port(r, LDNS_PORT);
586 ldns_resolver_set_domain(r, NULL);
587 ldns_resolver_set_defnames(r, false);
588 ldns_resolver_set_retry(r, 3);
589 ldns_resolver_set_retrans(r, 2);
590 ldns_resolver_set_fallback(r, true);
591 ldns_resolver_set_fail(r, false);
592 ldns_resolver_set_edns_udp_size(r, 0);
593 ldns_resolver_set_dnssec(r, false);
594 ldns_resolver_set_dnssec_cd(r, false);
595 ldns_resolver_set_dnssec_anchors(r, NULL);
596 ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
598 /* randomize the nameserver to be queried
599 * when there are multiple
601 ldns_resolver_set_random(r, true);
603 ldns_resolver_set_debug(r, 0);
605 r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
606 r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
609 r->_axfr_soa_count = 0;
611 r->_cur_axfr_pkt = NULL;
613 r->_tsig_keyname = NULL;
614 r->_tsig_keydata = NULL;
615 r->_tsig_algorithm = NULL;
620 ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
622 return ldns_resolver_new_frm_fp_l(res, fp, NULL);
626 ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
629 const char *keyword[LDNS_RESOLV_KEYWORDS];
630 char word[LDNS_MAX_LINELEN + 1];
643 * 1: default domain dname
644 * 2: NS aaaa or a record
647 /* recognized keywords */
648 keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
649 keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
650 keyword[LDNS_RESOLV_SEARCH] = "search";
651 /* these two are read but not used atm TODO */
652 keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
653 keyword[LDNS_RESOLV_OPTIONS] = "options";
654 keyword[LDNS_RESOLV_ANCHOR] = "anchor";
655 expect = LDNS_RESOLV_KEYWORD;
657 r = ldns_resolver_new();
659 return LDNS_STATUS_MEM_ERR;
666 if (word[0] == '#') {
667 /* read the rest of the line, should be 1 word */
668 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
669 /* prepare the next string for further parsing */
670 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
674 case LDNS_RESOLV_KEYWORD:
676 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
678 for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
679 if (strcasecmp(keyword[i], word) == 0) {
680 /* chosen the keyword and
681 * expect values carefully
687 /* no keyword recognized */
688 if (expect == LDNS_RESOLV_KEYWORD) {
691 ldns_resolver_deep_free(r);
692 return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
697 case LDNS_RESOLV_DEFDOMAIN:
698 /* default domain dname */
699 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
701 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
703 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
705 ldns_resolver_deep_free(r);
706 return LDNS_STATUS_SYNTAX_DNAME_ERR;
709 /* DOn't free, because we copy the pointer */
710 ldns_resolver_set_domain(r, tmp);
711 expect = LDNS_RESOLV_KEYWORD;
713 case LDNS_RESOLV_NAMESERVER:
714 /* NS aaaa or a record */
715 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
717 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
719 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
722 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
724 /* could not parse it, exit */
726 ldns_resolver_deep_free(r);
727 return LDNS_STATUS_SYNTAX_ERR;
729 (void)ldns_resolver_push_nameserver(r, tmp);
730 ldns_rdf_deep_free(tmp);
731 expect = LDNS_RESOLV_KEYWORD;
733 case LDNS_RESOLV_SEARCH:
734 /* search list domain dname */
735 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
736 b = LDNS_MALLOC(ldns_buffer);
737 ldns_buffer_new_frm_data(b, word, (size_t) gtr);
739 gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr);
741 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
743 ldns_resolver_deep_free(r);
744 return LDNS_STATUS_SYNTAX_DNAME_ERR;
747 ldns_resolver_push_searchlist(r, tmp);
749 ldns_rdf_deep_free(tmp);
750 gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr);
754 expect = LDNS_RESOLV_KEYWORD;
756 case LDNS_RESOLV_SORTLIST:
757 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
758 /* sortlist not implemented atm */
759 expect = LDNS_RESOLV_KEYWORD;
761 case LDNS_RESOLV_OPTIONS:
762 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
763 /* options not implemented atm */
764 expect = LDNS_RESOLV_KEYWORD;
766 case LDNS_RESOLV_ANCHOR:
767 /* a file containing a DNSSEC trust anchor */
768 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
770 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
774 tmp_rr = ldns_read_anchor_file(word);
775 (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
776 ldns_rr_free(tmp_rr);
778 expect = LDNS_RESOLV_KEYWORD;
785 return LDNS_STATUS_OK;
787 return LDNS_STATUS_NULL;
792 ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
799 fp = fopen(LDNS_RESOLV_CONF, "r");
802 fp = fopen(filename, "r");
805 return LDNS_STATUS_FILE_ERR;
808 s = ldns_resolver_new_frm_fp(&r, fp);
810 if (s == LDNS_STATUS_OK) {
813 return LDNS_STATUS_OK;
815 return LDNS_STATUS_NULL;
822 ldns_resolver_free(ldns_resolver *res)
828 ldns_resolver_deep_free(ldns_resolver *res)
833 if (res->_searchlist) {
834 for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
835 ldns_rdf_deep_free(res->_searchlist[i]);
837 LDNS_FREE(res->_searchlist);
839 if (res->_nameservers) {
840 for (i = 0; i < res->_nameserver_count; i++) {
841 ldns_rdf_deep_free(res->_nameservers[i]);
843 LDNS_FREE(res->_nameservers);
845 if (ldns_resolver_domain(res)) {
846 ldns_rdf_deep_free(ldns_resolver_domain(res));
848 if (ldns_resolver_tsig_keyname(res)) {
849 LDNS_FREE(res->_tsig_keyname);
852 if (res->_cur_axfr_pkt) {
853 ldns_pkt_free(res->_cur_axfr_pkt);
857 LDNS_FREE(res->_rtt);
859 if (res->_dnssec_anchors) {
860 ldns_rr_list_deep_free(res->_dnssec_anchors);
867 ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name,
868 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
873 ldns_rdf **search_list;
877 str_dname = ldns_rdf2str(name);
879 if (ldns_dname_str_absolute(str_dname)) {
881 return ldns_resolver_query(r, name, t, c, flags);
883 search_list = ldns_resolver_searchlist(r);
884 for (i = 0; i < ldns_resolver_searchlist_count(r); i++) {
885 new_name = ldns_dname_cat_clone(name, search_list[i]);
887 p = ldns_resolver_query(r, new_name, t, c, flags);
888 ldns_rdf_free(new_name);
898 ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
899 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
907 if (!ldns_resolver_defnames(r)) {
908 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name,
910 if (status == LDNS_STATUS_OK) {
916 fprintf(stderr, "error: %s\n", ldns_get_errorstr_by_id(status));
921 if (!ldns_resolver_domain(r)) {
922 /* _defnames is set, but the domain is not....?? */
923 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name,
925 if (status == LDNS_STATUS_OK) {
935 newname = ldns_dname_cat_clone((const ldns_rdf*)name, ldns_resolver_domain(r));
942 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, newname, t, c,
945 ldns_rdf_free(newname);
951 ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
954 ldns_pkt *answer_pkt = NULL;
955 ldns_status stat = LDNS_STATUS_OK;
957 stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
958 if (stat != LDNS_STATUS_OK) {
960 ldns_pkt_free(answer_pkt);
965 /* if tc=1 fall back to EDNS and/or TCP */
966 /* check for tcp first (otherwise we don't care about tc=1) */
967 if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
968 if (ldns_pkt_tc(answer_pkt)) {
970 if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
971 ldns_pkt_set_edns_udp_size(query_pkt, 4096);
972 ldns_pkt_free(answer_pkt);
973 stat = ldns_send(&answer_pkt, r, query_pkt);
975 /* either way, if it is still truncated, use TCP */
976 if (stat != LDNS_STATUS_OK ||
977 ldns_pkt_tc(answer_pkt)) {
978 ldns_resolver_set_usevc(r, true);
979 ldns_pkt_free(answer_pkt);
980 stat = ldns_send(&answer_pkt, r, query_pkt);
981 ldns_resolver_set_usevc(r, false);
989 *answer = answer_pkt;
996 ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
997 const ldns_rdf *name, ldns_rr_type t,
998 ldns_rr_class c, uint16_t flags)
1000 /* prepare a question pkt from the parameters
1001 * and then send this */
1002 *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
1004 return LDNS_STATUS_ERR;
1007 /* set DO bit if necessary */
1008 if (ldns_resolver_dnssec(r)) {
1009 if (ldns_resolver_edns_udp_size(r) == 0) {
1010 ldns_resolver_set_edns_udp_size(r, 4096);
1012 ldns_pkt_set_edns_do(*query_pkt, true);
1013 if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
1014 ldns_pkt_set_cd(*query_pkt, true);
1018 /* transfer the udp_edns_size from the resolver to the packet */
1019 if (ldns_resolver_edns_udp_size(r) != 0) {
1020 ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
1023 if (ldns_resolver_debug(r)) {
1024 ldns_pkt_print(stdout, *query_pkt);
1027 /* only set the id if it is not set yet */
1028 if (ldns_pkt_id(*query_pkt) == 0) {
1029 ldns_pkt_set_random_id(*query_pkt);
1032 return LDNS_STATUS_OK;
1037 ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
1038 ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1040 ldns_pkt *query_pkt;
1041 ldns_pkt *answer_pkt;
1045 assert(name != NULL);
1049 /* do all the preprocessing here, then fire of an query to
1056 c= LDNS_RR_CLASS_IN;
1058 if (0 == ldns_resolver_nameserver_count(r)) {
1059 return LDNS_STATUS_RES_NO_NS;
1061 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
1062 return LDNS_STATUS_RES_QUERY;
1065 status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
1067 if (status != LDNS_STATUS_OK) {
1071 /* if tsig values are set, tsign it */
1072 /* TODO: make last 3 arguments optional too? maybe make complete
1073 rr instead of seperate values in resolver (and packet)
1075 should this go in pkt_prepare?
1078 if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
1079 status = ldns_pkt_tsig_sign(query_pkt,
1080 ldns_resolver_tsig_keyname(r),
1081 ldns_resolver_tsig_keydata(r),
1082 300, ldns_resolver_tsig_algorithm(r), NULL);
1083 if (status != LDNS_STATUS_OK) {
1084 return LDNS_STATUS_CRYPTO_TSIG_ERR;
1088 return LDNS_STATUS_CRYPTO_TSIG_ERR;
1089 #endif /* HAVE_SSL */
1090 status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
1091 ldns_pkt_free(query_pkt);
1093 /* allows answer to be NULL when not interested in return value */
1095 *answer = answer_pkt;
1101 ldns_axfr_next(ldns_resolver *resolver)
1104 uint8_t *packet_wire;
1105 size_t packet_wire_size;
1106 ldns_lookup_table *rcode;
1109 /* check if start() has been called */
1110 if (!resolver || resolver->_socket == 0) {
1114 if (resolver->_cur_axfr_pkt) {
1115 if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
1116 ldns_pkt_free(resolver->_cur_axfr_pkt);
1117 resolver->_cur_axfr_pkt = NULL;
1118 return ldns_axfr_next(resolver);
1120 cur_rr = ldns_rr_clone(ldns_rr_list_rr(
1121 ldns_pkt_answer(resolver->_cur_axfr_pkt),
1122 resolver->_axfr_i));
1123 resolver->_axfr_i++;
1124 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
1125 resolver->_axfr_soa_count++;
1126 if (resolver->_axfr_soa_count >= 2) {
1127 close(resolver->_socket);
1128 resolver->_socket = 0;
1129 ldns_pkt_free(resolver->_cur_axfr_pkt);
1130 resolver->_cur_axfr_pkt = NULL;
1135 packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size);
1139 status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
1143 resolver->_axfr_i = 0;
1144 if (status != LDNS_STATUS_OK) {
1145 /* TODO: make status return type of this function (...api change) */
1146 fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
1148 } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
1149 rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt));
1150 fprintf(stderr, "Error in AXFR: %s\n", rcode->name);
1153 return ldns_axfr_next(resolver);
1161 ldns_axfr_complete(const ldns_resolver *res)
1163 /* complete when soa count is 2? */
1164 return res->_axfr_soa_count == 2;
1168 ldns_axfr_last_pkt(const ldns_resolver *res)
1170 return res->_cur_axfr_pkt;
1173 /* random isn't really that good */
1175 ldns_resolver_nameservers_randomize(ldns_resolver *r)
1178 ldns_rdf **ns, *tmp;
1180 /* should I check for ldns_resolver_random?? */
1183 ns = ldns_resolver_nameservers(r);
1185 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
1186 j = random() % ldns_resolver_nameserver_count(r);
1191 ldns_resolver_set_nameservers(r, ns);