17b5038d7SDag-Erling Smørgrav /*
27b5038d7SDag-Erling Smørgrav * resolver.c
37b5038d7SDag-Erling Smørgrav *
47b5038d7SDag-Erling Smørgrav * resolver implementation
57b5038d7SDag-Erling Smørgrav *
67b5038d7SDag-Erling Smørgrav * a Net::DNS like library for C
77b5038d7SDag-Erling Smørgrav *
87b5038d7SDag-Erling Smørgrav * (c) NLnet Labs, 2004-2006
97b5038d7SDag-Erling Smørgrav *
107b5038d7SDag-Erling Smørgrav * See the file LICENSE for the license
117b5038d7SDag-Erling Smørgrav */
127b5038d7SDag-Erling Smørgrav
137b5038d7SDag-Erling Smørgrav #include <ldns/config.h>
147b5038d7SDag-Erling Smørgrav
157b5038d7SDag-Erling Smørgrav #include <ldns/ldns.h>
167b5038d7SDag-Erling Smørgrav #include <strings.h>
177b5038d7SDag-Erling Smørgrav
187b5038d7SDag-Erling Smørgrav /* Access function for reading
197b5038d7SDag-Erling Smørgrav * and setting the different Resolver
207b5038d7SDag-Erling Smørgrav * options */
217b5038d7SDag-Erling Smørgrav
227b5038d7SDag-Erling Smørgrav /* read */
237b5038d7SDag-Erling Smørgrav uint16_t
ldns_resolver_port(const ldns_resolver * r)247b5038d7SDag-Erling Smørgrav ldns_resolver_port(const ldns_resolver *r)
257b5038d7SDag-Erling Smørgrav {
267b5038d7SDag-Erling Smørgrav return r->_port;
277b5038d7SDag-Erling Smørgrav }
287b5038d7SDag-Erling Smørgrav
2917d15b25SDag-Erling Smørgrav ldns_rdf *
ldns_resolver_source(const ldns_resolver * r)3017d15b25SDag-Erling Smørgrav ldns_resolver_source(const ldns_resolver *r)
3117d15b25SDag-Erling Smørgrav {
3217d15b25SDag-Erling Smørgrav return r->_source;
3317d15b25SDag-Erling Smørgrav }
3417d15b25SDag-Erling Smørgrav
357b5038d7SDag-Erling Smørgrav uint16_t
ldns_resolver_edns_udp_size(const ldns_resolver * r)367b5038d7SDag-Erling Smørgrav ldns_resolver_edns_udp_size(const ldns_resolver *r)
377b5038d7SDag-Erling Smørgrav {
387b5038d7SDag-Erling Smørgrav return r->_edns_udp_size;
397b5038d7SDag-Erling Smørgrav }
407b5038d7SDag-Erling Smørgrav
417b5038d7SDag-Erling Smørgrav uint8_t
ldns_resolver_retry(const ldns_resolver * r)427b5038d7SDag-Erling Smørgrav ldns_resolver_retry(const ldns_resolver *r)
437b5038d7SDag-Erling Smørgrav {
447b5038d7SDag-Erling Smørgrav return r->_retry;
457b5038d7SDag-Erling Smørgrav }
467b5038d7SDag-Erling Smørgrav
477b5038d7SDag-Erling Smørgrav uint8_t
ldns_resolver_retrans(const ldns_resolver * r)487b5038d7SDag-Erling Smørgrav ldns_resolver_retrans(const ldns_resolver *r)
497b5038d7SDag-Erling Smørgrav {
507b5038d7SDag-Erling Smørgrav return r->_retrans;
517b5038d7SDag-Erling Smørgrav }
527b5038d7SDag-Erling Smørgrav
537b5038d7SDag-Erling Smørgrav bool
ldns_resolver_fallback(const ldns_resolver * r)547b5038d7SDag-Erling Smørgrav ldns_resolver_fallback(const ldns_resolver *r)
557b5038d7SDag-Erling Smørgrav {
567b5038d7SDag-Erling Smørgrav return r->_fallback;
577b5038d7SDag-Erling Smørgrav }
587b5038d7SDag-Erling Smørgrav
597b5038d7SDag-Erling Smørgrav uint8_t
ldns_resolver_ip6(const ldns_resolver * r)607b5038d7SDag-Erling Smørgrav ldns_resolver_ip6(const ldns_resolver *r)
617b5038d7SDag-Erling Smørgrav {
627b5038d7SDag-Erling Smørgrav return r->_ip6;
637b5038d7SDag-Erling Smørgrav }
647b5038d7SDag-Erling Smørgrav
657b5038d7SDag-Erling Smørgrav bool
ldns_resolver_recursive(const ldns_resolver * r)667b5038d7SDag-Erling Smørgrav ldns_resolver_recursive(const ldns_resolver *r)
677b5038d7SDag-Erling Smørgrav {
687b5038d7SDag-Erling Smørgrav return r->_recursive;
697b5038d7SDag-Erling Smørgrav }
707b5038d7SDag-Erling Smørgrav
717b5038d7SDag-Erling Smørgrav bool
ldns_resolver_debug(const ldns_resolver * r)727b5038d7SDag-Erling Smørgrav ldns_resolver_debug(const ldns_resolver *r)
737b5038d7SDag-Erling Smørgrav {
747b5038d7SDag-Erling Smørgrav return r->_debug;
757b5038d7SDag-Erling Smørgrav }
767b5038d7SDag-Erling Smørgrav
777b5038d7SDag-Erling Smørgrav bool
ldns_resolver_dnsrch(const ldns_resolver * r)787b5038d7SDag-Erling Smørgrav ldns_resolver_dnsrch(const ldns_resolver *r)
797b5038d7SDag-Erling Smørgrav {
807b5038d7SDag-Erling Smørgrav return r->_dnsrch;
817b5038d7SDag-Erling Smørgrav }
827b5038d7SDag-Erling Smørgrav
837b5038d7SDag-Erling Smørgrav bool
ldns_resolver_fail(const ldns_resolver * r)847b5038d7SDag-Erling Smørgrav ldns_resolver_fail(const ldns_resolver *r)
857b5038d7SDag-Erling Smørgrav {
867b5038d7SDag-Erling Smørgrav return r->_fail;
877b5038d7SDag-Erling Smørgrav }
887b5038d7SDag-Erling Smørgrav
897b5038d7SDag-Erling Smørgrav bool
ldns_resolver_defnames(const ldns_resolver * r)907b5038d7SDag-Erling Smørgrav ldns_resolver_defnames(const ldns_resolver *r)
917b5038d7SDag-Erling Smørgrav {
927b5038d7SDag-Erling Smørgrav return r->_defnames;
937b5038d7SDag-Erling Smørgrav }
947b5038d7SDag-Erling Smørgrav
957b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_resolver_domain(const ldns_resolver * r)967b5038d7SDag-Erling Smørgrav ldns_resolver_domain(const ldns_resolver *r)
977b5038d7SDag-Erling Smørgrav {
987b5038d7SDag-Erling Smørgrav return r->_domain;
997b5038d7SDag-Erling Smørgrav }
1007b5038d7SDag-Erling Smørgrav
1017b5038d7SDag-Erling Smørgrav ldns_rdf **
ldns_resolver_searchlist(const ldns_resolver * r)1027b5038d7SDag-Erling Smørgrav ldns_resolver_searchlist(const ldns_resolver *r)
1037b5038d7SDag-Erling Smørgrav {
1047b5038d7SDag-Erling Smørgrav return r->_searchlist;
1057b5038d7SDag-Erling Smørgrav }
1067b5038d7SDag-Erling Smørgrav
1077b5038d7SDag-Erling Smørgrav ldns_rdf **
ldns_resolver_nameservers(const ldns_resolver * r)1087b5038d7SDag-Erling Smørgrav ldns_resolver_nameservers(const ldns_resolver *r)
1097b5038d7SDag-Erling Smørgrav {
1107b5038d7SDag-Erling Smørgrav return r->_nameservers;
1117b5038d7SDag-Erling Smørgrav }
1127b5038d7SDag-Erling Smørgrav
1137b5038d7SDag-Erling Smørgrav size_t
ldns_resolver_nameserver_count(const ldns_resolver * r)1147b5038d7SDag-Erling Smørgrav ldns_resolver_nameserver_count(const ldns_resolver *r)
1157b5038d7SDag-Erling Smørgrav {
1167b5038d7SDag-Erling Smørgrav return r->_nameserver_count;
1177b5038d7SDag-Erling Smørgrav }
1187b5038d7SDag-Erling Smørgrav
1197b5038d7SDag-Erling Smørgrav bool
ldns_resolver_dnssec(const ldns_resolver * r)1207b5038d7SDag-Erling Smørgrav ldns_resolver_dnssec(const ldns_resolver *r)
1217b5038d7SDag-Erling Smørgrav {
1227b5038d7SDag-Erling Smørgrav return r->_dnssec;
1237b5038d7SDag-Erling Smørgrav }
1247b5038d7SDag-Erling Smørgrav
1257b5038d7SDag-Erling Smørgrav bool
ldns_resolver_dnssec_cd(const ldns_resolver * r)1267b5038d7SDag-Erling Smørgrav ldns_resolver_dnssec_cd(const ldns_resolver *r)
1277b5038d7SDag-Erling Smørgrav {
1287b5038d7SDag-Erling Smørgrav return r->_dnssec_cd;
1297b5038d7SDag-Erling Smørgrav }
1307b5038d7SDag-Erling Smørgrav
1317b5038d7SDag-Erling Smørgrav ldns_rr_list *
ldns_resolver_dnssec_anchors(const ldns_resolver * r)1327b5038d7SDag-Erling Smørgrav ldns_resolver_dnssec_anchors(const ldns_resolver *r)
1337b5038d7SDag-Erling Smørgrav {
1347b5038d7SDag-Erling Smørgrav return r->_dnssec_anchors;
1357b5038d7SDag-Erling Smørgrav }
1367b5038d7SDag-Erling Smørgrav
1377b5038d7SDag-Erling Smørgrav bool
ldns_resolver_trusted_key(const ldns_resolver * r,ldns_rr_list * keys,ldns_rr_list * trusted_keys)1387b5038d7SDag-Erling Smørgrav ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
1397b5038d7SDag-Erling Smørgrav {
1407b5038d7SDag-Erling Smørgrav size_t i;
1417b5038d7SDag-Erling Smørgrav bool result = false;
1427b5038d7SDag-Erling Smørgrav
1437b5038d7SDag-Erling Smørgrav ldns_rr_list * trust_anchors;
1447b5038d7SDag-Erling Smørgrav ldns_rr * cur_rr;
1457b5038d7SDag-Erling Smørgrav
1467b5038d7SDag-Erling Smørgrav if (!r || !keys) { return false; }
1477b5038d7SDag-Erling Smørgrav
1487b5038d7SDag-Erling Smørgrav trust_anchors = ldns_resolver_dnssec_anchors(r);
1497b5038d7SDag-Erling Smørgrav
1507b5038d7SDag-Erling Smørgrav if (!trust_anchors) { return false; }
1517b5038d7SDag-Erling Smørgrav
1527b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
1537b5038d7SDag-Erling Smørgrav
1547b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_list_rr(keys, i);
1557b5038d7SDag-Erling Smørgrav if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
1567b5038d7SDag-Erling Smørgrav if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
1577b5038d7SDag-Erling Smørgrav result = true;
1587b5038d7SDag-Erling Smørgrav }
1597b5038d7SDag-Erling Smørgrav }
1607b5038d7SDag-Erling Smørgrav
1617b5038d7SDag-Erling Smørgrav return result;
1627b5038d7SDag-Erling Smørgrav }
1637b5038d7SDag-Erling Smørgrav
1647b5038d7SDag-Erling Smørgrav bool
ldns_resolver_igntc(const ldns_resolver * r)1657b5038d7SDag-Erling Smørgrav ldns_resolver_igntc(const ldns_resolver *r)
1667b5038d7SDag-Erling Smørgrav {
1677b5038d7SDag-Erling Smørgrav return r->_igntc;
1687b5038d7SDag-Erling Smørgrav }
1697b5038d7SDag-Erling Smørgrav
1707b5038d7SDag-Erling Smørgrav bool
ldns_resolver_usevc(const ldns_resolver * r)1717b5038d7SDag-Erling Smørgrav ldns_resolver_usevc(const ldns_resolver *r)
1727b5038d7SDag-Erling Smørgrav {
1737b5038d7SDag-Erling Smørgrav return r->_usevc;
1747b5038d7SDag-Erling Smørgrav }
1757b5038d7SDag-Erling Smørgrav
1767b5038d7SDag-Erling Smørgrav size_t *
ldns_resolver_rtt(const ldns_resolver * r)1777b5038d7SDag-Erling Smørgrav ldns_resolver_rtt(const ldns_resolver *r)
1787b5038d7SDag-Erling Smørgrav {
1797b5038d7SDag-Erling Smørgrav return r->_rtt;
1807b5038d7SDag-Erling Smørgrav }
1817b5038d7SDag-Erling Smørgrav
1827b5038d7SDag-Erling Smørgrav size_t
ldns_resolver_nameserver_rtt(const ldns_resolver * r,size_t pos)1837b5038d7SDag-Erling Smørgrav ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
1847b5038d7SDag-Erling Smørgrav {
1857b5038d7SDag-Erling Smørgrav size_t *rtt;
1867b5038d7SDag-Erling Smørgrav
1877b5038d7SDag-Erling Smørgrav assert(r != NULL);
1887b5038d7SDag-Erling Smørgrav
1897b5038d7SDag-Erling Smørgrav rtt = ldns_resolver_rtt(r);
1907b5038d7SDag-Erling Smørgrav
1917b5038d7SDag-Erling Smørgrav if (pos >= ldns_resolver_nameserver_count(r)) {
1927b5038d7SDag-Erling Smørgrav /* error ?*/
1937b5038d7SDag-Erling Smørgrav return 0;
1947b5038d7SDag-Erling Smørgrav } else {
1957b5038d7SDag-Erling Smørgrav return rtt[pos];
1967b5038d7SDag-Erling Smørgrav }
1977b5038d7SDag-Erling Smørgrav
1987b5038d7SDag-Erling Smørgrav }
1997b5038d7SDag-Erling Smørgrav
2007b5038d7SDag-Erling Smørgrav struct timeval
ldns_resolver_timeout(const ldns_resolver * r)2017b5038d7SDag-Erling Smørgrav ldns_resolver_timeout(const ldns_resolver *r)
2027b5038d7SDag-Erling Smørgrav {
2037b5038d7SDag-Erling Smørgrav return r->_timeout;
2047b5038d7SDag-Erling Smørgrav }
2057b5038d7SDag-Erling Smørgrav
206986ba33cSDag-Erling Smørgrav const char *
ldns_resolver_tsig_keyname(const ldns_resolver * r)2077b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_keyname(const ldns_resolver *r)
2087b5038d7SDag-Erling Smørgrav {
2097b5038d7SDag-Erling Smørgrav return r->_tsig_keyname;
2107b5038d7SDag-Erling Smørgrav }
2117b5038d7SDag-Erling Smørgrav
212986ba33cSDag-Erling Smørgrav const char *
ldns_resolver_tsig_algorithm(const ldns_resolver * r)2137b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_algorithm(const ldns_resolver *r)
2147b5038d7SDag-Erling Smørgrav {
2157b5038d7SDag-Erling Smørgrav return r->_tsig_algorithm;
2167b5038d7SDag-Erling Smørgrav }
2177b5038d7SDag-Erling Smørgrav
218986ba33cSDag-Erling Smørgrav const char *
ldns_resolver_tsig_keydata(const ldns_resolver * r)2197b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_keydata(const ldns_resolver *r)
2207b5038d7SDag-Erling Smørgrav {
2217b5038d7SDag-Erling Smørgrav return r->_tsig_keydata;
2227b5038d7SDag-Erling Smørgrav }
2237b5038d7SDag-Erling Smørgrav
2247b5038d7SDag-Erling Smørgrav bool
ldns_resolver_random(const ldns_resolver * r)2257b5038d7SDag-Erling Smørgrav ldns_resolver_random(const ldns_resolver *r)
2267b5038d7SDag-Erling Smørgrav {
2277b5038d7SDag-Erling Smørgrav return r->_random;
2287b5038d7SDag-Erling Smørgrav }
2297b5038d7SDag-Erling Smørgrav
2307b5038d7SDag-Erling Smørgrav size_t
ldns_resolver_searchlist_count(const ldns_resolver * r)2317b5038d7SDag-Erling Smørgrav ldns_resolver_searchlist_count(const ldns_resolver *r)
2327b5038d7SDag-Erling Smørgrav {
2337b5038d7SDag-Erling Smørgrav return r->_searchlist_count;
2347b5038d7SDag-Erling Smørgrav }
2357b5038d7SDag-Erling Smørgrav
2367b5038d7SDag-Erling Smørgrav /* write */
2377b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_port(ldns_resolver * r,uint16_t p)2387b5038d7SDag-Erling Smørgrav ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
2397b5038d7SDag-Erling Smørgrav {
2407b5038d7SDag-Erling Smørgrav r->_port = p;
2417b5038d7SDag-Erling Smørgrav }
2427b5038d7SDag-Erling Smørgrav
24317d15b25SDag-Erling Smørgrav void
ldns_resolver_set_source(ldns_resolver * r,ldns_rdf * s)24417d15b25SDag-Erling Smørgrav ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
24517d15b25SDag-Erling Smørgrav {
24617d15b25SDag-Erling Smørgrav r->_source = s;
24717d15b25SDag-Erling Smørgrav }
24817d15b25SDag-Erling Smørgrav
2497b5038d7SDag-Erling Smørgrav ldns_rdf *
ldns_resolver_pop_nameserver(ldns_resolver * r)2507b5038d7SDag-Erling Smørgrav ldns_resolver_pop_nameserver(ldns_resolver *r)
2517b5038d7SDag-Erling Smørgrav {
2527b5038d7SDag-Erling Smørgrav ldns_rdf **nameservers;
2537b5038d7SDag-Erling Smørgrav ldns_rdf *pop;
2547b5038d7SDag-Erling Smørgrav size_t ns_count;
2557b5038d7SDag-Erling Smørgrav size_t *rtt;
2567b5038d7SDag-Erling Smørgrav
2577b5038d7SDag-Erling Smørgrav assert(r != NULL);
2587b5038d7SDag-Erling Smørgrav
2597b5038d7SDag-Erling Smørgrav ns_count = ldns_resolver_nameserver_count(r);
2607b5038d7SDag-Erling Smørgrav nameservers = ldns_resolver_nameservers(r);
2617b5038d7SDag-Erling Smørgrav rtt = ldns_resolver_rtt(r);
2627b5038d7SDag-Erling Smørgrav if (ns_count == 0 || !nameservers) {
2637b5038d7SDag-Erling Smørgrav return NULL;
2647b5038d7SDag-Erling Smørgrav }
2657b5038d7SDag-Erling Smørgrav
2667b5038d7SDag-Erling Smørgrav pop = nameservers[ns_count - 1];
2677b5038d7SDag-Erling Smørgrav
2682787e39aSDag-Erling Smørgrav if (ns_count == 1) {
2692787e39aSDag-Erling Smørgrav LDNS_FREE(nameservers);
2702787e39aSDag-Erling Smørgrav LDNS_FREE(rtt);
2712787e39aSDag-Erling Smørgrav
2722787e39aSDag-Erling Smørgrav ldns_resolver_set_nameservers(r, NULL);
2732787e39aSDag-Erling Smørgrav ldns_resolver_set_rtt(r, NULL);
2742787e39aSDag-Erling Smørgrav } else {
2752787e39aSDag-Erling Smørgrav nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *,
2762787e39aSDag-Erling Smørgrav (ns_count - 1));
2777b5038d7SDag-Erling Smørgrav rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
2787b5038d7SDag-Erling Smørgrav
2797b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameservers(r, nameservers);
2807b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(r, rtt);
2812787e39aSDag-Erling Smørgrav }
2827b5038d7SDag-Erling Smørgrav /* decr the count */
2837b5038d7SDag-Erling Smørgrav ldns_resolver_dec_nameserver_count(r);
2847b5038d7SDag-Erling Smørgrav return pop;
2857b5038d7SDag-Erling Smørgrav }
2867b5038d7SDag-Erling Smørgrav
2877b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_push_nameserver(ldns_resolver * r,const ldns_rdf * n)288986ba33cSDag-Erling Smørgrav ldns_resolver_push_nameserver(ldns_resolver *r, const ldns_rdf *n)
2897b5038d7SDag-Erling Smørgrav {
2907b5038d7SDag-Erling Smørgrav ldns_rdf **nameservers;
2917b5038d7SDag-Erling Smørgrav size_t ns_count;
2927b5038d7SDag-Erling Smørgrav size_t *rtt;
2937b5038d7SDag-Erling Smørgrav
2947b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
2957b5038d7SDag-Erling Smørgrav ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
2967b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
2977b5038d7SDag-Erling Smørgrav }
2987b5038d7SDag-Erling Smørgrav
2997b5038d7SDag-Erling Smørgrav ns_count = ldns_resolver_nameserver_count(r);
3007b5038d7SDag-Erling Smørgrav nameservers = ldns_resolver_nameservers(r);
3017b5038d7SDag-Erling Smørgrav rtt = ldns_resolver_rtt(r);
3027b5038d7SDag-Erling Smørgrav
3037b5038d7SDag-Erling Smørgrav /* make room for the next one */
3047b5038d7SDag-Erling Smørgrav if (ns_count == 0) {
3057b5038d7SDag-Erling Smørgrav nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
3067b5038d7SDag-Erling Smørgrav } else {
3077b5038d7SDag-Erling Smørgrav nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
3087b5038d7SDag-Erling Smørgrav }
3097b5038d7SDag-Erling Smørgrav if(!nameservers)
3107b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
3117b5038d7SDag-Erling Smørgrav
3127b5038d7SDag-Erling Smørgrav /* set the new value in the resolver */
3137b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameservers(r, nameservers);
3147b5038d7SDag-Erling Smørgrav
3157b5038d7SDag-Erling Smørgrav /* don't forget the rtt */
3167b5038d7SDag-Erling Smørgrav if (ns_count == 0) {
3177b5038d7SDag-Erling Smørgrav rtt = LDNS_XMALLOC(size_t, 1);
3187b5038d7SDag-Erling Smørgrav } else {
3197b5038d7SDag-Erling Smørgrav rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
3207b5038d7SDag-Erling Smørgrav }
3217b5038d7SDag-Erling Smørgrav if(!rtt)
3227b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
3237b5038d7SDag-Erling Smørgrav
3247b5038d7SDag-Erling Smørgrav /* slide n in its slot. */
3257b5038d7SDag-Erling Smørgrav /* we clone it here, because then we can free the original
3267b5038d7SDag-Erling Smørgrav * rr's where it stood */
3277b5038d7SDag-Erling Smørgrav nameservers[ns_count] = ldns_rdf_clone(n);
3287b5038d7SDag-Erling Smørgrav rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
3297b5038d7SDag-Erling Smørgrav ldns_resolver_incr_nameserver_count(r);
3307b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(r, rtt);
3317b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
3327b5038d7SDag-Erling Smørgrav }
3337b5038d7SDag-Erling Smørgrav
3347b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_push_nameserver_rr(ldns_resolver * r,const ldns_rr * rr)335986ba33cSDag-Erling Smørgrav ldns_resolver_push_nameserver_rr(ldns_resolver *r, const ldns_rr *rr)
3367b5038d7SDag-Erling Smørgrav {
3377b5038d7SDag-Erling Smørgrav ldns_rdf *address;
3387b5038d7SDag-Erling Smørgrav if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
3397b5038d7SDag-Erling Smørgrav ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
3407b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
3417b5038d7SDag-Erling Smørgrav }
3427b5038d7SDag-Erling Smørgrav address = ldns_rr_rdf(rr, 0); /* extract the ip number */
3437b5038d7SDag-Erling Smørgrav if (address) {
3447b5038d7SDag-Erling Smørgrav return ldns_resolver_push_nameserver(r, address);
3457b5038d7SDag-Erling Smørgrav } else {
3467b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
3477b5038d7SDag-Erling Smørgrav }
3487b5038d7SDag-Erling Smørgrav }
3497b5038d7SDag-Erling Smørgrav
3507b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_push_nameserver_rr_list(ldns_resolver * r,const ldns_rr_list * rrlist)351986ba33cSDag-Erling Smørgrav ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, const ldns_rr_list *rrlist)
3527b5038d7SDag-Erling Smørgrav {
3537b5038d7SDag-Erling Smørgrav ldns_rr *rr;
3547b5038d7SDag-Erling Smørgrav ldns_status stat;
3557b5038d7SDag-Erling Smørgrav size_t i;
3567b5038d7SDag-Erling Smørgrav
3577b5038d7SDag-Erling Smørgrav stat = LDNS_STATUS_OK;
3587b5038d7SDag-Erling Smørgrav if (rrlist) {
3597b5038d7SDag-Erling Smørgrav for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
3607b5038d7SDag-Erling Smørgrav rr = ldns_rr_list_rr(rrlist, i);
3617b5038d7SDag-Erling Smørgrav if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
3627b5038d7SDag-Erling Smørgrav stat = LDNS_STATUS_ERR;
3637b5038d7SDag-Erling Smørgrav break;
3647b5038d7SDag-Erling Smørgrav }
3657b5038d7SDag-Erling Smørgrav }
3667b5038d7SDag-Erling Smørgrav return stat;
3677b5038d7SDag-Erling Smørgrav } else {
3687b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
3697b5038d7SDag-Erling Smørgrav }
3707b5038d7SDag-Erling Smørgrav }
3717b5038d7SDag-Erling Smørgrav
3727b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_edns_udp_size(ldns_resolver * r,uint16_t s)3737b5038d7SDag-Erling Smørgrav ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
3747b5038d7SDag-Erling Smørgrav {
3757b5038d7SDag-Erling Smørgrav r->_edns_udp_size = s;
3767b5038d7SDag-Erling Smørgrav }
3777b5038d7SDag-Erling Smørgrav
3787b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_recursive(ldns_resolver * r,bool re)3797b5038d7SDag-Erling Smørgrav ldns_resolver_set_recursive(ldns_resolver *r, bool re)
3807b5038d7SDag-Erling Smørgrav {
3817b5038d7SDag-Erling Smørgrav r->_recursive = re;
3827b5038d7SDag-Erling Smørgrav }
3837b5038d7SDag-Erling Smørgrav
3847b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_dnssec(ldns_resolver * r,bool d)3857b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
3867b5038d7SDag-Erling Smørgrav {
3877b5038d7SDag-Erling Smørgrav r->_dnssec = d;
3887b5038d7SDag-Erling Smørgrav }
3897b5038d7SDag-Erling Smørgrav
3907b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_dnssec_cd(ldns_resolver * r,bool d)3917b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
3927b5038d7SDag-Erling Smørgrav {
3937b5038d7SDag-Erling Smørgrav r->_dnssec_cd = d;
3947b5038d7SDag-Erling Smørgrav }
3957b5038d7SDag-Erling Smørgrav
3967b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_dnssec_anchors(ldns_resolver * r,ldns_rr_list * l)3977b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
3987b5038d7SDag-Erling Smørgrav {
3997b5038d7SDag-Erling Smørgrav r->_dnssec_anchors = l;
4007b5038d7SDag-Erling Smørgrav }
4017b5038d7SDag-Erling Smørgrav
4027b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_push_dnssec_anchor(ldns_resolver * r,ldns_rr * rr)4037b5038d7SDag-Erling Smørgrav ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
4047b5038d7SDag-Erling Smørgrav {
4057b5038d7SDag-Erling Smørgrav ldns_rr_list * trust_anchors;
4067b5038d7SDag-Erling Smørgrav
4072787e39aSDag-Erling Smørgrav if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
4082787e39aSDag-Erling Smørgrav ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
4092787e39aSDag-Erling Smørgrav
4107b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
4117b5038d7SDag-Erling Smørgrav }
4127b5038d7SDag-Erling Smørgrav
4137b5038d7SDag-Erling Smørgrav if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
4147b5038d7SDag-Erling Smørgrav trust_anchors = ldns_rr_list_new();
4157b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_anchors(r, trust_anchors);
4167b5038d7SDag-Erling Smørgrav }
4177b5038d7SDag-Erling Smørgrav
4187b5038d7SDag-Erling Smørgrav return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
4197b5038d7SDag-Erling Smørgrav }
4207b5038d7SDag-Erling Smørgrav
4217b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_igntc(ldns_resolver * r,bool i)4227b5038d7SDag-Erling Smørgrav ldns_resolver_set_igntc(ldns_resolver *r, bool i)
4237b5038d7SDag-Erling Smørgrav {
4247b5038d7SDag-Erling Smørgrav r->_igntc = i;
4257b5038d7SDag-Erling Smørgrav }
4267b5038d7SDag-Erling Smørgrav
4277b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_usevc(ldns_resolver * r,bool vc)4287b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
4297b5038d7SDag-Erling Smørgrav {
4307b5038d7SDag-Erling Smørgrav r->_usevc = vc;
4317b5038d7SDag-Erling Smørgrav }
4327b5038d7SDag-Erling Smørgrav
4337b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_debug(ldns_resolver * r,bool d)4347b5038d7SDag-Erling Smørgrav ldns_resolver_set_debug(ldns_resolver *r, bool d)
4357b5038d7SDag-Erling Smørgrav {
4367b5038d7SDag-Erling Smørgrav r->_debug = d;
4377b5038d7SDag-Erling Smørgrav }
4387b5038d7SDag-Erling Smørgrav
4397b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_ip6(ldns_resolver * r,uint8_t ip6)4407b5038d7SDag-Erling Smørgrav ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
4417b5038d7SDag-Erling Smørgrav {
4427b5038d7SDag-Erling Smørgrav r->_ip6 = ip6;
4437b5038d7SDag-Erling Smørgrav }
4447b5038d7SDag-Erling Smørgrav
4457b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_fail(ldns_resolver * r,bool f)4467b5038d7SDag-Erling Smørgrav ldns_resolver_set_fail(ldns_resolver *r, bool f)
4477b5038d7SDag-Erling Smørgrav {
4487b5038d7SDag-Erling Smørgrav r->_fail =f;
4497b5038d7SDag-Erling Smørgrav }
4507b5038d7SDag-Erling Smørgrav
4517b5038d7SDag-Erling Smørgrav static void
ldns_resolver_set_searchlist_count(ldns_resolver * r,size_t c)4527b5038d7SDag-Erling Smørgrav ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
4537b5038d7SDag-Erling Smørgrav {
4547b5038d7SDag-Erling Smørgrav r->_searchlist_count = c;
4557b5038d7SDag-Erling Smørgrav }
4567b5038d7SDag-Erling Smørgrav
4577b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_nameserver_count(ldns_resolver * r,size_t c)4587b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
4597b5038d7SDag-Erling Smørgrav {
4607b5038d7SDag-Erling Smørgrav r->_nameserver_count = c;
4617b5038d7SDag-Erling Smørgrav }
4627b5038d7SDag-Erling Smørgrav
4637b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_dnsrch(ldns_resolver * r,bool d)4647b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
4657b5038d7SDag-Erling Smørgrav {
4667b5038d7SDag-Erling Smørgrav r->_dnsrch = d;
4677b5038d7SDag-Erling Smørgrav }
4687b5038d7SDag-Erling Smørgrav
4697b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_retry(ldns_resolver * r,uint8_t retry)4707b5038d7SDag-Erling Smørgrav ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
4717b5038d7SDag-Erling Smørgrav {
4727b5038d7SDag-Erling Smørgrav r->_retry = retry;
4737b5038d7SDag-Erling Smørgrav }
4747b5038d7SDag-Erling Smørgrav
4757b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_retrans(ldns_resolver * r,uint8_t retrans)4767b5038d7SDag-Erling Smørgrav ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
4777b5038d7SDag-Erling Smørgrav {
4787b5038d7SDag-Erling Smørgrav r->_retrans = retrans;
4797b5038d7SDag-Erling Smørgrav }
4807b5038d7SDag-Erling Smørgrav
4817b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_fallback(ldns_resolver * r,bool fallback)4827b5038d7SDag-Erling Smørgrav ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
4837b5038d7SDag-Erling Smørgrav {
4847b5038d7SDag-Erling Smørgrav r->_fallback = fallback;
4857b5038d7SDag-Erling Smørgrav }
4867b5038d7SDag-Erling Smørgrav
4877b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_nameservers(ldns_resolver * r,ldns_rdf ** n)4887b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
4897b5038d7SDag-Erling Smørgrav {
4907b5038d7SDag-Erling Smørgrav r->_nameservers = n;
4917b5038d7SDag-Erling Smørgrav }
4927b5038d7SDag-Erling Smørgrav
4937b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_defnames(ldns_resolver * r,bool d)4947b5038d7SDag-Erling Smørgrav ldns_resolver_set_defnames(ldns_resolver *r, bool d)
4957b5038d7SDag-Erling Smørgrav {
4967b5038d7SDag-Erling Smørgrav r->_defnames = d;
4977b5038d7SDag-Erling Smørgrav }
4987b5038d7SDag-Erling Smørgrav
4997b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_rtt(ldns_resolver * r,size_t * rtt)5007b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
5017b5038d7SDag-Erling Smørgrav {
5027b5038d7SDag-Erling Smørgrav r->_rtt = rtt;
5037b5038d7SDag-Erling Smørgrav }
5047b5038d7SDag-Erling Smørgrav
5057b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_nameserver_rtt(ldns_resolver * r,size_t pos,size_t value)5067b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
5077b5038d7SDag-Erling Smørgrav {
5087b5038d7SDag-Erling Smørgrav size_t *rtt;
5097b5038d7SDag-Erling Smørgrav
5107b5038d7SDag-Erling Smørgrav assert(r != NULL);
5117b5038d7SDag-Erling Smørgrav
5127b5038d7SDag-Erling Smørgrav rtt = ldns_resolver_rtt(r);
5137b5038d7SDag-Erling Smørgrav
5147b5038d7SDag-Erling Smørgrav if (pos >= ldns_resolver_nameserver_count(r)) {
5157b5038d7SDag-Erling Smørgrav /* error ?*/
5167b5038d7SDag-Erling Smørgrav } else {
5177b5038d7SDag-Erling Smørgrav rtt[pos] = value;
5187b5038d7SDag-Erling Smørgrav }
5197b5038d7SDag-Erling Smørgrav
5207b5038d7SDag-Erling Smørgrav }
5217b5038d7SDag-Erling Smørgrav
5227b5038d7SDag-Erling Smørgrav void
ldns_resolver_incr_nameserver_count(ldns_resolver * r)5237b5038d7SDag-Erling Smørgrav ldns_resolver_incr_nameserver_count(ldns_resolver *r)
5247b5038d7SDag-Erling Smørgrav {
5257b5038d7SDag-Erling Smørgrav size_t c;
5267b5038d7SDag-Erling Smørgrav
5277b5038d7SDag-Erling Smørgrav c = ldns_resolver_nameserver_count(r);
5287b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameserver_count(r, ++c);
5297b5038d7SDag-Erling Smørgrav }
5307b5038d7SDag-Erling Smørgrav
5317b5038d7SDag-Erling Smørgrav void
ldns_resolver_dec_nameserver_count(ldns_resolver * r)5327b5038d7SDag-Erling Smørgrav ldns_resolver_dec_nameserver_count(ldns_resolver *r)
5337b5038d7SDag-Erling Smørgrav {
5347b5038d7SDag-Erling Smørgrav size_t c;
5357b5038d7SDag-Erling Smørgrav
5367b5038d7SDag-Erling Smørgrav c = ldns_resolver_nameserver_count(r);
5377b5038d7SDag-Erling Smørgrav if (c == 0) {
5387b5038d7SDag-Erling Smørgrav return;
5397b5038d7SDag-Erling Smørgrav } else {
5407b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameserver_count(r, --c);
5417b5038d7SDag-Erling Smørgrav }
5427b5038d7SDag-Erling Smørgrav }
5437b5038d7SDag-Erling Smørgrav
5447b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_domain(ldns_resolver * r,ldns_rdf * d)5457b5038d7SDag-Erling Smørgrav ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
5467b5038d7SDag-Erling Smørgrav {
5477b5038d7SDag-Erling Smørgrav r->_domain = d;
5487b5038d7SDag-Erling Smørgrav }
5497b5038d7SDag-Erling Smørgrav
5507b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_timeout(ldns_resolver * r,struct timeval timeout)5517b5038d7SDag-Erling Smørgrav ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
5527b5038d7SDag-Erling Smørgrav {
5537b5038d7SDag-Erling Smørgrav r->_timeout.tv_sec = timeout.tv_sec;
5547b5038d7SDag-Erling Smørgrav r->_timeout.tv_usec = timeout.tv_usec;
5557b5038d7SDag-Erling Smørgrav }
5567b5038d7SDag-Erling Smørgrav
5577b5038d7SDag-Erling Smørgrav void
ldns_resolver_push_searchlist(ldns_resolver * r,ldns_rdf * d)5587b5038d7SDag-Erling Smørgrav ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
5597b5038d7SDag-Erling Smørgrav {
5607b5038d7SDag-Erling Smørgrav ldns_rdf **searchlist;
5617b5038d7SDag-Erling Smørgrav size_t list_count;
5627b5038d7SDag-Erling Smørgrav
5637b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
5647b5038d7SDag-Erling Smørgrav return;
5657b5038d7SDag-Erling Smørgrav }
5667b5038d7SDag-Erling Smørgrav
5677b5038d7SDag-Erling Smørgrav list_count = ldns_resolver_searchlist_count(r);
5687b5038d7SDag-Erling Smørgrav searchlist = ldns_resolver_searchlist(r);
5697b5038d7SDag-Erling Smørgrav
5707b5038d7SDag-Erling Smørgrav searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
5717b5038d7SDag-Erling Smørgrav if (searchlist) {
5727b5038d7SDag-Erling Smørgrav r->_searchlist = searchlist;
5737b5038d7SDag-Erling Smørgrav
5747b5038d7SDag-Erling Smørgrav searchlist[list_count] = ldns_rdf_clone(d);
5757b5038d7SDag-Erling Smørgrav ldns_resolver_set_searchlist_count(r, list_count + 1);
5767b5038d7SDag-Erling Smørgrav } /* no way to report mem err */
5777b5038d7SDag-Erling Smørgrav }
5787b5038d7SDag-Erling Smørgrav
5797b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_tsig_keyname(ldns_resolver * r,const char * tsig_keyname)580986ba33cSDag-Erling Smørgrav ldns_resolver_set_tsig_keyname(ldns_resolver *r, const char *tsig_keyname)
5817b5038d7SDag-Erling Smørgrav {
5827b5038d7SDag-Erling Smørgrav LDNS_FREE(r->_tsig_keyname);
5837b5038d7SDag-Erling Smørgrav r->_tsig_keyname = strdup(tsig_keyname);
5847b5038d7SDag-Erling Smørgrav }
5857b5038d7SDag-Erling Smørgrav
5867b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_tsig_algorithm(ldns_resolver * r,const char * tsig_algorithm)587986ba33cSDag-Erling Smørgrav ldns_resolver_set_tsig_algorithm(ldns_resolver *r, const char *tsig_algorithm)
5887b5038d7SDag-Erling Smørgrav {
5897b5038d7SDag-Erling Smørgrav LDNS_FREE(r->_tsig_algorithm);
5907b5038d7SDag-Erling Smørgrav r->_tsig_algorithm = strdup(tsig_algorithm);
5917b5038d7SDag-Erling Smørgrav }
5927b5038d7SDag-Erling Smørgrav
5937b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_tsig_keydata(ldns_resolver * r,const char * tsig_keydata)594986ba33cSDag-Erling Smørgrav ldns_resolver_set_tsig_keydata(ldns_resolver *r, const char *tsig_keydata)
5957b5038d7SDag-Erling Smørgrav {
5967b5038d7SDag-Erling Smørgrav LDNS_FREE(r->_tsig_keydata);
5977b5038d7SDag-Erling Smørgrav r->_tsig_keydata = strdup(tsig_keydata);
5987b5038d7SDag-Erling Smørgrav }
5997b5038d7SDag-Erling Smørgrav
6007b5038d7SDag-Erling Smørgrav void
ldns_resolver_set_random(ldns_resolver * r,bool b)6017b5038d7SDag-Erling Smørgrav ldns_resolver_set_random(ldns_resolver *r, bool b)
6027b5038d7SDag-Erling Smørgrav {
6037b5038d7SDag-Erling Smørgrav r->_random = b;
6047b5038d7SDag-Erling Smørgrav }
6057b5038d7SDag-Erling Smørgrav
6067b5038d7SDag-Erling Smørgrav /* more sophisticated functions */
6077b5038d7SDag-Erling Smørgrav ldns_resolver *
ldns_resolver_new(void)6087b5038d7SDag-Erling Smørgrav ldns_resolver_new(void)
6097b5038d7SDag-Erling Smørgrav {
6107b5038d7SDag-Erling Smørgrav ldns_resolver *r;
6117b5038d7SDag-Erling Smørgrav
6127b5038d7SDag-Erling Smørgrav r = LDNS_MALLOC(ldns_resolver);
6137b5038d7SDag-Erling Smørgrav if (!r) {
6147b5038d7SDag-Erling Smørgrav return NULL;
6157b5038d7SDag-Erling Smørgrav }
6167b5038d7SDag-Erling Smørgrav
6177b5038d7SDag-Erling Smørgrav r->_searchlist = NULL;
6187b5038d7SDag-Erling Smørgrav r->_nameservers = NULL;
6197b5038d7SDag-Erling Smørgrav r->_rtt = NULL;
6207b5038d7SDag-Erling Smørgrav
6217b5038d7SDag-Erling Smørgrav /* defaults are filled out */
6227b5038d7SDag-Erling Smørgrav ldns_resolver_set_searchlist_count(r, 0);
6237b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameserver_count(r, 0);
6247b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(r, 0);
6257b5038d7SDag-Erling Smørgrav ldns_resolver_set_port(r, LDNS_PORT);
6267b5038d7SDag-Erling Smørgrav ldns_resolver_set_domain(r, NULL);
6277b5038d7SDag-Erling Smørgrav ldns_resolver_set_defnames(r, false);
6287b5038d7SDag-Erling Smørgrav ldns_resolver_set_retry(r, 3);
6297b5038d7SDag-Erling Smørgrav ldns_resolver_set_retrans(r, 2);
6307b5038d7SDag-Erling Smørgrav ldns_resolver_set_fallback(r, true);
6317b5038d7SDag-Erling Smørgrav ldns_resolver_set_fail(r, false);
6327b5038d7SDag-Erling Smørgrav ldns_resolver_set_edns_udp_size(r, 0);
6337b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec(r, false);
6347b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_cd(r, false);
6357b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnssec_anchors(r, NULL);
6367b5038d7SDag-Erling Smørgrav ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
6377b5038d7SDag-Erling Smørgrav ldns_resolver_set_igntc(r, false);
6387b5038d7SDag-Erling Smørgrav ldns_resolver_set_recursive(r, false);
6397b5038d7SDag-Erling Smørgrav ldns_resolver_set_dnsrch(r, true);
64017d15b25SDag-Erling Smørgrav ldns_resolver_set_source(r, NULL);
641986ba33cSDag-Erling Smørgrav ldns_resolver_set_ixfr_serial(r, 0);
6427b5038d7SDag-Erling Smørgrav
6437b5038d7SDag-Erling Smørgrav /* randomize the nameserver to be queried
6447b5038d7SDag-Erling Smørgrav * when there are multiple
6457b5038d7SDag-Erling Smørgrav */
6467b5038d7SDag-Erling Smørgrav ldns_resolver_set_random(r, true);
6477b5038d7SDag-Erling Smørgrav
6487b5038d7SDag-Erling Smørgrav ldns_resolver_set_debug(r, 0);
6497b5038d7SDag-Erling Smørgrav
6507b5038d7SDag-Erling Smørgrav r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
6517b5038d7SDag-Erling Smørgrav r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
6527b5038d7SDag-Erling Smørgrav
653986ba33cSDag-Erling Smørgrav r->_socket = -1;
6547b5038d7SDag-Erling Smørgrav r->_axfr_soa_count = 0;
6557b5038d7SDag-Erling Smørgrav r->_axfr_i = 0;
6567b5038d7SDag-Erling Smørgrav r->_cur_axfr_pkt = NULL;
6577b5038d7SDag-Erling Smørgrav
6587b5038d7SDag-Erling Smørgrav r->_tsig_keyname = NULL;
6597b5038d7SDag-Erling Smørgrav r->_tsig_keydata = NULL;
6607b5038d7SDag-Erling Smørgrav r->_tsig_algorithm = NULL;
6617b5038d7SDag-Erling Smørgrav return r;
6627b5038d7SDag-Erling Smørgrav }
6637b5038d7SDag-Erling Smørgrav
664986ba33cSDag-Erling Smørgrav ldns_resolver *
ldns_resolver_clone(ldns_resolver * src)665986ba33cSDag-Erling Smørgrav ldns_resolver_clone(ldns_resolver *src)
666986ba33cSDag-Erling Smørgrav {
667986ba33cSDag-Erling Smørgrav ldns_resolver *dst;
668986ba33cSDag-Erling Smørgrav size_t i;
669986ba33cSDag-Erling Smørgrav
670986ba33cSDag-Erling Smørgrav assert(src != NULL);
671986ba33cSDag-Erling Smørgrav
672986ba33cSDag-Erling Smørgrav if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
673986ba33cSDag-Erling Smørgrav (void) memcpy(dst, src, sizeof(ldns_resolver));
674986ba33cSDag-Erling Smørgrav
675986ba33cSDag-Erling Smørgrav if (dst->_searchlist_count == 0)
676986ba33cSDag-Erling Smørgrav dst->_searchlist = NULL;
677986ba33cSDag-Erling Smørgrav else {
678986ba33cSDag-Erling Smørgrav if (!(dst->_searchlist =
679986ba33cSDag-Erling Smørgrav LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
680986ba33cSDag-Erling Smørgrav goto error;
681986ba33cSDag-Erling Smørgrav for (i = 0; i < dst->_searchlist_count; i++)
682986ba33cSDag-Erling Smørgrav if (!(dst->_searchlist[i] =
683986ba33cSDag-Erling Smørgrav ldns_rdf_clone(src->_searchlist[i]))) {
684986ba33cSDag-Erling Smørgrav dst->_searchlist_count = i;
685986ba33cSDag-Erling Smørgrav goto error_searchlist;
686986ba33cSDag-Erling Smørgrav }
687986ba33cSDag-Erling Smørgrav }
688986ba33cSDag-Erling Smørgrav if (dst->_nameserver_count == 0) {
689986ba33cSDag-Erling Smørgrav dst->_nameservers = NULL;
690986ba33cSDag-Erling Smørgrav dst->_rtt = NULL;
691986ba33cSDag-Erling Smørgrav } else {
692986ba33cSDag-Erling Smørgrav if (!(dst->_nameservers =
693986ba33cSDag-Erling Smørgrav LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
694986ba33cSDag-Erling Smørgrav goto error_searchlist;
695986ba33cSDag-Erling Smørgrav for (i = 0; i < dst->_nameserver_count; i++)
696986ba33cSDag-Erling Smørgrav if (!(dst->_nameservers[i] =
697986ba33cSDag-Erling Smørgrav ldns_rdf_clone(src->_nameservers[i]))) {
698986ba33cSDag-Erling Smørgrav dst->_nameserver_count = i;
699986ba33cSDag-Erling Smørgrav goto error_nameservers;
700986ba33cSDag-Erling Smørgrav }
701986ba33cSDag-Erling Smørgrav if (!(dst->_rtt =
702986ba33cSDag-Erling Smørgrav LDNS_XMALLOC(size_t, dst->_nameserver_count)))
703986ba33cSDag-Erling Smørgrav goto error_nameservers;
704986ba33cSDag-Erling Smørgrav (void) memcpy(dst->_rtt, src->_rtt,
705986ba33cSDag-Erling Smørgrav sizeof(size_t) * dst->_nameserver_count);
706986ba33cSDag-Erling Smørgrav }
707986ba33cSDag-Erling Smørgrav if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
708986ba33cSDag-Erling Smørgrav goto error_rtt;
709986ba33cSDag-Erling Smørgrav
710986ba33cSDag-Erling Smørgrav if (dst->_tsig_keyname &&
711986ba33cSDag-Erling Smørgrav (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
712986ba33cSDag-Erling Smørgrav goto error_domain;
713986ba33cSDag-Erling Smørgrav
714986ba33cSDag-Erling Smørgrav if (dst->_tsig_keydata &&
715986ba33cSDag-Erling Smørgrav (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
716986ba33cSDag-Erling Smørgrav goto error_tsig_keyname;
717986ba33cSDag-Erling Smørgrav
718986ba33cSDag-Erling Smørgrav if (dst->_tsig_algorithm &&
719986ba33cSDag-Erling Smørgrav (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
720986ba33cSDag-Erling Smørgrav goto error_tsig_keydata;
721986ba33cSDag-Erling Smørgrav
722986ba33cSDag-Erling Smørgrav if (dst->_cur_axfr_pkt &&
723986ba33cSDag-Erling Smørgrav (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
724986ba33cSDag-Erling Smørgrav goto error_tsig_algorithm;
725986ba33cSDag-Erling Smørgrav
726986ba33cSDag-Erling Smørgrav if (dst->_dnssec_anchors &&
727986ba33cSDag-Erling Smørgrav (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
728986ba33cSDag-Erling Smørgrav goto error_cur_axfr_pkt;
729986ba33cSDag-Erling Smørgrav
730986ba33cSDag-Erling Smørgrav return dst;
731986ba33cSDag-Erling Smørgrav
732986ba33cSDag-Erling Smørgrav error_cur_axfr_pkt:
733986ba33cSDag-Erling Smørgrav ldns_pkt_free(dst->_cur_axfr_pkt);
734986ba33cSDag-Erling Smørgrav error_tsig_algorithm:
735986ba33cSDag-Erling Smørgrav LDNS_FREE(dst->_tsig_algorithm);
736986ba33cSDag-Erling Smørgrav error_tsig_keydata:
737986ba33cSDag-Erling Smørgrav LDNS_FREE(dst->_tsig_keydata);
738986ba33cSDag-Erling Smørgrav error_tsig_keyname:
739986ba33cSDag-Erling Smørgrav LDNS_FREE(dst->_tsig_keyname);
740986ba33cSDag-Erling Smørgrav error_domain:
741986ba33cSDag-Erling Smørgrav ldns_rdf_deep_free(dst->_domain);
742986ba33cSDag-Erling Smørgrav error_rtt:
743986ba33cSDag-Erling Smørgrav LDNS_FREE(dst->_rtt);
744986ba33cSDag-Erling Smørgrav error_nameservers:
745986ba33cSDag-Erling Smørgrav for (i = 0; i < dst->_nameserver_count; i++)
746986ba33cSDag-Erling Smørgrav ldns_rdf_deep_free(dst->_nameservers[i]);
747986ba33cSDag-Erling Smørgrav LDNS_FREE(dst->_nameservers);
748986ba33cSDag-Erling Smørgrav error_searchlist:
749986ba33cSDag-Erling Smørgrav for (i = 0; i < dst->_searchlist_count; i++)
750986ba33cSDag-Erling Smørgrav ldns_rdf_deep_free(dst->_searchlist[i]);
751986ba33cSDag-Erling Smørgrav LDNS_FREE(dst->_searchlist);
752986ba33cSDag-Erling Smørgrav error:
753986ba33cSDag-Erling Smørgrav LDNS_FREE(dst);
754986ba33cSDag-Erling Smørgrav return NULL;
755986ba33cSDag-Erling Smørgrav }
756986ba33cSDag-Erling Smørgrav
757986ba33cSDag-Erling Smørgrav
7587b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_new_frm_fp(ldns_resolver ** res,FILE * fp)7597b5038d7SDag-Erling Smørgrav ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
7607b5038d7SDag-Erling Smørgrav {
7617b5038d7SDag-Erling Smørgrav return ldns_resolver_new_frm_fp_l(res, fp, NULL);
7627b5038d7SDag-Erling Smørgrav }
7637b5038d7SDag-Erling Smørgrav
7647b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_new_frm_fp_l(ldns_resolver ** res,FILE * fp,int * line_nr)7657b5038d7SDag-Erling Smørgrav ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
7667b5038d7SDag-Erling Smørgrav {
7675afab0e5SDag-Erling Smørgrav ldns_resolver *r = NULL;
7687b5038d7SDag-Erling Smørgrav const char *keyword[LDNS_RESOLV_KEYWORDS];
7697b5038d7SDag-Erling Smørgrav char word[LDNS_MAX_LINELEN + 1];
7707b5038d7SDag-Erling Smørgrav int8_t expect;
7717b5038d7SDag-Erling Smørgrav uint8_t i;
7727b5038d7SDag-Erling Smørgrav ldns_rdf *tmp;
7737b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
7747b5038d7SDag-Erling Smørgrav ldns_rr *tmp_rr;
7757b5038d7SDag-Erling Smørgrav #endif
7767b5038d7SDag-Erling Smørgrav ssize_t gtr, bgtr;
7777b5038d7SDag-Erling Smørgrav ldns_buffer *b;
778*3b092e49SDag-Erling Smørgrav int lnr = 0;
77917d15b25SDag-Erling Smørgrav FILE* myfp = fp;
7807b5038d7SDag-Erling Smørgrav if(!line_nr) line_nr = &lnr;
7817b5038d7SDag-Erling Smørgrav
78217d15b25SDag-Erling Smørgrav if(!fp) {
7835afab0e5SDag-Erling Smørgrav myfp = fopen(LDNS_RESOLV_CONF, "r");
78417d15b25SDag-Erling Smørgrav if(!myfp)
78517d15b25SDag-Erling Smørgrav return LDNS_STATUS_FILE_ERR;
78617d15b25SDag-Erling Smørgrav }
78717d15b25SDag-Erling Smørgrav
7887b5038d7SDag-Erling Smørgrav /* do this better
7897b5038d7SDag-Erling Smørgrav * expect =
7907b5038d7SDag-Erling Smørgrav * 0: keyword
7917b5038d7SDag-Erling Smørgrav * 1: default domain dname
7927b5038d7SDag-Erling Smørgrav * 2: NS aaaa or a record
7937b5038d7SDag-Erling Smørgrav */
7947b5038d7SDag-Erling Smørgrav
7957b5038d7SDag-Erling Smørgrav /* recognized keywords */
7967b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
7977b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
7987b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_SEARCH] = "search";
7997b5038d7SDag-Erling Smørgrav /* these two are read but not used atm TODO */
8007b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
8017b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_OPTIONS] = "options";
8027b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_ANCHOR] = "anchor";
8037b5038d7SDag-Erling Smørgrav
8047b5038d7SDag-Erling Smørgrav r = ldns_resolver_new();
8057b5038d7SDag-Erling Smørgrav if (!r) {
80617d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8077b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
8087b5038d7SDag-Erling Smørgrav }
8097b5038d7SDag-Erling Smørgrav
8107b5038d7SDag-Erling Smørgrav gtr = 1;
8117b5038d7SDag-Erling Smørgrav word[0] = 0;
8127b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
8137b5038d7SDag-Erling Smørgrav while (gtr > 0) {
8147b5038d7SDag-Erling Smørgrav switch(expect) {
8157b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_KEYWORD:
8167b5038d7SDag-Erling Smørgrav /* keyword */
817*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
8187b5038d7SDag-Erling Smørgrav if (gtr != 0) {
8197b5038d7SDag-Erling Smørgrav for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
8207b5038d7SDag-Erling Smørgrav if (strcasecmp(keyword[i], word) == 0) {
8217b5038d7SDag-Erling Smørgrav /* chosen the keyword and
8227b5038d7SDag-Erling Smørgrav * expect values carefully
8237b5038d7SDag-Erling Smørgrav */
8247b5038d7SDag-Erling Smørgrav expect = i;
8257b5038d7SDag-Erling Smørgrav break;
8267b5038d7SDag-Erling Smørgrav }
8277b5038d7SDag-Erling Smørgrav }
8287b5038d7SDag-Erling Smørgrav /* no keyword recognized */
8297b5038d7SDag-Erling Smørgrav if (expect == LDNS_RESOLV_KEYWORD) {
8307b5038d7SDag-Erling Smørgrav /* skip line */
8317b5038d7SDag-Erling Smørgrav /*
8327b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
83317d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8347b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
8357b5038d7SDag-Erling Smørgrav */
8367b5038d7SDag-Erling Smørgrav }
8377b5038d7SDag-Erling Smørgrav }
8387b5038d7SDag-Erling Smørgrav break;
8397b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_DEFDOMAIN:
8407b5038d7SDag-Erling Smørgrav /* default domain dname */
841*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
8427b5038d7SDag-Erling Smørgrav if (gtr == 0) {
84317d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8445afab0e5SDag-Erling Smørgrav ldns_resolver_deep_free(r);
8457b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
8467b5038d7SDag-Erling Smørgrav }
8477b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
8487b5038d7SDag-Erling Smørgrav if (!tmp) {
84917d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8505afab0e5SDag-Erling Smørgrav ldns_resolver_deep_free(r);
8517b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_DNAME_ERR;
8527b5038d7SDag-Erling Smørgrav }
8537b5038d7SDag-Erling Smørgrav
8547b5038d7SDag-Erling Smørgrav /* DOn't free, because we copy the pointer */
8557b5038d7SDag-Erling Smørgrav ldns_resolver_set_domain(r, tmp);
8567b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
8577b5038d7SDag-Erling Smørgrav break;
8587b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_NAMESERVER:
8597b5038d7SDag-Erling Smørgrav /* NS aaaa or a record */
860*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
8617b5038d7SDag-Erling Smørgrav if (gtr == 0) {
86217d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8635afab0e5SDag-Erling Smørgrav ldns_resolver_deep_free(r);
8647b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
8657b5038d7SDag-Erling Smørgrav }
8667b5038d7SDag-Erling Smørgrav if(strchr(word, '%')) {
8677b5038d7SDag-Erling Smørgrav /* snip off interface labels,
8687b5038d7SDag-Erling Smørgrav * fe80::222:19ff:fe31:4222%eth0 */
8697b5038d7SDag-Erling Smørgrav strchr(word, '%')[0]=0;
8707b5038d7SDag-Erling Smørgrav }
8717b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
8727b5038d7SDag-Erling Smørgrav if (!tmp) {
8737b5038d7SDag-Erling Smørgrav /* try ip4 */
8747b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
8757b5038d7SDag-Erling Smørgrav }
8767b5038d7SDag-Erling Smørgrav /* could not parse it, exit */
8777b5038d7SDag-Erling Smørgrav if (!tmp) {
8787b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
87917d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8807b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR;
8817b5038d7SDag-Erling Smørgrav }
8827b5038d7SDag-Erling Smørgrav (void)ldns_resolver_push_nameserver(r, tmp);
8837b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp);
8847b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
8857b5038d7SDag-Erling Smørgrav break;
8867b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_SEARCH:
8877b5038d7SDag-Erling Smørgrav /* search list domain dname */
888*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
8897b5038d7SDag-Erling Smørgrav b = LDNS_MALLOC(ldns_buffer);
8907b5038d7SDag-Erling Smørgrav if(!b) {
8917b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
89217d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
8937b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
8947b5038d7SDag-Erling Smørgrav }
8957b5038d7SDag-Erling Smørgrav
8967b5038d7SDag-Erling Smørgrav ldns_buffer_new_frm_data(b, word, (size_t) gtr);
8977b5038d7SDag-Erling Smørgrav if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
8987b5038d7SDag-Erling Smørgrav LDNS_FREE(b);
8997b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
90017d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
9017b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
9027b5038d7SDag-Erling Smørgrav }
9037b5038d7SDag-Erling Smørgrav bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
9047b5038d7SDag-Erling Smørgrav while (bgtr > 0) {
9057b5038d7SDag-Erling Smørgrav gtr -= bgtr;
9067b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
9077b5038d7SDag-Erling Smørgrav if (!tmp) {
9087b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
9097b5038d7SDag-Erling Smørgrav ldns_buffer_free(b);
91017d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
9117b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_DNAME_ERR;
9127b5038d7SDag-Erling Smørgrav }
9137b5038d7SDag-Erling Smørgrav
9147b5038d7SDag-Erling Smørgrav ldns_resolver_push_searchlist(r, tmp);
9157b5038d7SDag-Erling Smørgrav
9167b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp);
9177b5038d7SDag-Erling Smørgrav bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
9187b5038d7SDag-Erling Smørgrav (size_t) gtr + 1);
9197b5038d7SDag-Erling Smørgrav }
9207b5038d7SDag-Erling Smørgrav ldns_buffer_free(b);
9212787e39aSDag-Erling Smørgrav if (expect != LDNS_RESOLV_KEYWORD) {
9227b5038d7SDag-Erling Smørgrav gtr = 1;
9237b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
9242787e39aSDag-Erling Smørgrav }
9257b5038d7SDag-Erling Smørgrav break;
9267b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_SORTLIST:
927*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
9287b5038d7SDag-Erling Smørgrav /* sortlist not implemented atm */
9297b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
9307b5038d7SDag-Erling Smørgrav break;
9317b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_OPTIONS:
932*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
9337b5038d7SDag-Erling Smørgrav /* options not implemented atm */
9347b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
9357b5038d7SDag-Erling Smørgrav break;
9367b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_ANCHOR:
9377b5038d7SDag-Erling Smørgrav /* a file containing a DNSSEC trust anchor */
938*3b092e49SDag-Erling Smørgrav gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
9397b5038d7SDag-Erling Smørgrav if (gtr == 0) {
9407b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
94117d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp);
9427b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
9437b5038d7SDag-Erling Smørgrav }
9447b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
9457b5038d7SDag-Erling Smørgrav tmp_rr = ldns_read_anchor_file(word);
9467b5038d7SDag-Erling Smørgrav (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
9477b5038d7SDag-Erling Smørgrav ldns_rr_free(tmp_rr);
9487b5038d7SDag-Erling Smørgrav #endif
9497b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD;
9507b5038d7SDag-Erling Smørgrav break;
9517b5038d7SDag-Erling Smørgrav }
9527b5038d7SDag-Erling Smørgrav }
9537b5038d7SDag-Erling Smørgrav
95417d15b25SDag-Erling Smørgrav if(!fp)
95517d15b25SDag-Erling Smørgrav fclose(myfp);
95617d15b25SDag-Erling Smørgrav
9577b5038d7SDag-Erling Smørgrav if (res) {
9587b5038d7SDag-Erling Smørgrav *res = r;
9597b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
9607b5038d7SDag-Erling Smørgrav } else {
9617b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r);
9627b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL;
9637b5038d7SDag-Erling Smørgrav }
9647b5038d7SDag-Erling Smørgrav }
9657b5038d7SDag-Erling Smørgrav
9667b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_new_frm_file(ldns_resolver ** res,const char * filename)9677b5038d7SDag-Erling Smørgrav ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
9687b5038d7SDag-Erling Smørgrav {
9697b5038d7SDag-Erling Smørgrav ldns_resolver *r;
9707b5038d7SDag-Erling Smørgrav FILE *fp;
9717b5038d7SDag-Erling Smørgrav ldns_status s;
9727b5038d7SDag-Erling Smørgrav
9737b5038d7SDag-Erling Smørgrav if (!filename) {
9747b5038d7SDag-Erling Smørgrav fp = fopen(LDNS_RESOLV_CONF, "r");
9757b5038d7SDag-Erling Smørgrav
9767b5038d7SDag-Erling Smørgrav } else {
9777b5038d7SDag-Erling Smørgrav fp = fopen(filename, "r");
9787b5038d7SDag-Erling Smørgrav }
9797b5038d7SDag-Erling Smørgrav if (!fp) {
9807b5038d7SDag-Erling Smørgrav return LDNS_STATUS_FILE_ERR;
9817b5038d7SDag-Erling Smørgrav }
9827b5038d7SDag-Erling Smørgrav
9837b5038d7SDag-Erling Smørgrav s = ldns_resolver_new_frm_fp(&r, fp);
9847b5038d7SDag-Erling Smørgrav fclose(fp);
9857b5038d7SDag-Erling Smørgrav if (s == LDNS_STATUS_OK) {
9867b5038d7SDag-Erling Smørgrav if (res) {
9877b5038d7SDag-Erling Smørgrav *res = r;
9887b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
9897b5038d7SDag-Erling Smørgrav } else {
9902787e39aSDag-Erling Smørgrav ldns_resolver_free(r);
9917b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL;
9927b5038d7SDag-Erling Smørgrav }
9937b5038d7SDag-Erling Smørgrav }
9947b5038d7SDag-Erling Smørgrav return s;
9957b5038d7SDag-Erling Smørgrav }
9967b5038d7SDag-Erling Smørgrav
9977b5038d7SDag-Erling Smørgrav void
ldns_resolver_free(ldns_resolver * res)9987b5038d7SDag-Erling Smørgrav ldns_resolver_free(ldns_resolver *res)
9997b5038d7SDag-Erling Smørgrav {
10007b5038d7SDag-Erling Smørgrav LDNS_FREE(res);
10017b5038d7SDag-Erling Smørgrav }
10027b5038d7SDag-Erling Smørgrav
10037b5038d7SDag-Erling Smørgrav void
ldns_resolver_deep_free(ldns_resolver * res)10047b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(ldns_resolver *res)
10057b5038d7SDag-Erling Smørgrav {
10067b5038d7SDag-Erling Smørgrav size_t i;
10077b5038d7SDag-Erling Smørgrav
10087b5038d7SDag-Erling Smørgrav if (res) {
1009986ba33cSDag-Erling Smørgrav close_socket(res->_socket);
1010986ba33cSDag-Erling Smørgrav
10117b5038d7SDag-Erling Smørgrav if (res->_searchlist) {
10127b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
10137b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(res->_searchlist[i]);
10147b5038d7SDag-Erling Smørgrav }
10157b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_searchlist);
10167b5038d7SDag-Erling Smørgrav }
10177b5038d7SDag-Erling Smørgrav if (res->_nameservers) {
10187b5038d7SDag-Erling Smørgrav for (i = 0; i < res->_nameserver_count; i++) {
10197b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(res->_nameservers[i]);
10207b5038d7SDag-Erling Smørgrav }
10217b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_nameservers);
10227b5038d7SDag-Erling Smørgrav }
10237b5038d7SDag-Erling Smørgrav if (ldns_resolver_domain(res)) {
10247b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_resolver_domain(res));
10257b5038d7SDag-Erling Smørgrav }
10267b5038d7SDag-Erling Smørgrav if (res->_tsig_keyname) {
10277b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_tsig_keyname);
10287b5038d7SDag-Erling Smørgrav }
10297b5038d7SDag-Erling Smørgrav if (res->_tsig_keydata) {
10307b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_tsig_keydata);
10317b5038d7SDag-Erling Smørgrav }
10327b5038d7SDag-Erling Smørgrav if (res->_tsig_algorithm) {
10337b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_tsig_algorithm);
10347b5038d7SDag-Erling Smørgrav }
10357b5038d7SDag-Erling Smørgrav
10367b5038d7SDag-Erling Smørgrav if (res->_cur_axfr_pkt) {
10377b5038d7SDag-Erling Smørgrav ldns_pkt_free(res->_cur_axfr_pkt);
10387b5038d7SDag-Erling Smørgrav }
10397b5038d7SDag-Erling Smørgrav
10407b5038d7SDag-Erling Smørgrav if (res->_rtt) {
10417b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_rtt);
10427b5038d7SDag-Erling Smørgrav }
10437b5038d7SDag-Erling Smørgrav if (res->_dnssec_anchors) {
10447b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(res->_dnssec_anchors);
10457b5038d7SDag-Erling Smørgrav }
10467b5038d7SDag-Erling Smørgrav LDNS_FREE(res);
10477b5038d7SDag-Erling Smørgrav }
10487b5038d7SDag-Erling Smørgrav }
10497b5038d7SDag-Erling Smørgrav
105017d15b25SDag-Erling Smørgrav ldns_status
ldns_resolver_search_status(ldns_pkt ** pkt,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)105117d15b25SDag-Erling Smørgrav ldns_resolver_search_status(ldns_pkt** pkt,
105217d15b25SDag-Erling Smørgrav ldns_resolver *r, const ldns_rdf *name,
10537b5038d7SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags)
10547b5038d7SDag-Erling Smørgrav {
10557b5038d7SDag-Erling Smørgrav ldns_rdf *new_name;
10567b5038d7SDag-Erling Smørgrav ldns_rdf **search_list;
10577b5038d7SDag-Erling Smørgrav size_t i;
105817d15b25SDag-Erling Smørgrav ldns_status s = LDNS_STATUS_OK;
1059986ba33cSDag-Erling Smørgrav ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
10607b5038d7SDag-Erling Smørgrav
10612787e39aSDag-Erling Smørgrav if (ldns_dname_absolute(name)) {
10627b5038d7SDag-Erling Smørgrav /* query as-is */
106317d15b25SDag-Erling Smørgrav return ldns_resolver_query_status(pkt, r, name, t, c, flags);
10647b5038d7SDag-Erling Smørgrav } else if (ldns_resolver_dnsrch(r)) {
10657b5038d7SDag-Erling Smørgrav search_list = ldns_resolver_searchlist(r);
1066986ba33cSDag-Erling Smørgrav for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
1067986ba33cSDag-Erling Smørgrav if (i == ldns_resolver_searchlist_count(r)) {
1068986ba33cSDag-Erling Smørgrav new_name = ldns_dname_cat_clone(name,
1069986ba33cSDag-Erling Smørgrav &root_dname);
1070986ba33cSDag-Erling Smørgrav } else {
1071986ba33cSDag-Erling Smørgrav new_name = ldns_dname_cat_clone(name,
1072986ba33cSDag-Erling Smørgrav search_list[i]);
1073986ba33cSDag-Erling Smørgrav }
10747b5038d7SDag-Erling Smørgrav
107517d15b25SDag-Erling Smørgrav s = ldns_resolver_query_status(pkt, r,
107617d15b25SDag-Erling Smørgrav new_name, t, c, flags);
10775afab0e5SDag-Erling Smørgrav ldns_rdf_deep_free(new_name);
10785afab0e5SDag-Erling Smørgrav
1079986ba33cSDag-Erling Smørgrav if (pkt && *pkt) {
1080986ba33cSDag-Erling Smørgrav if (s == LDNS_STATUS_OK &&
108117d15b25SDag-Erling Smørgrav ldns_pkt_get_rcode(*pkt) ==
108217d15b25SDag-Erling Smørgrav LDNS_RCODE_NOERROR) {
1083986ba33cSDag-Erling Smørgrav
108417d15b25SDag-Erling Smørgrav return LDNS_STATUS_OK;
108517d15b25SDag-Erling Smørgrav }
108617d15b25SDag-Erling Smørgrav ldns_pkt_free(*pkt);
1087986ba33cSDag-Erling Smørgrav *pkt = NULL;
10887b5038d7SDag-Erling Smørgrav }
10897b5038d7SDag-Erling Smørgrav }
10907b5038d7SDag-Erling Smørgrav }
109117d15b25SDag-Erling Smørgrav return s;
10927b5038d7SDag-Erling Smørgrav }
109317d15b25SDag-Erling Smørgrav
109417d15b25SDag-Erling Smørgrav ldns_pkt *
ldns_resolver_search(const ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)109517d15b25SDag-Erling Smørgrav ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name,
109617d15b25SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags)
109717d15b25SDag-Erling Smørgrav {
109817d15b25SDag-Erling Smørgrav ldns_pkt* pkt = NULL;
109917d15b25SDag-Erling Smørgrav if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
110017d15b25SDag-Erling Smørgrav name, t, c, flags) != LDNS_STATUS_OK) {
110117d15b25SDag-Erling Smørgrav ldns_pkt_free(pkt);
11025afab0e5SDag-Erling Smørgrav return NULL;
110317d15b25SDag-Erling Smørgrav }
110417d15b25SDag-Erling Smørgrav return pkt;
110517d15b25SDag-Erling Smørgrav }
110617d15b25SDag-Erling Smørgrav
110717d15b25SDag-Erling Smørgrav ldns_status
ldns_resolver_query_status(ldns_pkt ** pkt,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)110817d15b25SDag-Erling Smørgrav ldns_resolver_query_status(ldns_pkt** pkt,
110917d15b25SDag-Erling Smørgrav ldns_resolver *r, const ldns_rdf *name,
111017d15b25SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags)
111117d15b25SDag-Erling Smørgrav {
111217d15b25SDag-Erling Smørgrav ldns_rdf *newname;
111317d15b25SDag-Erling Smørgrav ldns_status status;
111417d15b25SDag-Erling Smørgrav
111517d15b25SDag-Erling Smørgrav if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
111617d15b25SDag-Erling Smørgrav return ldns_resolver_send(pkt, r, name, t, c, flags);
111717d15b25SDag-Erling Smørgrav }
111817d15b25SDag-Erling Smørgrav
111917d15b25SDag-Erling Smørgrav newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
112017d15b25SDag-Erling Smørgrav if (!newname) {
112117d15b25SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR;
112217d15b25SDag-Erling Smørgrav }
112317d15b25SDag-Erling Smørgrav status = ldns_resolver_send(pkt, r, newname, t, c, flags);
112417d15b25SDag-Erling Smørgrav ldns_rdf_free(newname);
112517d15b25SDag-Erling Smørgrav return status;
11267b5038d7SDag-Erling Smørgrav }
11277b5038d7SDag-Erling Smørgrav
11287b5038d7SDag-Erling Smørgrav ldns_pkt *
ldns_resolver_query(const ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)11297b5038d7SDag-Erling Smørgrav ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
11307b5038d7SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags)
11317b5038d7SDag-Erling Smørgrav {
113217d15b25SDag-Erling Smørgrav ldns_pkt* pkt = NULL;
113317d15b25SDag-Erling Smørgrav if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
113417d15b25SDag-Erling Smørgrav name, t, c, flags) != LDNS_STATUS_OK) {
11357b5038d7SDag-Erling Smørgrav ldns_pkt_free(pkt);
11365afab0e5SDag-Erling Smørgrav return NULL;
11377b5038d7SDag-Erling Smørgrav }
11387b5038d7SDag-Erling Smørgrav return pkt;
11397b5038d7SDag-Erling Smørgrav }
11407b5038d7SDag-Erling Smørgrav
11417b5038d7SDag-Erling Smørgrav static size_t *
ldns_resolver_backup_rtt(ldns_resolver * r)11427b5038d7SDag-Erling Smørgrav ldns_resolver_backup_rtt(ldns_resolver *r)
11437b5038d7SDag-Erling Smørgrav {
11447b5038d7SDag-Erling Smørgrav size_t *new_rtt;
11457b5038d7SDag-Erling Smørgrav size_t *old_rtt = ldns_resolver_rtt(r);
11467b5038d7SDag-Erling Smørgrav
11477b5038d7SDag-Erling Smørgrav if (old_rtt && ldns_resolver_nameserver_count(r)) {
11487b5038d7SDag-Erling Smørgrav new_rtt = LDNS_XMALLOC(size_t
11497b5038d7SDag-Erling Smørgrav , ldns_resolver_nameserver_count(r));
11505afab0e5SDag-Erling Smørgrav if (!new_rtt) return NULL;
11517b5038d7SDag-Erling Smørgrav memcpy(new_rtt, old_rtt, sizeof(size_t)
11527b5038d7SDag-Erling Smørgrav * ldns_resolver_nameserver_count(r));
11537b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(r, new_rtt);
11547b5038d7SDag-Erling Smørgrav return old_rtt;
11557b5038d7SDag-Erling Smørgrav }
11567b5038d7SDag-Erling Smørgrav return NULL;
11577b5038d7SDag-Erling Smørgrav }
11587b5038d7SDag-Erling Smørgrav
11597b5038d7SDag-Erling Smørgrav static void
ldns_resolver_restore_rtt(ldns_resolver * r,size_t * old_rtt)11607b5038d7SDag-Erling Smørgrav ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
11617b5038d7SDag-Erling Smørgrav {
11627b5038d7SDag-Erling Smørgrav size_t *cur_rtt = ldns_resolver_rtt(r);
11637b5038d7SDag-Erling Smørgrav
11647b5038d7SDag-Erling Smørgrav if (cur_rtt) {
11657b5038d7SDag-Erling Smørgrav LDNS_FREE(cur_rtt);
11667b5038d7SDag-Erling Smørgrav }
11677b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(r, old_rtt);
11687b5038d7SDag-Erling Smørgrav }
11697b5038d7SDag-Erling Smørgrav
11707b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_send_pkt(ldns_pkt ** answer,ldns_resolver * r,ldns_pkt * query_pkt)11717b5038d7SDag-Erling Smørgrav ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
11727b5038d7SDag-Erling Smørgrav ldns_pkt *query_pkt)
11737b5038d7SDag-Erling Smørgrav {
11747b5038d7SDag-Erling Smørgrav ldns_pkt *answer_pkt = NULL;
11757b5038d7SDag-Erling Smørgrav ldns_status stat = LDNS_STATUS_OK;
11767b5038d7SDag-Erling Smørgrav size_t *rtt;
11777b5038d7SDag-Erling Smørgrav
11787b5038d7SDag-Erling Smørgrav stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
11797b5038d7SDag-Erling Smørgrav if (stat != LDNS_STATUS_OK) {
11807b5038d7SDag-Erling Smørgrav if(answer_pkt) {
11817b5038d7SDag-Erling Smørgrav ldns_pkt_free(answer_pkt);
11827b5038d7SDag-Erling Smørgrav answer_pkt = NULL;
11837b5038d7SDag-Erling Smørgrav }
11847b5038d7SDag-Erling Smørgrav } else {
11857b5038d7SDag-Erling Smørgrav /* if tc=1 fall back to EDNS and/or TCP */
11867b5038d7SDag-Erling Smørgrav /* check for tcp first (otherwise we don't care about tc=1) */
11877b5038d7SDag-Erling Smørgrav if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
11887b5038d7SDag-Erling Smørgrav if (ldns_pkt_tc(answer_pkt)) {
11897b5038d7SDag-Erling Smørgrav /* was EDNS0 set? */
11907b5038d7SDag-Erling Smørgrav if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
11917b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(query_pkt
11927b5038d7SDag-Erling Smørgrav , 4096);
11937b5038d7SDag-Erling Smørgrav ldns_pkt_free(answer_pkt);
1194986ba33cSDag-Erling Smørgrav answer_pkt = NULL;
11957b5038d7SDag-Erling Smørgrav /* Nameservers should not become
11967b5038d7SDag-Erling Smørgrav * unreachable because fragments are
11977b5038d7SDag-Erling Smørgrav * dropped (network error). We might
11987b5038d7SDag-Erling Smørgrav * still have success with TCP.
11997b5038d7SDag-Erling Smørgrav * Therefore maintain reachability
12007b5038d7SDag-Erling Smørgrav * statuses of the nameservers by
12017b5038d7SDag-Erling Smørgrav * backup and restore the rtt list.
12027b5038d7SDag-Erling Smørgrav */
12037b5038d7SDag-Erling Smørgrav rtt = ldns_resolver_backup_rtt(r);
12047b5038d7SDag-Erling Smørgrav stat = ldns_send(&answer_pkt, r
12057b5038d7SDag-Erling Smørgrav , query_pkt);
12067b5038d7SDag-Erling Smørgrav ldns_resolver_restore_rtt(r, rtt);
12077b5038d7SDag-Erling Smørgrav }
12087b5038d7SDag-Erling Smørgrav /* either way, if it is still truncated, use TCP */
12097b5038d7SDag-Erling Smørgrav if (stat != LDNS_STATUS_OK ||
12107b5038d7SDag-Erling Smørgrav ldns_pkt_tc(answer_pkt)) {
12117b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(r, true);
12127b5038d7SDag-Erling Smørgrav ldns_pkt_free(answer_pkt);
12135afab0e5SDag-Erling Smørgrav answer_pkt = NULL;
12147b5038d7SDag-Erling Smørgrav stat = ldns_send(&answer_pkt, r, query_pkt);
12157b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(r, false);
12167b5038d7SDag-Erling Smørgrav }
12177b5038d7SDag-Erling Smørgrav }
12187b5038d7SDag-Erling Smørgrav }
12197b5038d7SDag-Erling Smørgrav }
12207b5038d7SDag-Erling Smørgrav
12215afab0e5SDag-Erling Smørgrav if (answer && answer_pkt) {
12227b5038d7SDag-Erling Smørgrav *answer = answer_pkt;
12237b5038d7SDag-Erling Smørgrav }
12247b5038d7SDag-Erling Smørgrav
12257b5038d7SDag-Erling Smørgrav return stat;
12267b5038d7SDag-Erling Smørgrav }
12277b5038d7SDag-Erling Smørgrav
12287b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_prepare_query_pkt(ldns_pkt ** query_pkt,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)12297b5038d7SDag-Erling Smørgrav ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
12307b5038d7SDag-Erling Smørgrav const ldns_rdf *name, ldns_rr_type t,
12317b5038d7SDag-Erling Smørgrav ldns_rr_class c, uint16_t flags)
12327b5038d7SDag-Erling Smørgrav {
12337b5038d7SDag-Erling Smørgrav struct timeval now;
1234986ba33cSDag-Erling Smørgrav ldns_rr* soa = NULL;
12357b5038d7SDag-Erling Smørgrav
12367b5038d7SDag-Erling Smørgrav /* prepare a question pkt from the parameters
12377b5038d7SDag-Erling Smørgrav * and then send this */
123817d15b25SDag-Erling Smørgrav if (t == LDNS_RR_TYPE_IXFR) {
1239986ba33cSDag-Erling Smørgrav ldns_rdf *owner_rdf;
1240986ba33cSDag-Erling Smørgrav ldns_rdf *mname_rdf;
1241986ba33cSDag-Erling Smørgrav ldns_rdf *rname_rdf;
1242986ba33cSDag-Erling Smørgrav ldns_rdf *serial_rdf;
1243986ba33cSDag-Erling Smørgrav ldns_rdf *refresh_rdf;
1244986ba33cSDag-Erling Smørgrav ldns_rdf *retry_rdf;
1245986ba33cSDag-Erling Smørgrav ldns_rdf *expire_rdf;
1246986ba33cSDag-Erling Smørgrav ldns_rdf *minimum_rdf;
1247986ba33cSDag-Erling Smørgrav soa = ldns_rr_new();
1248986ba33cSDag-Erling Smørgrav
1249986ba33cSDag-Erling Smørgrav if (!soa) {
1250986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1251986ba33cSDag-Erling Smørgrav }
1252986ba33cSDag-Erling Smørgrav owner_rdf = ldns_rdf_clone(name);
1253986ba33cSDag-Erling Smørgrav if (!owner_rdf) {
1254986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1255986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1256986ba33cSDag-Erling Smørgrav }
1257986ba33cSDag-Erling Smørgrav ldns_rr_set_owner(soa, owner_rdf);
1258986ba33cSDag-Erling Smørgrav ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
1259986ba33cSDag-Erling Smørgrav ldns_rr_set_class(soa, c);
1260986ba33cSDag-Erling Smørgrav ldns_rr_set_question(soa, false);
1261986ba33cSDag-Erling Smørgrav if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
1262986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1263986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1264986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, mname_rdf);
1265986ba33cSDag-Erling Smørgrav if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
1266986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1267986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1268986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, rname_rdf);
1269986ba33cSDag-Erling Smørgrav serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
1270986ba33cSDag-Erling Smørgrav if (!serial_rdf) {
1271986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1272986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1273986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, serial_rdf);
1274986ba33cSDag-Erling Smørgrav refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1275986ba33cSDag-Erling Smørgrav if (!refresh_rdf) {
1276986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1277986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1278986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, refresh_rdf);
1279986ba33cSDag-Erling Smørgrav retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1280986ba33cSDag-Erling Smørgrav if (!retry_rdf) {
1281986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1282986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1283986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, retry_rdf);
1284986ba33cSDag-Erling Smørgrav expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1285986ba33cSDag-Erling Smørgrav if (!expire_rdf) {
1286986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1287986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1288986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, expire_rdf);
1289986ba33cSDag-Erling Smørgrav minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1290986ba33cSDag-Erling Smørgrav if (!minimum_rdf) {
1291986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
1292986ba33cSDag-Erling Smørgrav return LDNS_STATUS_ERR;
1293986ba33cSDag-Erling Smørgrav } else ldns_rr_push_rdf(soa, minimum_rdf);
1294986ba33cSDag-Erling Smørgrav
129517d15b25SDag-Erling Smørgrav *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
1296986ba33cSDag-Erling Smørgrav c, flags, soa);
129717d15b25SDag-Erling Smørgrav } else {
12987b5038d7SDag-Erling Smørgrav *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
129917d15b25SDag-Erling Smørgrav }
13007b5038d7SDag-Erling Smørgrav if (!*query_pkt) {
1301986ba33cSDag-Erling Smørgrav ldns_rr_free(soa);
13027b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR;
13037b5038d7SDag-Erling Smørgrav }
13047b5038d7SDag-Erling Smørgrav
13057b5038d7SDag-Erling Smørgrav /* set DO bit if necessary */
13067b5038d7SDag-Erling Smørgrav if (ldns_resolver_dnssec(r)) {
13077b5038d7SDag-Erling Smørgrav if (ldns_resolver_edns_udp_size(r) == 0) {
13087b5038d7SDag-Erling Smørgrav ldns_resolver_set_edns_udp_size(r, 4096);
13097b5038d7SDag-Erling Smørgrav }
13107b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_do(*query_pkt, true);
13117b5038d7SDag-Erling Smørgrav if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
13127b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(*query_pkt, true);
13137b5038d7SDag-Erling Smørgrav }
13147b5038d7SDag-Erling Smørgrav }
13157b5038d7SDag-Erling Smørgrav
13167b5038d7SDag-Erling Smørgrav /* transfer the udp_edns_size from the resolver to the packet */
13177b5038d7SDag-Erling Smørgrav if (ldns_resolver_edns_udp_size(r) != 0) {
13187b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
13197b5038d7SDag-Erling Smørgrav }
13207b5038d7SDag-Erling Smørgrav
13217b5038d7SDag-Erling Smørgrav /* set the timestamp */
13227b5038d7SDag-Erling Smørgrav now.tv_sec = time(NULL);
13237b5038d7SDag-Erling Smørgrav now.tv_usec = 0;
13247b5038d7SDag-Erling Smørgrav ldns_pkt_set_timestamp(*query_pkt, now);
13257b5038d7SDag-Erling Smørgrav
13267b5038d7SDag-Erling Smørgrav
13277b5038d7SDag-Erling Smørgrav if (ldns_resolver_debug(r)) {
13287b5038d7SDag-Erling Smørgrav ldns_pkt_print(stdout, *query_pkt);
13297b5038d7SDag-Erling Smørgrav }
13307b5038d7SDag-Erling Smørgrav
13317b5038d7SDag-Erling Smørgrav /* only set the id if it is not set yet */
13327b5038d7SDag-Erling Smørgrav if (ldns_pkt_id(*query_pkt) == 0) {
13337b5038d7SDag-Erling Smørgrav ldns_pkt_set_random_id(*query_pkt);
13347b5038d7SDag-Erling Smørgrav }
13357b5038d7SDag-Erling Smørgrav
13367b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK;
13377b5038d7SDag-Erling Smørgrav }
13387b5038d7SDag-Erling Smørgrav
13397b5038d7SDag-Erling Smørgrav ldns_status
ldns_resolver_send(ldns_pkt ** answer,ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)13407b5038d7SDag-Erling Smørgrav ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
13417b5038d7SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags)
13427b5038d7SDag-Erling Smørgrav {
13437b5038d7SDag-Erling Smørgrav ldns_pkt *query_pkt;
13447b5038d7SDag-Erling Smørgrav ldns_pkt *answer_pkt;
13457b5038d7SDag-Erling Smørgrav ldns_status status;
13467b5038d7SDag-Erling Smørgrav
13477b5038d7SDag-Erling Smørgrav assert(r != NULL);
13487b5038d7SDag-Erling Smørgrav assert(name != NULL);
13497b5038d7SDag-Erling Smørgrav
13507b5038d7SDag-Erling Smørgrav answer_pkt = NULL;
13517b5038d7SDag-Erling Smørgrav
13527b5038d7SDag-Erling Smørgrav /* do all the preprocessing here, then fire of an query to
13537b5038d7SDag-Erling Smørgrav * the network */
13547b5038d7SDag-Erling Smørgrav
13557b5038d7SDag-Erling Smørgrav if (0 == t) {
13567b5038d7SDag-Erling Smørgrav t= LDNS_RR_TYPE_A;
13577b5038d7SDag-Erling Smørgrav }
13587b5038d7SDag-Erling Smørgrav if (0 == c) {
13597b5038d7SDag-Erling Smørgrav c= LDNS_RR_CLASS_IN;
13607b5038d7SDag-Erling Smørgrav }
13617b5038d7SDag-Erling Smørgrav if (0 == ldns_resolver_nameserver_count(r)) {
13627b5038d7SDag-Erling Smørgrav return LDNS_STATUS_RES_NO_NS;
13637b5038d7SDag-Erling Smørgrav }
13647b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
13657b5038d7SDag-Erling Smørgrav return LDNS_STATUS_RES_QUERY;
13667b5038d7SDag-Erling Smørgrav }
13677b5038d7SDag-Erling Smørgrav
13687b5038d7SDag-Erling Smørgrav status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
13697b5038d7SDag-Erling Smørgrav t, c, flags);
13707b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
13717b5038d7SDag-Erling Smørgrav return status;
13727b5038d7SDag-Erling Smørgrav }
13737b5038d7SDag-Erling Smørgrav
13747b5038d7SDag-Erling Smørgrav /* if tsig values are set, tsign it */
13757b5038d7SDag-Erling Smørgrav /* TODO: make last 3 arguments optional too? maybe make complete
137617d15b25SDag-Erling Smørgrav rr instead of separate values in resolver (and packet)
13777b5038d7SDag-Erling Smørgrav Jelte
13787b5038d7SDag-Erling Smørgrav should this go in pkt_prepare?
13797b5038d7SDag-Erling Smørgrav */
13807b5038d7SDag-Erling Smørgrav if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
13817b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL
13827b5038d7SDag-Erling Smørgrav status = ldns_pkt_tsig_sign(query_pkt,
13837b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_keyname(r),
13847b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_keydata(r),
13857b5038d7SDag-Erling Smørgrav 300, ldns_resolver_tsig_algorithm(r), NULL);
13867b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
13872787e39aSDag-Erling Smørgrav ldns_pkt_free(query_pkt);
13887b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_TSIG_ERR;
13897b5038d7SDag-Erling Smørgrav }
13907b5038d7SDag-Erling Smørgrav #else
13912787e39aSDag-Erling Smørgrav ldns_pkt_free(query_pkt);
13927b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_TSIG_ERR;
13937b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */
13947b5038d7SDag-Erling Smørgrav }
13957b5038d7SDag-Erling Smørgrav
13967b5038d7SDag-Erling Smørgrav status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
13977b5038d7SDag-Erling Smørgrav ldns_pkt_free(query_pkt);
13987b5038d7SDag-Erling Smørgrav
13997b5038d7SDag-Erling Smørgrav /* allows answer to be NULL when not interested in return value */
14007b5038d7SDag-Erling Smørgrav if (answer) {
14017b5038d7SDag-Erling Smørgrav *answer = answer_pkt;
14027b5038d7SDag-Erling Smørgrav }
14037b5038d7SDag-Erling Smørgrav return status;
14047b5038d7SDag-Erling Smørgrav }
14057b5038d7SDag-Erling Smørgrav
14067b5038d7SDag-Erling Smørgrav ldns_rr *
ldns_axfr_next(ldns_resolver * resolver)14077b5038d7SDag-Erling Smørgrav ldns_axfr_next(ldns_resolver *resolver)
14087b5038d7SDag-Erling Smørgrav {
14097b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr;
14107b5038d7SDag-Erling Smørgrav uint8_t *packet_wire;
14117b5038d7SDag-Erling Smørgrav size_t packet_wire_size;
14127b5038d7SDag-Erling Smørgrav ldns_status status;
14137b5038d7SDag-Erling Smørgrav
14147b5038d7SDag-Erling Smørgrav /* check if start() has been called */
1415986ba33cSDag-Erling Smørgrav if (!resolver || resolver->_socket == -1) {
14167b5038d7SDag-Erling Smørgrav return NULL;
14177b5038d7SDag-Erling Smørgrav }
14187b5038d7SDag-Erling Smørgrav
14197b5038d7SDag-Erling Smørgrav if (resolver->_cur_axfr_pkt) {
14207b5038d7SDag-Erling Smørgrav if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
14217b5038d7SDag-Erling Smørgrav ldns_pkt_free(resolver->_cur_axfr_pkt);
14227b5038d7SDag-Erling Smørgrav resolver->_cur_axfr_pkt = NULL;
14237b5038d7SDag-Erling Smørgrav return ldns_axfr_next(resolver);
14247b5038d7SDag-Erling Smørgrav }
14257b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_clone(ldns_rr_list_rr(
14267b5038d7SDag-Erling Smørgrav ldns_pkt_answer(resolver->_cur_axfr_pkt),
14277b5038d7SDag-Erling Smørgrav resolver->_axfr_i));
14287b5038d7SDag-Erling Smørgrav resolver->_axfr_i++;
14297b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
14307b5038d7SDag-Erling Smørgrav resolver->_axfr_soa_count++;
14317b5038d7SDag-Erling Smørgrav if (resolver->_axfr_soa_count >= 2) {
1432986ba33cSDag-Erling Smørgrav
1433986ba33cSDag-Erling Smørgrav close_socket(resolver->_socket);
1434986ba33cSDag-Erling Smørgrav
14357b5038d7SDag-Erling Smørgrav ldns_pkt_free(resolver->_cur_axfr_pkt);
14367b5038d7SDag-Erling Smørgrav resolver->_cur_axfr_pkt = NULL;
14377b5038d7SDag-Erling Smørgrav }
14387b5038d7SDag-Erling Smørgrav }
14397b5038d7SDag-Erling Smørgrav return cur_rr;
14407b5038d7SDag-Erling Smørgrav } else {
1441986ba33cSDag-Erling Smørgrav packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
14427b5038d7SDag-Erling Smørgrav if(!packet_wire)
14437b5038d7SDag-Erling Smørgrav return NULL;
14447b5038d7SDag-Erling Smørgrav
14457b5038d7SDag-Erling Smørgrav status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
14467b5038d7SDag-Erling Smørgrav packet_wire_size);
14477b5038d7SDag-Erling Smørgrav LDNS_FREE(packet_wire);
14487b5038d7SDag-Erling Smørgrav
14497b5038d7SDag-Erling Smørgrav resolver->_axfr_i = 0;
14507b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) {
14517b5038d7SDag-Erling Smørgrav /* TODO: make status return type of this function (...api change) */
145217d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
14537b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
145417d15b25SDag-Erling Smørgrav #endif
14557b5038d7SDag-Erling Smørgrav
145617d15b25SDag-Erling Smørgrav /* we must now also close the socket, otherwise subsequent uses of the
14577b5038d7SDag-Erling Smørgrav same resolver structure will fail because the link is still open or
14587b5038d7SDag-Erling Smørgrav in an undefined state */
1459986ba33cSDag-Erling Smørgrav
1460986ba33cSDag-Erling Smørgrav close_socket(resolver->_socket);
14617b5038d7SDag-Erling Smørgrav
14627b5038d7SDag-Erling Smørgrav return NULL;
14637b5038d7SDag-Erling Smørgrav } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
146417d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS
1465986ba33cSDag-Erling Smørgrav ldns_lookup_table *rcode = ldns_lookup_by_id(
1466986ba33cSDag-Erling Smørgrav ldns_rcodes,(int) ldns_pkt_get_rcode(
1467986ba33cSDag-Erling Smørgrav resolver->_cur_axfr_pkt));
14682787e39aSDag-Erling Smørgrav if (rcode) {
14692787e39aSDag-Erling Smørgrav fprintf(stderr, "Error in AXFR: %s\n",
14702787e39aSDag-Erling Smørgrav rcode->name);
14712787e39aSDag-Erling Smørgrav } else {
14722787e39aSDag-Erling Smørgrav fprintf(stderr, "Error in AXFR: %d\n",
14732787e39aSDag-Erling Smørgrav (int) ldns_pkt_get_rcode(
14742787e39aSDag-Erling Smørgrav resolver->_cur_axfr_pkt));
14752787e39aSDag-Erling Smørgrav }
147617d15b25SDag-Erling Smørgrav #endif
14777b5038d7SDag-Erling Smørgrav
147817d15b25SDag-Erling Smørgrav /* we must now also close the socket, otherwise subsequent uses of the
14797b5038d7SDag-Erling Smørgrav same resolver structure will fail because the link is still open or
14807b5038d7SDag-Erling Smørgrav in an undefined state */
1481986ba33cSDag-Erling Smørgrav
1482986ba33cSDag-Erling Smørgrav close_socket(resolver->_socket);
14837b5038d7SDag-Erling Smørgrav
14847b5038d7SDag-Erling Smørgrav return NULL;
14857b5038d7SDag-Erling Smørgrav } else {
14867b5038d7SDag-Erling Smørgrav return ldns_axfr_next(resolver);
14877b5038d7SDag-Erling Smørgrav }
14887b5038d7SDag-Erling Smørgrav
14897b5038d7SDag-Erling Smørgrav }
14907b5038d7SDag-Erling Smørgrav
14917b5038d7SDag-Erling Smørgrav }
14927b5038d7SDag-Erling Smørgrav
149317d15b25SDag-Erling Smørgrav /* this function is needed to abort a transfer that is in progress;
149417d15b25SDag-Erling Smørgrav * without it an aborted transfer will lead to the AXFR code in the
149517d15b25SDag-Erling Smørgrav * library staying in an indetermined state because the socket for the
149617d15b25SDag-Erling Smørgrav * AXFR is never closed
149717d15b25SDag-Erling Smørgrav */
1498daf4c72fSDag-Erling Smørgrav void
ldns_axfr_abort(ldns_resolver * resolver)149917d15b25SDag-Erling Smørgrav ldns_axfr_abort(ldns_resolver *resolver)
150017d15b25SDag-Erling Smørgrav {
150117d15b25SDag-Erling Smørgrav /* Only abort if an actual AXFR is in progress */
15025afab0e5SDag-Erling Smørgrav if (resolver->_socket != -1)
150317d15b25SDag-Erling Smørgrav {
150417d15b25SDag-Erling Smørgrav #ifndef USE_WINSOCK
150517d15b25SDag-Erling Smørgrav close(resolver->_socket);
150617d15b25SDag-Erling Smørgrav #else
150717d15b25SDag-Erling Smørgrav closesocket(resolver->_socket);
150817d15b25SDag-Erling Smørgrav #endif
15095afab0e5SDag-Erling Smørgrav resolver->_socket = -1;
151017d15b25SDag-Erling Smørgrav }
151117d15b25SDag-Erling Smørgrav }
151217d15b25SDag-Erling Smørgrav
15137b5038d7SDag-Erling Smørgrav bool
ldns_axfr_complete(const ldns_resolver * res)15147b5038d7SDag-Erling Smørgrav ldns_axfr_complete(const ldns_resolver *res)
15157b5038d7SDag-Erling Smørgrav {
15167b5038d7SDag-Erling Smørgrav /* complete when soa count is 2? */
15177b5038d7SDag-Erling Smørgrav return res->_axfr_soa_count == 2;
15187b5038d7SDag-Erling Smørgrav }
15197b5038d7SDag-Erling Smørgrav
15207b5038d7SDag-Erling Smørgrav ldns_pkt *
ldns_axfr_last_pkt(const ldns_resolver * res)15217b5038d7SDag-Erling Smørgrav ldns_axfr_last_pkt(const ldns_resolver *res)
15227b5038d7SDag-Erling Smørgrav {
15237b5038d7SDag-Erling Smørgrav return res->_cur_axfr_pkt;
15247b5038d7SDag-Erling Smørgrav }
15257b5038d7SDag-Erling Smørgrav
1526986ba33cSDag-Erling Smørgrav void
ldns_resolver_set_ixfr_serial(ldns_resolver * r,uint32_t serial)1527986ba33cSDag-Erling Smørgrav ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
1528986ba33cSDag-Erling Smørgrav {
1529986ba33cSDag-Erling Smørgrav r->_serial = serial;
1530986ba33cSDag-Erling Smørgrav }
1531986ba33cSDag-Erling Smørgrav
1532986ba33cSDag-Erling Smørgrav uint32_t
ldns_resolver_get_ixfr_serial(const ldns_resolver * res)1533986ba33cSDag-Erling Smørgrav ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
1534986ba33cSDag-Erling Smørgrav {
1535986ba33cSDag-Erling Smørgrav return res->_serial;
1536986ba33cSDag-Erling Smørgrav }
1537986ba33cSDag-Erling Smørgrav
1538986ba33cSDag-Erling Smørgrav
15397b5038d7SDag-Erling Smørgrav /* random isn't really that good */
15407b5038d7SDag-Erling Smørgrav void
ldns_resolver_nameservers_randomize(ldns_resolver * r)15417b5038d7SDag-Erling Smørgrav ldns_resolver_nameservers_randomize(ldns_resolver *r)
15427b5038d7SDag-Erling Smørgrav {
15437b5038d7SDag-Erling Smørgrav uint16_t i, j;
15442787e39aSDag-Erling Smørgrav ldns_rdf **ns, *tmpns;
15452787e39aSDag-Erling Smørgrav size_t *rtt, tmprtt;
15467b5038d7SDag-Erling Smørgrav
15477b5038d7SDag-Erling Smørgrav /* should I check for ldns_resolver_random?? */
15487b5038d7SDag-Erling Smørgrav assert(r != NULL);
15497b5038d7SDag-Erling Smørgrav
15507b5038d7SDag-Erling Smørgrav ns = ldns_resolver_nameservers(r);
15512787e39aSDag-Erling Smørgrav rtt = ldns_resolver_rtt(r);
15527b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
15537b5038d7SDag-Erling Smørgrav j = ldns_get_random() % ldns_resolver_nameserver_count(r);
15542787e39aSDag-Erling Smørgrav tmpns = ns[i];
15557b5038d7SDag-Erling Smørgrav ns[i] = ns[j];
15562787e39aSDag-Erling Smørgrav ns[j] = tmpns;
15572787e39aSDag-Erling Smørgrav tmprtt = rtt[i];
15582787e39aSDag-Erling Smørgrav rtt[i] = rtt[j];
15592787e39aSDag-Erling Smørgrav rtt[j] = tmprtt;
15607b5038d7SDag-Erling Smørgrav }
15617b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameservers(r, ns);
15627b5038d7SDag-Erling Smørgrav }
15637b5038d7SDag-Erling Smørgrav
1564