Merge branch 'vendor/BYACC'
[dragonfly.git] / contrib / ldns / resolver.c
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