Merge branch 'vendor/LIBARCHIVE'
[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         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