net.c revision 238104
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 34ldns_status 35ldns_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 59ldns_status 60ldns_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 */ 228static void 229ldns_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 */ 248static void 249ldns_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 */ 268static int 269ldns_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 290ldns_status 291ldns_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 334int 335ldns_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 357int 358ldns_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 372int 373ldns_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 462ssize_t 463ldns_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 */ 487ssize_t 488ldns_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 505uint8_t * 506ldns_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 535uint8_t * 536ldns_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 594uint8_t * 595ldns_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 */ 646ldns_status 647ldns_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 680int 681ldns_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 */ 705struct sockaddr_storage * 706ldns_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 748ldns_rdf * 749ldns_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 */ 783ldns_status 784ldns_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