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