summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDamien Miller <djm@cvs.openbsd.org>2008-04-18 21:36:33 +0000
committerDamien Miller <djm@cvs.openbsd.org>2008-04-18 21:36:33 +0000
commit9401d49a2b768142978900366550c34248f01d0d (patch)
treece1027559ac892f112b90cf0dc93ecdaa8895e40
parentade8c4cfcd982e74d7424cee174e1dbee07b073f (diff)
convert select() => poll(), saves a runtime malloc+free per retry
feedback deraadt@ drahn@; ok deraadt@
-rw-r--r--lib/libc/net/res_send.c39
1 files changed, 16 insertions, 23 deletions
diff --git a/lib/libc/net/res_send.c b/lib/libc/net/res_send.c
index f7631350bc4..187210cbd87 100644
--- a/lib/libc/net/res_send.c
+++ b/lib/libc/net/res_send.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: res_send.c,v 1.19 2005/08/06 20:30:04 espie Exp $ */
+/* $OpenBSD: res_send.c,v 1.20 2008/04/18 21:36:32 djm Exp $ */
/*
* ++Copyright++ 1985, 1989, 1993
@@ -75,10 +75,11 @@
#include <arpa/nameser.h>
#include <arpa/inet.h>
-#include <stdio.h>
-#include <netdb.h>
#include <errno.h>
+#include <netdb.h>
+#include <poll.h>
#include <resolv.h>
+#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
@@ -466,7 +467,7 @@ res_send(const u_char *buf, int buflen, u_char *ans, int anssiz)
/*
* Receive length & response
*/
-read_len:
+ read_len:
cp = ans;
len = INT16SZ;
while ((n = read(s, (char *)cp, (int)len)) > 0) {
@@ -553,8 +554,8 @@ read_len:
/*
* Use datagrams.
*/
- struct timeval timeout;
- fd_set *dsmaskp;
+ struct pollfd pfd;
+ int timeout;
struct sockaddr_storage from;
socklen_t fromlen;
@@ -594,7 +595,7 @@ read_len:
* ICMP port unreachable message to be returned.
* If our datagram socket is "connected" to the
* server, we get an ECONNREFUSED error on the next
- * socket operation, and select returns if the
+ * socket operation, and poll returns if the
* error message is received. We can thus detect
* the absence of a nameserver without timing out.
* If we have sent queries to at least two servers,
@@ -676,27 +677,19 @@ read_len:
/*
* Wait for reply
*/
- timeout.tv_sec = (_resp->retrans << try);
+ timeout = 1000 * (_resp->retrans << try);
if (try > 0)
- timeout.tv_sec /= _resp->nscount;
- if ((long) timeout.tv_sec <= 0)
- timeout.tv_sec = 1;
- timeout.tv_usec = 0;
+ timeout /= _resp->nscount;
+ if (timeout < 1000)
+ timeout = 1000;
wait:
- dsmaskp = (fd_set *)calloc(howmany(s+1, NFDBITS),
- sizeof(fd_mask));
- if (dsmaskp == NULL) {
- res_close();
- goto next_ns;
- }
- FD_SET(s, dsmaskp);
- n = select(s+1, dsmaskp, (fd_set *)NULL,
- (fd_set *)NULL, &timeout);
- free(dsmaskp);
+ pfd.fd = s;
+ pfd.events = POLLIN;
+ n = poll(&pfd, 1, timeout);
if (n < 0) {
if (errno == EINTR)
goto wait;
- Perror(stderr, "select", errno);
+ Perror(stderr, "poll", errno);
res_close();
goto next_ns;
}