Commit 08a70d11 authored by Steinar H. Gunderson's avatar Steinar H. Gunderson
Browse files

Support a few more socket options, and refactor the option setting a bit....

Support a few more socket options, and refactor the option setting a bit. (Patch from the Google tree.)
parent 6ce589c3
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -98,6 +98,8 @@ extern "C" {
#define ARES_OPT_LOOKUPS        (1 << 8)
#define ARES_OPT_SOCK_STATE_CB  (1 << 9)
#define ARES_OPT_SORTLIST       (1 << 10)
#define ARES_OPT_SOCK_SNDBUF    (1 << 11)
#define ARES_OPT_SOCK_RCVBUF    (1 << 12)

/* Nameinfo flag values */
#define ARES_NI_NOFQDN                  (1 << 0)
@@ -177,6 +179,8 @@ struct ares_options {
  int ndots;
  unsigned short udp_port;
  unsigned short tcp_port;
  int socket_send_buffer_size;
  int socket_receive_buffer_size;
  struct in_addr *servers;
  int nservers;
  char **domains;
+8 −0
Original line number Diff line number Diff line
@@ -133,6 +133,8 @@ int ares_init_options(ares_channel *channelptr, struct ares_options *options,
  channel->ndots = -1;
  channel->udp_port = -1;
  channel->tcp_port = -1;
  channel->socket_send_buffer_size = -1;
  channel->socket_receive_buffer_size = -1;
  channel->nservers = -1;
  channel->ndomains = -1;
  channel->nsort = -1;
@@ -320,6 +322,12 @@ static int init_by_options(ares_channel channel,
      channel->sock_state_cb = options->sock_state_cb;
      channel->sock_state_cb_data = options->sock_state_cb_data;
    }
  if ((optmask & ARES_OPT_SOCK_SNDBUF)
      && channel->socket_send_buffer_size == -1)
    channel->socket_send_buffer_size = options->socket_send_buffer_size;
  if ((optmask & ARES_OPT_SOCK_RCVBUF)
      && channel->socket_receive_buffer_size == -1)
    channel->socket_receive_buffer_size = options->socket_receive_buffer_size;

  /* Copy the servers, if given. */
  if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
+52 −3
Original line number Diff line number Diff line
@@ -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));