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 ldns_resolver_set_nameservers(r, nameservers); 260 ldns_resolver_set_rtt(r, rtt); 261 /* decr the count */ 262 ldns_resolver_dec_nameserver_count(r); 263 return pop; 264 } 265 266 ldns_status 267 ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n) 268 { 269 ldns_rdf **nameservers; 270 size_t ns_count; 271 size_t *rtt; 272 273 if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A && 274 ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) { 275 return LDNS_STATUS_ERR; 276 } 277 278 ns_count = ldns_resolver_nameserver_count(r); 279 nameservers = ldns_resolver_nameservers(r); 280 rtt = ldns_resolver_rtt(r); 281 282 /* make room for the next one */ 283 nameservers = LDNS_XREALLOC(nameservers, ldns_rdf *, (ns_count + 1)); 284 /* don't forget the rtt */ 285 rtt = LDNS_XREALLOC(rtt, size_t, (ns_count + 1)); 286 287 /* set the new value in the resolver */ 288 ldns_resolver_set_nameservers(r, nameservers); 289 290 /* slide n in its slot. */ 291 /* we clone it here, because then we can free the original 292 * rr's where it stood */ 293 nameservers[ns_count] = ldns_rdf_clone(n); 294 rtt[ns_count] = LDNS_RESOLV_RTT_MIN; 295 ldns_resolver_incr_nameserver_count(r); 296 ldns_resolver_set_rtt(r, rtt); 297 return LDNS_STATUS_OK; 298 } 299 300 ldns_status 301 ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr) 302 { 303 ldns_rdf *address; 304 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A && 305 ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) { 306 return LDNS_STATUS_ERR; 307 } 308 address = ldns_rr_rdf(rr, 0); /* extract the ip number */ 309 if (address) { 310 return ldns_resolver_push_nameserver(r, address); 311 } else { 312 return LDNS_STATUS_ERR; 313 } 314 } 315 316 ldns_status 317 ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist) 318 { 319 ldns_rr *rr; 320 ldns_status stat; 321 size_t i; 322 323 stat = LDNS_STATUS_OK; 324 if (rrlist) { 325 for(i = 0; i < ldns_rr_list_rr_count(rrlist); i++) { 326 rr = ldns_rr_list_rr(rrlist, i); 327 if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) { 328 stat = LDNS_STATUS_ERR; 329 } 330 } 331 return stat; 332 } else { 333 return LDNS_STATUS_ERR; 334 } 335 } 336 337 void 338 ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s) 339 { 340 r->_edns_udp_size = s; 341 } 342 343 void 344 ldns_resolver_set_recursive(ldns_resolver *r, bool re) 345 { 346 r->_recursive = re; 347 } 348 349 void 350 ldns_resolver_set_dnssec(ldns_resolver *r, bool d) 351 { 352 r->_dnssec = d; 353 } 354 355 void 356 ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d) 357 { 358 r->_dnssec_cd = d; 359 } 360 361 void 362 ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l) 363 { 364 r->_dnssec_anchors = l; 365 } 366 367 ldns_status 368 ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr) 369 { 370 ldns_rr_list * trust_anchors; 371 372 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY)) { 373 return LDNS_STATUS_ERR; 374 } 375 376 if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */ 377 trust_anchors = ldns_rr_list_new(); 378 ldns_resolver_set_dnssec_anchors(r, trust_anchors); 379 } 380 381 return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR; 382 } 383 384 void 385 ldns_resolver_set_igntc(ldns_resolver *r, bool i) 386 { 387 r->_igntc = i; 388 } 389 390 void 391 ldns_resolver_set_usevc(ldns_resolver *r, bool vc) 392 { 393 r->_usevc = vc; 394 } 395 396 void 397 ldns_resolver_set_debug(ldns_resolver *r, bool d) 398 { 399 r->_debug = d; 400 } 401 402 void 403 ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6) 404 { 405 r->_ip6 = ip6; 406 } 407 408 void 409 ldns_resolver_set_fail(ldns_resolver *r, bool f) 410 { 411 r->_fail =f; 412 } 413 414 void 415 ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c) 416 { 417 r->_searchlist_count = c; 418 } 419 420 void 421 ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c) 422 { 423 r->_nameserver_count = c; 424 } 425 426 void 427 ldns_resolver_set_dnsrch(ldns_resolver *r, bool d) 428 { 429 r->_dnsrch = d; 430 } 431 432 void 433 ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry) 434 { 435 r->_retry = retry; 436 } 437 438 void 439 ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans) 440 { 441 r->_retrans = retrans; 442 } 443 444 void 445 ldns_resolver_set_fallback(ldns_resolver *r, bool fallback) 446 { 447 r->_fallback = fallback; 448 } 449 450 void 451 ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n) 452 { 453 r->_nameservers = n; 454 } 455 456 void 457 ldns_resolver_set_defnames(ldns_resolver *r, bool d) 458 { 459 r->_defnames = d; 460 } 461 462 void 463 ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt) 464 { 465 r->_rtt = rtt; 466 } 467 468 void 469 ldns_resolver_set_nameserver_rtt(ldns_resolver *r, size_t pos, size_t value) 470 { 471 size_t *rtt; 472 473 assert(r != NULL); 474 475 rtt = ldns_resolver_rtt(r); 476 477 if (pos >= ldns_resolver_nameserver_count(r)) { 478 /* error ?*/ 479 } else { 480 rtt[pos] = value; 481 } 482 483 } 484 485 void 486 ldns_resolver_incr_nameserver_count(ldns_resolver *r) 487 { 488 size_t c; 489 490 c = ldns_resolver_nameserver_count(r); 491 ldns_resolver_set_nameserver_count(r, ++c); 492 } 493 494 void 495 ldns_resolver_dec_nameserver_count(ldns_resolver *r) 496 { 497 size_t c; 498 499 c = ldns_resolver_nameserver_count(r); 500 if (c == 0) { 501 return; 502 } else { 503 ldns_resolver_set_nameserver_count(r, --c); 504 } 505 } 506 507 void 508 ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d) 509 { 510 r->_domain = d; 511 } 512 513 void 514 ldns_resolver_set_timeout(ldns_resolver *r, struct timeval timeout) 515 { 516 r->_timeout.tv_sec = timeout.tv_sec; 517 r->_timeout.tv_usec = timeout.tv_usec; 518 } 519 520 void 521 ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d) 522 { 523 ldns_rdf **searchlist; 524 size_t list_count; 525 526 if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) { 527 return; 528 } 529 530 list_count = ldns_resolver_searchlist_count(r); 531 searchlist = ldns_resolver_searchlist(r); 532 533 searchlist = LDNS_XREALLOC(searchlist, ldns_rdf *, (list_count + 1)); 534 if (searchlist) { 535 r->_searchlist = searchlist; 536 537 searchlist[list_count] = ldns_rdf_clone(d); 538 ldns_resolver_set_searchlist_count(r, list_count + 1); 539 } 540 } 541 542 void 543 ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname) 544 { 545 r->_tsig_keyname = tsig_keyname; 546 } 547 548 void 549 ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm) 550 { 551 r->_tsig_algorithm = tsig_algorithm; 552 } 553 554 void 555 ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata) 556 { 557 r->_tsig_keydata = tsig_keydata; 558 } 559 560 void 561 ldns_resolver_set_random(ldns_resolver *r, bool b) 562 { 563 r->_random = b; 564 } 565 566 /* more sophisticated functions */ 567 ldns_resolver * 568 ldns_resolver_new(void) 569 { 570 ldns_resolver *r; 571 572 r = LDNS_MALLOC(ldns_resolver); 573 if (!r) { 574 return NULL; 575 } 576 577 r->_searchlist = NULL; 578 r->_nameservers = NULL; 579 r->_rtt = NULL; 580 581 /* defaults are filled out */ 582 ldns_resolver_set_searchlist_count(r, 0); 583 ldns_resolver_set_nameserver_count(r, 0); 584 ldns_resolver_set_usevc(r, 0); 585 ldns_resolver_set_port(r, LDNS_PORT); 586 ldns_resolver_set_domain(r, NULL); 587 ldns_resolver_set_defnames(r, false); 588 ldns_resolver_set_retry(r, 3); 589 ldns_resolver_set_retrans(r, 2); 590 ldns_resolver_set_fallback(r, true); 591 ldns_resolver_set_fail(r, false); 592 ldns_resolver_set_edns_udp_size(r, 0); 593 ldns_resolver_set_dnssec(r, false); 594 ldns_resolver_set_dnssec_cd(r, false); 595 ldns_resolver_set_dnssec_anchors(r, NULL); 596 ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY); 597 598 /* randomize the nameserver to be queried 599 * when there are multiple 600 */ 601 ldns_resolver_set_random(r, true); 602 603 ldns_resolver_set_debug(r, 0); 604 605 r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; 606 r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC; 607 608 r->_socket = 0; 609 r->_axfr_soa_count = 0; 610 r->_axfr_i = 0; 611 r->_cur_axfr_pkt = NULL; 612 613 r->_tsig_keyname = NULL; 614 r->_tsig_keydata = NULL; 615 r->_tsig_algorithm = NULL; 616 return r; 617 } 618 619 ldns_status 620 ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp) 621 { 622 return ldns_resolver_new_frm_fp_l(res, fp, NULL); 623 } 624 625 ldns_status 626 ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) 627 { 628 ldns_resolver *r; 629 const char *keyword[LDNS_RESOLV_KEYWORDS]; 630 char word[LDNS_MAX_LINELEN + 1]; 631 int8_t expect; 632 uint8_t i; 633 ldns_rdf *tmp; 634 #ifdef HAVE_SSL 635 ldns_rr *tmp_rr; 636 #endif 637 ssize_t gtr; 638 ldns_buffer *b; 639 640 /* do this better 641 * expect = 642 * 0: keyword 643 * 1: default domain dname 644 * 2: NS aaaa or a record 645 */ 646 647 /* recognized keywords */ 648 keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; 649 keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; 650 keyword[LDNS_RESOLV_SEARCH] = "search"; 651 /* these two are read but not used atm TODO */ 652 keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; 653 keyword[LDNS_RESOLV_OPTIONS] = "options"; 654 keyword[LDNS_RESOLV_ANCHOR] = "anchor"; 655 expect = LDNS_RESOLV_KEYWORD; 656 657 r = ldns_resolver_new(); 658 if (!r) { 659 return LDNS_STATUS_MEM_ERR; 660 } 661 662 gtr = 1; 663 word[0] = 0; 664 while (gtr > 0) { 665 /* check comments */ 666 if (word[0] == '#') { 667 /* read the rest of the line, should be 1 word */ 668 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 669 /* prepare the next string for further parsing */ 670 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 671 continue; 672 } 673 switch(expect) { 674 case LDNS_RESOLV_KEYWORD: 675 /* keyword */ 676 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 677 if (gtr != 0) { 678 for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { 679 if (strcasecmp(keyword[i], word) == 0) { 680 /* chosen the keyword and 681 * expect values carefully 682 */ 683 expect = i; 684 break; 685 } 686 } 687 /* no keyword recognized */ 688 if (expect == LDNS_RESOLV_KEYWORD) { 689 /* skip line */ 690 /* 691 ldns_resolver_deep_free(r); 692 return LDNS_STATUS_SYNTAX_KEYWORD_ERR; 693 */ 694 } 695 } 696 break; 697 case LDNS_RESOLV_DEFDOMAIN: 698 /* default domain dname */ 699 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 700 if (gtr == 0) { 701 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 702 } 703 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 704 if (!tmp) { 705 ldns_resolver_deep_free(r); 706 return LDNS_STATUS_SYNTAX_DNAME_ERR; 707 } 708 709 /* DOn't free, because we copy the pointer */ 710 ldns_resolver_set_domain(r, tmp); 711 expect = LDNS_RESOLV_KEYWORD; 712 break; 713 case LDNS_RESOLV_NAMESERVER: 714 /* NS aaaa or a record */ 715 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 716 if (gtr == 0) { 717 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 718 } 719 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); 720 if (!tmp) { 721 /* try ip4 */ 722 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); 723 } 724 /* could not parse it, exit */ 725 if (!tmp) { 726 ldns_resolver_deep_free(r); 727 return LDNS_STATUS_SYNTAX_ERR; 728 } 729 (void)ldns_resolver_push_nameserver(r, tmp); 730 ldns_rdf_deep_free(tmp); 731 expect = LDNS_RESOLV_KEYWORD; 732 break; 733 case LDNS_RESOLV_SEARCH: 734 /* search list domain dname */ 735 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 736 b = LDNS_MALLOC(ldns_buffer); 737 ldns_buffer_new_frm_data(b, word, (size_t) gtr); 738 739 gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr); 740 while (gtr > 0) { 741 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 742 if (!tmp) { 743 ldns_resolver_deep_free(r); 744 return LDNS_STATUS_SYNTAX_DNAME_ERR; 745 } 746 747 ldns_resolver_push_searchlist(r, tmp); 748 749 ldns_rdf_deep_free(tmp); 750 gtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr); 751 } 752 ldns_buffer_free(b); 753 gtr = 1; 754 expect = LDNS_RESOLV_KEYWORD; 755 break; 756 case LDNS_RESOLV_SORTLIST: 757 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 758 /* sortlist not implemented atm */ 759 expect = LDNS_RESOLV_KEYWORD; 760 break; 761 case LDNS_RESOLV_OPTIONS: 762 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 763 /* options not implemented atm */ 764 expect = LDNS_RESOLV_KEYWORD; 765 break; 766 case LDNS_RESOLV_ANCHOR: 767 /* a file containing a DNSSEC trust anchor */ 768 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 769 if (gtr == 0) { 770 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 771 } 772 773 #ifdef HAVE_SSL 774 tmp_rr = ldns_read_anchor_file(word); 775 (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); 776 ldns_rr_free(tmp_rr); 777 #endif 778 expect = LDNS_RESOLV_KEYWORD; 779 break; 780 } 781 } 782 783 if (res) { 784 *res = r; 785 return LDNS_STATUS_OK; 786 } else { 787 return LDNS_STATUS_NULL; 788 } 789 } 790 791 ldns_status 792 ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename) 793 { 794 ldns_resolver *r; 795 FILE *fp; 796 ldns_status s; 797 798 if (!filename) { 799 fp = fopen(LDNS_RESOLV_CONF, "r"); 800 801 } else { 802 fp = fopen(filename, "r"); 803 } 804 if (!fp) { 805 return LDNS_STATUS_FILE_ERR; 806 } 807 808 s = ldns_resolver_new_frm_fp(&r, fp); 809 fclose(fp); 810 if (s == LDNS_STATUS_OK) { 811 if (res) { 812 *res = r; 813 return LDNS_STATUS_OK; 814 } else { 815 return LDNS_STATUS_NULL; 816 } 817 } 818 return s; 819 } 820 821 void 822 ldns_resolver_free(ldns_resolver *res) 823 { 824 LDNS_FREE(res); 825 } 826 827 void 828 ldns_resolver_deep_free(ldns_resolver *res) 829 { 830 size_t i; 831 832 if (res) { 833 if (res->_searchlist) { 834 for (i = 0; i < ldns_resolver_searchlist_count(res); i++) { 835 ldns_rdf_deep_free(res->_searchlist[i]); 836 } 837 LDNS_FREE(res->_searchlist); 838 } 839 if (res->_nameservers) { 840 for (i = 0; i < res->_nameserver_count; i++) { 841 ldns_rdf_deep_free(res->_nameservers[i]); 842 } 843 LDNS_FREE(res->_nameservers); 844 } 845 if (ldns_resolver_domain(res)) { 846 ldns_rdf_deep_free(ldns_resolver_domain(res)); 847 } 848 if (ldns_resolver_tsig_keyname(res)) { 849 LDNS_FREE(res->_tsig_keyname); 850 } 851 852 if (res->_cur_axfr_pkt) { 853 ldns_pkt_free(res->_cur_axfr_pkt); 854 } 855 856 if (res->_rtt) { 857 LDNS_FREE(res->_rtt); 858 } 859 if (res->_dnssec_anchors) { 860 ldns_rr_list_deep_free(res->_dnssec_anchors); 861 } 862 LDNS_FREE(res); 863 } 864 } 865 866 ldns_pkt * 867 ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name, 868 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 869 { 870 871 char *str_dname; 872 ldns_rdf *new_name; 873 ldns_rdf **search_list; 874 size_t i; 875 ldns_pkt *p; 876 877 str_dname = ldns_rdf2str(name); 878 879 if (ldns_dname_str_absolute(str_dname)) { 880 /* query as-is */ 881 return ldns_resolver_query(r, name, t, c, flags); 882 } else { 883 search_list = ldns_resolver_searchlist(r); 884 for (i = 0; i < ldns_resolver_searchlist_count(r); i++) { 885 new_name = ldns_dname_cat_clone(name, search_list[i]); 886 887 p = ldns_resolver_query(r, new_name, t, c, flags); 888 ldns_rdf_free(new_name); 889 if (p) { 890 return p; 891 } 892 } 893 } 894 return NULL; 895 } 896 897 ldns_pkt * 898 ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, 899 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 900 { 901 ldns_rdf *newname; 902 ldns_pkt *pkt; 903 ldns_status status; 904 905 pkt = NULL; 906 907 if (!ldns_resolver_defnames(r)) { 908 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name, 909 t, c, flags); 910 if (status == LDNS_STATUS_OK) { 911 return pkt; 912 } else { 913 if (pkt) { 914 ldns_pkt_free(pkt); 915 } 916 fprintf(stderr, "error: %s\n", ldns_get_errorstr_by_id(status)); 917 return NULL; 918 } 919 } 920 921 if (!ldns_resolver_domain(r)) { 922 /* _defnames is set, but the domain is not....?? */ 923 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name, 924 t, c, flags); 925 if (status == LDNS_STATUS_OK) { 926 return pkt; 927 } else { 928 if (pkt) { 929 ldns_pkt_free(pkt); 930 } 931 return NULL; 932 } 933 } 934 935 newname = ldns_dname_cat_clone((const ldns_rdf*)name, ldns_resolver_domain(r)); 936 if (!newname) { 937 if (pkt) { 938 ldns_pkt_free(pkt); 939 } 940 return NULL; 941 } 942 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, newname, t, c, 943 flags); 944 945 ldns_rdf_free(newname); 946 947 return pkt; 948 } 949 950 ldns_status 951 ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, 952 ldns_pkt *query_pkt) 953 { 954 ldns_pkt *answer_pkt = NULL; 955 ldns_status stat = LDNS_STATUS_OK; 956 957 stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt); 958 if (stat != LDNS_STATUS_OK) { 959 if(answer_pkt) { 960 ldns_pkt_free(answer_pkt); 961 answer_pkt = NULL; 962 } 963 } else { 964 965 /* if tc=1 fall back to EDNS and/or TCP */ 966 /* check for tcp first (otherwise we don't care about tc=1) */ 967 if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) { 968 if (ldns_pkt_tc(answer_pkt)) { 969 /* was EDNS0 set? */ 970 if (ldns_pkt_edns_udp_size(query_pkt) == 0) { 971 ldns_pkt_set_edns_udp_size(query_pkt, 4096); 972 ldns_pkt_free(answer_pkt); 973 stat = ldns_send(&answer_pkt, r, query_pkt); 974 } 975 /* either way, if it is still truncated, use TCP */ 976 if (stat != LDNS_STATUS_OK || 977 ldns_pkt_tc(answer_pkt)) { 978 ldns_resolver_set_usevc(r, true); 979 ldns_pkt_free(answer_pkt); 980 stat = ldns_send(&answer_pkt, r, query_pkt); 981 ldns_resolver_set_usevc(r, false); 982 } 983 } 984 } 985 } 986 987 988 if (answer) { 989 *answer = answer_pkt; 990 } 991 992 return stat; 993 } 994 995 ldns_status 996 ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, 997 const ldns_rdf *name, ldns_rr_type t, 998 ldns_rr_class c, uint16_t flags) 999 { 1000 /* prepare a question pkt from the parameters 1001 * and then send this */ 1002 *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags); 1003 if (!*query_pkt) { 1004 return LDNS_STATUS_ERR; 1005 } 1006 1007 /* set DO bit if necessary */ 1008 if (ldns_resolver_dnssec(r)) { 1009 if (ldns_resolver_edns_udp_size(r) == 0) { 1010 ldns_resolver_set_edns_udp_size(r, 4096); 1011 } 1012 ldns_pkt_set_edns_do(*query_pkt, true); 1013 if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) { 1014 ldns_pkt_set_cd(*query_pkt, true); 1015 } 1016 } 1017 1018 /* transfer the udp_edns_size from the resolver to the packet */ 1019 if (ldns_resolver_edns_udp_size(r) != 0) { 1020 ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r)); 1021 } 1022 1023 if (ldns_resolver_debug(r)) { 1024 ldns_pkt_print(stdout, *query_pkt); 1025 } 1026 1027 /* only set the id if it is not set yet */ 1028 if (ldns_pkt_id(*query_pkt) == 0) { 1029 ldns_pkt_set_random_id(*query_pkt); 1030 } 1031 1032 return LDNS_STATUS_OK; 1033 } 1034 1035 1036 ldns_status 1037 ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, 1038 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1039 { 1040 ldns_pkt *query_pkt; 1041 ldns_pkt *answer_pkt; 1042 ldns_status status; 1043 1044 assert(r != NULL); 1045 assert(name != NULL); 1046 1047 answer_pkt = NULL; 1048 1049 /* do all the preprocessing here, then fire of an query to 1050 * the network */ 1051 1052 if (0 == t) { 1053 t= LDNS_RR_TYPE_A; 1054 } 1055 if (0 == c) { 1056 c= LDNS_RR_CLASS_IN; 1057 } 1058 if (0 == ldns_resolver_nameserver_count(r)) { 1059 return LDNS_STATUS_RES_NO_NS; 1060 } 1061 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) { 1062 return LDNS_STATUS_RES_QUERY; 1063 } 1064 1065 status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name, 1066 t, c, flags); 1067 if (status != LDNS_STATUS_OK) { 1068 return status; 1069 } 1070 1071 /* if tsig values are set, tsign it */ 1072 /* TODO: make last 3 arguments optional too? maybe make complete 1073 rr instead of seperate values in resolver (and packet) 1074 Jelte 1075 should this go in pkt_prepare? 1076 */ 1077 #ifdef HAVE_SSL 1078 if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) { 1079 status = ldns_pkt_tsig_sign(query_pkt, 1080 ldns_resolver_tsig_keyname(r), 1081 ldns_resolver_tsig_keydata(r), 1082 300, ldns_resolver_tsig_algorithm(r), NULL); 1083 if (status != LDNS_STATUS_OK) { 1084 return LDNS_STATUS_CRYPTO_TSIG_ERR; 1085 } 1086 } 1087 #else 1088 return LDNS_STATUS_CRYPTO_TSIG_ERR; 1089 #endif /* HAVE_SSL */ 1090 status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt); 1091 ldns_pkt_free(query_pkt); 1092 1093 /* allows answer to be NULL when not interested in return value */ 1094 if (answer) { 1095 *answer = answer_pkt; 1096 } 1097 return status; 1098 } 1099 1100 ldns_rr * 1101 ldns_axfr_next(ldns_resolver *resolver) 1102 { 1103 ldns_rr *cur_rr; 1104 uint8_t *packet_wire; 1105 size_t packet_wire_size; 1106 ldns_lookup_table *rcode; 1107 ldns_status status; 1108 1109 /* check if start() has been called */ 1110 if (!resolver || resolver->_socket == 0) { 1111 return NULL; 1112 } 1113 1114 if (resolver->_cur_axfr_pkt) { 1115 if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) { 1116 ldns_pkt_free(resolver->_cur_axfr_pkt); 1117 resolver->_cur_axfr_pkt = NULL; 1118 return ldns_axfr_next(resolver); 1119 } 1120 cur_rr = ldns_rr_clone(ldns_rr_list_rr( 1121 ldns_pkt_answer(resolver->_cur_axfr_pkt), 1122 resolver->_axfr_i)); 1123 resolver->_axfr_i++; 1124 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { 1125 resolver->_axfr_soa_count++; 1126 if (resolver->_axfr_soa_count >= 2) { 1127 close(resolver->_socket); 1128 resolver->_socket = 0; 1129 ldns_pkt_free(resolver->_cur_axfr_pkt); 1130 resolver->_cur_axfr_pkt = NULL; 1131 } 1132 } 1133 return cur_rr; 1134 } else { 1135 packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); 1136 if(!packet_wire) 1137 return NULL; 1138 1139 status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, 1140 packet_wire_size); 1141 free(packet_wire); 1142 1143 resolver->_axfr_i = 0; 1144 if (status != LDNS_STATUS_OK) { 1145 /* TODO: make status return type of this function (...api change) */ 1146 fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status)); 1147 return NULL; 1148 } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { 1149 rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt)); 1150 fprintf(stderr, "Error in AXFR: %s\n", rcode->name); 1151 return NULL; 1152 } else { 1153 return ldns_axfr_next(resolver); 1154 } 1155 1156 } 1157 1158 } 1159 1160 bool 1161 ldns_axfr_complete(const ldns_resolver *res) 1162 { 1163 /* complete when soa count is 2? */ 1164 return res->_axfr_soa_count == 2; 1165 } 1166 1167 ldns_pkt * 1168 ldns_axfr_last_pkt(const ldns_resolver *res) 1169 { 1170 return res->_cur_axfr_pkt; 1171 } 1172 1173 /* random isn't really that good */ 1174 void 1175 ldns_resolver_nameservers_randomize(ldns_resolver *r) 1176 { 1177 uint8_t i, j; 1178 ldns_rdf **ns, *tmp; 1179 1180 /* should I check for ldns_resolver_random?? */ 1181 assert(r != NULL); 1182 1183 ns = ldns_resolver_nameservers(r); 1184 1185 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { 1186 j = random() % ldns_resolver_nameserver_count(r); 1187 tmp = ns[i]; 1188 ns[i] = ns[j]; 1189 ns[j] = tmp; 1190 } 1191 ldns_resolver_set_nameservers(r, ns); 1192 } 1193 1194