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