diff options
author | Damien Miller <djm@cvs.openbsd.org> | 2008-04-18 21:36:33 +0000 |
---|---|---|
committer | Damien Miller <djm@cvs.openbsd.org> | 2008-04-18 21:36:33 +0000 |
commit | 9401d49a2b768142978900366550c34248f01d0d (patch) | |
tree | ce1027559ac892f112b90cf0dc93ecdaa8895e40 | |
parent | ade8c4cfcd982e74d7424cee174e1dbee07b073f (diff) |
convert select() => poll(), saves a runtime malloc+free per retry
feedback deraadt@ drahn@; ok deraadt@
-rw-r--r-- | lib/libc/net/res_send.c | 39 |
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; } |