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