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 LDNS_FREE(r->_tsig_keyname); 546 r->_tsig_keyname = strdup(tsig_keyname); 547 } 548 549 void 550 ldns_resolver_set_tsig_algorithm(ldns_resolver *r, char *tsig_algorithm) 551 { 552 LDNS_FREE(r->_tsig_algorithm); 553 r->_tsig_algorithm = strdup(tsig_algorithm); 554 } 555 556 void 557 ldns_resolver_set_tsig_keydata(ldns_resolver *r, char *tsig_keydata) 558 { 559 LDNS_FREE(r->_tsig_keydata); 560 r->_tsig_keydata = strdup(tsig_keydata); 561 } 562 563 void 564 ldns_resolver_set_random(ldns_resolver *r, bool b) 565 { 566 r->_random = b; 567 } 568 569 /* more sophisticated functions */ 570 ldns_resolver * 571 ldns_resolver_new(void) 572 { 573 ldns_resolver *r; 574 575 r = LDNS_MALLOC(ldns_resolver); 576 if (!r) { 577 return NULL; 578 } 579 580 r->_searchlist = NULL; 581 r->_nameservers = NULL; 582 r->_rtt = NULL; 583 584 /* defaults are filled out */ 585 ldns_resolver_set_searchlist_count(r, 0); 586 ldns_resolver_set_nameserver_count(r, 0); 587 ldns_resolver_set_usevc(r, 0); 588 ldns_resolver_set_port(r, LDNS_PORT); 589 ldns_resolver_set_domain(r, NULL); 590 ldns_resolver_set_defnames(r, false); 591 ldns_resolver_set_retry(r, 3); 592 ldns_resolver_set_retrans(r, 2); 593 ldns_resolver_set_fallback(r, true); 594 ldns_resolver_set_fail(r, false); 595 ldns_resolver_set_edns_udp_size(r, 0); 596 ldns_resolver_set_dnssec(r, false); 597 ldns_resolver_set_dnssec_cd(r, false); 598 ldns_resolver_set_dnssec_anchors(r, NULL); 599 ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY); 600 ldns_resolver_set_igntc(r, false); 601 ldns_resolver_set_recursive(r, false); 602 ldns_resolver_set_dnsrch(r, true); 603 604 /* randomize the nameserver to be queried 605 * when there are multiple 606 */ 607 ldns_resolver_set_random(r, true); 608 609 ldns_resolver_set_debug(r, 0); 610 611 r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; 612 r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC; 613 614 /* TODO: fd=0 is actually a valid socket (stdin), 615 replace with -1 */ 616 r->_socket = 0; 617 r->_axfr_soa_count = 0; 618 r->_axfr_i = 0; 619 r->_cur_axfr_pkt = NULL; 620 621 r->_tsig_keyname = NULL; 622 r->_tsig_keydata = NULL; 623 r->_tsig_algorithm = NULL; 624 return r; 625 } 626 627 ldns_status 628 ldns_resolver_new_frm_fp(ldns_resolver **res, FILE *fp) 629 { 630 return ldns_resolver_new_frm_fp_l(res, fp, NULL); 631 } 632 633 ldns_status 634 ldns_resolver_new_frm_fp_l(ldns_resolver **res, FILE *fp, int *line_nr) 635 { 636 ldns_resolver *r; 637 const char *keyword[LDNS_RESOLV_KEYWORDS]; 638 char word[LDNS_MAX_LINELEN + 1]; 639 int8_t expect; 640 uint8_t i; 641 ldns_rdf *tmp; 642 #ifdef HAVE_SSL 643 ldns_rr *tmp_rr; 644 #endif 645 ssize_t gtr, bgtr; 646 ldns_buffer *b; 647 int lnr = 0, oldline; 648 if(!line_nr) line_nr = &lnr; 649 650 /* do this better 651 * expect = 652 * 0: keyword 653 * 1: default domain dname 654 * 2: NS aaaa or a record 655 */ 656 657 /* recognized keywords */ 658 keyword[LDNS_RESOLV_NAMESERVER] = "nameserver"; 659 keyword[LDNS_RESOLV_DEFDOMAIN] = "domain"; 660 keyword[LDNS_RESOLV_SEARCH] = "search"; 661 /* these two are read but not used atm TODO */ 662 keyword[LDNS_RESOLV_SORTLIST] = "sortlist"; 663 keyword[LDNS_RESOLV_OPTIONS] = "options"; 664 keyword[LDNS_RESOLV_ANCHOR] = "anchor"; 665 expect = LDNS_RESOLV_KEYWORD; 666 667 r = ldns_resolver_new(); 668 if (!r) { 669 return LDNS_STATUS_MEM_ERR; 670 } 671 672 gtr = 1; 673 word[0] = 0; 674 oldline = *line_nr; 675 expect = LDNS_RESOLV_KEYWORD; 676 while (gtr > 0) { 677 /* check comments */ 678 if (word[0] == '#') { 679 word[0]='x'; 680 if(oldline == *line_nr) { 681 /* skip until end of line */ 682 int c; 683 do { 684 c = fgetc(fp); 685 } while(c != EOF && c != '\n'); 686 if(c=='\n' && line_nr) (*line_nr)++; 687 } 688 /* and read next to prepare for further parsing */ 689 oldline = *line_nr; 690 continue; 691 } 692 oldline = *line_nr; 693 switch(expect) { 694 case LDNS_RESOLV_KEYWORD: 695 /* keyword */ 696 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 697 if (gtr != 0) { 698 if(word[0] == '#') continue; 699 for(i = 0; i < LDNS_RESOLV_KEYWORDS; i++) { 700 if (strcasecmp(keyword[i], word) == 0) { 701 /* chosen the keyword and 702 * expect values carefully 703 */ 704 expect = i; 705 break; 706 } 707 } 708 /* no keyword recognized */ 709 if (expect == LDNS_RESOLV_KEYWORD) { 710 /* skip line */ 711 /* 712 ldns_resolver_deep_free(r); 713 return LDNS_STATUS_SYNTAX_KEYWORD_ERR; 714 */ 715 } 716 } 717 break; 718 case LDNS_RESOLV_DEFDOMAIN: 719 /* default domain dname */ 720 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 721 if (gtr == 0) { 722 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 723 } 724 if(word[0] == '#') { 725 expect = LDNS_RESOLV_KEYWORD; 726 continue; 727 } 728 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 729 if (!tmp) { 730 ldns_resolver_deep_free(r); 731 return LDNS_STATUS_SYNTAX_DNAME_ERR; 732 } 733 734 /* DOn't free, because we copy the pointer */ 735 ldns_resolver_set_domain(r, tmp); 736 expect = LDNS_RESOLV_KEYWORD; 737 break; 738 case LDNS_RESOLV_NAMESERVER: 739 /* NS aaaa or a record */ 740 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 741 if (gtr == 0) { 742 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 743 } 744 if(word[0] == '#') { 745 expect = LDNS_RESOLV_KEYWORD; 746 continue; 747 } 748 if(strchr(word, '%')) { 749 /* snip off interface labels, 750 * fe80::222:19ff:fe31:4222%eth0 */ 751 strchr(word, '%')[0]=0; 752 } 753 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_AAAA, word); 754 if (!tmp) { 755 /* try ip4 */ 756 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_A, word); 757 } 758 /* could not parse it, exit */ 759 if (!tmp) { 760 ldns_resolver_deep_free(r); 761 return LDNS_STATUS_SYNTAX_ERR; 762 } 763 (void)ldns_resolver_push_nameserver(r, tmp); 764 ldns_rdf_deep_free(tmp); 765 expect = LDNS_RESOLV_KEYWORD; 766 break; 767 case LDNS_RESOLV_SEARCH: 768 /* search list domain dname */ 769 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 770 b = LDNS_MALLOC(ldns_buffer); 771 if(!b) { 772 ldns_resolver_deep_free(r); 773 return LDNS_STATUS_MEM_ERR; 774 } 775 776 ldns_buffer_new_frm_data(b, word, (size_t) gtr); 777 if(ldns_buffer_status(b) != LDNS_STATUS_OK) { 778 LDNS_FREE(b); 779 ldns_resolver_deep_free(r); 780 return LDNS_STATUS_MEM_ERR; 781 } 782 bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, (size_t) gtr + 1); 783 while (bgtr > 0) { 784 gtr -= bgtr; 785 if(word[0] == '#') { 786 expect = LDNS_RESOLV_KEYWORD; 787 ldns_buffer_free(b); 788 continue; 789 } 790 tmp = ldns_rdf_new_frm_str(LDNS_RDF_TYPE_DNAME, word); 791 if (!tmp) { 792 ldns_resolver_deep_free(r); 793 ldns_buffer_free(b); 794 return LDNS_STATUS_SYNTAX_DNAME_ERR; 795 } 796 797 ldns_resolver_push_searchlist(r, tmp); 798 799 ldns_rdf_deep_free(tmp); 800 bgtr = ldns_bget_token(b, word, LDNS_PARSE_NORMAL, 801 (size_t) gtr + 1); 802 } 803 ldns_buffer_free(b); 804 gtr = 1; 805 expect = LDNS_RESOLV_KEYWORD; 806 break; 807 case LDNS_RESOLV_SORTLIST: 808 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 809 /* sortlist not implemented atm */ 810 expect = LDNS_RESOLV_KEYWORD; 811 break; 812 case LDNS_RESOLV_OPTIONS: 813 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_SKIP_SPACE, 0, line_nr); 814 /* options not implemented atm */ 815 expect = LDNS_RESOLV_KEYWORD; 816 break; 817 case LDNS_RESOLV_ANCHOR: 818 /* a file containing a DNSSEC trust anchor */ 819 gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr); 820 if (gtr == 0) { 821 ldns_resolver_deep_free(r); 822 return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR; 823 } 824 if(word[0] == '#') { 825 expect = LDNS_RESOLV_KEYWORD; 826 continue; 827 } 828 829 #ifdef HAVE_SSL 830 tmp_rr = ldns_read_anchor_file(word); 831 (void) ldns_resolver_push_dnssec_anchor(r, tmp_rr); 832 ldns_rr_free(tmp_rr); 833 #endif 834 expect = LDNS_RESOLV_KEYWORD; 835 break; 836 } 837 } 838 839 if (res) { 840 *res = r; 841 return LDNS_STATUS_OK; 842 } else { 843 ldns_resolver_deep_free(r); 844 return LDNS_STATUS_NULL; 845 } 846 } 847 848 ldns_status 849 ldns_resolver_new_frm_file(ldns_resolver **res, const char *filename) 850 { 851 ldns_resolver *r; 852 FILE *fp; 853 ldns_status s; 854 855 if (!filename) { 856 fp = fopen(LDNS_RESOLV_CONF, "r"); 857 858 } else { 859 fp = fopen(filename, "r"); 860 } 861 if (!fp) { 862 return LDNS_STATUS_FILE_ERR; 863 } 864 865 s = ldns_resolver_new_frm_fp(&r, fp); 866 fclose(fp); 867 if (s == LDNS_STATUS_OK) { 868 if (res) { 869 *res = r; 870 return LDNS_STATUS_OK; 871 } else { 872 return LDNS_STATUS_NULL; 873 } 874 } 875 return s; 876 } 877 878 void 879 ldns_resolver_free(ldns_resolver *res) 880 { 881 LDNS_FREE(res); 882 } 883 884 void 885 ldns_resolver_deep_free(ldns_resolver *res) 886 { 887 size_t i; 888 889 if (res) { 890 if (res->_searchlist) { 891 for (i = 0; i < ldns_resolver_searchlist_count(res); i++) { 892 ldns_rdf_deep_free(res->_searchlist[i]); 893 } 894 LDNS_FREE(res->_searchlist); 895 } 896 if (res->_nameservers) { 897 for (i = 0; i < res->_nameserver_count; i++) { 898 ldns_rdf_deep_free(res->_nameservers[i]); 899 } 900 LDNS_FREE(res->_nameservers); 901 } 902 if (ldns_resolver_domain(res)) { 903 ldns_rdf_deep_free(ldns_resolver_domain(res)); 904 } 905 if (res->_tsig_keyname) { 906 LDNS_FREE(res->_tsig_keyname); 907 } 908 if (res->_tsig_keydata) { 909 LDNS_FREE(res->_tsig_keydata); 910 } 911 if (res->_tsig_algorithm) { 912 LDNS_FREE(res->_tsig_algorithm); 913 } 914 915 if (res->_cur_axfr_pkt) { 916 ldns_pkt_free(res->_cur_axfr_pkt); 917 } 918 919 if (res->_rtt) { 920 LDNS_FREE(res->_rtt); 921 } 922 if (res->_dnssec_anchors) { 923 ldns_rr_list_deep_free(res->_dnssec_anchors); 924 } 925 LDNS_FREE(res); 926 } 927 } 928 929 ldns_pkt * 930 ldns_resolver_search(const ldns_resolver *r,const ldns_rdf *name, 931 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 932 { 933 934 char *str_dname; 935 ldns_rdf *new_name; 936 ldns_rdf **search_list; 937 size_t i; 938 ldns_pkt *p; 939 940 str_dname = ldns_rdf2str(name); 941 942 if (ldns_dname_str_absolute(str_dname)) { 943 /* query as-is */ 944 return ldns_resolver_query(r, name, t, c, flags); 945 } else if (ldns_resolver_dnsrch(r)) { 946 search_list = ldns_resolver_searchlist(r); 947 for (i = 0; i < ldns_resolver_searchlist_count(r); i++) { 948 new_name = ldns_dname_cat_clone(name, search_list[i]); 949 950 p = ldns_resolver_query(r, new_name, t, c, flags); 951 ldns_rdf_free(new_name); 952 if (p) { 953 if (ldns_pkt_get_rcode(p) == LDNS_RCODE_NOERROR) { 954 return p; 955 } else { 956 ldns_pkt_free(p); 957 p = NULL; 958 } 959 } 960 } 961 } 962 return NULL; 963 } 964 965 ldns_pkt * 966 ldns_resolver_query(const ldns_resolver *r, const ldns_rdf *name, 967 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 968 { 969 ldns_rdf *newname; 970 ldns_pkt *pkt; 971 ldns_status status; 972 973 pkt = NULL; 974 975 if (!ldns_resolver_defnames(r)) { 976 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name, 977 t, c, flags); 978 if (status == LDNS_STATUS_OK) { 979 return pkt; 980 } else { 981 if (pkt) { 982 ldns_pkt_free(pkt); 983 } 984 return NULL; 985 } 986 } 987 988 if (!ldns_resolver_domain(r)) { 989 /* _defnames is set, but the domain is not....?? */ 990 status = ldns_resolver_send(&pkt, (ldns_resolver *)r, name, 991 t, c, flags); 992 if (status == LDNS_STATUS_OK) { 993 return pkt; 994 } else { 995 if (pkt) { 996 ldns_pkt_free(pkt); 997 } 998 return NULL; 999 } 1000 } 1001 1002 newname = ldns_dname_cat_clone((const ldns_rdf*)name, ldns_resolver_domain(r)); 1003 if (!newname) { 1004 if (pkt) { 1005 ldns_pkt_free(pkt); 1006 } 1007 return NULL; 1008 } 1009 1010 (void)ldns_resolver_send(&pkt, (ldns_resolver *)r, newname, t, c, 1011 flags); 1012 1013 ldns_rdf_free(newname); 1014 1015 return pkt; 1016 } 1017 1018 ldns_status 1019 ldns_resolver_send_pkt(ldns_pkt **answer, ldns_resolver *r, 1020 ldns_pkt *query_pkt) 1021 { 1022 ldns_pkt *answer_pkt = NULL; 1023 ldns_status stat = LDNS_STATUS_OK; 1024 1025 stat = ldns_send(&answer_pkt, (ldns_resolver *)r, query_pkt); 1026 if (stat != LDNS_STATUS_OK) { 1027 if(answer_pkt) { 1028 ldns_pkt_free(answer_pkt); 1029 answer_pkt = NULL; 1030 } 1031 } else { 1032 /* if tc=1 fall back to EDNS and/or TCP */ 1033 /* check for tcp first (otherwise we don't care about tc=1) */ 1034 if (!ldns_resolver_usevc(r) && ldns_resolver_fallback(r)) { 1035 if (ldns_pkt_tc(answer_pkt)) { 1036 /* was EDNS0 set? */ 1037 if (ldns_pkt_edns_udp_size(query_pkt) == 0) { 1038 ldns_pkt_set_edns_udp_size(query_pkt, 4096); 1039 ldns_pkt_free(answer_pkt); 1040 stat = ldns_send(&answer_pkt, r, query_pkt); 1041 } 1042 /* either way, if it is still truncated, use TCP */ 1043 if (stat != LDNS_STATUS_OK || 1044 ldns_pkt_tc(answer_pkt)) { 1045 ldns_resolver_set_usevc(r, true); 1046 ldns_pkt_free(answer_pkt); 1047 stat = ldns_send(&answer_pkt, r, query_pkt); 1048 ldns_resolver_set_usevc(r, false); 1049 } 1050 } 1051 } 1052 } 1053 1054 if (answer) { 1055 *answer = answer_pkt; 1056 } 1057 1058 return stat; 1059 } 1060 1061 ldns_status 1062 ldns_resolver_prepare_query_pkt(ldns_pkt **query_pkt, ldns_resolver *r, 1063 const ldns_rdf *name, ldns_rr_type t, 1064 ldns_rr_class c, uint16_t flags) 1065 { 1066 /* prepare a question pkt from the parameters 1067 * and then send this */ 1068 *query_pkt = ldns_pkt_query_new(ldns_rdf_clone(name), t, c, flags); 1069 if (!*query_pkt) { 1070 return LDNS_STATUS_ERR; 1071 } 1072 1073 /* set DO bit if necessary */ 1074 if (ldns_resolver_dnssec(r)) { 1075 if (ldns_resolver_edns_udp_size(r) == 0) { 1076 ldns_resolver_set_edns_udp_size(r, 4096); 1077 } 1078 ldns_pkt_set_edns_do(*query_pkt, true); 1079 if (ldns_resolver_dnssec_cd(r) || (flags & LDNS_CD)) { 1080 ldns_pkt_set_cd(*query_pkt, true); 1081 } 1082 } 1083 1084 /* transfer the udp_edns_size from the resolver to the packet */ 1085 if (ldns_resolver_edns_udp_size(r) != 0) { 1086 ldns_pkt_set_edns_udp_size(*query_pkt, ldns_resolver_edns_udp_size(r)); 1087 } 1088 1089 if (ldns_resolver_debug(r)) { 1090 ldns_pkt_print(stdout, *query_pkt); 1091 } 1092 1093 /* only set the id if it is not set yet */ 1094 if (ldns_pkt_id(*query_pkt) == 0) { 1095 ldns_pkt_set_random_id(*query_pkt); 1096 } 1097 1098 return LDNS_STATUS_OK; 1099 } 1100 1101 1102 ldns_status 1103 ldns_resolver_send(ldns_pkt **answer, ldns_resolver *r, const ldns_rdf *name, 1104 ldns_rr_type t, ldns_rr_class c, uint16_t flags) 1105 { 1106 ldns_pkt *query_pkt; 1107 ldns_pkt *answer_pkt; 1108 ldns_status status; 1109 1110 assert(r != NULL); 1111 assert(name != NULL); 1112 1113 answer_pkt = NULL; 1114 1115 /* do all the preprocessing here, then fire of an query to 1116 * the network */ 1117 1118 if (0 == t) { 1119 t= LDNS_RR_TYPE_A; 1120 } 1121 if (0 == c) { 1122 c= LDNS_RR_CLASS_IN; 1123 } 1124 if (0 == ldns_resolver_nameserver_count(r)) { 1125 return LDNS_STATUS_RES_NO_NS; 1126 } 1127 if (ldns_rdf_get_type(name) != LDNS_RDF_TYPE_DNAME) { 1128 return LDNS_STATUS_RES_QUERY; 1129 } 1130 1131 status = ldns_resolver_prepare_query_pkt(&query_pkt, r, name, 1132 t, c, flags); 1133 if (status != LDNS_STATUS_OK) { 1134 return status; 1135 } 1136 1137 /* if tsig values are set, tsign it */ 1138 /* TODO: make last 3 arguments optional too? maybe make complete 1139 rr instead of seperate values in resolver (and packet) 1140 Jelte 1141 should this go in pkt_prepare? 1142 */ 1143 #ifdef HAVE_SSL 1144 if (ldns_resolver_tsig_keyname(r) && ldns_resolver_tsig_keydata(r)) { 1145 status = ldns_pkt_tsig_sign(query_pkt, 1146 ldns_resolver_tsig_keyname(r), 1147 ldns_resolver_tsig_keydata(r), 1148 300, ldns_resolver_tsig_algorithm(r), NULL); 1149 if (status != LDNS_STATUS_OK) { 1150 return LDNS_STATUS_CRYPTO_TSIG_ERR; 1151 } 1152 } 1153 #else 1154 return LDNS_STATUS_CRYPTO_TSIG_ERR; 1155 #endif /* HAVE_SSL */ 1156 1157 status = ldns_resolver_send_pkt(&answer_pkt, r, query_pkt); 1158 ldns_pkt_free(query_pkt); 1159 1160 /* allows answer to be NULL when not interested in return value */ 1161 if (answer) { 1162 *answer = answer_pkt; 1163 } 1164 return status; 1165 } 1166 1167 ldns_rr * 1168 ldns_axfr_next(ldns_resolver *resolver) 1169 { 1170 ldns_rr *cur_rr; 1171 uint8_t *packet_wire; 1172 size_t packet_wire_size; 1173 ldns_lookup_table *rcode; 1174 ldns_status status; 1175 1176 /* check if start() has been called */ 1177 if (!resolver || resolver->_socket == 0) { 1178 return NULL; 1179 } 1180 1181 if (resolver->_cur_axfr_pkt) { 1182 if (resolver->_axfr_i == ldns_pkt_ancount(resolver->_cur_axfr_pkt)) { 1183 ldns_pkt_free(resolver->_cur_axfr_pkt); 1184 resolver->_cur_axfr_pkt = NULL; 1185 return ldns_axfr_next(resolver); 1186 } 1187 cur_rr = ldns_rr_clone(ldns_rr_list_rr( 1188 ldns_pkt_answer(resolver->_cur_axfr_pkt), 1189 resolver->_axfr_i)); 1190 resolver->_axfr_i++; 1191 if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { 1192 resolver->_axfr_soa_count++; 1193 if (resolver->_axfr_soa_count >= 2) { 1194 #ifndef USE_WINSOCK 1195 close(resolver->_socket); 1196 #else 1197 closesocket(resolver->_socket); 1198 #endif 1199 resolver->_socket = 0; 1200 ldns_pkt_free(resolver->_cur_axfr_pkt); 1201 resolver->_cur_axfr_pkt = NULL; 1202 } 1203 } 1204 return cur_rr; 1205 } else { 1206 packet_wire = ldns_tcp_read_wire(resolver->_socket, &packet_wire_size); 1207 if(!packet_wire) 1208 return NULL; 1209 1210 status = ldns_wire2pkt(&resolver->_cur_axfr_pkt, packet_wire, 1211 packet_wire_size); 1212 free(packet_wire); 1213 1214 resolver->_axfr_i = 0; 1215 if (status != LDNS_STATUS_OK) { 1216 /* TODO: make status return type of this function (...api change) */ 1217 fprintf(stderr, "Error parsing rr during AXFR: %s\n", ldns_get_errorstr_by_id(status)); 1218 1219 /* RoRi: we must now also close the socket, otherwise subsequent uses of the 1220 same resolver structure will fail because the link is still open or 1221 in an undefined state */ 1222 #ifndef USE_WINSOCK 1223 close(resolver->_socket); 1224 #else 1225 closesocket(resolver->_socket); 1226 #endif 1227 resolver->_socket = 0; 1228 1229 return NULL; 1230 } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { 1231 rcode = ldns_lookup_by_id(ldns_rcodes, (int) ldns_pkt_get_rcode(resolver->_cur_axfr_pkt)); 1232 fprintf(stderr, "Error in AXFR: %s\n", rcode->name); 1233 1234 /* RoRi: we must now also close the socket, otherwise subsequent uses of the 1235 same resolver structure will fail because the link is still open or 1236 in an undefined state */ 1237 #ifndef USE_WINSOCK 1238 close(resolver->_socket); 1239 #else 1240 closesocket(resolver->_socket); 1241 #endif 1242 resolver->_socket = 0; 1243 1244 return NULL; 1245 } else { 1246 return ldns_axfr_next(resolver); 1247 } 1248 1249 } 1250 1251 } 1252 1253 bool 1254 ldns_axfr_complete(const ldns_resolver *res) 1255 { 1256 /* complete when soa count is 2? */ 1257 return res->_axfr_soa_count == 2; 1258 } 1259 1260 ldns_pkt * 1261 ldns_axfr_last_pkt(const ldns_resolver *res) 1262 { 1263 return res->_cur_axfr_pkt; 1264 } 1265 1266 /* random isn't really that good */ 1267 void 1268 ldns_resolver_nameservers_randomize(ldns_resolver *r) 1269 { 1270 uint16_t i, j; 1271 ldns_rdf **ns, *tmp; 1272 1273 /* should I check for ldns_resolver_random?? */ 1274 assert(r != NULL); 1275 1276 ns = ldns_resolver_nameservers(r); 1277 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { 1278 j = ldns_get_random() % ldns_resolver_nameserver_count(r); 1279 tmp = ns[i]; 1280 ns[i] = ns[j]; 1281 ns[j] = tmp; 1282 } 1283 ldns_resolver_set_nameservers(r, ns); 1284 } 1285 1286