Commit 21f331ea authored by Yang Tse's avatar Yang Tse
Browse files

Added IPv6 name servers support
parent f9337470
Loading
Loading
Loading
Loading
+21 −0
Original line number Diff line number Diff line
  Changelog for the c-ares project

* March 5, 2010 (Yang Tse)
- Added IPv6 name servers support. Implementation has been based on code,
  comments and feedback provided November and December of 2008 by Daniel
  Stenberg, Gregor Jasny, Phil Blundell and myself, December 2009 by Cedric
  Bail, and February 2010 by Jakub Hrozek on the c-ares mailing list. On
  March I reviewed all that, selected the best of each, and adjusted or
  extended parts of it to make the best fit.

  The external and visible result of all this is that two new functions are
  added to the external API, ares_get_servers() and ares_set_servers(), which
  becomes now the preferred way of getting and setting name servers for any
  ares channel as these support both IPv4 and IPv6 name servers.

  In order to not break ABI compatibility, ares_init_options() with option
  mask ARES_OPT_SERVERS and ares_save_options() may still be used in code
  which is intended to run on IPv4-only stacks. But remember that these
  functions do not support IPv6 name servers. This implies that if the user
  is capable of defining or providing an IPv6 name server, and the app is
  using ares_init_options() or ares_save_options() at some point to handle
  the name servers, the app will likely loose IPv6 name servers.

* January 28, 2010 (Daniel Stenberg)
- Tommie Gannert pointed out a silly bug in ares_process_fd() since it didn't
  check for broken connections like ares_process() did. Based on that, I
+8 −1
Original line number Diff line number Diff line
@@ -20,6 +20,7 @@ CSOURCES = ares__close_sockets.c \
  ares_llist.c				\
  ares_mkquery.c			\
  ares_nowarn.c				\
  ares_options.c			\
  ares_parse_a_reply.c			\
  ares_parse_aaaa_reply.c		\
  ares_parse_ns_reply.c			\
@@ -48,8 +49,8 @@ HHEADERS = ares.h \
  ares_ipv6.h				\
  ares_library_init.h			\
  ares_llist.h				\
  ares_private.h			\
  ares_nowarn.h				\
  ares_private.h			\
  ares_rules.h				\
  ares_strcasecmp.h			\
  ares_strdup.h				\
@@ -72,6 +73,7 @@ MANPAGES = ares_cancel.3 \
  ares_free_data.3			\
  ares_free_hostent.3			\
  ares_free_string.3			\
  ares_get_servers.3			\
  ares_gethostbyaddr.3			\
  ares_gethostbyname.3			\
  ares_gethostbyname_file.3		\
@@ -93,6 +95,7 @@ MANPAGES = ares_cancel.3 \
  ares_save_options.3			\
  ares_search.3				\
  ares_send.3				\
  ares_set_servers.3			\
  ares_set_socket_callback.3		\
  ares_strerror.3			\
  ares_timeout.3			\
@@ -108,6 +111,7 @@ HTMLPAGES = ares_cancel.html \
  ares_free_data.html			\
  ares_free_hostent.html		\
  ares_free_string.html			\
  ares_get_servers.html			\
  ares_gethostbyaddr.html		\
  ares_gethostbyname.html		\
  ares_gethostbyname_file.html		\
@@ -129,6 +133,7 @@ HTMLPAGES = ares_cancel.html \
  ares_save_options.html		\
  ares_search.html			\
  ares_send.html			\
  ares_set_servers.html			\
  ares_set_socket_callback.html		\
  ares_strerror.html			\
  ares_timeout.html			\
@@ -144,6 +149,7 @@ PDFPAGES = ares_cancel.pdf \
  ares_free_data.pdf			\
  ares_free_hostent.pdf			\
  ares_free_string.pdf			\
  ares_get_servers.pdf			\
  ares_gethostbyaddr.pdf		\
  ares_gethostbyname.pdf		\
  ares_gethostbyname_file.pdf		\
@@ -165,6 +171,7 @@ PDFPAGES = ares_cancel.pdf \
  ares_save_options.pdf			\
  ares_search.pdf			\
  ares_send.pdf				\
  ares_set_servers.pdf			\
  ares_set_socket_callback.pdf		\
  ares_strerror.pdf			\
  ares_timeout.pdf			\
+3 −2
Original line number Diff line number Diff line
@@ -2,7 +2,7 @@ This is what's new and changed in the c-ares 1.7.1 release:

Changed:

 o 
 o added IPv6 name servers support

Fixed:

@@ -12,6 +12,7 @@ Fixed:

Thanks go to these friendly people for their efforts and contributions:

 Ingmar Runge, Laszlo Tamas Szabo, Yang Tse, Tommie Gannert
 Ingmar Runge, Laszlo Tamas Szabo, Yang Tse, Tommie Gannert, Gregor Jasny,
 Phil Blundell, Cedric Bail, Jakub Hrozek

Have fun!
+85 −16
Original line number Diff line number Diff line
@@ -164,8 +164,6 @@ static const char *rcodes[] = {
  "(unknown)", "(unknown)", "(unknown)", "(unknown)", "NOCHANGE"
};

static struct in_addr inaddr;

static void callback(void *arg, int status, int timeouts,
                     unsigned char *abuf, int alen);
static const unsigned char *display_question(const unsigned char *aptr,
@@ -176,6 +174,9 @@ static const unsigned char *display_rr(const unsigned char *aptr,
static const char *type_name(int type);
static const char *class_name(int dnsclass);
static void usage(void);
static void destroy_addr_list(struct ares_addr_node *head);
static void append_addr_list(struct ares_addr_node **head,
                             struct ares_addr_node *node);

int main(int argc, char **argv)
{
@@ -186,6 +187,7 @@ int main(int argc, char **argv)
  struct hostent *hostent;
  fd_set read_fds, write_fds;
  struct timeval *tvp, tv;
  struct ares_addr_node *srvr, *servers = NULL;

#ifdef USE_WINSOCK
  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
@@ -227,27 +229,56 @@ int main(int argc, char **argv)
          break;

        case 's':
          /* Add a server, and specify servers in the option mask. */
          if (ares_inet_pton(AF_INET, optarg, &inaddr) <= 0)
          /* User specified name servers override default ones. */
          srvr = malloc(sizeof(struct ares_addr_node));
          if (!srvr)
            {
              fprintf(stderr, "Out of memory!\n");
              destroy_addr_list(servers);
              return 1;
            }
          append_addr_list(&servers, srvr);
          if (ares_inet_pton(AF_INET, optarg, &srvr->addr.addr4) > 0)
            srvr->family = AF_INET;
          else if (ares_inet_pton(AF_INET6, optarg, &srvr->addr.addr6) > 0)
            srvr->family = AF_INET6;
          else
            {
              hostent = gethostbyname(optarg);
              if (!hostent || hostent->h_addrtype != AF_INET)
              if (!hostent)
                {
                  fprintf(stderr, "adig: server %s not found.\n", optarg);
                  destroy_addr_list(servers);
                  return 1;
                }
              memcpy(&inaddr, hostent->h_addr, sizeof(struct in_addr));
            }
          options.servers = realloc(options.servers, (options.nservers + 1)
                                    * sizeof(struct in_addr));
          if (!options.servers)
              switch (hostent->h_addrtype)
                {
              fprintf(stderr, "Out of memory!\n");
                  case AF_INET:
                    srvr->family = AF_INET;
                    memcpy(&srvr->addr.addr4, hostent->h_addr,
                           sizeof(srvr->addr.addr4));
                    break;
                  case AF_INET6:
                    srvr->family = AF_INET6;
                    memcpy(&srvr->addr.addr6, hostent->h_addr,
                           sizeof(srvr->addr.addr6));
                    break;
                  default:
                    fprintf(stderr,
                      "adig: server %s unsupported address family.\n", optarg);
                    destroy_addr_list(servers);
                    return 1;
                }
          memcpy(&options.servers[options.nservers], &inaddr,
                 sizeof(struct in_addr));
          options.nservers++;
            }
          /* Notice that calling ares_init_options() without servers in the
           * options struct and with ARES_OPT_SERVERS set simultaneously in
           * the options mask, results in an initialization with no servers.
           * When alternative name servers have been specified these are set
           * later calling ares_set_servers() overriding any existing server
           * configuration. To prevent initial configuration with default
           * servers that will be discarded later ARES_OPT_SERVERS is set.
           * If this flag is not set here the result shall be the same but
           * ares_init_options() will do needless work. */
          optmask |= ARES_OPT_SERVERS;
          break;

@@ -308,6 +339,18 @@ int main(int argc, char **argv)
      return 1;
    }

  if(servers)
    {
      status = ares_set_servers(channel, servers);
      destroy_addr_list(servers);
      if (status != ARES_SUCCESS)
        {
          fprintf(stderr, "ares_init_options: %s\n",
                  ares_strerror(status));
          return 1;
        }
    }

  /* Initiate the queries, one per command-line argument.  If there is
   * only one query to do, supply NULL as the callback argument;
   * otherwise, supply the query name as an argument so we can
@@ -749,3 +792,29 @@ static void usage(void)
          "[-t type] [-p port] name ...\n");
  exit(1);
}

static void destroy_addr_list(struct ares_addr_node *head)
{
  while(head)
    {
      struct ares_addr_node *detached = head;
      head = head->next;
      free(detached);
    }
}

static void append_addr_list(struct ares_addr_node **head,
                             struct ares_addr_node *node)
{
  struct ares_addr_node *last;
  node->next = NULL;
  if(*head)
    {
      last = *head;
      while(last->next)
        last = last->next;
      last->next = node;
    }
  else
    *head = node;
}
+1 −1
Original line number Diff line number Diff line
@@ -69,7 +69,7 @@ int main(int argc, char **argv)
  fd_set read_fds, write_fds;
  struct timeval *tvp, tv;
  struct in_addr addr4;
  struct in6_addr addr6;
  struct ares_in6_addr addr6;

#ifdef USE_WINSOCK
  WORD wVersionRequested = MAKEWORD(USE_WINSOCK,USE_WINSOCK);
Loading