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