diff options
Diffstat (limited to 'net.c')
-rw-r--r-- | net.c | 122 |
1 files changed, 59 insertions, 63 deletions
@@ -30,6 +30,9 @@ #include <sys/time.h> #include <errno.h> #include <fcntl.h> +#ifdef HAVE_POLL +#include <poll.h> +#endif ldns_status ldns_send(ldns_pkt **result_packet, ldns_resolver *r, const ldns_pkt *query_pkt) @@ -150,6 +153,7 @@ static int ldns_sock_wait(int sockfd, struct timeval timeout, int write) { int ret; +#ifndef HAVE_POLL #ifndef S_SPLINT_S fd_set fds; FD_ZERO(&fds); @@ -159,6 +163,21 @@ ldns_sock_wait(int sockfd, struct timeval timeout, int write) else ret = select(sockfd+1, &fds, NULL, NULL, &timeout); #endif +#else + struct pollfd pfds[2]; + + memset(&pfds[0], 0, sizeof(pfds[0]) * 2); + + pfds[0].fd = sockfd; + pfds[0].events = POLLIN|POLLERR; + + if (write) { + pfds[0].events |= POLLOUT; + } + + ret = poll(pfds, 1, (int)(timeout.tv_sec * 1000 + + timeout.tv_usec / 1000)); +#endif if(ret == 0) /* timeout expired */ return 0; @@ -178,30 +197,30 @@ ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen, #ifndef S_SPLINT_S if ((sockfd = socket((int)((struct sockaddr*)to)->sa_family, SOCK_STREAM, - IPPROTO_TCP)) == -1) { + IPPROTO_TCP)) == SOCK_INVALID) { return 0; } #endif - if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == -1){ + if (from && bind(sockfd, (const struct sockaddr*)from, fromlen) == SOCK_INVALID){ return 0; } /* perform nonblocking connect, to be able to wait with select() */ ldns_sock_nonblock(sockfd); - if (connect(sockfd, (struct sockaddr*)to, tolen) == -1) { + if (connect(sockfd, (struct sockaddr*)to, tolen) == SOCK_INVALID) { #ifndef USE_WINSOCK #ifdef EINPROGRESS if(errno != EINPROGRESS) { #else if(1) { #endif - close(sockfd); + close_socket(sockfd); return 0; } #else /* USE_WINSOCK */ if(WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEWOULDBLOCK) { - closesocket(sockfd); + close_socket(sockfd); return 0; } #endif @@ -214,11 +233,7 @@ ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen, socklen_t len = (socklen_t)sizeof(error); if(!ldns_sock_wait(sockfd, timeout, 1)) { -#ifndef USE_WINSOCK - close(sockfd); -#else - closesocket(sockfd); -#endif + close_socket(sockfd); return 0; } @@ -237,7 +252,7 @@ ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen, continue; /* try again */ #endif else if(error != 0) { - close(sockfd); + close_socket(sockfd); /* error in errno for our user */ errno = error; return 0; @@ -248,7 +263,7 @@ ldns_tcp_connect_from(const struct sockaddr_storage *to, socklen_t tolen, else if(error == WSAEWOULDBLOCK) continue; else if(error != 0) { - closesocket(sockfd); + close_socket(sockfd); errno = error; return 0; } @@ -285,11 +300,7 @@ ldns_tcp_bgsend_from(ldns_buffer *qbin, } if (ldns_tcp_send_query(qbin, sockfd, to, tolen) == 0) { -#ifndef USE_WINSOCK - close(sockfd); -#else - closesocket(sockfd); -#endif + close_socket(sockfd); return 0; } @@ -324,11 +335,7 @@ ldns_tcp_send_from(uint8_t **result, ldns_buffer *qbin, } answer = ldns_tcp_read_wire_timeout(sockfd, answer_size, timeout); -#ifndef USE_WINSOCK - close(sockfd); -#else - closesocket(sockfd); -#endif + close_socket(sockfd); if (*answer_size == 0) { /* oops */ @@ -387,11 +394,7 @@ ldns_udp_bgsend_from(ldns_buffer *qbin, } if (ldns_udp_send_query(qbin, sockfd, to, tolen) == 0) { -#ifndef USE_WINSOCK - close(sockfd); -#else - closesocket(sockfd); -#endif + close_socket(sockfd); return 0; } return sockfd; @@ -422,11 +425,7 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin, /* wait for an response*/ if(!ldns_sock_wait(sockfd, timeout, 0)) { -#ifndef USE_WINSOCK - close(sockfd); -#else - closesocket(sockfd); -#endif + close_socket(sockfd); return LDNS_STATUS_NETWORK_ERR; } @@ -436,11 +435,7 @@ ldns_udp_send_from(uint8_t **result, ldns_buffer *qbin, ldns_sock_nonblock(sockfd); answer = ldns_udp_read_wire(sockfd, answer_size, NULL, NULL); -#ifndef USE_WINSOCK - close(sockfd); -#else - closesocket(sockfd); -#endif + close_socket(sockfd); if (*answer_size == 0) { /* oops */ @@ -827,7 +822,7 @@ ldns_tcp_read_wire(int sockfd, size_t *size) #ifndef S_SPLINT_S ldns_rdf * -ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port) +ldns_sockaddr_storage2rdf(const struct sockaddr_storage *sock, uint16_t *port) { ldns_rdf *addr; struct sockaddr_in *data_in; @@ -862,7 +857,7 @@ ldns_sockaddr_storage2rdf(struct sockaddr_storage *sock, uint16_t *port) /* code from resolver.c */ ldns_status -ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) +ldns_axfr_start(ldns_resolver *resolver, const ldns_rdf *domain, ldns_rr_class class) { ldns_pkt *query; ldns_buffer *query_wire; @@ -892,7 +887,7 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) * @hostname is used */ for (ns_i = 0; ns_i < ldns_resolver_nameserver_count(resolver) && - resolver->_socket == 0; + resolver->_socket == SOCK_INVALID; ns_i++) { if (ns != NULL) { LDNS_FREE(ns); @@ -900,6 +895,23 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) ns = ldns_rdf2native_sockaddr_storage( resolver->_nameservers[ns_i], ldns_resolver_port(resolver), &ns_len); +#ifndef S_SPLINT_S + if ((ns->ss_family == AF_INET) && + (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET6)) { + /* not reachable */ + LDNS_FREE(ns); + ns = NULL; + continue; + } + + if ((ns->ss_family == AF_INET6) && + (ldns_resolver_ip6(resolver) == LDNS_RESOLV_INET)) { + /* not reachable */ + LDNS_FREE(ns); + ns = NULL; + continue; + } +#endif resolver->_socket = ldns_tcp_connect_from( ns, (socklen_t)ns_len, @@ -907,7 +919,7 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) ldns_resolver_timeout(resolver)); } - if (resolver->_socket == 0) { + if (resolver->_socket == SOCK_INVALID) { ldns_pkt_free(query); LDNS_FREE(ns); return LDNS_STATUS_NETWORK_ERR; @@ -922,11 +934,7 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) if (status != LDNS_STATUS_OK) { /* to prevent problems on subsequent calls to * ldns_axfr_start we have to close the socket here! */ -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif + close_socket(resolver->_socket); resolver->_socket = 0; ldns_pkt_free(query); @@ -944,12 +952,8 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) if(!query_wire) { ldns_pkt_free(query); LDNS_FREE(ns); -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif - resolver->_socket = 0; + + close_socket(resolver->_socket); return LDNS_STATUS_MEM_ERR; } @@ -961,11 +965,7 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) /* to prevent problems on subsequent calls to ldns_axfr_start * we have to close the socket here! */ -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif + close_socket(resolver->_socket); resolver->_socket = 0; return status; @@ -980,12 +980,8 @@ ldns_axfr_start(ldns_resolver *resolver, ldns_rdf *domain, ldns_rr_class class) /* to prevent problems on subsequent calls to ldns_axfr_start * we have to close the socket here! */ -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif - resolver->_socket = 0; + + close_socket(resolver->_socket); return LDNS_STATUS_NETWORK_ERR; } |