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 {

Reply via email to