1/*
2 * resolver.c
3 *
4 * resolver implementation
5 *
6 * a Net::DNS like library for C
7 *
8 * (c) NLnet Labs, 2004-2006
9 *
10 * See the file LICENSE for the license
11 */
12
13#include <ldns/config.h>
14
15#include <ldns/ldns.h>
16#include <strings.h>
17
18/* Access function for reading
19 * and setting the different Resolver
20 * options */
21
22/* read */
23uint16_t
24ldns_resolver_port(const ldns_resolver *r)
25{
26	return r->_port;
27}
28
29ldns_rdf *
30ldns_resolver_source(const ldns_resolver *r)
31{
32	return r->_source;
33}
34
35uint16_t
36ldns_resolver_edns_udp_size(const ldns_resolver *r)
37{
38	        return r->_edns_udp_size;
39}
40
41uint8_t
42ldns_resolver_retry(const ldns_resolver *r)
43{
44	return r->_retry;
45}
46
47uint8_t
48ldns_resolver_retrans(const ldns_resolver *r)
49{
50	return r->_retrans;
51}
52
53bool
54ldns_resolver_fallback(const ldns_resolver *r)
55{
56	return r->_fallback;
57}
58
59uint8_t
60ldns_resolver_ip6(const ldns_resolver *r)
61{
62	return r->_ip6;
63}
64
65bool
66ldns_resolver_recursive(const ldns_resolver *r)
67{
68	return r->_recursive;
69}
70
71bool
72ldns_resolver_debug(const ldns_resolver *r)
73{
74	return r->_debug;
75}
76
77bool
78ldns_resolver_dnsrch(const ldns_resolver *r)
79{
80	return r->_dnsrch;
81}
82
83bool
84ldns_resolver_fail(const ldns_resolver *r)
85{
86	return r->_fail;
87}
88
89bool
90ldns_resolver_defnames(const ldns_resolver *r)
91{
92	return r->_defnames;
93}
94
95ldns_rdf *
96ldns_resolver_domain(const ldns_resolver *r)
97{
98	return r->_domain;
99}
100
101ldns_rdf **
102ldns_resolver_searchlist(const ldns_resolver *r)
103{
104	return r->_searchlist;
105}
106
107ldns_rdf **
108ldns_resolver_nameservers(const ldns_resolver *r)
109{
110	return r->_nameservers;
111}
112
113size_t
114ldns_resolver_nameserver_count(const ldns_resolver *r)
115{
116	return r->_nameserver_count;
117}
118
119bool
120ldns_resolver_dnssec(const ldns_resolver *r)
121{
122	return r->_dnssec;
123}
124
125bool
126ldns_resolver_dnssec_cd(const ldns_resolver *r)
127{
128	return r->_dnssec_cd;
129}
130
131ldns_rr_list *
132ldns_resolver_dnssec_anchors(const ldns_resolver *r)
133{
134    return r->_dnssec_anchors;
135}
136
137bool
138ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
139{
140  size_t i;
141  bool result = false;
142
143  ldns_rr_list * trust_anchors;
144  ldns_rr * cur_rr;
145
146  if (!r || !keys) { return false; }
147
148  trust_anchors = ldns_resolver_dnssec_anchors(r);
149
150  if (!trust_anchors) { return false; }
151
152  for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
153
154    cur_rr = ldns_rr_list_rr(keys, i);
155    if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
156      if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
157      result = true;
158    }
159  }
160
161  return result;
162}
163
164bool
165ldns_resolver_igntc(const ldns_resolver *r)
166{
167	return r->_igntc;
168}
169
170bool
171ldns_resolver_usevc(const ldns_resolver *r)
172{
173	return r->_usevc;
174}
175
176size_t *
177ldns_resolver_rtt(const ldns_resolver *r)
178{
179	return r->_rtt;
180}
181
182size_t
183ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
184{
185	size_t *rtt;
186
187	assert(r != NULL);
188
189	rtt = ldns_resolver_rtt(r);
190
191	if (pos >= ldns_resolver_nameserver_count(r)) {
192		/* error ?*/
193		return 0;
194	} else {
195		return rtt[pos];
196	}
197
198}
199
200struct timeval
201ldns_resolver_timeout(const ldns_resolver *r)
202{
203	return r->_timeout;
204}
205
206const char *
207ldns_resolver_tsig_keyname(const ldns_resolver *r)
208{
209	return r->_tsig_keyname;
210}
211
212const char *
213ldns_resolver_tsig_algorithm(const ldns_resolver *r)
214{
215	return r->_tsig_algorithm;
216}
217
218const char *
219ldns_resolver_tsig_keydata(const ldns_resolver *r)
220{
221	return r->_tsig_keydata;
222}
223
224bool
225ldns_resolver_random(const ldns_resolver *r)
226{
227	return r->_random;
228}
229
230size_t
231ldns_resolver_searchlist_count(const ldns_resolver *r)
232{
233	return r->_searchlist_count;
234}
235
236/* write */
237void
238ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
239{
240	r->_port = p;
241}
242
243void
244ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
245{
246	r->_source = s;
247}
248
249ldns_rdf *
250ldns_resolver_pop_nameserver(ldns_resolver *r)
251{
252	ldns_rdf **nameservers;
253	ldns_rdf *pop;
254	size_t ns_count;
255	size_t *rtt;
256
257	assert(r != NULL);
258
259	ns_count = ldns_resolver_nameserver_count(r);
260	nameservers = ldns_resolver_nameservers(r);
261	rtt = ldns_resolver_rtt(r);
262	if (ns_count == 0 || !nameservers) {
263		return NULL;
264	}
265
266	pop = nameservers[ns_count - 1];
267
268	if (ns_count == 1) {
269		LDNS_FREE(nameservers);
270		LDNS_FREE(rtt);
271
272		ldns_resolver_set_nameservers(r, NULL);
273		ldns_resolver_set_rtt(r, NULL);
274	} else {
275		nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *,
276				(ns_count - 1));
277		rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
278
279	        ldns_resolver_set_nameservers(r, nameservers);
280	        ldns_resolver_set_rtt(r, rtt);
281	}
282	/* decr the count */
283	ldns_resolver_dec_nameserver_count(r);
284	return pop;
285}
286
287ldns_status
288ldns_resolver_push_nameserver(ldns_resolver *r, const ldns_rdf *n)
289{
290	ldns_rdf **nameservers;
291	size_t ns_count;
292	size_t *rtt;
293
294	if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A &&
295			ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) {
296		return LDNS_STATUS_ERR;
297	}
298
299	ns_count = ldns_resolver_nameserver_count(r);
300	nameservers = ldns_resolver_nameservers(r);
301	rtt = ldns_resolver_rtt(r);
302
303	/* make room for the next one */
304	if (ns_count == 0) {
305		nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
306	} else {
307		nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
308	}
309        if(!nameservers)
310                return LDNS_STATUS_MEM_ERR;
311
312	/* set the new value in the resolver */
313	ldns_resolver_set_nameservers(r, nameservers);
314
315	/* don't forget the rtt */
316	if (ns_count == 0) {
317		rtt = LDNS_XMALLOC(size_t, 1);
318	} else {
319		rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
320	}
321        if(!rtt)
322                return LDNS_STATUS_MEM_ERR;
323
324	/* slide n in its slot. */
325	/* we clone it here, because then we can free the original
326	 * rr's where it stood */
327	nameservers[ns_count] = ldns_rdf_clone(n);
328	rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
329	ldns_resolver_incr_nameserver_count(r);
330	ldns_resolver_set_rtt(r, rtt);
331	return LDNS_STATUS_OK;
332}
333
334ldns_status
335ldns_resolver_push_nameserver_rr(ldns_resolver *r, const ldns_rr *rr)
336{
337	ldns_rdf *address;
338	if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
339			ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) {
340		return LDNS_STATUS_ERR;
341	}
342	address = ldns_rr_rdf(rr, 0); /* extract the ip number */
343	if (address) {
344		return ldns_resolver_push_nameserver(r, address);
345	} else {
346		return LDNS_STATUS_ERR;
347	}
348}
349
350ldns_status
351ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, const ldns_rr_list *rrlist)
352{
353	ldns_rr *rr;
354	ldns_status stat;
355	size_t i;
356
357	stat = LDNS_STATUS_OK;
358	if (rrlist) {
359		for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
360			rr = ldns_rr_list_rr(rrlist, i);
361			if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) {
362				stat = LDNS_STATUS_ERR;
363				break;
364			}
365		}
366		return stat;
367	} else {
368		return LDNS_STATUS_ERR;
369	}
370}
371
372void
373ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
374{
375	        r->_edns_udp_size = s;
376}
377
378void
379ldns_resolver_set_recursive(ldns_resolver *r, bool re)
380{
381	r->_recursive = re;
382}
383
384void
385ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
386{
387	r->_dnssec = d;
388}
389
390void
391ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
392{
393	r->_dnssec_cd = d;
394}
395
396void
397ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
398{
399  r->_dnssec_anchors = l;
400}
401
402ldns_status
403ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
404{
405  ldns_rr_list * trust_anchors;
406
407  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
408                ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) {
409
410    return LDNS_STATUS_ERR;
411  }
412
413  if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
414    trust_anchors = ldns_rr_list_new();
415    ldns_resolver_set_dnssec_anchors(r, trust_anchors);
416  }
417
418  return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
419}
420
421void
422ldns_resolver_set_igntc(ldns_resolver *r, bool i)
423{
424	r->_igntc = i;
425}
426
427void
428ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
429{
430	r->_usevc = vc;
431}
432
433void
434ldns_resolver_set_debug(ldns_resolver *r, bool d)
435{
436	r->_debug = d;
437}
438
439void
440ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
441{
442	r->_ip6 = ip6;
443}
444
445void
446ldns_resolver_set_fail(ldns_resolver *r, bool f)
447{
448	r->_fail =f;
449}
450
451static void
452ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
453{
454	r->_searchlist_count = c;
455}
456
457void
458ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
459{
460	r->_nameserver_count = c;
461}
462
463void
464ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
465{
466	r->_dnsrch = d;
467}
468
469void
470ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
471{
472	r->_retry = retry;
473}
474
475void
476ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
477{
478	r->_retrans = retrans;
479}
480
481void
482ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
483{
484	r->_fallback = fallback;
485}
486
487void
488ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
489{
490	r->_nameservers = n;
491}
492
493void
494ldns_resolver_set_defnames(ldns_resolver *r, bool d)
495{
496	r->_defnames = d;
497}
498
499void
500ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
501{
502	r->_rtt = rtt;
503}
504
505void
506ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
507{
508	size_t *rtt;
509
510	assert(r != NULL);
511
512	rtt = ldns_resolver_rtt(r);
513
514	if (pos >= ldns_resolver_nameserver_count(r)) {
515		/* error ?*/
516	} else {
517		rtt[pos] = value;
518	}
519
520}
521
522void
523ldns_resolver_incr_nameserver_count(ldns_resolver *r)
524{
525	size_t c;
526
527	c = ldns_resolver_nameserver_count(r);
528	ldns_resolver_set_nameserver_count(r, ++c);
529}
530
531void
532ldns_resolver_dec_nameserver_count(ldns_resolver *r)
533{
534	size_t c;
535
536	c = ldns_resolver_nameserver_count(r);
537	if (c == 0) {
538		return;
539	} else {
540		ldns_resolver_set_nameserver_count(r, --c);
541	}
542}
543
544void
545ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
546{
547	r->_domain = d;
548}
549
550void
551ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
552{
553	r->_timeout.tv_sec = timeout.tv_sec;
554	r->_timeout.tv_usec = timeout.tv_usec;
555}
556
557void
558ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
559{
560	ldns_rdf **searchlist;
561	size_t list_count;
562
563	if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) {
564		return;
565	}
566
567	list_count = ldns_resolver_searchlist_count(r);
568	searchlist = ldns_resolver_searchlist(r);
569
570	searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
571	if (searchlist) {
572		r->_searchlist = searchlist;
573
574		searchlist[list_count] = ldns_rdf_clone(d);
575		ldns_resolver_set_searchlist_count(r, list_count + 1);
576	} /* no way to report mem err */
577}
578
579void
580ldns_resolver_set_tsig_keyname(ldns_resolver *r, const char *tsig_keyname)
581{
582	LDNS_FREE(r->_tsig_keyname);
583	r->_tsig_keyname = strdup(tsig_keyname);
584}
585
586void
587ldns_resolver_set_tsig_algorithm(ldns_resolver *r, const char *tsig_algorithm)
588{
589	LDNS_FREE(r->_tsig_algorithm);
590	r->_tsig_algorithm = strdup(tsig_algorithm);
591}
592
593void
594ldns_resolver_set_tsig_keydata(ldns_resolver *r, const char *tsig_keydata)
595{
596	LDNS_FREE(r->_tsig_keydata);
597	r->_tsig_keydata = strdup(tsig_keydata);
598}
599
600void
601ldns_resolver_set_random(ldns_resolver *r, bool b)
602{
603	r->_random = b;
604}
605
606/* more sophisticated functions */
607ldns_resolver *
608ldns_resolver_new(void)
609{
610	ldns_resolver *r;
611
612	r = LDNS_MALLOC(ldns_resolver);
613	if (!r) {
614		return NULL;
615	}
616
617	r->_searchlist = NULL;
618	r->_nameservers = NULL;
619	r->_rtt = NULL;
620
621	/* defaults are filled out */
622	ldns_resolver_set_searchlist_count(r, 0);
623	ldns_resolver_set_nameserver_count(r, 0);
624	ldns_resolver_set_usevc(r, 0);
625	ldns_resolver_set_port(r, LDNS_PORT);
626	ldns_resolver_set_domain(r, NULL);
627	ldns_resolver_set_defnames(r, false);
628	ldns_resolver_set_retry(r, 3);
629	ldns_resolver_set_retrans(r, 2);
630	ldns_resolver_set_fallback(r, true);
631	ldns_resolver_set_fail(r, false);
632	ldns_resolver_set_edns_udp_size(r, 0);
633	ldns_resolver_set_dnssec(r, false);
634	ldns_resolver_set_dnssec_cd(r, false);
635	ldns_resolver_set_dnssec_anchors(r, NULL);
636	ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
637	ldns_resolver_set_igntc(r, false);
638	ldns_resolver_set_recursive(r, false);
639	ldns_resolver_set_dnsrch(r, true);
640	ldns_resolver_set_source(r, NULL);
641	ldns_resolver_set_ixfr_serial(r, 0);
642
643	/* randomize the nameserver to be queried
644	 * when there are multiple
645	 */
646	ldns_resolver_set_random(r, true);
647
648	ldns_resolver_set_debug(r, 0);
649
650	r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC;
651	r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
652
653	r->_socket = -1;
654	r->_axfr_soa_count = 0;
655	r->_axfr_i = 0;
656	r->_cur_axfr_pkt = NULL;
657
658	r->_tsig_keyname = NULL;
659	r->_tsig_keydata = NULL;
660	r->_tsig_algorithm = NULL;
661	return r;
662}
663
664ldns_resolver *
665ldns_resolver_clone(ldns_resolver *src)
666{
667	ldns_resolver *dst;
668	size_t i;
669
670	assert(src != NULL);
671
672	if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
673	(void) memcpy(dst, src, sizeof(ldns_resolver));
674
675	if (dst->_searchlist_count == 0)
676		dst->_searchlist = NULL;
677	else {
678		if (!(dst->_searchlist =
679		    LDNS_XMALLOC(ldns_rdf *, dst->_searchlist_count)))
680			goto error;
681		for (i = 0; i < dst->_searchlist_count; i++)
682			if (!(dst->_searchlist[i] =
683			    ldns_rdf_clone(src->_searchlist[i]))) {
684				dst->_searchlist_count = i;
685				goto error_searchlist;
686			}
687	}
688	if (dst->_nameserver_count == 0) {
689		dst->_nameservers = NULL;
690		dst->_rtt = NULL;
691	} else {
692		if (!(dst->_nameservers =
693		    LDNS_XMALLOC(ldns_rdf *, dst->_nameserver_count)))
694			goto error_searchlist;
695		for (i = 0; i < dst->_nameserver_count; i++)
696			if (!(dst->_nameservers[i] =
697			    ldns_rdf_clone(src->_nameservers[i]))) {
698				dst->_nameserver_count = i;
699				goto error_nameservers;
700			}
701		if (!(dst->_rtt =
702		    LDNS_XMALLOC(size_t, dst->_nameserver_count)))
703			goto error_nameservers;
704		(void) memcpy(dst->_rtt, src->_rtt,
705		    sizeof(size_t) * dst->_nameserver_count);
706	}
707	if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
708		goto error_rtt;
709
710	if (dst->_tsig_keyname &&
711	    (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
712		goto error_domain;
713
714	if (dst->_tsig_keydata &&
715	    (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
716		goto error_tsig_keyname;
717
718	if (dst->_tsig_algorithm &&
719	    (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
720		goto error_tsig_keydata;
721
722	if (dst->_cur_axfr_pkt &&
723	    (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
724		goto error_tsig_algorithm;
725
726	if (dst->_dnssec_anchors &&
727	    (!(dst->_dnssec_anchors=ldns_rr_list_clone(src->_dnssec_anchors))))
728		goto error_cur_axfr_pkt;
729
730	return dst;
731
732error_cur_axfr_pkt:
733	ldns_pkt_free(dst->_cur_axfr_pkt);
734error_tsig_algorithm:
735	LDNS_FREE(dst->_tsig_algorithm);
736error_tsig_keydata:
737	LDNS_FREE(dst->_tsig_keydata);
738error_tsig_keyname:
739	LDNS_FREE(dst->_tsig_keyname);
740error_domain:
741	ldns_rdf_deep_free(dst->_domain);
742error_rtt:
743	LDNS_FREE(dst->_rtt);
744error_nameservers:
745	for (i = 0; i < dst->_nameserver_count; i++)
746		ldns_rdf_deep_free(dst->_nameservers[i]);
747	LDNS_FREE(dst->_nameservers);
748error_searchlist:
749	for (i = 0; i < dst->_searchlist_count; i++)
750		ldns_rdf_deep_free(dst->_searchlist[i]);
751	LDNS_FREE(dst->_searchlist);
752error:
753	LDNS_FREE(dst);
754	return NULL;
755}
756
757
758ldns_status
759ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
760{
761	return ldns_resolver_new_frm_fp_l(res, fp, NULL);
762}
763
764ldns_status
765ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
766{
767	ldns_resolver *r = NULL;
768	const char *keyword[LDNS_RESOLV_KEYWORDS];
769	char word[LDNS_MAX_LINELEN + 1];
770	int8_t expect;
771	uint8_t i;
772	ldns_rdf *tmp;
773#ifdef HAVE_SSL
774	ldns_rr *tmp_rr;
775#endif
776	ssize_t gtr, bgtr;
777	ldns_buffer *b;
778        int lnr = 0;
779	FILE* myfp = fp;
780        if(!line_nr) line_nr = &lnr;
781
782	if(!fp) {
783		myfp = fopen(LDNS_RESOLV_CONF, "r");
784		if(!myfp)
785			return LDNS_STATUS_FILE_ERR;
786	}
787
788	/* do this better
789	 * expect =
790	 * 0: keyword
791	 * 1: default domain dname
792	 * 2: NS aaaa or a record
793	 */
794
795	/* recognized keywords */
796	keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
797	keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
798	keyword[LDNS_RESOLV_SEARCH] = "search";
799	/* these two are read but not used atm TODO */
800	keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
801	keyword[LDNS_RESOLV_OPTIONS] = "options";
802	keyword[LDNS_RESOLV_ANCHOR] = "anchor";
803
804	r = ldns_resolver_new();
805	if (!r) {
806		if(!fp) fclose(myfp);
807		return LDNS_STATUS_MEM_ERR;
808	}
809
810	gtr = 1;
811	word[0] = 0;
812        expect = LDNS_RESOLV_KEYWORD;
813	while (gtr > 0) {
814		switch(expect) {
815			case LDNS_RESOLV_KEYWORD:
816				/* keyword */
817				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
818				if (gtr != 0) {
819					for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
820						if (strcasecmp(keyword[i], word) == 0) {
821							/* chosen the keyword and
822							 * expect values carefully
823							 */
824							expect = i;
825							break;
826						}
827					}
828					/* no keyword recognized */
829					if (expect == LDNS_RESOLV_KEYWORD) {
830						/* skip line */
831						/*
832						ldns_resolver_deep_free(r);
833						if(!fp) fclose(myfp);
834						return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
835						*/
836					}
837				}
838				break;
839			case LDNS_RESOLV_DEFDOMAIN:
840				/* default domain dname */
841				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
842				if (gtr == 0) {
843					if(!fp) fclose(myfp);
844					ldns_resolver_deep_free(r);
845					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
846				}
847				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
848				if (!tmp) {
849					if(!fp) fclose(myfp);
850					ldns_resolver_deep_free(r);
851					return LDNS_STATUS_SYNTAX_DNAME_ERR;
852				}
853
854				/* DOn't free, because we copy the pointer */
855				ldns_resolver_set_domain(r, tmp);
856				expect = LDNS_RESOLV_KEYWORD;
857				break;
858			case LDNS_RESOLV_NAMESERVER:
859				/* NS aaaa or a record */
860				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
861				if (gtr == 0) {
862					if(!fp) fclose(myfp);
863					ldns_resolver_deep_free(r);
864					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
865				}
866                                if(strchr(word, '%')) {
867                                        /* snip off interface labels,
868                                         * fe80::222:19ff:fe31:4222%eth0 */
869                                        strchr(word, '%')[0]=0;
870                                }
871				tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word);
872				if (!tmp) {
873					/* try ip4 */
874					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word);
875				}
876				/* could not parse it, exit */
877				if (!tmp) {
878					ldns_resolver_deep_free(r);
879					if(!fp) fclose(myfp);
880					return LDNS_STATUS_SYNTAX_ERR;
881				}
882				(void)ldns_resolver_push_nameserver(r, tmp);
883				ldns_rdf_deep_free(tmp);
884				expect = LDNS_RESOLV_KEYWORD;
885				break;
886			case LDNS_RESOLV_SEARCH:
887				/* search list domain dname */
888				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
889				b = LDNS_MALLOC(ldns_buffer);
890				if(!b) {
891					ldns_resolver_deep_free(r);
892					if(!fp) fclose(myfp);
893					return LDNS_STATUS_MEM_ERR;
894				}
895
896				ldns_buffer_new_frm_data(b, word, (size_t) gtr);
897				if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
898					LDNS_FREE(b);
899					ldns_resolver_deep_free(r);
900					if(!fp) fclose(myfp);
901					return LDNS_STATUS_MEM_ERR;
902				}
903				bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
904				while (bgtr > 0) {
905					gtr -= bgtr;
906					tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word);
907					if (!tmp) {
908						ldns_resolver_deep_free(r);
909						ldns_buffer_free(b);
910						if(!fp) fclose(myfp);
911						return LDNS_STATUS_SYNTAX_DNAME_ERR;
912					}
913
914					ldns_resolver_push_searchlist(r, tmp);
915
916					ldns_rdf_deep_free(tmp);
917					bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
918					    (size_t) gtr + 1);
919				}
920				ldns_buffer_free(b);
921				if (expect != LDNS_RESOLV_KEYWORD) {
922					gtr = 1;
923					expect = LDNS_RESOLV_KEYWORD;
924				}
925				break;
926			case LDNS_RESOLV_SORTLIST:
927				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
928				/* sortlist not implemented atm */
929				expect = LDNS_RESOLV_KEYWORD;
930				break;
931			case LDNS_RESOLV_OPTIONS:
932				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
933				/* options not implemented atm */
934				expect = LDNS_RESOLV_KEYWORD;
935				break;
936			case LDNS_RESOLV_ANCHOR:
937				/* a file containing a DNSSEC trust anchor */
938				gtr = ldns_fget_token_l_resolv_conf(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
939				if (gtr == 0) {
940					ldns_resolver_deep_free(r);
941					if(!fp) fclose(myfp);
942					return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
943				}
944#ifdef HAVE_SSL
945				tmp_rr = ldns_read_anchor_file(word);
946				(void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
947				ldns_rr_free(tmp_rr);
948#endif
949				expect = LDNS_RESOLV_KEYWORD;
950				break;
951		}
952	}
953
954	if(!fp)
955		fclose(myfp);
956
957	if (res) {
958		*res = r;
959		return LDNS_STATUS_OK;
960	} else {
961		ldns_resolver_deep_free(r);
962		return LDNS_STATUS_NULL;
963	}
964}
965
966ldns_status
967ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
968{
969	ldns_resolver *r;
970	FILE *fp;
971	ldns_status s;
972
973	if (!filename) {
974		fp = fopen(LDNS_RESOLV_CONF, "r");
975
976	} else {
977		fp = fopen(filename, "r");
978	}
979	if (!fp) {
980		return LDNS_STATUS_FILE_ERR;
981	}
982
983	s = ldns_resolver_new_frm_fp(&r, fp);
984	fclose(fp);
985	if (s == LDNS_STATUS_OK) {
986		if (res) {
987			*res = r;
988			return LDNS_STATUS_OK;
989		} else  {
990			ldns_resolver_free(r);
991			return LDNS_STATUS_NULL;
992		}
993	}
994	return s;
995}
996
997void
998ldns_resolver_free(ldns_resolver *res)
999{
1000	LDNS_FREE(res);
1001}
1002
1003void
1004ldns_resolver_deep_free(ldns_resolver *res)
1005{
1006	size_t i;
1007
1008	if (res) {
1009		close_socket(res->_socket);
1010
1011		if (res->_searchlist) {
1012			for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
1013				ldns_rdf_deep_free(res->_searchlist[i]);
1014			}
1015			LDNS_FREE(res->_searchlist);
1016		}
1017		if (res->_nameservers) {
1018			for (i = 0; i < res->_nameserver_count; i++) {
1019				ldns_rdf_deep_free(res->_nameservers[i]);
1020			}
1021			LDNS_FREE(res->_nameservers);
1022		}
1023		if (ldns_resolver_domain(res)) {
1024			ldns_rdf_deep_free(ldns_resolver_domain(res));
1025		}
1026		if (res->_tsig_keyname) {
1027			LDNS_FREE(res->_tsig_keyname);
1028		}
1029		if (res->_tsig_keydata) {
1030			LDNS_FREE(res->_tsig_keydata);
1031		}
1032		if (res->_tsig_algorithm) {
1033			LDNS_FREE(res->_tsig_algorithm);
1034		}
1035
1036		if (res->_cur_axfr_pkt) {
1037			ldns_pkt_free(res->_cur_axfr_pkt);
1038		}
1039
1040		if (res->_rtt) {
1041			LDNS_FREE(res->_rtt);
1042		}
1043		if (res->_dnssec_anchors) {
1044			ldns_rr_list_deep_free(res->_dnssec_anchors);
1045		}
1046		LDNS_FREE(res);
1047	}
1048}
1049
1050ldns_status
1051ldns_resolver_search_status(ldns_pkt** pkt,
1052		ldns_resolver *r, const  ldns_rdf *name,
1053		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1054{
1055	ldns_rdf *new_name;
1056	ldns_rdf **search_list;
1057	size_t i;
1058	ldns_status s = LDNS_STATUS_OK;
1059	ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
1060
1061	if (ldns_dname_absolute(name)) {
1062		/* query as-is */
1063		return ldns_resolver_query_status(pkt, r, name, t, c, flags);
1064	} else if (ldns_resolver_dnsrch(r)) {
1065		search_list = ldns_resolver_searchlist(r);
1066		for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
1067			if (i == ldns_resolver_searchlist_count(r)) {
1068				new_name = ldns_dname_cat_clone(name,
1069						&root_dname);
1070			} else {
1071				new_name = ldns_dname_cat_clone(name,
1072						search_list[i]);
1073			}
1074
1075			s = ldns_resolver_query_status(pkt, r,
1076					new_name, t, c, flags);
1077			ldns_rdf_deep_free(new_name);
1078
1079			if (pkt && *pkt) {
1080				if (s == LDNS_STATUS_OK &&
1081						ldns_pkt_get_rcode(*pkt) ==
1082						LDNS_RCODE_NOERROR) {
1083
1084					return LDNS_STATUS_OK;
1085				}
1086				ldns_pkt_free(*pkt);
1087				*pkt = NULL;
1088			}
1089		}
1090	}
1091	return s;
1092}
1093
1094ldns_pkt *
1095ldns_resolver_search(const ldns_resolver *r,const  ldns_rdf *name,
1096	ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1097{
1098	ldns_pkt* pkt = NULL;
1099	if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r,
1100				name, t, c, flags) != LDNS_STATUS_OK) {
1101		ldns_pkt_free(pkt);
1102		return NULL;
1103	}
1104	return pkt;
1105}
1106
1107ldns_status
1108ldns_resolver_query_status(ldns_pkt** pkt,
1109		ldns_resolver *r, const ldns_rdf *name,
1110		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1111{
1112	ldns_rdf *newname;
1113	ldns_status status;
1114
1115	if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) {
1116		return ldns_resolver_send(pkt, r, name, t, c, flags);
1117	}
1118
1119	newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
1120	if (!newname) {
1121		return LDNS_STATUS_MEM_ERR;
1122	}
1123	status = ldns_resolver_send(pkt, r, newname, t, c, flags);
1124	ldns_rdf_free(newname);
1125	return status;
1126}
1127
1128ldns_pkt *
1129ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name,
1130	ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1131{
1132	ldns_pkt* pkt = NULL;
1133	if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r,
1134				name, t, c, flags) != LDNS_STATUS_OK) {
1135		ldns_pkt_free(pkt);
1136		return NULL;
1137	}
1138	return pkt;
1139}
1140
1141static size_t *
1142ldns_resolver_backup_rtt(ldns_resolver *r)
1143{
1144	size_t *new_rtt;
1145	size_t *old_rtt = ldns_resolver_rtt(r);
1146
1147	if (old_rtt && ldns_resolver_nameserver_count(r)) {
1148		new_rtt = LDNS_XMALLOC(size_t
1149				, ldns_resolver_nameserver_count(r));
1150		if (!new_rtt) return NULL;
1151		memcpy(new_rtt, old_rtt, sizeof(size_t)
1152				* ldns_resolver_nameserver_count(r));
1153		ldns_resolver_set_rtt(r, new_rtt);
1154		return old_rtt;
1155	}
1156	return NULL;
1157}
1158
1159static void
1160ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
1161{
1162	size_t *cur_rtt = ldns_resolver_rtt(r);
1163
1164	if (cur_rtt) {
1165		LDNS_FREE(cur_rtt);
1166	}
1167	ldns_resolver_set_rtt(r, old_rtt);
1168}
1169
1170ldns_status
1171ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r,
1172				   ldns_pkt *query_pkt)
1173{
1174	ldns_pkt *answer_pkt = NULL;
1175	ldns_status stat = LDNS_STATUS_OK;
1176	size_t *rtt;
1177
1178	stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
1179	if (stat != LDNS_STATUS_OK) {
1180		if(answer_pkt) {
1181			ldns_pkt_free(answer_pkt);
1182			answer_pkt = NULL;
1183		}
1184	} else {
1185		/* if tc=1 fall back to EDNS and/or TCP */
1186		/* check for tcp first (otherwise we don't care about tc=1) */
1187		if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) {
1188			if (ldns_pkt_tc(answer_pkt)) {
1189				/* was EDNS0 set? */
1190				if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
1191					ldns_pkt_set_edns_udp_size(query_pkt
1192							, 4096);
1193					ldns_pkt_free(answer_pkt);
1194					answer_pkt = NULL;
1195					/* Nameservers should not become
1196					 * unreachable because fragments are
1197					 * dropped (network error). We might
1198					 * still have success with TCP.
1199					 * Therefore maintain reachability
1200					 * statuses of the nameservers by
1201					 * backup and restore the rtt list.
1202					 */
1203					rtt = ldns_resolver_backup_rtt(r);
1204					stat = ldns_send(&answer_pkt, r
1205							, query_pkt);
1206					ldns_resolver_restore_rtt(r, rtt);
1207				}
1208				/* either way, if it is still truncated, use TCP */
1209				if (stat != LDNS_STATUS_OK ||
1210				    ldns_pkt_tc(answer_pkt)) {
1211					ldns_resolver_set_usevc(r, true);
1212					ldns_pkt_free(answer_pkt);
1213					answer_pkt = NULL;
1214					stat = ldns_send(&answer_pkt, r, query_pkt);
1215					ldns_resolver_set_usevc(r, false);
1216				}
1217			}
1218		}
1219	}
1220
1221	if (answer && answer_pkt) {
1222		*answer = answer_pkt;
1223	}
1224
1225	return stat;
1226}
1227
1228ldns_status
1229ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r,
1230                                const ldns_rdf *name, ldns_rr_type t,
1231                                ldns_rr_class c, uint16_t flags)
1232{
1233	struct timeval now;
1234	ldns_rr* soa = NULL;
1235
1236	/* prepare a question pkt from the parameters
1237	 * and then send this */
1238	if (t == LDNS_RR_TYPE_IXFR) {
1239		ldns_rdf *owner_rdf;
1240		ldns_rdf *mname_rdf;
1241		ldns_rdf *rname_rdf;
1242		ldns_rdf *serial_rdf;
1243		ldns_rdf *refresh_rdf;
1244		ldns_rdf *retry_rdf;
1245		ldns_rdf *expire_rdf;
1246		ldns_rdf *minimum_rdf;
1247		soa = ldns_rr_new();
1248
1249		if (!soa) {
1250			return LDNS_STATUS_ERR;
1251		}
1252		owner_rdf = ldns_rdf_clone(name);
1253		if (!owner_rdf) {
1254			ldns_rr_free(soa);
1255			return LDNS_STATUS_ERR;
1256		}
1257		ldns_rr_set_owner(soa, owner_rdf);
1258		ldns_rr_set_type(soa, LDNS_RR_TYPE_SOA);
1259		ldns_rr_set_class(soa, c);
1260		ldns_rr_set_question(soa, false);
1261		if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
1262			ldns_rr_free(soa);
1263			return LDNS_STATUS_ERR;
1264		} else	ldns_rr_push_rdf(soa, mname_rdf);
1265		if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
1266			ldns_rr_free(soa);
1267			return LDNS_STATUS_ERR;
1268		} else	ldns_rr_push_rdf(soa, rname_rdf);
1269		serial_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, ldns_resolver_get_ixfr_serial(r));
1270		if (!serial_rdf) {
1271			ldns_rr_free(soa);
1272			return LDNS_STATUS_ERR;
1273		} else	ldns_rr_push_rdf(soa, serial_rdf);
1274		refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1275		if (!refresh_rdf) {
1276			ldns_rr_free(soa);
1277			return LDNS_STATUS_ERR;
1278		} else	ldns_rr_push_rdf(soa, refresh_rdf);
1279		retry_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1280		if (!retry_rdf) {
1281			ldns_rr_free(soa);
1282			return LDNS_STATUS_ERR;
1283		} else	ldns_rr_push_rdf(soa, retry_rdf);
1284		expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1285		if (!expire_rdf) {
1286			ldns_rr_free(soa);
1287			return LDNS_STATUS_ERR;
1288		} else	ldns_rr_push_rdf(soa, expire_rdf);
1289		minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1290		if (!minimum_rdf) {
1291			ldns_rr_free(soa);
1292			return LDNS_STATUS_ERR;
1293		} else	ldns_rr_push_rdf(soa, minimum_rdf);
1294
1295		*query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
1296			c, flags, soa);
1297	} else {
1298		*query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
1299	}
1300	if (!*query_pkt) {
1301		ldns_rr_free(soa);
1302		return LDNS_STATUS_ERR;
1303	}
1304
1305	/* set DO bit if necessary */
1306	if (ldns_resolver_dnssec(r)) {
1307		if (ldns_resolver_edns_udp_size(r) == 0) {
1308			ldns_resolver_set_edns_udp_size(r, 4096);
1309		}
1310		ldns_pkt_set_edns_do(*query_pkt, true);
1311		if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
1312			ldns_pkt_set_cd(*query_pkt, true);
1313		}
1314	}
1315
1316	/* transfer the udp_edns_size from the resolver to the packet */
1317	if (ldns_resolver_edns_udp_size(r) != 0) {
1318		ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r));
1319	}
1320
1321	/* set the timestamp */
1322	now.tv_sec = time(NULL);
1323	now.tv_usec = 0;
1324	ldns_pkt_set_timestamp(*query_pkt, now);
1325
1326
1327	if (ldns_resolver_debug(r)) {
1328		ldns_pkt_print(stdout, *query_pkt);
1329	}
1330
1331	/* only set the id if it is not set yet */
1332	if (ldns_pkt_id(*query_pkt) == 0) {
1333		ldns_pkt_set_random_id(*query_pkt);
1334	}
1335
1336	return LDNS_STATUS_OK;
1337}
1338
1339ldns_status
1340ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name,
1341		ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1342{
1343	ldns_pkt *query_pkt;
1344	ldns_pkt *answer_pkt;
1345	ldns_status status;
1346
1347	assert(r != NULL);
1348	assert(name != NULL);
1349
1350	answer_pkt = NULL;
1351
1352	/* do all the preprocessing here, then fire of an query to
1353	 * the network */
1354
1355	if (0 == t) {
1356		t= LDNS_RR_TYPE_A;
1357	}
1358	if (0 == c) {
1359		c= LDNS_RR_CLASS_IN;
1360	}
1361	if (0 == ldns_resolver_nameserver_count(r)) {
1362		return LDNS_STATUS_RES_NO_NS;
1363	}
1364	if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
1365		return LDNS_STATUS_RES_QUERY;
1366	}
1367
1368	status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
1369	                                         t, c, flags);
1370	if (status != LDNS_STATUS_OK) {
1371		return status;
1372	}
1373
1374	/* if tsig values are set, tsign it */
1375	/* TODO: make last 3 arguments optional too? maybe make complete
1376	         rr instead of separate values in resolver (and packet)
1377	  Jelte
1378	  should this go in pkt_prepare?
1379	*/
1380	if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) {
1381#ifdef HAVE_SSL
1382		status = ldns_pkt_tsig_sign(query_pkt,
1383		                            ldns_resolver_tsig_keyname(r),
1384		                            ldns_resolver_tsig_keydata(r),
1385		                            300, ldns_resolver_tsig_algorithm(r), NULL);
1386		if (status != LDNS_STATUS_OK) {
1387			ldns_pkt_free(query_pkt);
1388			return LDNS_STATUS_CRYPTO_TSIG_ERR;
1389		}
1390#else
1391		ldns_pkt_free(query_pkt);
1392	        return LDNS_STATUS_CRYPTO_TSIG_ERR;
1393#endif /* HAVE_SSL */
1394	}
1395
1396	status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
1397	ldns_pkt_free(query_pkt);
1398
1399	/* allows answer to be NULL when not interested in return value */
1400	if (answer) {
1401		*answer = answer_pkt;
1402	}
1403	return status;
1404}
1405
1406ldns_rr *
1407ldns_axfr_next(ldns_resolver *resolver)
1408{
1409	ldns_rr *cur_rr;
1410	uint8_t *packet_wire;
1411	size_t packet_wire_size;
1412	ldns_status status;
1413
1414	/* check if start() has been called */
1415	if (!resolver || resolver->_socket == -1) {
1416		return NULL;
1417	}
1418
1419	if (resolver->_cur_axfr_pkt) {
1420		if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
1421			ldns_pkt_free(resolver->_cur_axfr_pkt);
1422			resolver->_cur_axfr_pkt = NULL;
1423			return ldns_axfr_next(resolver);
1424		}
1425		cur_rr = ldns_rr_clone(ldns_rr_list_rr(
1426					ldns_pkt_answer(resolver->_cur_axfr_pkt),
1427					resolver->_axfr_i));
1428		resolver->_axfr_i++;
1429		if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
1430			resolver->_axfr_soa_count++;
1431			if (resolver->_axfr_soa_count >= 2) {
1432
1433				close_socket(resolver->_socket);
1434
1435				ldns_pkt_free(resolver->_cur_axfr_pkt);
1436				resolver->_cur_axfr_pkt = NULL;
1437			}
1438		}
1439		return cur_rr;
1440	} else {
1441               packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
1442		if(!packet_wire)
1443			return NULL;
1444
1445		status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
1446				     packet_wire_size);
1447		LDNS_FREE(packet_wire);
1448
1449		resolver->_axfr_i = 0;
1450		if (status != LDNS_STATUS_OK) {
1451			/* TODO: make status return type of this function (...api change) */
1452#ifdef STDERR_MSGS
1453			fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
1454#endif
1455
1456			/* we must now also close the socket, otherwise subsequent uses of the
1457			   same resolver structure will fail because the link is still open or
1458			   in an undefined state */
1459
1460			close_socket(resolver->_socket);
1461
1462			return NULL;
1463		} else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
1464#ifdef STDERR_MSGS
1465			ldns_lookup_table *rcode = ldns_lookup_by_id(
1466				ldns_rcodes,(int) ldns_pkt_get_rcode(
1467				resolver->_cur_axfr_pkt));
1468			if (rcode) {
1469				fprintf(stderr, "Error in AXFR: %s\n",
1470						rcode->name);
1471			} else {
1472				fprintf(stderr, "Error in AXFR: %d\n",
1473						(int) ldns_pkt_get_rcode(
1474						resolver->_cur_axfr_pkt));
1475			}
1476#endif
1477
1478			/* we must now also close the socket, otherwise subsequent uses of the
1479			   same resolver structure will fail because the link is still open or
1480			   in an undefined state */
1481
1482			close_socket(resolver->_socket);
1483
1484			return NULL;
1485		} else {
1486			return ldns_axfr_next(resolver);
1487		}
1488
1489	}
1490
1491}
1492
1493/* this function is needed to abort a transfer that is in progress;
1494 * without it an aborted transfer will lead to the AXFR code in the
1495 * library staying in an indetermined state because the socket for the
1496 * AXFR is never closed
1497 */
1498void
1499ldns_axfr_abort(ldns_resolver *resolver)
1500{
1501	/* Only abort if an actual AXFR is in progress */
1502	if (resolver->_socket != -1)
1503	{
1504#ifndef USE_WINSOCK
1505		close(resolver->_socket);
1506#else
1507		closesocket(resolver->_socket);
1508#endif
1509		resolver->_socket = -1;
1510	}
1511}
1512
1513bool
1514ldns_axfr_complete(const ldns_resolver *res)
1515{
1516	/* complete when soa count is 2? */
1517	return res->_axfr_soa_count == 2;
1518}
1519
1520ldns_pkt *
1521ldns_axfr_last_pkt(const ldns_resolver *res)
1522{
1523	return res->_cur_axfr_pkt;
1524}
1525
1526void
1527ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
1528{
1529	r->_serial = serial;
1530}
1531
1532uint32_t
1533ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
1534{
1535	return res->_serial;
1536}
1537
1538
1539/* random isn't really that good */
1540void
1541ldns_resolver_nameservers_randomize(ldns_resolver *r)
1542{
1543	uint16_t i, j;
1544	ldns_rdf **ns, *tmpns;
1545	size_t *rtt, tmprtt;
1546
1547	/* should I check for ldns_resolver_random?? */
1548	assert(r != NULL);
1549
1550	ns = ldns_resolver_nameservers(r);
1551	rtt = ldns_resolver_rtt(r);
1552	for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
1553		j = ldns_get_random() % ldns_resolver_nameserver_count(r);
1554		tmpns = ns[i];
1555		ns[i] = ns[j];
1556		ns[j] = tmpns;
1557		tmprtt = rtt[i];
1558		rtt[i] = rtt[j];
1559		rtt[j] = tmprtt;
1560	}
1561	ldns_resolver_set_nameservers(r, ns);
1562}
1563
1564