resolver.c
Go to the documentation of this file.
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
25 {
26  return r->_port;
27 }
28 
29 uint16_t
31 {
32  return r->_edns_udp_size;
33 }
34 
35 uint8_t
37 {
38  return r->_retry;
39 }
40 
41 uint8_t
43 {
44  return r->_retrans;
45 }
46 
47 bool
49 {
50  return r->_fallback;
51 }
52 
53 uint8_t
55 {
56  return r->_ip6;
57 }
58 
59 bool
61 {
62  return r->_recursive;
63 }
64 
65 bool
67 {
68  return r->_debug;
69 }
70 
71 bool
73 {
74  return r->_dnsrch;
75 }
76 
77 bool
79 {
80  return r->_fail;
81 }
82 
83 bool
85 {
86  return r->_defnames;
87 }
88 
89 ldns_rdf *
91 {
92  return r->_domain;
93 }
94 
95 ldns_rdf **
97 {
98  return r->_searchlist;
99 }
100 
101 ldns_rdf **
103 {
104  return r->_nameservers;
105 }
106 
107 size_t
109 {
110  return r->_nameserver_count;
111 }
112 
113 bool
115 {
116  return r->_dnssec;
117 }
118 
119 bool
121 {
122  return r->_dnssec_cd;
123 }
124 
125 ldns_rr_list *
127 {
128  return r->_dnssec_anchors;
129 }
130 
131 bool
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
160 {
161  return r->_igntc;
162 }
163 
164 bool
166 {
167  return r->_usevc;
168 }
169 
170 size_t *
172 {
173  return r->_rtt;
174 }
175 
176 size_t
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
196 {
197  return r->_timeout;
198 }
199 
200 char *
202 {
203  return r->_tsig_keyname;
204 }
205 
206 char *
208 {
209  return r->_tsig_algorithm;
210 }
211 
212 char *
214 {
215  return r->_tsig_keydata;
216 }
217 
218 bool
220 {
221  return r->_random;
222 }
223 
224 size_t
226 {
227  return r->_searchlist_count;
228 }
229 
230 /* write */
231 void
233 {
234  r->_port = p;
235 }
236 
237 ldns_rdf *
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 
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 */
272  return pop;
273 }
274 
277 {
278  ldns_rdf **nameservers;
279  size_t ns_count;
280  size_t *rtt;
281 
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;
318  ldns_resolver_set_rtt(r, rtt);
319  return LDNS_STATUS_OK;
320 }
321 
324 {
325  ldns_rdf *address;
326  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
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 
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);
350  stat = LDNS_STATUS_ERR;
351  break;
352  }
353  }
354  return stat;
355  } else {
356  return LDNS_STATUS_ERR;
357  }
358 }
359 
360 void
362 {
363  r->_edns_udp_size = s;
364 }
365 
366 void
368 {
369  r->_recursive = re;
370 }
371 
372 void
374 {
375  r->_dnssec = d;
376 }
377 
378 void
380 {
381  r->_dnssec_cd = d;
382 }
383 
384 void
386 {
387  r->_dnssec_anchors = l;
388 }
389 
392 {
393  ldns_rr_list * trust_anchors;
394 
395  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
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
411 {
412  r->_igntc = i;
413 }
414 
415 void
417 {
418  r->_usevc = vc;
419 }
420 
421 void
423 {
424  r->_debug = d;
425 }
426 
427 void
429 {
430  r->_ip6 = ip6;
431 }
432 
433 void
435 {
436  r->_fail =f;
437 }
438 
439 void
441 {
442  r->_searchlist_count = c;
443 }
444 
445 void
447 {
448  r->_nameserver_count = c;
449 }
450 
451 void
453 {
454  r->_dnsrch = d;
455 }
456 
457 void
459 {
460  r->_retry = retry;
461 }
462 
463 void
465 {
466  r->_retrans = retrans;
467 }
468 
469 void
471 {
472  r->_fallback = fallback;
473 }
474 
475 void
477 {
478  r->_nameservers = n;
479 }
480 
481 void
483 {
484  r->_defnames = d;
485 }
486 
487 void
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
512 {
513  size_t c;
514 
517 }
518 
519 void
521 {
522  size_t c;
523 
525  if (c == 0) {
526  return;
527  } else {
529  }
530 }
531 
532 void
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
547 {
548  ldns_rdf **searchlist;
549  size_t list_count;
550 
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
569 {
571  r->_tsig_keyname = strdup(tsig_keyname);
572 }
573 
574 void
576 {
578  r->_tsig_algorithm = strdup(tsig_algorithm);
579 }
580 
581 void
583 {
585  r->_tsig_keydata = strdup(tsig_keydata);
586 }
587 
588 void
590 {
591  r->_random = b;
592 }
593 
594 /* more sophisticated functions */
597 {
598  ldns_resolver *r;
599 
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 */
614  ldns_resolver_set_domain(r, NULL);
615  ldns_resolver_set_defnames(r, false);
619  ldns_resolver_set_fail(r, false);
621  ldns_resolver_set_dnssec(r, false);
622  ldns_resolver_set_dnssec_cd(r, false);
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 
635 
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 
654 {
655  return ldns_resolver_new_frm_fp_l(res, fp, NULL);
656 }
657 
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;
744  /* default domain dname */
745  gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
746  if (gtr == 0) {
748  }
749  if(word[0] == '#') {
750  expect = LDNS_RESOLV_KEYWORD;
751  continue;
752  }
754  if (!tmp) {
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;
764  /* NS aaaa or a record */
765  gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
766  if (gtr == 0) {
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  }
779  if (!tmp) {
780  /* try ip4 */
782  }
783  /* could not parse it, exit */
784  if (!tmp) {
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);
796  if(!b) {
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);
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  }
815  if (!tmp) {
817  ldns_buffer_free(b);
819  }
820 
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;
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) {
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 {
870  return LDNS_STATUS_NULL;
871  }
872 }
873 
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 {
899  return LDNS_STATUS_NULL;
900  }
901  }
902  return s;
903 }
904 
905 void
907 {
908  LDNS_FREE(res);
909 }
910 
911 void
913 {
914  size_t i;
915 
916  if (res) {
917  if (res->_searchlist) {
918  for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
920  }
921  LDNS_FREE(res->_searchlist);
922  }
923  if (res->_nameservers) {
924  for (i = 0; i < res->_nameserver_count; i++) {
926  }
927  LDNS_FREE(res->_nameservers);
928  }
929  if (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) {
940  }
941 
942  if (res->_cur_axfr_pkt) {
944  }
945 
946  if (res->_rtt) {
947  LDNS_FREE(res->_rtt);
948  }
949  if (res->_dnssec_anchors) {
951  }
952  LDNS_FREE(res);
953  }
954 }
955 
956 ldns_pkt *
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) {
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 *
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
1048  memcpy(new_rtt, old_rtt, sizeof(size_t)
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 
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) */
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 
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) {
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) {
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 
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  */
1214 #ifdef HAVE_SSL
1215  status = ldns_pkt_tsig_sign(query_pkt,
1218  300, ldns_resolver_tsig_algorithm(r), NULL);
1219  if (status != LDNS_STATUS_OK) {
1220  ldns_pkt_free(query_pkt);
1222  }
1223 #else
1224  ldns_pkt_free(query_pkt);
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 *
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) {
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
1334 {
1335  /* complete when soa count is 2? */
1336  return res->_axfr_soa_count == 2;
1337 }
1338 
1339 ldns_pkt *
1341 {
1342  return res->_cur_axfr_pkt;
1343 }
1344 
1345 /* random isn't really that good */
1346 void
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++) {
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  }
1368 }
1369