4 * Network implementation
5 * All network related functions are grouped here
7 * a Net::DNS like library for C
9 * (c) NLnet Labs, 2004-2006
11 * See the file LICENSE for the license
14 #include <ldns/config.h>
16 #include <ldns/ldns.h>
18 #ifdef HAVE_NETINET_IN_H
19 #include <netinet/in.h>
21 #ifdef HAVE_SYS_SOCKET_H
22 #include <sys/socket.h>
27 #ifdef HAVE_ARPA_INET_H
28 #include <arpa/inet.h>
35 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
39 ldns_rdf *tsig_mac = NULL;
41 qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
43 if (query_pkt && ldns_pkt_tsig(query_pkt)) {
44 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
49 ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
50 result = LDNS_STATUS_ERR;
52 result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
61 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
65 struct sockaddr_storage *ns;
73 bool all_servers_rtt_inf;
76 uint8_t *reply_bytes = NULL;
77 size_t reply_size = 0;
78 ldns_status status, send_status;
82 status = LDNS_STATUS_OK;
83 rtt = ldns_resolver_rtt(r);
84 ns_array = ldns_resolver_nameservers(r);
88 all_servers_rtt_inf = true;
90 if (ldns_resolver_random(r)) {
91 ldns_resolver_nameservers_randomize(r);
94 /* loop through all defined nameservers */
95 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
96 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
97 /* not reachable nameserver! */
100 all_servers_rtt_inf = false;
102 /* maybe verbosity setting?
103 printf("Sending to ");
104 ldns_rdf_print(stdout, ns_array[i]);
107 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
108 ldns_resolver_port(r), &ns_len);
110 if ((ns->ss_family == AF_INET) &&
111 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
115 if ((ns->ss_family == AF_INET6) &&
116 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
120 gettimeofday(&tv_s, NULL);
122 send_status = LDNS_STATUS_ERR;
124 /* reply_bytes implicitly handles our error */
125 if (1 == ldns_resolver_usevc(r)) {
126 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
128 ldns_tcp_send(&reply_bytes, qb, ns,
129 (socklen_t)ns_len, ldns_resolver_timeout(r),
131 if (send_status == LDNS_STATUS_OK) {
136 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
137 /* ldns_rdf_print(stdout, ns_array[i]); */
139 ldns_udp_send(&reply_bytes, qb, ns,
140 (socklen_t)ns_len, ldns_resolver_timeout(r),
143 if (send_status == LDNS_STATUS_OK) {
149 if (send_status != LDNS_STATUS_OK) {
150 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
151 status = send_status;
154 /* obey the fail directive */
156 /* the current nameserver seems to have a problem, blacklist it */
157 if (ldns_resolver_fail(r)) {
159 return LDNS_STATUS_ERR;
166 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
167 if (status != LDNS_STATUS_OK) {
168 LDNS_FREE(reply_bytes);
174 gettimeofday(&tv_e, NULL);
177 ldns_pkt_set_querytime(reply, (uint32_t)
178 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
179 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
180 ldns_pkt_set_answerfrom(reply, ns_array[i]);
181 ldns_pkt_set_timestamp(reply, tv_s);
182 ldns_pkt_set_size(reply, reply_size);
185 if (ldns_resolver_fail(r)) {
186 /* if fail is set bail out, after the first
192 /* wait retrans seconds... */
193 sleep((unsigned int) ldns_resolver_retrans(r));
196 if (all_servers_rtt_inf) {
197 LDNS_FREE(reply_bytes);
198 return LDNS_STATUS_RES_NO_NS;
201 if (tsig_mac && reply_bytes) {
202 if (!ldns_pkt_tsig_verify(reply,
205 ldns_resolver_tsig_keyname(r),
206 ldns_resolver_tsig_keydata(r), tsig_mac)) {
207 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
212 #endif /* HAVE_SSL */
214 LDNS_FREE(reply_bytes);
222 /** best effort to set nonblocking */
224 ldns_sock_nonblock(int sockfd)
228 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
230 if(fcntl(sockfd, F_SETFL, flag) == -1) {
231 /* ignore error, continue blockingly */
234 #elif defined(HAVE_IOCTLSOCKET)
235 unsigned long on = 1;
236 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
237 /* ignore error, continue blockingly */
242 /** best effort to set blocking */
244 ldns_sock_block(int sockfd)
248 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
250 if(fcntl(sockfd, F_SETFL, flag) == -1) {
251 /* ignore error, continue */
254 #elif defined(HAVE_IOCTLSOCKET)
255 unsigned long off = 0;
256 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
257 /* ignore error, continue */
262 /** wait for a socket to become ready */
264 ldns_sock_wait(int sockfd, struct timeval timeout, int write)
269 FD_SET(FD_SET_T sockfd, &fds);
271 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
273 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
275 /* timeout expired */
284 ldns_udp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
285 socklen_t tolen, struct timeval timeout, size_t *answer_size)
290 sockfd = ldns_udp_bgsend(qbin, to, tolen, timeout);
293 return LDNS_STATUS_SOCKET_ERROR;
296 /* wait for an response*/
297 if(!ldns_sock_wait(sockfd, timeout, 0)) {
299 return LDNS_STATUS_NETWORK_ERR;
302 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
305 if (*answer_size == 0) {
307 return LDNS_STATUS_NETWORK_ERR;
311 return LDNS_STATUS_OK;
315 ldns_udp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen,
316 struct timeval timeout)
320 sockfd = ldns_udp_connect(to, timeout);
326 if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
333 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
337 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
346 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
347 struct timeval timeout)
351 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM,
352 IPPROTO_TCP)) == -1) {
356 /* perform nonblocking connect, to be able to wait with select() */
357 ldns_sock_nonblock(sockfd);
358 if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) {
361 if(errno != EINPROGRESS) {
368 #else /* USE_WINSOCK */
369 if(WSAGetLastError() != WSAEINPROGRESS &&
370 WSAGetLastError() != WSAEWOULDBLOCK) {
375 /* error was only telling us that it would block */
378 /* wait(write) until connected or error */
381 socklen_t len = (socklen_t)sizeof(error);
383 if(!ldns_sock_wait(sockfd, timeout, 1)) {
388 /* check if there is a pending error for nonblocking connect */
389 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
392 error = errno; /* on solaris errno is error */
394 error = WSAGetLastError();
398 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
399 if(error == EINPROGRESS || error == EWOULDBLOCK)
400 continue; /* try again */
402 else if(error != 0) {
404 /* error in errno for our user */
408 #else /* USE_WINSOCK */
409 if(error == WSAEINPROGRESS)
411 else if(error == WSAEWOULDBLOCK)
413 else if(error != 0) {
418 #endif /* USE_WINSOCK */
423 /* set the socket blocking again */
424 ldns_sock_block(sockfd);
430 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
431 const struct sockaddr_storage *to, socklen_t tolen)
436 /* add length of packet */
437 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
438 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
439 memcpy(sendbuf + 2, ldns_buffer_export(qbin), ldns_buffer_position(qbin));
441 bytes = sendto(sockfd, (void*)sendbuf,
442 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
446 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
452 /* don't wait for an answer */
454 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
459 bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
460 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
462 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
465 if ((size_t) bytes != ldns_buffer_position(qbin)) {
472 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
478 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
484 wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0,
485 (struct sockaddr *)from, fromlen);
487 /* recvfrom can also return 0 */
488 if (wire_size == -1 || wire_size == 0) {
494 *size = (size_t)wire_size;
495 wire = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
501 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
507 wire = LDNS_XMALLOC(uint8_t, 2);
514 if(!ldns_sock_wait(sockfd, timeout, 0)) {
519 bytes = recv(sockfd, (void*)wire, 2, 0);
520 if (bytes == -1 || bytes == 0) {
527 wire_size = ldns_read_uint16(wire);
530 wire = LDNS_XMALLOC(uint8_t, wire_size);
533 while (bytes < (ssize_t) wire_size) {
534 if(!ldns_sock_wait(sockfd, timeout, 0)) {
539 bytes += recv(sockfd, (void*) (wire + bytes),
540 (size_t) (wire_size - bytes), 0);
541 if (bytes == -1 || bytes == 0) {
548 *size = (size_t) bytes;
553 ldns_tcp_read_wire(int sockfd, size_t *size)
559 wire = LDNS_XMALLOC(uint8_t, 2);
566 bytes = recv(sockfd, (void*)wire, 2, 0);
567 if (bytes == -1 || bytes == 0) {
574 wire_size = ldns_read_uint16(wire);
577 wire = LDNS_XMALLOC(uint8_t, wire_size);
580 while (bytes < (ssize_t) wire_size) {
581 bytes += recv(sockfd, (void*) (wire + bytes),
582 (size_t) (wire_size - bytes), 0);
583 if (bytes == -1 || bytes == 0) {
590 *size = (size_t) bytes;
594 /* keep in mind that in DNS tcp messages the first 2 bytes signal the
595 * amount data to expect
598 ldns_tcp_send(uint8_t **result, ldns_buffer *qbin, const struct sockaddr_storage *to,
599 socklen_t tolen, struct timeval timeout, size_t *answer_size)
604 sockfd = ldns_tcp_bgsend(qbin, to, tolen, timeout);
607 return LDNS_STATUS_ERR;
610 answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
613 if (*answer_size == 0) {
615 return LDNS_STATUS_NETWORK_ERR;
618 /* resize accordingly */
619 answer = (uint8_t*)LDNS_XREALLOC(answer, uint8_t *, (size_t)*answer_size);
621 return LDNS_STATUS_OK;
625 ldns_tcp_bgsend(ldns_buffer *qbin, const struct sockaddr_storage *to, socklen_t tolen,
626 struct timeval timeout)
630 sockfd = ldns_tcp_connect(to, tolen, timeout);
636 if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
643 /* code from rdata.c */
644 struct sockaddr_storage *
645 ldns_rdf2native_sockaddr_storage(const ldns_rdf *rd, uint16_t port, size_t *size)
647 struct sockaddr_storage *data;
648 struct sockaddr_in *data_in;
649 struct sockaddr_in6 *data_in6;
651 data = LDNS_MALLOC(struct sockaddr_storage);
655 /* zero the structure for portability */
656 memset(data, 0, sizeof(struct sockaddr_storage));
661 switch(ldns_rdf_get_type(rd)) {
662 case LDNS_RDF_TYPE_A:
663 data->ss_family = AF_INET;
664 data_in = (struct sockaddr_in*) data;
665 data_in->sin_port = (in_port_t)htons(port);
666 memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
667 *size = sizeof(struct sockaddr_in);
669 case LDNS_RDF_TYPE_AAAA:
670 data->ss_family = AF_INET6;
671 data_in6 = (struct sockaddr_in6*) data;
672 data_in6->sin6_port = (in_port_t)htons(port);
673 memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
674 *size = sizeof(struct sockaddr_in6);
683 ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port)
686 struct sockaddr_in *data_in;
687 struct sockaddr_in6 *data_in6;
689 switch(sock->ss_family) {
691 data_in = (struct sockaddr_in*)sock;
693 *port = ntohs((uint16_t)data_in->sin_port);
695 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
696 LDNS_IP4ADDRLEN, &data_in->sin_addr);
699 data_in6 = (struct sockaddr_in6*)sock;
701 *port = ntohs((uint16_t)data_in6->sin6_port);
703 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
704 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
715 /* code from resolver.c */
717 ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class)
720 ldns_buffer *query_wire;
722 struct sockaddr_storage *ns = NULL;
727 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
728 return LDNS_STATUS_ERR;
731 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
734 return LDNS_STATUS_ADDRESS_ERR;
736 /* For AXFR, we have to make the connection ourselves */
737 /* try all nameservers (which usually would mean v4 fallback if
738 * @hostname is used */
740 ns_i < ldns_resolver_nameserver_count(resolver) &&
741 resolver->_socket == 0;
743 ns = ldns_rdf2native_sockaddr_storage(
744 resolver->_nameservers[ns_i],
745 ldns_resolver_port(resolver), &ns_len);
747 resolver->_socket = ldns_tcp_connect(ns, (socklen_t)ns_len,
748 ldns_resolver_timeout(resolver));
751 if (resolver->_socket == 0) {
752 ldns_pkt_free(query);
754 return LDNS_STATUS_NETWORK_ERR;
758 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
759 status = ldns_pkt_tsig_sign(query,
760 ldns_resolver_tsig_keyname(resolver),
761 ldns_resolver_tsig_keydata(resolver),
762 300, ldns_resolver_tsig_algorithm(resolver), NULL);
763 if (status != LDNS_STATUS_OK) {
764 return LDNS_STATUS_CRYPTO_TSIG_ERR;
767 #endif /* HAVE_SSL */
769 /* Convert the query to a buffer * Is this necessary?
771 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
772 status = ldns_pkt2buffer_wire(query_wire, query);
773 if (status != LDNS_STATUS_OK) {
774 ldns_pkt_free(query);
779 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
780 (socklen_t)ns_len) == 0) {
781 ldns_pkt_free(query);
782 ldns_buffer_free(query_wire);
784 return LDNS_STATUS_NETWORK_ERR;
787 ldns_pkt_free(query);
788 ldns_buffer_free(query_wire);
792 * The AXFR is done once the second SOA record is sent
794 resolver->_axfr_soa_count = 0;
795 return LDNS_STATUS_OK;