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 ldns_rdf *
31 {
32  return r->_source;
33 }
34 
35 uint16_t
37 {
38  return r->_edns_udp_size;
39 }
40 
41 uint8_t
43 {
44  return r->_retry;
45 }
46 
47 uint8_t
49 {
50  return r->_retrans;
51 }
52 
53 bool
55 {
56  return r->_fallback;
57 }
58 
59 uint8_t
61 {
62  return r->_ip6;
63 }
64 
65 bool
67 {
68  return r->_recursive;
69 }
70 
71 bool
73 {
74  return r->_debug;
75 }
76 
77 bool
79 {
80  return r->_dnsrch;
81 }
82 
83 bool
85 {
86  return r->_fail;
87 }
88 
89 bool
91 {
92  return r->_defnames;
93 }
94 
95 ldns_rdf *
97 {
98  return r->_domain;
99 }
100 
101 ldns_rdf **
103 {
104  return r->_searchlist;
105 }
106 
107 ldns_rdf **
109 {
110  return r->_nameservers;
111 }
112 
113 size_t
115 {
116  return r->_nameserver_count;
117 }
118 
119 bool
121 {
122  return r->_dnssec;
123 }
124 
125 bool
127 {
128  return r->_dnssec_cd;
129 }
130 
131 ldns_rr_list *
133 {
134  return r->_dnssec_anchors;
135 }
136 
137 bool
139 {
140  size_t i;
141  bool result = false;
142 
143  ldns_rr_list * trust_anchors;
144  ldns_rr * cur_rr;
145 
146  if (!r || !keys) { return false; }
147 
148  trust_anchors = ldns_resolver_dnssec_anchors(r);
149 
150  if (!trust_anchors) { return false; }
151 
152  for (i = 0; i < ldns_rr_list_rr_count(keys); i++) {
153 
154  cur_rr = ldns_rr_list_rr(keys, i);
155  if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
156  if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
157  result = true;
158  }
159  }
160 
161  return result;
162 }
163 
164 bool
166 {
167  return r->_igntc;
168 }
169 
170 bool
172 {
173  return r->_usevc;
174 }
175 
176 size_t *
178 {
179  return r->_rtt;
180 }
181 
182 size_t
184 {
185  size_t *rtt;
186 
187  assert(r != NULL);
188 
189  rtt = ldns_resolver_rtt(r);
190 
191  if (pos >= ldns_resolver_nameserver_count(r)) {
192  /* error ?*/
193  return 0;
194  } else {
195  return rtt[pos];
196  }
197 
198 }
199 
200 struct timeval
202 {
203  return r->_timeout;
204 }
205 
206 const char *
208 {
209  return r->_tsig_keyname;
210 }
211 
212 const char *
214 {
215  return r->_tsig_algorithm;
216 }
217 
218 const char *
220 {
221  return r->_tsig_keydata;
222 }
223 
224 bool
226 {
227  return r->_random;
228 }
229 
230 size_t
232 {
233  return r->_searchlist_count;
234 }
235 
236 /* write */
237 void
239 {
240  r->_port = p;
241 }
242 
243 void
245 {
246  r->_source = s;
247 }
248 
249 ldns_rdf *
251 {
252  ldns_rdf **nameservers;
253  ldns_rdf *pop;
254  size_t ns_count;
255  size_t *rtt;
256 
257  assert(r != NULL);
258 
259  ns_count = ldns_resolver_nameserver_count(r);
260  nameservers = ldns_resolver_nameservers(r);
261  rtt = ldns_resolver_rtt(r);
262  if (ns_count == 0 || !nameservers) {
263  return NULL;
264  }
265 
266  pop = nameservers[ns_count - 1];
267 
268  if (ns_count == 1) {
269  LDNS_FREE(nameservers);
270  LDNS_FREE(rtt);
271 
273  ldns_resolver_set_rtt(r, NULL);
274  } else {
275  nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *,
276  (ns_count - 1));
277  rtt = LDNS_XREALLOC(rtt, size_t, (ns_count - 1));
278 
279  ldns_resolver_set_nameservers(r, nameservers);
280  ldns_resolver_set_rtt(r, rtt);
281  }
282  /* decr the count */
284  return pop;
285 }
286 
289 {
290  ldns_rdf **nameservers;
291  size_t ns_count;
292  size_t *rtt;
293 
296  return LDNS_STATUS_ERR;
297  }
298 
299  ns_count = ldns_resolver_nameserver_count(r);
300  nameservers = ldns_resolver_nameservers(r);
301  rtt = ldns_resolver_rtt(r);
302 
303  /* make room for the next one */
304  if (ns_count == 0) {
305  nameservers = LDNS_XMALLOC(ldns_rdf *, 1);
306  } else {
307  nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1));
308  }
309  if(!nameservers)
310  return LDNS_STATUS_MEM_ERR;
311 
312  /* set the new value in the resolver */
313  ldns_resolver_set_nameservers(r, nameservers);
314 
315  /* don't forget the rtt */
316  if (ns_count == 0) {
317  rtt = LDNS_XMALLOC(size_t, 1);
318  } else {
319  rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1));
320  }
321  if(!rtt)
322  return LDNS_STATUS_MEM_ERR;
323 
324  /* slide n in its slot. */
325  /* we clone it here, because then we can free the original
326  * rr's where it stood */
327  nameservers[ns_count] = ldns_rdf_clone(n);
328  rtt[ns_count] = LDNS_RESOLV_RTT_MIN;
330  ldns_resolver_set_rtt(r, rtt);
331  return LDNS_STATUS_OK;
332 }
333 
336 {
337  ldns_rdf *address;
338  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A &&
340  return LDNS_STATUS_ERR;
341  }
342  address = ldns_rr_rdf(rr, 0); /* extract the ip number */
343  if (address) {
344  return ldns_resolver_push_nameserver(r, address);
345  } else {
346  return LDNS_STATUS_ERR;
347  }
348 }
349 
352 {
353  ldns_rr *rr;
354  ldns_status stat;
355  size_t i;
356 
357  stat = LDNS_STATUS_OK;
358  if (rrlist) {
359  for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) {
360  rr = ldns_rr_list_rr(rrlist, i);
362  stat = LDNS_STATUS_ERR;
363  break;
364  }
365  }
366  return stat;
367  } else {
368  return LDNS_STATUS_ERR;
369  }
370 }
371 
372 void
374 {
375  r->_edns_udp_size = s;
376 }
377 
378 void
380 {
381  r->_recursive = re;
382 }
383 
384 void
386 {
387  r->_dnssec = d;
388 }
389 
390 void
392 {
393  r->_dnssec_cd = d;
394 }
395 
396 void
398 {
399  r->_dnssec_anchors = l;
400 }
401 
404 {
405  ldns_rr_list * trust_anchors;
406 
407  if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY &&
409 
410  return LDNS_STATUS_ERR;
411  }
412 
413  if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
414  trust_anchors = ldns_rr_list_new();
415  ldns_resolver_set_dnssec_anchors(r, trust_anchors);
416  }
417 
418  return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
419 }
420 
421 void
423 {
424  r->_igntc = i;
425 }
426 
427 void
429 {
430  r->_usevc = vc;
431 }
432 
433 void
435 {
436  r->_debug = d;
437 }
438 
439 void
441 {
442  r->_ip6 = ip6;
443 }
444 
445 void
447 {
448  r->_fail =f;
449 }
450 
451 static void
452 ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c)
453 {
454  r->_searchlist_count = c;
455 }
456 
457 void
459 {
460  r->_nameserver_count = c;
461 }
462 
463 void
465 {
466  r->_dnsrch = d;
467 }
468 
469 void
471 {
472  r->_retry = retry;
473 }
474 
475 void
477 {
478  r->_retrans = retrans;
479 }
480 
481 void
483 {
484  r->_fallback = fallback;
485 }
486 
487 void
489 {
490  r->_nameservers = n;
491 }
492 
493 void
495 {
496  r->_defnames = d;
497 }
498 
499 void
501 {
502  r->_rtt = rtt;
503 }
504 
505 void
506 ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
507 {
508  size_t *rtt;
509 
510  assert(r != NULL);
511 
512  rtt = ldns_resolver_rtt(r);
513 
514  if (pos >= ldns_resolver_nameserver_count(r)) {
515  /* error ?*/
516  } else {
517  rtt[pos] = value;
518  }
519 
520 }
521 
522 void
524 {
525  size_t c;
526 
529 }
530 
531 void
533 {
534  size_t c;
535 
537  if (c == 0) {
538  return;
539  } else {
541  }
542 }
543 
544 void
546 {
547  r->_domain = d;
548 }
549 
550 void
551 ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
552 {
553  r->_timeout.tv_sec = timeout.tv_sec;
554  r->_timeout.tv_usec = timeout.tv_usec;
555 }
556 
557 void
559 {
560  ldns_rdf **searchlist;
561  size_t list_count;
562 
564  return;
565  }
566 
567  list_count = ldns_resolver_searchlist_count(r);
568  searchlist = ldns_resolver_searchlist(r);
569 
570  searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1));
571  if (searchlist) {
572  r->_searchlist = searchlist;
573 
574  searchlist[list_count] = ldns_rdf_clone(d);
575  ldns_resolver_set_searchlist_count(r, list_count + 1);
576  } /* no way to report mem err */
577 }
578 
579 void
580 ldns_resolver_set_tsig_keyname(ldns_resolver *r, const char *tsig_keyname)
581 {
583  r->_tsig_keyname = strdup(tsig_keyname);
584 }
585 
586 void
587 ldns_resolver_set_tsig_algorithm(ldns_resolver *r, const char *tsig_algorithm)
588 {
590  r->_tsig_algorithm = strdup(tsig_algorithm);
591 }
592 
593 void
594 ldns_resolver_set_tsig_keydata(ldns_resolver *r, const char *tsig_keydata)
595 {
597  r->_tsig_keydata = strdup(tsig_keydata);
598 }
599 
600 void
602 {
603  r->_random = b;
604 }
605 
606 /* more sophisticated functions */
609 {
610  ldns_resolver *r;
611 
613  if (!r) {
614  return NULL;
615  }
616 
617  r->_searchlist = NULL;
618  r->_nameservers = NULL;
619  r->_rtt = NULL;
620 
621  /* defaults are filled out */
622  ldns_resolver_set_searchlist_count(r, 0);
626  ldns_resolver_set_domain(r, NULL);
627  ldns_resolver_set_defnames(r, false);
631  ldns_resolver_set_fail(r, false);
633  ldns_resolver_set_dnssec(r, false);
634  ldns_resolver_set_dnssec_cd(r, false);
637  ldns_resolver_set_igntc(r, false);
638  ldns_resolver_set_recursive(r, false);
639  ldns_resolver_set_dnsrch(r, true);
640  ldns_resolver_set_source(r, NULL);
642 
643  /* randomize the nameserver to be queried
644  * when there are multiple
645  */
646  ldns_resolver_set_random(r, true);
647 
649 
651  r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC;
652 
653  r->_socket = -1;
654  r->_axfr_soa_count = 0;
655  r->_axfr_i = 0;
656  r->_cur_axfr_pkt = NULL;
657 
658  r->_tsig_keyname = NULL;
659  r->_tsig_keydata = NULL;
660  r->_tsig_algorithm = NULL;
661  return r;
662 }
663 
666 {
667  ldns_resolver *dst;
668  size_t i;
669 
670  assert(src != NULL);
671 
672  if (!(dst = LDNS_MALLOC(ldns_resolver))) return NULL;
673  (void) memcpy(dst, src, sizeof(ldns_resolver));
674 
675  if (dst->_searchlist_count == 0)
676  dst->_searchlist = NULL;
677  else {
678  if (!(dst->_searchlist =
680  goto error;
681  for (i = 0; i < dst->_searchlist_count; i++)
682  if (!(dst->_searchlist[i] =
683  ldns_rdf_clone(src->_searchlist[i]))) {
684  dst->_searchlist_count = i;
685  goto error_searchlist;
686  }
687  }
688  if (dst->_nameserver_count == 0) {
689  dst->_nameservers = NULL;
690  dst->_rtt = NULL;
691  } else {
692  if (!(dst->_nameservers =
694  goto error_searchlist;
695  for (i = 0; i < dst->_nameserver_count; i++)
696  if (!(dst->_nameservers[i] =
697  ldns_rdf_clone(src->_nameservers[i]))) {
698  dst->_nameserver_count = i;
699  goto error_nameservers;
700  }
701  if (!(dst->_rtt =
702  LDNS_XMALLOC(size_t, dst->_nameserver_count)))
703  goto error_nameservers;
704  (void) memcpy(dst->_rtt, src->_rtt,
705  sizeof(size_t) * dst->_nameserver_count);
706  }
707  if (dst->_domain && (!(dst->_domain = ldns_rdf_clone(src->_domain))))
708  goto error_rtt;
709 
710  if (dst->_tsig_keyname &&
711  (!(dst->_tsig_keyname = strdup(src->_tsig_keyname))))
712  goto error_domain;
713 
714  if (dst->_tsig_keydata &&
715  (!(dst->_tsig_keydata = strdup(src->_tsig_keydata))))
716  goto error_tsig_keyname;
717 
718  if (dst->_tsig_algorithm &&
719  (!(dst->_tsig_algorithm = strdup(src->_tsig_algorithm))))
720  goto error_tsig_keydata;
721 
722  if (dst->_cur_axfr_pkt &&
723  (!(dst->_cur_axfr_pkt = ldns_pkt_clone(src->_cur_axfr_pkt))))
724  goto error_tsig_algorithm;
725 
726  if (dst->_dnssec_anchors &&
728  goto error_cur_axfr_pkt;
729 
730  return dst;
731 
732 error_cur_axfr_pkt:
734 error_tsig_algorithm:
736 error_tsig_keydata:
737  LDNS_FREE(dst->_tsig_keydata);
738 error_tsig_keyname:
739  LDNS_FREE(dst->_tsig_keyname);
740 error_domain:
742 error_rtt:
743  LDNS_FREE(dst->_rtt);
744 error_nameservers:
745  for (i = 0; i < dst->_nameserver_count; i++)
747  LDNS_FREE(dst->_nameservers);
748 error_searchlist:
749  for (i = 0; i < dst->_searchlist_count; i++)
751  LDNS_FREE(dst->_searchlist);
752 error:
753  LDNS_FREE(dst);
754  return NULL;
755 }
756 
757 
760 {
761  return ldns_resolver_new_frm_fp_l(res, fp, NULL);
762 }
763 
765 ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
766 {
767  ldns_resolver *r = NULL;
768  const char *keyword[LDNS_RESOLV_KEYWORDS];
769  char word[LDNS_MAX_LINELEN + 1];
770  int8_t expect;
771  uint8_t i;
772  ldns_rdf *tmp;
773 #ifdef HAVE_SSL
774  ldns_rr *tmp_rr;
775 #endif
776  ssize_t gtr, bgtr;
777  ldns_buffer *b;
778  int lnr = 0, oldline;
779  FILE* myfp = fp;
780  if(!line_nr) line_nr = &lnr;
781 
782  if(!fp) {
783  myfp = fopen(LDNS_RESOLV_CONF, "r");
784  if(!myfp)
785  return LDNS_STATUS_FILE_ERR;
786  }
787 
788  /* do this better
789  * expect =
790  * 0: keyword
791  * 1: default domain dname
792  * 2: NS aaaa or a record
793  */
794 
795  /* recognized keywords */
796  keyword[LDNS_RESOLV_NAMESERVER] = "nameserver";
797  keyword[LDNS_RESOLV_DEFDOMAIN] = "domain";
798  keyword[LDNS_RESOLV_SEARCH] = "search";
799  /* these two are read but not used atm TODO */
800  keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
801  keyword[LDNS_RESOLV_OPTIONS] = "options";
802  keyword[LDNS_RESOLV_ANCHOR] = "anchor";
803 
804  r = ldns_resolver_new();
805  if (!r) {
806  if(!fp) fclose(myfp);
807  return LDNS_STATUS_MEM_ERR;
808  }
809 
810  gtr = 1;
811  word[0] = 0;
812  oldline = *line_nr;
813  expect = LDNS_RESOLV_KEYWORD;
814  while (gtr > 0) {
815  /* check comments */
816  if (word[0] == '#') {
817  word[0]='x';
818  if(oldline == *line_nr) {
819  /* skip until end of line */
820  int c;
821  do {
822  c = fgetc(myfp);
823  } while(c != EOF && c != '\n');
824  if(c=='\n') (*line_nr)++;
825  }
826  /* and read next to prepare for further parsing */
827  oldline = *line_nr;
828  continue;
829  }
830  oldline = *line_nr;
831  switch(expect) {
832  case LDNS_RESOLV_KEYWORD:
833  /* keyword */
834  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
835  if (gtr != 0) {
836  if(word[0] == '#') continue;
837  for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) {
838  if (strcasecmp(keyword[i], word) == 0) {
839  /* chosen the keyword and
840  * expect values carefully
841  */
842  expect = i;
843  break;
844  }
845  }
846  /* no keyword recognized */
847  if (expect == LDNS_RESOLV_KEYWORD) {
848  /* skip line */
849  /*
850  ldns_resolver_deep_free(r);
851  if(!fp) fclose(myfp);
852  return LDNS_STATUS_SYNTAX_KEYWORD_ERR;
853  */
854  }
855  }
856  break;
858  /* default domain dname */
859  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
860  if (gtr == 0) {
861  if(!fp) fclose(myfp);
864  }
865  if(word[0] == '#') {
866  expect = LDNS_RESOLV_KEYWORD;
867  continue;
868  }
870  if (!tmp) {
871  if(!fp) fclose(myfp);
874  }
875 
876  /* DOn't free, because we copy the pointer */
877  ldns_resolver_set_domain(r, tmp);
878  expect = LDNS_RESOLV_KEYWORD;
879  break;
881  /* NS aaaa or a record */
882  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
883  if (gtr == 0) {
884  if(!fp) fclose(myfp);
887  }
888  if(word[0] == '#') {
889  expect = LDNS_RESOLV_KEYWORD;
890  continue;
891  }
892  if(strchr(word, '%')) {
893  /* snip off interface labels,
894  * fe80::222:19ff:fe31:4222%eth0 */
895  strchr(word, '%')[0]=0;
896  }
898  if (!tmp) {
899  /* try ip4 */
901  }
902  /* could not parse it, exit */
903  if (!tmp) {
905  if(!fp) fclose(myfp);
906  return LDNS_STATUS_SYNTAX_ERR;
907  }
908  (void)ldns_resolver_push_nameserver(r, tmp);
909  ldns_rdf_deep_free(tmp);
910  expect = LDNS_RESOLV_KEYWORD;
911  break;
912  case LDNS_RESOLV_SEARCH:
913  /* search list domain dname */
914  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
916  if(!b) {
918  if(!fp) fclose(myfp);
919  return LDNS_STATUS_MEM_ERR;
920  }
921 
922  ldns_buffer_new_frm_data(b, word, (size_t) gtr);
923  if(ldns_buffer_status(b) != LDNS_STATUS_OK) {
924  LDNS_FREE(b);
926  if(!fp) fclose(myfp);
927  return LDNS_STATUS_MEM_ERR;
928  }
929  bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1);
930  while (bgtr > 0) {
931  gtr -= bgtr;
932  if(word[0] == '#') {
933  expect = LDNS_RESOLV_KEYWORD;
934  break;
935  }
937  if (!tmp) {
939  ldns_buffer_free(b);
940  if(!fp) fclose(myfp);
942  }
943 
945 
946  ldns_rdf_deep_free(tmp);
947  bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL,
948  (size_t) gtr + 1);
949  }
950  ldns_buffer_free(b);
951  if (expect != LDNS_RESOLV_KEYWORD) {
952  gtr = 1;
953  expect = LDNS_RESOLV_KEYWORD;
954  }
955  break;
957  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
958  /* sortlist not implemented atm */
959  expect = LDNS_RESOLV_KEYWORD;
960  break;
961  case LDNS_RESOLV_OPTIONS:
962  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr);
963  /* options not implemented atm */
964  expect = LDNS_RESOLV_KEYWORD;
965  break;
966  case LDNS_RESOLV_ANCHOR:
967  /* a file containing a DNSSEC trust anchor */
968  gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr);
969  if (gtr == 0) {
971  if(!fp) fclose(myfp);
973  }
974  if(word[0] == '#') {
975  expect = LDNS_RESOLV_KEYWORD;
976  continue;
977  }
978 
979 #ifdef HAVE_SSL
980  tmp_rr = ldns_read_anchor_file(word);
981  (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr);
982  ldns_rr_free(tmp_rr);
983 #endif
984  expect = LDNS_RESOLV_KEYWORD;
985  break;
986  }
987  }
988 
989  if(!fp)
990  fclose(myfp);
991 
992  if (res) {
993  *res = r;
994  return LDNS_STATUS_OK;
995  } else {
997  return LDNS_STATUS_NULL;
998  }
999 }
1000 
1002 ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
1003 {
1004  ldns_resolver *r;
1005  FILE *fp;
1006  ldns_status s;
1007 
1008  if (!filename) {
1009  fp = fopen(LDNS_RESOLV_CONF, "r");
1010 
1011  } else {
1012  fp = fopen(filename, "r");
1013  }
1014  if (!fp) {
1015  return LDNS_STATUS_FILE_ERR;
1016  }
1017 
1018  s = ldns_resolver_new_frm_fp(&r, fp);
1019  fclose(fp);
1020  if (s == LDNS_STATUS_OK) {
1021  if (res) {
1022  *res = r;
1023  return LDNS_STATUS_OK;
1024  } else {
1025  ldns_resolver_free(r);
1026  return LDNS_STATUS_NULL;
1027  }
1028  }
1029  return s;
1030 }
1031 
1032 void
1034 {
1035  LDNS_FREE(res);
1036 }
1037 
1038 void
1040 {
1041  size_t i;
1042 
1043  if (res) {
1044  close_socket(res->_socket);
1045 
1046  if (res->_searchlist) {
1047  for (i = 0; i < ldns_resolver_searchlist_count(res); i++) {
1049  }
1050  LDNS_FREE(res->_searchlist);
1051  }
1052  if (res->_nameservers) {
1053  for (i = 0; i < res->_nameserver_count; i++) {
1055  }
1056  LDNS_FREE(res->_nameservers);
1057  }
1058  if (ldns_resolver_domain(res)) {
1060  }
1061  if (res->_tsig_keyname) {
1062  LDNS_FREE(res->_tsig_keyname);
1063  }
1064  if (res->_tsig_keydata) {
1065  LDNS_FREE(res->_tsig_keydata);
1066  }
1067  if (res->_tsig_algorithm) {
1068  LDNS_FREE(res->_tsig_algorithm);
1069  }
1070 
1071  if (res->_cur_axfr_pkt) {
1073  }
1074 
1075  if (res->_rtt) {
1076  LDNS_FREE(res->_rtt);
1077  }
1078  if (res->_dnssec_anchors) {
1080  }
1081  LDNS_FREE(res);
1082  }
1083 }
1084 
1087  ldns_resolver *r, const ldns_rdf *name,
1088  ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1089 {
1090  ldns_rdf *new_name;
1091  ldns_rdf **search_list;
1092  size_t i;
1094  ldns_rdf root_dname = { 1, LDNS_RDF_TYPE_DNAME, (void *)"" };
1095 
1096  if (ldns_dname_absolute(name)) {
1097  /* query as-is */
1098  return ldns_resolver_query_status(pkt, r, name, t, c, flags);
1099  } else if (ldns_resolver_dnsrch(r)) {
1100  search_list = ldns_resolver_searchlist(r);
1101  for (i = 0; i <= ldns_resolver_searchlist_count(r); i++) {
1102  if (i == ldns_resolver_searchlist_count(r)) {
1103  new_name = ldns_dname_cat_clone(name,
1104  &root_dname);
1105  } else {
1106  new_name = ldns_dname_cat_clone(name,
1107  search_list[i]);
1108  }
1109 
1110  s = ldns_resolver_query_status(pkt, r,
1111  new_name, t, c, flags);
1112  ldns_rdf_deep_free(new_name);
1113 
1114  if (pkt && *pkt) {
1115  if (s == LDNS_STATUS_OK &&
1116  ldns_pkt_get_rcode(*pkt) ==
1118 
1119  return LDNS_STATUS_OK;
1120  }
1121  ldns_pkt_free(*pkt);
1122  *pkt = NULL;
1123  }
1124  }
1125  }
1126  return s;
1127 }
1128 
1129 ldns_pkt *
1131  ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1132 {
1133  ldns_pkt* pkt = NULL;
1135  name, t, c, flags) != LDNS_STATUS_OK) {
1136  ldns_pkt_free(pkt);
1137  return NULL;
1138  }
1139  return pkt;
1140 }
1141 
1144  ldns_resolver *r, const ldns_rdf *name,
1145  ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1146 {
1147  ldns_rdf *newname;
1148  ldns_status status;
1149 
1151  return ldns_resolver_send(pkt, r, name, t, c, flags);
1152  }
1153 
1154  newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r));
1155  if (!newname) {
1156  return LDNS_STATUS_MEM_ERR;
1157  }
1158  status = ldns_resolver_send(pkt, r, newname, t, c, flags);
1159  ldns_rdf_free(newname);
1160  return status;
1161 }
1162 
1163 ldns_pkt *
1165  ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1166 {
1167  ldns_pkt* pkt = NULL;
1169  name, t, c, flags) != LDNS_STATUS_OK) {
1170  ldns_pkt_free(pkt);
1171  return NULL;
1172  }
1173  return pkt;
1174 }
1175 
1176 static size_t *
1177 ldns_resolver_backup_rtt(ldns_resolver *r)
1178 {
1179  size_t *new_rtt;
1180  size_t *old_rtt = ldns_resolver_rtt(r);
1181 
1182  if (old_rtt && ldns_resolver_nameserver_count(r)) {
1183  new_rtt = LDNS_XMALLOC(size_t
1185  if (!new_rtt) return NULL;
1186  memcpy(new_rtt, old_rtt, sizeof(size_t)
1188  ldns_resolver_set_rtt(r, new_rtt);
1189  return old_rtt;
1190  }
1191  return NULL;
1192 }
1193 
1194 static void
1195 ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt)
1196 {
1197  size_t *cur_rtt = ldns_resolver_rtt(r);
1198 
1199  if (cur_rtt) {
1200  LDNS_FREE(cur_rtt);
1201  }
1202  ldns_resolver_set_rtt(r, old_rtt);
1203 }
1204 
1207  ldns_pkt *query_pkt)
1208 {
1209  ldns_pkt *answer_pkt = NULL;
1210  ldns_status stat = LDNS_STATUS_OK;
1211  size_t *rtt;
1212 
1213  stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt);
1214  if (stat != LDNS_STATUS_OK) {
1215  if(answer_pkt) {
1216  ldns_pkt_free(answer_pkt);
1217  answer_pkt = NULL;
1218  }
1219  } else {
1220  /* if tc=1 fall back to EDNS and/or TCP */
1221  /* check for tcp first (otherwise we don't care about tc=1) */
1223  if (ldns_pkt_tc(answer_pkt)) {
1224  /* was EDNS0 set? */
1225  if (ldns_pkt_edns_udp_size(query_pkt) == 0) {
1226  ldns_pkt_set_edns_udp_size(query_pkt
1227  , 4096);
1228  ldns_pkt_free(answer_pkt);
1229  answer_pkt = NULL;
1230  /* Nameservers should not become
1231  * unreachable because fragments are
1232  * dropped (network error). We might
1233  * still have success with TCP.
1234  * Therefore maintain reachability
1235  * statuses of the nameservers by
1236  * backup and restore the rtt list.
1237  */
1238  rtt = ldns_resolver_backup_rtt(r);
1239  stat = ldns_send(&answer_pkt, r
1240  , query_pkt);
1241  ldns_resolver_restore_rtt(r, rtt);
1242  }
1243  /* either way, if it is still truncated, use TCP */
1244  if (stat != LDNS_STATUS_OK ||
1245  ldns_pkt_tc(answer_pkt)) {
1246  ldns_resolver_set_usevc(r, true);
1247  ldns_pkt_free(answer_pkt);
1248  answer_pkt = NULL;
1249  stat = ldns_send(&answer_pkt, r, query_pkt);
1250  ldns_resolver_set_usevc(r, false);
1251  }
1252  }
1253  }
1254  }
1255 
1256  if (answer && answer_pkt) {
1257  *answer = answer_pkt;
1258  }
1259 
1260  return stat;
1261 }
1262 
1265  const ldns_rdf *name, ldns_rr_type t,
1266  ldns_rr_class c, uint16_t flags)
1267 {
1268  struct timeval now;
1269  ldns_rr* soa = NULL;
1270 
1271  /* prepare a question pkt from the parameters
1272  * and then send this */
1273  if (t == LDNS_RR_TYPE_IXFR) {
1274  ldns_rdf *owner_rdf;
1275  ldns_rdf *mname_rdf;
1276  ldns_rdf *rname_rdf;
1277  ldns_rdf *serial_rdf;
1278  ldns_rdf *refresh_rdf;
1279  ldns_rdf *retry_rdf;
1280  ldns_rdf *expire_rdf;
1281  ldns_rdf *minimum_rdf;
1282  soa = ldns_rr_new();
1283 
1284  if (!soa) {
1285  return LDNS_STATUS_ERR;
1286  }
1287  owner_rdf = ldns_rdf_clone(name);
1288  if (!owner_rdf) {
1289  ldns_rr_free(soa);
1290  return LDNS_STATUS_ERR;
1291  }
1292  ldns_rr_set_owner(soa, owner_rdf);
1294  ldns_rr_set_class(soa, c);
1295  ldns_rr_set_question(soa, false);
1296  if (ldns_str2rdf_dname(&mname_rdf, ".") != LDNS_STATUS_OK) {
1297  ldns_rr_free(soa);
1298  return LDNS_STATUS_ERR;
1299  } else ldns_rr_push_rdf(soa, mname_rdf);
1300  if (ldns_str2rdf_dname(&rname_rdf, ".") != LDNS_STATUS_OK) {
1301  ldns_rr_free(soa);
1302  return LDNS_STATUS_ERR;
1303  } else ldns_rr_push_rdf(soa, rname_rdf);
1305  if (!serial_rdf) {
1306  ldns_rr_free(soa);
1307  return LDNS_STATUS_ERR;
1308  } else ldns_rr_push_rdf(soa, serial_rdf);
1309  refresh_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1310  if (!refresh_rdf) {
1311  ldns_rr_free(soa);
1312  return LDNS_STATUS_ERR;
1313  } else ldns_rr_push_rdf(soa, refresh_rdf);
1315  if (!retry_rdf) {
1316  ldns_rr_free(soa);
1317  return LDNS_STATUS_ERR;
1318  } else ldns_rr_push_rdf(soa, retry_rdf);
1319  expire_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1320  if (!expire_rdf) {
1321  ldns_rr_free(soa);
1322  return LDNS_STATUS_ERR;
1323  } else ldns_rr_push_rdf(soa, expire_rdf);
1324  minimum_rdf = ldns_native2rdf_int32(LDNS_RDF_TYPE_INT32, 0);
1325  if (!minimum_rdf) {
1326  ldns_rr_free(soa);
1327  return LDNS_STATUS_ERR;
1328  } else ldns_rr_push_rdf(soa, minimum_rdf);
1329 
1330  *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name),
1331  c, flags, soa);
1332  } else {
1333  *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags);
1334  }
1335  if (!*query_pkt) {
1336  ldns_rr_free(soa);
1337  return LDNS_STATUS_ERR;
1338  }
1339 
1340  /* set DO bit if necessary */
1341  if (ldns_resolver_dnssec(r)) {
1342  if (ldns_resolver_edns_udp_size(r) == 0) {
1344  }
1345  ldns_pkt_set_edns_do(*query_pkt, true);
1346  if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) {
1347  ldns_pkt_set_cd(*query_pkt, true);
1348  }
1349  }
1350 
1351  /* transfer the udp_edns_size from the resolver to the packet */
1352  if (ldns_resolver_edns_udp_size(r) != 0) {
1354  }
1355 
1356  /* set the timestamp */
1357  now.tv_sec = time(NULL);
1358  now.tv_usec = 0;
1359  ldns_pkt_set_timestamp(*query_pkt, now);
1360 
1361 
1362  if (ldns_resolver_debug(r)) {
1363  ldns_pkt_print(stdout, *query_pkt);
1364  }
1365 
1366  /* only set the id if it is not set yet */
1367  if (ldns_pkt_id(*query_pkt) == 0) {
1368  ldns_pkt_set_random_id(*query_pkt);
1369  }
1370 
1371  return LDNS_STATUS_OK;
1372 }
1373 
1376  ldns_rr_type t, ldns_rr_class c, uint16_t flags)
1377 {
1378  ldns_pkt *query_pkt;
1379  ldns_pkt *answer_pkt;
1380  ldns_status status;
1381 
1382  assert(r != NULL);
1383  assert(name != NULL);
1384 
1385  answer_pkt = NULL;
1386 
1387  /* do all the preprocessing here, then fire of an query to
1388  * the network */
1389 
1390  if (0 == t) {
1391  t= LDNS_RR_TYPE_A;
1392  }
1393  if (0 == c) {
1394  c= LDNS_RR_CLASS_IN;
1395  }
1396  if (0 == ldns_resolver_nameserver_count(r)) {
1397  return LDNS_STATUS_RES_NO_NS;
1398  }
1399  if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) {
1400  return LDNS_STATUS_RES_QUERY;
1401  }
1402 
1403  status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name,
1404  t, c, flags);
1405  if (status != LDNS_STATUS_OK) {
1406  return status;
1407  }
1408 
1409  /* if tsig values are set, tsign it */
1410  /* TODO: make last 3 arguments optional too? maybe make complete
1411  rr instead of separate values in resolver (and packet)
1412  Jelte
1413  should this go in pkt_prepare?
1414  */
1416 #ifdef HAVE_SSL
1417  status = ldns_pkt_tsig_sign(query_pkt,
1420  300, ldns_resolver_tsig_algorithm(r), NULL);
1421  if (status != LDNS_STATUS_OK) {
1422  ldns_pkt_free(query_pkt);
1424  }
1425 #else
1426  ldns_pkt_free(query_pkt);
1428 #endif /* HAVE_SSL */
1429  }
1430 
1431  status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt);
1432  ldns_pkt_free(query_pkt);
1433 
1434  /* allows answer to be NULL when not interested in return value */
1435  if (answer) {
1436  *answer = answer_pkt;
1437  }
1438  return status;
1439 }
1440 
1441 ldns_rr *
1443 {
1444  ldns_rr *cur_rr;
1445  uint8_t *packet_wire;
1446  size_t packet_wire_size;
1447  ldns_status status;
1448 
1449  /* check if start() has been called */
1450  if (!resolver || resolver->_socket == -1) {
1451  return NULL;
1452  }
1453 
1454  if (resolver->_cur_axfr_pkt) {
1455  if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) {
1456  ldns_pkt_free(resolver->_cur_axfr_pkt);
1457  resolver->_cur_axfr_pkt = NULL;
1458  return ldns_axfr_next(resolver);
1459  }
1460  cur_rr = ldns_rr_clone(ldns_rr_list_rr(
1461  ldns_pkt_answer(resolver->_cur_axfr_pkt),
1462  resolver->_axfr_i));
1463  resolver->_axfr_i++;
1464  if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) {
1465  resolver->_axfr_soa_count++;
1466  if (resolver->_axfr_soa_count >= 2) {
1467 
1468  close_socket(resolver->_socket);
1469 
1470  ldns_pkt_free(resolver->_cur_axfr_pkt);
1471  resolver->_cur_axfr_pkt = NULL;
1472  }
1473  }
1474  return cur_rr;
1475  } else {
1476  packet_wire = ldns_tcp_read_wire_timeout(resolver->_socket, &packet_wire_size, resolver->_timeout);
1477  if(!packet_wire)
1478  return NULL;
1479 
1480  status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire,
1481  packet_wire_size);
1482  LDNS_FREE(packet_wire);
1483 
1484  resolver->_axfr_i = 0;
1485  if (status != LDNS_STATUS_OK) {
1486  /* TODO: make status return type of this function (...api change) */
1487 #ifdef STDERR_MSGS
1488  fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status));
1489 #endif
1490 
1491  /* we must now also close the socket, otherwise subsequent uses of the
1492  same resolver structure will fail because the link is still open or
1493  in an undefined state */
1494 
1495  close_socket(resolver->_socket);
1496 
1497  return NULL;
1498  } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) {
1499 #ifdef STDERR_MSGS
1502  resolver->_cur_axfr_pkt));
1503  if (rcode) {
1504  fprintf(stderr, "Error in AXFR: %s\n",
1505  rcode->name);
1506  } else {
1507  fprintf(stderr, "Error in AXFR: %d\n",
1508  (int) ldns_pkt_get_rcode(
1509  resolver->_cur_axfr_pkt));
1510  }
1511 #endif
1512 
1513  /* we must now also close the socket, otherwise subsequent uses of the
1514  same resolver structure will fail because the link is still open or
1515  in an undefined state */
1516 
1517  close_socket(resolver->_socket);
1518 
1519  return NULL;
1520  } else {
1521  return ldns_axfr_next(resolver);
1522  }
1523 
1524  }
1525 
1526 }
1527 
1528 /* this function is needed to abort a transfer that is in progress;
1529  * without it an aborted transfer will lead to the AXFR code in the
1530  * library staying in an indetermined state because the socket for the
1531  * AXFR is never closed
1532  */
1533 void
1535 {
1536  /* Only abort if an actual AXFR is in progress */
1537  if (resolver->_socket != -1)
1538  {
1539 #ifndef USE_WINSOCK
1540  close(resolver->_socket);
1541 #else
1542  closesocket(resolver->_socket);
1543 #endif
1544  resolver->_socket = -1;
1545  }
1546 }
1547 
1548 bool
1550 {
1551  /* complete when soa count is 2? */
1552  return res->_axfr_soa_count == 2;
1553 }
1554 
1555 ldns_pkt *
1557 {
1558  return res->_cur_axfr_pkt;
1559 }
1560 
1561 void
1563 {
1564  r->_serial = serial;
1565 }
1566 
1567 uint32_t
1569 {
1570  return res->_serial;
1571 }
1572 
1573 
1574 /* random isn't really that good */
1575 void
1577 {
1578  uint16_t i, j;
1579  ldns_rdf **ns, *tmpns;
1580  size_t *rtt, tmprtt;
1581 
1582  /* should I check for ldns_resolver_random?? */
1583  assert(r != NULL);
1584 
1585  ns = ldns_resolver_nameservers(r);
1586  rtt = ldns_resolver_rtt(r);
1587  for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
1589  tmpns = ns[i];
1590  ns[i] = ns[j];
1591  ns[j] = tmpns;
1592  tmprtt = rtt[i];
1593  rtt[i] = rtt[j];
1594  rtt[j] = tmprtt;
1595  }
1597 }
1598 
void ldns_buffer_free(ldns_buffer *buffer)
frees the buffer.
Definition: buffer.c:137
void ldns_buffer_new_frm_data(ldns_buffer *buffer, const void *data, size_t size)
creates a buffer with the specified data.
Definition: buffer.c:41
#define close_socket(_s)
Definition: config.h:756
bool ldns_dname_absolute(const ldns_rdf *rdf)
Checks whether the given dname is absolute (i.e.
Definition: dname.c:548
ldns_rdf * ldns_dname_cat_clone(const ldns_rdf *rd1, const ldns_rdf *rd2)
concatenates two dnames together
Definition: dname.c:52
const char * ldns_get_errorstr_by_id(ldns_status err)
look up a descriptive text by each error.
Definition: error.c:191
@ LDNS_STATUS_FILE_ERR
Definition: error.h:48
@ LDNS_STATUS_SYNTAX_ERR
Definition: error.h:97
@ LDNS_STATUS_NULL
Definition: error.h:51
@ LDNS_STATUS_SYNTAX_DNAME_ERR
Definition: error.h:84
@ LDNS_STATUS_ERR
Definition: error.h:37
@ LDNS_STATUS_MEM_ERR
Definition: error.h:34
@ LDNS_STATUS_RES_QUERY
Definition: error.h:71
@ LDNS_STATUS_OK
Definition: error.h:26
@ LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR
Definition: error.h:93
@ LDNS_STATUS_CRYPTO_TSIG_ERR
Definition: error.h:65
@ LDNS_STATUS_RES_NO_NS
Definition: error.h:70
enum ldns_enum_status ldns_status
Definition: error.h:146
ldns_lookup_table ldns_rcodes[]
Response codes.
Definition: host2str.c:109
void ldns_pkt_print(FILE *output, const ldns_pkt *pkt)
Prints the data in the DNS packet to the given file stream (in presentation format)
Definition: host2str.c:3430
ldns_rr * ldns_read_anchor_file(const char *filename)
Instantiates a DNSKEY or DS RR from file.
Definition: keys.c:2084
Including this file will include all ldns files, and define some lookup tables.
#define LDNS_PORT
Definition: ldns.h:134
uint8_t * ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
Gives back a raw packet from the wire and reads the header data from the given socket.
Definition: net.c:751
ldns_status ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
Sends ptk to the nameserver at the resolver object.
Definition: net.c:38
#define LDNS_DEFAULT_TIMEOUT_SEC
Definition: net.h:23
#define LDNS_DEFAULT_TIMEOUT_USEC
Definition: net.h:24
ldns_pkt * ldns_pkt_clone(const ldns_pkt *pkt)
clones the given packet, creating a fully allocated copy
Definition: packet.c:1214
void ldns_pkt_free(ldns_pkt *packet)
frees the packet structure and all data that it contains.
Definition: packet.c:895
ldns_pkt * ldns_pkt_ixfr_request_new(ldns_rdf *rr_name, ldns_rr_class rr_class, uint16_t flags, ldns_rr *soa)
creates an IXFR request packet for the given name, type and class.
Definition: packet.c:1156
void ldns_pkt_set_edns_udp_size(ldns_pkt *packet, uint16_t s)
Set the packet's edns udp size.
Definition: packet.c:612
void ldns_pkt_set_random_id(ldns_pkt *packet)
Set the packet's id to a random value.
Definition: packet.c:477
uint16_t ldns_pkt_id(const ldns_pkt *packet)
Read the packet id.
Definition: packet.c:40
void ldns_pkt_set_timestamp(ldns_pkt *packet, struct timeval timeval)
Set the packet's timestamp.
Definition: packet.c:599
void ldns_pkt_set_cd(ldns_pkt *packet, bool cd)
Set the packet's cd bit.
Definition: packet.c:533
uint16_t ldns_pkt_ancount(const ldns_pkt *packet)
Return the packet's an count.
Definition: packet.c:106
void ldns_pkt_set_edns_do(ldns_pkt *packet, bool value)
Set the packet's edns do bit.
Definition: packet.c:237
ldns_rr_list * ldns_pkt_answer(const ldns_pkt *packet)
Return the packet's answer section.
Definition: packet.c:130
ldns_pkt_rcode ldns_pkt_get_rcode(const ldns_pkt *packet)
Return the packet's response code.
Definition: packet.c:94
bool ldns_pkt_tc(const ldns_pkt *packet)
Read the packet's tc bit.
Definition: packet.c:58
ldns_pkt * ldns_pkt_query_new(ldns_rdf *rr_name, ldns_rr_type rr_type, ldns_rr_class rr_class, uint16_t flags)
creates a packet with a query in it for the given name, type and class.
Definition: packet.c:1148
uint16_t ldns_pkt_edns_udp_size(const ldns_pkt *packet)
return the packet's edns udp size
Definition: packet.c:207
#define LDNS_CD
Definition: packet.h:31
@ LDNS_RCODE_NOERROR
Definition: packet.h:57
ssize_t ldns_fget_token_l(FILE *f, char *token, const char *delim, size_t limit, int *line_nr)
returns a token/char from the stream F.
Definition: parse.c:220
ssize_t ldns_bget_token(ldns_buffer *b, char *token, const char *delim, size_t limit)
returns a token/char from the buffer b.
Definition: parse.c:274
#define LDNS_PARSE_SKIP_SPACE
Definition: parse.h:20
#define LDNS_MAX_LINELEN
Definition: parse.h:23
#define LDNS_PARSE_NORMAL
Definition: parse.h:21
ldns_rdf_type ldns_rdf_get_type(const ldns_rdf *rd)
returns the type of the rdf.
Definition: rdata.c:31
void ldns_rdf_deep_free(ldns_rdf *rd)
frees a rdf structure and frees the data.
Definition: rdata.c:230
ldns_rdf * ldns_rdf_new_frm_str(ldns_rdf_type type, const char *str)
creates a new rdf from a string.
Definition: rdata.c:249
ldns_rdf * ldns_native2rdf_int32(ldns_rdf_type type, uint32_t value)
returns an rdf that contains the given int32 value.
Definition: rdata.c:147
void ldns_rdf_free(ldns_rdf *rd)
frees a rdf structure, leaving the data pointer intact.
Definition: rdata.c:241
ldns_rdf * ldns_rdf_clone(const ldns_rdf *rd)
clones a rdf structure.
Definition: rdata.c:222
@ LDNS_RDF_TYPE_INT32
32 bits
Definition: rdata.h:56
@ LDNS_RDF_TYPE_AAAA
AAAA record.
Definition: rdata.h:60
@ LDNS_RDF_TYPE_DNAME
domain name
Definition: rdata.h:50
@ LDNS_RDF_TYPE_A
A record.
Definition: rdata.h:58
void ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s)
Set maximum udp size.
Definition: resolver.c:373
void ldns_resolver_set_random(ldns_resolver *r, bool b)
Should the nameserver list be randomized before each use.
Definition: resolver.c:601
void ldns_resolver_set_recursive(ldns_resolver *r, bool re)
Set the resolver recursion.
Definition: resolver.c:379
ldns_status ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, const ldns_rr_list *rrlist)
Push a new nameserver rr_list to the resolver.
Definition: resolver.c:351
void ldns_resolver_set_dnsrch(ldns_resolver *r, bool d)
Whether the resolver uses the searchlist.
Definition: resolver.c:464
void ldns_resolver_set_tsig_algorithm(ldns_resolver *r, const char *tsig_algorithm)
Set the tsig algorithm.
Definition: resolver.c:587
ldns_pkt * ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send a query to a nameserver.
Definition: resolver.c:1164
ldns_rr * ldns_axfr_next(ldns_resolver *resolver)
Get the next stream of RRs in a AXFR.
Definition: resolver.c:1442
const char * ldns_resolver_tsig_algorithm(const ldns_resolver *r)
Return the tsig algorithm as used by the nameserver.
Definition: resolver.c:213
void ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout)
Set the resolver's socket time out when talking to remote hosts.
Definition: resolver.c:551
bool ldns_resolver_dnssec(const ldns_resolver *r)
Does the resolver do DNSSEC.
Definition: resolver.c:120
void ldns_resolver_set_tsig_keydata(ldns_resolver *r, const char *tsig_keydata)
Set the tsig key data.
Definition: resolver.c:594
void ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list *l)
Set the resolver's DNSSEC anchor list directly.
Definition: resolver.c:397
ldns_resolver * ldns_resolver_new(void)
Create a new resolver structure.
Definition: resolver.c:608
void ldns_resolver_set_usevc(ldns_resolver *r, bool vc)
Whether the resolver uses a virtual circuit (TCP)
Definition: resolver.c:428
const char * ldns_resolver_tsig_keydata(const ldns_resolver *r)
Return the tsig keydata as used by the nameserver.
Definition: resolver.c:219
ldns_rdf * ldns_resolver_pop_nameserver(ldns_resolver *r)
pop the last nameserver from the resolver.
Definition: resolver.c:250
void ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value)
Set round trip time for a specific nameserver.
Definition: resolver.c:506
bool ldns_resolver_usevc(const ldns_resolver *r)
Does the resolver use tcp or udp.
Definition: resolver.c:171
void ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d)
Push a new rd to the resolver's searchlist.
Definition: resolver.c:558
bool ldns_resolver_debug(const ldns_resolver *r)
Get the debug status of the resolver.
Definition: resolver.c:72
size_t ldns_resolver_searchlist_count(const ldns_resolver *r)
Return the resolver's searchlist count.
Definition: resolver.c:231
ldns_rr_list * ldns_resolver_dnssec_anchors(const ldns_resolver *r)
Get the resolver's DNSSEC anchors.
Definition: resolver.c:132
void ldns_resolver_set_dnssec(ldns_resolver *r, bool d)
Whether the resolver uses DNSSEC.
Definition: resolver.c:385
ldns_status ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr)
Create a resolver structure from a file like /etc/resolv.conf.
Definition: resolver.c:765
size_t ldns_resolver_nameserver_count(const ldns_resolver *r)
How many nameserver are configured in the resolver.
Definition: resolver.c:114
void ldns_resolver_free(ldns_resolver *res)
Frees the allocated space for this resolver.
Definition: resolver.c:1033
ldns_status ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Form a query packet from a resolver and name/type/class combo.
Definition: resolver.c:1264
void ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry)
Set the number of times a resolver should retry a nameserver before the next one is tried.
Definition: resolver.c:470
void ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt)
Set round trip time for all nameservers.
Definition: resolver.c:500
void ldns_resolver_dec_nameserver_count(ldns_resolver *r)
Decrement the resolver's nameserver count.
Definition: resolver.c:532
void ldns_resolver_set_debug(ldns_resolver *r, bool d)
Set the resolver debugging.
Definition: resolver.c:434
ldns_status ldns_resolver_query_status(ldns_pkt **pkt, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send a query to a nameserver.
Definition: resolver.c:1143
ldns_status ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename)
Configure a resolver by means of a resolv.conf file The file may be NULL in which case there will be ...
Definition: resolver.c:1002
bool ldns_axfr_complete(const ldns_resolver *res)
Returns true if the axfr transfer has completed (i.e.
Definition: resolver.c:1549
void ldns_resolver_set_ixfr_serial(ldns_resolver *r, uint32_t serial)
Get the serial for requesting IXFR.
Definition: resolver.c:1562
uint8_t ldns_resolver_retrans(const ldns_resolver *r)
Get the retransmit interval.
Definition: resolver.c:48
bool ldns_resolver_dnssec_cd(const ldns_resolver *r)
Does the resolver set the CD bit.
Definition: resolver.c:126
bool ldns_resolver_recursive(const ldns_resolver *r)
Is the resolver set to recurse.
Definition: resolver.c:66
void ldns_resolver_set_port(ldns_resolver *r, uint16_t p)
Set the port the resolver should use.
Definition: resolver.c:238
bool ldns_resolver_dnsrch(const ldns_resolver *r)
Does the resolver apply search list.
Definition: resolver.c:78
void ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n)
Set the resolver's nameserver count directly by using an rdf list.
Definition: resolver.c:488
size_t ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos)
Return the used round trip time for a specific nameserver.
Definition: resolver.c:183
void ldns_resolver_nameservers_randomize(ldns_resolver *r)
Randomize the nameserver list in the resolver.
Definition: resolver.c:1576
bool ldns_resolver_igntc(const ldns_resolver *r)
Does the resolver ignore the TC bit (truncated)
Definition: resolver.c:165
bool ldns_resolver_defnames(const ldns_resolver *r)
Does the resolver apply default domain name.
Definition: resolver.c:90
uint32_t ldns_resolver_get_ixfr_serial(const ldns_resolver *res)
Get the serial for requesting IXFR.
Definition: resolver.c:1568
ldns_rdf * ldns_resolver_domain(const ldns_resolver *r)
What is the default dname to add to relative queries.
Definition: resolver.c:96
uint16_t ldns_resolver_edns_udp_size(const ldns_resolver *r)
Get the resolver's udp size.
Definition: resolver.c:36
void ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d)
Whether the resolver uses the checking disable bit.
Definition: resolver.c:391
void ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c)
Set the resolver's nameserver count directly.
Definition: resolver.c:458
void ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d)
Set the resolver's default domain.
Definition: resolver.c:545
bool ldns_resolver_random(const ldns_resolver *r)
Does the resolver randomize the nameserver before usage.
Definition: resolver.c:225
struct timeval ldns_resolver_timeout(const ldns_resolver *r)
What is the timeout on socket connections.
Definition: resolver.c:201
ldns_status ldns_resolver_push_nameserver(ldns_resolver *r, const ldns_rdf *n)
Push a new nameserver to the resolver.
Definition: resolver.c:288
size_t * ldns_resolver_rtt(const ldns_resolver *r)
Return the used round trip times for the nameservers.
Definition: resolver.c:177
bool ldns_resolver_fallback(const ldns_resolver *r)
Get the truncation fallback status.
Definition: resolver.c:54
uint8_t ldns_resolver_ip6(const ldns_resolver *r)
Does the resolver use ip6 or ip4.
Definition: resolver.c:60
ldns_pkt * ldns_axfr_last_pkt(const ldns_resolver *res)
Returns a pointer to the last ldns_pkt that was sent by the server in the AXFR transfer usable for in...
Definition: resolver.c:1556
ldns_status ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
Push a new trust anchor to the resolver.
Definition: resolver.c:403
void ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s)
Set the source rdf (address) the resolver should use.
Definition: resolver.c:244
uint8_t ldns_resolver_retry(const ldns_resolver *r)
Get the number of retries.
Definition: resolver.c:42
void ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6)
Whether the resolver uses ip6.
Definition: resolver.c:440
ldns_status ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp)
Create a resolver structure from a file like /etc/resolv.conf.
Definition: resolver.c:759
void ldns_resolver_set_igntc(ldns_resolver *r, bool i)
Whether or not to ignore the TC bit.
Definition: resolver.c:422
void ldns_axfr_abort(ldns_resolver *resolver)
Abort a transfer that is in progress.
Definition: resolver.c:1534
ldns_rdf ** ldns_resolver_searchlist(const ldns_resolver *r)
What is the searchlist as used by the resolver.
Definition: resolver.c:102
bool ldns_resolver_fail(const ldns_resolver *r)
Does the resolver only try the first nameserver.
Definition: resolver.c:84
ldns_status ldns_resolver_push_nameserver_rr(ldns_resolver *r, const ldns_rr *rr)
Push a new nameserver to the resolver.
Definition: resolver.c:335
void ldns_resolver_incr_nameserver_count(ldns_resolver *r)
Incremental the resolver's nameserver count.
Definition: resolver.c:523
void ldns_resolver_set_defnames(ldns_resolver *r, bool d)
Whether the resolver uses the name set with _set_domain.
Definition: resolver.c:494
const char * ldns_resolver_tsig_keyname(const ldns_resolver *r)
Return the tsig keyname as used by the nameserver.
Definition: resolver.c:207
bool ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list *keys, ldns_rr_list *trusted_keys)
Returns true if at least one of the provided keys is a trust anchor.
Definition: resolver.c:138
ldns_rdf ** ldns_resolver_nameservers(const ldns_resolver *r)
Return the configured nameserver ip address.
Definition: resolver.c:108
void ldns_resolver_set_fallback(ldns_resolver *r, bool fallback)
Set whether the resolvers truncation fallback mechanism is used when ldns_resolver_query() is called.
Definition: resolver.c:482
void ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans)
Set the resolver retrans timeout (in seconds)
Definition: resolver.c:476
void ldns_resolver_set_tsig_keyname(ldns_resolver *r, const char *tsig_keyname)
Set the tsig key name.
Definition: resolver.c:580
ldns_rdf * ldns_resolver_source(const ldns_resolver *r)
Get the source address the resolver should use.
Definition: resolver.c:30
ldns_pkt * ldns_resolver_search(const ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send the query for using the resolver and take the search list into account The search algorithm is a...
Definition: resolver.c:1130
uint16_t ldns_resolver_port(const ldns_resolver *r)
Get the port the resolver should use.
Definition: resolver.c:24
void ldns_resolver_set_fail(ldns_resolver *r, bool f)
Whether or not to fail after one failed query.
Definition: resolver.c:446
ldns_resolver * ldns_resolver_clone(ldns_resolver *src)
Clone a resolver.
Definition: resolver.c:665
ldns_status ldns_resolver_search_status(ldns_pkt **pkt, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send the query for using the resolver and take the search list into account The search algorithm is a...
Definition: resolver.c:1086
ldns_status ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, ldns_pkt *query_pkt)
Send the given packet to a nameserver.
Definition: resolver.c:1206
ldns_status ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, ldns_rr_type t, ldns_rr_class c, uint16_t flags)
Send the query for name as-is.
Definition: resolver.c:1375
void ldns_resolver_deep_free(ldns_resolver *res)
Frees the allocated space for this resolver and all it's data.
Definition: resolver.c:1039
#define LDNS_RESOLV_INETANY
Definition: resolver.h:49
#define LDNS_RESOLV_OPTIONS
Definition: resolver.h:45
#define LDNS_RESOLV_RTT_MIN
Definition: resolver.h:54
#define LDNS_RESOLV_SORTLIST
Definition: resolver.h:44
#define LDNS_RESOLV_DEFDOMAIN
Definition: resolver.h:41
#define LDNS_RESOLV_KEYWORDS
Definition: resolver.h:47
#define LDNS_RESOLV_ANCHOR
Definition: resolver.h:46
#define LDNS_RESOLV_NAMESERVER
Definition: resolver.h:42
#define LDNS_RESOLV_SEARCH
Definition: resolver.h:43
#define LDNS_RESOLV_KEYWORD
Definition: resolver.h:40
#define LDNS_RESOLV_CONF
Default location of the resolv.conf file.
Definition: resolver.h:36
ldns_rr * ldns_rr_list_rr(const ldns_rr_list *rr_list, size_t nr)
returns a specific rr of an rrlist.
Definition: rr.c:990
void ldns_rr_list_deep_free(ldns_rr_list *rr_list)
frees an rr_list structure and all rrs contained therein.
Definition: rr.c:1020
void ldns_rr_free(ldns_rr *rr)
frees an RR structure
Definition: rr.c:81
void ldns_rr_set_owner(ldns_rr *rr, ldns_rdf *owner)
sets the owner in the rr structure.
Definition: rr.c:804
void ldns_rr_set_type(ldns_rr *rr, ldns_rr_type rr_type)
sets the type in the rr.
Definition: rr.c:828
size_t ldns_rr_list_rr_count(const ldns_rr_list *rr_list)
returns the number of rr's in an rr_list.
Definition: rr.c:957
void ldns_rr_set_question(ldns_rr *rr, bool question)
sets the question flag in the rr structure.
Definition: rr.c:810
ldns_rr_type ldns_rr_get_type(const ldns_rr *rr)
returns the type of the rr.
Definition: rr.c:943
bool ldns_rr_list_push_rr(ldns_rr_list *rr_list, const ldns_rr *rr)
pushes an rr to an rrlist.
Definition: rr.c:1132
bool ldns_rr_list_contains_rr(const ldns_rr_list *rr_list, const ldns_rr *rr)
returns true if the given rr is one of the rrs in the list, or if it is equal to one
Definition: rr.c:1240
void ldns_rr_set_class(ldns_rr *rr, ldns_rr_class rr_class)
sets the class in the rr.
Definition: rr.c:834
ldns_rr_list * ldns_rr_list_new(void)
creates a new rr_list structure.
Definition: rr.c:1000
bool ldns_rr_push_rdf(ldns_rr *rr, const ldns_rdf *f)
sets rd_field member, it will be placed in the next available spot.
Definition: rr.c:857
ldns_rr * ldns_rr_clone(const ldns_rr *rr)
clones a rr and all its data
Definition: rr.c:1400
ldns_rr_list * ldns_rr_list_clone(const ldns_rr_list *rrlist)
clones an rrlist.
Definition: rr.c:1431
ldns_rdf * ldns_rr_rdf(const ldns_rr *rr, size_t nr)
returns the rdata field member counter.
Definition: rr.c:909
ldns_rr * ldns_rr_new(void)
creates a new rr structure.
Definition: rr.c:30
enum ldns_enum_rr_type ldns_rr_type
Definition: rr.h:243
@ LDNS_RR_TYPE_A
a host address
Definition: rr.h:80
@ LDNS_RR_TYPE_IXFR
Definition: rr.h:215
@ LDNS_RR_TYPE_DNSKEY
Definition: rr.h:172
@ LDNS_RR_TYPE_SOA
marks the start of a zone of authority
Definition: rr.h:90
@ LDNS_RR_TYPE_DS
RFC4034, RFC3658.
Definition: rr.h:164
@ LDNS_RR_TYPE_AAAA
ipv6 address
Definition: rr.h:134
enum ldns_enum_rr_class ldns_rr_class
Definition: rr.h:61
@ LDNS_RR_CLASS_IN
the Internet
Definition: rr.h:47
ldns_status ldns_str2rdf_dname(ldns_rdf **d, const char *str)
convert a dname string into wireformat
Definition: str2host.c:311
implementation of buffers to ease operations
Definition: buffer.h:51
A general purpose lookup table.
Definition: util.h:156
const char * name
Definition: util.h:158
DNS packet.
Definition: packet.h:235
Resource record data field.
Definition: rdata.h:197
DNS stub resolver structure.
Definition: resolver.h:60
bool _fallback
Use new fallback mechanism (try EDNS, then do TCP)
Definition: resolver.h:92
ldns_pkt * _cur_axfr_pkt
Packet currently handled when doing part of an AXFR.
Definition: resolver.h:126
int _socket
Keep some things to make AXFR possible.
Definition: resolver.h:117
uint16_t _axfr_i
Counter for within the AXFR packets.
Definition: resolver.h:128
char * _tsig_keyname
Name of the key to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values,...
Definition: resolver.h:138
uint8_t _retrans
Time to wait before retrying.
Definition: resolver.h:90
ldns_rdf * _source
Source address to query from.
Definition: resolver.h:145
uint16_t _edns_udp_size
Definition: resolver.h:130
bool _recursive
Whether or not to be recursive.
Definition: resolver.h:73
ldns_rr_list * _dnssec_anchors
Optional trust anchors for complete DNSSEC validation.
Definition: resolver.h:99
bool _debug
Print debug information.
Definition: resolver.h:76
size_t _nameserver_count
Number of nameservers in _nameservers.
Definition: resolver.h:67
bool _fail
Only try the first nameserver, and return with an error directly if it fails.
Definition: resolver.h:113
ldns_rdf ** _searchlist
Searchlist array, add the names in this array if a query cannot be found.
Definition: resolver.h:82
uint8_t _ip6
Whether to use ip6: 0->does not matter, 1 is IPv4, 2 is IPv6.
Definition: resolver.h:105
ldns_rdf ** _nameservers
Array of nameservers to query (IP addresses or dnames)
Definition: resolver.h:65
bool _dnssec_cd
Whether to set the CD bit on DNSSEC requests.
Definition: resolver.h:97
char * _tsig_keydata
Secret key data to use with TSIG, if _tsig_keyname and _tsig_keydata both contain values,...
Definition: resolver.h:140
size_t * _rtt
Round trip time; 0 -> infinity.
Definition: resolver.h:70
bool _usevc
Whether to use tcp or udp (tcp if the value is true)
Definition: resolver.h:101
char * _tsig_algorithm
TSIG signing algorithm.
Definition: resolver.h:142
int _axfr_soa_count
Count the number of LDNS_RR_TYPE_SOA RRs we have seen so far (the second one signifies the end of the...
Definition: resolver.h:121
bool _defnames
If true append the default domain.
Definition: resolver.h:107
bool _dnsrch
If true apply the search list.
Definition: resolver.h:109
size_t _searchlist_count
Number of entries in the searchlist array.
Definition: resolver.h:85
struct timeval _timeout
Timeout for socket connections.
Definition: resolver.h:111
bool _dnssec
Whether to do DNSSEC.
Definition: resolver.h:95
bool _random
Randomly choose a nameserver.
Definition: resolver.h:115
uint8_t _retry
Number of times to retry before giving up.
Definition: resolver.h:88
ldns_rdf * _domain
Default domain to add to non fully qualified domain names.
Definition: resolver.h:79
bool _igntc
Whether to ignore the tc bit.
Definition: resolver.h:103
uint16_t _port
Port to send queries to.
Definition: resolver.h:62
List or Set of Resource Records.
Definition: rr.h:338
Resource Record.
Definition: rr.h:310
ldns_status ldns_pkt_tsig_sign(ldns_pkt *pkt, const char *key_name, const char *key_data, uint16_t fudge, const char *algorithm_name, const ldns_rdf *query_mac)
creates a tsig rr for the given packet and key.
Definition: tsig.c:376
ldns_lookup_table * ldns_lookup_by_id(ldns_lookup_table *table, int id)
Definition: util.c:41
uint16_t ldns_get_random(void)
Get random number.
Definition: util.c:410
#define LDNS_FREE(ptr)
Definition: util.h:60
#define LDNS_MALLOC(type)
Memory management macros.
Definition: util.h:49
#define LDNS_XMALLOC(type, count)
Definition: util.h:51
#define LDNS_XREALLOC(ptr, type, count)
Definition: util.h:57
ldns_status ldns_wire2pkt(ldns_pkt **packet_p, const uint8_t *wire, size_t max)
converts the data on the uint8_t bytearray (in wire format) to a DNS packet.
Definition: wire2host.c:405