xref: /dragonfly/contrib/ldns/resolver.c (revision d4ef6694)
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 	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 
275 ldns_status
276 ldns_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 
322 ldns_status
323 ldns_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 
338 ldns_status
339 ldns_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 
360 void
361 ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
362 {
363 	        r->_edns_udp_size = s;
364 }
365 
366 void
367 ldns_resolver_set_recursive(ldns_resolver *r, bool re)
368 {
369 	r->_recursive = re;
370 }
371 
372 void
373 ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
374 {
375 	r->_dnssec = d;
376 }
377 
378 void
379 ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
380 {
381 	r->_dnssec_cd = d;
382 }
383 
384 void
385 ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
386 {
387   r->_dnssec_anchors = l;
388 }
389 
390 ldns_status
391 ldns_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 
409 void
410 ldns_resolver_set_igntc(ldns_resolver *r, bool i)
411 {
412 	r->_igntc = i;
413 }
414 
415 void
416 ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
417 {
418 	r->_usevc = vc;
419 }
420 
421 void
422 ldns_resolver_set_debug(ldns_resolver *r, bool d)
423 {
424 	r->_debug = d;
425 }
426 
427 void
428 ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
429 {
430 	r->_ip6 = ip6;
431 }
432 
433 void
434 ldns_resolver_set_fail(ldns_resolver *r, bool f)
435 {
436 	r->_fail =f;
437 }
438 
439 void
440 ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
441 {
442 	r->_searchlist_count = c;
443 }
444 
445 void
446 ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
447 {
448 	r->_nameserver_count = c;
449 }
450 
451 void
452 ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
453 {
454 	r->_dnsrch = d;
455 }
456 
457 void
458 ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
459 {
460 	r->_retry = retry;
461 }
462 
463 void
464 ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
465 {
466 	r->_retrans = retrans;
467 }
468 
469 void
470 ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
471 {
472 	r->_fallback = fallback;
473 }
474 
475 void
476 ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
477 {
478 	r->_nameservers = n;
479 }
480 
481 void
482 ldns_resolver_set_defnames(ldns_resolver *r, bool d)
483 {
484 	r->_defnames = d;
485 }
486 
487 void
488 ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
489 {
490 	r->_rtt = rtt;
491 }
492 
493 void
494 ldns_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 
510 void
511 ldns_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 
519 void
520 ldns_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 
532 void
533 ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
534 {
535 	r->_domain = d;
536 }
537 
538 void
539 ldns_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 
545 void
546 ldns_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 
567 void
568 ldns_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 
574 void
575 ldns_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 
581 void
582 ldns_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 
588 void
589 ldns_resolver_set_random(ldns_resolver *r, bool b)
590 {
591 	r->_random = b;
592 }
593 
594 /* more sophisticated functions */
595 ldns_resolver *
596 ldns_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 
652 ldns_status
653 ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
654 {
655 	return ldns_resolver_new_frm_fp_l(res, fp, NULL);
656 }
657 
658 ldns_status
659 ldns_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 
874 ldns_status
875 ldns_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 
905 void
906 ldns_resolver_free(ldns_resolver *res)
907 {
908 	LDNS_FREE(res);
909 }
910 
911 void
912 ldns_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 
956 ldns_pkt *
957 ldns_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 
989 ldns_pkt *
990 ldns_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 
1039 static size_t *
1040 ldns_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 
1056 static void
1057 ldns_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 
1067 ldns_status
1068 ldns_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 
1123 ldns_status
1124 ldns_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 
1172 ldns_status
1173 ldns_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 
1239 ldns_rr *
1240 ldns_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 
1332 bool
1333 ldns_axfr_complete(const ldns_resolver *res)
1334 {
1335 	/* complete when soa count is 2? */
1336 	return res->_axfr_soa_count == 2;
1337 }
1338 
1339 ldns_pkt *
1340 ldns_axfr_last_pkt(const ldns_resolver *res)
1341 {
1342 	return res->_cur_axfr_pkt;
1343 }
1344 
1345 /* random isn't really that good */
1346 void
1347 ldns_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