1825eb42bSJan Lentfer /*
2825eb42bSJan Lentfer * resolver.c
3825eb42bSJan Lentfer *
4825eb42bSJan Lentfer * resolver implementation
5825eb42bSJan Lentfer *
6825eb42bSJan Lentfer * a Net::DNS like library for C
7825eb42bSJan Lentfer *
8825eb42bSJan Lentfer * (c) NLnet Labs, 2004-2006
9825eb42bSJan Lentfer *
10825eb42bSJan Lentfer * See the file LICENSE for the license
11825eb42bSJan Lentfer */
12825eb42bSJan Lentfer
13825eb42bSJan Lentfer #include <ldns/config.h>
14825eb42bSJan Lentfer
15825eb42bSJan Lentfer #include <ldns/ldns.h>
16825eb42bSJan Lentfer #include <strings.h>
17825eb42bSJan Lentfer
18825eb42bSJan Lentfer /* Access function for reading
19825eb42bSJan Lentfer * and setting the different Resolver
20825eb42bSJan Lentfer * options */
21825eb42bSJan Lentfer
22825eb42bSJan Lentfer /* read */
23825eb42bSJan Lentfer uint16_t
ldns_resolver_port(const ldns_resolver * r)24825eb42bSJan Lentfer ldns_resolver_port(const ldns_resolver *r)
25825eb42bSJan Lentfer {
26825eb42bSJan Lentfer return r->_port;
27825eb42bSJan Lentfer }
28825eb42bSJan Lentfer
295340022aSzrj ldns_rdf *
ldns_resolver_source(const ldns_resolver * r)305340022aSzrj ldns_resolver_source(const ldns_resolver *r)
315340022aSzrj {
325340022aSzrj return r->_source;
335340022aSzrj }
345340022aSzrj
35825eb42bSJan Lentfer uint16_t
ldns_resolver_edns_udp_size(const ldns_resolver * r)36825eb42bSJan Lentfer ldns_resolver_edns_udp_size(const ldns_resolver *r)
37825eb42bSJan Lentfer {
38825eb42bSJan Lentfer return r->_edns_udp_size;
39825eb42bSJan Lentfer }
40825eb42bSJan Lentfer
41825eb42bSJan Lentfer uint8_t
ldns_resolver_retry(const ldns_resolver * r)42825eb42bSJan Lentfer ldns_resolver_retry(const ldns_resolver *r)
43825eb42bSJan Lentfer {
44825eb42bSJan Lentfer return r->_retry;
45825eb42bSJan Lentfer }
46825eb42bSJan Lentfer
47825eb42bSJan Lentfer uint8_t
ldns_resolver_retrans(const ldns_resolver * r)48825eb42bSJan Lentfer ldns_resolver_retrans(const ldns_resolver *r)
49825eb42bSJan Lentfer {
50825eb42bSJan Lentfer return r->_retrans;
51825eb42bSJan Lentfer }
52825eb42bSJan Lentfer
53825eb42bSJan Lentfer bool
ldns_resolver_fallback(const ldns_resolver * r)54825eb42bSJan Lentfer ldns_resolver_fallback(const ldns_resolver *r)
55825eb42bSJan Lentfer {
56825eb42bSJan Lentfer return r->_fallback;
57825eb42bSJan Lentfer }
58825eb42bSJan Lentfer
59825eb42bSJan Lentfer uint8_t
ldns_resolver_ip6(const ldns_resolver * r)60825eb42bSJan Lentfer ldns_resolver_ip6(const ldns_resolver *r)
61825eb42bSJan Lentfer {
62825eb42bSJan Lentfer return r->_ip6;
63825eb42bSJan Lentfer }
64825eb42bSJan Lentfer
65825eb42bSJan Lentfer bool
ldns_resolver_recursive(const ldns_resolver * r)66825eb42bSJan Lentfer ldns_resolver_recursive(const ldns_resolver *r)
67825eb42bSJan Lentfer {
68825eb42bSJan Lentfer return r->_recursive;
69825eb42bSJan Lentfer }
70825eb42bSJan Lentfer
71825eb42bSJan Lentfer bool
ldns_resolver_debug(const ldns_resolver * r)72825eb42bSJan Lentfer ldns_resolver_debug(const ldns_resolver *r)
73825eb42bSJan Lentfer {
74825eb42bSJan Lentfer return r->_debug;
75825eb42bSJan Lentfer }
76825eb42bSJan Lentfer
77825eb42bSJan Lentfer bool
ldns_resolver_dnsrch(const ldns_resolver * r)78825eb42bSJan Lentfer ldns_resolver_dnsrch(const ldns_resolver *r)
79825eb42bSJan Lentfer {
80825eb42bSJan Lentfer return r->_dnsrch;
81825eb42bSJan Lentfer }
82825eb42bSJan Lentfer
83825eb42bSJan Lentfer bool
ldns_resolver_fail(const ldns_resolver * r)84825eb42bSJan Lentfer ldns_resolver_fail(const ldns_resolver *r)
85825eb42bSJan Lentfer {
86825eb42bSJan Lentfer return r->_fail;
87825eb42bSJan Lentfer }
88825eb42bSJan Lentfer
89825eb42bSJan Lentfer bool
ldns_resolver_defnames(const ldns_resolver * r)90825eb42bSJan Lentfer ldns_resolver_defnames(const ldns_resolver *r)
91825eb42bSJan Lentfer {
92825eb42bSJan Lentfer return r->_defnames;
93825eb42bSJan Lentfer }
94825eb42bSJan Lentfer
95825eb42bSJan Lentfer ldns_rdf *
ldns_resolver_domain(const ldns_resolver * r)96825eb42bSJan Lentfer ldns_resolver_domain(const ldns_resolver *r)
97825eb42bSJan Lentfer {
98825eb42bSJan Lentfer return r->_domain;
99825eb42bSJan Lentfer }
100825eb42bSJan Lentfer
101825eb42bSJan Lentfer ldns_rdf **
ldns_resolver_searchlist(const ldns_resolver * r)102825eb42bSJan Lentfer ldns_resolver_searchlist(const ldns_resolver *r)
103825eb42bSJan Lentfer {
104825eb42bSJan Lentfer return r->_searchlist;
105825eb42bSJan Lentfer }
106825eb42bSJan Lentfer
107825eb42bSJan Lentfer ldns_rdf **
ldns_resolver_nameservers(const ldns_resolver * r)108825eb42bSJan Lentfer ldns_resolver_nameservers(const ldns_resolver *r)
109825eb42bSJan Lentfer {
110825eb42bSJan Lentfer return r->_nameservers;
111825eb42bSJan Lentfer }
112825eb42bSJan Lentfer
113825eb42bSJan Lentfer size_t
ldns_resolver_nameserver_count(const ldns_resolver * r)114825eb42bSJan Lentfer ldns_resolver_nameserver_count(const ldns_resolver *r)
115825eb42bSJan Lentfer {
116825eb42bSJan Lentfer return r->_nameserver_count;
117825eb42bSJan Lentfer }
118825eb42bSJan Lentfer
119825eb42bSJan Lentfer bool
ldns_resolver_dnssec(const ldns_resolver * r)120825eb42bSJan Lentfer ldns_resolver_dnssec(const ldns_resolver *r)
121825eb42bSJan Lentfer {
122825eb42bSJan Lentfer return r->_dnssec;
123825eb42bSJan Lentfer }
124825eb42bSJan Lentfer
125825eb42bSJan Lentfer bool
ldns_resolver_dnssec_cd(const ldns_resolver * r)126825eb42bSJan Lentfer ldns_resolver_dnssec_cd(const ldns_resolver *r)
127825eb42bSJan Lentfer {
128825eb42bSJan Lentfer return r->_dnssec_cd;
129825eb42bSJan Lentfer }
130825eb42bSJan Lentfer
131825eb42bSJan Lentfer ldns_rr_list *
ldns_resolver_dnssec_anchors(const ldns_resolver * r)132825eb42bSJan Lentfer ldns_resolver_dnssec_anchors(const ldns_resolver *r)
133825eb42bSJan Lentfer {
134825eb42bSJan Lentfer return r->_dnssec_anchors;
135825eb42bSJan Lentfer }
136825eb42bSJan Lentfer
137825eb42bSJan Lentfer bool
ldns_resolver_trusted_key(const ldns_resolver * r,ldns_rr_list * keys,ldns_rr_list * trusted_keys)138825eb42bSJan Lentfer ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
139825eb42bSJan Lentfer {
140825eb42bSJan Lentfer size_t i;
141825eb42bSJan Lentfer bool result = false;
142825eb42bSJan Lentfer
143825eb42bSJan Lentfer ldns_rr_list * trust_anchors;
144825eb42bSJan Lentfer ldns_rr * cur_rr;
145825eb42bSJan Lentfer
146825eb42bSJan Lentfer if (!r || !keys) { return false; }
147825eb42bSJan Lentfer
148825eb42bSJan Lentfer trust_anchors = ldns_resolver_dnssec_anchors(r);
149825eb42bSJan Lentfer
150825eb42bSJan Lentfer if (!trust_anchors) { return false; }
151825eb42bSJan Lentfer
152825eb42bSJan Lentfer for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
153825eb42bSJan Lentfer
154825eb42bSJan Lentfer cur_rr = ldns_rr_list_rr(keys, i);
155825eb42bSJan Lentfer if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
156825eb42bSJan Lentfer if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
157825eb42bSJan Lentfer result = true;
158825eb42bSJan Lentfer }
159825eb42bSJan Lentfer }
160825eb42bSJan Lentfer
161825eb42bSJan Lentfer return result;
162825eb42bSJan Lentfer }
163825eb42bSJan Lentfer
164825eb42bSJan Lentfer bool
ldns_resolver_igntc(const ldns_resolver * r)165825eb42bSJan Lentfer ldns_resolver_igntc(const ldns_resolver *r)
166825eb42bSJan Lentfer {
167825eb42bSJan Lentfer return r->_igntc;
168825eb42bSJan Lentfer }
169825eb42bSJan Lentfer
170825eb42bSJan Lentfer bool
ldns_resolver_usevc(const ldns_resolver * r)171825eb42bSJan Lentfer ldns_resolver_usevc(const ldns_resolver *r)
172825eb42bSJan Lentfer {
173825eb42bSJan Lentfer return r->_usevc;
174825eb42bSJan Lentfer }
175825eb42bSJan Lentfer
176825eb42bSJan Lentfer size_t *
ldns_resolver_rtt(const ldns_resolver * r)177825eb42bSJan Lentfer ldns_resolver_rtt(const ldns_resolver *r)
178825eb42bSJan Lentfer {
179825eb42bSJan Lentfer return r->_rtt;
180825eb42bSJan Lentfer }
181825eb42bSJan Lentfer
182825eb42bSJan Lentfer size_t
ldns_resolver_nameserver_rtt(const ldns_resolver * r,size_t pos)183825eb42bSJan Lentfer ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
184825eb42bSJan Lentfer {
185825eb42bSJan Lentfer size_t *rtt;
186825eb42bSJan Lentfer
187825eb42bSJan Lentfer assert(r != NULL);
188825eb42bSJan Lentfer
189825eb42bSJan Lentfer rtt = ldns_resolver_rtt(r);
190825eb42bSJan Lentfer
191825eb42bSJan Lentfer if (pos >= ldns_resolver_nameserver_count(r)) {
192825eb42bSJan Lentfer /* error ?*/
193825eb42bSJan Lentfer return 0;
194825eb42bSJan Lentfer } else {
195825eb42bSJan Lentfer return rtt[pos];
196825eb42bSJan Lentfer }
197825eb42bSJan Lentfer
198825eb42bSJan Lentfer }
199825eb42bSJan Lentfer
200825eb42bSJan Lentfer struct timeval
ldns_resolver_timeout(const ldns_resolver * r)201825eb42bSJan Lentfer ldns_resolver_timeout(const ldns_resolver *r)
202825eb42bSJan Lentfer {
203825eb42bSJan Lentfer return r->_timeout;
204825eb42bSJan Lentfer }
205825eb42bSJan Lentfer
2065340022aSzrj const char *
ldns_resolver_tsig_keyname(const ldns_resolver * r)207825eb42bSJan Lentfer ldns_resolver_tsig_keyname(const ldns_resolver *r)
208825eb42bSJan Lentfer {
209825eb42bSJan Lentfer return r->_tsig_keyname;
210825eb42bSJan Lentfer }
211825eb42bSJan Lentfer
2125340022aSzrj const char *
ldns_resolver_tsig_algorithm(const ldns_resolver * r)213825eb42bSJan Lentfer ldns_resolver_tsig_algorithm(const ldns_resolver *r)
214825eb42bSJan Lentfer {
215825eb42bSJan Lentfer return r->_tsig_algorithm;
216825eb42bSJan Lentfer }
217825eb42bSJan Lentfer
2185340022aSzrj const char *
ldns_resolver_tsig_keydata(const ldns_resolver * r)219825eb42bSJan Lentfer ldns_resolver_tsig_keydata(const ldns_resolver *r)
220825eb42bSJan Lentfer {
221825eb42bSJan Lentfer return r->_tsig_keydata;
222825eb42bSJan Lentfer }
223825eb42bSJan Lentfer
224825eb42bSJan Lentfer bool
ldns_resolver_random(const ldns_resolver * r)225825eb42bSJan Lentfer ldns_resolver_random(const ldns_resolver *r)
226825eb42bSJan Lentfer {
227825eb42bSJan Lentfer return r->_random;
228825eb42bSJan Lentfer }
229825eb42bSJan Lentfer
230825eb42bSJan Lentfer size_t
ldns_resolver_searchlist_count(const ldns_resolver * r)231825eb42bSJan Lentfer ldns_resolver_searchlist_count(const ldns_resolver *r)
232825eb42bSJan Lentfer {
233825eb42bSJan Lentfer return r->_searchlist_count;
234825eb42bSJan Lentfer }
235825eb42bSJan Lentfer
236825eb42bSJan Lentfer /* write */
237825eb42bSJan Lentfer void
ldns_resolver_set_port(ldns_resolver * r,uint16_t p)238825eb42bSJan Lentfer ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
239825eb42bSJan Lentfer {
240825eb42bSJan Lentfer r->_port = p;
241825eb42bSJan Lentfer }
242825eb42bSJan Lentfer
2435340022aSzrj void
ldns_resolver_set_source(ldns_resolver * r,ldns_rdf * s)2445340022aSzrj ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
2455340022aSzrj {
2465340022aSzrj r->_source = s;
2475340022aSzrj }
2485340022aSzrj
249825eb42bSJan Lentfer ldns_rdf *
ldns_resolver_pop_nameserver(ldns_resolver * r)250825eb42bSJan Lentfer ldns_resolver_pop_nameserver(ldns_resolver *r)
251825eb42bSJan Lentfer {
252825eb42bSJan Lentfer ldns_rdf **nameservers;
253825eb42bSJan Lentfer ldns_rdf *pop;
254825eb42bSJan Lentfer size_t ns_count;
255825eb42bSJan Lentfer size_t *rtt;
256825eb42bSJan Lentfer
257825eb42bSJan Lentfer assert(r != NULL);
258825eb42bSJan Lentfer
259825eb42bSJan Lentfer ns_count = ldns_resolver_nameserver_count(r);
260825eb42bSJan Lentfer nameservers = ldns_resolver_nameservers(r);
261825eb42bSJan Lentfer rtt = ldns_resolver_rtt(r);
262825eb42bSJan Lentfer if (ns_count == 0 || !nameservers) {
263825eb42bSJan Lentfer return NULL;
264825eb42bSJan Lentfer }
265825eb42bSJan Lentfer
266825eb42bSJan Lentfer pop = nameservers[ns_count - 1];
267825eb42bSJan Lentfer
268d1b2b5caSJohn Marino if (ns_count == 1) {
269d1b2b5caSJohn Marino LDNS_FREE(nameservers);
270d1b2b5caSJohn Marino LDNS_FREE(rtt);
271d1b2b5caSJohn Marino
272d1b2b5caSJohn Marino ldns_resolver_set_nameservers(r, NULL);
273d1b2b5caSJohn Marino ldns_resolver_set_rtt(r, NULL);
274d1b2b5caSJohn Marino } else {
275d1b2b5caSJohn Marino nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *,
276d1b2b5caSJohn Marino (ns_count - 1));
277825eb42bSJan Lentfer rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
278825eb42bSJan Lentfer
279825eb42bSJan Lentfer ldns_resolver_set_nameservers(r, nameservers);
280825eb42bSJan Lentfer ldns_resolver_set_rtt(r, rtt);
281d1b2b5caSJohn Marino }
282825eb42bSJan Lentfer /* decr the count */
283825eb42bSJan Lentfer ldns_resolver_dec_nameserver_count(r);
284825eb42bSJan Lentfer return pop;
285825eb42bSJan Lentfer }
286825eb42bSJan Lentfer
287825eb42bSJan Lentfer ldns_status
ldns_resolver_push_nameserver(ldns_resolver * r,const ldns_rdf * n)2885340022aSzrj ldns_resolver_push_nameserver(ldns_resolver *r, const ldns_rdf *n)
289825eb42bSJan Lentfer {
290825eb42bSJan Lentfer ldns_rdf **nameservers;
291825eb42bSJan Lentfer size_t ns_count;
292825eb42bSJan Lentfer size_t *rtt;
293825eb42bSJan Lentfer
294825eb42bSJan Lentfer if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
295825eb42bSJan Lentfer ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
296825eb42bSJan Lentfer return LDNS_STATUS_ERR;
297825eb42bSJan Lentfer }
298825eb42bSJan Lentfer
299825eb42bSJan Lentfer ns_count = ldns_resolver_nameserver_count(r);
300825eb42bSJan Lentfer nameservers = ldns_resolver_nameservers(r);
301825eb42bSJan Lentfer rtt = ldns_resolver_rtt(r);
302825eb42bSJan Lentfer
303825eb42bSJan Lentfer /* make room for the next one */
304fd185f4dSJan Lentfer if (ns_count == 0) {
305fd185f4dSJan Lentfer nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
306fd185f4dSJan Lentfer } else {
307825eb42bSJan Lentfer nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
308fd185f4dSJan Lentfer }
309fd185f4dSJan Lentfer if(!nameservers)
310fd185f4dSJan Lentfer return LDNS_STATUS_MEM_ERR;
311825eb42bSJan Lentfer
312825eb42bSJan Lentfer /* set the new value in the resolver */
313825eb42bSJan Lentfer ldns_resolver_set_nameservers(r, nameservers);
314825eb42bSJan Lentfer
315fd185f4dSJan Lentfer /* don't forget the rtt */
316fd185f4dSJan Lentfer if (ns_count == 0) {
317fd185f4dSJan Lentfer rtt = LDNS_XMALLOC(size_t, 1);
318fd185f4dSJan Lentfer } else {
319fd185f4dSJan Lentfer rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
320fd185f4dSJan Lentfer }
321fd185f4dSJan Lentfer if(!rtt)
322fd185f4dSJan Lentfer return LDNS_STATUS_MEM_ERR;
323fd185f4dSJan Lentfer
324825eb42bSJan Lentfer /* slide n in its slot. */
325825eb42bSJan Lentfer /* we clone it here, because then we can free the original
326825eb42bSJan Lentfer * rr's where it stood */
327825eb42bSJan Lentfer nameservers[ns_count] = ldns_rdf_clone(n);
328825eb42bSJan Lentfer rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
329825eb42bSJan Lentfer ldns_resolver_incr_nameserver_count(r);
330825eb42bSJan Lentfer ldns_resolver_set_rtt(r, rtt);
331825eb42bSJan Lentfer return LDNS_STATUS_OK;
332825eb42bSJan Lentfer }
333825eb42bSJan Lentfer
334825eb42bSJan Lentfer ldns_status
ldns_resolver_push_nameserver_rr(ldns_resolver * r,const ldns_rr * rr)3355340022aSzrj ldns_resolver_push_nameserver_rr(ldns_resolver *r, const ldns_rr *rr)
336825eb42bSJan Lentfer {
337825eb42bSJan Lentfer ldns_rdf *address;
338825eb42bSJan Lentfer if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
339825eb42bSJan Lentfer ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
340825eb42bSJan Lentfer return LDNS_STATUS_ERR;
341825eb42bSJan Lentfer }
342825eb42bSJan Lentfer address = ldns_rr_rdf(rr, 0); /* extract the ip number */
343825eb42bSJan Lentfer if (address) {
344825eb42bSJan Lentfer return ldns_resolver_push_nameserver(r, address);
345825eb42bSJan Lentfer } else {
346825eb42bSJan Lentfer return LDNS_STATUS_ERR;
347825eb42bSJan Lentfer }
348825eb42bSJan Lentfer }
349825eb42bSJan Lentfer
350825eb42bSJan Lentfer ldns_status
ldns_resolver_push_nameserver_rr_list(ldns_resolver * r,const ldns_rr_list * rrlist)3515340022aSzrj ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, const ldns_rr_list *rrlist)
352825eb42bSJan Lentfer {
353825eb42bSJan Lentfer ldns_rr *rr;
354825eb42bSJan Lentfer ldns_status stat;
355825eb42bSJan Lentfer size_t i;
356825eb42bSJan Lentfer
357825eb42bSJan Lentfer stat = LDNS_STATUS_OK;
358825eb42bSJan Lentfer if (rrlist) {
359825eb42bSJan Lentfer for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
360825eb42bSJan Lentfer rr = ldns_rr_list_rr(rrlist, i);
361825eb42bSJan Lentfer if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
362825eb42bSJan Lentfer stat = LDNS_STATUS_ERR;
363fd185f4dSJan Lentfer break;
364825eb42bSJan Lentfer }
365825eb42bSJan Lentfer }
366825eb42bSJan Lentfer return stat;
367825eb42bSJan Lentfer } else {
368825eb42bSJan Lentfer return LDNS_STATUS_ERR;
369825eb42bSJan Lentfer }
370825eb42bSJan Lentfer }
371825eb42bSJan Lentfer
372825eb42bSJan Lentfer void
ldns_resolver_set_edns_udp_size(ldns_resolver * r,uint16_t s)373825eb42bSJan Lentfer ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
374825eb42bSJan Lentfer {
375825eb42bSJan Lentfer r->_edns_udp_size = s;
376825eb42bSJan Lentfer }
377825eb42bSJan Lentfer
378825eb42bSJan Lentfer void
ldns_resolver_set_recursive(ldns_resolver * r,bool re)379825eb42bSJan Lentfer ldns_resolver_set_recursive(ldns_resolver *r, bool re)
380825eb42bSJan Lentfer {
381825eb42bSJan Lentfer r->_recursive = re;
382825eb42bSJan Lentfer }
383825eb42bSJan Lentfer
384825eb42bSJan Lentfer void
ldns_resolver_set_dnssec(ldns_resolver * r,bool d)385825eb42bSJan Lentfer ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
386825eb42bSJan Lentfer {
387825eb42bSJan Lentfer r->_dnssec = d;
388825eb42bSJan Lentfer }
389825eb42bSJan Lentfer
390825eb42bSJan Lentfer void
ldns_resolver_set_dnssec_cd(ldns_resolver * r,bool d)391825eb42bSJan Lentfer ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
392825eb42bSJan Lentfer {
393825eb42bSJan Lentfer r->_dnssec_cd = d;
394825eb42bSJan Lentfer }
395825eb42bSJan Lentfer
396825eb42bSJan Lentfer void
ldns_resolver_set_dnssec_anchors(ldns_resolver * r,ldns_rr_list * l)397825eb42bSJan Lentfer ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
398825eb42bSJan Lentfer {
399825eb42bSJan Lentfer r->_dnssec_anchors = l;
400825eb42bSJan Lentfer }
401825eb42bSJan Lentfer
402825eb42bSJan Lentfer ldns_status
ldns_resolver_push_dnssec_anchor(ldns_resolver * r,ldns_rr * rr)403825eb42bSJan Lentfer ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
404825eb42bSJan Lentfer {
405825eb42bSJan Lentfer ldns_rr_list * trust_anchors;
406825eb42bSJan Lentfer
407d1b2b5caSJohn Marino if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
408d1b2b5caSJohn Marino ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
409d1b2b5caSJohn Marino
410825eb42bSJan Lentfer return LDNS_STATUS_ERR;
411825eb42bSJan Lentfer }
412825eb42bSJan Lentfer
413825eb42bSJan Lentfer if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
414825eb42bSJan Lentfer trust_anchors = ldns_rr_list_new();
415825eb42bSJan Lentfer ldns_resolver_set_dnssec_anchors(r, trust_anchors);
416825eb42bSJan Lentfer }
417825eb42bSJan Lentfer
418825eb42bSJan Lentfer return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
419825eb42bSJan Lentfer }
420825eb42bSJan Lentfer
421825eb42bSJan Lentfer void
ldns_resolver_set_igntc(ldns_resolver * r,bool i)422825eb42bSJan Lentfer ldns_resolver_set_igntc(ldns_resolver *r, bool i)
423825eb42bSJan Lentfer {
424825eb42bSJan Lentfer r->_igntc = i;
425825eb42bSJan Lentfer }
426825eb42bSJan Lentfer
427825eb42bSJan Lentfer void
ldns_resolver_set_usevc(ldns_resolver * r,bool vc)428825eb42bSJan Lentfer ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
429825eb42bSJan Lentfer {
430825eb42bSJan Lentfer r->_usevc = vc;
431825eb42bSJan Lentfer }
432825eb42bSJan Lentfer
433825eb42bSJan Lentfer void
ldns_resolver_set_debug(ldns_resolver * r,bool d)434825eb42bSJan Lentfer ldns_resolver_set_debug(ldns_resolver *r, bool d)
435825eb42bSJan Lentfer {
436825eb42bSJan Lentfer r->_debug = d;
437825eb42bSJan Lentfer }
438825eb42bSJan Lentfer
439825eb42bSJan Lentfer void
ldns_resolver_set_ip6(ldns_resolver * r,uint8_t ip6)440825eb42bSJan Lentfer ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
441825eb42bSJan Lentfer {
442825eb42bSJan Lentfer r->_ip6 = ip6;
443825eb42bSJan Lentfer }
444825eb42bSJan Lentfer
445825eb42bSJan Lentfer void
ldns_resolver_set_fail(ldns_resolver * r,bool f)446825eb42bSJan Lentfer ldns_resolver_set_fail(ldns_resolver *r, bool f)
447825eb42bSJan Lentfer {
448825eb42bSJan Lentfer r->_fail =f;
449825eb42bSJan Lentfer }
450825eb42bSJan Lentfer
4515340022aSzrj static void
ldns_resolver_set_searchlist_count(ldns_resolver * r,size_t c)452825eb42bSJan Lentfer ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
453825eb42bSJan Lentfer {
454825eb42bSJan Lentfer r->_searchlist_count = c;
455825eb42bSJan Lentfer }
456825eb42bSJan Lentfer
457825eb42bSJan Lentfer void
ldns_resolver_set_nameserver_count(ldns_resolver * r,size_t c)458825eb42bSJan Lentfer ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
459825eb42bSJan Lentfer {
460825eb42bSJan Lentfer r->_nameserver_count = c;
461825eb42bSJan Lentfer }
462825eb42bSJan Lentfer
463825eb42bSJan Lentfer void
ldns_resolver_set_dnsrch(ldns_resolver * r,bool d)464825eb42bSJan Lentfer ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
465825eb42bSJan Lentfer {
466825eb42bSJan Lentfer r->_dnsrch = d;
467825eb42bSJan Lentfer }
468825eb42bSJan Lentfer
469825eb42bSJan Lentfer void
ldns_resolver_set_retry(ldns_resolver * r,uint8_t retry)470825eb42bSJan Lentfer ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
471825eb42bSJan Lentfer {
472825eb42bSJan Lentfer r->_retry = retry;
473825eb42bSJan Lentfer }
474825eb42bSJan Lentfer
475825eb42bSJan Lentfer void
ldns_resolver_set_retrans(ldns_resolver * r,uint8_t retrans)476825eb42bSJan Lentfer ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
477825eb42bSJan Lentfer {
478825eb42bSJan Lentfer r->_retrans = retrans;
479825eb42bSJan Lentfer }
480825eb42bSJan Lentfer
481825eb42bSJan Lentfer void
ldns_resolver_set_fallback(ldns_resolver * r,bool fallback)482825eb42bSJan Lentfer ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
483825eb42bSJan Lentfer {
484825eb42bSJan Lentfer r->_fallback = fallback;
485825eb42bSJan Lentfer }
486825eb42bSJan Lentfer
487825eb42bSJan Lentfer void
ldns_resolver_set_nameservers(ldns_resolver * r,ldns_rdf ** n)488825eb42bSJan Lentfer ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
489825eb42bSJan Lentfer {
490825eb42bSJan Lentfer r->_nameservers = n;
491825eb42bSJan Lentfer }
492825eb42bSJan Lentfer
493825eb42bSJan Lentfer void
ldns_resolver_set_defnames(ldns_resolver * r,bool d)494825eb42bSJan Lentfer ldns_resolver_set_defnames(ldns_resolver *r, bool d)
495825eb42bSJan Lentfer {
496825eb42bSJan Lentfer r->_defnames = d;
497825eb42bSJan Lentfer }
498825eb42bSJan Lentfer
499825eb42bSJan Lentfer void
ldns_resolver_set_rtt(ldns_resolver * r,size_t * rtt)500825eb42bSJan Lentfer ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
501825eb42bSJan Lentfer {
502825eb42bSJan Lentfer r->_rtt = rtt;
503825eb42bSJan Lentfer }
504825eb42bSJan Lentfer
505825eb42bSJan Lentfer void
ldns_resolver_set_nameserver_rtt(ldns_resolver * r,size_t pos,size_t value)506825eb42bSJan Lentfer ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
507825eb42bSJan Lentfer {
508825eb42bSJan Lentfer size_t *rtt;
509825eb42bSJan Lentfer
510825eb42bSJan Lentfer assert(r != NULL);
511825eb42bSJan Lentfer
512825eb42bSJan Lentfer rtt = ldns_resolver_rtt(r);
513825eb42bSJan Lentfer
514825eb42bSJan Lentfer if (pos >= ldns_resolver_nameserver_count(r)) {
515825eb42bSJan Lentfer /* error ?*/
516825eb42bSJan Lentfer } else {
517825eb42bSJan Lentfer rtt[pos] = value;
518825eb42bSJan Lentfer }
519825eb42bSJan Lentfer
520825eb42bSJan Lentfer }
521825eb42bSJan Lentfer
522825eb42bSJan Lentfer void
ldns_resolver_incr_nameserver_count(ldns_resolver * r)523825eb42bSJan Lentfer ldns_resolver_incr_nameserver_count(ldns_resolver *r)
524825eb42bSJan Lentfer {
525825eb42bSJan Lentfer size_t c;
526825eb42bSJan Lentfer
527825eb42bSJan Lentfer c = ldns_resolver_nameserver_count(r);
528825eb42bSJan Lentfer ldns_resolver_set_nameserver_count(r, ++c);
529825eb42bSJan Lentfer }
530825eb42bSJan Lentfer
531825eb42bSJan Lentfer void
ldns_resolver_dec_nameserver_count(ldns_resolver * r)532825eb42bSJan Lentfer ldns_resolver_dec_nameserver_count(ldns_resolver *r)
533825eb42bSJan Lentfer {
534825eb42bSJan Lentfer size_t c;
535825eb42bSJan Lentfer
536825eb42bSJan Lentfer c = ldns_resolver_nameserver_count(r);
537825eb42bSJan Lentfer if (c == 0) {
538825eb42bSJan Lentfer return;
539825eb42bSJan Lentfer } else {
540825eb42bSJan Lentfer ldns_resolver_set_nameserver_count(r, --c);
541825eb42bSJan Lentfer }
542825eb42bSJan Lentfer }
543825eb42bSJan Lentfer
544825eb42bSJan Lentfer void
ldns_resolver_set_domain(ldns_resolver * r,ldns_rdf * d)545825eb42bSJan Lentfer ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
546825eb42bSJan Lentfer {
547825eb42bSJan Lentfer r->_domain = d;
548825eb42bSJan Lentfer }
549825eb42bSJan Lentfer
550825eb42bSJan Lentfer void
ldns_resolver_set_timeout(ldns_resolver * r,struct timeval timeout)551825eb42bSJan Lentfer ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
552825eb42bSJan Lentfer {
553825eb42bSJan Lentfer r->_timeout.tv_sec = timeout.tv_sec;
554825eb42bSJan Lentfer r->_timeout.tv_usec = timeout.tv_usec;
555825eb42bSJan Lentfer }
556825eb42bSJan Lentfer
557825eb42bSJan Lentfer void
ldns_resolver_push_searchlist(ldns_resolver * r,ldns_rdf * d)558825eb42bSJan Lentfer ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
559825eb42bSJan Lentfer {
560825eb42bSJan Lentfer ldns_rdf **searchlist;
561825eb42bSJan Lentfer size_t list_count;
562825eb42bSJan Lentfer
563825eb42bSJan Lentfer if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
564825eb42bSJan Lentfer return;
565825eb42bSJan Lentfer }
566825eb42bSJan Lentfer
567825eb42bSJan Lentfer list_count = ldns_resolver_searchlist_count(r);
568825eb42bSJan Lentfer searchlist = ldns_resolver_searchlist(r);
569825eb42bSJan Lentfer
570825eb42bSJan Lentfer searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
571825eb42bSJan Lentfer if (searchlist) {
572825eb42bSJan Lentfer r->_searchlist = searchlist;
573825eb42bSJan Lentfer
574825eb42bSJan Lentfer searchlist[list_count] = ldns_rdf_clone(d);
575825eb42bSJan Lentfer ldns_resolver_set_searchlist_count(r, list_count + 1);
576fd185f4dSJan Lentfer } /* no way to report mem err */
577825eb42bSJan Lentfer }
578825eb42bSJan Lentfer
579825eb42bSJan Lentfer void
ldns_resolver_set_tsig_keyname(ldns_resolver * r,const char * tsig_keyname)5805340022aSzrj ldns_resolver_set_tsig_keyname(ldns_resolver *r, const char *tsig_keyname)
581825eb42bSJan Lentfer {
582ac996e71SJan Lentfer LDNS_FREE(r->_tsig_keyname);
583ac996e71SJan Lentfer r->_tsig_keyname = strdup(tsig_keyname);
584825eb42bSJan Lentfer }
585825eb42bSJan Lentfer
586825eb42bSJan Lentfer void
ldns_resolver_set_tsig_algorithm(ldns_resolver * r,const char * tsig_algorithm)5875340022aSzrj ldns_resolver_set_tsig_algorithm(ldns_resolver *r, const char *tsig_algorithm)
588825eb42bSJan Lentfer {
589ac996e71SJan Lentfer LDNS_FREE(r->_tsig_algorithm);
590ac996e71SJan Lentfer r->_tsig_algorithm = strdup(tsig_algorithm);
591825eb42bSJan Lentfer }
592825eb42bSJan Lentfer
593825eb42bSJan Lentfer void
ldns_resolver_set_tsig_keydata(ldns_resolver * r,const char * tsig_keydata)5945340022aSzrj ldns_resolver_set_tsig_keydata(ldns_resolver *r, const char *tsig_keydata)
595825eb42bSJan Lentfer {
596ac996e71SJan Lentfer LDNS_FREE(r->_tsig_keydata);
597ac996e71SJan Lentfer r->_tsig_keydata = strdup(tsig_keydata);
598825eb42bSJan Lentfer }
599825eb42bSJan Lentfer
600825eb42bSJan Lentfer void
ldns_resolver_set_random(ldns_resolver * r,bool b)601825eb42bSJan Lentfer ldns_resolver_set_random(ldns_resolver *r, bool b)
602825eb42bSJan Lentfer {
603825eb42bSJan Lentfer r->_random = b;
604825eb42bSJan Lentfer }
605825eb42bSJan Lentfer
606825eb42bSJan Lentfer /* more sophisticated functions */
607825eb42bSJan Lentfer ldns_resolver *
ldns_resolver_new(void)608825eb42bSJan Lentfer ldns_resolver_new(void)
609825eb42bSJan Lentfer {
610825eb42bSJan Lentfer ldns_resolver *r;
611825eb42bSJan Lentfer
612825eb42bSJan Lentfer r = LDNS_MALLOC(ldns_resolver);
613825eb42bSJan Lentfer if (!r) {
614825eb42bSJan Lentfer return NULL;
615825eb42bSJan Lentfer }
616825eb42bSJan Lentfer
617825eb42bSJan Lentfer r->_searchlist = NULL;
618825eb42bSJan Lentfer r->_nameservers = NULL;
619825eb42bSJan Lentfer r->_rtt = NULL;
620825eb42bSJan Lentfer
621825eb42bSJan Lentfer /* defaults are filled out */
622825eb42bSJan Lentfer ldns_resolver_set_searchlist_count(r, 0);
623825eb42bSJan Lentfer ldns_resolver_set_nameserver_count(r, 0);
624825eb42bSJan Lentfer ldns_resolver_set_usevc(r, 0);
625825eb42bSJan Lentfer ldns_resolver_set_port(r, LDNS_PORT);
626825eb42bSJan Lentfer ldns_resolver_set_domain(r, NULL);
627825eb42bSJan Lentfer ldns_resolver_set_defnames(r, false);
628825eb42bSJan Lentfer ldns_resolver_set_retry(r, 3);
629825eb42bSJan Lentfer ldns_resolver_set_retrans(r, 2);
630825eb42bSJan Lentfer ldns_resolver_set_fallback(r, true);
631825eb42bSJan Lentfer ldns_resolver_set_fail(r, false);
632825eb42bSJan Lentfer ldns_resolver_set_edns_udp_size(r, 0);
633825eb42bSJan Lentfer ldns_resolver_set_dnssec(r, false);
634825eb42bSJan Lentfer ldns_resolver_set_dnssec_cd(r, false);
635825eb42bSJan Lentfer ldns_resolver_set_dnssec_anchors(r, NULL);
636825eb42bSJan Lentfer ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
637ac996e71SJan Lentfer ldns_resolver_set_igntc(r, false);
638ac996e71SJan Lentfer ldns_resolver_set_recursive(r, false);
639ac996e71SJan Lentfer ldns_resolver_set_dnsrch(r, true);
6405340022aSzrj ldns_resolver_set_source(r, NULL);
6415340022aSzrj ldns_resolver_set_ixfr_serial(r, 0);
642825eb42bSJan Lentfer
643825eb42bSJan Lentfer /* randomize the nameserver to be queried
644825eb42bSJan Lentfer * when there are multiple
645825eb42bSJan Lentfer */
646825eb42bSJan Lentfer ldns_resolver_set_random(r, true);
647825eb42bSJan Lentfer
648825eb42bSJan Lentfer ldns_resolver_set_debug(r, 0);
649825eb42bSJan Lentfer
650825eb42bSJan Lentfer r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
651825eb42bSJan Lentfer r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
652825eb42bSJan Lentfer
6535340022aSzrj r->_socket = -1;
654825eb42bSJan Lentfer r->_axfr_soa_count = 0;
655825eb42bSJan Lentfer r->_axfr_i = 0;
656825eb42bSJan Lentfer r->_cur_axfr_pkt = NULL;
657825eb42bSJan Lentfer
658825eb42bSJan Lentfer r->_tsig_keyname = NULL;
659825eb42bSJan Lentfer r->_tsig_keydata = NULL;
660825eb42bSJan Lentfer r->_tsig_algorithm = NULL;
661825eb42bSJan Lentfer return r;
662825eb42bSJan Lentfer }
663825eb42bSJan Lentfer
6645340022aSzrj ldns_resolver *
ldns_resolver_clone(ldns_resolver * src)6655340022aSzrj ldns_resolver_clone(ldns_resolver *src)
6665340022aSzrj {
6675340022aSzrj ldns_resolver *dst;
6685340022aSzrj size_t i;
6695340022aSzrj
6705340022aSzrj assert(src != NULL);
6715340022aSzrj
6725340022aSzrj if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
6735340022aSzrj (void) memcpy(dst, src, sizeof(ldns_resolver));
6745340022aSzrj
6755340022aSzrj if (dst->_searchlist_count == 0)
6765340022aSzrj dst->_searchlist = NULL;
6775340022aSzrj else {
6785340022aSzrj if (!(dst->_searchlist =
6795340022aSzrj LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
6805340022aSzrj goto error;
6815340022aSzrj for (i = 0; i < dst->_searchlist_count; i++)
6825340022aSzrj if (!(dst->_searchlist[i] =
6835340022aSzrj ldns_rdf_clone(src->_searchlist[i]))) {
6845340022aSzrj dst->_searchlist_count = i;
6855340022aSzrj goto error_searchlist;
6865340022aSzrj }
6875340022aSzrj }
6885340022aSzrj if (dst->_nameserver_count == 0) {
6895340022aSzrj dst->_nameservers = NULL;
6905340022aSzrj dst->_rtt = NULL;
6915340022aSzrj } else {
6925340022aSzrj if (!(dst->_nameservers =
6935340022aSzrj LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
6945340022aSzrj goto error_searchlist;
6955340022aSzrj for (i = 0; i < dst->_nameserver_count; i++)
6965340022aSzrj if (!(dst->_nameservers[i] =
6975340022aSzrj ldns_rdf_clone(src->_nameservers[i]))) {
6985340022aSzrj dst->_nameserver_count = i;
6995340022aSzrj goto error_nameservers;
7005340022aSzrj }
7015340022aSzrj if (!(dst->_rtt =
7025340022aSzrj LDNS_XMALLOC(size_t, dst->_nameserver_count)))
7035340022aSzrj goto error_nameservers;
7045340022aSzrj (void) memcpy(dst->_rtt, src->_rtt,
7055340022aSzrj sizeof(size_t) * dst->_nameserver_count);
7065340022aSzrj }
7075340022aSzrj if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
7085340022aSzrj goto error_rtt;
7095340022aSzrj
7105340022aSzrj if (dst->_tsig_keyname &&
7115340022aSzrj (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
7125340022aSzrj goto error_domain;
7135340022aSzrj
7145340022aSzrj if (dst->_tsig_keydata &&
7155340022aSzrj (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
7165340022aSzrj goto error_tsig_keyname;
7175340022aSzrj
7185340022aSzrj if (dst->_tsig_algorithm &&
7195340022aSzrj (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
7205340022aSzrj goto error_tsig_keydata;
7215340022aSzrj
7225340022aSzrj if (dst->_cur_axfr_pkt &&
7235340022aSzrj (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
7245340022aSzrj goto error_tsig_algorithm;
7255340022aSzrj
7265340022aSzrj if (dst->_dnssec_anchors &&
7275340022aSzrj (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
7285340022aSzrj goto error_cur_axfr_pkt;
7295340022aSzrj
7305340022aSzrj return dst;
7315340022aSzrj
7325340022aSzrj error_cur_axfr_pkt:
7335340022aSzrj ldns_pkt_free(dst->_cur_axfr_pkt);
7345340022aSzrj error_tsig_algorithm:
7355340022aSzrj LDNS_FREE(dst->_tsig_algorithm);
7365340022aSzrj error_tsig_keydata:
7375340022aSzrj LDNS_FREE(dst->_tsig_keydata);
7385340022aSzrj error_tsig_keyname:
7395340022aSzrj LDNS_FREE(dst->_tsig_keyname);
7405340022aSzrj error_domain:
7415340022aSzrj ldns_rdf_deep_free(dst->_domain);
7425340022aSzrj error_rtt:
7435340022aSzrj LDNS_FREE(dst->_rtt);
7445340022aSzrj error_nameservers:
7455340022aSzrj for (i = 0; i < dst->_nameserver_count; i++)
7465340022aSzrj ldns_rdf_deep_free(dst->_nameservers[i]);
7475340022aSzrj LDNS_FREE(dst->_nameservers);
7485340022aSzrj error_searchlist:
7495340022aSzrj for (i = 0; i < dst->_searchlist_count; i++)
7505340022aSzrj ldns_rdf_deep_free(dst->_searchlist[i]);
7515340022aSzrj LDNS_FREE(dst->_searchlist);
7525340022aSzrj error:
7535340022aSzrj LDNS_FREE(dst);
7545340022aSzrj return NULL;
7555340022aSzrj }
7565340022aSzrj
7575340022aSzrj
758825eb42bSJan Lentfer ldns_status
ldns_resolver_new_frm_fp(ldns_resolver ** res,FILE * fp)759825eb42bSJan Lentfer ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
760825eb42bSJan Lentfer {
761825eb42bSJan Lentfer return ldns_resolver_new_frm_fp_l(res, fp, NULL);
762825eb42bSJan Lentfer }
763825eb42bSJan Lentfer
764825eb42bSJan Lentfer ldns_status
ldns_resolver_new_frm_fp_l(ldns_resolver ** res,FILE * fp,int * line_nr)765825eb42bSJan Lentfer ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
766825eb42bSJan Lentfer {
767819dec71SDaniel Fojt ldns_resolver *r = NULL;
768825eb42bSJan Lentfer const char *keyword[LDNS_RESOLV_KEYWORDS];
769825eb42bSJan Lentfer char word[LDNS_MAX_LINELEN + 1];
770825eb42bSJan Lentfer int8_t expect;
771825eb42bSJan Lentfer uint8_t i;
772825eb42bSJan Lentfer ldns_rdf *tmp;
773825eb42bSJan Lentfer #ifdef HAVE_SSL
774825eb42bSJan Lentfer ldns_rr *tmp_rr;
775825eb42bSJan Lentfer #endif
776ac996e71SJan Lentfer ssize_t gtr, bgtr;
777825eb42bSJan Lentfer ldns_buffer *b;
778ac996e71SJan Lentfer int lnr = 0, oldline;
7795340022aSzrj FILE* myfp = fp;
780ac996e71SJan Lentfer if(!line_nr) line_nr = &lnr;
781825eb42bSJan Lentfer
7825340022aSzrj if(!fp) {
783*ee791febSAntonio Huete Jimenez myfp = fopen(LDNS_RESOLV_CONF, "r");
7845340022aSzrj if(!myfp)
7855340022aSzrj return LDNS_STATUS_FILE_ERR;
7865340022aSzrj }
7875340022aSzrj
788825eb42bSJan Lentfer /* do this better
789825eb42bSJan Lentfer * expect =
790825eb42bSJan Lentfer * 0: keyword
791825eb42bSJan Lentfer * 1: default domain dname
792825eb42bSJan Lentfer * 2: NS aaaa or a record
793825eb42bSJan Lentfer */
794825eb42bSJan Lentfer
795825eb42bSJan Lentfer /* recognized keywords */
796825eb42bSJan Lentfer keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
797825eb42bSJan Lentfer keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
798825eb42bSJan Lentfer keyword[LDNS_RESOLV_SEARCH] = "search";
799825eb42bSJan Lentfer /* these two are read but not used atm TODO */
800825eb42bSJan Lentfer keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
801825eb42bSJan Lentfer keyword[LDNS_RESOLV_OPTIONS] = "options";
802825eb42bSJan Lentfer keyword[LDNS_RESOLV_ANCHOR] = "anchor";
803825eb42bSJan Lentfer
804825eb42bSJan Lentfer r = ldns_resolver_new();
805825eb42bSJan Lentfer if (!r) {
8065340022aSzrj if(!fp) fclose(myfp);
807825eb42bSJan Lentfer return LDNS_STATUS_MEM_ERR;
808825eb42bSJan Lentfer }
809825eb42bSJan Lentfer
810825eb42bSJan Lentfer gtr = 1;
811825eb42bSJan Lentfer word[0] = 0;
812ac996e71SJan Lentfer oldline = *line_nr;
813ac996e71SJan Lentfer expect = LDNS_RESOLV_KEYWORD;
814825eb42bSJan Lentfer while (gtr > 0) {
815825eb42bSJan Lentfer /* check comments */
816825eb42bSJan Lentfer if (word[0] == '#') {
817ac996e71SJan Lentfer word[0]='x';
818ac996e71SJan Lentfer if(oldline == *line_nr) {
819ac996e71SJan Lentfer /* skip until end of line */
820ac996e71SJan Lentfer int c;
821ac996e71SJan Lentfer do {
8225340022aSzrj c = fgetc(myfp);
823ac996e71SJan Lentfer } while(c != EOF && c != '\n');
8245340022aSzrj if(c=='\n') (*line_nr)++;
825ac996e71SJan Lentfer }
826ac996e71SJan Lentfer /* and read next to prepare for further parsing */
827ac996e71SJan Lentfer oldline = *line_nr;
828825eb42bSJan Lentfer continue;
829825eb42bSJan Lentfer }
830ac996e71SJan Lentfer oldline = *line_nr;
831825eb42bSJan Lentfer switch(expect) {
832825eb42bSJan Lentfer case LDNS_RESOLV_KEYWORD:
833825eb42bSJan Lentfer /* keyword */
8345340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
835825eb42bSJan Lentfer if (gtr != 0) {
836ac996e71SJan Lentfer if(word[0] == '#') continue;
837825eb42bSJan Lentfer for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
838825eb42bSJan Lentfer if (strcasecmp(keyword[i], word) == 0) {
839825eb42bSJan Lentfer /* chosen the keyword and
840825eb42bSJan Lentfer * expect values carefully
841825eb42bSJan Lentfer */
842825eb42bSJan Lentfer expect = i;
843825eb42bSJan Lentfer break;
844825eb42bSJan Lentfer }
845825eb42bSJan Lentfer }
846825eb42bSJan Lentfer /* no keyword recognized */
847825eb42bSJan Lentfer if (expect == LDNS_RESOLV_KEYWORD) {
848825eb42bSJan Lentfer /* skip line */
849825eb42bSJan Lentfer /*
850825eb42bSJan Lentfer ldns_resolver_deep_free(r);
8515340022aSzrj if(!fp) fclose(myfp);
852825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
853825eb42bSJan Lentfer */
854825eb42bSJan Lentfer }
855825eb42bSJan Lentfer }
856825eb42bSJan Lentfer break;
857825eb42bSJan Lentfer case LDNS_RESOLV_DEFDOMAIN:
858825eb42bSJan Lentfer /* default domain dname */
8595340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
860825eb42bSJan Lentfer if (gtr == 0) {
8615340022aSzrj if(!fp) fclose(myfp);
862819dec71SDaniel Fojt ldns_resolver_deep_free(r);
863825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
864825eb42bSJan Lentfer }
865ac996e71SJan Lentfer if(word[0] == '#') {
866ac996e71SJan Lentfer expect = LDNS_RESOLV_KEYWORD;
867ac996e71SJan Lentfer continue;
868ac996e71SJan Lentfer }
869825eb42bSJan Lentfer tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
870825eb42bSJan Lentfer if (!tmp) {
8715340022aSzrj if(!fp) fclose(myfp);
872819dec71SDaniel Fojt ldns_resolver_deep_free(r);
873825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_DNAME_ERR;
874825eb42bSJan Lentfer }
875825eb42bSJan Lentfer
876825eb42bSJan Lentfer /* DOn't free, because we copy the pointer */
877825eb42bSJan Lentfer ldns_resolver_set_domain(r, tmp);
878825eb42bSJan Lentfer expect = LDNS_RESOLV_KEYWORD;
879825eb42bSJan Lentfer break;
880825eb42bSJan Lentfer case LDNS_RESOLV_NAMESERVER:
881825eb42bSJan Lentfer /* NS aaaa or a record */
8825340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
883825eb42bSJan Lentfer if (gtr == 0) {
8845340022aSzrj if(!fp) fclose(myfp);
885819dec71SDaniel Fojt ldns_resolver_deep_free(r);
886825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
887825eb42bSJan Lentfer }
888ac996e71SJan Lentfer if(word[0] == '#') {
889ac996e71SJan Lentfer expect = LDNS_RESOLV_KEYWORD;
890ac996e71SJan Lentfer continue;
891ac996e71SJan Lentfer }
892ac996e71SJan Lentfer if(strchr(word, '%')) {
893ac996e71SJan Lentfer /* snip off interface labels,
894ac996e71SJan Lentfer * fe80::222:19ff:fe31:4222%eth0 */
895ac996e71SJan Lentfer strchr(word, '%')[0]=0;
896ac996e71SJan Lentfer }
897825eb42bSJan Lentfer tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
898825eb42bSJan Lentfer if (!tmp) {
899825eb42bSJan Lentfer /* try ip4 */
900825eb42bSJan Lentfer tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
901825eb42bSJan Lentfer }
902825eb42bSJan Lentfer /* could not parse it, exit */
903825eb42bSJan Lentfer if (!tmp) {
904825eb42bSJan Lentfer ldns_resolver_deep_free(r);
9055340022aSzrj if(!fp) fclose(myfp);
906825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_ERR;
907825eb42bSJan Lentfer }
908825eb42bSJan Lentfer (void)ldns_resolver_push_nameserver(r, tmp);
909825eb42bSJan Lentfer ldns_rdf_deep_free(tmp);
910825eb42bSJan Lentfer expect = LDNS_RESOLV_KEYWORD;
911825eb42bSJan Lentfer break;
912825eb42bSJan Lentfer case LDNS_RESOLV_SEARCH:
913825eb42bSJan Lentfer /* search list domain dname */
9145340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
915825eb42bSJan Lentfer b = LDNS_MALLOC(ldns_buffer);
916ac996e71SJan Lentfer if(!b) {
917ac996e71SJan Lentfer ldns_resolver_deep_free(r);
9185340022aSzrj if(!fp) fclose(myfp);
919ac996e71SJan Lentfer return LDNS_STATUS_MEM_ERR;
920ac996e71SJan Lentfer }
921825eb42bSJan Lentfer
922ac996e71SJan Lentfer ldns_buffer_new_frm_data(b, word, (size_t) gtr);
923ac996e71SJan Lentfer if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
924ac996e71SJan Lentfer LDNS_FREE(b);
925ac996e71SJan Lentfer ldns_resolver_deep_free(r);
9265340022aSzrj if(!fp) fclose(myfp);
927ac996e71SJan Lentfer return LDNS_STATUS_MEM_ERR;
928ac996e71SJan Lentfer }
929ac996e71SJan Lentfer bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
930ac996e71SJan Lentfer while (bgtr > 0) {
931ac996e71SJan Lentfer gtr -= bgtr;
932ac996e71SJan Lentfer if(word[0] == '#') {
933ac996e71SJan Lentfer expect = LDNS_RESOLV_KEYWORD;
934d1b2b5caSJohn Marino break;
935ac996e71SJan Lentfer }
936825eb42bSJan Lentfer tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
937825eb42bSJan Lentfer if (!tmp) {
938825eb42bSJan Lentfer ldns_resolver_deep_free(r);
939ac996e71SJan Lentfer ldns_buffer_free(b);
9405340022aSzrj if(!fp) fclose(myfp);
941825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_DNAME_ERR;
942825eb42bSJan Lentfer }
943825eb42bSJan Lentfer
944825eb42bSJan Lentfer ldns_resolver_push_searchlist(r, tmp);
945825eb42bSJan Lentfer
946825eb42bSJan Lentfer ldns_rdf_deep_free(tmp);
947ac996e71SJan Lentfer bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
948ac996e71SJan Lentfer (size_t) gtr + 1);
949825eb42bSJan Lentfer }
950825eb42bSJan Lentfer ldns_buffer_free(b);
951d1b2b5caSJohn Marino if (expect != LDNS_RESOLV_KEYWORD) {
952825eb42bSJan Lentfer gtr = 1;
953825eb42bSJan Lentfer expect = LDNS_RESOLV_KEYWORD;
954d1b2b5caSJohn Marino }
955825eb42bSJan Lentfer break;
956825eb42bSJan Lentfer case LDNS_RESOLV_SORTLIST:
9575340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
958825eb42bSJan Lentfer /* sortlist not implemented atm */
959825eb42bSJan Lentfer expect = LDNS_RESOLV_KEYWORD;
960825eb42bSJan Lentfer break;
961825eb42bSJan Lentfer case LDNS_RESOLV_OPTIONS:
9625340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
963825eb42bSJan Lentfer /* options not implemented atm */
964825eb42bSJan Lentfer expect = LDNS_RESOLV_KEYWORD;
965825eb42bSJan Lentfer break;
966825eb42bSJan Lentfer case LDNS_RESOLV_ANCHOR:
967825eb42bSJan Lentfer /* a file containing a DNSSEC trust anchor */
9685340022aSzrj gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
969825eb42bSJan Lentfer if (gtr == 0) {
970ac996e71SJan Lentfer ldns_resolver_deep_free(r);
9715340022aSzrj if(!fp) fclose(myfp);
972825eb42bSJan Lentfer return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
973825eb42bSJan Lentfer }
974ac996e71SJan Lentfer if(word[0] == '#') {
975ac996e71SJan Lentfer expect = LDNS_RESOLV_KEYWORD;
976ac996e71SJan Lentfer continue;
977ac996e71SJan Lentfer }
978825eb42bSJan Lentfer
979825eb42bSJan Lentfer #ifdef HAVE_SSL
980825eb42bSJan Lentfer tmp_rr = ldns_read_anchor_file(word);
981825eb42bSJan Lentfer (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
982825eb42bSJan Lentfer ldns_rr_free(tmp_rr);
983825eb42bSJan Lentfer #endif
984825eb42bSJan Lentfer expect = LDNS_RESOLV_KEYWORD;
985825eb42bSJan Lentfer break;
986825eb42bSJan Lentfer }
987825eb42bSJan Lentfer }
988825eb42bSJan Lentfer
9895340022aSzrj if(!fp)
9905340022aSzrj fclose(myfp);
9915340022aSzrj
992825eb42bSJan Lentfer if (res) {
993825eb42bSJan Lentfer *res = r;
994825eb42bSJan Lentfer return LDNS_STATUS_OK;
995825eb42bSJan Lentfer } else {
996ac996e71SJan Lentfer ldns_resolver_deep_free(r);
997825eb42bSJan Lentfer return LDNS_STATUS_NULL;
998825eb42bSJan Lentfer }
999825eb42bSJan Lentfer }
1000825eb42bSJan Lentfer
1001825eb42bSJan Lentfer ldns_status
ldns_resolver_new_frm_file(ldns_resolver ** res,const char * filename)1002825eb42bSJan Lentfer ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
1003825eb42bSJan Lentfer {
1004825eb42bSJan Lentfer ldns_resolver *r;
1005825eb42bSJan Lentfer FILE *fp;
1006825eb42bSJan Lentfer ldns_status s;
1007825eb42bSJan Lentfer
1008825eb42bSJan Lentfer if (!filename) {
1009825eb42bSJan Lentfer fp = fopen(LDNS_RESOLV_CONF, "r");
1010825eb42bSJan Lentfer
1011825eb42bSJan Lentfer } else {
1012825eb42bSJan Lentfer fp = fopen(filename, "r");
1013825eb42bSJan Lentfer }
1014825eb42bSJan Lentfer if (!fp) {
1015825eb42bSJan Lentfer return LDNS_STATUS_FILE_ERR;
1016825eb42bSJan Lentfer }
1017825eb42bSJan Lentfer
1018825eb42bSJan Lentfer s = ldns_resolver_new_frm_fp(&r, fp);
1019825eb42bSJan Lentfer fclose(fp);
1020825eb42bSJan Lentfer if (s == LDNS_STATUS_OK) {
1021825eb42bSJan Lentfer if (res) {
1022825eb42bSJan Lentfer *res = r;
1023825eb42bSJan Lentfer return LDNS_STATUS_OK;
1024825eb42bSJan Lentfer } else {
1025d1b2b5caSJohn Marino ldns_resolver_free(r);
1026825eb42bSJan Lentfer return LDNS_STATUS_NULL;
1027825eb42bSJan Lentfer }
1028825eb42bSJan Lentfer }
1029825eb42bSJan Lentfer return s;
1030825eb42bSJan Lentfer }
1031825eb42bSJan Lentfer
1032825eb42bSJan Lentfer void
ldns_resolver_free(ldns_resolver * res)1033825eb42bSJan Lentfer ldns_resolver_free(ldns_resolver *res)
1034825eb42bSJan Lentfer {
1035825eb42bSJan Lentfer LDNS_FREE(res);
1036825eb42bSJan Lentfer }
1037825eb42bSJan Lentfer
1038825eb42bSJan Lentfer void
ldns_resolver_deep_free(ldns_resolver * res)1039825eb42bSJan Lentfer ldns_resolver_deep_free(ldns_resolver *res)
1040825eb42bSJan Lentfer {
1041825eb42bSJan Lentfer size_t i;
1042825eb42bSJan Lentfer
1043825eb42bSJan Lentfer if (res) {
10445340022aSzrj close_socket(res->_socket);
10455340022aSzrj
1046825eb42bSJan Lentfer if (res->_searchlist) {
1047825eb42bSJan Lentfer for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
1048825eb42bSJan Lentfer ldns_rdf_deep_free(res->_searchlist[i]);
1049825eb42bSJan Lentfer }
1050825eb42bSJan Lentfer LDNS_FREE(res->_searchlist);
1051825eb42bSJan Lentfer }
1052825eb42bSJan Lentfer if (res->_nameservers) {
1053825eb42bSJan Lentfer for (i = 0; i < res->_nameserver_count; i++) {
1054825eb42bSJan Lentfer ldns_rdf_deep_free(res->_nameservers[i]);
1055825eb42bSJan Lentfer }
1056825eb42bSJan Lentfer LDNS_FREE(res->_nameservers);
1057825eb42bSJan Lentfer }
1058825eb42bSJan Lentfer if (ldns_resolver_domain(res)) {
1059825eb42bSJan Lentfer ldns_rdf_deep_free(ldns_resolver_domain(res));
1060825eb42bSJan Lentfer }
1061ac996e71SJan Lentfer if (res->_tsig_keyname) {
1062825eb42bSJan Lentfer LDNS_FREE(res->_tsig_keyname);
1063825eb42bSJan Lentfer }
1064ac996e71SJan Lentfer if (res->_tsig_keydata) {
1065ac996e71SJan Lentfer LDNS_FREE(res->_tsig_keydata);
1066ac996e71SJan Lentfer }
1067ac996e71SJan Lentfer if (res->_tsig_algorithm) {
1068ac996e71SJan Lentfer LDNS_FREE(res->_tsig_algorithm);
1069ac996e71SJan Lentfer }
1070825eb42bSJan Lentfer
1071825eb42bSJan Lentfer if (res->_cur_axfr_pkt) {
1072825eb42bSJan Lentfer ldns_pkt_free(res->_cur_axfr_pkt);
1073825eb42bSJan Lentfer }
1074825eb42bSJan Lentfer
1075825eb42bSJan Lentfer if (res->_rtt) {
1076825eb42bSJan Lentfer LDNS_FREE(res->_rtt);
1077825eb42bSJan Lentfer }
1078825eb42bSJan Lentfer if (res->_dnssec_anchors) {
1079825eb42bSJan Lentfer ldns_rr_list_deep_free(res->_dnssec_anchors);
1080825eb42bSJan Lentfer }
1081825eb42bSJan Lentfer LDNS_FREE(res);
1082825eb42bSJan Lentfer }
1083825eb42bSJan Lentfer }
1084825eb42bSJan Lentfer
10855340022aSzrj 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)10865340022aSzrj ldns_resolver_search_status(ldns_pkt** pkt,
10875340022aSzrj ldns_resolver *r, const ldns_rdf *name,
10885340022aSzrj ldns_rr_type t, ldns_rr_class c, uint16_t flags)
10895340022aSzrj {
10905340022aSzrj ldns_rdf *new_name;
10915340022aSzrj ldns_rdf **search_list;
10925340022aSzrj size_t i;
10935340022aSzrj ldns_status s = LDNS_STATUS_OK;
10945340022aSzrj ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
10955340022aSzrj
10965340022aSzrj if (ldns_dname_absolute(name)) {
10975340022aSzrj /* query as-is */
10985340022aSzrj return ldns_resolver_query_status(pkt, r, name, t, c, flags);
10995340022aSzrj } else if (ldns_resolver_dnsrch(r)) {
11005340022aSzrj search_list = ldns_resolver_searchlist(r);
11015340022aSzrj for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
11025340022aSzrj if (i == ldns_resolver_searchlist_count(r)) {
11035340022aSzrj new_name = ldns_dname_cat_clone(name,
11045340022aSzrj &root_dname);
11055340022aSzrj } else {
11065340022aSzrj new_name = ldns_dname_cat_clone(name,
11075340022aSzrj search_list[i]);
11085340022aSzrj }
11095340022aSzrj
11105340022aSzrj s = ldns_resolver_query_status(pkt, r,
11115340022aSzrj new_name, t, c, flags);
1112819dec71SDaniel Fojt ldns_rdf_deep_free(new_name);
1113819dec71SDaniel Fojt
11145340022aSzrj if (pkt && *pkt) {
11155340022aSzrj if (s == LDNS_STATUS_OK &&
11165340022aSzrj ldns_pkt_get_rcode(*pkt) ==
11175340022aSzrj LDNS_RCODE_NOERROR) {
11185340022aSzrj
11195340022aSzrj return LDNS_STATUS_OK;
11205340022aSzrj }
11215340022aSzrj ldns_pkt_free(*pkt);
11225340022aSzrj *pkt = NULL;
11235340022aSzrj }
11245340022aSzrj }
11255340022aSzrj }
11265340022aSzrj return s;
11275340022aSzrj }
11285340022aSzrj
1129825eb42bSJan Lentfer ldns_pkt *
ldns_resolver_search(const ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1130825eb42bSJan Lentfer ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name,
1131825eb42bSJan Lentfer ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1132825eb42bSJan Lentfer {
11335340022aSzrj ldns_pkt* pkt = NULL;
11345340022aSzrj if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
11355340022aSzrj name, t, c, flags) != LDNS_STATUS_OK) {
11365340022aSzrj ldns_pkt_free(pkt);
1137819dec71SDaniel Fojt return NULL;
11385340022aSzrj }
11395340022aSzrj return pkt;
11405340022aSzrj }
1141825eb42bSJan Lentfer
11425340022aSzrj 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)11435340022aSzrj ldns_resolver_query_status(ldns_pkt** pkt,
11445340022aSzrj ldns_resolver *r, const ldns_rdf *name,
11455340022aSzrj ldns_rr_type t, ldns_rr_class c, uint16_t flags)
11465340022aSzrj {
11475340022aSzrj ldns_rdf *newname;
11485340022aSzrj ldns_status status;
1149825eb42bSJan Lentfer
11505340022aSzrj if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
11515340022aSzrj return ldns_resolver_send(pkt, r, name, t, c, flags);
11525340022aSzrj }
1153825eb42bSJan Lentfer
11545340022aSzrj newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
11555340022aSzrj if (!newname) {
11565340022aSzrj return LDNS_STATUS_MEM_ERR;
1157ac996e71SJan Lentfer }
11585340022aSzrj status = ldns_resolver_send(pkt, r, newname, t, c, flags);
11595340022aSzrj ldns_rdf_free(newname);
11605340022aSzrj return status;
1161825eb42bSJan Lentfer }
1162825eb42bSJan Lentfer
1163825eb42bSJan Lentfer ldns_pkt *
ldns_resolver_query(const ldns_resolver * r,const ldns_rdf * name,ldns_rr_type t,ldns_rr_class c,uint16_t flags)1164825eb42bSJan Lentfer ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
1165825eb42bSJan Lentfer ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1166825eb42bSJan Lentfer {
11675340022aSzrj ldns_pkt* pkt = NULL;
11685340022aSzrj if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
11695340022aSzrj name, t, c, flags) != LDNS_STATUS_OK) {
1170825eb42bSJan Lentfer ldns_pkt_free(pkt);
1171819dec71SDaniel Fojt return NULL;
1172825eb42bSJan Lentfer }
1173825eb42bSJan Lentfer return pkt;
1174825eb42bSJan Lentfer }
1175825eb42bSJan Lentfer
1176b5dedccaSJan Lentfer static size_t *
ldns_resolver_backup_rtt(ldns_resolver * r)1177b5dedccaSJan Lentfer ldns_resolver_backup_rtt(ldns_resolver *r)
1178b5dedccaSJan Lentfer {
1179b5dedccaSJan Lentfer size_t *new_rtt;
1180b5dedccaSJan Lentfer size_t *old_rtt = ldns_resolver_rtt(r);
1181b5dedccaSJan Lentfer
1182b5dedccaSJan Lentfer if (old_rtt && ldns_resolver_nameserver_count(r)) {
1183b5dedccaSJan Lentfer new_rtt = LDNS_XMALLOC(size_t
1184b5dedccaSJan Lentfer , ldns_resolver_nameserver_count(r));
1185819dec71SDaniel Fojt if (!new_rtt) return NULL;
1186b5dedccaSJan Lentfer memcpy(new_rtt, old_rtt, sizeof(size_t)
1187b5dedccaSJan Lentfer * ldns_resolver_nameserver_count(r));
1188b5dedccaSJan Lentfer ldns_resolver_set_rtt(r, new_rtt);
1189b5dedccaSJan Lentfer return old_rtt;
1190b5dedccaSJan Lentfer }
1191b5dedccaSJan Lentfer return NULL;
1192b5dedccaSJan Lentfer }
1193b5dedccaSJan Lentfer
1194b5dedccaSJan Lentfer static void
ldns_resolver_restore_rtt(ldns_resolver * r,size_t * old_rtt)1195b5dedccaSJan Lentfer ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
1196b5dedccaSJan Lentfer {
1197b5dedccaSJan Lentfer size_t *cur_rtt = ldns_resolver_rtt(r);
1198b5dedccaSJan Lentfer
1199b5dedccaSJan Lentfer if (cur_rtt) {
1200b5dedccaSJan Lentfer LDNS_FREE(cur_rtt);
1201b5dedccaSJan Lentfer }
1202b5dedccaSJan Lentfer ldns_resolver_set_rtt(r, old_rtt);
1203b5dedccaSJan Lentfer }
1204b5dedccaSJan Lentfer
1205825eb42bSJan Lentfer ldns_status
ldns_resolver_send_pkt(ldns_pkt ** answer,ldns_resolver * r,ldns_pkt * query_pkt)1206825eb42bSJan Lentfer ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
1207825eb42bSJan Lentfer ldns_pkt *query_pkt)
1208825eb42bSJan Lentfer {
1209825eb42bSJan Lentfer ldns_pkt *answer_pkt = NULL;
1210825eb42bSJan Lentfer ldns_status stat = LDNS_STATUS_OK;
1211b5dedccaSJan Lentfer size_t *rtt;
1212825eb42bSJan Lentfer
1213825eb42bSJan Lentfer stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
1214825eb42bSJan Lentfer if (stat != LDNS_STATUS_OK) {
1215825eb42bSJan Lentfer if(answer_pkt) {
1216825eb42bSJan Lentfer ldns_pkt_free(answer_pkt);
1217825eb42bSJan Lentfer answer_pkt = NULL;
1218825eb42bSJan Lentfer }
1219825eb42bSJan Lentfer } else {
1220825eb42bSJan Lentfer /* if tc=1 fall back to EDNS and/or TCP */
1221825eb42bSJan Lentfer /* check for tcp first (otherwise we don't care about tc=1) */
1222825eb42bSJan Lentfer if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
1223825eb42bSJan Lentfer if (ldns_pkt_tc(answer_pkt)) {
1224825eb42bSJan Lentfer /* was EDNS0 set? */
1225825eb42bSJan Lentfer if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
1226b5dedccaSJan Lentfer ldns_pkt_set_edns_udp_size(query_pkt
1227b5dedccaSJan Lentfer , 4096);
1228825eb42bSJan Lentfer ldns_pkt_free(answer_pkt);
12295340022aSzrj answer_pkt = NULL;
1230b5dedccaSJan Lentfer /* Nameservers should not become
1231b5dedccaSJan Lentfer * unreachable because fragments are
1232b5dedccaSJan Lentfer * dropped (network error). We might
1233b5dedccaSJan Lentfer * still have success with TCP.
1234b5dedccaSJan Lentfer * Therefore maintain reachability
1235b5dedccaSJan Lentfer * statuses of the nameservers by
1236b5dedccaSJan Lentfer * backup and restore the rtt list.
1237b5dedccaSJan Lentfer */
1238b5dedccaSJan Lentfer rtt = ldns_resolver_backup_rtt(r);
1239b5dedccaSJan Lentfer stat = ldns_send(&answer_pkt, r
1240b5dedccaSJan Lentfer , query_pkt);
1241b5dedccaSJan Lentfer ldns_resolver_restore_rtt(r, rtt);
1242825eb42bSJan Lentfer }
1243825eb42bSJan Lentfer /* either way, if it is still truncated, use TCP */
1244825eb42bSJan Lentfer if (stat != LDNS_STATUS_OK ||
1245825eb42bSJan Lentfer ldns_pkt_tc(answer_pkt)) {
1246825eb42bSJan Lentfer ldns_resolver_set_usevc(r, true);
1247825eb42bSJan Lentfer ldns_pkt_free(answer_pkt);
1248819dec71SDaniel Fojt answer_pkt = NULL;
1249825eb42bSJan Lentfer stat = ldns_send(&answer_pkt, r, query_pkt);
1250825eb42bSJan Lentfer ldns_resolver_set_usevc(r, false);
1251825eb42bSJan Lentfer }
1252825eb42bSJan Lentfer }
1253825eb42bSJan Lentfer }
1254825eb42bSJan Lentfer }
1255825eb42bSJan Lentfer
1256819dec71SDaniel Fojt if (answer && answer_pkt) {
1257825eb42bSJan Lentfer *answer = answer_pkt;
1258825eb42bSJan Lentfer }
1259825eb42bSJan Lentfer
1260825eb42bSJan Lentfer return stat;
1261825eb42bSJan Lentfer }
1262825eb42bSJan Lentfer
1263825eb42bSJan Lentfer 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)1264825eb42bSJan Lentfer ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
1265825eb42bSJan Lentfer const ldns_rdf *name, ldns_rr_type t,
1266825eb42bSJan Lentfer ldns_rr_class c, uint16_t flags)
1267825eb42bSJan Lentfer {
1268fd185f4dSJan Lentfer struct timeval now;
12695340022aSzrj ldns_rr* soa = NULL;
1270fd185f4dSJan Lentfer
1271825eb42bSJan Lentfer /* prepare a question pkt from the parameters
1272825eb42bSJan Lentfer * and then send this */
12735340022aSzrj if (t == LDNS_RR_TYPE_IXFR) {
12745340022aSzrj ldns_rdf *owner_rdf;
12755340022aSzrj ldns_rdf *mname_rdf;
12765340022aSzrj ldns_rdf *rname_rdf;
12775340022aSzrj ldns_rdf *serial_rdf;
12785340022aSzrj ldns_rdf *refresh_rdf;
12795340022aSzrj ldns_rdf *retry_rdf;
12805340022aSzrj ldns_rdf *expire_rdf;
12815340022aSzrj ldns_rdf *minimum_rdf;
12825340022aSzrj soa = ldns_rr_new();
12835340022aSzrj
12845340022aSzrj if (!soa) {
12855340022aSzrj return LDNS_STATUS_ERR;
12865340022aSzrj }
12875340022aSzrj owner_rdf = ldns_rdf_clone(name);
12885340022aSzrj if (!owner_rdf) {
12895340022aSzrj ldns_rr_free(soa);
12905340022aSzrj return LDNS_STATUS_ERR;
12915340022aSzrj }
12925340022aSzrj ldns_rr_set_owner(soa, owner_rdf);
12935340022aSzrj ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
12945340022aSzrj ldns_rr_set_class(soa, c);
12955340022aSzrj ldns_rr_set_question(soa, false);
12965340022aSzrj if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
12975340022aSzrj ldns_rr_free(soa);
12985340022aSzrj return LDNS_STATUS_ERR;
12995340022aSzrj } else ldns_rr_push_rdf(soa, mname_rdf);
13005340022aSzrj if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
13015340022aSzrj ldns_rr_free(soa);
13025340022aSzrj return LDNS_STATUS_ERR;
13035340022aSzrj } else ldns_rr_push_rdf(soa, rname_rdf);
13045340022aSzrj serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
13055340022aSzrj if (!serial_rdf) {
13065340022aSzrj ldns_rr_free(soa);
13075340022aSzrj return LDNS_STATUS_ERR;
13085340022aSzrj } else ldns_rr_push_rdf(soa, serial_rdf);
13095340022aSzrj refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
13105340022aSzrj if (!refresh_rdf) {
13115340022aSzrj ldns_rr_free(soa);
13125340022aSzrj return LDNS_STATUS_ERR;
13135340022aSzrj } else ldns_rr_push_rdf(soa, refresh_rdf);
13145340022aSzrj retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
13155340022aSzrj if (!retry_rdf) {
13165340022aSzrj ldns_rr_free(soa);
13175340022aSzrj return LDNS_STATUS_ERR;
13185340022aSzrj } else ldns_rr_push_rdf(soa, retry_rdf);
13195340022aSzrj expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
13205340022aSzrj if (!expire_rdf) {
13215340022aSzrj ldns_rr_free(soa);
13225340022aSzrj return LDNS_STATUS_ERR;
13235340022aSzrj } else ldns_rr_push_rdf(soa, expire_rdf);
13245340022aSzrj minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
13255340022aSzrj if (!minimum_rdf) {
13265340022aSzrj ldns_rr_free(soa);
13275340022aSzrj return LDNS_STATUS_ERR;
13285340022aSzrj } else ldns_rr_push_rdf(soa, minimum_rdf);
13295340022aSzrj
13305340022aSzrj *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
13315340022aSzrj c, flags, soa);
13325340022aSzrj } else {
1333825eb42bSJan Lentfer *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
13345340022aSzrj }
1335825eb42bSJan Lentfer if (!*query_pkt) {
13365340022aSzrj ldns_rr_free(soa);
1337825eb42bSJan Lentfer return LDNS_STATUS_ERR;
1338825eb42bSJan Lentfer }
1339825eb42bSJan Lentfer
1340825eb42bSJan Lentfer /* set DO bit if necessary */
1341825eb42bSJan Lentfer if (ldns_resolver_dnssec(r)) {
1342825eb42bSJan Lentfer if (ldns_resolver_edns_udp_size(r) == 0) {
1343825eb42bSJan Lentfer ldns_resolver_set_edns_udp_size(r, 4096);
1344825eb42bSJan Lentfer }
1345825eb42bSJan Lentfer ldns_pkt_set_edns_do(*query_pkt, true);
1346825eb42bSJan Lentfer if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
1347825eb42bSJan Lentfer ldns_pkt_set_cd(*query_pkt, true);
1348825eb42bSJan Lentfer }
1349825eb42bSJan Lentfer }
1350825eb42bSJan Lentfer
1351825eb42bSJan Lentfer /* transfer the udp_edns_size from the resolver to the packet */
1352825eb42bSJan Lentfer if (ldns_resolver_edns_udp_size(r) != 0) {
1353825eb42bSJan Lentfer ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
1354825eb42bSJan Lentfer }
1355825eb42bSJan Lentfer
1356fd185f4dSJan Lentfer /* set the timestamp */
1357fd185f4dSJan Lentfer now.tv_sec = time(NULL);
1358fd185f4dSJan Lentfer now.tv_usec = 0;
1359fd185f4dSJan Lentfer ldns_pkt_set_timestamp(*query_pkt, now);
1360fd185f4dSJan Lentfer
1361fd185f4dSJan Lentfer
1362825eb42bSJan Lentfer if (ldns_resolver_debug(r)) {
1363825eb42bSJan Lentfer ldns_pkt_print(stdout, *query_pkt);
1364825eb42bSJan Lentfer }
1365825eb42bSJan Lentfer
1366825eb42bSJan Lentfer /* only set the id if it is not set yet */
1367825eb42bSJan Lentfer if (ldns_pkt_id(*query_pkt) == 0) {
1368825eb42bSJan Lentfer ldns_pkt_set_random_id(*query_pkt);
1369825eb42bSJan Lentfer }
1370825eb42bSJan Lentfer
1371825eb42bSJan Lentfer return LDNS_STATUS_OK;
1372825eb42bSJan Lentfer }
1373825eb42bSJan Lentfer
1374825eb42bSJan Lentfer 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)1375825eb42bSJan Lentfer ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
1376825eb42bSJan Lentfer ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1377825eb42bSJan Lentfer {
1378825eb42bSJan Lentfer ldns_pkt *query_pkt;
1379825eb42bSJan Lentfer ldns_pkt *answer_pkt;
1380825eb42bSJan Lentfer ldns_status status;
1381825eb42bSJan Lentfer
1382825eb42bSJan Lentfer assert(r != NULL);
1383825eb42bSJan Lentfer assert(name != NULL);
1384825eb42bSJan Lentfer
1385825eb42bSJan Lentfer answer_pkt = NULL;
1386825eb42bSJan Lentfer
1387825eb42bSJan Lentfer /* do all the preprocessing here, then fire of an query to
1388825eb42bSJan Lentfer * the network */
1389825eb42bSJan Lentfer
1390825eb42bSJan Lentfer if (0 == t) {
1391825eb42bSJan Lentfer t= LDNS_RR_TYPE_A;
1392825eb42bSJan Lentfer }
1393825eb42bSJan Lentfer if (0 == c) {
1394825eb42bSJan Lentfer c= LDNS_RR_CLASS_IN;
1395825eb42bSJan Lentfer }
1396825eb42bSJan Lentfer if (0 == ldns_resolver_nameserver_count(r)) {
1397825eb42bSJan Lentfer return LDNS_STATUS_RES_NO_NS;
1398825eb42bSJan Lentfer }
1399825eb42bSJan Lentfer if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
1400825eb42bSJan Lentfer return LDNS_STATUS_RES_QUERY;
1401825eb42bSJan Lentfer }
1402825eb42bSJan Lentfer
1403825eb42bSJan Lentfer status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
1404825eb42bSJan Lentfer t, c, flags);
1405825eb42bSJan Lentfer if (status != LDNS_STATUS_OK) {
1406825eb42bSJan Lentfer return status;
1407825eb42bSJan Lentfer }
1408825eb42bSJan Lentfer
1409825eb42bSJan Lentfer /* if tsig values are set, tsign it */
1410825eb42bSJan Lentfer /* TODO: make last 3 arguments optional too? maybe make complete
14115340022aSzrj rr instead of separate values in resolver (and packet)
1412825eb42bSJan Lentfer Jelte
1413825eb42bSJan Lentfer should this go in pkt_prepare?
1414825eb42bSJan Lentfer */
1415825eb42bSJan Lentfer if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
1416fd185f4dSJan Lentfer #ifdef HAVE_SSL
1417825eb42bSJan Lentfer status = ldns_pkt_tsig_sign(query_pkt,
1418825eb42bSJan Lentfer ldns_resolver_tsig_keyname(r),
1419825eb42bSJan Lentfer ldns_resolver_tsig_keydata(r),
1420825eb42bSJan Lentfer 300, ldns_resolver_tsig_algorithm(r), NULL);
1421825eb42bSJan Lentfer if (status != LDNS_STATUS_OK) {
1422d1b2b5caSJohn Marino ldns_pkt_free(query_pkt);
1423825eb42bSJan Lentfer return LDNS_STATUS_CRYPTO_TSIG_ERR;
1424825eb42bSJan Lentfer }
1425825eb42bSJan Lentfer #else
1426d1b2b5caSJohn Marino ldns_pkt_free(query_pkt);
1427825eb42bSJan Lentfer return LDNS_STATUS_CRYPTO_TSIG_ERR;
1428825eb42bSJan Lentfer #endif /* HAVE_SSL */
1429fd185f4dSJan Lentfer }
1430ac996e71SJan Lentfer
1431825eb42bSJan Lentfer status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
1432825eb42bSJan Lentfer ldns_pkt_free(query_pkt);
1433825eb42bSJan Lentfer
1434825eb42bSJan Lentfer /* allows answer to be NULL when not interested in return value */
1435825eb42bSJan Lentfer if (answer) {
1436825eb42bSJan Lentfer *answer = answer_pkt;
1437825eb42bSJan Lentfer }
1438825eb42bSJan Lentfer return status;
1439825eb42bSJan Lentfer }
1440825eb42bSJan Lentfer
1441825eb42bSJan Lentfer ldns_rr *
ldns_axfr_next(ldns_resolver * resolver)1442825eb42bSJan Lentfer ldns_axfr_next(ldns_resolver *resolver)
1443825eb42bSJan Lentfer {
1444825eb42bSJan Lentfer ldns_rr *cur_rr;
1445825eb42bSJan Lentfer uint8_t *packet_wire;
1446825eb42bSJan Lentfer size_t packet_wire_size;
1447825eb42bSJan Lentfer ldns_status status;
1448825eb42bSJan Lentfer
1449825eb42bSJan Lentfer /* check if start() has been called */
14505340022aSzrj if (!resolver || resolver->_socket == -1) {
1451825eb42bSJan Lentfer return NULL;
1452825eb42bSJan Lentfer }
1453825eb42bSJan Lentfer
1454825eb42bSJan Lentfer if (resolver->_cur_axfr_pkt) {
1455825eb42bSJan Lentfer if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
1456825eb42bSJan Lentfer ldns_pkt_free(resolver->_cur_axfr_pkt);
1457825eb42bSJan Lentfer resolver->_cur_axfr_pkt = NULL;
1458825eb42bSJan Lentfer return ldns_axfr_next(resolver);
1459825eb42bSJan Lentfer }
1460825eb42bSJan Lentfer cur_rr = ldns_rr_clone(ldns_rr_list_rr(
1461825eb42bSJan Lentfer ldns_pkt_answer(resolver->_cur_axfr_pkt),
1462825eb42bSJan Lentfer resolver->_axfr_i));
1463825eb42bSJan Lentfer resolver->_axfr_i++;
1464825eb42bSJan Lentfer if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
1465825eb42bSJan Lentfer resolver->_axfr_soa_count++;
1466825eb42bSJan Lentfer if (resolver->_axfr_soa_count >= 2) {
14675340022aSzrj
14685340022aSzrj close_socket(resolver->_socket);
14695340022aSzrj
1470825eb42bSJan Lentfer ldns_pkt_free(resolver->_cur_axfr_pkt);
1471825eb42bSJan Lentfer resolver->_cur_axfr_pkt = NULL;
1472825eb42bSJan Lentfer }
1473825eb42bSJan Lentfer }
1474825eb42bSJan Lentfer return cur_rr;
1475825eb42bSJan Lentfer } else {
14765340022aSzrj packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
1477825eb42bSJan Lentfer if(!packet_wire)
1478825eb42bSJan Lentfer return NULL;
1479825eb42bSJan Lentfer
1480825eb42bSJan Lentfer status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
1481825eb42bSJan Lentfer packet_wire_size);
1482d1b2b5caSJohn Marino LDNS_FREE(packet_wire);
1483825eb42bSJan Lentfer
1484825eb42bSJan Lentfer resolver->_axfr_i = 0;
1485825eb42bSJan Lentfer if (status != LDNS_STATUS_OK) {
1486825eb42bSJan Lentfer /* TODO: make status return type of this function (...api change) */
14875340022aSzrj #ifdef STDERR_MSGS
1488825eb42bSJan Lentfer fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
14895340022aSzrj #endif
1490ac996e71SJan Lentfer
14915340022aSzrj /* we must now also close the socket, otherwise subsequent uses of the
1492ac996e71SJan Lentfer same resolver structure will fail because the link is still open or
1493ac996e71SJan Lentfer in an undefined state */
14945340022aSzrj
14955340022aSzrj close_socket(resolver->_socket);
1496ac996e71SJan Lentfer
1497825eb42bSJan Lentfer return NULL;
1498825eb42bSJan Lentfer } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
14995340022aSzrj #ifdef STDERR_MSGS
15005340022aSzrj ldns_lookup_table *rcode = ldns_lookup_by_id(
15015340022aSzrj ldns_rcodes,(int) ldns_pkt_get_rcode(
15025340022aSzrj resolver->_cur_axfr_pkt));
1503d1b2b5caSJohn Marino if (rcode) {
1504d1b2b5caSJohn Marino fprintf(stderr, "Error in AXFR: %s\n",
1505d1b2b5caSJohn Marino rcode->name);
1506d1b2b5caSJohn Marino } else {
1507d1b2b5caSJohn Marino fprintf(stderr, "Error in AXFR: %d\n",
1508d1b2b5caSJohn Marino (int) ldns_pkt_get_rcode(
1509d1b2b5caSJohn Marino resolver->_cur_axfr_pkt));
1510d1b2b5caSJohn Marino }
15115340022aSzrj #endif
1512ac996e71SJan Lentfer
15135340022aSzrj /* we must now also close the socket, otherwise subsequent uses of the
1514ac996e71SJan Lentfer same resolver structure will fail because the link is still open or
1515ac996e71SJan Lentfer in an undefined state */
15165340022aSzrj
15175340022aSzrj close_socket(resolver->_socket);
1518ac996e71SJan Lentfer
1519825eb42bSJan Lentfer return NULL;
1520825eb42bSJan Lentfer } else {
1521825eb42bSJan Lentfer return ldns_axfr_next(resolver);
1522825eb42bSJan Lentfer }
1523825eb42bSJan Lentfer
1524825eb42bSJan Lentfer }
1525825eb42bSJan Lentfer
1526825eb42bSJan Lentfer }
1527825eb42bSJan Lentfer
15285340022aSzrj /* this function is needed to abort a transfer that is in progress;
15295340022aSzrj * without it an aborted transfer will lead to the AXFR code in the
15305340022aSzrj * library staying in an indetermined state because the socket for the
15315340022aSzrj * AXFR is never closed
15325340022aSzrj */
15335340022aSzrj void
ldns_axfr_abort(ldns_resolver * resolver)15345340022aSzrj ldns_axfr_abort(ldns_resolver *resolver)
15355340022aSzrj {
15365340022aSzrj /* Only abort if an actual AXFR is in progress */
1537819dec71SDaniel Fojt if (resolver->_socket != -1)
15385340022aSzrj {
15395340022aSzrj #ifndef USE_WINSOCK
15405340022aSzrj close(resolver->_socket);
15415340022aSzrj #else
15425340022aSzrj closesocket(resolver->_socket);
15435340022aSzrj #endif
1544819dec71SDaniel Fojt resolver->_socket = -1;
15455340022aSzrj }
15465340022aSzrj }
15475340022aSzrj
1548825eb42bSJan Lentfer bool
ldns_axfr_complete(const ldns_resolver * res)1549825eb42bSJan Lentfer ldns_axfr_complete(const ldns_resolver *res)
1550825eb42bSJan Lentfer {
1551825eb42bSJan Lentfer /* complete when soa count is 2? */
1552825eb42bSJan Lentfer return res->_axfr_soa_count == 2;
1553825eb42bSJan Lentfer }
1554825eb42bSJan Lentfer
1555825eb42bSJan Lentfer ldns_pkt *
ldns_axfr_last_pkt(const ldns_resolver * res)1556825eb42bSJan Lentfer ldns_axfr_last_pkt(const ldns_resolver *res)
1557825eb42bSJan Lentfer {
1558825eb42bSJan Lentfer return res->_cur_axfr_pkt;
1559825eb42bSJan Lentfer }
1560825eb42bSJan Lentfer
15615340022aSzrj void
ldns_resolver_set_ixfr_serial(ldns_resolver * r,uint32_t serial)15625340022aSzrj ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
15635340022aSzrj {
15645340022aSzrj r->_serial = serial;
15655340022aSzrj }
15665340022aSzrj
15675340022aSzrj uint32_t
ldns_resolver_get_ixfr_serial(const ldns_resolver * res)15685340022aSzrj ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
15695340022aSzrj {
15705340022aSzrj return res->_serial;
15715340022aSzrj }
15725340022aSzrj
15735340022aSzrj
1574825eb42bSJan Lentfer /* random isn't really that good */
1575825eb42bSJan Lentfer void
ldns_resolver_nameservers_randomize(ldns_resolver * r)1576825eb42bSJan Lentfer ldns_resolver_nameservers_randomize(ldns_resolver *r)
1577825eb42bSJan Lentfer {
1578ac996e71SJan Lentfer uint16_t i, j;
1579d1b2b5caSJohn Marino ldns_rdf **ns, *tmpns;
1580d1b2b5caSJohn Marino size_t *rtt, tmprtt;
1581825eb42bSJan Lentfer
1582825eb42bSJan Lentfer /* should I check for ldns_resolver_random?? */
1583825eb42bSJan Lentfer assert(r != NULL);
1584825eb42bSJan Lentfer
1585825eb42bSJan Lentfer ns = ldns_resolver_nameservers(r);
1586d1b2b5caSJohn Marino rtt = ldns_resolver_rtt(r);
1587825eb42bSJan Lentfer for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
1588ac996e71SJan Lentfer j = ldns_get_random() % ldns_resolver_nameserver_count(r);
1589d1b2b5caSJohn Marino tmpns = ns[i];
1590825eb42bSJan Lentfer ns[i] = ns[j];
1591d1b2b5caSJohn Marino ns[j] = tmpns;
1592d1b2b5caSJohn Marino tmprtt = rtt[i];
1593d1b2b5caSJohn Marino rtt[i] = rtt[j];
1594d1b2b5caSJohn Marino rtt[j] = tmprtt;
1595825eb42bSJan Lentfer }
1596825eb42bSJan Lentfer ldns_resolver_set_nameservers(r, ns);
1597825eb42bSJan Lentfer }
1598825eb42bSJan Lentfer
1599