diff options
author | Steinar H. Gunderson <sesse@google.com> | 2007-09-28 15:15:39 +0000 |
---|---|---|
committer | Steinar H. Gunderson <sesse@google.com> | 2007-09-28 15:15:39 +0000 |
commit | 56ffdcefe1a7e2f60bf451a7d3a16cb903dcf9d9 (patch) | |
tree | 69230da18683f08219e68132dfd937784784537f /ares_process.c | |
parent | 50ba81cd230f9054fa7c45cb4202ce8720c502b3 (diff) | |
download | c-ares-56ffdcefe1a7e2f60bf451a7d3a16cb903dcf9d9.tar.gz c-ares-56ffdcefe1a7e2f60bf451a7d3a16cb903dcf9d9.tar.bz2 c-ares-56ffdcefe1a7e2f60bf451a7d3a16cb903dcf9d9.zip |
Support a few more socket options, and refactor the option setting a bit. (Patch from the Google tree.)
Diffstat (limited to 'ares_process.c')
-rw-r--r-- | ares_process.c | 55 |
1 files changed, 52 insertions, 3 deletions
diff --git a/ares_process.c b/ares_process.c index d359b11..1db3d11 100644 --- a/ares_process.c +++ b/ares_process.c @@ -25,6 +25,7 @@ #ifdef HAVE_SYS_UIO_H #include <sys/uio.h> #endif +#include <netinet/tcp.h> /* for TCP_NODELAY */ #include <netinet/in.h> #include <netdb.h> #include <arpa/nameser.h> @@ -732,9 +733,36 @@ static int nonblock(ares_socket_t sockfd, /* operate on this */ #endif } +static int configure_socket(int s, ares_channel channel) +{ + nonblock(s, TRUE); + +#ifdef FD_CLOEXEC + /* Configure the socket fd as close-on-exec. */ + if (fcntl(s, F_SETFD, FD_CLOEXEC) == -1) + return -1; +#endif + + /* Set the socket's send and receive buffer sizes. */ + if ((channel->socket_send_buffer_size > 0) && + setsockopt(s, SOL_SOCKET, SO_SNDBUF, + &channel->socket_send_buffer_size, + sizeof(channel->socket_send_buffer_size)) == -1) + return -1; + + if ((channel->socket_receive_buffer_size > 0) && + setsockopt(s, SOL_SOCKET, SO_RCVBUF, + &channel->socket_receive_buffer_size, + sizeof(channel->socket_receive_buffer_size)) == -1) + return -1; + + return 0; + } + static int open_tcp_socket(ares_channel channel, struct server_state *server) { ares_socket_t s; + int opt; struct sockaddr_in sockin; /* Acquire a socket. */ @@ -742,8 +770,25 @@ static int open_tcp_socket(ares_channel channel, struct server_state *server) if (s == ARES_SOCKET_BAD) return -1; - /* Set the socket non-blocking. */ - nonblock(s, TRUE); + /* Configure it. */ + if (configure_socket(s, channel) < 0) + { + close(s); + return -1; + } + + /* + * Disable the Nagle algorithm (only relevant for TCP sockets, and thus not in + * configure_socket). In general, in DNS lookups we're pretty much interested + * in firing off a single request and then waiting for a reply, so batching + * isn't very interesting in general. + */ + opt = 1; + if (setsockopt(s, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)) == -1) + { + close(s); + return -1; + } /* Connect to the server. */ memset(&sockin, 0, sizeof(sockin)); @@ -777,7 +822,11 @@ static int open_udp_socket(ares_channel channel, struct server_state *server) return -1; /* Set the socket non-blocking. */ - nonblock(s, TRUE); + if (configure_socket(s, channel) < 0) + { + close(s); + return -1; + } /* Connect to the server. */ memset(&sockin, 0, sizeof(sockin)); |