Source: ldns Severity: important Tags: patch
-- System Information: Debian Release: 8.0 APT prefers testing APT policy: (500, 'testing') Architecture: amd64 (x86_64) Kernel: Linux 3.16-2-amd64 (SMP w/2 CPU cores) Locale: LANG=en_US.UTF-8, LC_CTYPE=en_US.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/dash Init: systemd (via /run/systemd/system) -- William King Senior Engineer Quentus Technologies, INC 1037 NE 65th St Suite 273 Seattle, WA 98115 Main: (877) 211-9337 Office: (206) 388-4772 Cell: (253) 686-5518 [email protected]
commit 4e6f7728b09861b5d323a08496185c94af778666 Author: William King <[email protected]> Date: Fri Apr 3 14:39:40 2015 -0700 use poll where necessary so we don't select beyond 1024 on nix's that don't support it diff --git a/ldns/ldns.h b/ldns/ldns.h index 60663ef..7039d29 100644 --- a/ldns/ldns.h +++ b/ldns/ldns.h @@ -151,6 +151,16 @@ extern ldns_lookup_table ldns_opcodes[]; /** EDNS flags */ extern ldns_lookup_table ldns_edns_flags[]; + +#ifdef USE_WINSOCK +#define SOCK_INVALID INVALID_SOCKET +#define close_socket(_s) if (_s > SOCK_INVALID) {closesocket(_s); _s = SOCK_INVALID;} +#else +#define SOCK_INVALID -1 +#define close_socket(_s) if (_s > SOCK_INVALID) {close(_s); _s = SOCK_INVALID;} +#endif + + #ifdef __cplusplus } #endif diff --git a/net.c b/net.c index b8a5385..8be18ef 100644 --- a/net.c +++ b/net.c @@ -145,11 +145,16 @@ ldns_sock_block(int sockfd) #endif } +#ifndef WIN32 +#include <poll.h> +#endif + /** wait for a socket to become ready */ static int ldns_sock_wait(int sockfd, struct timeval timeout, int write) { int ret; +#ifdef WIN32 #ifndef S_SPLINT_S fd_set fds; FD_ZERO(&fds); @@ -159,6 +164,23 @@ 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]; + int x = 0; + + 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, timeout.tv_sec * 1000 + timeout.tv_usec / 1000); + +#endif if(ret == 0) /* timeout expired */ return 0; @@ -178,30 +200,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 +236,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 +255,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 +266,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 +303,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 +338,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 +397,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 +428,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 +438,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 */ @@ -892,7 +890,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); @@ -907,7 +905,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 +920,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 +938,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 +951,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 +966,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; } diff --git a/resolver.c b/resolver.c index 1474dc8..ff8aa47 100644 --- a/resolver.c +++ b/resolver.c @@ -649,9 +649,7 @@ ldns_resolver_new(void) r->_timeout.tv_sec = LDNS_DEFAULT_TIMEOUT_SEC; r->_timeout.tv_usec = LDNS_DEFAULT_TIMEOUT_USEC; - /* TODO: fd=0 is actually a valid socket (stdin), - replace with -1 */ - r->_socket = 0; + r->_socket = -1; r->_axfr_soa_count = 0; r->_axfr_i = 0; r->_cur_axfr_pkt = NULL; @@ -947,6 +945,8 @@ ldns_resolver_deep_free(ldns_resolver *res) size_t i; if (res) { + close_socket(res->_socket); + if (res->_searchlist) { for (i = 0; i < ldns_resolver_searchlist_count(res); i++) { ldns_rdf_deep_free(res->_searchlist[i]); @@ -1281,7 +1281,7 @@ ldns_axfr_next(ldns_resolver *resolver) ldns_status status; /* check if start() has been called */ - if (!resolver || resolver->_socket == 0) { + if (!resolver || resolver->_socket == -1) { return NULL; } @@ -1298,12 +1298,9 @@ ldns_axfr_next(ldns_resolver *resolver) if (ldns_rr_get_type(cur_rr) == LDNS_RR_TYPE_SOA) { resolver->_axfr_soa_count++; if (resolver->_axfr_soa_count >= 2) { -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif - resolver->_socket = 0; + + close_socket(resolver->_socket); + ldns_pkt_free(resolver->_cur_axfr_pkt); resolver->_cur_axfr_pkt = NULL; } @@ -1328,12 +1325,8 @@ ldns_axfr_next(ldns_resolver *resolver) /* we must now also close the socket, otherwise subsequent uses of the same resolver structure will fail because the link is still open or in an undefined state */ -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif - resolver->_socket = 0; + + close_socket(resolver->_socket); return NULL; } else if (ldns_pkt_get_rcode(resolver->_cur_axfr_pkt) != 0) { @@ -1352,12 +1345,8 @@ ldns_axfr_next(ldns_resolver *resolver) /* we must now also close the socket, otherwise subsequent uses of the same resolver structure will fail because the link is still open or in an undefined state */ -#ifndef USE_WINSOCK - close(resolver->_socket); -#else - closesocket(resolver->_socket); -#endif - resolver->_socket = 0; + + close_socket(resolver->_socket); return NULL; } else {

