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>
38 ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt)
42 ldns_rdf *tsig_mac = NULL;
44 qb = ldns_buffer_new(LDNS_MIN_BUFLEN);
46 if (query_pkt && ldns_pkt_tsig(query_pkt)) {
47 tsig_mac = ldns_rr_rdf(ldns_pkt_tsig(query_pkt), 3);
51 ldns_pkt2buffer_wire(qb, query_pkt) != LDNS_STATUS_OK) {
52 result = LDNS_STATUS_ERR;
54 result = ldns_send_buffer(result_packet, r, qb, tsig_mac);
62 /* code from rdata.c */
63 static struct sockaddr_storage *
64 ldns_rdf2native_sockaddr_storage_port(
65 const ldns_rdf *rd, uint16_t port, size_t *size)
67 struct sockaddr_storage *data;
68 struct sockaddr_in *data_in;
69 struct sockaddr_in6 *data_in6;
71 data = LDNS_MALLOC(struct sockaddr_storage);
75 /* zero the structure for portability */
76 memset(data, 0, sizeof(struct sockaddr_storage));
78 switch(ldns_rdf_get_type(rd)) {
81 data->ss_family = AF_INET;
83 data_in = (struct sockaddr_in*) data;
84 data_in->sin_port = (in_port_t)htons(port);
85 memcpy(&(data_in->sin_addr), ldns_rdf_data(rd), ldns_rdf_size(rd));
86 *size = sizeof(struct sockaddr_in);
88 case LDNS_RDF_TYPE_AAAA:
90 data->ss_family = AF_INET6;
92 data_in6 = (struct sockaddr_in6*) data;
93 data_in6->sin6_port = (in_port_t)htons(port);
94 memcpy(&data_in6->sin6_addr, ldns_rdf_data(rd), ldns_rdf_size(rd));
95 *size = sizeof(struct sockaddr_in6);
103 struct sockaddr_storage *
104 ldns_rdf2native_sockaddr_storage(
105 const ldns_rdf *rd, uint16_t port, size_t *size)
107 return ldns_rdf2native_sockaddr_storage_port(
108 rd, (port == 0 ? (uint16_t)LDNS_PORT : port), size);
111 /** best effort to set nonblocking */
113 ldns_sock_nonblock(int sockfd)
117 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
119 if(fcntl(sockfd, F_SETFL, flag) == -1) {
120 /* ignore error, continue blockingly */
123 #elif defined(HAVE_IOCTLSOCKET)
124 unsigned long on = 1;
125 if(ioctlsocket(sockfd, FIONBIO, &on) != 0) {
126 /* ignore error, continue blockingly */
131 /** best effort to set blocking */
133 ldns_sock_block(int sockfd)
137 if((flag = fcntl(sockfd, F_GETFL)) != -1) {
139 if(fcntl(sockfd, F_SETFL, flag) == -1) {
140 /* ignore error, continue */
143 #elif defined(HAVE_IOCTLSOCKET)
144 unsigned long off = 0;
145 if(ioctlsocket(sockfd, FIONBIO, &off) != 0) {
146 /* ignore error, continue */
151 /** wait for a socket to become ready */
153 ldns_sock_wait(int sockfd, struct timeval timeout, int write)
160 FD_SET(FD_SET_T sockfd, &fds);
162 ret = select(sockfd+1, NULL, &fds, NULL, &timeout);
164 ret = select(sockfd+1, &fds, NULL, NULL, &timeout);
167 struct pollfd pfds[2];
169 memset(&pfds[0], 0, sizeof(pfds[0]) * 2);
172 pfds[0].events = POLLIN|POLLERR;
175 pfds[0].events |= POLLOUT;
178 ret = poll(pfds, 1, (int)(timeout.tv_sec * 1000
179 + timeout.tv_usec / 1000));
182 /* timeout expired */
192 ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen,
193 const struct sockaddr_storage *from, socklen_t fromlen,
194 struct timeval timeout)
199 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM,
200 IPPROTO_TCP)) == SOCK_INVALID) {
204 if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == SOCK_INVALID){
208 /* perform nonblocking connect, to be able to wait with select() */
209 ldns_sock_nonblock(sockfd);
210 if (connect(sockfd, (struct sockaddr*)to, tolen) == SOCK_INVALID) {
213 if(errno != EINPROGRESS) {
217 close_socket(sockfd);
220 #else /* USE_WINSOCK */
221 if(WSAGetLastError() != WSAEINPROGRESS &&
222 WSAGetLastError() != WSAEWOULDBLOCK) {
223 close_socket(sockfd);
227 /* error was only telling us that it would block */
230 /* wait(write) until connected or error */
233 socklen_t len = (socklen_t)sizeof(error);
235 if(!ldns_sock_wait(sockfd, timeout, 1)) {
236 close_socket(sockfd);
240 /* check if there is a pending error for nonblocking connect */
241 if(getsockopt(sockfd, SOL_SOCKET, SO_ERROR, (void*)&error,
244 error = errno; /* on solaris errno is error */
246 error = WSAGetLastError();
250 #if defined(EINPROGRESS) && defined(EWOULDBLOCK)
251 if(error == EINPROGRESS || error == EWOULDBLOCK)
252 continue; /* try again */
254 else if(error != 0) {
255 close_socket(sockfd);
256 /* error in errno for our user */
260 #else /* USE_WINSOCK */
261 if(error == WSAEINPROGRESS)
263 else if(error == WSAEWOULDBLOCK)
265 else if(error != 0) {
266 close_socket(sockfd);
270 #endif /* USE_WINSOCK */
275 /* set the socket blocking again */
276 ldns_sock_block(sockfd);
282 ldns_tcp_connect(const struct sockaddr_storage *to, socklen_t tolen,
283 struct timeval timeout)
285 return ldns_tcp_connect_from(to, tolen, NULL, 0, timeout);
289 ldns_tcp_bgsend_from(ldns_buffer *qbin,
290 const struct sockaddr_storage *to, socklen_t tolen,
291 const struct sockaddr_storage *from, socklen_t fromlen,
292 struct timeval timeout)
296 sockfd = ldns_tcp_connect_from(to, tolen, from, fromlen, timeout);
302 if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) {
303 close_socket(sockfd);
311 ldns_tcp_bgsend(ldns_buffer *qbin,
312 const struct sockaddr_storage *to, socklen_t tolen,
313 struct timeval timeout)
315 return ldns_tcp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
319 /* keep in mind that in DNS tcp messages the first 2 bytes signal the
320 * amount data to expect
323 ldns_tcp_send_from(uint8_t **result, ldns_buffer *qbin,
324 const struct sockaddr_storage *to, socklen_t tolen,
325 const struct sockaddr_storage *from, socklen_t fromlen,
326 struct timeval timeout, size_t *answer_size)
331 sockfd = ldns_tcp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
334 return LDNS_STATUS_ERR;
337 answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout);
338 close_socket(sockfd);
340 if (*answer_size == 0) {
342 return LDNS_STATUS_NETWORK_ERR;
345 /* resize accordingly */
346 *result = LDNS_XREALLOC(answer, uint8_t, (size_t)*answer_size);
349 return LDNS_STATUS_MEM_ERR;
351 return LDNS_STATUS_OK;
355 ldns_tcp_send(uint8_t **result, ldns_buffer *qbin,
356 const struct sockaddr_storage *to, socklen_t tolen,
357 struct timeval timeout, size_t *answer_size)
359 return ldns_tcp_send_from(result, qbin,
360 to, tolen, NULL, 0, timeout, answer_size);
364 ldns_udp_connect(const struct sockaddr_storage *to, struct timeval ATTR_UNUSED(timeout))
369 if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_DGRAM,
379 ldns_udp_bgsend_from(ldns_buffer *qbin,
380 const struct sockaddr_storage *to , socklen_t tolen,
381 const struct sockaddr_storage *from, socklen_t fromlen,
382 struct timeval timeout)
386 sockfd = ldns_udp_connect(to, timeout);
392 if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){
396 if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) {
397 close_socket(sockfd);
404 ldns_udp_bgsend(ldns_buffer *qbin,
405 const struct sockaddr_storage *to , socklen_t tolen,
406 struct timeval timeout)
408 return ldns_udp_bgsend_from(qbin, to, tolen, NULL, 0, timeout);
412 ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin,
413 const struct sockaddr_storage *to , socklen_t tolen,
414 const struct sockaddr_storage *from, socklen_t fromlen,
415 struct timeval timeout, size_t *answer_size)
420 sockfd = ldns_udp_bgsend_from(qbin, to, tolen, from, fromlen, timeout);
423 return LDNS_STATUS_SOCKET_ERROR;
426 /* wait for an response*/
427 if(!ldns_sock_wait(sockfd, timeout, 0)) {
428 close_socket(sockfd);
429 return LDNS_STATUS_NETWORK_ERR;
432 /* set to nonblocking, so if the checksum is bad, it becomes
433 * an EGAIN error and the ldns_udp_send function does not block,
434 * but returns a 'NETWORK_ERROR' much like a timeout. */
435 ldns_sock_nonblock(sockfd);
437 answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL);
438 close_socket(sockfd);
440 if (*answer_size == 0) {
442 return LDNS_STATUS_NETWORK_ERR;
446 return LDNS_STATUS_OK;
450 ldns_udp_send(uint8_t **result, ldns_buffer *qbin,
451 const struct sockaddr_storage *to , socklen_t tolen,
452 struct timeval timeout, size_t *answer_size)
454 return ldns_udp_send_from(result, qbin, to, tolen, NULL, 0,
455 timeout, answer_size);
459 ldns_send_buffer(ldns_pkt **result, ldns_resolver *r, ldns_buffer *qb, ldns_rdf *tsig_mac)
463 struct sockaddr_storage *src = NULL;
465 struct sockaddr_storage *ns;
473 bool all_servers_rtt_inf;
476 uint8_t *reply_bytes = NULL;
477 size_t reply_size = 0;
478 ldns_status status, send_status;
482 status = LDNS_STATUS_OK;
483 rtt = ldns_resolver_rtt(r);
484 ns_array = ldns_resolver_nameservers(r);
488 all_servers_rtt_inf = true;
490 if (ldns_resolver_random(r)) {
491 ldns_resolver_nameservers_randomize(r);
494 if(ldns_resolver_source(r)) {
495 src = ldns_rdf2native_sockaddr_storage_port(
496 ldns_resolver_source(r), 0, &src_len);
499 /* loop through all defined nameservers */
500 for (i = 0; i < ldns_resolver_nameserver_count(r); i++) {
501 if (rtt[i] == LDNS_RESOLV_RTT_INF) {
502 /* not reachable nameserver! */
506 /* maybe verbosity setting?
507 printf("Sending to ");
508 ldns_rdf_print(stdout, ns_array[i]);
511 ns = ldns_rdf2native_sockaddr_storage(ns_array[i],
512 ldns_resolver_port(r), &ns_len);
516 if ((ns->ss_family == AF_INET) &&
517 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET6)) {
523 if ((ns->ss_family == AF_INET6) &&
524 (ldns_resolver_ip6(r) == LDNS_RESOLV_INET)) {
531 all_servers_rtt_inf = false;
533 gettimeofday(&tv_s, NULL);
535 send_status = LDNS_STATUS_ERR;
537 /* reply_bytes implicitly handles our error */
538 if (ldns_resolver_usevc(r)) {
539 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
541 ldns_tcp_send_from(&reply_bytes, qb,
542 ns, (socklen_t)ns_len,
543 src, (socklen_t)src_len,
544 ldns_resolver_timeout(r),
546 if (send_status == LDNS_STATUS_OK) {
551 for (retries = ldns_resolver_retry(r); retries > 0; retries--) {
552 /* ldns_rdf_print(stdout, ns_array[i]); */
554 ldns_udp_send_from(&reply_bytes, qb,
555 ns, (socklen_t)ns_len,
556 src, (socklen_t)src_len,
557 ldns_resolver_timeout(r),
559 if (send_status == LDNS_STATUS_OK) {
565 if (send_status != LDNS_STATUS_OK) {
566 ldns_resolver_set_nameserver_rtt(r, i, LDNS_RESOLV_RTT_INF);
567 status = send_status;
570 /* obey the fail directive */
572 /* the current nameserver seems to have a problem, blacklist it */
573 if (ldns_resolver_fail(r)) {
575 return LDNS_STATUS_ERR;
582 status = ldns_wire2pkt(&reply, reply_bytes, reply_size);
583 if (status != LDNS_STATUS_OK) {
584 LDNS_FREE(reply_bytes);
590 gettimeofday(&tv_e, NULL);
593 ldns_pkt_set_querytime(reply, (uint32_t)
594 ((tv_e.tv_sec - tv_s.tv_sec) * 1000) +
595 (tv_e.tv_usec - tv_s.tv_usec) / 1000);
596 ldns_pkt_set_answerfrom(reply,
597 ldns_rdf_clone(ns_array[i]));
598 ldns_pkt_set_timestamp(reply, tv_s);
599 ldns_pkt_set_size(reply, reply_size);
602 if (ldns_resolver_fail(r)) {
603 /* if fail is set bail out, after the first
609 /* wait retrans seconds... */
610 sleep((unsigned int) ldns_resolver_retrans(r));
616 if (all_servers_rtt_inf) {
617 LDNS_FREE(reply_bytes);
618 return LDNS_STATUS_RES_NO_NS;
621 if (tsig_mac && reply && reply_bytes) {
622 if (!ldns_pkt_tsig_verify(reply,
625 ldns_resolver_tsig_keyname(r),
626 ldns_resolver_tsig_keydata(r), tsig_mac)) {
627 status = LDNS_STATUS_CRYPTO_TSIG_BOGUS;
632 #endif /* HAVE_SSL */
634 LDNS_FREE(reply_bytes);
643 ldns_tcp_send_query(ldns_buffer *qbin, int sockfd,
644 const struct sockaddr_storage *to, socklen_t tolen)
649 /* add length of packet */
650 sendbuf = LDNS_XMALLOC(uint8_t, ldns_buffer_position(qbin) + 2);
651 if(!sendbuf) return 0;
652 ldns_write_uint16(sendbuf, ldns_buffer_position(qbin));
653 memcpy(sendbuf + 2, ldns_buffer_begin(qbin), ldns_buffer_position(qbin));
655 bytes = sendto(sockfd, (void*)sendbuf,
656 ldns_buffer_position(qbin) + 2, 0, (struct sockaddr *)to, tolen);
660 if (bytes == -1 || (size_t) bytes != ldns_buffer_position(qbin) + 2 ) {
666 /* don't wait for an answer */
668 ldns_udp_send_query(ldns_buffer *qbin, int sockfd, const struct sockaddr_storage *to,
673 bytes = sendto(sockfd, (void*)ldns_buffer_begin(qbin),
674 ldns_buffer_position(qbin), 0, (struct sockaddr *)to, tolen);
676 if (bytes == -1 || (size_t)bytes != ldns_buffer_position(qbin)) {
679 if ((size_t) bytes != ldns_buffer_position(qbin)) {
686 ldns_udp_read_wire(int sockfd, size_t *size, struct sockaddr_storage *from,
689 uint8_t *wire, *wireout;
692 wire = LDNS_XMALLOC(uint8_t, LDNS_MAX_PACKETLEN);
698 wire_size = recvfrom(sockfd, (void*)wire, LDNS_MAX_PACKETLEN, 0,
699 (struct sockaddr *)from, fromlen);
701 /* recvfrom can also return 0 */
702 if (wire_size == -1 || wire_size == 0) {
708 *size = (size_t)wire_size;
709 wireout = LDNS_XREALLOC(wire, uint8_t, (size_t)wire_size);
710 if(!wireout) LDNS_FREE(wire);
716 ldns_tcp_read_wire_timeout(int sockfd, size_t *size, struct timeval timeout)
720 ssize_t bytes = 0, rc = 0;
722 wire = LDNS_XMALLOC(uint8_t, 2);
729 if(!ldns_sock_wait(sockfd, timeout, 0)) {
734 rc = recv(sockfd, (void*) (wire + bytes),
735 (size_t) (2 - bytes), 0);
736 if (rc == -1 || rc == 0) {
744 wire_size = ldns_read_uint16(wire);
747 wire = LDNS_XMALLOC(uint8_t, wire_size);
754 while (bytes < (ssize_t) wire_size) {
755 if(!ldns_sock_wait(sockfd, timeout, 0)) {
760 rc = recv(sockfd, (void*) (wire + bytes),
761 (size_t) (wire_size - bytes), 0);
762 if (rc == -1 || rc == 0) {
770 *size = (size_t) bytes;
775 ldns_tcp_read_wire(int sockfd, size_t *size)
779 ssize_t bytes = 0, rc = 0;
781 wire = LDNS_XMALLOC(uint8_t, 2);
788 rc = recv(sockfd, (void*) (wire + bytes),
789 (size_t) (2 - bytes), 0);
790 if (rc == -1 || rc == 0) {
798 wire_size = ldns_read_uint16(wire);
801 wire = LDNS_XMALLOC(uint8_t, wire_size);
808 while (bytes < (ssize_t) wire_size) {
809 rc = recv(sockfd, (void*) (wire + bytes),
810 (size_t) (wire_size - bytes), 0);
811 if (rc == -1 || rc == 0) {
819 *size = (size_t) bytes;
825 ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port)
828 struct sockaddr_in *data_in;
829 struct sockaddr_in6 *data_in6;
831 switch(sock->ss_family) {
833 data_in = (struct sockaddr_in*)sock;
835 *port = ntohs((uint16_t)data_in->sin_port);
837 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_A,
838 LDNS_IP4ADDRLEN, &data_in->sin_addr);
841 data_in6 = (struct sockaddr_in6*)sock;
843 *port = ntohs((uint16_t)data_in6->sin6_port);
845 addr = ldns_rdf_new_frm_data(LDNS_RDF_TYPE_AAAA,
846 LDNS_IP6ADDRLEN, &data_in6->sin6_addr);
858 /* code from resolver.c */
860 ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class)
863 ldns_buffer *query_wire;
865 struct sockaddr_storage *src = NULL;
867 struct sockaddr_storage *ns = NULL;
872 if (!resolver || ldns_resolver_nameserver_count(resolver) < 1) {
873 return LDNS_STATUS_ERR;
876 query = ldns_pkt_query_new(ldns_rdf_clone(domain), LDNS_RR_TYPE_AXFR, class, 0);
879 return LDNS_STATUS_ADDRESS_ERR;
881 if(ldns_resolver_source(resolver)) {
882 src = ldns_rdf2native_sockaddr_storage_port(
883 ldns_resolver_source(resolver), 0, &src_len);
885 /* For AXFR, we have to make the connection ourselves */
886 /* try all nameservers (which usually would mean v4 fallback if
887 * @hostname is used */
889 ns_i < ldns_resolver_nameserver_count(resolver) &&
890 resolver->_socket == SOCK_INVALID;
895 ns = ldns_rdf2native_sockaddr_storage(
896 resolver->_nameservers[ns_i],
897 ldns_resolver_port(resolver), &ns_len);
899 if ((ns->ss_family == AF_INET) &&
900 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET6)) {
907 if ((ns->ss_family == AF_INET6) &&
908 (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET)) {
916 resolver->_socket = ldns_tcp_connect_from(
917 ns, (socklen_t)ns_len,
918 src, (socklen_t)src_len,
919 ldns_resolver_timeout(resolver));
922 if (resolver->_socket == SOCK_INVALID) {
923 ldns_pkt_free(query);
925 return LDNS_STATUS_NETWORK_ERR;
929 if (ldns_resolver_tsig_keyname(resolver) && ldns_resolver_tsig_keydata(resolver)) {
930 status = ldns_pkt_tsig_sign(query,
931 ldns_resolver_tsig_keyname(resolver),
932 ldns_resolver_tsig_keydata(resolver),
933 300, ldns_resolver_tsig_algorithm(resolver), NULL);
934 if (status != LDNS_STATUS_OK) {
935 /* to prevent problems on subsequent calls to
936 * ldns_axfr_start we have to close the socket here! */
937 close_socket(resolver->_socket);
938 resolver->_socket = 0;
940 ldns_pkt_free(query);
943 return LDNS_STATUS_CRYPTO_TSIG_ERR;
946 #endif /* HAVE_SSL */
948 /* Convert the query to a buffer
951 query_wire = ldns_buffer_new(LDNS_MAX_PACKETLEN);
953 ldns_pkt_free(query);
956 close_socket(resolver->_socket);
958 return LDNS_STATUS_MEM_ERR;
960 status = ldns_pkt2buffer_wire(query_wire, query);
961 if (status != LDNS_STATUS_OK) {
962 ldns_pkt_free(query);
963 ldns_buffer_free(query_wire);
966 /* to prevent problems on subsequent calls to ldns_axfr_start
967 * we have to close the socket here! */
968 close_socket(resolver->_socket);
969 resolver->_socket = 0;
974 if (ldns_tcp_send_query(query_wire, resolver->_socket, ns,
975 (socklen_t)ns_len) == 0) {
976 ldns_pkt_free(query);
977 ldns_buffer_free(query_wire);
980 /* to prevent problems on subsequent calls to ldns_axfr_start
981 * we have to close the socket here! */
984 close_socket(resolver->_socket);
986 return LDNS_STATUS_NETWORK_ERR;
989 ldns_pkt_free(query);
990 ldns_buffer_free(query_wire);
994 * The AXFR is done once the second SOA record is sent
996 resolver->_axfr_soa_count = 0;
997 return LDNS_STATUS_OK;