resolver.c revision 269257
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 */ 23uint16_t 24ldns_resolver_port(const ldns_resolver *r) 25{ 26 return r->_port; 27} 28 29ldns_rdf * 30ldns_resolver_source(const ldns_resolver *r) 31{ 32 return r->_source; 33} 34 35uint16_t 36ldns_resolver_edns_udp_size(const ldns_resolver *r) 37{ 38 return r->_edns_udp_size; 39} 40 41uint8_t 42ldns_resolver_retry(const ldns_resolver *r) 43{ 44 return r->_retry; 45} 46 47uint8_t 48ldns_resolver_retrans(const ldns_resolver *r) 49{ 50 return r->_retrans; 51} 52 53bool 54ldns_resolver_fallback(const ldns_resolver *r) 55{ 56 return r->_fallback; 57} 58 59uint8_t 60ldns_resolver_ip6(const ldns_resolver *r) 61{ 62 return r->_ip6; 63} 64 65bool 66ldns_resolver_recursive(const ldns_resolver *r) 67{ 68 return r->_recursive; 69} 70 71bool 72ldns_resolver_debug(const ldns_resolver *r) 73{ 74 return r->_debug; 75} 76 77bool 78ldns_resolver_dnsrch(const ldns_resolver *r) 79{ 80 return r->_dnsrch; 81} 82 83bool 84ldns_resolver_fail(const ldns_resolver *r) 85{ 86 return r->_fail; 87} 88 89bool 90ldns_resolver_defnames(const ldns_resolver *r) 91{ 92 return r->_defnames; 93} 94 95ldns_rdf * 96ldns_resolver_domain(const ldns_resolver *r) 97{ 98 return r->_domain; 99} 100 101ldns_rdf ** 102ldns_resolver_searchlist(const ldns_resolver *r) 103{ 104 return r->_searchlist; 105} 106 107ldns_rdf ** 108ldns_resolver_nameservers(const ldns_resolver *r) 109{ 110 return r->_nameservers; 111} 112 113size_t 114ldns_resolver_nameserver_count(const ldns_resolver *r) 115{ 116 return r->_nameserver_count; 117} 118 119bool 120ldns_resolver_dnssec(const ldns_resolver *r) 121{ 122 return r->_dnssec; 123} 124 125bool 126ldns_resolver_dnssec_cd(const ldns_resolver *r) 127{ 128 return r->_dnssec_cd; 129} 130 131ldns_rr_list * 132ldns_resolver_dnssec_anchors(const ldns_resolver *r) 133{ 134 return r->_dnssec_anchors; 135} 136 137bool 138ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys) 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 164bool 165ldns_resolver_igntc(const ldns_resolver *r) 166{ 167 return r->_igntc; 168} 169 170bool 171ldns_resolver_usevc(const ldns_resolver *r) 172{ 173 return r->_usevc; 174} 175 176size_t * 177ldns_resolver_rtt(const ldns_resolver *r) 178{ 179 return r->_rtt; 180} 181 182size_t 183ldns_resolver_nameserver_rtt(const ldns_resolver *r, size_t pos) 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 200struct timeval 201ldns_resolver_timeout(const ldns_resolver *r) 202{ 203 return r->_timeout; 204} 205 206char * 207ldns_resolver_tsig_keyname(const ldns_resolver *r) 208{ 209 return r->_tsig_keyname; 210} 211 212char * 213ldns_resolver_tsig_algorithm(const ldns_resolver *r) 214{ 215 return r->_tsig_algorithm; 216} 217 218char * 219ldns_resolver_tsig_keydata(const ldns_resolver *r) 220{ 221 return r->_tsig_keydata; 222} 223 224bool 225ldns_resolver_random(const ldns_resolver *r) 226{ 227 return r->_random; 228} 229 230size_t 231ldns_resolver_searchlist_count(const ldns_resolver *r) 232{ 233 return r->_searchlist_count; 234} 235 236/* write */ 237void 238ldns_resolver_set_port(ldns_resolver *r, uint16_t p) 239{ 240 r->_port = p; 241} 242 243void 244ldns_resolver_set_source(ldns_resolver *r, ldns_rdf *s) 245{ 246 r->_source = s; 247} 248 249ldns_rdf * 250ldns_resolver_pop_nameserver(ldns_resolver *r) 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 272 ldns_resolver_set_nameservers(r, NULL); 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 */ 283 ldns_resolver_dec_nameserver_count(r); 284 return pop; 285} 286 287ldns_status 288ldns_resolver_push_nameserver(ldns_resolver *r, ldns_rdf *n) 289{ 290 ldns_rdf **nameservers; 291 size_t ns_count; 292 size_t *rtt; 293 294 if (ldns_rdf_get_type(n) != LDNS_RDF_TYPE_A && 295 ldns_rdf_get_type(n) != LDNS_RDF_TYPE_AAAA) { 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; 329 ldns_resolver_incr_nameserver_count(r); 330 ldns_resolver_set_rtt(r, rtt); 331 return LDNS_STATUS_OK; 332} 333 334ldns_status 335ldns_resolver_push_nameserver_rr(ldns_resolver *r, ldns_rr *rr) 336{ 337 ldns_rdf *address; 338 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_A && 339 ldns_rr_get_type(rr) != LDNS_RR_TYPE_AAAA)) { 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 350ldns_status 351ldns_resolver_push_nameserver_rr_list(ldns_resolver *r, ldns_rr_list *rrlist) 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); 361 if (ldns_resolver_push_nameserver_rr(r, rr) != LDNS_STATUS_OK) { 362 stat = LDNS_STATUS_ERR; 363 break; 364 } 365 } 366 return stat; 367 } else { 368 return LDNS_STATUS_ERR; 369 } 370} 371 372void 373ldns_resolver_set_edns_udp_size(ldns_resolver *r, uint16_t s) 374{ 375 r->_edns_udp_size = s; 376} 377 378void 379ldns_resolver_set_recursive(ldns_resolver *r, bool re) 380{ 381 r->_recursive = re; 382} 383 384void 385ldns_resolver_set_dnssec(ldns_resolver *r, bool d) 386{ 387 r->_dnssec = d; 388} 389 390void 391ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool d) 392{ 393 r->_dnssec_cd = d; 394} 395 396void 397ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l) 398{ 399 r->_dnssec_anchors = l; 400} 401 402ldns_status 403ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr) 404{ 405 ldns_rr_list * trust_anchors; 406 407 if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY && 408 ldns_rr_get_type(rr) != LDNS_RR_TYPE_DS)) { 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 421void 422ldns_resolver_set_igntc(ldns_resolver *r, bool i) 423{ 424 r->_igntc = i; 425} 426 427void 428ldns_resolver_set_usevc(ldns_resolver *r, bool vc) 429{ 430 r->_usevc = vc; 431} 432 433void 434ldns_resolver_set_debug(ldns_resolver *r, bool d) 435{ 436 r->_debug = d; 437} 438 439void 440ldns_resolver_set_ip6(ldns_resolver *r, uint8_t ip6) 441{ 442 r->_ip6 = ip6; 443} 444 445void 446ldns_resolver_set_fail(ldns_resolver *r, bool f) 447{ 448 r->_fail =f; 449} 450 451static void 452ldns_resolver_set_searchlist_count(ldns_resolver *r, size_t c) 453{ 454 r->_searchlist_count = c; 455} 456 457void 458ldns_resolver_set_nameserver_count(ldns_resolver *r, size_t c) 459{ 460 r->_nameserver_count = c; 461} 462 463void 464ldns_resolver_set_dnsrch(ldns_resolver *r, bool d) 465{ 466 r->_dnsrch = d; 467} 468 469void 470ldns_resolver_set_retry(ldns_resolver *r, uint8_t retry) 471{ 472 r->_retry = retry; 473} 474 475void 476ldns_resolver_set_retrans(ldns_resolver *r, uint8_t retrans) 477{ 478 r->_retrans = retrans; 479} 480 481void 482ldns_resolver_set_fallback(ldns_resolver *r, bool fallback) 483{ 484 r->_fallback = fallback; 485} 486 487void 488ldns_resolver_set_nameservers(ldns_resolver *r, ldns_rdf **n) 489{ 490 r->_nameservers = n; 491} 492 493void 494ldns_resolver_set_defnames(ldns_resolver *r, bool d) 495{ 496 r->_defnames = d; 497} 498 499void 500ldns_resolver_set_rtt(ldns_resolver *r, size_t *rtt) 501{ 502 r->_rtt = rtt; 503} 504 505void 506ldns_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 522void 523ldns_resolver_incr_nameserver_count(ldns_resolver *r) 524{ 525 size_t c; 526 527 c = ldns_resolver_nameserver_count(r); 528 ldns_resolver_set_nameserver_count(r, ++c); 529} 530 531void 532ldns_resolver_dec_nameserver_count(ldns_resolver *r) 533{ 534 size_t c; 535 536 c = ldns_resolver_nameserver_count(r); 537 if (c == 0) { 538 return; 539 } else { 540 ldns_resolver_set_nameserver_count(r, --c); 541 } 542} 543 544void 545ldns_resolver_set_domain(ldns_resolver *r, ldns_rdf *d) 546{ 547 r->_domain = d; 548} 549 550void 551ldns_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 557void 558ldns_resolver_push_searchlist(ldns_resolver *r, ldns_rdf *d) 559{ 560 ldns_rdf **searchlist; 561 size_t list_count; 562 563 if (ldns_rdf_get_type(d) != LDNS_RDF_TYPE_DNAME) { 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 579void 580ldns_resolver_set_tsig_keyname(ldns_resolver *r, char *tsig_keyname) 581{ 582 LDNS_FREE(r->_tsig_keyname); 583 r->_tsig_keyname = strdup(tsig_keyname); 584} 585 586void 587ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm) 588{ 589 LDNS_FREE(r->_tsig_algorithm); 590 r->_tsig_algorithm = strdup(tsig_algorithm); 591} 592 593void 594ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata) 595{ 596 LDNS_FREE(r->_tsig_keydata); 597 r->_tsig_keydata = strdup(tsig_keydata); 598} 599 600void 601ldns_resolver_set_random(ldns_resolver *r, bool b) 602{ 603 r->_random = b; 604} 605 606/* more sophisticated functions */ 607ldns_resolver * 608ldns_resolver_new(void) 609{ 610 ldns_resolver *r; 611 612 r = LDNS_MALLOC(ldns_resolver); 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); 623 ldns_resolver_set_nameserver_count(r, 0); 624 ldns_resolver_set_usevc(r, 0); 625 ldns_resolver_set_port(r, LDNS_PORT); 626 ldns_resolver_set_domain(r, NULL); 627 ldns_resolver_set_defnames(r, false); 628 ldns_resolver_set_retry(r, 3); 629 ldns_resolver_set_retrans(r, 2); 630 ldns_resolver_set_fallback(r, true); 631 ldns_resolver_set_fail(r, false); 632 ldns_resolver_set_edns_udp_size(r, 0); 633 ldns_resolver_set_dnssec(r, false); 634 ldns_resolver_set_dnssec_cd(r, false); 635 ldns_resolver_set_dnssec_anchors(r, NULL); 636 ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY); 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); 641 642 /* randomize the nameserver to be queried 643 * when there are multiple 644 */ 645 ldns_resolver_set_random(r, true); 646 647 ldns_resolver_set_debug(r, 0); 648 649 r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; 650 r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC; 651 652 /* TODO: fd=0 is actually a valid socket (stdin), 653 replace with -1 */ 654 r->_socket = 0; 655 r->_axfr_soa_count = 0; 656 r->_axfr_i = 0; 657 r->_cur_axfr_pkt = NULL; 658 659 r->_tsig_keyname = NULL; 660 r->_tsig_keydata = NULL; 661 r->_tsig_algorithm = NULL; 662 return r; 663} 664 665ldns_status 666ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp) 667{ 668 return ldns_resolver_new_frm_fp_l(res, fp, NULL); 669} 670 671ldns_status 672ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) 673{ 674 ldns_resolver *r; 675 const char *keyword[LDNS_RESOLV_KEYWORDS]; 676 char word[LDNS_MAX_LINELEN + 1]; 677 int8_t expect; 678 uint8_t i; 679 ldns_rdf *tmp; 680#ifdef HAVE_SSL 681 ldns_rr *tmp_rr; 682#endif 683 ssize_t gtr, bgtr; 684 ldns_buffer *b; 685 int lnr = 0, oldline; 686 FILE* myfp = fp; 687 if(!line_nr) line_nr = &lnr; 688 689 if(!fp) { 690 myfp = fopen("/etc/resolv.conf", "r"); 691 if(!myfp) 692 return LDNS_STATUS_FILE_ERR; 693 } 694 695 /* do this better 696 * expect = 697 * 0: keyword 698 * 1: default domain dname 699 * 2: NS aaaa or a record 700 */ 701 702 /* recognized keywords */ 703 keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; 704 keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; 705 keyword[LDNS_RESOLV_SEARCH] = "search"; 706 /* these two are read but not used atm TODO */ 707 keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; 708 keyword[LDNS_RESOLV_OPTIONS] = "options"; 709 keyword[LDNS_RESOLV_ANCHOR] = "anchor"; 710 expect = LDNS_RESOLV_KEYWORD; 711 712 r = ldns_resolver_new(); 713 if (!r) { 714 if(!fp) fclose(myfp); 715 return LDNS_STATUS_MEM_ERR; 716 } 717 718 gtr = 1; 719 word[0] = 0; 720 oldline = *line_nr; 721 expect = LDNS_RESOLV_KEYWORD; 722 while (gtr > 0) { 723 /* check comments */ 724 if (word[0] == '#') { 725 word[0]='x'; 726 if(oldline == *line_nr) { 727 /* skip until end of line */ 728 int c; 729 do { 730 c = fgetc(myfp); 731 } while(c != EOF && c != '\n'); 732 if(c=='\n') (*line_nr)++; 733 } 734 /* and read next to prepare for further parsing */ 735 oldline = *line_nr; 736 continue; 737 } 738 oldline = *line_nr; 739 switch(expect) { 740 case LDNS_RESOLV_KEYWORD: 741 /* keyword */ 742 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 743 if (gtr != 0) { 744 if(word[0] == '#') continue; 745 for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { 746 if (strcasecmp(keyword[i], word) == 0) { 747 /* chosen the keyword and 748 * expect values carefully 749 */ 750 expect = i; 751 break; 752 } 753 } 754 /* no keyword recognized */ 755 if (expect == LDNS_RESOLV_KEYWORD) { 756 /* skip line */ 757 /* 758 ldns_resolver_deep_free(r); 759 if(!fp) fclose(myfp); 760 return LDNS_STATUS_SYNTAX_KEYWORD_ERR; 761 */ 762 } 763 } 764 break; 765 case LDNS_RESOLV_DEFDOMAIN: 766 /* default domain dname */ 767 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 768 if (gtr == 0) { 769 if(!fp) fclose(myfp); 770 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 771 } 772 if(word[0] == '#') { 773 expect = LDNS_RESOLV_KEYWORD; 774 continue; 775 } 776 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 777 if (!tmp) { 778 ldns_resolver_deep_free(r); 779 if(!fp) fclose(myfp); 780 return LDNS_STATUS_SYNTAX_DNAME_ERR; 781 } 782 783 /* DOn't free, because we copy the pointer */ 784 ldns_resolver_set_domain(r, tmp); 785 expect = LDNS_RESOLV_KEYWORD; 786 break; 787 case LDNS_RESOLV_NAMESERVER: 788 /* NS aaaa or a record */ 789 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 790 if (gtr == 0) { 791 if(!fp) fclose(myfp); 792 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 793 } 794 if(word[0] == '#') { 795 expect = LDNS_RESOLV_KEYWORD; 796 continue; 797 } 798 if(strchr(word, '%')) { 799 /* snip off interface labels, 800 * fe80::222:19ff:fe31:4222%eth0 */ 801 strchr(word, '%')[0]=0; 802 } 803 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); 804 if (!tmp) { 805 /* try ip4 */ 806 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); 807 } 808 /* could not parse it, exit */ 809 if (!tmp) { 810 ldns_resolver_deep_free(r); 811 if(!fp) fclose(myfp); 812 return LDNS_STATUS_SYNTAX_ERR; 813 } 814 (void)ldns_resolver_push_nameserver(r, tmp); 815 ldns_rdf_deep_free(tmp); 816 expect = LDNS_RESOLV_KEYWORD; 817 break; 818 case LDNS_RESOLV_SEARCH: 819 /* search list domain dname */ 820 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 821 b = LDNS_MALLOC(ldns_buffer); 822 if(!b) { 823 ldns_resolver_deep_free(r); 824 if(!fp) fclose(myfp); 825 return LDNS_STATUS_MEM_ERR; 826 } 827 828 ldns_buffer_new_frm_data(b, word, (size_t) gtr); 829 if(ldns_buffer_status(b) != LDNS_STATUS_OK) { 830 LDNS_FREE(b); 831 ldns_resolver_deep_free(r); 832 if(!fp) fclose(myfp); 833 return LDNS_STATUS_MEM_ERR; 834 } 835 bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); 836 while (bgtr > 0) { 837 gtr -= bgtr; 838 if(word[0] == '#') { 839 expect = LDNS_RESOLV_KEYWORD; 840 break; 841 } 842 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 843 if (!tmp) { 844 ldns_resolver_deep_free(r); 845 ldns_buffer_free(b); 846 if(!fp) fclose(myfp); 847 return LDNS_STATUS_SYNTAX_DNAME_ERR; 848 } 849 850 ldns_resolver_push_searchlist(r, tmp); 851 852 ldns_rdf_deep_free(tmp); 853 bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, 854 (size_t) gtr + 1); 855 } 856 ldns_buffer_free(b); 857 if (expect != LDNS_RESOLV_KEYWORD) { 858 gtr = 1; 859 expect = LDNS_RESOLV_KEYWORD; 860 } 861 break; 862 case LDNS_RESOLV_SORTLIST: 863 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 864 /* sortlist not implemented atm */ 865 expect = LDNS_RESOLV_KEYWORD; 866 break; 867 case LDNS_RESOLV_OPTIONS: 868 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 869 /* options not implemented atm */ 870 expect = LDNS_RESOLV_KEYWORD; 871 break; 872 case LDNS_RESOLV_ANCHOR: 873 /* a file containing a DNSSEC trust anchor */ 874 gtr = ldns_fget_token_l(myfp, word, LDNS_PARSE_NORMAL, 0, line_nr); 875 if (gtr == 0) { 876 ldns_resolver_deep_free(r); 877 if(!fp) fclose(myfp); 878 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 879 } 880 if(word[0] == '#') { 881 expect = LDNS_RESOLV_KEYWORD; 882 continue; 883 } 884 885#ifdef HAVE_SSL 886 tmp_rr = ldns_read_anchor_file(word); 887 (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); 888 ldns_rr_free(tmp_rr); 889#endif 890 expect = LDNS_RESOLV_KEYWORD; 891 break; 892 } 893 } 894 895 if(!fp) 896 fclose(myfp); 897 898 if (res) { 899 *res = r; 900 return LDNS_STATUS_OK; 901 } else { 902 ldns_resolver_deep_free(r); 903 return LDNS_STATUS_NULL; 904 } 905} 906 907ldns_status 908ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename) 909{ 910 ldns_resolver *r; 911 FILE *fp; 912 ldns_status s; 913 914 if (!filename) { 915 fp = fopen(LDNS_RESOLV_CONF, "r"); 916 917 } else { 918 fp = fopen(filename, "r"); 919 } 920 if (!fp) { 921 return LDNS_STATUS_FILE_ERR; 922 } 923 924 s = ldns_resolver_new_frm_fp(&r, fp); 925 fclose(fp); 926 if (s == LDNS_STATUS_OK) { 927 if (res) { 928 *res = r; 929 return LDNS_STATUS_OK; 930 } else { 931 ldns_resolver_free(r); 932 return LDNS_STATUS_NULL; 933 } 934 } 935 return s; 936} 937 938void 939ldns_resolver_free(ldns_resolver *res) 940{ 941 LDNS_FREE(res); 942} 943 944void 945ldns_resolver_deep_free(ldns_resolver *res) 946{ 947 size_t i; 948 949 if (res) { 950 if (res->_searchlist) { 951 for (i = 0; i < ldns_resolver_searchlist_count(res); i++) { 952 ldns_rdf_deep_free(res->_searchlist[i]); 953 } 954 LDNS_FREE(res->_searchlist); 955 } 956 if (res->_nameservers) { 957 for (i = 0; i < res->_nameserver_count; i++) { 958 ldns_rdf_deep_free(res->_nameservers[i]); 959 } 960 LDNS_FREE(res->_nameservers); 961 } 962 if (ldns_resolver_domain(res)) { 963 ldns_rdf_deep_free(ldns_resolver_domain(res)); 964 } 965 if (res->_tsig_keyname) { 966 LDNS_FREE(res->_tsig_keyname); 967 } 968 if (res->_tsig_keydata) { 969 LDNS_FREE(res->_tsig_keydata); 970 } 971 if (res->_tsig_algorithm) { 972 LDNS_FREE(res->_tsig_algorithm); 973 } 974 975 if (res->_cur_axfr_pkt) { 976 ldns_pkt_free(res->_cur_axfr_pkt); 977 } 978 979 if (res->_rtt) { 980 LDNS_FREE(res->_rtt); 981 } 982 if (res->_dnssec_anchors) { 983 ldns_rr_list_deep_free(res->_dnssec_anchors); 984 } 985 LDNS_FREE(res); 986 } 987} 988 989ldns_status 990ldns_resolver_search_status(ldns_pkt** pkt, 991 ldns_resolver *r, const ldns_rdf *name, 992 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 993{ 994 ldns_rdf *new_name; 995 ldns_rdf **search_list; 996 size_t i; 997 ldns_status s = LDNS_STATUS_OK; 998 999 if (ldns_dname_absolute(name)) { 1000 /* query as-is */ 1001 return ldns_resolver_query_status(pkt, r, name, t, c, flags); 1002 } else if (ldns_resolver_dnsrch(r)) { 1003 search_list = ldns_resolver_searchlist(r); 1004 for (i = 0; i < ldns_resolver_searchlist_count(r); i++) { 1005 new_name = ldns_dname_cat_clone(name, search_list[i]); 1006 1007 s = ldns_resolver_query_status(pkt, r, 1008 new_name, t, c, flags); 1009 ldns_rdf_free(new_name); 1010 if (pkt) { 1011 if (s == LDNS_STATUS_OK && *pkt && 1012 ldns_pkt_get_rcode(*pkt) == 1013 LDNS_RCODE_NOERROR) { 1014 return LDNS_STATUS_OK; 1015 } 1016 ldns_pkt_free(*pkt); 1017 } 1018 } 1019 } 1020 return s; 1021} 1022 1023ldns_pkt * 1024ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name, 1025 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1026{ 1027 ldns_pkt* pkt = NULL; 1028 if (ldns_resolver_search_status(&pkt, (ldns_resolver *)r, 1029 name, t, c, flags) != LDNS_STATUS_OK) { 1030 ldns_pkt_free(pkt); 1031 } 1032 return pkt; 1033} 1034 1035ldns_status 1036ldns_resolver_query_status(ldns_pkt** pkt, 1037 ldns_resolver *r, const ldns_rdf *name, 1038 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1039{ 1040 ldns_rdf *newname; 1041 ldns_status status; 1042 1043 if (!ldns_resolver_defnames(r) || !ldns_resolver_domain(r)) { 1044 return ldns_resolver_send(pkt, r, name, t, c, flags); 1045 } 1046 1047 newname = ldns_dname_cat_clone(name, ldns_resolver_domain(r)); 1048 if (!newname) { 1049 return LDNS_STATUS_MEM_ERR; 1050 } 1051 status = ldns_resolver_send(pkt, r, newname, t, c, flags); 1052 ldns_rdf_free(newname); 1053 return status; 1054} 1055 1056ldns_pkt * 1057ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, 1058 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1059{ 1060 ldns_pkt* pkt = NULL; 1061 if (ldns_resolver_query_status(&pkt, (ldns_resolver *)r, 1062 name, t, c, flags) != LDNS_STATUS_OK) { 1063 ldns_pkt_free(pkt); 1064 } 1065 return pkt; 1066} 1067 1068static size_t * 1069ldns_resolver_backup_rtt(ldns_resolver *r) 1070{ 1071 size_t *new_rtt; 1072 size_t *old_rtt = ldns_resolver_rtt(r); 1073 1074 if (old_rtt && ldns_resolver_nameserver_count(r)) { 1075 new_rtt = LDNS_XMALLOC(size_t 1076 , ldns_resolver_nameserver_count(r)); 1077 memcpy(new_rtt, old_rtt, sizeof(size_t) 1078 * ldns_resolver_nameserver_count(r)); 1079 ldns_resolver_set_rtt(r, new_rtt); 1080 return old_rtt; 1081 } 1082 return NULL; 1083} 1084 1085static void 1086ldns_resolver_restore_rtt(ldns_resolver *r, size_t *old_rtt) 1087{ 1088 size_t *cur_rtt = ldns_resolver_rtt(r); 1089 1090 if (cur_rtt) { 1091 LDNS_FREE(cur_rtt); 1092 } 1093 ldns_resolver_set_rtt(r, old_rtt); 1094} 1095 1096ldns_status 1097ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, 1098 ldns_pkt *query_pkt) 1099{ 1100 ldns_pkt *answer_pkt = NULL; 1101 ldns_status stat = LDNS_STATUS_OK; 1102 size_t *rtt; 1103 1104 stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt); 1105 if (stat != LDNS_STATUS_OK) { 1106 if(answer_pkt) { 1107 ldns_pkt_free(answer_pkt); 1108 answer_pkt = NULL; 1109 } 1110 } else { 1111 /* if tc=1 fall back to EDNS and/or TCP */ 1112 /* check for tcp first (otherwise we don't care about tc=1) */ 1113 if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) { 1114 if (ldns_pkt_tc(answer_pkt)) { 1115 /* was EDNS0 set? */ 1116 if (ldns_pkt_edns_udp_size(query_pkt) == 0) { 1117 ldns_pkt_set_edns_udp_size(query_pkt 1118 , 4096); 1119 ldns_pkt_free(answer_pkt); 1120 /* Nameservers should not become 1121 * unreachable because fragments are 1122 * dropped (network error). We might 1123 * still have success with TCP. 1124 * Therefore maintain reachability 1125 * statuses of the nameservers by 1126 * backup and restore the rtt list. 1127 */ 1128 rtt = ldns_resolver_backup_rtt(r); 1129 stat = ldns_send(&answer_pkt, r 1130 , query_pkt); 1131 ldns_resolver_restore_rtt(r, rtt); 1132 } 1133 /* either way, if it is still truncated, use TCP */ 1134 if (stat != LDNS_STATUS_OK || 1135 ldns_pkt_tc(answer_pkt)) { 1136 ldns_resolver_set_usevc(r, true); 1137 ldns_pkt_free(answer_pkt); 1138 stat = ldns_send(&answer_pkt, r, query_pkt); 1139 ldns_resolver_set_usevc(r, false); 1140 } 1141 } 1142 } 1143 } 1144 1145 if (answer) { 1146 *answer = answer_pkt; 1147 } 1148 1149 return stat; 1150} 1151 1152ldns_status 1153ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, 1154 const ldns_rdf *name, ldns_rr_type t, 1155 ldns_rr_class c, uint16_t flags) 1156{ 1157 struct timeval now; 1158 1159 /* prepare a question pkt from the parameters 1160 * and then send this */ 1161 if (t == LDNS_RR_TYPE_IXFR) { 1162 *query_pkt = ldns_pkt_ixfr_request_new(ldns_rdf_clone(name), 1163 c, flags, NULL); 1164 } else { 1165 *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags); 1166 } 1167 if (!*query_pkt) { 1168 return LDNS_STATUS_ERR; 1169 } 1170 1171 /* set DO bit if necessary */ 1172 if (ldns_resolver_dnssec(r)) { 1173 if (ldns_resolver_edns_udp_size(r) == 0) { 1174 ldns_resolver_set_edns_udp_size(r, 4096); 1175 } 1176 ldns_pkt_set_edns_do(*query_pkt, true); 1177 if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) { 1178 ldns_pkt_set_cd(*query_pkt, true); 1179 } 1180 } 1181 1182 /* transfer the udp_edns_size from the resolver to the packet */ 1183 if (ldns_resolver_edns_udp_size(r) != 0) { 1184 ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r)); 1185 } 1186 1187 /* set the timestamp */ 1188 now.tv_sec = time(NULL); 1189 now.tv_usec = 0; 1190 ldns_pkt_set_timestamp(*query_pkt, now); 1191 1192 1193 if (ldns_resolver_debug(r)) { 1194 ldns_pkt_print(stdout, *query_pkt); 1195 } 1196 1197 /* only set the id if it is not set yet */ 1198 if (ldns_pkt_id(*query_pkt) == 0) { 1199 ldns_pkt_set_random_id(*query_pkt); 1200 } 1201 1202 return LDNS_STATUS_OK; 1203} 1204 1205 1206ldns_status 1207ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, 1208 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1209{ 1210 ldns_pkt *query_pkt; 1211 ldns_pkt *answer_pkt; 1212 ldns_status status; 1213 1214 assert(r != NULL); 1215 assert(name != NULL); 1216 1217 answer_pkt = NULL; 1218 1219 /* do all the preprocessing here, then fire of an query to 1220 * the network */ 1221 1222 if (0 == t) { 1223 t= LDNS_RR_TYPE_A; 1224 } 1225 if (0 == c) { 1226 c= LDNS_RR_CLASS_IN; 1227 } 1228 if (0 == ldns_resolver_nameserver_count(r)) { 1229 return LDNS_STATUS_RES_NO_NS; 1230 } 1231 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) { 1232 return LDNS_STATUS_RES_QUERY; 1233 } 1234 1235 status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name, 1236 t, c, flags); 1237 if (status != LDNS_STATUS_OK) { 1238 return status; 1239 } 1240 1241 /* if tsig values are set, tsign it */ 1242 /* TODO: make last 3 arguments optional too? maybe make complete 1243 rr instead of separate values in resolver (and packet) 1244 Jelte 1245 should this go in pkt_prepare? 1246 */ 1247 if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) { 1248#ifdef HAVE_SSL 1249 status = ldns_pkt_tsig_sign(query_pkt, 1250 ldns_resolver_tsig_keyname(r), 1251 ldns_resolver_tsig_keydata(r), 1252 300, ldns_resolver_tsig_algorithm(r), NULL); 1253 if (status != LDNS_STATUS_OK) { 1254 ldns_pkt_free(query_pkt); 1255 return LDNS_STATUS_CRYPTO_TSIG_ERR; 1256 } 1257#else 1258 ldns_pkt_free(query_pkt); 1259 return LDNS_STATUS_CRYPTO_TSIG_ERR; 1260#endif /* HAVE_SSL */ 1261 } 1262 1263 status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt); 1264 ldns_pkt_free(query_pkt); 1265 1266 /* allows answer to be NULL when not interested in return value */ 1267 if (answer) { 1268 *answer = answer_pkt; 1269 } 1270 return status; 1271} 1272 1273ldns_rr * 1274ldns_axfr_next(ldns_resolver *resolver) 1275{ 1276 ldns_rr *cur_rr; 1277 uint8_t *packet_wire; 1278 size_t packet_wire_size; 1279 ldns_lookup_table *rcode; 1280 ldns_status status; 1281 1282 /* check if start() has been called */ 1283 if (!resolver || resolver->_socket == 0) { 1284 return NULL; 1285 } 1286 1287 if (resolver->_cur_axfr_pkt) { 1288 if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) { 1289 ldns_pkt_free(resolver->_cur_axfr_pkt); 1290 resolver->_cur_axfr_pkt = NULL; 1291 return ldns_axfr_next(resolver); 1292 } 1293 cur_rr = ldns_rr_clone(ldns_rr_list_rr( 1294 ldns_pkt_answer(resolver->_cur_axfr_pkt), 1295 resolver->_axfr_i)); 1296 resolver->_axfr_i++; 1297 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { 1298 resolver->_axfr_soa_count++; 1299 if (resolver->_axfr_soa_count >= 2) { 1300#ifndef USE_WINSOCK 1301 close(resolver->_socket); 1302#else 1303 closesocket(resolver->_socket); 1304#endif 1305 resolver->_socket = 0; 1306 ldns_pkt_free(resolver->_cur_axfr_pkt); 1307 resolver->_cur_axfr_pkt = NULL; 1308 } 1309 } 1310 return cur_rr; 1311 } else { 1312 packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); 1313 if(!packet_wire) 1314 return NULL; 1315 1316 status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, 1317 packet_wire_size); 1318 LDNS_FREE(packet_wire); 1319 1320 resolver->_axfr_i = 0; 1321 if (status != LDNS_STATUS_OK) { 1322 /* TODO: make status return type of this function (...api change) */ 1323#ifdef STDERR_MSGS 1324 fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status)); 1325#endif 1326 1327 /* we must now also close the socket, otherwise subsequent uses of the 1328 same resolver structure will fail because the link is still open or 1329 in an undefined state */ 1330#ifndef USE_WINSOCK 1331 close(resolver->_socket); 1332#else 1333 closesocket(resolver->_socket); 1334#endif 1335 resolver->_socket = 0; 1336 1337 return NULL; 1338 } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { 1339 rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt)); 1340#ifdef STDERR_MSGS 1341 if (rcode) { 1342 fprintf(stderr, "Error in AXFR: %s\n", 1343 rcode->name); 1344 } else { 1345 fprintf(stderr, "Error in AXFR: %d\n", 1346 (int) ldns_pkt_get_rcode( 1347 resolver->_cur_axfr_pkt)); 1348 } 1349#endif 1350 1351 /* we must now also close the socket, otherwise subsequent uses of the 1352 same resolver structure will fail because the link is still open or 1353 in an undefined state */ 1354#ifndef USE_WINSOCK 1355 close(resolver->_socket); 1356#else 1357 closesocket(resolver->_socket); 1358#endif 1359 resolver->_socket = 0; 1360 1361 return NULL; 1362 } else { 1363 return ldns_axfr_next(resolver); 1364 } 1365 1366 } 1367 1368} 1369 1370/* this function is needed to abort a transfer that is in progress; 1371 * without it an aborted transfer will lead to the AXFR code in the 1372 * library staying in an indetermined state because the socket for the 1373 * AXFR is never closed 1374 */ 1375void 1376ldns_axfr_abort(ldns_resolver *resolver) 1377{ 1378 /* Only abort if an actual AXFR is in progress */ 1379 if (resolver->_socket != 0) 1380 { 1381#ifndef USE_WINSOCK 1382 close(resolver->_socket); 1383#else 1384 closesocket(resolver->_socket); 1385#endif 1386 resolver->_socket = 0; 1387 } 1388} 1389 1390bool 1391ldns_axfr_complete(const ldns_resolver *res) 1392{ 1393 /* complete when soa count is 2? */ 1394 return res->_axfr_soa_count == 2; 1395} 1396 1397ldns_pkt * 1398ldns_axfr_last_pkt(const ldns_resolver *res) 1399{ 1400 return res->_cur_axfr_pkt; 1401} 1402 1403/* random isn't really that good */ 1404void 1405ldns_resolver_nameservers_randomize(ldns_resolver *r) 1406{ 1407 uint16_t i, j; 1408 ldns_rdf **ns, *tmpns; 1409 size_t *rtt, tmprtt; 1410 1411 /* should I check for ldns_resolver_random?? */ 1412 assert(r != NULL); 1413 1414 ns = ldns_resolver_nameservers(r); 1415 rtt = ldns_resolver_rtt(r); 1416 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { 1417 j = ldns_get_random() % ldns_resolver_nameserver_count(r); 1418 tmpns = ns[i]; 1419 ns[i] = ns[j]; 1420 ns[j] = tmpns; 1421 tmprtt = rtt[i]; 1422 rtt[i] = rtt[j]; 1423 rtt[j] = tmprtt; 1424 } 1425 ldns_resolver_set_nameservers(r, ns); 1426} 1427 1428