00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <ldns/config.h>
00015
00016 #include <ldns/ldns.h>
00017
00018 #ifdef HAVE_NETINET_IN_H
00019 #include <netinet/in.h>
00020 #endif
00021 #ifdef HAVE_SYS_SOCKET_H
00022 #include <sys/socket.h>
00023 #endif
00024 #ifdef HAVE_NETDB_H
00025 #include <netdb.h>
00026 #endif
00027 #ifdef HAVE_ARPA_INET_H
00028 #include <arpa/inet.h>
00029 #endif
00030 #include <sys/time.h>
00031 #include <errno.h>
00032 #include <fcntl.h>
00033
00034 ldns_status
00035 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
00036 {
00037 ldns_buffer *qb;
00038 ldns_status result;
00039 ldns_rdf *tsig_mac = NULL;
00040
00041 qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
00042
00043 if (query_pkt && ldns_pkt_tsig(query_pkt)) {
00044 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
00045 }
00046
00047 if (!query_pkt ||
00048 ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
00049 result = LDNS_STATUS_ERR;
00050 } else {
00051 result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
00052 }
00053
00054 ldns_buffer_free(qb);
00055
00056 return result;
00057 }
00058
00059 ldns_status
00060 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
00061 {
00062 uint8_t i;
00063
00064 struct sockaddr_storage *ns;
00065 size_t ns_len;
00066 struct timeval tv_s;
00067 struct timeval tv_e;
00068
00069 ldns_rdf **ns_array;
00070 size_t *rtt;
00071 ldns_pkt *reply;
00072 bool all_servers_rtt_inf;
00073 uint8_t retries;
00074
00075 uint8_t *reply_bytes = NULL;
00076 size_t reply_size = 0;
00077 ldns_status status, send_status;
00078
00079 assert(r != NULL);
00080
00081 status = LDNS_STATUS_OK;
00082 rtt = ldns_resolver_rtt(r);
00083 ns_array = ldns_resolver_nameservers(r);
00084 reply = NULL;
00085 ns_len = 0;
00086
00087 all_servers_rtt_inf = true;
00088
00089 if (ldns_resolver_random(r)) {
00090 ldns_resolver_nameservers_randomize(r);
00091 }
00092
00093
00094 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
00095 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
00096
00097 continue;
00098 }
00099
00100
00101
00102
00103
00104
00105 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
00106 ldns_resolver_port(r), &ns_len);
00107
00108
00109 #ifndef S_SPLINT_S
00110 if ((ns->ss_family == AF_INET) &&
00111 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
00112
00113 continue;
00114 }
00115
00116 if ((ns->ss_family == AF_INET6) &&
00117 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
00118
00119 continue;
00120 }
00121 #endif
00122
00123 all_servers_rtt_inf = false;
00124
00125 gettimeofday(&tv_s, NULL);
00126
00127 send_status = LDNS_STATUS_ERR;
00128
00129
00130 if (1 == ldns_resolver_usevc(r)) {
00131 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
00132 send_status =
00133 ldns_tcp_send(&reply_bytes, qb, ns,
00134 (socklen_t)ns_len, ldns_resolver_timeout(r),
00135 &reply_size);
00136 if (send_status == LDNS_STATUS_OK) {
00137 break;
00138 }
00139 }
00140 } else {
00141 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
00142
00143 send_status =
00144 ldns_udp_send(&reply_bytes, qb, ns,
00145 (socklen_t)ns_len, ldns_resolver_timeout(r),
00146 &reply_size);
00147
00148 if (send_status == LDNS_STATUS_OK) {
00149 break;
00150 }
00151 }
00152 }
00153
00154 if (send_status != LDNS_STATUS_OK) {
00155 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
00156 status = send_status;
00157 }
00158
00159
00160 if (!reply_bytes) {
00161
00162 if (ldns_resolver_fail(r)) {
00163 LDNS_FREE(ns);
00164 return LDNS_STATUS_ERR;
00165 } else {
00166 LDNS_FREE(ns);
00167 continue;
00168 }
00169 }
00170
00171 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
00172 if (status != LDNS_STATUS_OK) {
00173 LDNS_FREE(reply_bytes);
00174 LDNS_FREE(ns);
00175 return status;
00176 }
00177
00178 LDNS_FREE(ns);
00179 gettimeofday(&tv_e, NULL);
00180
00181 if (reply) {
00182 ldns_pkt_set_querytime(reply, (uint32_t)
00183 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
00184 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
00185 ldns_pkt_set_answerfrom(reply, ns_array[i]);
00186 ldns_pkt_set_timestamp(reply, tv_s);
00187 ldns_pkt_set_size(reply, reply_size);
00188 break;
00189 } else {
00190 if (ldns_resolver_fail(r)) {
00191
00192
00193 break;
00194 }
00195 }
00196
00197
00198 sleep((unsigned int) ldns_resolver_retrans(r));
00199 }
00200
00201 if (all_servers_rtt_inf) {
00202 LDNS_FREE(reply_bytes);
00203 return LDNS_STATUS_RES_NO_NS;
00204 }
00205 #ifdef HAVE_SSL
00206 if (tsig_mac && reply_bytes) {
00207 if (!ldns_pkt_tsig_verify(reply,
00208 reply_bytes,
00209 reply_size,
00210 ldns_resolver_tsig_keyname(r),
00211 ldns_resolver_tsig_keydata(r), tsig_mac)) {
00212 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
00213 }
00214 }
00215 #else
00216 (void)tsig_mac;
00217 #endif
00218
00219 LDNS_FREE(reply_bytes);
00220 if (result) {
00221 *result = reply;
00222 }
00223
00224 return status;
00225 }
00226
00228 static void
00229 ldns_sock_nonblock(int sockfd)
00230 {
00231 #ifdef HAVE_FCNTL
00232 int flag;
00233 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
00234 flag |= O_NONBLOCK;
00235 if(fcntl(sockfd, F_SETFL, flag) == -1) {
00236
00237 }
00238 }
00239 #elif defined(HAVE_IOCTLSOCKET)
00240 unsigned long on = 1;
00241 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
00242
00243 }
00244 #endif
00245 }
00246
00248 static void
00249 ldns_sock_block(int sockfd)
00250 {
00251 #ifdef HAVE_FCNTL
00252 int flag;
00253 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
00254 flag &= ~O_NONBLOCK;
00255 if(fcntl(sockfd, F_SETFL, flag) == -1) {
00256
00257 }
00258 }
00259 #elif defined(HAVE_IOCTLSOCKET)
00260 unsigned long off = 0;
00261 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
00262
00263 }
00264 #endif
00265 }
00266
00268 static int
00269 ldns_sock_wait(int sockfd, struct timeval timeout, int write)
00270 {
00271 int ret;
00272 #ifndef S_SPLINT_S
00273 fd_set fds;
00274 FD_ZERO(&fds);
00275 FD_SET(FD_SET_T sockfd, &fds);
00276 if(write)
00277 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
00278 else
00279 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
00280 #endif
00281 if(ret == 0)
00282
00283 return 0;
00284 else if(ret == -1)
00285
00286 return 0;
00287 return 1;
00288 }
00289
00290 ldns_status
00291 ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
00292 socklen_t tolen, struct timeval timeout, size_t *answer_size)
00293 {
00294 int sockfd;
00295 uint8_t *answer;
00296
00297 sockfd = ldns_udp_bgsend(qbin, to, tolen, timeout);
00298
00299 if (sockfd == 0) {
00300 return LDNS_STATUS_SOCKET_ERROR;
00301 }
00302
00303
00304 if(!ldns_sock_wait(sockfd, timeout, 0)) {
00305 #ifndef USE_WINSOCK
00306 close(sockfd);
00307 #else
00308 closesocket(sockfd);
00309 #endif
00310 return LDNS_STATUS_NETWORK_ERR;
00311 }
00312
00313
00314
00315
00316 ldns_sock_nonblock(sockfd);
00317
00318 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
00319 #ifndef USE_WINSOCK
00320 close(sockfd);
00321 #else
00322 closesocket(sockfd);
00323 #endif
00324
00325 if (*answer_size == 0) {
00326
00327 return LDNS_STATUS_NETWORK_ERR;
00328 }
00329
00330 *result = answer;
00331 return LDNS_STATUS_OK;
00332 }
00333
00334 int
00335 ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen,
00336 struct timeval timeout)
00337 {
00338 int sockfd;
00339
00340 sockfd = ldns_udp_connect(to, timeout);
00341
00342 if (sockfd == 0) {
00343 return 0;
00344 }
00345
00346 if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
00347 #ifndef USE_WINSOCK
00348 close(sockfd);
00349 #else
00350 closesocket(sockfd);
00351 #endif
00352 return 0;
00353 }
00354 return sockfd;
00355 }
00356
00357 int
00358 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
00359 {
00360 int sockfd;
00361
00362 #ifndef S_SPLINT_S
00363 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
00364 IPPROTO_UDP))
00365 == -1) {
00366 return 0;
00367 }
00368 #endif
00369 return sockfd;
00370 }
00371
00372 int
00373 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
00374 struct timeval timeout)
00375 {
00376 int sockfd;
00377
00378 #ifndef S_SPLINT_S
00379 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM,
00380 IPPROTO_TCP)) == -1) {
00381 return 0;
00382 }
00383 #endif
00384
00385
00386 ldns_sock_nonblock(sockfd);
00387 if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
00388 #ifndef USE_WINSOCK
00389 #ifdef EINPROGRESS
00390 if(errno != EINPROGRESS) {
00391 #else
00392 if(1) {
00393 #endif
00394 close(sockfd);
00395 return 0;
00396 }
00397 #else
00398 if(WSAGetLastError() != WSAEINPROGRESS &&
00399 WSAGetLastError() != WSAEWOULDBLOCK) {
00400 closesocket(sockfd);
00401 return 0;
00402 }
00403 #endif
00404
00405 }
00406
00407
00408 while(1) {
00409 int error = 0;
00410 socklen_t len = (socklen_t)sizeof(error);
00411
00412 if(!ldns_sock_wait(sockfd, timeout, 1)) {
00413 #ifndef USE_WINSOCK
00414 close(sockfd);
00415 #else
00416 closesocket(sockfd);
00417 #endif
00418 return 0;
00419 }
00420
00421
00422 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
00423 &len) < 0) {
00424 #ifndef USE_WINSOCK
00425 error = errno;
00426 #else
00427 error = WSAGetLastError();
00428 #endif
00429 }
00430 #ifndef USE_WINSOCK
00431 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
00432 if(error == EINPROGRESS || error == EWOULDBLOCK)
00433 continue;
00434 #endif
00435 else if(error != 0) {
00436 close(sockfd);
00437
00438 errno = error;
00439 return 0;
00440 }
00441 #else
00442 if(error == WSAEINPROGRESS)
00443 continue;
00444 else if(error == WSAEWOULDBLOCK)
00445 continue;
00446 else if(error != 0) {
00447 closesocket(sockfd);
00448 errno = error;
00449 return 0;
00450 }
00451 #endif
00452
00453 break;
00454 }
00455
00456
00457 ldns_sock_block(sockfd);
00458
00459 return sockfd;
00460 }
00461
00462 ssize_t
00463 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
00464 const struct sockaddr_storage *to, socklen_t tolen)
00465 {
00466 uint8_t *sendbuf;
00467 ssize_t bytes;
00468
00469
00470 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
00471 if(!sendbuf) return 0;
00472 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
00473 memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin));
00474
00475 bytes = sendto(sockfd, (void*)sendbuf,
00476 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
00477
00478 LDNS_FREE(sendbuf);
00479
00480 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
00481 return 0;
00482 }
00483 return bytes;
00484 }
00485
00486
00487 ssize_t
00488 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
00489 socklen_t tolen)
00490 {
00491 ssize_t bytes;
00492
00493 bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
00494 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
00495
00496 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
00497 return 0;
00498 }
00499 if ((size_t) bytes != ldns_buffer_position(qbin)) {
00500 return 0;
00501 }
00502 return bytes;
00503 }
00504
00505 uint8_t *
00506 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
00507 socklen_t *fromlen)
00508 {
00509 uint8_t *wire, *wireout;
00510 ssize_t wire_size;
00511
00512 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
00513 if (!wire) {
00514 *size = 0;
00515 return NULL;
00516 }
00517
00518 wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0,
00519 (struct sockaddr *)from, fromlen);
00520
00521
00522 if (wire_size == -1 || wire_size == 0) {
00523 *size = 0;
00524 LDNS_FREE(wire);
00525 return NULL;
00526 }
00527
00528 *size = (size_t)wire_size;
00529 wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
00530 if(!wireout) LDNS_FREE(wire);
00531
00532 return wireout;
00533 }
00534
00535 uint8_t *
00536 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
00537 {
00538 uint8_t *wire;
00539 uint16_t wire_size;
00540 ssize_t bytes = 0, rc = 0;
00541
00542 wire = LDNS_XMALLOC(uint8_t, 2);
00543 if (!wire) {
00544 *size = 0;
00545 return NULL;
00546 }
00547
00548 while (bytes < 2) {
00549 if(!ldns_sock_wait(sockfd, timeout, 0)) {
00550 *size = 0;
00551 LDNS_FREE(wire);
00552 return NULL;
00553 }
00554 rc = recv(sockfd, (void*) (wire + bytes),
00555 (size_t) (2 - bytes), 0);
00556 if (rc == -1 || rc == 0) {
00557 *size = 0;
00558 LDNS_FREE(wire);
00559 return NULL;
00560 }
00561 bytes += rc;
00562 }
00563
00564 wire_size = ldns_read_uint16(wire);
00565
00566 LDNS_FREE(wire);
00567 wire = LDNS_XMALLOC(uint8_t, wire_size);
00568 if (!wire) {
00569 *size = 0;
00570 return NULL;
00571 }
00572 bytes = 0;
00573
00574 while (bytes < (ssize_t) wire_size) {
00575 if(!ldns_sock_wait(sockfd, timeout, 0)) {
00576 *size = 0;
00577 LDNS_FREE(wire);
00578 return NULL;
00579 }
00580 rc = recv(sockfd, (void*) (wire + bytes),
00581 (size_t) (wire_size - bytes), 0);
00582 if (rc == -1 || rc == 0) {
00583 LDNS_FREE(wire);
00584 *size = 0;
00585 return NULL;
00586 }
00587 bytes += rc;
00588 }
00589
00590 *size = (size_t) bytes;
00591 return wire;
00592 }
00593
00594 uint8_t *
00595 ldns_tcp_read_wire(int sockfd, size_t *size)
00596 {
00597 uint8_t *wire;
00598 uint16_t wire_size;
00599 ssize_t bytes = 0, rc = 0;
00600
00601 wire = LDNS_XMALLOC(uint8_t, 2);
00602 if (!wire) {
00603 *size = 0;
00604 return NULL;
00605 }
00606
00607 while (bytes < 2) {
00608 rc = recv(sockfd, (void*) (wire + bytes),
00609 (size_t) (2 - bytes), 0);
00610 if (rc == -1 || rc == 0) {
00611 *size = 0;
00612 LDNS_FREE(wire);
00613 return NULL;
00614 }
00615 bytes += rc;
00616 }
00617
00618 wire_size = ldns_read_uint16(wire);
00619
00620 LDNS_FREE(wire);
00621 wire = LDNS_XMALLOC(uint8_t, wire_size);
00622 if (!wire) {
00623 *size = 0;
00624 return NULL;
00625 }
00626 bytes = 0;
00627
00628 while (bytes < (ssize_t) wire_size) {
00629 rc = recv(sockfd, (void*) (wire + bytes),
00630 (size_t) (wire_size - bytes), 0);
00631 if (rc == -1 || rc == 0) {
00632 LDNS_FREE(wire);
00633 *size = 0;
00634 return NULL;
00635 }
00636 bytes += rc;
00637 }
00638
00639 *size = (size_t) bytes;
00640 return wire;
00641 }
00642
00643
00644
00645
00646 ldns_status
00647 ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
00648 socklen_t tolen, struct timeval timeout, size_t *answer_size)
00649 {
00650 int sockfd;
00651 uint8_t *answer;
00652
00653 sockfd = ldns_tcp_bgsend(qbin, to, tolen, timeout);
00654
00655 if (sockfd == 0) {
00656 return LDNS_STATUS_ERR;
00657 }
00658
00659 answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
00660 #ifndef USE_WINSOCK
00661 close(sockfd);
00662 #else
00663 closesocket(sockfd);
00664 #endif
00665
00666 if (*answer_size == 0) {
00667
00668 return LDNS_STATUS_NETWORK_ERR;
00669 }
00670
00671
00672 *result = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size);
00673 if(!*result) {
00674 LDNS_FREE(answer);
00675 return LDNS_STATUS_MEM_ERR;
00676 }
00677 return LDNS_STATUS_OK;
00678 }
00679
00680 int
00681 ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen,
00682 struct timeval timeout)
00683 {
00684 int sockfd;
00685
00686 sockfd = ldns_tcp_connect(to, tolen, timeout);
00687
00688 if (sockfd == 0) {
00689 return 0;
00690 }
00691
00692 if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
00693 #ifndef USE_WINSOCK
00694 close(sockfd);
00695 #else
00696 closesocket(sockfd);
00697 #endif
00698 return 0;
00699 }
00700
00701 return sockfd;
00702 }
00703
00704
00705 struct sockaddr_storage *
00706 ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size)
00707 {
00708 struct sockaddr_storage *data;
00709 struct sockaddr_in *data_in;
00710 struct sockaddr_in6 *data_in6;
00711
00712 data = LDNS_MALLOC(struct sockaddr_storage);
00713 if (!data) {
00714 return NULL;
00715 }
00716
00717 memset(data, 0, sizeof(struct sockaddr_storage));
00718 if (port == 0) {
00719 port = LDNS_PORT;
00720 }
00721
00722 switch(ldns_rdf_get_type(rd)) {
00723 case LDNS_RDF_TYPE_A:
00724 #ifndef S_SPLINT_S
00725 data->ss_family = AF_INET;
00726 #endif
00727 data_in = (struct sockaddr_in*) data;
00728 data_in->sin_port = (in_port_t)htons(port);
00729 memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
00730 *size = sizeof(struct sockaddr_in);
00731 return data;
00732 case LDNS_RDF_TYPE_AAAA:
00733 #ifndef S_SPLINT_S
00734 data->ss_family = AF_INET6;
00735 #endif
00736 data_in6 = (struct sockaddr_in6*) data;
00737 data_in6->sin6_port = (in_port_t)htons(port);
00738 memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
00739 *size = sizeof(struct sockaddr_in6);
00740 return data;
00741 default:
00742 LDNS_FREE(data);
00743 return NULL;
00744 }
00745 }
00746
00747 #ifndef S_SPLINT_S
00748 ldns_rdf *
00749 ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
00750 {
00751 ldns_rdf *addr;
00752 struct sockaddr_in *data_in;
00753 struct sockaddr_in6 *data_in6;
00754
00755 switch(sock->ss_family) {
00756 case AF_INET:
00757 data_in = (struct sockaddr_in*)sock;
00758 if (port) {
00759 *port = ntohs((uint16_t)data_in->sin_port);
00760 }
00761 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
00762 LDNS_IP4ADDRLEN, &data_in->sin_addr);
00763 break;
00764 case AF_INET6:
00765 data_in6 = (struct sockaddr_in6*)sock;
00766 if (port) {
00767 *port = ntohs((uint16_t)data_in6->sin6_port);
00768 }
00769 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
00770 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
00771 break;
00772 default:
00773 if (port) {
00774 *port = 0;
00775 }
00776 return NULL;
00777 }
00778 return addr;
00779 }
00780 #endif
00781
00782
00783 ldns_status
00784 ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
00785 {
00786 ldns_pkt *query;
00787 ldns_buffer *query_wire;
00788
00789 struct sockaddr_storage *ns = NULL;
00790 size_t ns_len = 0;
00791 size_t ns_i;
00792 ldns_status status;
00793
00794 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
00795 return LDNS_STATUS_ERR;
00796 }
00797
00798 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
00799
00800 if (!query) {
00801 return LDNS_STATUS_ADDRESS_ERR;
00802 }
00803
00804
00805
00806 for (ns_i = 0;
00807 ns_i < ldns_resolver_nameserver_count(resolver) &&
00808 resolver->_socket == 0;
00809 ns_i++) {
00810 ns = ldns_rdf2native_sockaddr_storage(
00811 resolver->_nameservers[ns_i],
00812 ldns_resolver_port(resolver), &ns_len);
00813
00814 resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len,
00815 ldns_resolver_timeout(resolver));
00816 }
00817
00818 if (resolver->_socket == 0) {
00819 ldns_pkt_free(query);
00820 LDNS_FREE(ns);
00821 return LDNS_STATUS_NETWORK_ERR;
00822 }
00823
00824 #ifdef HAVE_SSL
00825 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
00826 status = ldns_pkt_tsig_sign(query,
00827 ldns_resolver_tsig_keyname(resolver),
00828 ldns_resolver_tsig_keydata(resolver),
00829 300, ldns_resolver_tsig_algorithm(resolver), NULL);
00830 if (status != LDNS_STATUS_OK) {
00831
00832
00833 #ifndef USE_WINSOCK
00834 close(resolver->_socket);
00835 #else
00836 closesocket(resolver->_socket);
00837 #endif
00838 resolver->_socket = 0;
00839
00840 return LDNS_STATUS_CRYPTO_TSIG_ERR;
00841 }
00842 }
00843 #endif
00844
00845
00846
00847
00848 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
00849 if(!query_wire) {
00850 ldns_pkt_free(query);
00851 LDNS_FREE(ns);
00852 #ifndef USE_WINSOCK
00853 close(resolver->_socket);
00854 #else
00855 closesocket(resolver->_socket);
00856 #endif
00857 resolver->_socket = 0;
00858
00859 return LDNS_STATUS_MEM_ERR;
00860 }
00861 status = ldns_pkt2buffer_wire(query_wire, query);
00862 if (status != LDNS_STATUS_OK) {
00863 ldns_pkt_free(query);
00864 ldns_buffer_free(query_wire);
00865 LDNS_FREE(ns);
00866
00867
00868
00869 #ifndef USE_WINSOCK
00870 close(resolver->_socket);
00871 #else
00872 closesocket(resolver->_socket);
00873 #endif
00874 resolver->_socket = 0;
00875
00876 return status;
00877 }
00878
00879 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
00880 (socklen_t)ns_len) == 0) {
00881 ldns_pkt_free(query);
00882 ldns_buffer_free(query_wire);
00883 LDNS_FREE(ns);
00884
00885
00886
00887
00888 #ifndef USE_WINSOCK
00889 close(resolver->_socket);
00890 #else
00891 closesocket(resolver->_socket);
00892 #endif
00893 resolver->_socket = 0;
00894
00895 return LDNS_STATUS_NETWORK_ERR;
00896 }
00897
00898 ldns_pkt_free(query);
00899 ldns_buffer_free(query_wire);
00900 LDNS_FREE(ns);
00901
00902
00903
00904
00905 resolver->_axfr_soa_count = 0;
00906 return LDNS_STATUS_OK;
00907 }