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 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 29*17d15b25SDag-Erling Smørgrav ldns_rdf * 30*17d15b25SDag-Erling Smørgrav ldns_resolver_source(const ldns_resolver *r) 31*17d15b25SDag-Erling Smørgrav { 32*17d15b25SDag-Erling Smørgrav return r->_source; 33*17d15b25SDag-Erling Smørgrav } 34*17d15b25SDag-Erling Smørgrav 357b5038d7SDag-Erling Smørgrav uint16_t 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 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 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 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 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 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 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 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 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 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 * 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 ** 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 ** 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 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 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 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 * 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 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 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 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 * 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 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 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 2067b5038d7SDag-Erling Smørgrav char * 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 2127b5038d7SDag-Erling Smørgrav char * 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 2187b5038d7SDag-Erling Smørgrav char * 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 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 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 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 243*17d15b25SDag-Erling Smørgrav void 244*17d15b25SDag-Erling Smørgrav ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s) 245*17d15b25SDag-Erling Smørgrav { 246*17d15b25SDag-Erling Smørgrav r->_source = s; 247*17d15b25SDag-Erling Smørgrav } 248*17d15b25SDag-Erling Smørgrav 2497b5038d7SDag-Erling Smørgrav ldns_rdf * 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 2887b5038d7SDag-Erling Smørgrav ldns_resolver_push_nameserver(ldns_resolver *r, 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 3357b5038d7SDag-Erling Smørgrav ldns_resolver_push_nameserver_rr(ldns_resolver *r, 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 3517b5038d7SDag-Erling Smørgrav ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 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 5807b5038d7SDag-Erling Smørgrav ldns_resolver_set_tsig_keyname(ldns_resolver *r, 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 5877b5038d7SDag-Erling Smørgrav ldns_resolver_set_tsig_algorithm(ldns_resolver *r, 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 5947b5038d7SDag-Erling Smørgrav ldns_resolver_set_tsig_keydata(ldns_resolver *r, 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 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 * 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); 640*17d15b25SDag-Erling Smørgrav ldns_resolver_set_source(r, NULL); 6417b5038d7SDag-Erling Smørgrav 6427b5038d7SDag-Erling Smørgrav /* randomize the nameserver to be queried 6437b5038d7SDag-Erling Smørgrav * when there are multiple 6447b5038d7SDag-Erling Smørgrav */ 6457b5038d7SDag-Erling Smørgrav ldns_resolver_set_random(r, true); 6467b5038d7SDag-Erling Smørgrav 6477b5038d7SDag-Erling Smørgrav ldns_resolver_set_debug(r, 0); 6487b5038d7SDag-Erling Smørgrav 6497b5038d7SDag-Erling Smørgrav r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; 6507b5038d7SDag-Erling Smørgrav r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC; 6517b5038d7SDag-Erling Smørgrav 6527b5038d7SDag-Erling Smørgrav /* TODO: fd=0 is actually a valid socket (stdin), 6537b5038d7SDag-Erling Smørgrav replace with -1 */ 6547b5038d7SDag-Erling Smørgrav r->_socket = 0; 6557b5038d7SDag-Erling Smørgrav r->_axfr_soa_count = 0; 6567b5038d7SDag-Erling Smørgrav r->_axfr_i = 0; 6577b5038d7SDag-Erling Smørgrav r->_cur_axfr_pkt = NULL; 6587b5038d7SDag-Erling Smørgrav 6597b5038d7SDag-Erling Smørgrav r->_tsig_keyname = NULL; 6607b5038d7SDag-Erling Smørgrav r->_tsig_keydata = NULL; 6617b5038d7SDag-Erling Smørgrav r->_tsig_algorithm = NULL; 6627b5038d7SDag-Erling Smørgrav return r; 6637b5038d7SDag-Erling Smørgrav } 6647b5038d7SDag-Erling Smørgrav 6657b5038d7SDag-Erling Smørgrav ldns_status 6667b5038d7SDag-Erling Smørgrav ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp) 6677b5038d7SDag-Erling Smørgrav { 6687b5038d7SDag-Erling Smørgrav return ldns_resolver_new_frm_fp_l(res, fp, NULL); 6697b5038d7SDag-Erling Smørgrav } 6707b5038d7SDag-Erling Smørgrav 6717b5038d7SDag-Erling Smørgrav ldns_status 6727b5038d7SDag-Erling Smørgrav ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) 6737b5038d7SDag-Erling Smørgrav { 6747b5038d7SDag-Erling Smørgrav ldns_resolver *r; 6757b5038d7SDag-Erling Smørgrav const char *keyword[LDNS_RESOLV_KEYWORDS]; 6767b5038d7SDag-Erling Smørgrav char word[LDNS_MAX_LINELEN + 1]; 6777b5038d7SDag-Erling Smørgrav int8_t expect; 6787b5038d7SDag-Erling Smørgrav uint8_t i; 6797b5038d7SDag-Erling Smørgrav ldns_rdf *tmp; 6807b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 6817b5038d7SDag-Erling Smørgrav ldns_rr *tmp_rr; 6827b5038d7SDag-Erling Smørgrav #endif 6837b5038d7SDag-Erling Smørgrav ssize_t gtr, bgtr; 6847b5038d7SDag-Erling Smørgrav ldns_buffer *b; 6857b5038d7SDag-Erling Smørgrav int lnr = 0, oldline; 686*17d15b25SDag-Erling Smørgrav FILE* myfp = fp; 6877b5038d7SDag-Erling Smørgrav if(!line_nr) line_nr = &lnr; 6887b5038d7SDag-Erling Smørgrav 689*17d15b25SDag-Erling Smørgrav if(!fp) { 690*17d15b25SDag-Erling Smørgrav myfp = fopen("/etc/resolv.conf", "r"); 691*17d15b25SDag-Erling Smørgrav if(!myfp) 692*17d15b25SDag-Erling Smørgrav return LDNS_STATUS_FILE_ERR; 693*17d15b25SDag-Erling Smørgrav } 694*17d15b25SDag-Erling Smørgrav 6957b5038d7SDag-Erling Smørgrav /* do this better 6967b5038d7SDag-Erling Smørgrav * expect = 6977b5038d7SDag-Erling Smørgrav * 0: keyword 6987b5038d7SDag-Erling Smørgrav * 1: default domain dname 6997b5038d7SDag-Erling Smørgrav * 2: NS aaaa or a record 7007b5038d7SDag-Erling Smørgrav */ 7017b5038d7SDag-Erling Smørgrav 7027b5038d7SDag-Erling Smørgrav /* recognized keywords */ 7037b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; 7047b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; 7057b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_SEARCH] = "search"; 7067b5038d7SDag-Erling Smørgrav /* these two are read but not used atm TODO */ 7077b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; 7087b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_OPTIONS] = "options"; 7097b5038d7SDag-Erling Smørgrav keyword[LDNS_RESOLV_ANCHOR] = "anchor"; 7107b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 7117b5038d7SDag-Erling Smørgrav 7127b5038d7SDag-Erling Smørgrav r = ldns_resolver_new(); 7137b5038d7SDag-Erling Smørgrav if (!r) { 714*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 7157b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 7167b5038d7SDag-Erling Smørgrav } 7177b5038d7SDag-Erling Smørgrav 7187b5038d7SDag-Erling Smørgrav gtr = 1; 7197b5038d7SDag-Erling Smørgrav word[0] = 0; 7207b5038d7SDag-Erling Smørgrav oldline = *line_nr; 7217b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 7227b5038d7SDag-Erling Smørgrav while (gtr > 0) { 7237b5038d7SDag-Erling Smørgrav /* check comments */ 7247b5038d7SDag-Erling Smørgrav if (word[0] == '#') { 7257b5038d7SDag-Erling Smørgrav word[0]='x'; 7267b5038d7SDag-Erling Smørgrav if(oldline == *line_nr) { 7277b5038d7SDag-Erling Smørgrav /* skip until end of line */ 7287b5038d7SDag-Erling Smørgrav int c; 7297b5038d7SDag-Erling Smørgrav do { 730*17d15b25SDag-Erling Smørgrav c = fgetc(myfp); 7317b5038d7SDag-Erling Smørgrav } while(c != EOF && c != '\n'); 732*17d15b25SDag-Erling Smørgrav if(c=='\n') (*line_nr)++; 7337b5038d7SDag-Erling Smørgrav } 7347b5038d7SDag-Erling Smørgrav /* and read next to prepare for further parsing */ 7357b5038d7SDag-Erling Smørgrav oldline = *line_nr; 7367b5038d7SDag-Erling Smørgrav continue; 7377b5038d7SDag-Erling Smørgrav } 7387b5038d7SDag-Erling Smørgrav oldline = *line_nr; 7397b5038d7SDag-Erling Smørgrav switch(expect) { 7407b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_KEYWORD: 7417b5038d7SDag-Erling Smørgrav /* keyword */ 742*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 7437b5038d7SDag-Erling Smørgrav if (gtr != 0) { 7447b5038d7SDag-Erling Smørgrav if(word[0] == '#') continue; 7457b5038d7SDag-Erling Smørgrav for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { 7467b5038d7SDag-Erling Smørgrav if (strcasecmp(keyword[i], word) == 0) { 7477b5038d7SDag-Erling Smørgrav /* chosen the keyword and 7487b5038d7SDag-Erling Smørgrav * expect values carefully 7497b5038d7SDag-Erling Smørgrav */ 7507b5038d7SDag-Erling Smørgrav expect = i; 7517b5038d7SDag-Erling Smørgrav break; 7527b5038d7SDag-Erling Smørgrav } 7537b5038d7SDag-Erling Smørgrav } 7547b5038d7SDag-Erling Smørgrav /* no keyword recognized */ 7557b5038d7SDag-Erling Smørgrav if (expect == LDNS_RESOLV_KEYWORD) { 7567b5038d7SDag-Erling Smørgrav /* skip line */ 7577b5038d7SDag-Erling Smørgrav /* 7587b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 759*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 7607b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_KEYWORD_ERR; 7617b5038d7SDag-Erling Smørgrav */ 7627b5038d7SDag-Erling Smørgrav } 7637b5038d7SDag-Erling Smørgrav } 7647b5038d7SDag-Erling Smørgrav break; 7657b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_DEFDOMAIN: 7667b5038d7SDag-Erling Smørgrav /* default domain dname */ 767*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 7687b5038d7SDag-Erling Smørgrav if (gtr == 0) { 769*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 7707b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 7717b5038d7SDag-Erling Smørgrav } 7727b5038d7SDag-Erling Smørgrav if(word[0] == '#') { 7737b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 7747b5038d7SDag-Erling Smørgrav continue; 7757b5038d7SDag-Erling Smørgrav } 7767b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 7777b5038d7SDag-Erling Smørgrav if (!tmp) { 7787b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 779*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 7807b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_DNAME_ERR; 7817b5038d7SDag-Erling Smørgrav } 7827b5038d7SDag-Erling Smørgrav 7837b5038d7SDag-Erling Smørgrav /* DOn't free, because we copy the pointer */ 7847b5038d7SDag-Erling Smørgrav ldns_resolver_set_domain(r, tmp); 7857b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 7867b5038d7SDag-Erling Smørgrav break; 7877b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_NAMESERVER: 7887b5038d7SDag-Erling Smørgrav /* NS aaaa or a record */ 789*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 7907b5038d7SDag-Erling Smørgrav if (gtr == 0) { 791*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 7927b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 7937b5038d7SDag-Erling Smørgrav } 7947b5038d7SDag-Erling Smørgrav if(word[0] == '#') { 7957b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 7967b5038d7SDag-Erling Smørgrav continue; 7977b5038d7SDag-Erling Smørgrav } 7987b5038d7SDag-Erling Smørgrav if(strchr(word, '%')) { 7997b5038d7SDag-Erling Smørgrav /* snip off interface labels, 8007b5038d7SDag-Erling Smørgrav * fe80::222:19ff:fe31:4222%eth0 */ 8017b5038d7SDag-Erling Smørgrav strchr(word, '%')[0]=0; 8027b5038d7SDag-Erling Smørgrav } 8037b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); 8047b5038d7SDag-Erling Smørgrav if (!tmp) { 8057b5038d7SDag-Erling Smørgrav /* try ip4 */ 8067b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); 8077b5038d7SDag-Erling Smørgrav } 8087b5038d7SDag-Erling Smørgrav /* could not parse it, exit */ 8097b5038d7SDag-Erling Smørgrav if (!tmp) { 8107b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 811*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 8127b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_ERR; 8137b5038d7SDag-Erling Smørgrav } 8147b5038d7SDag-Erling Smørgrav (void)ldns_resolver_push_nameserver(r, tmp); 8157b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp); 8167b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8177b5038d7SDag-Erling Smørgrav break; 8187b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_SEARCH: 8197b5038d7SDag-Erling Smørgrav /* search list domain dname */ 820*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 8217b5038d7SDag-Erling Smørgrav b = LDNS_MALLOC(ldns_buffer); 8227b5038d7SDag-Erling Smørgrav if(!b) { 8237b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 824*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 8257b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 8267b5038d7SDag-Erling Smørgrav } 8277b5038d7SDag-Erling Smørgrav 8287b5038d7SDag-Erling Smørgrav ldns_buffer_new_frm_data(b, word, (size_t) gtr); 8297b5038d7SDag-Erling Smørgrav if(ldns_buffer_status(b) != LDNS_STATUS_OK) { 8307b5038d7SDag-Erling Smørgrav LDNS_FREE(b); 8317b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 832*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 8337b5038d7SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 8347b5038d7SDag-Erling Smørgrav } 8357b5038d7SDag-Erling Smørgrav bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); 8367b5038d7SDag-Erling Smørgrav while (bgtr > 0) { 8377b5038d7SDag-Erling Smørgrav gtr -= bgtr; 8387b5038d7SDag-Erling Smørgrav if(word[0] == '#') { 8397b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8402787e39aSDag-Erling Smørgrav break; 8417b5038d7SDag-Erling Smørgrav } 8427b5038d7SDag-Erling Smørgrav tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 8437b5038d7SDag-Erling Smørgrav if (!tmp) { 8447b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 8457b5038d7SDag-Erling Smørgrav ldns_buffer_free(b); 846*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 8477b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_DNAME_ERR; 8487b5038d7SDag-Erling Smørgrav } 8497b5038d7SDag-Erling Smørgrav 8507b5038d7SDag-Erling Smørgrav ldns_resolver_push_searchlist(r, tmp); 8517b5038d7SDag-Erling Smørgrav 8527b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(tmp); 8537b5038d7SDag-Erling Smørgrav bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, 8547b5038d7SDag-Erling Smørgrav (size_t) gtr + 1); 8557b5038d7SDag-Erling Smørgrav } 8567b5038d7SDag-Erling Smørgrav ldns_buffer_free(b); 8572787e39aSDag-Erling Smørgrav if (expect != LDNS_RESOLV_KEYWORD) { 8587b5038d7SDag-Erling Smørgrav gtr = 1; 8597b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8602787e39aSDag-Erling Smørgrav } 8617b5038d7SDag-Erling Smørgrav break; 8627b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_SORTLIST: 863*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 8647b5038d7SDag-Erling Smørgrav /* sortlist not implemented atm */ 8657b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8667b5038d7SDag-Erling Smørgrav break; 8677b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_OPTIONS: 868*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 8697b5038d7SDag-Erling Smørgrav /* options not implemented atm */ 8707b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8717b5038d7SDag-Erling Smørgrav break; 8727b5038d7SDag-Erling Smørgrav case LDNS_RESOLV_ANCHOR: 8737b5038d7SDag-Erling Smørgrav /* a file containing a DNSSEC trust anchor */ 874*17d15b25SDag-Erling Smørgrav gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 8757b5038d7SDag-Erling Smørgrav if (gtr == 0) { 8767b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 877*17d15b25SDag-Erling Smørgrav if(!fp) fclose(myfp); 8787b5038d7SDag-Erling Smørgrav return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 8797b5038d7SDag-Erling Smørgrav } 8807b5038d7SDag-Erling Smørgrav if(word[0] == '#') { 8817b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8827b5038d7SDag-Erling Smørgrav continue; 8837b5038d7SDag-Erling Smørgrav } 8847b5038d7SDag-Erling Smørgrav 8857b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 8867b5038d7SDag-Erling Smørgrav tmp_rr = ldns_read_anchor_file(word); 8877b5038d7SDag-Erling Smørgrav (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); 8887b5038d7SDag-Erling Smørgrav ldns_rr_free(tmp_rr); 8897b5038d7SDag-Erling Smørgrav #endif 8907b5038d7SDag-Erling Smørgrav expect = LDNS_RESOLV_KEYWORD; 8917b5038d7SDag-Erling Smørgrav break; 8927b5038d7SDag-Erling Smørgrav } 8937b5038d7SDag-Erling Smørgrav } 8947b5038d7SDag-Erling Smørgrav 895*17d15b25SDag-Erling Smørgrav if(!fp) 896*17d15b25SDag-Erling Smørgrav fclose(myfp); 897*17d15b25SDag-Erling Smørgrav 8987b5038d7SDag-Erling Smørgrav if (res) { 8997b5038d7SDag-Erling Smørgrav *res = r; 9007b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 9017b5038d7SDag-Erling Smørgrav } else { 9027b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(r); 9037b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL; 9047b5038d7SDag-Erling Smørgrav } 9057b5038d7SDag-Erling Smørgrav } 9067b5038d7SDag-Erling Smørgrav 9077b5038d7SDag-Erling Smørgrav ldns_status 9087b5038d7SDag-Erling Smørgrav ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename) 9097b5038d7SDag-Erling Smørgrav { 9107b5038d7SDag-Erling Smørgrav ldns_resolver *r; 9117b5038d7SDag-Erling Smørgrav FILE *fp; 9127b5038d7SDag-Erling Smørgrav ldns_status s; 9137b5038d7SDag-Erling Smørgrav 9147b5038d7SDag-Erling Smørgrav if (!filename) { 9157b5038d7SDag-Erling Smørgrav fp = fopen(LDNS_RESOLV_CONF, "r"); 9167b5038d7SDag-Erling Smørgrav 9177b5038d7SDag-Erling Smørgrav } else { 9187b5038d7SDag-Erling Smørgrav fp = fopen(filename, "r"); 9197b5038d7SDag-Erling Smørgrav } 9207b5038d7SDag-Erling Smørgrav if (!fp) { 9217b5038d7SDag-Erling Smørgrav return LDNS_STATUS_FILE_ERR; 9227b5038d7SDag-Erling Smørgrav } 9237b5038d7SDag-Erling Smørgrav 9247b5038d7SDag-Erling Smørgrav s = ldns_resolver_new_frm_fp(&r, fp); 9257b5038d7SDag-Erling Smørgrav fclose(fp); 9267b5038d7SDag-Erling Smørgrav if (s == LDNS_STATUS_OK) { 9277b5038d7SDag-Erling Smørgrav if (res) { 9287b5038d7SDag-Erling Smørgrav *res = r; 9297b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 9307b5038d7SDag-Erling Smørgrav } else { 9312787e39aSDag-Erling Smørgrav ldns_resolver_free(r); 9327b5038d7SDag-Erling Smørgrav return LDNS_STATUS_NULL; 9337b5038d7SDag-Erling Smørgrav } 9347b5038d7SDag-Erling Smørgrav } 9357b5038d7SDag-Erling Smørgrav return s; 9367b5038d7SDag-Erling Smørgrav } 9377b5038d7SDag-Erling Smørgrav 9387b5038d7SDag-Erling Smørgrav void 9397b5038d7SDag-Erling Smørgrav ldns_resolver_free(ldns_resolver *res) 9407b5038d7SDag-Erling Smørgrav { 9417b5038d7SDag-Erling Smørgrav LDNS_FREE(res); 9427b5038d7SDag-Erling Smørgrav } 9437b5038d7SDag-Erling Smørgrav 9447b5038d7SDag-Erling Smørgrav void 9457b5038d7SDag-Erling Smørgrav ldns_resolver_deep_free(ldns_resolver *res) 9467b5038d7SDag-Erling Smørgrav { 9477b5038d7SDag-Erling Smørgrav size_t i; 9487b5038d7SDag-Erling Smørgrav 9497b5038d7SDag-Erling Smørgrav if (res) { 9507b5038d7SDag-Erling Smørgrav if (res->_searchlist) { 9517b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_resolver_searchlist_count(res); i++) { 9527b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(res->_searchlist[i]); 9537b5038d7SDag-Erling Smørgrav } 9547b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_searchlist); 9557b5038d7SDag-Erling Smørgrav } 9567b5038d7SDag-Erling Smørgrav if (res->_nameservers) { 9577b5038d7SDag-Erling Smørgrav for (i = 0; i < res->_nameserver_count; i++) { 9587b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(res->_nameservers[i]); 9597b5038d7SDag-Erling Smørgrav } 9607b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_nameservers); 9617b5038d7SDag-Erling Smørgrav } 9627b5038d7SDag-Erling Smørgrav if (ldns_resolver_domain(res)) { 9637b5038d7SDag-Erling Smørgrav ldns_rdf_deep_free(ldns_resolver_domain(res)); 9647b5038d7SDag-Erling Smørgrav } 9657b5038d7SDag-Erling Smørgrav if (res->_tsig_keyname) { 9667b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_tsig_keyname); 9677b5038d7SDag-Erling Smørgrav } 9687b5038d7SDag-Erling Smørgrav if (res->_tsig_keydata) { 9697b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_tsig_keydata); 9707b5038d7SDag-Erling Smørgrav } 9717b5038d7SDag-Erling Smørgrav if (res->_tsig_algorithm) { 9727b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_tsig_algorithm); 9737b5038d7SDag-Erling Smørgrav } 9747b5038d7SDag-Erling Smørgrav 9757b5038d7SDag-Erling Smørgrav if (res->_cur_axfr_pkt) { 9767b5038d7SDag-Erling Smørgrav ldns_pkt_free(res->_cur_axfr_pkt); 9777b5038d7SDag-Erling Smørgrav } 9787b5038d7SDag-Erling Smørgrav 9797b5038d7SDag-Erling Smørgrav if (res->_rtt) { 9807b5038d7SDag-Erling Smørgrav LDNS_FREE(res->_rtt); 9817b5038d7SDag-Erling Smørgrav } 9827b5038d7SDag-Erling Smørgrav if (res->_dnssec_anchors) { 9837b5038d7SDag-Erling Smørgrav ldns_rr_list_deep_free(res->_dnssec_anchors); 9847b5038d7SDag-Erling Smørgrav } 9857b5038d7SDag-Erling Smørgrav LDNS_FREE(res); 9867b5038d7SDag-Erling Smørgrav } 9877b5038d7SDag-Erling Smørgrav } 9887b5038d7SDag-Erling Smørgrav 989*17d15b25SDag-Erling Smørgrav ldns_status 990*17d15b25SDag-Erling Smørgrav ldns_resolver_search_status(ldns_pkt** pkt, 991*17d15b25SDag-Erling Smørgrav ldns_resolver *r, const ldns_rdf *name, 9927b5038d7SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags) 9937b5038d7SDag-Erling Smørgrav { 9947b5038d7SDag-Erling Smørgrav ldns_rdf *new_name; 9957b5038d7SDag-Erling Smørgrav ldns_rdf **search_list; 9967b5038d7SDag-Erling Smørgrav size_t i; 997*17d15b25SDag-Erling Smørgrav ldns_status s = LDNS_STATUS_OK; 9987b5038d7SDag-Erling Smørgrav 9992787e39aSDag-Erling Smørgrav if (ldns_dname_absolute(name)) { 10007b5038d7SDag-Erling Smørgrav /* query as-is */ 1001*17d15b25SDag-Erling Smørgrav return ldns_resolver_query_status(pkt, r, name, t, c, flags); 10027b5038d7SDag-Erling Smørgrav } else if (ldns_resolver_dnsrch(r)) { 10037b5038d7SDag-Erling Smørgrav search_list = ldns_resolver_searchlist(r); 10047b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_resolver_searchlist_count(r); i++) { 10057b5038d7SDag-Erling Smørgrav new_name = ldns_dname_cat_clone(name, search_list[i]); 10067b5038d7SDag-Erling Smørgrav 1007*17d15b25SDag-Erling Smørgrav s = ldns_resolver_query_status(pkt, r, 1008*17d15b25SDag-Erling Smørgrav new_name, t, c, flags); 10097b5038d7SDag-Erling Smørgrav ldns_rdf_free(new_name); 1010*17d15b25SDag-Erling Smørgrav if (pkt) { 1011*17d15b25SDag-Erling Smørgrav if (s == LDNS_STATUS_OK && *pkt && 1012*17d15b25SDag-Erling Smørgrav ldns_pkt_get_rcode(*pkt) == 1013*17d15b25SDag-Erling Smørgrav LDNS_RCODE_NOERROR) { 1014*17d15b25SDag-Erling Smørgrav return LDNS_STATUS_OK; 1015*17d15b25SDag-Erling Smørgrav } 1016*17d15b25SDag-Erling Smørgrav ldns_pkt_free(*pkt); 10177b5038d7SDag-Erling Smørgrav } 10187b5038d7SDag-Erling Smørgrav } 10197b5038d7SDag-Erling Smørgrav } 1020*17d15b25SDag-Erling Smørgrav return s; 10217b5038d7SDag-Erling Smørgrav } 1022*17d15b25SDag-Erling Smørgrav 1023*17d15b25SDag-Erling Smørgrav ldns_pkt * 1024*17d15b25SDag-Erling Smørgrav ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name, 1025*17d15b25SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1026*17d15b25SDag-Erling Smørgrav { 1027*17d15b25SDag-Erling Smørgrav ldns_pkt* pkt = NULL; 1028*17d15b25SDag-Erling Smørgrav if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r, 1029*17d15b25SDag-Erling Smørgrav name, t, c, flags) != LDNS_STATUS_OK) { 1030*17d15b25SDag-Erling Smørgrav ldns_pkt_free(pkt); 1031*17d15b25SDag-Erling Smørgrav } 1032*17d15b25SDag-Erling Smørgrav return pkt; 1033*17d15b25SDag-Erling Smørgrav } 1034*17d15b25SDag-Erling Smørgrav 1035*17d15b25SDag-Erling Smørgrav ldns_status 1036*17d15b25SDag-Erling Smørgrav ldns_resolver_query_status(ldns_pkt** pkt, 1037*17d15b25SDag-Erling Smørgrav ldns_resolver *r, const ldns_rdf *name, 1038*17d15b25SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1039*17d15b25SDag-Erling Smørgrav { 1040*17d15b25SDag-Erling Smørgrav ldns_rdf *newname; 1041*17d15b25SDag-Erling Smørgrav ldns_status status; 1042*17d15b25SDag-Erling Smørgrav 1043*17d15b25SDag-Erling Smørgrav if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) { 1044*17d15b25SDag-Erling Smørgrav return ldns_resolver_send(pkt, r, name, t, c, flags); 1045*17d15b25SDag-Erling Smørgrav } 1046*17d15b25SDag-Erling Smørgrav 1047*17d15b25SDag-Erling Smørgrav newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r)); 1048*17d15b25SDag-Erling Smørgrav if (!newname) { 1049*17d15b25SDag-Erling Smørgrav return LDNS_STATUS_MEM_ERR; 1050*17d15b25SDag-Erling Smørgrav } 1051*17d15b25SDag-Erling Smørgrav status = ldns_resolver_send(pkt, r, newname, t, c, flags); 1052*17d15b25SDag-Erling Smørgrav ldns_rdf_free(newname); 1053*17d15b25SDag-Erling Smørgrav return status; 10547b5038d7SDag-Erling Smørgrav } 10557b5038d7SDag-Erling Smørgrav 10567b5038d7SDag-Erling Smørgrav ldns_pkt * 10577b5038d7SDag-Erling Smørgrav ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, 10587b5038d7SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags) 10597b5038d7SDag-Erling Smørgrav { 1060*17d15b25SDag-Erling Smørgrav ldns_pkt* pkt = NULL; 1061*17d15b25SDag-Erling Smørgrav if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r, 1062*17d15b25SDag-Erling Smørgrav name, t, c, flags) != LDNS_STATUS_OK) { 10637b5038d7SDag-Erling Smørgrav ldns_pkt_free(pkt); 10647b5038d7SDag-Erling Smørgrav } 10657b5038d7SDag-Erling Smørgrav return pkt; 10667b5038d7SDag-Erling Smørgrav } 10677b5038d7SDag-Erling Smørgrav 10687b5038d7SDag-Erling Smørgrav static size_t * 10697b5038d7SDag-Erling Smørgrav ldns_resolver_backup_rtt(ldns_resolver *r) 10707b5038d7SDag-Erling Smørgrav { 10717b5038d7SDag-Erling Smørgrav size_t *new_rtt; 10727b5038d7SDag-Erling Smørgrav size_t *old_rtt = ldns_resolver_rtt(r); 10737b5038d7SDag-Erling Smørgrav 10747b5038d7SDag-Erling Smørgrav if (old_rtt && ldns_resolver_nameserver_count(r)) { 10757b5038d7SDag-Erling Smørgrav new_rtt = LDNS_XMALLOC(size_t 10767b5038d7SDag-Erling Smørgrav , ldns_resolver_nameserver_count(r)); 10777b5038d7SDag-Erling Smørgrav memcpy(new_rtt, old_rtt, sizeof(size_t) 10787b5038d7SDag-Erling Smørgrav * ldns_resolver_nameserver_count(r)); 10797b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(r, new_rtt); 10807b5038d7SDag-Erling Smørgrav return old_rtt; 10817b5038d7SDag-Erling Smørgrav } 10827b5038d7SDag-Erling Smørgrav return NULL; 10837b5038d7SDag-Erling Smørgrav } 10847b5038d7SDag-Erling Smørgrav 10857b5038d7SDag-Erling Smørgrav static void 10867b5038d7SDag-Erling Smørgrav ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt) 10877b5038d7SDag-Erling Smørgrav { 10887b5038d7SDag-Erling Smørgrav size_t *cur_rtt = ldns_resolver_rtt(r); 10897b5038d7SDag-Erling Smørgrav 10907b5038d7SDag-Erling Smørgrav if (cur_rtt) { 10917b5038d7SDag-Erling Smørgrav LDNS_FREE(cur_rtt); 10927b5038d7SDag-Erling Smørgrav } 10937b5038d7SDag-Erling Smørgrav ldns_resolver_set_rtt(r, old_rtt); 10947b5038d7SDag-Erling Smørgrav } 10957b5038d7SDag-Erling Smørgrav 10967b5038d7SDag-Erling Smørgrav ldns_status 10977b5038d7SDag-Erling Smørgrav ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, 10987b5038d7SDag-Erling Smørgrav ldns_pkt *query_pkt) 10997b5038d7SDag-Erling Smørgrav { 11007b5038d7SDag-Erling Smørgrav ldns_pkt *answer_pkt = NULL; 11017b5038d7SDag-Erling Smørgrav ldns_status stat = LDNS_STATUS_OK; 11027b5038d7SDag-Erling Smørgrav size_t *rtt; 11037b5038d7SDag-Erling Smørgrav 11047b5038d7SDag-Erling Smørgrav stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt); 11057b5038d7SDag-Erling Smørgrav if (stat != LDNS_STATUS_OK) { 11067b5038d7SDag-Erling Smørgrav if(answer_pkt) { 11077b5038d7SDag-Erling Smørgrav ldns_pkt_free(answer_pkt); 11087b5038d7SDag-Erling Smørgrav answer_pkt = NULL; 11097b5038d7SDag-Erling Smørgrav } 11107b5038d7SDag-Erling Smørgrav } else { 11117b5038d7SDag-Erling Smørgrav /* if tc=1 fall back to EDNS and/or TCP */ 11127b5038d7SDag-Erling Smørgrav /* check for tcp first (otherwise we don't care about tc=1) */ 11137b5038d7SDag-Erling Smørgrav if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) { 11147b5038d7SDag-Erling Smørgrav if (ldns_pkt_tc(answer_pkt)) { 11157b5038d7SDag-Erling Smørgrav /* was EDNS0 set? */ 11167b5038d7SDag-Erling Smørgrav if (ldns_pkt_edns_udp_size(query_pkt) == 0) { 11177b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(query_pkt 11187b5038d7SDag-Erling Smørgrav , 4096); 11197b5038d7SDag-Erling Smørgrav ldns_pkt_free(answer_pkt); 11207b5038d7SDag-Erling Smørgrav /* Nameservers should not become 11217b5038d7SDag-Erling Smørgrav * unreachable because fragments are 11227b5038d7SDag-Erling Smørgrav * dropped (network error). We might 11237b5038d7SDag-Erling Smørgrav * still have success with TCP. 11247b5038d7SDag-Erling Smørgrav * Therefore maintain reachability 11257b5038d7SDag-Erling Smørgrav * statuses of the nameservers by 11267b5038d7SDag-Erling Smørgrav * backup and restore the rtt list. 11277b5038d7SDag-Erling Smørgrav */ 11287b5038d7SDag-Erling Smørgrav rtt = ldns_resolver_backup_rtt(r); 11297b5038d7SDag-Erling Smørgrav stat = ldns_send(&answer_pkt, r 11307b5038d7SDag-Erling Smørgrav , query_pkt); 11317b5038d7SDag-Erling Smørgrav ldns_resolver_restore_rtt(r, rtt); 11327b5038d7SDag-Erling Smørgrav } 11337b5038d7SDag-Erling Smørgrav /* either way, if it is still truncated, use TCP */ 11347b5038d7SDag-Erling Smørgrav if (stat != LDNS_STATUS_OK || 11357b5038d7SDag-Erling Smørgrav ldns_pkt_tc(answer_pkt)) { 11367b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(r, true); 11377b5038d7SDag-Erling Smørgrav ldns_pkt_free(answer_pkt); 11387b5038d7SDag-Erling Smørgrav stat = ldns_send(&answer_pkt, r, query_pkt); 11397b5038d7SDag-Erling Smørgrav ldns_resolver_set_usevc(r, false); 11407b5038d7SDag-Erling Smørgrav } 11417b5038d7SDag-Erling Smørgrav } 11427b5038d7SDag-Erling Smørgrav } 11437b5038d7SDag-Erling Smørgrav } 11447b5038d7SDag-Erling Smørgrav 11457b5038d7SDag-Erling Smørgrav if (answer) { 11467b5038d7SDag-Erling Smørgrav *answer = answer_pkt; 11477b5038d7SDag-Erling Smørgrav } 11487b5038d7SDag-Erling Smørgrav 11497b5038d7SDag-Erling Smørgrav return stat; 11507b5038d7SDag-Erling Smørgrav } 11517b5038d7SDag-Erling Smørgrav 11527b5038d7SDag-Erling Smørgrav ldns_status 11537b5038d7SDag-Erling Smørgrav ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, 11547b5038d7SDag-Erling Smørgrav const ldns_rdf *name, ldns_rr_type t, 11557b5038d7SDag-Erling Smørgrav ldns_rr_class c, uint16_t flags) 11567b5038d7SDag-Erling Smørgrav { 11577b5038d7SDag-Erling Smørgrav struct timeval now; 11587b5038d7SDag-Erling Smørgrav 11597b5038d7SDag-Erling Smørgrav /* prepare a question pkt from the parameters 11607b5038d7SDag-Erling Smørgrav * and then send this */ 1161*17d15b25SDag-Erling Smørgrav if (t == LDNS_RR_TYPE_IXFR) { 1162*17d15b25SDag-Erling Smørgrav *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name), 1163*17d15b25SDag-Erling Smørgrav c, flags, NULL); 1164*17d15b25SDag-Erling Smørgrav } else { 11657b5038d7SDag-Erling Smørgrav *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags); 1166*17d15b25SDag-Erling Smørgrav } 11677b5038d7SDag-Erling Smørgrav if (!*query_pkt) { 11687b5038d7SDag-Erling Smørgrav return LDNS_STATUS_ERR; 11697b5038d7SDag-Erling Smørgrav } 11707b5038d7SDag-Erling Smørgrav 11717b5038d7SDag-Erling Smørgrav /* set DO bit if necessary */ 11727b5038d7SDag-Erling Smørgrav if (ldns_resolver_dnssec(r)) { 11737b5038d7SDag-Erling Smørgrav if (ldns_resolver_edns_udp_size(r) == 0) { 11747b5038d7SDag-Erling Smørgrav ldns_resolver_set_edns_udp_size(r, 4096); 11757b5038d7SDag-Erling Smørgrav } 11767b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_do(*query_pkt, true); 11777b5038d7SDag-Erling Smørgrav if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) { 11787b5038d7SDag-Erling Smørgrav ldns_pkt_set_cd(*query_pkt, true); 11797b5038d7SDag-Erling Smørgrav } 11807b5038d7SDag-Erling Smørgrav } 11817b5038d7SDag-Erling Smørgrav 11827b5038d7SDag-Erling Smørgrav /* transfer the udp_edns_size from the resolver to the packet */ 11837b5038d7SDag-Erling Smørgrav if (ldns_resolver_edns_udp_size(r) != 0) { 11847b5038d7SDag-Erling Smørgrav ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r)); 11857b5038d7SDag-Erling Smørgrav } 11867b5038d7SDag-Erling Smørgrav 11877b5038d7SDag-Erling Smørgrav /* set the timestamp */ 11887b5038d7SDag-Erling Smørgrav now.tv_sec = time(NULL); 11897b5038d7SDag-Erling Smørgrav now.tv_usec = 0; 11907b5038d7SDag-Erling Smørgrav ldns_pkt_set_timestamp(*query_pkt, now); 11917b5038d7SDag-Erling Smørgrav 11927b5038d7SDag-Erling Smørgrav 11937b5038d7SDag-Erling Smørgrav if (ldns_resolver_debug(r)) { 11947b5038d7SDag-Erling Smørgrav ldns_pkt_print(stdout, *query_pkt); 11957b5038d7SDag-Erling Smørgrav } 11967b5038d7SDag-Erling Smørgrav 11977b5038d7SDag-Erling Smørgrav /* only set the id if it is not set yet */ 11987b5038d7SDag-Erling Smørgrav if (ldns_pkt_id(*query_pkt) == 0) { 11997b5038d7SDag-Erling Smørgrav ldns_pkt_set_random_id(*query_pkt); 12007b5038d7SDag-Erling Smørgrav } 12017b5038d7SDag-Erling Smørgrav 12027b5038d7SDag-Erling Smørgrav return LDNS_STATUS_OK; 12037b5038d7SDag-Erling Smørgrav } 12047b5038d7SDag-Erling Smørgrav 12057b5038d7SDag-Erling Smørgrav 12067b5038d7SDag-Erling Smørgrav ldns_status 12077b5038d7SDag-Erling Smørgrav ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, 12087b5038d7SDag-Erling Smørgrav ldns_rr_type t, ldns_rr_class c, uint16_t flags) 12097b5038d7SDag-Erling Smørgrav { 12107b5038d7SDag-Erling Smørgrav ldns_pkt *query_pkt; 12117b5038d7SDag-Erling Smørgrav ldns_pkt *answer_pkt; 12127b5038d7SDag-Erling Smørgrav ldns_status status; 12137b5038d7SDag-Erling Smørgrav 12147b5038d7SDag-Erling Smørgrav assert(r != NULL); 12157b5038d7SDag-Erling Smørgrav assert(name != NULL); 12167b5038d7SDag-Erling Smørgrav 12177b5038d7SDag-Erling Smørgrav answer_pkt = NULL; 12187b5038d7SDag-Erling Smørgrav 12197b5038d7SDag-Erling Smørgrav /* do all the preprocessing here, then fire of an query to 12207b5038d7SDag-Erling Smørgrav * the network */ 12217b5038d7SDag-Erling Smørgrav 12227b5038d7SDag-Erling Smørgrav if (0 == t) { 12237b5038d7SDag-Erling Smørgrav t= LDNS_RR_TYPE_A; 12247b5038d7SDag-Erling Smørgrav } 12257b5038d7SDag-Erling Smørgrav if (0 == c) { 12267b5038d7SDag-Erling Smørgrav c= LDNS_RR_CLASS_IN; 12277b5038d7SDag-Erling Smørgrav } 12287b5038d7SDag-Erling Smørgrav if (0 == ldns_resolver_nameserver_count(r)) { 12297b5038d7SDag-Erling Smørgrav return LDNS_STATUS_RES_NO_NS; 12307b5038d7SDag-Erling Smørgrav } 12317b5038d7SDag-Erling Smørgrav if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) { 12327b5038d7SDag-Erling Smørgrav return LDNS_STATUS_RES_QUERY; 12337b5038d7SDag-Erling Smørgrav } 12347b5038d7SDag-Erling Smørgrav 12357b5038d7SDag-Erling Smørgrav status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name, 12367b5038d7SDag-Erling Smørgrav t, c, flags); 12377b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) { 12387b5038d7SDag-Erling Smørgrav return status; 12397b5038d7SDag-Erling Smørgrav } 12407b5038d7SDag-Erling Smørgrav 12417b5038d7SDag-Erling Smørgrav /* if tsig values are set, tsign it */ 12427b5038d7SDag-Erling Smørgrav /* TODO: make last 3 arguments optional too? maybe make complete 1243*17d15b25SDag-Erling Smørgrav rr instead of separate values in resolver (and packet) 12447b5038d7SDag-Erling Smørgrav Jelte 12457b5038d7SDag-Erling Smørgrav should this go in pkt_prepare? 12467b5038d7SDag-Erling Smørgrav */ 12477b5038d7SDag-Erling Smørgrav if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) { 12487b5038d7SDag-Erling Smørgrav #ifdef HAVE_SSL 12497b5038d7SDag-Erling Smørgrav status = ldns_pkt_tsig_sign(query_pkt, 12507b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_keyname(r), 12517b5038d7SDag-Erling Smørgrav ldns_resolver_tsig_keydata(r), 12527b5038d7SDag-Erling Smørgrav 300, ldns_resolver_tsig_algorithm(r), NULL); 12537b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) { 12542787e39aSDag-Erling Smørgrav ldns_pkt_free(query_pkt); 12557b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_TSIG_ERR; 12567b5038d7SDag-Erling Smørgrav } 12577b5038d7SDag-Erling Smørgrav #else 12582787e39aSDag-Erling Smørgrav ldns_pkt_free(query_pkt); 12597b5038d7SDag-Erling Smørgrav return LDNS_STATUS_CRYPTO_TSIG_ERR; 12607b5038d7SDag-Erling Smørgrav #endif /* HAVE_SSL */ 12617b5038d7SDag-Erling Smørgrav } 12627b5038d7SDag-Erling Smørgrav 12637b5038d7SDag-Erling Smørgrav status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt); 12647b5038d7SDag-Erling Smørgrav ldns_pkt_free(query_pkt); 12657b5038d7SDag-Erling Smørgrav 12667b5038d7SDag-Erling Smørgrav /* allows answer to be NULL when not interested in return value */ 12677b5038d7SDag-Erling Smørgrav if (answer) { 12687b5038d7SDag-Erling Smørgrav *answer = answer_pkt; 12697b5038d7SDag-Erling Smørgrav } 12707b5038d7SDag-Erling Smørgrav return status; 12717b5038d7SDag-Erling Smørgrav } 12727b5038d7SDag-Erling Smørgrav 12737b5038d7SDag-Erling Smørgrav ldns_rr * 12747b5038d7SDag-Erling Smørgrav ldns_axfr_next(ldns_resolver *resolver) 12757b5038d7SDag-Erling Smørgrav { 12767b5038d7SDag-Erling Smørgrav ldns_rr *cur_rr; 12777b5038d7SDag-Erling Smørgrav uint8_t *packet_wire; 12787b5038d7SDag-Erling Smørgrav size_t packet_wire_size; 12797b5038d7SDag-Erling Smørgrav ldns_lookup_table *rcode; 12807b5038d7SDag-Erling Smørgrav ldns_status status; 12817b5038d7SDag-Erling Smørgrav 12827b5038d7SDag-Erling Smørgrav /* check if start() has been called */ 12837b5038d7SDag-Erling Smørgrav if (!resolver || resolver->_socket == 0) { 12847b5038d7SDag-Erling Smørgrav return NULL; 12857b5038d7SDag-Erling Smørgrav } 12867b5038d7SDag-Erling Smørgrav 12877b5038d7SDag-Erling Smørgrav if (resolver->_cur_axfr_pkt) { 12887b5038d7SDag-Erling Smørgrav if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) { 12897b5038d7SDag-Erling Smørgrav ldns_pkt_free(resolver->_cur_axfr_pkt); 12907b5038d7SDag-Erling Smørgrav resolver->_cur_axfr_pkt = NULL; 12917b5038d7SDag-Erling Smørgrav return ldns_axfr_next(resolver); 12927b5038d7SDag-Erling Smørgrav } 12937b5038d7SDag-Erling Smørgrav cur_rr = ldns_rr_clone(ldns_rr_list_rr( 12947b5038d7SDag-Erling Smørgrav ldns_pkt_answer(resolver->_cur_axfr_pkt), 12957b5038d7SDag-Erling Smørgrav resolver->_axfr_i)); 12967b5038d7SDag-Erling Smørgrav resolver->_axfr_i++; 12977b5038d7SDag-Erling Smørgrav if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { 12987b5038d7SDag-Erling Smørgrav resolver->_axfr_soa_count++; 12997b5038d7SDag-Erling Smørgrav if (resolver->_axfr_soa_count >= 2) { 13007b5038d7SDag-Erling Smørgrav #ifndef USE_WINSOCK 13017b5038d7SDag-Erling Smørgrav close(resolver->_socket); 13027b5038d7SDag-Erling Smørgrav #else 13037b5038d7SDag-Erling Smørgrav closesocket(resolver->_socket); 13047b5038d7SDag-Erling Smørgrav #endif 13057b5038d7SDag-Erling Smørgrav resolver->_socket = 0; 13067b5038d7SDag-Erling Smørgrav ldns_pkt_free(resolver->_cur_axfr_pkt); 13077b5038d7SDag-Erling Smørgrav resolver->_cur_axfr_pkt = NULL; 13087b5038d7SDag-Erling Smørgrav } 13097b5038d7SDag-Erling Smørgrav } 13107b5038d7SDag-Erling Smørgrav return cur_rr; 13117b5038d7SDag-Erling Smørgrav } else { 13127b5038d7SDag-Erling Smørgrav packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); 13137b5038d7SDag-Erling Smørgrav if(!packet_wire) 13147b5038d7SDag-Erling Smørgrav return NULL; 13157b5038d7SDag-Erling Smørgrav 13167b5038d7SDag-Erling Smørgrav status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, 13177b5038d7SDag-Erling Smørgrav packet_wire_size); 13187b5038d7SDag-Erling Smørgrav LDNS_FREE(packet_wire); 13197b5038d7SDag-Erling Smørgrav 13207b5038d7SDag-Erling Smørgrav resolver->_axfr_i = 0; 13217b5038d7SDag-Erling Smørgrav if (status != LDNS_STATUS_OK) { 13227b5038d7SDag-Erling Smørgrav /* TODO: make status return type of this function (...api change) */ 1323*17d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS 13247b5038d7SDag-Erling Smørgrav fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status)); 1325*17d15b25SDag-Erling Smørgrav #endif 13267b5038d7SDag-Erling Smørgrav 1327*17d15b25SDag-Erling Smørgrav /* we must now also close the socket, otherwise subsequent uses of the 13287b5038d7SDag-Erling Smørgrav same resolver structure will fail because the link is still open or 13297b5038d7SDag-Erling Smørgrav in an undefined state */ 13307b5038d7SDag-Erling Smørgrav #ifndef USE_WINSOCK 13317b5038d7SDag-Erling Smørgrav close(resolver->_socket); 13327b5038d7SDag-Erling Smørgrav #else 13337b5038d7SDag-Erling Smørgrav closesocket(resolver->_socket); 13347b5038d7SDag-Erling Smørgrav #endif 13357b5038d7SDag-Erling Smørgrav resolver->_socket = 0; 13367b5038d7SDag-Erling Smørgrav 13377b5038d7SDag-Erling Smørgrav return NULL; 13387b5038d7SDag-Erling Smørgrav } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { 13397b5038d7SDag-Erling Smørgrav rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt)); 1340*17d15b25SDag-Erling Smørgrav #ifdef STDERR_MSGS 13412787e39aSDag-Erling Smørgrav if (rcode) { 13422787e39aSDag-Erling Smørgrav fprintf(stderr, "Error in AXFR: %s\n", 13432787e39aSDag-Erling Smørgrav rcode->name); 13442787e39aSDag-Erling Smørgrav } else { 13452787e39aSDag-Erling Smørgrav fprintf(stderr, "Error in AXFR: %d\n", 13462787e39aSDag-Erling Smørgrav (int) ldns_pkt_get_rcode( 13472787e39aSDag-Erling Smørgrav resolver->_cur_axfr_pkt)); 13482787e39aSDag-Erling Smørgrav } 1349*17d15b25SDag-Erling Smørgrav #endif 13507b5038d7SDag-Erling Smørgrav 1351*17d15b25SDag-Erling Smørgrav /* we must now also close the socket, otherwise subsequent uses of the 13527b5038d7SDag-Erling Smørgrav same resolver structure will fail because the link is still open or 13537b5038d7SDag-Erling Smørgrav in an undefined state */ 13547b5038d7SDag-Erling Smørgrav #ifndef USE_WINSOCK 13557b5038d7SDag-Erling Smørgrav close(resolver->_socket); 13567b5038d7SDag-Erling Smørgrav #else 13577b5038d7SDag-Erling Smørgrav closesocket(resolver->_socket); 13587b5038d7SDag-Erling Smørgrav #endif 13597b5038d7SDag-Erling Smørgrav resolver->_socket = 0; 13607b5038d7SDag-Erling Smørgrav 13617b5038d7SDag-Erling Smørgrav return NULL; 13627b5038d7SDag-Erling Smørgrav } else { 13637b5038d7SDag-Erling Smørgrav return ldns_axfr_next(resolver); 13647b5038d7SDag-Erling Smørgrav } 13657b5038d7SDag-Erling Smørgrav 13667b5038d7SDag-Erling Smørgrav } 13677b5038d7SDag-Erling Smørgrav 13687b5038d7SDag-Erling Smørgrav } 13697b5038d7SDag-Erling Smørgrav 1370*17d15b25SDag-Erling Smørgrav /* this function is needed to abort a transfer that is in progress; 1371*17d15b25SDag-Erling Smørgrav * without it an aborted transfer will lead to the AXFR code in the 1372*17d15b25SDag-Erling Smørgrav * library staying in an indetermined state because the socket for the 1373*17d15b25SDag-Erling Smørgrav * AXFR is never closed 1374*17d15b25SDag-Erling Smørgrav */ 1375*17d15b25SDag-Erling Smørgrav static void 1376*17d15b25SDag-Erling Smørgrav ldns_axfr_abort(ldns_resolver *resolver) 1377*17d15b25SDag-Erling Smørgrav { 1378*17d15b25SDag-Erling Smørgrav /* Only abort if an actual AXFR is in progress */ 1379*17d15b25SDag-Erling Smørgrav if (resolver->_socket != 0) 1380*17d15b25SDag-Erling Smørgrav { 1381*17d15b25SDag-Erling Smørgrav #ifndef USE_WINSOCK 1382*17d15b25SDag-Erling Smørgrav close(resolver->_socket); 1383*17d15b25SDag-Erling Smørgrav #else 1384*17d15b25SDag-Erling Smørgrav closesocket(resolver->_socket); 1385*17d15b25SDag-Erling Smørgrav #endif 1386*17d15b25SDag-Erling Smørgrav resolver->_socket = 0; 1387*17d15b25SDag-Erling Smørgrav } 1388*17d15b25SDag-Erling Smørgrav } 1389*17d15b25SDag-Erling Smørgrav 13907b5038d7SDag-Erling Smørgrav bool 13917b5038d7SDag-Erling Smørgrav ldns_axfr_complete(const ldns_resolver *res) 13927b5038d7SDag-Erling Smørgrav { 13937b5038d7SDag-Erling Smørgrav /* complete when soa count is 2? */ 13947b5038d7SDag-Erling Smørgrav return res->_axfr_soa_count == 2; 13957b5038d7SDag-Erling Smørgrav } 13967b5038d7SDag-Erling Smørgrav 13977b5038d7SDag-Erling Smørgrav ldns_pkt * 13987b5038d7SDag-Erling Smørgrav ldns_axfr_last_pkt(const ldns_resolver *res) 13997b5038d7SDag-Erling Smørgrav { 14007b5038d7SDag-Erling Smørgrav return res->_cur_axfr_pkt; 14017b5038d7SDag-Erling Smørgrav } 14027b5038d7SDag-Erling Smørgrav 14037b5038d7SDag-Erling Smørgrav /* random isn't really that good */ 14047b5038d7SDag-Erling Smørgrav void 14057b5038d7SDag-Erling Smørgrav ldns_resolver_nameservers_randomize(ldns_resolver *r) 14067b5038d7SDag-Erling Smørgrav { 14077b5038d7SDag-Erling Smørgrav uint16_t i, j; 14082787e39aSDag-Erling Smørgrav ldns_rdf **ns, *tmpns; 14092787e39aSDag-Erling Smørgrav size_t *rtt, tmprtt; 14107b5038d7SDag-Erling Smørgrav 14117b5038d7SDag-Erling Smørgrav /* should I check for ldns_resolver_random?? */ 14127b5038d7SDag-Erling Smørgrav assert(r != NULL); 14137b5038d7SDag-Erling Smørgrav 14147b5038d7SDag-Erling Smørgrav ns = ldns_resolver_nameservers(r); 14152787e39aSDag-Erling Smørgrav rtt = ldns_resolver_rtt(r); 14167b5038d7SDag-Erling Smørgrav for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { 14177b5038d7SDag-Erling Smørgrav j = ldns_get_random() % ldns_resolver_nameserver_count(r); 14182787e39aSDag-Erling Smørgrav tmpns = ns[i]; 14197b5038d7SDag-Erling Smørgrav ns[i] = ns[j]; 14202787e39aSDag-Erling Smørgrav ns[j] = tmpns; 14212787e39aSDag-Erling Smørgrav tmprtt = rtt[i]; 14222787e39aSDag-Erling Smørgrav rtt[i] = rtt[j]; 14232787e39aSDag-Erling Smørgrav rtt[j] = tmprtt; 14247b5038d7SDag-Erling Smørgrav } 14257b5038d7SDag-Erling Smørgrav ldns_resolver_set_nameservers(r, ns); 14267b5038d7SDag-Erling Smørgrav } 14277b5038d7SDag-Erling Smørgrav 1428