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