Home | History | Annotate | Download | only in c-ares
      1 
      2 /* Copyright 1998 by the Massachusetts Institute of Technology.
      3  * Copyright (C) 2007-2011 by Daniel Stenberg
      4  *
      5  * Permission to use, copy, modify, and distribute this
      6  * software and its documentation for any purpose and without
      7  * fee is hereby granted, provided that the above copyright
      8  * notice appear in all copies and that both that copyright
      9  * notice and this permission notice appear in supporting
     10  * documentation, and that the name of M.I.T. not be used in
     11  * advertising or publicity pertaining to distribution of the
     12  * software without specific, written prior permission.
     13  * M.I.T. makes no representations about the suitability of
     14  * this software for any purpose.  It is provided "as is"
     15  * without express or implied warranty.
     16  */
     17 
     18 #include "ares_setup.h"
     19 
     20 #ifdef HAVE_SYS_PARAM_H
     21 #include <sys/param.h>
     22 #endif
     23 
     24 #ifdef HAVE_SYS_TIME_H
     25 #include <sys/time.h>
     26 #endif
     27 
     28 #ifdef HAVE_SYS_SOCKET_H
     29 #include <sys/socket.h>
     30 #endif
     31 
     32 #ifdef HAVE_NETINET_IN_H
     33 #include <netinet/in.h>
     34 #endif
     35 
     36 #ifdef HAVE_NETDB_H
     37 #include <netdb.h>
     38 #endif
     39 
     40 #ifdef HAVE_ARPA_INET_H
     41 #include <arpa/inet.h>
     42 #endif
     43 
     44 #ifdef HAVE_ARPA_NAMESER_H
     45 #  include <arpa/nameser.h>
     46 #else
     47 #  include "nameser.h"
     48 #endif
     49 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
     50 #  include <arpa/nameser_compat.h>
     51 #endif
     52 
     53 #ifdef HAVE_UNISTD_H
     54 #include <unistd.h>
     55 #endif
     56 
     57 #include <stdio.h>
     58 #include <stdlib.h>
     59 #include <string.h>
     60 #include <ctype.h>
     61 #include <time.h>
     62 
     63 #ifdef ANDROID
     64 #include <sys/system_properties.h>
     65 #endif
     66 
     67 #include "ares.h"
     68 #include "inet_net_pton.h"
     69 #include "ares_library_init.h"
     70 #include "ares_nowarn.h"
     71 #include "ares_platform.h"
     72 #include "inet_ntop.h"
     73 #include "ares_private.h"
     74 
     75 #ifdef WATT32
     76 #undef WIN32  /* Redefined in MingW/MSVC headers */
     77 #endif
     78 
     79 static int init_by_options(ares_channel channel, const struct ares_options *options,
     80                            int optmask);
     81 static int init_by_environment(ares_channel channel);
     82 static int init_by_resolv_conf(ares_channel channel);
     83 static int init_by_defaults(ares_channel channel);
     84 
     85 #ifndef WATT32
     86 static int config_nameserver(struct server_state **servers, int *nservers,
     87                              char *str);
     88 #endif
     89 static int set_search(ares_channel channel, const char *str);
     90 static int set_options(ares_channel channel, const char *str);
     91 static const char *try_option(const char *p, const char *q, const char *opt);
     92 static int init_id_key(rc4_key* key,int key_data_len);
     93 
     94 #if !defined(WIN32) && !defined(WATT32)
     95 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
     96 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
     97 static void natural_mask(struct apattern *pat);
     98 static int config_domain(ares_channel channel, char *str);
     99 static int config_lookup(ares_channel channel, const char *str,
    100                          const char *bindch, const char *filech);
    101 static int config_sortlist(struct apattern **sortlist, int *nsort,
    102                            const char *str);
    103 static char *try_config(char *s, const char *opt, char scc);
    104 #endif
    105 
    106 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
    107                              x->nservers > -1 && \
    108                              x->ndomains > -1 && \
    109                              x->ndots > -1 && x->timeout > -1 && \
    110                              x->tries > -1)
    111 
    112 int ares_init(ares_channel *channelptr)
    113 {
    114   return ares_init_options(channelptr, NULL, 0);
    115 }
    116 
    117 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
    118                       int optmask)
    119 {
    120   ares_channel channel;
    121   int i;
    122   int status = ARES_SUCCESS;
    123   struct timeval now;
    124 
    125 #ifdef CURLDEBUG
    126   const char *env = getenv("CARES_MEMDEBUG");
    127 
    128   if (env)
    129     curl_memdebug(env);
    130   env = getenv("CARES_MEMLIMIT");
    131   if (env) {
    132     char *endptr;
    133     long num = strtol(env, &endptr, 10);
    134     if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
    135       curl_memlimit(num);
    136   }
    137 #endif
    138 
    139   if (ares_library_initialized() != ARES_SUCCESS)
    140     return ARES_ENOTINITIALIZED;
    141 
    142   channel = malloc(sizeof(struct ares_channeldata));
    143   if (!channel) {
    144     *channelptr = NULL;
    145     return ARES_ENOMEM;
    146   }
    147 
    148   now = ares__tvnow();
    149 
    150   /* Set everything to distinguished values so we know they haven't
    151    * been set yet.
    152    */
    153   channel->flags = -1;
    154   channel->timeout = -1;
    155   channel->tries = -1;
    156   channel->ndots = -1;
    157   channel->rotate = -1;
    158   channel->udp_port = -1;
    159   channel->tcp_port = -1;
    160   channel->socket_send_buffer_size = -1;
    161   channel->socket_receive_buffer_size = -1;
    162   channel->nservers = -1;
    163   channel->ndomains = -1;
    164   channel->nsort = -1;
    165   channel->tcp_connection_generation = 0;
    166   channel->lookups = NULL;
    167   channel->domains = NULL;
    168   channel->sortlist = NULL;
    169   channel->servers = NULL;
    170   channel->sock_state_cb = NULL;
    171   channel->sock_state_cb_data = NULL;
    172   channel->sock_create_cb = NULL;
    173   channel->sock_create_cb_data = NULL;
    174 
    175   channel->last_server = 0;
    176   channel->last_timeout_processed = (time_t)now.tv_sec;
    177 
    178   memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
    179   channel->local_ip4 = 0;
    180   memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
    181 
    182   /* Initialize our lists of queries */
    183   ares__init_list_head(&(channel->all_queries));
    184   for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
    185     {
    186       ares__init_list_head(&(channel->queries_by_qid[i]));
    187     }
    188   for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
    189     {
    190       ares__init_list_head(&(channel->queries_by_timeout[i]));
    191     }
    192 
    193   /* Initialize configuration by each of the four sources, from highest
    194    * precedence to lowest.
    195    */
    196 
    197   if (status == ARES_SUCCESS) {
    198     status = init_by_options(channel, options, optmask);
    199     if (status != ARES_SUCCESS)
    200       DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
    201                      ares_strerror(status)));
    202   }
    203   if (status == ARES_SUCCESS) {
    204     status = init_by_environment(channel);
    205     if (status != ARES_SUCCESS)
    206       DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
    207                      ares_strerror(status)));
    208   }
    209   if (status == ARES_SUCCESS) {
    210     status = init_by_resolv_conf(channel);
    211     if (status != ARES_SUCCESS)
    212       DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
    213                      ares_strerror(status)));
    214   }
    215 
    216   /*
    217    * No matter what failed or succeeded, seed defaults to provide
    218    * useful behavior for things that we missed.
    219    */
    220   status = init_by_defaults(channel);
    221   if (status != ARES_SUCCESS)
    222     DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
    223                    ares_strerror(status)));
    224 
    225   /* Generate random key */
    226 
    227   if (status == ARES_SUCCESS) {
    228     status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
    229     if (status == ARES_SUCCESS)
    230       channel->next_id = ares__generate_new_id(&channel->id_key);
    231     else
    232       DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
    233                      ares_strerror(status)));
    234   }
    235 
    236   if (status != ARES_SUCCESS)
    237     {
    238       /* Something failed; clean up memory we may have allocated. */
    239       if (channel->servers)
    240         free(channel->servers);
    241       if (channel->domains)
    242         {
    243           for (i = 0; i < channel->ndomains; i++)
    244             free(channel->domains[i]);
    245           free(channel->domains);
    246         }
    247       if (channel->sortlist)
    248         free(channel->sortlist);
    249       if(channel->lookups)
    250         free(channel->lookups);
    251       free(channel);
    252       return status;
    253     }
    254 
    255   /* Trim to one server if ARES_FLAG_PRIMARY is set. */
    256   if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
    257     channel->nservers = 1;
    258 
    259   ares__init_servers_state(channel);
    260 
    261   *channelptr = channel;
    262   return ARES_SUCCESS;
    263 }
    264 
    265 /* ares_dup() duplicates a channel handle with all its options and returns a
    266    new channel handle */
    267 int ares_dup(ares_channel *dest, ares_channel src)
    268 {
    269   struct ares_options opts;
    270   struct ares_addr_node *servers;
    271   int ipv6_nservers = 0;
    272   int i, rc;
    273   int optmask;
    274 
    275   *dest = NULL; /* in case of failure return NULL explicitly */
    276 
    277   /* First get the options supported by the old ares_save_options() function,
    278      which is most of them */
    279   rc = ares_save_options(src, &opts, &optmask);
    280   if(rc)
    281     return rc;
    282 
    283   /* Then create the new channel with those options */
    284   rc = ares_init_options(dest, &opts, optmask);
    285 
    286   /* destroy the options copy to not leak any memory */
    287   ares_destroy_options(&opts);
    288 
    289   if(rc)
    290     return rc;
    291 
    292   /* Now clone the options that ares_save_options() doesn't support. */
    293   (*dest)->sock_create_cb      = src->sock_create_cb;
    294   (*dest)->sock_create_cb_data = src->sock_create_cb_data;
    295 
    296   strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name));
    297   (*dest)->local_ip4 = src->local_ip4;
    298   memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
    299 
    300   /* Full name server cloning required when not all are IPv4 */
    301   for (i = 0; i < src->nservers; i++)
    302     {
    303       if (src->servers[i].addr.family != AF_INET) {
    304         ipv6_nservers++;
    305         break;
    306       }
    307     }
    308   if (ipv6_nservers) {
    309     rc = ares_get_servers(src, &servers);
    310     if (rc != ARES_SUCCESS)
    311       return rc;
    312     rc = ares_set_servers(*dest, servers);
    313     ares_free_data(servers);
    314     if (rc != ARES_SUCCESS)
    315       return rc;
    316   }
    317 
    318   return ARES_SUCCESS; /* everything went fine */
    319 }
    320 
    321 /* Save options from initialized channel */
    322 int ares_save_options(ares_channel channel, struct ares_options *options,
    323                       int *optmask)
    324 {
    325   int i, j;
    326   int ipv4_nservers = 0;
    327 
    328   /* Zero everything out */
    329   memset(options, 0, sizeof(struct ares_options));
    330 
    331   if (!ARES_CONFIG_CHECK(channel))
    332     return ARES_ENODATA;
    333 
    334   /* Traditionally the optmask wasn't saved in the channel struct so it was
    335      recreated here. ROTATE is the first option that has no struct field of
    336      its own in the public config struct */
    337   (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
    338                 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
    339                 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
    340                 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
    341     (channel->optmask & ARES_OPT_ROTATE);
    342 
    343   /* Copy easy stuff */
    344   options->flags   = channel->flags;
    345 
    346   /* We return full millisecond resolution but that's only because we don't
    347      set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
    348   options->timeout = channel->timeout;
    349   options->tries   = channel->tries;
    350   options->ndots   = channel->ndots;
    351   options->udp_port = (unsigned short)channel->udp_port;
    352   options->tcp_port = (unsigned short)channel->tcp_port;
    353   options->sock_state_cb     = channel->sock_state_cb;
    354   options->sock_state_cb_data = channel->sock_state_cb_data;
    355 
    356   /* Copy IPv4 servers */
    357   if (channel->nservers) {
    358     for (i = 0; i < channel->nservers; i++)
    359     {
    360       if (channel->servers[i].addr.family == AF_INET)
    361         ipv4_nservers++;
    362     }
    363     if (ipv4_nservers) {
    364       options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
    365       if (!options->servers)
    366         return ARES_ENOMEM;
    367       for (i = j = 0; i < channel->nservers; i++)
    368       {
    369         if (channel->servers[i].addr.family == AF_INET)
    370           memcpy(&options->servers[j++],
    371                  &channel->servers[i].addr.addrV4,
    372                  sizeof(channel->servers[i].addr.addrV4));
    373       }
    374     }
    375   }
    376   options->nservers = ipv4_nservers;
    377 
    378   /* copy domains */
    379   if (channel->ndomains) {
    380     options->domains = malloc(channel->ndomains * sizeof(char *));
    381     if (!options->domains)
    382       return ARES_ENOMEM;
    383 
    384     for (i = 0; i < channel->ndomains; i++)
    385     {
    386       options->ndomains = i;
    387       options->domains[i] = strdup(channel->domains[i]);
    388       if (!options->domains[i])
    389         return ARES_ENOMEM;
    390     }
    391   }
    392   options->ndomains = channel->ndomains;
    393 
    394   /* copy lookups */
    395   if (channel->lookups) {
    396     options->lookups = strdup(channel->lookups);
    397     if (!options->lookups && channel->lookups)
    398       return ARES_ENOMEM;
    399   }
    400 
    401   /* copy sortlist */
    402   if (channel->nsort) {
    403     options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
    404     if (!options->sortlist)
    405       return ARES_ENOMEM;
    406     for (i = 0; i < channel->nsort; i++)
    407       options->sortlist[i] = channel->sortlist[i];
    408   }
    409   options->nsort = channel->nsort;
    410 
    411   return ARES_SUCCESS;
    412 }
    413 
    414 static int init_by_options(ares_channel channel,
    415                            const struct ares_options *options,
    416                            int optmask)
    417 {
    418   int i;
    419 
    420   /* Easy stuff. */
    421   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
    422     channel->flags = options->flags;
    423   if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
    424     channel->timeout = options->timeout;
    425   else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
    426     channel->timeout = options->timeout * 1000;
    427   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
    428     channel->tries = options->tries;
    429   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
    430     channel->ndots = options->ndots;
    431   if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
    432     channel->rotate = 1;
    433   if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
    434     channel->udp_port = options->udp_port;
    435   if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
    436     channel->tcp_port = options->tcp_port;
    437   if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
    438     {
    439       channel->sock_state_cb = options->sock_state_cb;
    440       channel->sock_state_cb_data = options->sock_state_cb_data;
    441     }
    442   if ((optmask & ARES_OPT_SOCK_SNDBUF)
    443       && channel->socket_send_buffer_size == -1)
    444     channel->socket_send_buffer_size = options->socket_send_buffer_size;
    445   if ((optmask & ARES_OPT_SOCK_RCVBUF)
    446       && channel->socket_receive_buffer_size == -1)
    447     channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
    448 
    449   /* Copy the IPv4 servers, if given. */
    450   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
    451     {
    452       /* Avoid zero size allocations at any cost */
    453       if (options->nservers > 0)
    454         {
    455           channel->servers =
    456             malloc(options->nservers * sizeof(struct server_state));
    457           if (!channel->servers)
    458             return ARES_ENOMEM;
    459           for (i = 0; i < options->nservers; i++)
    460             {
    461               channel->servers[i].addr.family = AF_INET;
    462               memcpy(&channel->servers[i].addr.addrV4,
    463                      &options->servers[i],
    464                      sizeof(channel->servers[i].addr.addrV4));
    465             }
    466         }
    467       channel->nservers = options->nservers;
    468     }
    469 
    470   /* Copy the domains, if given.  Keep channel->ndomains consistent so
    471    * we can clean up in case of error.
    472    */
    473   if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
    474     {
    475       /* Avoid zero size allocations at any cost */
    476       if (options->ndomains > 0)
    477       {
    478         channel->domains = malloc(options->ndomains * sizeof(char *));
    479         if (!channel->domains)
    480           return ARES_ENOMEM;
    481         for (i = 0; i < options->ndomains; i++)
    482           {
    483             channel->ndomains = i;
    484             channel->domains[i] = strdup(options->domains[i]);
    485             if (!channel->domains[i])
    486               return ARES_ENOMEM;
    487           }
    488       }
    489       channel->ndomains = options->ndomains;
    490     }
    491 
    492   /* Set lookups, if given. */
    493   if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
    494     {
    495       channel->lookups = strdup(options->lookups);
    496       if (!channel->lookups)
    497         return ARES_ENOMEM;
    498     }
    499 
    500   /* copy sortlist */
    501   if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
    502       (options->nsort>0)) {
    503     channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
    504     if (!channel->sortlist)
    505       return ARES_ENOMEM;
    506     for (i = 0; i < options->nsort; i++)
    507       channel->sortlist[i] = options->sortlist[i];
    508     channel->nsort = options->nsort;
    509   }
    510 
    511   channel->optmask = optmask;
    512 
    513   return ARES_SUCCESS;
    514 }
    515 
    516 static int init_by_environment(ares_channel channel)
    517 {
    518   const char *localdomain, *res_options;
    519   int status;
    520 
    521   localdomain = getenv("LOCALDOMAIN");
    522   if (localdomain && channel->ndomains == -1)
    523     {
    524       status = set_search(channel, localdomain);
    525       if (status != ARES_SUCCESS)
    526         return status;
    527     }
    528 
    529   res_options = getenv("RES_OPTIONS");
    530   if (res_options)
    531     {
    532       status = set_options(channel, res_options);
    533       if (status != ARES_SUCCESS)
    534         return status;
    535     }
    536 
    537   return ARES_SUCCESS;
    538 }
    539 
    540 #ifdef WIN32
    541 /*
    542  * Warning: returns a dynamically allocated buffer, the user MUST
    543  * use free() if the function returns 1
    544  */
    545 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
    546 {
    547   /* Test for the size we need */
    548   DWORD size = 0;
    549   int result;
    550 
    551   result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
    552   if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
    553     return 0;
    554   *obuf = malloc(size+1);
    555   if (!*obuf)
    556     return 0;
    557 
    558   if (RegQueryValueEx(hKey, subkey, 0, NULL,
    559                       (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
    560   {
    561     free(*obuf);
    562     return 0;
    563   }
    564   if (size == 1)
    565   {
    566     free(*obuf);
    567     return 0;
    568   }
    569   return 1;
    570 }
    571 
    572 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
    573 {
    574   char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
    575   DWORD enum_size = 39;
    576   int idx = 0;
    577   HKEY hVal;
    578 
    579   while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
    580                       NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
    581   {
    582     int rc;
    583 
    584     enum_size = 39;
    585     if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
    586         ERROR_SUCCESS)
    587       continue;
    588     rc = get_res_nt(hVal, subkey, obuf);
    589       RegCloseKey(hVal);
    590     if (rc)
    591       return 1;
    592     }
    593   return 0;
    594 }
    595 
    596 /**
    597  * The desired output for this method is that we set "ret_buf" to
    598  * something like:
    599  *
    600  * 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
    601  *
    602  * The only ordering requirement is that primary servers are listed
    603  * before secondary. There is no requirement that IPv4 addresses should
    604  * necessarily be before IPv6.
    605  *
    606  * Note that ret_size should ideally be big enough to hold around
    607  * 2-3 IPv4 and 2-3 IPv6 addresses.
    608  *
    609  * Finally, we need to return the total number of DNS servers located.
    610  */
    611 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
    612 {
    613   const size_t  ipv4_size = INET_ADDRSTRLEN  + 1;  /* +1 for ',' at end */
    614   const size_t  ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," at end */
    615   size_t        left = ret_size;
    616   char         *ret  = ret_buf;
    617   int           count = 0;
    618 
    619   /* Use the GetAdaptersAddresses method if it's available, otherwise
    620      fall back to GetNetworkParams. */
    621   if (ares_fpGetAdaptersAddresses != ZERO_NULL)
    622   {
    623     const ULONG            working_buf_size = 15000;
    624     IP_ADAPTER_ADDRESSES   *pFirstEntry = NULL;
    625     IP_ADAPTER_ADDRESSES   *pEntry = NULL;
    626     ULONG                  bufSize = 0;
    627     ULONG                  result = 0;
    628 
    629     /* According to MSDN, the recommended way to do this is to use a temporary
    630        buffer of 15K, to "dramatically reduce the chance that the GetAdaptersAddresses
    631        method returns ERROR_BUFFER_OVERFLOW" */
    632     pFirstEntry  = ( IP_ADAPTER_ADDRESSES * ) malloc( working_buf_size );
    633     bufSize = working_buf_size;
    634     if( !pFirstEntry )
    635       return 0;
    636 
    637     /* Call the method one time */
    638     result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
    639     if( result == ERROR_BUFFER_OVERFLOW )
    640     {
    641       /* Reallocate, bufSize should now be set to the required size */
    642       pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
    643       if( !pFirstEntry )
    644         return 0;
    645 
    646       /* Call the method a second time */
    647       result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
    648       if( result == ERROR_BUFFER_OVERFLOW )
    649       {
    650         /* Reallocate, bufSize should now be set to the required size */
    651         pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
    652         if( !pFirstEntry )
    653           return 0;
    654 
    655         /* Call the method a third time. The maximum number of times we're going to do
    656            this is 3. Three shall be the number thou shalt count, and the number of the
    657            counting shall be three.  Five is right out. */
    658         result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
    659       }
    660     }
    661 
    662     /* Check the current result for failure */
    663     if( result != ERROR_SUCCESS )
    664     {
    665       free( pFirstEntry );
    666       return 0;
    667     }
    668 
    669     /* process the results */
    670     for( pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next )
    671     {
    672       IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
    673       for( ; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next )
    674       {
    675         struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
    676         size_t stringlen = 0;
    677 
    678         if( pGenericAddr->sa_family == AF_INET && left > ipv4_size )
    679         {
    680           /* Handle the v4 case */
    681           struct sockaddr_in *pIPv4Addr = ( struct sockaddr_in * ) pGenericAddr;
    682           ares_inet_ntop( AF_INET, &pIPv4Addr->sin_addr, ret, ipv4_size - 1 ); /* -1 for comma */
    683 
    684           /* Append a comma to the end, THEN NULL. Should be OK because we
    685              already tested the size at the top of the if statement. */
    686           stringlen = strlen( ret );
    687           ret[ stringlen ] = ',';
    688           ret[ stringlen + 1 ] = '\0';
    689           ret += stringlen + 1;
    690           left -= ret - ret_buf;
    691           ++count;
    692         }
    693         else if( pGenericAddr->sa_family == AF_INET6 && left > ipv6_size )
    694         {
    695           /* Handle the v6 case */
    696           struct sockaddr_in6 *pIPv6Addr = ( struct sockaddr_in6 * ) pGenericAddr;
    697           ares_inet_ntop( AF_INET6, &pIPv6Addr->sin6_addr, ret, ipv6_size - 1 ); /* -1 for comma */
    698 
    699           /* Append a comma to the end, THEN NULL. Should be OK because we
    700              already tested the size at the top of the if statement. */
    701           stringlen = strlen( ret );
    702           ret[ stringlen ] = ',';
    703           ret[ stringlen + 1 ] = '\0';
    704           ret += stringlen + 1;
    705           left -= ret - ret_buf;
    706           ++count;
    707 
    708           /* NB on Windows this also returns stuff in the fec0::/10 range,
    709              seems to be hard-coded somehow. Do we need to ignore them? */
    710         }
    711       }
    712     }
    713 
    714     if( pFirstEntry )
    715       free( pFirstEntry );
    716     if (ret > ret_buf)
    717       ret[-1] = '\0';
    718     return count;
    719   }
    720   else
    721   {
    722     FIXED_INFO    *fi, *newfi;
    723     DWORD          size = sizeof (*fi);
    724     IP_ADDR_STRING *ipAddr;
    725     int            i;
    726     int            debug  = 0;
    727     HRESULT        res;
    728 
    729     fi = malloc(size);
    730     if (!fi)
    731       return 0;
    732 
    733     res = (*ares_fpGetNetworkParams) (fi, &size);
    734     if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
    735       goto quit;
    736 
    737     newfi = realloc(fi, size);
    738     if (!newfi)
    739       goto quit;
    740 
    741     fi = newfi;
    742     res = (*ares_fpGetNetworkParams) (fi, &size);
    743     if (res != ERROR_SUCCESS)
    744       goto quit;
    745 
    746     if (debug)
    747     {
    748       printf ("Host Name: %s\n", fi->HostName);
    749       printf ("Domain Name: %s\n", fi->DomainName);
    750       printf ("DNS Servers:\n"
    751               "    %s (primary)\n", fi->DnsServerList.IpAddress.String);
    752     }
    753     if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
    754         inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
    755         left > ipv4_size)
    756     {
    757       ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
    758       left -= ret - ret_buf;
    759       ++count;
    760     }
    761 
    762     for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
    763          ipAddr = ipAddr->Next, i++)
    764     {
    765       if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
    766       {
    767          ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
    768          left -= ret - ret_buf;
    769          ++count;
    770       }
    771       if (debug)
    772          printf ("    %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
    773     }
    774 
    775 quit:
    776     if (fi)
    777       free(fi);
    778 
    779     if (debug && left <= ipv4_size)
    780       printf ("Too many nameservers. Truncating to %d addressess", count);
    781     if (ret > ret_buf)
    782       ret[-1] = '\0';
    783     return count;
    784   }
    785 }
    786 #endif
    787 
    788 static int init_by_resolv_conf(ares_channel channel)
    789 {
    790 #ifndef WATT32
    791   char *line = NULL;
    792 #endif
    793   int status = -1, nservers = 0, nsort = 0;
    794   struct server_state *servers = NULL;
    795   struct apattern *sortlist = NULL;
    796 
    797 #ifdef WIN32
    798 
    799     /*
    800   NameServer info via IPHLPAPI (IP helper API):
    801     GetNetworkParams() should be the trusted source for this.
    802     Available in Win-98/2000 and later. If that fail, fall-back to
    803     registry information.
    804 
    805   NameServer Registry:
    806 
    807    On Windows 9X, the DNS server can be found in:
    808 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
    809 
    810         On Windows NT/2000/XP/2003:
    811 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
    812         or
    813 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
    814         or
    815 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
    816 NameServer
    817         or
    818 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
    819 DhcpNameServer
    820    */
    821 
    822   HKEY mykey;
    823   HKEY subkey;
    824   DWORD data_type;
    825   DWORD bytes;
    826   DWORD result;
    827   char  buf[512];
    828   win_platform platform;
    829 
    830   if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
    831      return ARES_SUCCESS;
    832 
    833   if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
    834   {
    835     status = config_nameserver(&servers, &nservers, buf);
    836     if (status == ARES_SUCCESS)
    837       goto okay;
    838   }
    839 
    840   platform = ares__getplatform();
    841 
    842   if (platform == WIN_NT)
    843   {
    844     if (RegOpenKeyEx(
    845           HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
    846           KEY_READ, &mykey
    847           ) == ERROR_SUCCESS)
    848     {
    849       RegOpenKeyEx(mykey, "Interfaces", 0,
    850                    KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
    851       if (get_res_nt(mykey, NAMESERVER, &line))
    852       {
    853         status = config_nameserver(&servers, &nservers, line);
    854         free(line);
    855       }
    856       else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
    857       {
    858         status = config_nameserver(&servers, &nservers, line);
    859         free(line);
    860       }
    861       /* Try the interfaces */
    862       else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
    863       {
    864         status = config_nameserver(&servers, &nservers, line);
    865         free(line);
    866       }
    867       else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
    868       {
    869         status = config_nameserver(&servers, &nservers, line);
    870         free(line);
    871       }
    872       RegCloseKey(subkey);
    873       RegCloseKey(mykey);
    874     }
    875   }
    876   else if (platform == WIN_9X)
    877   {
    878     if (RegOpenKeyEx(
    879           HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
    880           KEY_READ, &mykey
    881           ) == ERROR_SUCCESS)
    882     {
    883       if ((result = RegQueryValueEx(
    884              mykey, NAMESERVER, NULL, &data_type,
    885              NULL, &bytes
    886              )
    887             ) == ERROR_SUCCESS ||
    888           result == ERROR_MORE_DATA)
    889       {
    890         if (bytes)
    891         {
    892           line = malloc(bytes+1);
    893           if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
    894                               (unsigned char *)line, &bytes) ==
    895               ERROR_SUCCESS)
    896           {
    897             status = config_nameserver(&servers, &nservers, line);
    898           }
    899           free(line);
    900         }
    901       }
    902     }
    903     RegCloseKey(mykey);
    904   }
    905 
    906   if (status == ARES_SUCCESS)
    907     status = ARES_EOF;
    908   else
    909     /* Catch the case when all the above checks fail (which happens when there
    910        is no network card or the cable is unplugged) */
    911     status = ARES_EFILE;
    912 
    913 #elif defined(__riscos__)
    914 
    915   /* Under RISC OS, name servers are listed in the
    916      system variable Inet$Resolvers, space separated. */
    917 
    918   line = getenv("Inet$Resolvers");
    919   status = ARES_EOF;
    920   if (line) {
    921     char *resolvers = strdup(line), *pos, *space;
    922 
    923     if (!resolvers)
    924       return ARES_ENOMEM;
    925 
    926     pos = resolvers;
    927     do {
    928       space = strchr(pos, ' ');
    929       if (space)
    930         *space = '\0';
    931       status = config_nameserver(&servers, &nservers, pos);
    932       if (status != ARES_SUCCESS)
    933         break;
    934       pos = space + 1;
    935     } while (space);
    936 
    937     if (status == ARES_SUCCESS)
    938       status = ARES_EOF;
    939 
    940     free(resolvers);
    941   }
    942 
    943 #elif defined(WATT32)
    944   int i;
    945 
    946   sock_init();
    947   for (i = 0; def_nameservers[i]; i++)
    948       ;
    949   if (i == 0)
    950     return ARES_SUCCESS; /* use localhost DNS server */
    951 
    952   nservers = i;
    953   servers = calloc(i, sizeof(struct server_state));
    954   if (!servers)
    955      return ARES_ENOMEM;
    956 
    957   for (i = 0; def_nameservers[i]; i++)
    958   {
    959     servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
    960     servers[i].addr.family = AF_INET;
    961   }
    962   status = ARES_EOF;
    963 
    964 #elif defined(ANDROID)
    965   char value[PROP_VALUE_MAX]="";
    966   __system_property_get("net.dns1", value);
    967   status = config_nameserver(&servers, &nservers, value);
    968   if (status == ARES_SUCCESS)
    969     status = ARES_EOF;
    970 #else
    971   {
    972     char *p;
    973     FILE *fp;
    974     size_t linesize;
    975     int error;
    976 
    977     /* Don't read resolv.conf and friends if we don't have to */
    978     if (ARES_CONFIG_CHECK(channel))
    979         return ARES_SUCCESS;
    980 
    981     fp = fopen(PATH_RESOLV_CONF, "r");
    982     if (fp) {
    983       while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
    984       {
    985         if ((p = try_config(line, "domain", ';')))
    986           status = config_domain(channel, p);
    987         else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
    988           status = config_lookup(channel, p, "bind", "file");
    989         else if ((p = try_config(line, "search", ';')))
    990           status = set_search(channel, p);
    991         else if ((p = try_config(line, "nameserver", ';')) &&
    992                  channel->nservers == -1)
    993           status = config_nameserver(&servers, &nservers, p);
    994         else if ((p = try_config(line, "sortlist", ';')) &&
    995                  channel->nsort == -1)
    996           status = config_sortlist(&sortlist, &nsort, p);
    997         else if ((p = try_config(line, "options", ';')))
    998           status = set_options(channel, p);
    999         else
   1000           status = ARES_SUCCESS;
   1001         if (status != ARES_SUCCESS)
   1002           break;
   1003       }
   1004       fclose(fp);
   1005     }
   1006     else {
   1007       error = ERRNO;
   1008       switch(error) {
   1009       case ENOENT:
   1010       case ESRCH:
   1011         status = ARES_EOF;
   1012         break;
   1013       default:
   1014         DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
   1015                        error, strerror(error)));
   1016         DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
   1017         status = ARES_EFILE;
   1018       }
   1019     }
   1020 
   1021     if ((status == ARES_EOF) && (!channel->lookups)) {
   1022       /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
   1023       fp = fopen("/etc/nsswitch.conf", "r");
   1024       if (fp) {
   1025         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
   1026         {
   1027           if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
   1028             /* ignore errors */
   1029             (void)config_lookup(channel, p, "dns", "files");
   1030         }
   1031         fclose(fp);
   1032       }
   1033       else {
   1034         error = ERRNO;
   1035         switch(error) {
   1036         case ENOENT:
   1037         case ESRCH:
   1038           status = ARES_EOF;
   1039           break;
   1040         default:
   1041           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
   1042                          error, strerror(error)));
   1043           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
   1044           status = ARES_EFILE;
   1045         }
   1046       }
   1047     }
   1048 
   1049     if ((status == ARES_EOF) && (!channel->lookups)) {
   1050       /* Linux / GNU libc 2.x and possibly others have host.conf */
   1051       fp = fopen("/etc/host.conf", "r");
   1052       if (fp) {
   1053         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
   1054         {
   1055           if ((p = try_config(line, "order", '\0')) && !channel->lookups)
   1056             /* ignore errors */
   1057             (void)config_lookup(channel, p, "bind", "hosts");
   1058         }
   1059         fclose(fp);
   1060       }
   1061       else {
   1062         error = ERRNO;
   1063         switch(error) {
   1064         case ENOENT:
   1065         case ESRCH:
   1066           status = ARES_EOF;
   1067           break;
   1068         default:
   1069           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
   1070                          error, strerror(error)));
   1071           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
   1072           status = ARES_EFILE;
   1073         }
   1074       }
   1075     }
   1076 
   1077     if ((status == ARES_EOF) && (!channel->lookups)) {
   1078       /* Tru64 uses /etc/svc.conf */
   1079       fp = fopen("/etc/svc.conf", "r");
   1080       if (fp) {
   1081         while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
   1082         {
   1083           if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
   1084             /* ignore errors */
   1085             (void)config_lookup(channel, p, "bind", "local");
   1086         }
   1087         fclose(fp);
   1088       }
   1089       else {
   1090         error = ERRNO;
   1091         switch(error) {
   1092         case ENOENT:
   1093         case ESRCH:
   1094           status = ARES_EOF;
   1095           break;
   1096         default:
   1097           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
   1098                          error, strerror(error)));
   1099           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
   1100           status = ARES_EFILE;
   1101         }
   1102       }
   1103     }
   1104 
   1105     if(line)
   1106       free(line);
   1107   }
   1108 
   1109 #endif
   1110 
   1111   /* Handle errors. */
   1112   if (status != ARES_EOF)
   1113     {
   1114       if (servers != NULL)
   1115         free(servers);
   1116       if (sortlist != NULL)
   1117         free(sortlist);
   1118       return status;
   1119     }
   1120 
   1121   /* If we got any name server entries, fill them in. */
   1122 #ifdef WIN32
   1123 okay:
   1124 #endif
   1125   if (servers)
   1126     {
   1127       channel->servers = servers;
   1128       channel->nservers = nservers;
   1129     }
   1130 
   1131   /* If we got any sortlist entries, fill them in. */
   1132   if (sortlist)
   1133     {
   1134       channel->sortlist = sortlist;
   1135       channel->nsort = nsort;
   1136     }
   1137 
   1138   return ARES_SUCCESS;
   1139 }
   1140 
   1141 static int init_by_defaults(ares_channel channel)
   1142 {
   1143   char *hostname = NULL;
   1144   int rc = ARES_SUCCESS;
   1145 #ifdef HAVE_GETHOSTNAME
   1146   char *dot;
   1147 #endif
   1148 
   1149   if (channel->flags == -1)
   1150     channel->flags = 0;
   1151   if (channel->timeout == -1)
   1152     channel->timeout = DEFAULT_TIMEOUT;
   1153   if (channel->tries == -1)
   1154     channel->tries = DEFAULT_TRIES;
   1155   if (channel->ndots == -1)
   1156     channel->ndots = 1;
   1157   if (channel->rotate == -1)
   1158     channel->rotate = 0;
   1159   if (channel->udp_port == -1)
   1160     channel->udp_port = htons(NAMESERVER_PORT);
   1161   if (channel->tcp_port == -1)
   1162     channel->tcp_port = htons(NAMESERVER_PORT);
   1163 
   1164   if (channel->nservers == -1) {
   1165     /* If nobody specified servers, try a local named. */
   1166     channel->servers = malloc(sizeof(struct server_state));
   1167     if (!channel->servers) {
   1168       rc = ARES_ENOMEM;
   1169       goto error;
   1170     }
   1171     channel->servers[0].addr.family = AF_INET;
   1172     channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
   1173     channel->nservers = 1;
   1174   }
   1175 
   1176 #if defined(USE_WINSOCK)
   1177 #define toolong(x) (x == -1) &&  (SOCKERRNO == WSAEFAULT)
   1178 #elif defined(ENAMETOOLONG)
   1179 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
   1180                                  (SOCKERRNO == EINVAL))
   1181 #else
   1182 #define toolong(x) (x == -1) &&  (SOCKERRNO == EINVAL)
   1183 #endif
   1184 
   1185   if (channel->ndomains == -1) {
   1186     /* Derive a default domain search list from the kernel hostname,
   1187      * or set it to empty if the hostname isn't helpful.
   1188      */
   1189     size_t len = 64;
   1190     int res;
   1191     channel->ndomains = 0; /* default to none */
   1192 
   1193 #ifdef HAVE_GETHOSTNAME
   1194     hostname = malloc(len);
   1195     if(!hostname) {
   1196       rc = ARES_ENOMEM;
   1197       goto error;
   1198     }
   1199 
   1200     do {
   1201       res = gethostname(hostname, len);
   1202 
   1203       if(toolong(res)) {
   1204         char *p;
   1205         len *= 2;
   1206         p = realloc(hostname, len);
   1207         if(!p) {
   1208           rc = ARES_ENOMEM;
   1209           goto error;
   1210         }
   1211         hostname = p;
   1212         continue;
   1213       }
   1214       else if(res) {
   1215         rc = ARES_EBADNAME;
   1216         goto error;
   1217       }
   1218 
   1219     } while(0);
   1220 
   1221     dot = strchr(hostname, '.');
   1222     if (dot) {
   1223       /* a dot was found */
   1224       channel->domains = malloc(sizeof(char *));
   1225       if (!channel->domains) {
   1226         rc = ARES_ENOMEM;
   1227         goto error;
   1228       }
   1229       channel->domains[0] = strdup(dot + 1);
   1230       if (!channel->domains[0]) {
   1231         rc = ARES_ENOMEM;
   1232         goto error;
   1233       }
   1234       channel->ndomains = 1;
   1235     }
   1236 #endif
   1237   }
   1238 
   1239   if (channel->nsort == -1) {
   1240     channel->sortlist = NULL;
   1241     channel->nsort = 0;
   1242   }
   1243 
   1244   if (!channel->lookups) {
   1245     channel->lookups = strdup("fb");
   1246     if (!channel->lookups)
   1247       rc = ARES_ENOMEM;
   1248   }
   1249 
   1250   error:
   1251   if(rc) {
   1252     if(channel->servers)
   1253       free(channel->servers);
   1254 
   1255     if(channel->domains && channel->domains[0])
   1256       free(channel->domains[0]);
   1257     if(channel->domains)
   1258       free(channel->domains);
   1259     if(channel->lookups)
   1260       free(channel->lookups);
   1261   }
   1262 
   1263   if(hostname)
   1264     free(hostname);
   1265 
   1266   return rc;
   1267 }
   1268 
   1269 #if !defined(WIN32) && !defined(WATT32)
   1270 static int config_domain(ares_channel channel, char *str)
   1271 {
   1272   char *q;
   1273 
   1274   /* Set a single search domain. */
   1275   q = str;
   1276   while (*q && !ISSPACE(*q))
   1277     q++;
   1278   *q = '\0';
   1279   return set_search(channel, str);
   1280 }
   1281 
   1282 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
   1283     defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
   1284   /* workaround icc 9.1 optimizer issue */
   1285 # define vqualifier volatile
   1286 #else
   1287 # define vqualifier
   1288 #endif
   1289 
   1290 static int config_lookup(ares_channel channel, const char *str,
   1291                          const char *bindch, const char *filech)
   1292 {
   1293   char lookups[3], *l;
   1294   const char *vqualifier p;
   1295 
   1296   /* Set the lookup order.  Only the first letter of each work
   1297    * is relevant, and it has to be "b" for DNS or "f" for the
   1298    * host file.  Ignore everything else.
   1299    */
   1300   l = lookups;
   1301   p = str;
   1302   while (*p)
   1303     {
   1304       if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
   1305         if (*p == *bindch) *l++ = 'b';
   1306         else *l++ = 'f';
   1307       }
   1308       while (*p && !ISSPACE(*p) && (*p != ','))
   1309         p++;
   1310       while (*p && (ISSPACE(*p) || (*p == ',')))
   1311         p++;
   1312     }
   1313   *l = '\0';
   1314   channel->lookups = strdup(lookups);
   1315   return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
   1316 }
   1317 #endif  /* !WIN32 & !WATT32 */
   1318 
   1319 #ifndef WATT32
   1320 static int config_nameserver(struct server_state **servers, int *nservers,
   1321                              char *str)
   1322 {
   1323   struct ares_addr host;
   1324   struct server_state *newserv;
   1325   char *p, *txtaddr;
   1326   /* On Windows, there may be more than one nameserver specified in the same
   1327    * registry key, so we parse input as a space or comma seperated list.
   1328    */
   1329   for (p = str; p;)
   1330     {
   1331       /* Skip whitespace and commas. */
   1332       while (*p && (ISSPACE(*p) || (*p == ',')))
   1333         p++;
   1334       if (!*p)
   1335         /* No more input, done. */
   1336         break;
   1337 
   1338       /* Pointer to start of IPv4 or IPv6 address part. */
   1339       txtaddr = p;
   1340 
   1341       /* Advance past this address. */
   1342       while (*p && !ISSPACE(*p) && (*p != ','))
   1343         p++;
   1344       if (*p)
   1345         /* Null terminate this address. */
   1346         *p++ = '\0';
   1347       else
   1348         /* Reached end of input, done when this address is processed. */
   1349         p = NULL;
   1350 
   1351       /* Convert textual address to binary format. */
   1352       if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
   1353         host.family = AF_INET;
   1354       else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
   1355         host.family = AF_INET6;
   1356       else
   1357         continue;
   1358 
   1359       /* Resize servers state array. */
   1360       newserv = realloc(*servers, (*nservers + 1) *
   1361                         sizeof(struct server_state));
   1362       if (!newserv)
   1363         return ARES_ENOMEM;
   1364 
   1365       /* Store address data. */
   1366       newserv[*nservers].addr.family = host.family;
   1367       if (host.family == AF_INET)
   1368         memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
   1369                sizeof(host.addrV4));
   1370       else
   1371         memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
   1372                sizeof(host.addrV6));
   1373 
   1374       /* Update arguments. */
   1375       *servers = newserv;
   1376       *nservers += 1;
   1377     }
   1378 
   1379   return ARES_SUCCESS;
   1380 }
   1381 
   1382 #ifndef WIN32
   1383 static int config_sortlist(struct apattern **sortlist, int *nsort,
   1384                            const char *str)
   1385 {
   1386   struct apattern pat;
   1387   const char *q;
   1388 
   1389   /* Add sortlist entries. */
   1390   while (*str && *str != ';')
   1391     {
   1392       int bits;
   1393       char ipbuf[16], ipbufpfx[32];
   1394       /* Find just the IP */
   1395       q = str;
   1396       while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
   1397         q++;
   1398       memcpy(ipbuf, str, q-str);
   1399       ipbuf[q-str] = '\0';
   1400       /* Find the prefix */
   1401       if (*q == '/')
   1402         {
   1403           const char *str2 = q+1;
   1404           while (*q && *q != ';' && !ISSPACE(*q))
   1405             q++;
   1406           memcpy(ipbufpfx, str, q-str);
   1407           ipbufpfx[q-str] = '\0';
   1408           str = str2;
   1409         }
   1410       else
   1411         ipbufpfx[0] = '\0';
   1412       /* Lets see if it is CIDR */
   1413       /* First we'll try IPv6 */
   1414       if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
   1415                                      &pat.addrV6,
   1416                                      sizeof(pat.addrV6))) > 0)
   1417         {
   1418           pat.type = PATTERN_CIDR;
   1419           pat.mask.bits = (unsigned short)bits;
   1420           pat.family = AF_INET6;
   1421           if (!sortlist_alloc(sortlist, nsort, &pat))
   1422             return ARES_ENOMEM;
   1423         }
   1424       else if (ipbufpfx[0] &&
   1425                (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
   1426                                           sizeof(pat.addrV4))) > 0)
   1427         {
   1428           pat.type = PATTERN_CIDR;
   1429           pat.mask.bits = (unsigned short)bits;
   1430           pat.family = AF_INET;
   1431           if (!sortlist_alloc(sortlist, nsort, &pat))
   1432             return ARES_ENOMEM;
   1433         }
   1434       /* See if it is just a regular IP */
   1435       else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
   1436         {
   1437           if (ipbufpfx[0])
   1438             {
   1439               memcpy(ipbuf, str, q-str);
   1440               ipbuf[q-str] = '\0';
   1441               if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
   1442                 natural_mask(&pat);
   1443             }
   1444           else
   1445             natural_mask(&pat);
   1446           pat.family = AF_INET;
   1447           pat.type = PATTERN_MASK;
   1448           if (!sortlist_alloc(sortlist, nsort, &pat))
   1449             return ARES_ENOMEM;
   1450         }
   1451       else
   1452         {
   1453           while (*q && *q != ';' && !ISSPACE(*q))
   1454             q++;
   1455         }
   1456       str = q;
   1457       while (ISSPACE(*str))
   1458         str++;
   1459     }
   1460 
   1461   return ARES_SUCCESS;
   1462 }
   1463 #endif  /* !WIN32 */
   1464 #endif  /* !WATT32 */
   1465 
   1466 static int set_search(ares_channel channel, const char *str)
   1467 {
   1468   int n;
   1469   const char *p, *q;
   1470 
   1471   if(channel->ndomains != -1) {
   1472     /* if we already have some domains present, free them first */
   1473     for(n=0; n < channel->ndomains; n++)
   1474       free(channel->domains[n]);
   1475     free(channel->domains);
   1476     channel->domains = NULL;
   1477     channel->ndomains = -1;
   1478   }
   1479 
   1480   /* Count the domains given. */
   1481   n = 0;
   1482   p = str;
   1483   while (*p)
   1484     {
   1485       while (*p && !ISSPACE(*p))
   1486         p++;
   1487       while (ISSPACE(*p))
   1488         p++;
   1489       n++;
   1490     }
   1491 
   1492   if (!n)
   1493     {
   1494       channel->ndomains = 0;
   1495       return ARES_SUCCESS;
   1496     }
   1497 
   1498   channel->domains = malloc(n * sizeof(char *));
   1499   if (!channel->domains)
   1500     return ARES_ENOMEM;
   1501 
   1502   /* Now copy the domains. */
   1503   n = 0;
   1504   p = str;
   1505   while (*p)
   1506     {
   1507       channel->ndomains = n;
   1508       q = p;
   1509       while (*q && !ISSPACE(*q))
   1510         q++;
   1511       channel->domains[n] = malloc(q - p + 1);
   1512       if (!channel->domains[n])
   1513         return ARES_ENOMEM;
   1514       memcpy(channel->domains[n], p, q - p);
   1515       channel->domains[n][q - p] = 0;
   1516       p = q;
   1517       while (ISSPACE(*p))
   1518         p++;
   1519       n++;
   1520     }
   1521   channel->ndomains = n;
   1522 
   1523   return ARES_SUCCESS;
   1524 }
   1525 
   1526 static int set_options(ares_channel channel, const char *str)
   1527 {
   1528   const char *p, *q, *val;
   1529 
   1530   p = str;
   1531   while (*p)
   1532     {
   1533       q = p;
   1534       while (*q && !ISSPACE(*q))
   1535         q++;
   1536       val = try_option(p, q, "ndots:");
   1537       if (val && channel->ndots == -1)
   1538         channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
   1539       val = try_option(p, q, "retrans:");
   1540       if (val && channel->timeout == -1)
   1541         channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
   1542       val = try_option(p, q, "retry:");
   1543       if (val && channel->tries == -1)
   1544         channel->tries = aresx_sltosi(strtol(val, NULL, 10));
   1545       val = try_option(p, q, "rotate");
   1546       if (val && channel->rotate == -1)
   1547         channel->rotate = 1;
   1548       p = q;
   1549       while (ISSPACE(*p))
   1550         p++;
   1551     }
   1552 
   1553   return ARES_SUCCESS;
   1554 }
   1555 
   1556 static const char *try_option(const char *p, const char *q, const char *opt)
   1557 {
   1558   size_t len = strlen(opt);
   1559   return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
   1560 }
   1561 
   1562 #if !defined(WIN32) && !defined(WATT32)
   1563 static char *try_config(char *s, const char *opt, char scc)
   1564 {
   1565   size_t len;
   1566   char *p;
   1567   char *q;
   1568 
   1569   if (!s || !opt)
   1570     /* no line or no option */
   1571     return NULL;
   1572 
   1573   /* Hash '#' character is always used as primary comment char, additionally
   1574      a not-NUL secondary comment char will be considered when specified. */
   1575 
   1576   /* trim line comment */
   1577   p = s;
   1578   if(scc)
   1579     while (*p && (*p != '#') && (*p != scc))
   1580       p++;
   1581   else
   1582     while (*p && (*p != '#'))
   1583       p++;
   1584   *p = '\0';
   1585 
   1586   /* trim trailing whitespace */
   1587   q = p - 1;
   1588   while ((q >= s) && ISSPACE(*q))
   1589     q--;
   1590   *++q = '\0';
   1591 
   1592   /* skip leading whitespace */
   1593   p = s;
   1594   while (*p && ISSPACE(*p))
   1595     p++;
   1596 
   1597   if (!*p)
   1598     /* empty line */
   1599     return NULL;
   1600 
   1601   if ((len = strlen(opt)) == 0)
   1602     /* empty option */
   1603     return NULL;
   1604 
   1605   if (strncmp(p, opt, len) != 0)
   1606     /* line and option do not match */
   1607     return NULL;
   1608 
   1609   /* skip over given option name */
   1610   p += len;
   1611 
   1612   if (!*p)
   1613     /* no option value */
   1614     return NULL;
   1615 
   1616   if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
   1617     /* whitespace between option name and value is mandatory
   1618        for given option names which do not end with ':' or '=' */
   1619     return NULL;
   1620 
   1621   /* skip over whitespace */
   1622   while (*p && ISSPACE(*p))
   1623     p++;
   1624 
   1625   if (!*p)
   1626     /* no option value */
   1627     return NULL;
   1628 
   1629   /* return pointer to option value */
   1630   return p;
   1631 }
   1632 
   1633 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
   1634                           struct apattern *pat)
   1635 {
   1636   struct apattern *newsort;
   1637   newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
   1638   if (!newsort)
   1639     return 0;
   1640   newsort[*nsort] = *pat;
   1641   *sortlist = newsort;
   1642   (*nsort)++;
   1643   return 1;
   1644 }
   1645 
   1646 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
   1647 {
   1648 
   1649   /* Four octets and three periods yields at most 15 characters. */
   1650   if (len > 15)
   1651     return -1;
   1652 
   1653   addr->s_addr = inet_addr(ipbuf);
   1654   if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
   1655     return -1;
   1656   return 0;
   1657 }
   1658 
   1659 static void natural_mask(struct apattern *pat)
   1660 {
   1661   struct in_addr addr;
   1662 
   1663   /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,
   1664    * but portable.
   1665    */
   1666   addr.s_addr = ntohl(pat->addrV4.s_addr);
   1667 
   1668   /* This is out of date in the CIDR world, but some people might
   1669    * still rely on it.
   1670    */
   1671   if (IN_CLASSA(addr.s_addr))
   1672     pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
   1673   else if (IN_CLASSB(addr.s_addr))
   1674     pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
   1675   else
   1676     pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
   1677 }
   1678 #endif /* !WIN32 && !WATT32 */
   1679 
   1680 /* initialize an rc4 key. If possible a cryptographically secure random key
   1681    is generated using a suitable function (for example win32's RtlGenRandom as
   1682    described in
   1683    http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
   1684    otherwise the code defaults to cross-platform albeit less secure mechanism
   1685    using rand
   1686 */
   1687 static void randomize_key(unsigned char* key,int key_data_len)
   1688 {
   1689   int randomized = 0;
   1690   int counter=0;
   1691 #ifdef WIN32
   1692   BOOLEAN res;
   1693   if (ares_fpSystemFunction036)
   1694     {
   1695       res = (*ares_fpSystemFunction036) (key, key_data_len);
   1696       if (res)
   1697         randomized = 1;
   1698     }
   1699 #else /* !WIN32 */
   1700 #ifdef RANDOM_FILE
   1701   FILE *f = fopen(RANDOM_FILE, "rb");
   1702   if(f) {
   1703     counter = aresx_uztosi(fread(key, 1, key_data_len, f));
   1704     fclose(f);
   1705   }
   1706 #endif
   1707 #endif /* WIN32 */
   1708 
   1709   if ( !randomized ) {
   1710     for (;counter<key_data_len;counter++)
   1711       key[counter]=(unsigned char)(rand() % 256);
   1712   }
   1713 }
   1714 
   1715 static int init_id_key(rc4_key* key,int key_data_len)
   1716 {
   1717   unsigned char index1;
   1718   unsigned char index2;
   1719   unsigned char* state;
   1720   short counter;
   1721   unsigned char *key_data_ptr = 0;
   1722 
   1723   key_data_ptr = calloc(1,key_data_len);
   1724   if (!key_data_ptr)
   1725     return ARES_ENOMEM;
   1726 
   1727   state = &key->state[0];
   1728   for(counter = 0; counter < 256; counter++)
   1729     /* unnecessary AND but it keeps some compilers happier */
   1730     state[counter] = (unsigned char)(counter & 0xff);
   1731   randomize_key(key->state,key_data_len);
   1732   key->x = 0;
   1733   key->y = 0;
   1734   index1 = 0;
   1735   index2 = 0;
   1736   for(counter = 0; counter < 256; counter++)
   1737   {
   1738     index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
   1739                               index2) % 256);
   1740     ARES_SWAP_BYTE(&state[counter], &state[index2]);
   1741 
   1742     index1 = (unsigned char)((index1 + 1) % key_data_len);
   1743   }
   1744   free(key_data_ptr);
   1745   return ARES_SUCCESS;
   1746 }
   1747 
   1748 unsigned short ares__generate_new_id(rc4_key* key)
   1749 {
   1750   unsigned short r=0;
   1751   ares__rc4(key, (unsigned char *)&r, sizeof(r));
   1752   return r;
   1753 }
   1754 
   1755 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
   1756 {
   1757   channel->local_ip4 = local_ip;
   1758 }
   1759 
   1760 /* local_ip6 should be 16 bytes in length */
   1761 void ares_set_local_ip6(ares_channel channel,
   1762                         const unsigned char* local_ip6)
   1763 {
   1764   memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
   1765 }
   1766 
   1767 /* local_dev_name should be null terminated. */
   1768 void ares_set_local_dev(ares_channel channel,
   1769                         const char* local_dev_name)
   1770 {
   1771   strncpy(channel->local_dev_name, local_dev_name,
   1772           sizeof(channel->local_dev_name));
   1773   channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
   1774 }
   1775 
   1776 
   1777 void ares_set_socket_callback(ares_channel channel,
   1778                               ares_sock_create_callback cb,
   1779                               void *data)
   1780 {
   1781   channel->sock_create_cb = cb;
   1782   channel->sock_create_cb_data = data;
   1783 }
   1784 
   1785 void ares__init_servers_state(ares_channel channel)
   1786 {
   1787   struct server_state *server;
   1788   int i;
   1789 
   1790   for (i = 0; i < channel->nservers; i++)
   1791     {
   1792       server = &channel->servers[i];
   1793       server->udp_socket = ARES_SOCKET_BAD;
   1794       server->tcp_socket = ARES_SOCKET_BAD;
   1795       server->tcp_connection_generation = ++channel->tcp_connection_generation;
   1796       server->tcp_lenbuf_pos = 0;
   1797       server->tcp_buffer_pos = 0;
   1798       server->tcp_buffer = NULL;
   1799       server->tcp_length = 0;
   1800       server->qhead = NULL;
   1801       server->qtail = NULL;
   1802       ares__init_list_head(&server->queries_to_server);
   1803       server->channel = channel;
   1804       server->is_broken = 0;
   1805     }
   1806 }
   1807