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);
48 ldns_pkt2buffer_wire(qb
, query_pkt
) != LDNS_STATUS_OK
) {
49 result
= LDNS_STATUS_ERR
;
51 result
= ldns_send_buffer(result_packet
, r
, qb
, tsig_mac
);
60 ldns_send_buffer(ldns_pkt
**result
, ldns_resolver
*r
, ldns_buffer
*qb
, ldns_rdf
*tsig_mac
)
64 struct sockaddr_storage
*ns
;
72 bool all_servers_rtt_inf
;
75 uint8_t *reply_bytes
= NULL
;
76 size_t reply_size
= 0;
77 ldns_status status
, send_status
;
81 status
= LDNS_STATUS_OK
;
82 rtt
= ldns_resolver_rtt(r
);
83 ns_array
= ldns_resolver_nameservers(r
);
87 all_servers_rtt_inf
= true;
89 if (ldns_resolver_random(r
)) {
90 ldns_resolver_nameservers_randomize(r
);
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! */
100 /* maybe verbosity setting?
101 printf("Sending to ");
102 ldns_rdf_print(stdout, ns_array[i]);
105 ns
= ldns_rdf2native_sockaddr_storage(ns_array
[i
],
106 ldns_resolver_port(r
), &ns_len
);
110 if ((ns
->ss_family
== AF_INET
) &&
111 (ldns_resolver_ip6(r
) == LDNS_RESOLV_INET6
)) {
117 if ((ns
->ss_family
== AF_INET6
) &&
118 (ldns_resolver_ip6(r
) == LDNS_RESOLV_INET
)) {
125 all_servers_rtt_inf
= false;
127 gettimeofday(&tv_s
, NULL
);
129 send_status
= LDNS_STATUS_ERR
;
131 /* reply_bytes implicitly handles our error */
132 if (1 == ldns_resolver_usevc(r
)) {
133 for (retries
= ldns_resolver_retry(r
); retries
> 0; retries
--) {
135 ldns_tcp_send(&reply_bytes
, qb
, ns
,
136 (socklen_t
)ns_len
, ldns_resolver_timeout(r
),
138 if (send_status
== LDNS_STATUS_OK
) {
143 for (retries
= ldns_resolver_retry(r
); retries
> 0; retries
--) {
144 /* ldns_rdf_print(stdout, ns_array[i]); */
146 ldns_udp_send(&reply_bytes
, qb
, ns
,
147 (socklen_t
)ns_len
, ldns_resolver_timeout(r
),
150 if (send_status
== LDNS_STATUS_OK
) {
156 if (send_status
!= LDNS_STATUS_OK
) {
157 ldns_resolver_set_nameserver_rtt(r
, i
, LDNS_RESOLV_RTT_INF
);
158 status
= send_status
;
161 /* obey the fail directive */
163 /* the current nameserver seems to have a problem, blacklist it */
164 if (ldns_resolver_fail(r
)) {
166 return LDNS_STATUS_ERR
;
173 status
= ldns_wire2pkt(&reply
, reply_bytes
, reply_size
);
174 if (status
!= LDNS_STATUS_OK
) {
175 LDNS_FREE(reply_bytes
);
181 gettimeofday(&tv_e
, NULL
);
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
);
193 if (ldns_resolver_fail(r
)) {
194 /* if fail is set bail out, after the first
200 /* wait retrans seconds... */
201 sleep((unsigned int) ldns_resolver_retrans(r
));
204 if (all_servers_rtt_inf
) {
205 LDNS_FREE(reply_bytes
);
206 return LDNS_STATUS_RES_NO_NS
;
209 if (tsig_mac
&& reply
&& reply_bytes
) {
210 if (!ldns_pkt_tsig_verify(reply
,
213 ldns_resolver_tsig_keyname(r
),
214 ldns_resolver_tsig_keydata(r
), tsig_mac
)) {
215 status
= LDNS_STATUS_CRYPTO_TSIG_BOGUS
;
220 #endif /* HAVE_SSL */
222 LDNS_FREE(reply_bytes
);
230 /** best effort to set nonblocking */
232 ldns_sock_nonblock(int sockfd
)
236 if((flag
= fcntl(sockfd
, F_GETFL
)) != -1) {
238 if(fcntl(sockfd
, F_SETFL
, flag
) == -1) {
239 /* ignore error, continue blockingly */
242 #elif defined(HAVE_IOCTLSOCKET)
243 unsigned long on
= 1;
244 if(ioctlsocket(sockfd
, FIONBIO
, &on
) != 0) {
245 /* ignore error, continue blockingly */
250 /** best effort to set blocking */
252 ldns_sock_block(int sockfd
)
256 if((flag
= fcntl(sockfd
, F_GETFL
)) != -1) {
258 if(fcntl(sockfd
, F_SETFL
, flag
) == -1) {
259 /* ignore error, continue */
262 #elif defined(HAVE_IOCTLSOCKET)
263 unsigned long off
= 0;
264 if(ioctlsocket(sockfd
, FIONBIO
, &off
) != 0) {
265 /* ignore error, continue */
270 /** wait for a socket to become ready */
272 ldns_sock_wait(int sockfd
, struct timeval timeout
, int write
)
278 FD_SET(FD_SET_T sockfd
, &fds
);
280 ret
= select(sockfd
+1, NULL
, &fds
, NULL
, &timeout
);
282 ret
= select(sockfd
+1, &fds
, NULL
, NULL
, &timeout
);
285 /* timeout expired */
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
)
300 sockfd
= ldns_udp_bgsend(qbin
, to
, tolen
, timeout
);
303 return LDNS_STATUS_SOCKET_ERROR
;
306 /* wait for an response*/
307 if(!ldns_sock_wait(sockfd
, timeout
, 0)) {
313 return LDNS_STATUS_NETWORK_ERR
;
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
);
321 answer
= ldns_udp_read_wire(sockfd
, answer_size
, NULL
, NULL
);
328 if (*answer_size
== 0) {
330 return LDNS_STATUS_NETWORK_ERR
;
334 return LDNS_STATUS_OK
;
338 ldns_udp_bgsend(ldns_buffer
*qbin
, const struct sockaddr_storage
*to
, socklen_t tolen
,
339 struct timeval timeout
)
343 sockfd
= ldns_udp_connect(to
, timeout
);
349 if (ldns_udp_send_query(qbin
, sockfd
, to
, tolen
) == 0) {
361 ldns_udp_connect(const struct sockaddr_storage
*to
, struct timeval
ATTR_UNUSED(timeout
))
366 if ((sockfd
= socket((int)((struct sockaddr
*)to
)->sa_family
, SOCK_DGRAM
,
376 ldns_tcp_connect(const struct sockaddr_storage
*to
, socklen_t tolen
,
377 struct timeval timeout
)
382 if ((sockfd
= socket((int)((struct sockaddr
*)to
)->sa_family
, SOCK_STREAM
,
383 IPPROTO_TCP
)) == -1) {
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) {
393 if(errno
!= EINPROGRESS
) {
400 #else /* USE_WINSOCK */
401 if(WSAGetLastError() != WSAEINPROGRESS
&&
402 WSAGetLastError() != WSAEWOULDBLOCK
) {
407 /* error was only telling us that it would block */
410 /* wait(write) until connected or error */
413 socklen_t len
= (socklen_t
)sizeof(error
);
415 if(!ldns_sock_wait(sockfd
, timeout
, 1)) {
424 /* check if there is a pending error for nonblocking connect */
425 if(getsockopt(sockfd
, SOL_SOCKET
, SO_ERROR
, (void*)&error
,
428 error
= errno
; /* on solaris errno is error */
430 error
= WSAGetLastError();
434 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
435 if(error
== EINPROGRESS
|| error
== EWOULDBLOCK
)
436 continue; /* try again */
438 else if(error
!= 0) {
440 /* error in errno for our user */
444 #else /* USE_WINSOCK */
445 if(error
== WSAEINPROGRESS
)
447 else if(error
== WSAEWOULDBLOCK
)
449 else if(error
!= 0) {
454 #endif /* USE_WINSOCK */
459 /* set the socket blocking again */
460 ldns_sock_block(sockfd
);
466 ldns_tcp_send_query(ldns_buffer
*qbin
, int sockfd
,
467 const struct sockaddr_storage
*to
, socklen_t tolen
)
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
));
478 bytes
= sendto(sockfd
, (void*)sendbuf
,
479 ldns_buffer_position(qbin
) + 2, 0, (struct sockaddr
*)to
, tolen
);
483 if (bytes
== -1 || (size_t) bytes
!= ldns_buffer_position(qbin
) + 2 ) {
489 /* don't wait for an answer */
491 ldns_udp_send_query(ldns_buffer
*qbin
, int sockfd
, const struct sockaddr_storage
*to
,
496 bytes
= sendto(sockfd
, (void*)ldns_buffer_begin(qbin
),
497 ldns_buffer_position(qbin
), 0, (struct sockaddr
*)to
, tolen
);
499 if (bytes
== -1 || (size_t)bytes
!= ldns_buffer_position(qbin
)) {
502 if ((size_t) bytes
!= ldns_buffer_position(qbin
)) {
509 ldns_udp_read_wire(int sockfd
, size_t *size
, struct sockaddr_storage
*from
,
512 uint8_t *wire
, *wireout
;
515 wire
= LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN
);
521 wire_size
= recvfrom(sockfd
, (void*)wire
, LDNS_MAX_PACKETLEN
, 0,
522 (struct sockaddr
*)from
, fromlen
);
524 /* recvfrom can also return 0 */
525 if (wire_size
== -1 || wire_size
== 0) {
531 *size
= (size_t)wire_size
;
532 wireout
= LDNS_XREALLOC(wire
, uint8_t, (size_t)wire_size
);
533 if(!wireout
) LDNS_FREE(wire
);
539 ldns_tcp_read_wire_timeout(int sockfd
, size_t *size
, struct timeval timeout
)
543 ssize_t bytes
= 0, rc
= 0;
545 wire
= LDNS_XMALLOC(uint8_t, 2);
552 if(!ldns_sock_wait(sockfd
, timeout
, 0)) {
557 rc
= recv(sockfd
, (void*) (wire
+ bytes
),
558 (size_t) (2 - bytes
), 0);
559 if (rc
== -1 || rc
== 0) {
567 wire_size
= ldns_read_uint16(wire
);
570 wire
= LDNS_XMALLOC(uint8_t, wire_size
);
577 while (bytes
< (ssize_t
) wire_size
) {
578 if(!ldns_sock_wait(sockfd
, timeout
, 0)) {
583 rc
= recv(sockfd
, (void*) (wire
+ bytes
),
584 (size_t) (wire_size
- bytes
), 0);
585 if (rc
== -1 || rc
== 0) {
593 *size
= (size_t) bytes
;
598 ldns_tcp_read_wire(int sockfd
, size_t *size
)
602 ssize_t bytes
= 0, rc
= 0;
604 wire
= LDNS_XMALLOC(uint8_t, 2);
611 rc
= recv(sockfd
, (void*) (wire
+ bytes
),
612 (size_t) (2 - bytes
), 0);
613 if (rc
== -1 || rc
== 0) {
621 wire_size
= ldns_read_uint16(wire
);
624 wire
= LDNS_XMALLOC(uint8_t, wire_size
);
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) {
642 *size
= (size_t) bytes
;
646 /* keep in mind that in DNS tcp messages the first 2 bytes signal the
647 * amount data to expect
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
)
656 sockfd
= ldns_tcp_bgsend(qbin
, to
, tolen
, timeout
);
659 return LDNS_STATUS_ERR
;
662 answer
= ldns_tcp_read_wire_timeout(sockfd
, answer_size
, timeout
);
669 if (*answer_size
== 0) {
671 return LDNS_STATUS_NETWORK_ERR
;
674 /* resize accordingly */
675 *result
= LDNS_XREALLOC(answer
, uint8_t, (size_t)*answer_size
);
678 return LDNS_STATUS_MEM_ERR
;
680 return LDNS_STATUS_OK
;
684 ldns_tcp_bgsend(ldns_buffer
*qbin
, const struct sockaddr_storage
*to
, socklen_t tolen
,
685 struct timeval timeout
)
689 sockfd
= ldns_tcp_connect(to
, tolen
, timeout
);
695 if (ldns_tcp_send_query(qbin
, sockfd
, to
, tolen
) == 0) {
707 /* code from rdata.c */
708 struct sockaddr_storage
*
709 ldns_rdf2native_sockaddr_storage(const ldns_rdf
*rd
, uint16_t port
, size_t *size
)
711 struct sockaddr_storage
*data
;
712 struct sockaddr_in
*data_in
;
713 struct sockaddr_in6
*data_in6
;
715 data
= LDNS_MALLOC(struct sockaddr_storage
);
719 /* zero the structure for portability */
720 memset(data
, 0, sizeof(struct sockaddr_storage
));
725 switch(ldns_rdf_get_type(rd
)) {
726 case LDNS_RDF_TYPE_A
:
728 data
->ss_family
= AF_INET
;
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
);
735 case LDNS_RDF_TYPE_AAAA
:
737 data
->ss_family
= AF_INET6
;
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
);
752 ldns_sockaddr_storage2rdf(struct sockaddr_storage
*sock
, uint16_t *port
)
755 struct sockaddr_in
*data_in
;
756 struct sockaddr_in6
*data_in6
;
758 switch(sock
->ss_family
) {
760 data_in
= (struct sockaddr_in
*)sock
;
762 *port
= ntohs((uint16_t)data_in
->sin_port
);
764 addr
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A
,
765 LDNS_IP4ADDRLEN
, &data_in
->sin_addr
);
768 data_in6
= (struct sockaddr_in6
*)sock
;
770 *port
= ntohs((uint16_t)data_in6
->sin6_port
);
772 addr
= ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA
,
773 LDNS_IP6ADDRLEN
, &data_in6
->sin6_addr
);
785 /* code from resolver.c */
787 ldns_axfr_start(ldns_resolver
*resolver
, ldns_rdf
*domain
, ldns_rr_class
class)
790 ldns_buffer
*query_wire
;
792 struct sockaddr_storage
*ns
= NULL
;
797 if (!resolver
|| ldns_resolver_nameserver_count(resolver
) < 1) {
798 return LDNS_STATUS_ERR
;
801 query
= ldns_pkt_query_new(ldns_rdf_clone(domain
), LDNS_RR_TYPE_AXFR
, class, 0);
804 return LDNS_STATUS_ADDRESS_ERR
;
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 */
810 ns_i
< ldns_resolver_nameserver_count(resolver
) &&
811 resolver
->_socket
== 0;
816 ns
= ldns_rdf2native_sockaddr_storage(
817 resolver
->_nameservers
[ns_i
],
818 ldns_resolver_port(resolver
), &ns_len
);
820 resolver
->_socket
= ldns_tcp_connect(ns
, (socklen_t
)ns_len
,
821 ldns_resolver_timeout(resolver
));
824 if (resolver
->_socket
== 0) {
825 ldns_pkt_free(query
);
827 return LDNS_STATUS_NETWORK_ERR
;
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! */
840 close(resolver
->_socket
);
842 closesocket(resolver
->_socket
);
844 resolver
->_socket
= 0;
846 ldns_pkt_free(query
);
849 return LDNS_STATUS_CRYPTO_TSIG_ERR
;
852 #endif /* HAVE_SSL */
854 /* Convert the query to a buffer
857 query_wire
= ldns_buffer_new(LDNS_MAX_PACKETLEN
);
859 ldns_pkt_free(query
);
862 close(resolver
->_socket
);
864 closesocket(resolver
->_socket
);
866 resolver
->_socket
= 0;
868 return LDNS_STATUS_MEM_ERR
;
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
);
876 /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start
877 we have to close the socket here! */
879 close(resolver
->_socket
);
881 closesocket(resolver
->_socket
);
883 resolver
->_socket
= 0;
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
);
894 /* RoRi: to prevent problems on subsequent calls to ldns_axfr_start
895 we have to close the socket here! */
898 close(resolver
->_socket
);
900 closesocket(resolver
->_socket
);
902 resolver
->_socket
= 0;
904 return LDNS_STATUS_NETWORK_ERR
;
907 ldns_pkt_free(query
);
908 ldns_buffer_free(query_wire
);
912 * The AXFR is done once the second SOA record is sent
914 resolver
->_axfr_soa_count
= 0;
915 return LDNS_STATUS_OK
;