xref: /dragonfly/contrib/ldns/resolver.c (revision 678e8cc6)
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 */
23 uint16_t
24 ldns_resolver_port(const ldns_resolver *r)
25 {
26 	return r->_port;
27 }
28 
29 uint16_t
30 ldns_resolver_edns_udp_size(const ldns_resolver *r)
31 {
32 	        return r->_edns_udp_size;
33 }
34 
35 uint8_t
36 ldns_resolver_retry(const ldns_resolver *r)
37 {
38 	return r->_retry;
39 }
40 
41 uint8_t
42 ldns_resolver_retrans(const ldns_resolver *r)
43 {
44 	return r->_retrans;
45 }
46 
47 bool
48 ldns_resolver_fallback(const ldns_resolver *r)
49 {
50 	return r->_fallback;
51 }
52 
53 uint8_t
54 ldns_resolver_ip6(const ldns_resolver *r)
55 {
56 	return r->_ip6;
57 }
58 
59 bool
60 ldns_resolver_recursive(const ldns_resolver *r)
61 {
62 	return r->_recursive;
63 }
64 
65 bool
66 ldns_resolver_debug(const ldns_resolver *r)
67 {
68 	return r->_debug;
69 }
70 
71 bool
72 ldns_resolver_dnsrch(const ldns_resolver *r)
73 {
74 	return r->_dnsrch;
75 }
76 
77 bool
78 ldns_resolver_fail(const ldns_resolver *r)
79 {
80 	return r->_fail;
81 }
82 
83 bool
84 ldns_resolver_defnames(const ldns_resolver *r)
85 {
86 	return r->_defnames;
87 }
88 
89 ldns_rdf *
90 ldns_resolver_domain(const ldns_resolver *r)
91 {
92 	return r->_domain;
93 }
94 
95 ldns_rdf **
96 ldns_resolver_searchlist(const ldns_resolver *r)
97 {
98 	return r->_searchlist;
99 }
100 
101 ldns_rdf **
102 ldns_resolver_nameservers(const ldns_resolver *r)
103 {
104 	return r->_nameservers;
105 }
106 
107 size_t
108 ldns_resolver_nameserver_count(const ldns_resolver *r)
109 {
110 	return r->_nameserver_count;
111 }
112 
113 bool
114 ldns_resolver_dnssec(const ldns_resolver *r)
115 {
116 	return r->_dnssec;
117 }
118 
119 bool
120 ldns_resolver_dnssec_cd(const ldns_resolver *r)
121 {
122 	return r->_dnssec_cd;
123 }
124 
125 ldns_rr_list *
126 ldns_resolver_dnssec_anchors(const ldns_resolver *r)
127 {
128     return r->_dnssec_anchors;
129 }
130 
131 bool
132 ldns_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 
158 bool
159 ldns_resolver_igntc(const ldns_resolver *r)
160 {
161 	return r->_igntc;
162 }
163 
164 bool
165 ldns_resolver_usevc(const ldns_resolver *r)
166 {
167 	return r->_usevc;
168 }
169 
170 size_t *
171 ldns_resolver_rtt(const ldns_resolver *r)
172 {
173 	return r->_rtt;
174 }
175 
176 size_t
177 ldns_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 
194 struct timeval
195 ldns_resolver_timeout(const ldns_resolver *r)
196 {
197 	return r->_timeout;
198 }
199 
200 char *
201 ldns_resolver_tsig_keyname(const ldns_resolver *r)
202 {
203 	return r->_tsig_keyname;
204 }
205 
206 char *
207 ldns_resolver_tsig_algorithm(const ldns_resolver *r)
208 {
209 	return r->_tsig_algorithm;
210 }
211 
212 char *
213 ldns_resolver_tsig_keydata(const ldns_resolver *r)
214 {
215 	return r->_tsig_keydata;
216 }
217 
218 bool
219 ldns_resolver_random(const ldns_resolver *r)
220 {
221 	return r->_random;
222 }
223 
224 size_t
225 ldns_resolver_searchlist_count(const ldns_resolver *r)
226 {
227 	return r->_searchlist_count;
228 }
229 
230 /* write */
231 void
232 ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
233 {
234 	r->_port = p;
235 }
236 
237 ldns_rdf *
238 ldns_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 
268 ldns_status
269 ldns_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 
315 ldns_status
316 ldns_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 
331 ldns_status
332 ldns_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 
353 void
354 ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
355 {
356 	        r->_edns_udp_size = s;
357 }
358 
359 void
360 ldns_resolver_set_recursive(ldns_resolver *r, bool re)
361 {
362 	r->_recursive = re;
363 }
364 
365 void
366 ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
367 {
368 	r->_dnssec = d;
369 }
370 
371 void
372 ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
373 {
374 	r->_dnssec_cd = d;
375 }
376 
377 void
378 ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
379 {
380   r->_dnssec_anchors = l;
381 }
382 
383 ldns_status
384 ldns_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 
400 void
401 ldns_resolver_set_igntc(ldns_resolver *r, bool i)
402 {
403 	r->_igntc = i;
404 }
405 
406 void
407 ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
408 {
409 	r->_usevc = vc;
410 }
411 
412 void
413 ldns_resolver_set_debug(ldns_resolver *r, bool d)
414 {
415 	r->_debug = d;
416 }
417 
418 void
419 ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
420 {
421 	r->_ip6 = ip6;
422 }
423 
424 void
425 ldns_resolver_set_fail(ldns_resolver *r, bool f)
426 {
427 	r->_fail =f;
428 }
429 
430 void
431 ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
432 {
433 	r->_searchlist_count = c;
434 }
435 
436 void
437 ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
438 {
439 	r->_nameserver_count = c;
440 }
441 
442 void
443 ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
444 {
445 	r->_dnsrch = d;
446 }
447 
448 void
449 ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
450 {
451 	r->_retry = retry;
452 }
453 
454 void
455 ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
456 {
457 	r->_retrans = retrans;
458 }
459 
460 void
461 ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
462 {
463 	r->_fallback = fallback;
464 }
465 
466 void
467 ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
468 {
469 	r->_nameservers = n;
470 }
471 
472 void
473 ldns_resolver_set_defnames(ldns_resolver *r, bool d)
474 {
475 	r->_defnames = d;
476 }
477 
478 void
479 ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
480 {
481 	r->_rtt = rtt;
482 }
483 
484 void
485 ldns_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 
501 void
502 ldns_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 
510 void
511 ldns_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 
523 void
524 ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
525 {
526 	r->_domain = d;
527 }
528 
529 void
530 ldns_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 
536 void
537 ldns_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 
558 void
559 ldns_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 
565 void
566 ldns_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 
572 void
573 ldns_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 
579 void
580 ldns_resolver_set_random(ldns_resolver *r, bool b)
581 {
582 	r->_random = b;
583 }
584 
585 /* more sophisticated functions */
586 ldns_resolver *
587 ldns_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 
643 ldns_status
644 ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
645 {
646 	return ldns_resolver_new_frm_fp_l(res, fp, NULL);
647 }
648 
649 ldns_status
650 ldns_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 
864 ldns_status
865 ldns_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 
894 void
895 ldns_resolver_free(ldns_resolver *res)
896 {
897 	LDNS_FREE(res);
898 }
899 
900 void
901 ldns_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 
945 ldns_pkt *
946 ldns_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 
981 ldns_pkt *
982 ldns_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 
1034 static size_t *
1035 ldns_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 
1051 static void
1052 ldns_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 
1062 ldns_status
1063 ldns_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 
1118 ldns_status
1119 ldns_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 
1167 ldns_status
1168 ldns_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 
1232 ldns_rr *
1233 ldns_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 		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 
1318 bool
1319 ldns_axfr_complete(const ldns_resolver *res)
1320 {
1321 	/* complete when soa count is 2? */
1322 	return res->_axfr_soa_count == 2;
1323 }
1324 
1325 ldns_pkt *
1326 ldns_axfr_last_pkt(const ldns_resolver *res)
1327 {
1328 	return res->_cur_axfr_pkt;
1329 }
1330 
1331 /* random isn't really that good */
1332 void
1333 ldns_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