1 /* 2 * net.c 3 * 4 * Network implementation 5 * All network related functions are grouped here 6 * 7 * a Net::DNS like library for C 8 * 9 * (c) NLnet Labs, 2004-2006 10 * 11 * See the file LICENSE for the license 12 */ 13 14 #include <ldns/config.h> 15 16 #include <ldns/ldns.h> 17 18 #ifdef HAVE_NETINET_IN_H 19 #include <netinet/in.h> 20 #endif 21 #ifdef HAVE_SYS_SOCKET_H 22 #include <sys/socket.h> 23 #endif 24 #ifdef HAVE_NETDB_H 25 #include <netdb.h> 26 #endif 27 #ifdef HAVE_ARPA_INET_H 28 #include <arpa/inet.h> 29 #endif 30 #include <sys/time.h> 31 #include <errno.h> 32 #include <fcntl.h> 33 34 ldns_status 35 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt) 36 { 37 ldns_buffer *qb; 38 ldns_status result; 39 ldns_rdf *tsig_mac = NULL; 40 41 qb = ldns_buffer_new(LDNS_MIN_BUFLEN); 42 43 if (query_pkt && ldns_pkt_tsig(query_pkt)) { 44 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3); 45 } 46 47 if (!query_pkt || 48 ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) { 49 result = LDNS_STATUS_ERR; 50 } else { 51 result = ldns_send_buffer(result_packet, r, qb, tsig_mac); 52 } 53 54 ldns_buffer_free(qb); 55 56 return result; 57 } 58 59 ldns_status 60 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac) 61 { 62 uint8_t i; 63 64 struct sockaddr_storage *ns; 65 size_t ns_len; 66 struct timeval tv_s; 67 struct timeval tv_e; 68 69 ldns_rdf **ns_array; 70 size_t *rtt; 71 ldns_pkt *reply; 72 bool all_servers_rtt_inf; 73 uint8_t retries; 74 75 uint8_t *reply_bytes = NULL; 76 size_t reply_size = 0; 77 ldns_status status, send_status; 78 79 assert(r != NULL); 80 81 status = LDNS_STATUS_OK; 82 rtt = ldns_resolver_rtt(r); 83 ns_array = ldns_resolver_nameservers(r); 84 reply = NULL; 85 ns_len = 0; 86 87 all_servers_rtt_inf = true; 88 89 if (ldns_resolver_random(r)) { 90 ldns_resolver_nameservers_randomize(r); 91 } 92 93 /* loop through all defined nameservers */ 94 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) { 95 if (rtt[i] == LDNS_RESOLV_RTT_INF) { 96 /* not reachable nameserver! */ 97 continue; 98 } 99 100 /* maybe verbosity setting? 101 printf("Sending to "); 102 ldns_rdf_print(stdout, ns_array[i]); 103 printf("\n"); 104 */ 105 ns = ldns_rdf2native_sockaddr_storage(ns_array[i], 106 ldns_resolver_port(r), &ns_len); 107 108 109 #ifndef S_SPLINT_S 110 if ((ns->ss_family == AF_INET) && 111 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) { 112 /* not reachable */ 113 continue; 114 } 115 116 if ((ns->ss_family == AF_INET6) && 117 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) { 118 /* not reachable */ 119 continue; 120 } 121 #endif 122 123 all_servers_rtt_inf = false; 124 125 gettimeofday(&tv_s, NULL); 126 127 send_status = LDNS_STATUS_ERR; 128 129 /* reply_bytes implicitly handles our error */ 130 if (1 == ldns_resolver_usevc(r)) { 131 for (retries = ldns_resolver_retry(r); retries > 0; retries--) { 132 send_status = 133 ldns_tcp_send(&reply_bytes, qb, ns, 134 (socklen_t)ns_len, ldns_resolver_timeout(r), 135 &reply_size); 136 if (send_status == LDNS_STATUS_OK) { 137 break; 138 } 139 } 140 } else { 141 for (retries = ldns_resolver_retry(r); retries > 0; retries--) { 142 /* ldns_rdf_print(stdout, ns_array[i]); */ 143 send_status = 144 ldns_udp_send(&reply_bytes, qb, ns, 145 (socklen_t)ns_len, ldns_resolver_timeout(r), 146 &reply_size); 147 148 if (send_status == LDNS_STATUS_OK) { 149 break; 150 } 151 } 152 } 153 154 if (send_status != LDNS_STATUS_OK) { 155 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF); 156 status = send_status; 157 } 158 159 /* obey the fail directive */ 160 if (!reply_bytes) { 161 /* the current nameserver seems to have a problem, blacklist it */ 162 if (ldns_resolver_fail(r)) { 163 LDNS_FREE(ns); 164 return LDNS_STATUS_ERR; 165 } else { 166 LDNS_FREE(ns); 167 continue; 168 } 169 } 170 171 status = ldns_wire2pkt(&reply, reply_bytes, reply_size); 172 if (status != LDNS_STATUS_OK) { 173 LDNS_FREE(reply_bytes); 174 LDNS_FREE(ns); 175 return status; 176 } 177 178 LDNS_FREE(ns); 179 gettimeofday(&tv_e, NULL); 180 181 if (reply) { 182 ldns_pkt_set_querytime(reply, (uint32_t) 183 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) + 184 (tv_e.tv_usec - tv_s.tv_usec) / 1000); 185 ldns_pkt_set_answerfrom(reply, ns_array[i]); 186 ldns_pkt_set_timestamp(reply, tv_s); 187 ldns_pkt_set_size(reply, reply_size); 188 break; 189 } else { 190 if (ldns_resolver_fail(r)) { 191 /* if fail is set bail out, after the first 192 * one */ 193 break; 194 } 195 } 196 197 /* wait retrans seconds... */ 198 sleep((unsigned int) ldns_resolver_retrans(r)); 199 } 200 201 if (all_servers_rtt_inf) { 202 LDNS_FREE(reply_bytes); 203 return LDNS_STATUS_RES_NO_NS; 204 } 205 #ifdef HAVE_SSL 206 if (tsig_mac && reply_bytes) { 207 if (!ldns_pkt_tsig_verify(reply, 208 reply_bytes, 209 reply_size, 210 ldns_resolver_tsig_keyname(r), 211 ldns_resolver_tsig_keydata(r), tsig_mac)) { 212 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS; 213 } 214 } 215 #else 216 (void)tsig_mac; 217 #endif /* HAVE_SSL */ 218 219 LDNS_FREE(reply_bytes); 220 if (result) { 221 *result = reply; 222 } 223 224 return status; 225 } 226 227 /** best effort to set nonblocking */ 228 static void 229 ldns_sock_nonblock(int sockfd) 230 { 231 #ifdef HAVE_FCNTL 232 int flag; 233 if((flag = fcntl(sockfd, F_GETFL)) != -1) { 234 flag |= O_NONBLOCK; 235 if(fcntl(sockfd, F_SETFL, flag) == -1) { 236 /* ignore error, continue blockingly */ 237 } 238 } 239 #elif defined(HAVE_IOCTLSOCKET) 240 unsigned long on = 1; 241 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) { 242 /* ignore error, continue blockingly */ 243 } 244 #endif 245 } 246 247 /** best effort to set blocking */ 248 static void 249 ldns_sock_block(int sockfd) 250 { 251 #ifdef HAVE_FCNTL 252 int flag; 253 if((flag = fcntl(sockfd, F_GETFL)) != -1) { 254 flag &= ~O_NONBLOCK; 255 if(fcntl(sockfd, F_SETFL, flag) == -1) { 256 /* ignore error, continue */ 257 } 258 } 259 #elif defined(HAVE_IOCTLSOCKET) 260 unsigned long off = 0; 261 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) { 262 /* ignore error, continue */ 263 } 264 #endif 265 } 266 267 /** wait for a socket to become ready */ 268 static int 269 ldns_sock_wait(int sockfd, struct timeval timeout, int write) 270 { 271 int ret; 272 #ifndef S_SPLINT_S 273 fd_set fds; 274 FD_ZERO(&fds); 275 FD_SET(FD_SET_T sockfd, &fds); 276 if(write) 277 ret = select(sockfd+1, NULL, &fds, NULL, &timeout); 278 else 279 ret = select(sockfd+1, &fds, NULL, NULL, &timeout); 280 #endif 281 if(ret == 0) 282 /* timeout expired */ 283 return 0; 284 else if(ret == -1) 285 /* error */ 286 return 0; 287 return 1; 288 } 289 290 ldns_status 291 ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, 292 socklen_t tolen, struct timeval timeout, size_t *answer_size) 293 { 294 int sockfd; 295 uint8_t *answer; 296 297 sockfd = ldns_udp_bgsend(qbin, to, tolen, timeout); 298 299 if (sockfd == 0) { 300 return LDNS_STATUS_SOCKET_ERROR; 301 } 302 303 /* wait for an response*/ 304 if(!ldns_sock_wait(sockfd, timeout, 0)) { 305 #ifndef USE_WINSOCK 306 close(sockfd); 307 #else 308 closesocket(sockfd); 309 #endif 310 return LDNS_STATUS_NETWORK_ERR; 311 } 312 313 /* set to nonblocking, so if the checksum is bad, it becomes 314 * an EGAIN error and the ldns_udp_send function does not block, 315 * but returns a 'NETWORK_ERROR' much like a timeout. */ 316 ldns_sock_nonblock(sockfd); 317 318 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL); 319 #ifndef USE_WINSOCK 320 close(sockfd); 321 #else 322 closesocket(sockfd); 323 #endif 324 325 if (*answer_size == 0) { 326 /* oops */ 327 return LDNS_STATUS_NETWORK_ERR; 328 } 329 330 *result = answer; 331 return LDNS_STATUS_OK; 332 } 333 334 int 335 ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, 336 struct timeval timeout) 337 { 338 int sockfd; 339 340 sockfd = ldns_udp_connect(to, timeout); 341 342 if (sockfd == 0) { 343 return 0; 344 } 345 346 if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) { 347 #ifndef USE_WINSOCK 348 close(sockfd); 349 #else 350 closesocket(sockfd); 351 #endif 352 return 0; 353 } 354 return sockfd; 355 } 356 357 int 358 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout)) 359 { 360 int sockfd; 361 362 #ifndef S_SPLINT_S 363 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM, 364 IPPROTO_UDP)) 365 == -1) { 366 return 0; 367 } 368 #endif 369 return sockfd; 370 } 371 372 int 373 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen, 374 struct timeval timeout) 375 { 376 int sockfd; 377 378 #ifndef S_SPLINT_S 379 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM, 380 IPPROTO_TCP)) == -1) { 381 return 0; 382 } 383 #endif 384 385 /* perform nonblocking connect, to be able to wait with select() */ 386 ldns_sock_nonblock(sockfd); 387 if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) { 388 #ifndef USE_WINSOCK 389 #ifdef EINPROGRESS 390 if(errno != EINPROGRESS) { 391 #else 392 if(1) { 393 #endif 394 close(sockfd); 395 return 0; 396 } 397 #else /* USE_WINSOCK */ 398 if(WSAGetLastError() != WSAEINPROGRESS && 399 WSAGetLastError() != WSAEWOULDBLOCK) { 400 closesocket(sockfd); 401 return 0; 402 } 403 #endif 404 /* error was only telling us that it would block */ 405 } 406 407 /* wait(write) until connected or error */ 408 while(1) { 409 int error = 0; 410 socklen_t len = (socklen_t)sizeof(error); 411 412 if(!ldns_sock_wait(sockfd, timeout, 1)) { 413 #ifndef USE_WINSOCK 414 close(sockfd); 415 #else 416 closesocket(sockfd); 417 #endif 418 return 0; 419 } 420 421 /* check if there is a pending error for nonblocking connect */ 422 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error, 423 &len) < 0) { 424 #ifndef USE_WINSOCK 425 error = errno; /* on solaris errno is error */ 426 #else 427 error = WSAGetLastError(); 428 #endif 429 } 430 #ifndef USE_WINSOCK 431 #if defined(EINPROGRESS) && defined(EWOULDBLOCK) 432 if(error == EINPROGRESS || error == EWOULDBLOCK) 433 continue; /* try again */ 434 #endif 435 else if(error != 0) { 436 close(sockfd); 437 /* error in errno for our user */ 438 errno = error; 439 return 0; 440 } 441 #else /* USE_WINSOCK */ 442 if(error == WSAEINPROGRESS) 443 continue; 444 else if(error == WSAEWOULDBLOCK) 445 continue; 446 else if(error != 0) { 447 closesocket(sockfd); 448 errno = error; 449 return 0; 450 } 451 #endif /* USE_WINSOCK */ 452 /* connected */ 453 break; 454 } 455 456 /* set the socket blocking again */ 457 ldns_sock_block(sockfd); 458 459 return sockfd; 460 } 461 462 ssize_t 463 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd, 464 const struct sockaddr_storage *to, socklen_t tolen) 465 { 466 uint8_t *sendbuf; 467 ssize_t bytes; 468 469 /* add length of packet */ 470 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2); 471 if(!sendbuf) return 0; 472 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin)); 473 memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin)); 474 475 bytes = sendto(sockfd, (void*)sendbuf, 476 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen); 477 478 LDNS_FREE(sendbuf); 479 480 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) { 481 return 0; 482 } 483 return bytes; 484 } 485 486 /* don't wait for an answer */ 487 ssize_t 488 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to, 489 socklen_t tolen) 490 { 491 ssize_t bytes; 492 493 bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin), 494 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen); 495 496 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) { 497 return 0; 498 } 499 if ((size_t) bytes != ldns_buffer_position(qbin)) { 500 return 0; 501 } 502 return bytes; 503 } 504 505 uint8_t * 506 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from, 507 socklen_t *fromlen) 508 { 509 uint8_t *wire, *wireout; 510 ssize_t wire_size; 511 512 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN); 513 if (!wire) { 514 *size = 0; 515 return NULL; 516 } 517 518 wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0, 519 (struct sockaddr *)from, fromlen); 520 521 /* recvfrom can also return 0 */ 522 if (wire_size == -1 || wire_size == 0) { 523 *size = 0; 524 LDNS_FREE(wire); 525 return NULL; 526 } 527 528 *size = (size_t)wire_size; 529 wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size); 530 if(!wireout) LDNS_FREE(wire); 531 532 return wireout; 533 } 534 535 uint8_t * 536 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout) 537 { 538 uint8_t *wire; 539 uint16_t wire_size; 540 ssize_t bytes = 0, rc = 0; 541 542 wire = LDNS_XMALLOC(uint8_t, 2); 543 if (!wire) { 544 *size = 0; 545 return NULL; 546 } 547 548 while (bytes < 2) { 549 if(!ldns_sock_wait(sockfd, timeout, 0)) { 550 *size = 0; 551 LDNS_FREE(wire); 552 return NULL; 553 } 554 rc = recv(sockfd, (void*) (wire + bytes), 555 (size_t) (2 - bytes), 0); 556 if (rc == -1 || rc == 0) { 557 *size = 0; 558 LDNS_FREE(wire); 559 return NULL; 560 } 561 bytes += rc; 562 } 563 564 wire_size = ldns_read_uint16(wire); 565 566 LDNS_FREE(wire); 567 wire = LDNS_XMALLOC(uint8_t, wire_size); 568 if (!wire) { 569 *size = 0; 570 return NULL; 571 } 572 bytes = 0; 573 574 while (bytes < (ssize_t) wire_size) { 575 if(!ldns_sock_wait(sockfd, timeout, 0)) { 576 *size = 0; 577 LDNS_FREE(wire); 578 return NULL; 579 } 580 rc = recv(sockfd, (void*) (wire + bytes), 581 (size_t) (wire_size - bytes), 0); 582 if (rc == -1 || rc == 0) { 583 LDNS_FREE(wire); 584 *size = 0; 585 return NULL; 586 } 587 bytes += rc; 588 } 589 590 *size = (size_t) bytes; 591 return wire; 592 } 593 594 uint8_t * 595 ldns_tcp_read_wire(int sockfd, size_t *size) 596 { 597 uint8_t *wire; 598 uint16_t wire_size; 599 ssize_t bytes = 0, rc = 0; 600 601 wire = LDNS_XMALLOC(uint8_t, 2); 602 if (!wire) { 603 *size = 0; 604 return NULL; 605 } 606 607 while (bytes < 2) { 608 rc = recv(sockfd, (void*) (wire + bytes), 609 (size_t) (2 - bytes), 0); 610 if (rc == -1 || rc == 0) { 611 *size = 0; 612 LDNS_FREE(wire); 613 return NULL; 614 } 615 bytes += rc; 616 } 617 618 wire_size = ldns_read_uint16(wire); 619 620 LDNS_FREE(wire); 621 wire = LDNS_XMALLOC(uint8_t, wire_size); 622 if (!wire) { 623 *size = 0; 624 return NULL; 625 } 626 bytes = 0; 627 628 while (bytes < (ssize_t) wire_size) { 629 rc = recv(sockfd, (void*) (wire + bytes), 630 (size_t) (wire_size - bytes), 0); 631 if (rc == -1 || rc == 0) { 632 LDNS_FREE(wire); 633 *size = 0; 634 return NULL; 635 } 636 bytes += rc; 637 } 638 639 *size = (size_t) bytes; 640 return wire; 641 } 642 643 /* keep in mind that in DNS tcp messages the first 2 bytes signal the 644 * amount data to expect 645 */ 646 ldns_status 647 ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to, 648 socklen_t tolen, struct timeval timeout, size_t *answer_size) 649 { 650 int sockfd; 651 uint8_t *answer; 652 653 sockfd = ldns_tcp_bgsend(qbin, to, tolen, timeout); 654 655 if (sockfd == 0) { 656 return LDNS_STATUS_ERR; 657 } 658 659 answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout); 660 #ifndef USE_WINSOCK 661 close(sockfd); 662 #else 663 closesocket(sockfd); 664 #endif 665 666 if (*answer_size == 0) { 667 /* oops */ 668 return LDNS_STATUS_NETWORK_ERR; 669 } 670 671 /* resize accordingly */ 672 *result = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size); 673 if(!*result) { 674 LDNS_FREE(answer); 675 return LDNS_STATUS_MEM_ERR; 676 } 677 return LDNS_STATUS_OK; 678 } 679 680 int 681 ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen, 682 struct timeval timeout) 683 { 684 int sockfd; 685 686 sockfd = ldns_tcp_connect(to, tolen, timeout); 687 688 if (sockfd == 0) { 689 return 0; 690 } 691 692 if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) { 693 #ifndef USE_WINSOCK 694 close(sockfd); 695 #else 696 closesocket(sockfd); 697 #endif 698 return 0; 699 } 700 701 return sockfd; 702 } 703 704 /* code from rdata.c */ 705 struct sockaddr_storage * 706 ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size) 707 { 708 struct sockaddr_storage *data; 709 struct sockaddr_in *data_in; 710 struct sockaddr_in6 *data_in6; 711 712 data = LDNS_MALLOC(struct sockaddr_storage); 713 if (!data) { 714 return NULL; 715 } 716 /* zero the structure for portability */ 717 memset(data, 0, sizeof(struct sockaddr_storage)); 718 if (port == 0) { 719 port = LDNS_PORT; 720 } 721 722 switch(ldns_rdf_get_type(rd)) { 723 case LDNS_RDF_TYPE_A: 724 #ifndef S_SPLINT_S 725 data->ss_family = AF_INET; 726 #endif 727 data_in = (struct sockaddr_in*) data; 728 data_in->sin_port = (in_port_t)htons(port); 729 memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd)); 730 *size = sizeof(struct sockaddr_in); 731 return data; 732 case LDNS_RDF_TYPE_AAAA: 733 #ifndef S_SPLINT_S 734 data->ss_family = AF_INET6; 735 #endif 736 data_in6 = (struct sockaddr_in6*) data; 737 data_in6->sin6_port = (in_port_t)htons(port); 738 memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd)); 739 *size = sizeof(struct sockaddr_in6); 740 return data; 741 default: 742 LDNS_FREE(data); 743 return NULL; 744 } 745 } 746 747 #ifndef S_SPLINT_S 748 ldns_rdf * 749 ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port) 750 { 751 ldns_rdf *addr; 752 struct sockaddr_in *data_in; 753 struct sockaddr_in6 *data_in6; 754 755 switch(sock->ss_family) { 756 case AF_INET: 757 data_in = (struct sockaddr_in*)sock; 758 if (port) { 759 *port = ntohs((uint16_t)data_in->sin_port); 760 } 761 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A, 762 LDNS_IP4ADDRLEN, &data_in->sin_addr); 763 break; 764 case AF_INET6: 765 data_in6 = (struct sockaddr_in6*)sock; 766 if (port) { 767 *port = ntohs((uint16_t)data_in6->sin6_port); 768 } 769 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA, 770 LDNS_IP6ADDRLEN, &data_in6->sin6_addr); 771 break; 772 default: 773 if (port) { 774 *port = 0; 775 } 776 return NULL; 777 } 778 return addr; 779 } 780 #endif 781 782 /* code from resolver.c */ 783 ldns_status 784 ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) 785 { 786 ldns_pkt *query; 787 ldns_buffer *query_wire; 788 789 struct sockaddr_storage *ns = NULL; 790 size_t ns_len = 0; 791 size_t ns_i; 792 ldns_status status; 793 794 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) { 795 return LDNS_STATUS_ERR; 796 } 797 798 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0); 799 800 if (!query) { 801 return LDNS_STATUS_ADDRESS_ERR; 802 } 803 /* For AXFR, we have to make the connection ourselves */ 804 /* try all nameservers (which usually would mean v4 fallback if 805 * @hostname is used */ 806 for (ns_i = 0; 807 ns_i < ldns_resolver_nameserver_count(resolver) && 808 resolver->_socket == 0; 809 ns_i++) { 810 ns = ldns_rdf2native_sockaddr_storage( 811 resolver->_nameservers[ns_i], 812 ldns_resolver_port(resolver), &ns_len); 813 814 resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len, 815 ldns_resolver_timeout(resolver)); 816 } 817 818 if (resolver->_socket == 0) { 819 ldns_pkt_free(query); 820 LDNS_FREE(ns); 821 return LDNS_STATUS_NETWORK_ERR; 822 } 823 824 #ifdef HAVE_SSL 825 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) { 826 status = ldns_pkt_tsig_sign(query, 827 ldns_resolver_tsig_keyname(resolver), 828 ldns_resolver_tsig_keydata(resolver), 829 300, ldns_resolver_tsig_algorithm(resolver), NULL); 830 if (status != LDNS_STATUS_OK) { 831 /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start 832 we have to close the socket here! */ 833 #ifndef USE_WINSOCK 834 close(resolver->_socket); 835 #else 836 closesocket(resolver->_socket); 837 #endif 838 resolver->_socket = 0; 839 840 return LDNS_STATUS_CRYPTO_TSIG_ERR; 841 } 842 } 843 #endif /* HAVE_SSL */ 844 845 /* Convert the query to a buffer 846 * Is this necessary? 847 */ 848 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN); 849 if(!query_wire) { 850 ldns_pkt_free(query); 851 LDNS_FREE(ns); 852 #ifndef USE_WINSOCK 853 close(resolver->_socket); 854 #else 855 closesocket(resolver->_socket); 856 #endif 857 resolver->_socket = 0; 858 859 return LDNS_STATUS_MEM_ERR; 860 } 861 status = ldns_pkt2buffer_wire(query_wire, query); 862 if (status != LDNS_STATUS_OK) { 863 ldns_pkt_free(query); 864 ldns_buffer_free(query_wire); 865 LDNS_FREE(ns); 866 867 /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start 868 we have to close the socket here! */ 869 #ifndef USE_WINSOCK 870 close(resolver->_socket); 871 #else 872 closesocket(resolver->_socket); 873 #endif 874 resolver->_socket = 0; 875 876 return status; 877 } 878 /* Send the query */ 879 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns, 880 (socklen_t)ns_len) == 0) { 881 ldns_pkt_free(query); 882 ldns_buffer_free(query_wire); 883 LDNS_FREE(ns); 884 885 /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start 886 we have to close the socket here! */ 887 888 #ifndef USE_WINSOCK 889 close(resolver->_socket); 890 #else 891 closesocket(resolver->_socket); 892 #endif 893 resolver->_socket = 0; 894 895 return LDNS_STATUS_NETWORK_ERR; 896 } 897 898 ldns_pkt_free(query); 899 ldns_buffer_free(query_wire); 900 LDNS_FREE(ns); 901 902 /* 903 * The AXFR is done once the second SOA record is sent 904 */ 905 resolver->_axfr_soa_count = 0; 906 return LDNS_STATUS_OK; 907 } 908