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