92187e463e69c9094e1f552ffa72a7df4c526e5b
[platform/upstream/c-ares.git] / src / lib / ares_init.c
1
2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3  * Copyright (C) 2007-2013 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_NETINET_IN_H
25 #include <netinet/in.h>
26 #endif
27
28 #ifdef HAVE_NETDB_H
29 #include <netdb.h>
30 #endif
31
32 #ifdef HAVE_ARPA_INET_H
33 #include <arpa/inet.h>
34 #endif
35
36 #ifdef HAVE_ARPA_NAMESER_H
37 #  include <arpa/nameser.h>
38 #else
39 #  include "nameser.h"
40 #endif
41 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
42 #  include <arpa/nameser_compat.h>
43 #endif
44
45 #if defined(ANDROID) || defined(__ANDROID__)
46 #include <sys/system_properties.h>
47 #include "ares_android.h"
48 /* From the Bionic sources */
49 #define DNS_PROP_NAME_PREFIX  "net.dns"
50 #define MAX_DNS_PROPERTIES    8
51 #endif
52
53 #if defined(CARES_USE_LIBRESOLV)
54 #include <resolv.h>
55 #endif
56
57 #include "ares.h"
58 #include "ares_inet_net_pton.h"
59 #include "ares_library_init.h"
60 #include "ares_nowarn.h"
61 #include "ares_platform.h"
62 #include "ares_private.h"
63
64 #ifdef WATT32
65 #undef WIN32  /* Redefined in MingW/MSVC headers */
66 #endif
67
68 static int init_by_options(ares_channel channel,
69                            const struct ares_options *options,
70                            int optmask);
71 static int init_by_environment(ares_channel channel);
72 static int init_by_resolv_conf(ares_channel channel);
73 static int init_by_defaults(ares_channel channel);
74
75 #ifndef WATT32
76 static int config_nameserver(struct server_state **servers, int *nservers,
77                              char *str);
78 #endif
79 static int set_search(ares_channel channel, const char *str);
80 static int set_options(ares_channel channel, const char *str);
81 static const char *try_option(const char *p, const char *q, const char *opt);
82 static int init_id_key(rc4_key* key,int key_data_len);
83
84 static int config_sortlist(struct apattern **sortlist, int *nsort,
85                            const char *str);
86 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
87                           struct apattern *pat);
88 static int ip_addr(const char *s, ares_ssize_t len, struct in_addr *addr);
89 static void natural_mask(struct apattern *pat);
90 #if !defined(WIN32) && !defined(WATT32) && \
91     !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
92 static int config_domain(ares_channel channel, char *str);
93 static int config_lookup(ares_channel channel, const char *str,
94                          const char *bindch, const char *altbindch,
95                          const char *filech);
96 static char *try_config(char *s, const char *opt, char scc);
97 #endif
98
99 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
100                              x->nservers > -1 && \
101                              x->ndomains > -1 && \
102                              x->ndots > -1 && x->timeout > -1 && \
103                              x->tries > -1)
104
105 int ares_init(ares_channel *channelptr)
106 {
107   return ares_init_options(channelptr, NULL, 0);
108 }
109
110 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
111                       int optmask)
112 {
113   ares_channel channel;
114   int i;
115   int status = ARES_SUCCESS;
116   struct timeval now;
117
118   if (ares_library_initialized() != ARES_SUCCESS)
119     return ARES_ENOTINITIALIZED;  /* LCOV_EXCL_LINE: n/a on non-WinSock */
120
121   channel = ares_malloc(sizeof(struct ares_channeldata));
122   if (!channel) {
123     *channelptr = NULL;
124     return ARES_ENOMEM;
125   }
126
127   now = ares__tvnow();
128
129   /* Set everything to distinguished values so we know they haven't
130    * been set yet.
131    */
132   channel->flags = -1;
133   channel->timeout = -1;
134   channel->tries = -1;
135   channel->ndots = -1;
136   channel->rotate = -1;
137   channel->udp_port = -1;
138   channel->tcp_port = -1;
139   channel->ednspsz = -1;
140   channel->socket_send_buffer_size = -1;
141   channel->socket_receive_buffer_size = -1;
142   channel->nservers = -1;
143   channel->ndomains = -1;
144   channel->nsort = -1;
145   channel->tcp_connection_generation = 0;
146   channel->lookups = NULL;
147   channel->domains = NULL;
148   channel->sortlist = NULL;
149   channel->servers = NULL;
150   channel->sock_state_cb = NULL;
151   channel->sock_state_cb_data = NULL;
152   channel->sock_create_cb = NULL;
153   channel->sock_create_cb_data = NULL;
154   channel->sock_config_cb = NULL;
155   channel->sock_config_cb_data = NULL;
156   channel->sock_funcs = NULL;
157   channel->sock_func_cb_data = NULL;
158   channel->resolvconf_path = NULL;
159
160   channel->last_server = 0;
161   channel->last_timeout_processed = (time_t)now.tv_sec;
162
163   memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
164   channel->local_ip4 = 0;
165   memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
166
167   /* Initialize our lists of queries */
168   ares__init_list_head(&(channel->all_queries));
169   for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
170     {
171       ares__init_list_head(&(channel->queries_by_qid[i]));
172     }
173   for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
174     {
175       ares__init_list_head(&(channel->queries_by_timeout[i]));
176     }
177
178   /* Initialize configuration by each of the four sources, from highest
179    * precedence to lowest.
180    */
181
182   status = init_by_options(channel, options, optmask);
183   if (status != ARES_SUCCESS) {
184     DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
185                    ares_strerror(status)));
186     /* If we fail to apply user-specified options, fail the whole init process */
187     goto done;
188   }
189   status = init_by_environment(channel);
190   if (status != ARES_SUCCESS)
191     DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
192                    ares_strerror(status)));
193   if (status == ARES_SUCCESS) {
194     status = init_by_resolv_conf(channel);
195     if (status != ARES_SUCCESS)
196       DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
197                      ares_strerror(status)));
198   }
199
200   /*
201    * No matter what failed or succeeded, seed defaults to provide
202    * useful behavior for things that we missed.
203    */
204   status = init_by_defaults(channel);
205   if (status != ARES_SUCCESS)
206     DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
207                    ares_strerror(status)));
208
209   /* Generate random key */
210
211   if (status == ARES_SUCCESS) {
212     status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
213     if (status == ARES_SUCCESS)
214       channel->next_id = ares__generate_new_id(&channel->id_key);
215     else
216       DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
217                      ares_strerror(status)));
218   }
219
220 done:
221   if (status != ARES_SUCCESS)
222     {
223       /* Something failed; clean up memory we may have allocated. */
224       if (channel->servers)
225         ares_free(channel->servers);
226       if (channel->ndomains != -1)
227         ares_strsplit_free(channel->domains, channel->ndomains);
228       if (channel->sortlist)
229         ares_free(channel->sortlist);
230       if(channel->lookups)
231         ares_free(channel->lookups);
232       if(channel->resolvconf_path)
233         ares_free(channel->resolvconf_path);
234       ares_free(channel);
235       return status;
236     }
237
238   /* Trim to one server if ARES_FLAG_PRIMARY is set. */
239   if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
240     channel->nservers = 1;
241
242   ares__init_servers_state(channel);
243
244   *channelptr = channel;
245   return ARES_SUCCESS;
246 }
247
248 /* ares_dup() duplicates a channel handle with all its options and returns a
249    new channel handle */
250 int ares_dup(ares_channel *dest, ares_channel src)
251 {
252   struct ares_options opts;
253   struct ares_addr_port_node *servers;
254   int non_v4_default_port = 0;
255   int i, rc;
256   int optmask;
257
258   *dest = NULL; /* in case of failure return NULL explicitly */
259
260   /* First get the options supported by the old ares_save_options() function,
261      which is most of them */
262   rc = ares_save_options(src, &opts, &optmask);
263   if(rc)
264   {
265     ares_destroy_options(&opts);
266     return rc;
267   }
268
269   /* Then create the new channel with those options */
270   rc = ares_init_options(dest, &opts, optmask);
271
272   /* destroy the options copy to not leak any memory */
273   ares_destroy_options(&opts);
274
275   if(rc)
276     return rc;
277
278   /* Now clone the options that ares_save_options() doesn't support. */
279   (*dest)->sock_create_cb      = src->sock_create_cb;
280   (*dest)->sock_create_cb_data = src->sock_create_cb_data;
281   (*dest)->sock_config_cb      = src->sock_config_cb;
282   (*dest)->sock_config_cb_data = src->sock_config_cb_data;
283   (*dest)->sock_funcs          = src->sock_funcs;
284   (*dest)->sock_func_cb_data   = src->sock_func_cb_data;
285
286   strncpy((*dest)->local_dev_name, src->local_dev_name,
287           sizeof((*dest)->local_dev_name));
288   (*dest)->local_ip4 = src->local_ip4;
289   memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
290
291   /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
292   for (i = 0; i < src->nservers; i++)
293     {
294       if ((src->servers[i].addr.family != AF_INET) ||
295           (src->servers[i].addr.udp_port != 0) ||
296           (src->servers[i].addr.tcp_port != 0)) {
297         non_v4_default_port++;
298         break;
299       }
300     }
301   if (non_v4_default_port) {
302     rc = ares_get_servers_ports(src, &servers);
303     if (rc != ARES_SUCCESS) {
304       ares_destroy(*dest);
305       *dest = NULL;
306       return rc;
307     }
308     rc = ares_set_servers_ports(*dest, servers);
309     ares_free_data(servers);
310     if (rc != ARES_SUCCESS) {
311       ares_destroy(*dest);
312       *dest = NULL;
313       return rc;
314     }
315   }
316
317   return ARES_SUCCESS; /* everything went fine */
318 }
319
320 /* Save options from initialized channel */
321 int ares_save_options(ares_channel channel, struct ares_options *options,
322                       int *optmask)
323 {
324   int i, j;
325   int ipv4_nservers = 0;
326
327   /* Zero everything out */
328   memset(options, 0, sizeof(struct ares_options));
329
330   if (!ARES_CONFIG_CHECK(channel))
331     return ARES_ENODATA;
332
333   /* Traditionally the optmask wasn't saved in the channel struct so it was
334      recreated here. ROTATE is the first option that has no struct field of
335      its own in the public config struct */
336   (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
337                 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
338                 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
339                 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
340   (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
341
342   if (channel->resolvconf_path)
343     (*optmask) |= ARES_OPT_RESOLVCONF;
344
345   /* Copy easy stuff */
346   options->flags   = channel->flags;
347
348   /* We return full millisecond resolution but that's only because we don't
349      set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
350   options->timeout = channel->timeout;
351   options->tries   = channel->tries;
352   options->ndots   = channel->ndots;
353   options->udp_port = ntohs(aresx_sitous(channel->udp_port));
354   options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
355   options->sock_state_cb     = channel->sock_state_cb;
356   options->sock_state_cb_data = channel->sock_state_cb_data;
357
358   /* Copy IPv4 servers that use the default port */
359   if (channel->nservers) {
360     for (i = 0; i < channel->nservers; i++)
361     {
362       if ((channel->servers[i].addr.family == AF_INET) &&
363           (channel->servers[i].addr.udp_port == 0) &&
364           (channel->servers[i].addr.tcp_port == 0))
365         ipv4_nservers++;
366     }
367     if (ipv4_nservers) {
368       options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
369       if (!options->servers)
370         return ARES_ENOMEM;
371       for (i = j = 0; i < channel->nservers; i++)
372       {
373         if ((channel->servers[i].addr.family == AF_INET) &&
374             (channel->servers[i].addr.udp_port == 0) &&
375             (channel->servers[i].addr.tcp_port == 0))
376           memcpy(&options->servers[j++],
377                  &channel->servers[i].addr.addrV4,
378                  sizeof(channel->servers[i].addr.addrV4));
379       }
380     }
381   }
382   options->nservers = ipv4_nservers;
383
384   /* copy domains */
385   if (channel->ndomains) {
386     options->domains = ares_malloc(channel->ndomains * sizeof(char *));
387     if (!options->domains)
388       return ARES_ENOMEM;
389
390     for (i = 0; i < channel->ndomains; i++)
391     {
392       options->ndomains = i;
393       options->domains[i] = ares_strdup(channel->domains[i]);
394       if (!options->domains[i])
395         return ARES_ENOMEM;
396     }
397   }
398   options->ndomains = channel->ndomains;
399
400   /* copy lookups */
401   if (channel->lookups) {
402     options->lookups = ares_strdup(channel->lookups);
403     if (!options->lookups && channel->lookups)
404       return ARES_ENOMEM;
405   }
406
407   /* copy sortlist */
408   if (channel->nsort) {
409     options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
410     if (!options->sortlist)
411       return ARES_ENOMEM;
412     for (i = 0; i < channel->nsort; i++)
413       options->sortlist[i] = channel->sortlist[i];
414   }
415   options->nsort = channel->nsort;
416
417   /* copy path for resolv.conf file */
418   if (channel->resolvconf_path) {
419     options->resolvconf_path = ares_strdup(channel->resolvconf_path);
420     if (!options->resolvconf_path)
421       return ARES_ENOMEM;
422   }
423
424   return ARES_SUCCESS;
425 }
426
427 static int init_by_options(ares_channel channel,
428                            const struct ares_options *options,
429                            int optmask)
430 {
431   int i;
432
433   /* Easy stuff. */
434   if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
435     channel->flags = options->flags;
436   if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
437     channel->timeout = options->timeout;
438   else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
439     channel->timeout = options->timeout * 1000;
440   if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
441     channel->tries = options->tries;
442   if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
443     channel->ndots = options->ndots;
444   if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
445     channel->rotate = 1;
446   if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
447     channel->rotate = 0;
448   if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
449     channel->udp_port = htons(options->udp_port);
450   if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
451     channel->tcp_port = htons(options->tcp_port);
452   if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
453     {
454       channel->sock_state_cb = options->sock_state_cb;
455       channel->sock_state_cb_data = options->sock_state_cb_data;
456     }
457   if ((optmask & ARES_OPT_SOCK_SNDBUF)
458       && channel->socket_send_buffer_size == -1)
459     channel->socket_send_buffer_size = options->socket_send_buffer_size;
460   if ((optmask & ARES_OPT_SOCK_RCVBUF)
461       && channel->socket_receive_buffer_size == -1)
462     channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
463
464   if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
465     channel->ednspsz = options->ednspsz;
466
467   /* Copy the IPv4 servers, if given. */
468   if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
469     {
470       /* Avoid zero size allocations at any cost */
471       if (options->nservers > 0)
472         {
473           channel->servers =
474             ares_malloc(options->nservers * sizeof(struct server_state));
475           if (!channel->servers)
476             return ARES_ENOMEM;
477           for (i = 0; i < options->nservers; i++)
478             {
479               channel->servers[i].addr.family = AF_INET;
480               channel->servers[i].addr.udp_port = 0;
481               channel->servers[i].addr.tcp_port = 0;
482               memcpy(&channel->servers[i].addr.addrV4,
483                      &options->servers[i],
484                      sizeof(channel->servers[i].addr.addrV4));
485             }
486         }
487       channel->nservers = options->nservers;
488     }
489
490   /* Copy the domains, if given.  Keep channel->ndomains consistent so
491    * we can clean up in case of error.
492    */
493   if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
494     {
495       /* Avoid zero size allocations at any cost */
496       if (options->ndomains > 0)
497       {
498         channel->domains = ares_malloc(options->ndomains * sizeof(char *));
499         if (!channel->domains)
500           return ARES_ENOMEM;
501         for (i = 0; i < options->ndomains; i++)
502           {
503             channel->ndomains = i;
504             channel->domains[i] = ares_strdup(options->domains[i]);
505             if (!channel->domains[i])
506               return ARES_ENOMEM;
507           }
508       }
509       channel->ndomains = options->ndomains;
510     }
511
512   /* Set lookups, if given. */
513   if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
514     {
515       channel->lookups = ares_strdup(options->lookups);
516       if (!channel->lookups)
517         return ARES_ENOMEM;
518     }
519
520   /* copy sortlist */
521   if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1)) {
522     if (options->nsort > 0) {
523       channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
524       if (!channel->sortlist)
525         return ARES_ENOMEM;
526       for (i = 0; i < options->nsort; i++)
527         channel->sortlist[i] = options->sortlist[i];
528     }
529     channel->nsort = options->nsort;
530   }
531
532   /* Set path for resolv.conf file, if given. */
533   if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
534     {
535       channel->resolvconf_path = ares_strdup(options->resolvconf_path);
536       if (!channel->resolvconf_path && options->resolvconf_path)
537         return ARES_ENOMEM;
538     }
539
540   channel->optmask = optmask;
541
542   return ARES_SUCCESS;
543 }
544
545 static int init_by_environment(ares_channel channel)
546 {
547   const char *localdomain, *res_options;
548   int status;
549
550   localdomain = getenv("LOCALDOMAIN");
551   if (localdomain && channel->ndomains == -1)
552     {
553       status = set_search(channel, localdomain);
554       if (status != ARES_SUCCESS)
555         return status;
556     }
557
558   res_options = getenv("RES_OPTIONS");
559   if (res_options)
560     {
561       status = set_options(channel, res_options);
562       if (status != ARES_SUCCESS)
563         return status;  /* LCOV_EXCL_LINE: set_options() never fails */
564     }
565
566   return ARES_SUCCESS;
567 }
568
569 #ifdef WIN32
570 /*
571  * get_REG_SZ()
572  *
573  * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
574  * to the name of the registry leaf key to be queried, fetch it's string
575  * value and return a pointer in *outptr to a newly allocated memory area
576  * holding it as a null-terminated string.
577  *
578  * Returns 0 and nullifies *outptr upon inability to return a string value.
579  *
580  * Returns 1 and sets *outptr when returning a dynamically allocated string.
581  *
582  * Supported on Windows NT 3.5 and newer.
583  */
584 static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
585 {
586   DWORD size = 0;
587   int   res;
588
589   *outptr = NULL;
590
591   /* Find out size of string stored in registry */
592   res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size);
593   if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
594     return 0;
595
596   /* Allocate buffer of indicated size plus one given that string
597      might have been stored without null termination */
598   *outptr = ares_malloc(size+1);
599   if (!*outptr)
600     return 0;
601
602   /* Get the value for real */
603   res = RegQueryValueExA(hKey, leafKeyName, 0, NULL,
604                         (unsigned char *)*outptr, &size);
605   if ((res != ERROR_SUCCESS) || (size == 1))
606   {
607     ares_free(*outptr);
608     *outptr = NULL;
609     return 0;
610   }
611
612   /* Null terminate buffer allways */
613   *(*outptr + size) = '\0';
614
615   return 1;
616 }
617
618 /*
619  * get_REG_SZ_9X()
620  *
621  * Functionally identical to get_REG_SZ()
622  *
623  * Supported on Windows 95, 98 and ME.
624  */
625 static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
626 {
627   DWORD dataType = 0;
628   DWORD size = 0;
629   int   res;
630
631   *outptr = NULL;
632
633   /* Find out size of string stored in registry */
634   res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, NULL, &size);
635   if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
636     return 0;
637
638   /* Allocate buffer of indicated size plus one given that string
639      might have been stored without null termination */
640   *outptr = ares_malloc(size+1);
641   if (!*outptr)
642     return 0;
643
644   /* Get the value for real */
645   res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType,
646                         (unsigned char *)*outptr, &size);
647   if ((res != ERROR_SUCCESS) || (size == 1))
648   {
649     ares_free(*outptr);
650     *outptr = NULL;
651     return 0;
652   }
653
654   /* Null terminate buffer allways */
655   *(*outptr + size) = '\0';
656
657   return 1;
658 }
659
660 /*
661  * get_enum_REG_SZ()
662  *
663  * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
664  * pointer to the name of the registry leaf key to be queried, parent key
665  * is enumerated searching in child keys for given leaf key name and its
666  * associated string value. When located, this returns a pointer in *outptr
667  * to a newly allocated memory area holding it as a null-terminated string.
668  *
669  * Returns 0 and nullifies *outptr upon inability to return a string value.
670  *
671  * Returns 1 and sets *outptr when returning a dynamically allocated string.
672  *
673  * Supported on Windows NT 3.5 and newer.
674  */
675 static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
676                            char **outptr)
677 {
678   char  enumKeyName[256];
679   DWORD enumKeyNameBuffSize;
680   DWORD enumKeyIdx = 0;
681   HKEY  hKeyEnum;
682   int   gotString;
683   int   res;
684
685   *outptr = NULL;
686
687   for(;;)
688   {
689     enumKeyNameBuffSize = sizeof(enumKeyName);
690     res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName,
691                        &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
692     if (res != ERROR_SUCCESS)
693       break;
694     res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
695                        &hKeyEnum);
696     if (res != ERROR_SUCCESS)
697       continue;
698     gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
699     RegCloseKey(hKeyEnum);
700     if (gotString)
701       break;
702   }
703
704   if (!*outptr)
705     return 0;
706
707   return 1;
708 }
709
710 /*
711  * get_DNS_Registry_9X()
712  *
713  * Functionally identical to get_DNS_Registry()
714  *
715  * Implementation supports Windows 95, 98 and ME.
716  */
717 static int get_DNS_Registry_9X(char **outptr)
718 {
719   HKEY hKey_VxD_MStcp;
720   int  gotString;
721   int  res;
722
723   *outptr = NULL;
724
725   res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
726                      &hKey_VxD_MStcp);
727   if (res != ERROR_SUCCESS)
728     return 0;
729
730   gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
731   RegCloseKey(hKey_VxD_MStcp);
732
733   if (!gotString || !*outptr)
734     return 0;
735
736   return 1;
737 }
738
739 /*
740  * get_DNS_Registry_NT()
741  *
742  * Functionally identical to get_DNS_Registry()
743  *
744  * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
745  *
746  * Implementation supports Windows NT 3.5 and newer.
747  */
748 static int get_DNS_Registry_NT(char **outptr)
749 {
750   HKEY hKey_Interfaces = NULL;
751   HKEY hKey_Tcpip_Parameters;
752   int  gotString;
753   int  res;
754
755   *outptr = NULL;
756
757   res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
758                      &hKey_Tcpip_Parameters);
759   if (res != ERROR_SUCCESS)
760     return 0;
761
762   /*
763   ** Global DNS settings override adapter specific parameters when both
764   ** are set. Additionally static DNS settings override DHCP-configured
765   ** parameters when both are set.
766   */
767
768   /* Global DNS static parameters */
769   gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
770   if (gotString)
771     goto done;
772
773   /* Global DNS DHCP-configured parameters */
774   gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
775   if (gotString)
776     goto done;
777
778   /* Try adapter specific parameters */
779   res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0,
780                      KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
781                      &hKey_Interfaces);
782   if (res != ERROR_SUCCESS)
783   {
784     hKey_Interfaces = NULL;
785     goto done;
786   }
787
788   /* Adapter specific DNS static parameters */
789   gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
790   if (gotString)
791     goto done;
792
793   /* Adapter specific DNS DHCP-configured parameters */
794   gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
795
796 done:
797   if (hKey_Interfaces)
798     RegCloseKey(hKey_Interfaces);
799
800   RegCloseKey(hKey_Tcpip_Parameters);
801
802   if (!gotString || !*outptr)
803     return 0;
804
805   return 1;
806 }
807
808 /*
809  * get_DNS_Registry()
810  *
811  * Locates DNS info in the registry. When located, this returns a pointer
812  * in *outptr to a newly allocated memory area holding a null-terminated
813  * string with a space or comma seperated list of DNS IP addresses.
814  *
815  * Returns 0 and nullifies *outptr upon inability to return DNSes string.
816  *
817  * Returns 1 and sets *outptr when returning a dynamically allocated string.
818  */
819 static int get_DNS_Registry(char **outptr)
820 {
821   win_platform platform;
822   int gotString = 0;
823
824   *outptr = NULL;
825
826   platform = ares__getplatform();
827
828   if (platform == WIN_NT)
829     gotString = get_DNS_Registry_NT(outptr);
830   else if (platform == WIN_9X)
831     gotString = get_DNS_Registry_9X(outptr);
832
833   if (!gotString)
834     return 0;
835
836   return 1;
837 }
838
839 static void commanjoin(char** dst, const char* const src, const size_t len)
840 {
841   char *newbuf;
842   size_t newsize;
843
844   /* 1 for terminating 0 and 2 for , and terminating 0 */
845   newsize = len + (*dst ? (strlen(*dst) + 2) : 1);
846   newbuf = ares_realloc(*dst, newsize);
847   if (!newbuf)
848     return;
849   if (*dst == NULL)
850     *newbuf = '\0';
851   *dst = newbuf;
852   if (strlen(*dst) != 0)
853     strcat(*dst, ",");
854   strncat(*dst, src, len);
855 }
856
857 /*
858  * commajoin()
859  *
860  * RTF code.
861  */
862 static void commajoin(char **dst, const char *src)
863 {
864   commanjoin(dst, src, strlen(src));
865 }
866
867 /*
868  * get_DNS_NetworkParams()
869  *
870  * Locates DNS info using GetNetworkParams() function from the Internet
871  * Protocol Helper (IP Helper) API. When located, this returns a pointer
872  * in *outptr to a newly allocated memory area holding a null-terminated
873  * string with a space or comma seperated list of DNS IP addresses.
874  *
875  * Returns 0 and nullifies *outptr upon inability to return DNSes string.
876  *
877  * Returns 1 and sets *outptr when returning a dynamically allocated string.
878  *
879  * Implementation supports Windows 98 and newer.
880  *
881  * Note: Ancient PSDK required in order to build a W98 target.
882  */
883 static int get_DNS_NetworkParams(char **outptr)
884 {
885   FIXED_INFO       *fi, *newfi;
886   struct ares_addr namesrvr;
887   char             *txtaddr;
888   IP_ADDR_STRING   *ipAddr;
889   int              res;
890   DWORD            size = sizeof (*fi);
891
892   *outptr = NULL;
893
894   /* Verify run-time availability of GetNetworkParams() */
895   if (ares_fpGetNetworkParams == ZERO_NULL)
896     return 0;
897
898   fi = ares_malloc(size);
899   if (!fi)
900     return 0;
901
902   res = (*ares_fpGetNetworkParams) (fi, &size);
903   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
904     goto done;
905
906   newfi = ares_realloc(fi, size);
907   if (!newfi)
908     goto done;
909
910   fi = newfi;
911   res = (*ares_fpGetNetworkParams) (fi, &size);
912   if (res != ERROR_SUCCESS)
913     goto done;
914
915   for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
916   {
917     txtaddr = &ipAddr->IpAddress.String[0];
918
919     /* Validate converting textual address to binary format. */
920     if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
921     {
922       if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
923           (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
924         continue;
925     }
926     else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
927     {
928       if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
929                  sizeof(namesrvr.addrV6)) == 0)
930         continue;
931     }
932     else
933       continue;
934
935     commajoin(outptr, txtaddr);
936
937     if (!*outptr)
938       break;
939   }
940
941 done:
942   if (fi)
943     ares_free(fi);
944
945   if (!*outptr)
946     return 0;
947
948   return 1;
949 }
950
951 static BOOL ares_IsWindowsVistaOrGreater(void)
952 {
953   OSVERSIONINFO vinfo;
954   memset(&vinfo, 0, sizeof(vinfo));
955   vinfo.dwOSVersionInfoSize = sizeof(vinfo);
956 #ifdef _MSC_VER
957 #pragma warning(push)
958 #pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */
959 #endif
960   if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
961     return FALSE;
962   return TRUE;
963 #ifdef _MSC_VER
964 #pragma warning(pop)
965 #endif
966 }
967
968 /* A structure to hold the string form of IPv4 and IPv6 addresses so we can
969  * sort them by a metric.
970  */
971 typedef struct
972 {
973   /* The metric we sort them by. */
974   ULONG metric;
975
976   /* Original index of the item, used as a secondary sort parameter to make
977    * qsort() stable if the metrics are equal */
978   size_t orig_idx;
979
980   /* Room enough for the string form of any IPv4 or IPv6 address that
981    * ares_inet_ntop() will create.  Based on the existing c-ares practice.
982    */
983   char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
984 } Address;
985
986 /* Sort Address values \a left and \a right by metric, returning the usual
987  * indicators for qsort().
988  */
989 static int compareAddresses(const void *arg1,
990                             const void *arg2)
991 {
992   const Address * const left = arg1;
993   const Address * const right = arg2;
994   /* Lower metric the more preferred */
995   if(left->metric < right->metric) return -1;
996   if(left->metric > right->metric) return 1;
997   /* If metrics are equal, lower original index more preferred */
998   if(left->orig_idx < right->orig_idx) return -1;
999   if(left->orig_idx > right->orig_idx) return 1;
1000   return 0;
1001 }
1002
1003 /* There can be multiple routes to "the Internet".  And there can be different
1004  * DNS servers associated with each of the interfaces that offer those routes.
1005  * We have to assume that any DNS server can serve any request.  But, some DNS
1006  * servers may only respond if requested over their associated interface.  But
1007  * we also want to use "the preferred route to the Internet" whenever possible
1008  * (and not use DNS servers on a non-preferred route even by forcing request
1009  * to go out on the associated non-preferred interface).  i.e. We want to use
1010  * the DNS servers associated with the same interface that we would use to
1011  * make a general request to anything else.
1012  *
1013  * But, Windows won't sort the DNS servers by the metrics associated with the
1014  * routes and interfaces _even_ though it obviously sends IP packets based on
1015  * those same routes and metrics.  So, we must do it ourselves.
1016  *
1017  * So, we sort the DNS servers by the same metric values used to determine how
1018  * an outgoing IP packet will go, thus effectively using the DNS servers
1019  * associated with the interface that the DNS requests themselves will
1020  * travel.  This gives us optimal routing and avoids issues where DNS servers
1021  * won't respond to requests that don't arrive via some specific subnetwork
1022  * (and thus some specific interface).
1023  *
1024  * This function computes the metric we use to sort.  On the interface
1025  * identified by \a luid, it determines the best route to \a dest and combines
1026  * that route's metric with \a interfaceMetric to compute a metric for the
1027  * destination address on that interface.  This metric can be used as a weight
1028  * to sort the DNS server addresses associated with each interface (lower is
1029  * better).
1030  *
1031  * Note that by restricting the route search to the specific interface with
1032  * which the DNS servers are associated, this function asks the question "What
1033  * is the metric for sending IP packets to this DNS server?" which allows us
1034  * to sort the DNS servers correctly.
1035  */
1036 static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
1037                                 const SOCKADDR_INET * const dest,
1038                                 const ULONG interfaceMetric)
1039 {
1040   /* On this interface, get the best route to that destination. */
1041   MIB_IPFORWARD_ROW2 row;
1042   SOCKADDR_INET ignored;
1043   if(!ares_fpGetBestRoute2 ||
1044      ares_fpGetBestRoute2(/* The interface to use.  The index is ignored since we are
1045                            * passing a LUID.
1046                            */
1047                            luid, 0,
1048                            /* No specific source address. */
1049                            NULL,
1050                            /* Our destination address. */
1051                            dest,
1052                            /* No options. */
1053                            0,
1054                            /* The route row. */
1055                            &row,
1056                            /* The best source address, which we don't need. */
1057                            &ignored) != NO_ERROR
1058      /* If the metric is "unused" (-1) or too large for us to add the two
1059       * metrics, use the worst possible, thus sorting this last.
1060       */
1061      || row.Metric == (ULONG)-1
1062      || row.Metric > ((ULONG)-1) - interfaceMetric) {
1063     /* Return the worst possible metric. */
1064     return (ULONG)-1;
1065   }
1066
1067   /* Return the metric value from that row, plus the interface metric.
1068    *
1069    * See
1070    * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
1071    * which describes the combination as a "sum".
1072    */
1073   return row.Metric + interfaceMetric;
1074 }
1075
1076 /*
1077  * get_DNS_AdaptersAddresses()
1078  *
1079  * Locates DNS info using GetAdaptersAddresses() function from the Internet
1080  * Protocol Helper (IP Helper) API. When located, this returns a pointer
1081  * in *outptr to a newly allocated memory area holding a null-terminated
1082  * string with a space or comma seperated list of DNS IP addresses.
1083  *
1084  * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1085  *
1086  * Returns 1 and sets *outptr when returning a dynamically allocated string.
1087  *
1088  * Implementation supports Windows XP and newer.
1089  */
1090 #define IPAA_INITIAL_BUF_SZ 15 * 1024
1091 #define IPAA_MAX_TRIES 3
1092 static int get_DNS_AdaptersAddresses(char **outptr)
1093 {
1094   IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
1095   IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
1096   ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
1097   ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
1098   ULONG AddrFlags = 0;
1099   int trying = IPAA_MAX_TRIES;
1100   int res;
1101
1102   /* The capacity of addresses, in elements. */
1103   size_t addressesSize;
1104   /* The number of elements in addresses. */
1105   size_t addressesIndex = 0;
1106   /* The addresses we will sort. */
1107   Address *addresses;
1108
1109   union {
1110     struct sockaddr     *sa;
1111     struct sockaddr_in  *sa4;
1112     struct sockaddr_in6 *sa6;
1113   } namesrvr;
1114
1115   *outptr = NULL;
1116
1117   /* Verify run-time availability of GetAdaptersAddresses() */
1118   if (ares_fpGetAdaptersAddresses == ZERO_NULL)
1119     return 0;
1120
1121   ipaa = ares_malloc(Bufsz);
1122   if (!ipaa)
1123     return 0;
1124
1125   /* Start with enough room for a few DNS server addresses and we'll grow it
1126    * as we encounter more.
1127    */
1128   addressesSize = 4;
1129   addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
1130   if(addresses == NULL) {
1131     /* We need room for at least some addresses to function. */
1132     ares_free(ipaa);
1133     return 0;
1134   }
1135
1136   /* Usually this call suceeds with initial buffer size */
1137   res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1138                                         ipaa, &ReqBufsz);
1139   if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
1140     goto done;
1141
1142   while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
1143   {
1144     if (Bufsz < ReqBufsz)
1145     {
1146       newipaa = ares_realloc(ipaa, ReqBufsz);
1147       if (!newipaa)
1148         goto done;
1149       Bufsz = ReqBufsz;
1150       ipaa = newipaa;
1151     }
1152     res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1153                                           ipaa, &ReqBufsz);
1154     if (res == ERROR_SUCCESS)
1155       break;
1156   }
1157   if (res != ERROR_SUCCESS)
1158     goto done;
1159
1160   for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1161   {
1162     if(ipaaEntry->OperStatus != IfOperStatusUp)
1163         continue;
1164
1165     /* For each interface, find any associated DNS servers as IPv4 or IPv6
1166      * addresses.  For each found address, find the best route to that DNS
1167      * server address _on_ _that_ _interface_ (at this moment in time) and
1168      * compute the resulting total metric, just as Windows routing will do.
1169      * Then, sort all the addresses found by the metric.
1170      */
1171     for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1172          ipaDNSAddr;
1173          ipaDNSAddr = ipaDNSAddr->Next)
1174     {
1175       namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1176
1177       if (namesrvr.sa->sa_family == AF_INET)
1178       {
1179         if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1180             (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
1181           continue;
1182
1183         /* Allocate room for another address, if necessary, else skip. */
1184         if(addressesIndex == addressesSize) {
1185           const size_t newSize = addressesSize + 4;
1186           Address * const newMem =
1187             (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
1188           if(newMem == NULL) {
1189             continue;
1190           }
1191           addresses = newMem;
1192           addressesSize = newSize;
1193         }
1194
1195         /* Vista required for Luid or Ipv4Metric */
1196         if (ares_IsWindowsVistaOrGreater())
1197         {
1198           /* Save the address as the next element in addresses. */
1199           addresses[addressesIndex].metric =
1200             getBestRouteMetric(&ipaaEntry->Luid,
1201                                (SOCKADDR_INET*)(namesrvr.sa),
1202                                ipaaEntry->Ipv4Metric);
1203         }
1204         else
1205         {
1206           addresses[addressesIndex].metric = (ULONG)-1;
1207         }
1208
1209         /* Record insertion index to make qsort stable */
1210         addresses[addressesIndex].orig_idx = addressesIndex;
1211
1212         if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1213                              addresses[addressesIndex].text,
1214                              sizeof(addresses[0].text))) {
1215           continue;
1216         }
1217         ++addressesIndex;
1218       }
1219       else if (namesrvr.sa->sa_family == AF_INET6)
1220       {
1221         if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1222                    sizeof(namesrvr.sa6->sin6_addr)) == 0)
1223           continue;
1224
1225         /* Allocate room for another address, if necessary, else skip. */
1226         if(addressesIndex == addressesSize) {
1227           const size_t newSize = addressesSize + 4;
1228           Address * const newMem =
1229             (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
1230           if(newMem == NULL) {
1231             continue;
1232           }
1233           addresses = newMem;
1234           addressesSize = newSize;
1235         }
1236
1237         /* Vista required for Luid or Ipv4Metric */
1238         if (ares_IsWindowsVistaOrGreater())
1239         {
1240           /* Save the address as the next element in addresses. */
1241           addresses[addressesIndex].metric =
1242             getBestRouteMetric(&ipaaEntry->Luid,
1243                                (SOCKADDR_INET*)(namesrvr.sa),
1244                                ipaaEntry->Ipv6Metric);
1245         }
1246         else
1247         {
1248           addresses[addressesIndex].metric = (ULONG)-1;
1249         }
1250
1251         /* Record insertion index to make qsort stable */
1252         addresses[addressesIndex].orig_idx = addressesIndex;
1253
1254         if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1255                              addresses[addressesIndex].text,
1256                              sizeof(addresses[0].text))) {
1257           continue;
1258         }
1259         ++addressesIndex;
1260       }
1261       else {
1262         /* Skip non-IPv4/IPv6 addresses completely. */
1263         continue;
1264       }
1265     }
1266   }
1267
1268   /* Sort all of the textual addresses by their metric (and original index if
1269    * metrics are equal). */
1270   qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses);
1271
1272   /* Join them all into a single string, removing duplicates. */
1273   {
1274     size_t i;
1275     for(i = 0; i < addressesIndex; ++i) {
1276       size_t j;
1277       /* Look for this address text appearing previously in the results. */
1278       for(j = 0; j < i; ++j) {
1279         if(strcmp(addresses[j].text, addresses[i].text) == 0) {
1280           break;
1281         }
1282       }
1283       /* Iff we didn't emit this address already, emit it now. */
1284       if(j == i) {
1285         /* Add that to outptr (if we can). */
1286         commajoin(outptr, addresses[i].text);
1287       }
1288     }
1289   }
1290
1291 done:
1292   ares_free(addresses);
1293
1294   if (ipaa)
1295     ares_free(ipaa);
1296
1297   if (!*outptr) {
1298     return 0;
1299   }
1300
1301   return 1;
1302 }
1303
1304 /*
1305  * get_DNS_Windows()
1306  *
1307  * Locates DNS info from Windows employing most suitable methods available at
1308  * run-time no matter which Windows version it is. When located, this returns
1309  * a pointer in *outptr to a newly allocated memory area holding a string with
1310  * a space or comma seperated list of DNS IP addresses, null-terminated.
1311  *
1312  * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1313  *
1314  * Returns 1 and sets *outptr when returning a dynamically allocated string.
1315  *
1316  * Implementation supports Windows 95 and newer.
1317  */
1318 static int get_DNS_Windows(char **outptr)
1319 {
1320   /* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts
1321    * DNS servers by interface route metrics to try to use the best DNS server. */
1322   if (get_DNS_AdaptersAddresses(outptr))
1323     return 1;
1324
1325   /* Try using IP helper API GetNetworkParams(). IPv4 only. */
1326   if (get_DNS_NetworkParams(outptr))
1327     return 1;
1328
1329   /* Fall-back to registry information */
1330   return get_DNS_Registry(outptr);
1331 }
1332
1333 /*
1334  * get_SuffixList_Windows()
1335  *
1336  * Reads the "DNS Suffix Search List" from registry and writes the list items
1337  * whitespace separated to outptr. If the Search List is empty, the
1338  * "Primary Dns Suffix" is written to outptr.
1339  *
1340  * Returns 0 and nullifies *outptr upon inability to return the suffix list.
1341  *
1342  * Returns 1 and sets *outptr when returning a dynamically allocated string.
1343  *
1344  * Implementation supports Windows Server 2003 and newer
1345  */
1346 static int get_SuffixList_Windows(char **outptr)
1347 {
1348   HKEY hKey, hKeyEnum;
1349   char  keyName[256];
1350   DWORD keyNameBuffSize;
1351   DWORD keyIdx = 0;
1352   char *p = NULL;
1353
1354   *outptr = NULL;
1355
1356   if (ares__getplatform() != WIN_NT)
1357     return 0;
1358
1359   /* 1. Global DNS Suffix Search List */
1360   if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
1361       KEY_READ, &hKey) == ERROR_SUCCESS)
1362   {
1363     get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
1364     if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
1365     {
1366       commajoin(outptr, p);
1367       ares_free(p);
1368       p = NULL;
1369     }
1370     RegCloseKey(hKey);
1371   }
1372
1373   if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
1374       KEY_READ, &hKey) == ERROR_SUCCESS)
1375   {
1376     if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
1377     {
1378       commajoin(outptr, p);
1379       ares_free(p);
1380       p = NULL;
1381     }
1382     RegCloseKey(hKey);
1383   }
1384
1385   /* 2. Connection Specific Search List composed of:
1386    *  a. Primary DNS Suffix */
1387   if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
1388       KEY_READ, &hKey) == ERROR_SUCCESS)
1389   {
1390     if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
1391     {
1392       commajoin(outptr, p);
1393       ares_free(p);
1394       p = NULL;
1395     }
1396     RegCloseKey(hKey);
1397   }
1398
1399   /*  b. Interface SearchList, Domain, DhcpDomain */
1400   if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
1401       KEY_READ, &hKey) == ERROR_SUCCESS)
1402   {
1403     for(;;)
1404     {
1405       keyNameBuffSize = sizeof(keyName);
1406       if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
1407           0, NULL, NULL, NULL)
1408           != ERROR_SUCCESS)
1409         break;
1410       if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
1411           != ERROR_SUCCESS)
1412         continue;
1413       /* p can be comma separated (SearchList) */
1414       if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
1415       {
1416         commajoin(outptr, p);
1417         ares_free(p);
1418         p = NULL;
1419       }
1420       if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
1421       {
1422         commajoin(outptr, p);
1423         ares_free(p);
1424         p = NULL;
1425       }
1426       if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
1427       {
1428         commajoin(outptr, p);
1429         ares_free(p);
1430         p = NULL;
1431       }
1432       RegCloseKey(hKeyEnum);
1433     }
1434     RegCloseKey(hKey);
1435   }
1436
1437   return *outptr != NULL;
1438 }
1439
1440 #endif
1441
1442 static int init_by_resolv_conf(ares_channel channel)
1443 {
1444 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1445     !defined(CARES_USE_LIBRESOLV)
1446   char *line = NULL;
1447 #endif
1448   int status = -1, nservers = 0, nsort = 0;
1449   struct server_state *servers = NULL;
1450   struct apattern *sortlist = NULL;
1451
1452 #ifdef WIN32
1453
1454   if (channel->nservers > -1)  /* don't override ARES_OPT_SERVER */
1455      return ARES_SUCCESS;
1456
1457   if (get_DNS_Windows(&line))
1458   {
1459     status = config_nameserver(&servers, &nservers, line);
1460     ares_free(line);
1461   }
1462
1463   if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
1464   {
1465       status = set_search(channel, line);
1466       ares_free(line);
1467   }
1468
1469   if (status == ARES_SUCCESS)
1470     status = ARES_EOF;
1471   else
1472     /* Catch the case when all the above checks fail (which happens when there
1473        is no network card or the cable is unplugged) */
1474     status = ARES_EFILE;
1475
1476 #elif defined(__riscos__)
1477
1478   /* Under RISC OS, name servers are listed in the
1479      system variable Inet$Resolvers, space separated. */
1480
1481   line = getenv("Inet$Resolvers");
1482   status = ARES_EOF;
1483   if (line) {
1484     char *resolvers = ares_strdup(line), *pos, *space;
1485
1486     if (!resolvers)
1487       return ARES_ENOMEM;
1488
1489     pos = resolvers;
1490     do {
1491       space = strchr(pos, ' ');
1492       if (space)
1493         *space = '\0';
1494       status = config_nameserver(&servers, &nservers, pos);
1495       if (status != ARES_SUCCESS)
1496         break;
1497       pos = space + 1;
1498     } while (space);
1499
1500     if (status == ARES_SUCCESS)
1501       status = ARES_EOF;
1502
1503     ares_free(resolvers);
1504   }
1505
1506 #elif defined(WATT32)
1507   int i;
1508
1509   sock_init();
1510   for (i = 0; def_nameservers[i]; i++)
1511       ;
1512   if (i == 0)
1513     return ARES_SUCCESS; /* use localhost DNS server */
1514
1515   nservers = i;
1516   servers = ares_malloc(sizeof(struct server_state));
1517   if (!servers)
1518      return ARES_ENOMEM;
1519   memset(servers, 0, sizeof(struct server_state));
1520
1521   for (i = 0; def_nameservers[i]; i++)
1522   {
1523     servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1524     servers[i].addr.family = AF_INET;
1525     servers[i].addr.udp_port = 0;
1526     servers[i].addr.tcp_port = 0;
1527   }
1528   status = ARES_EOF;
1529
1530 #elif defined(ANDROID) || defined(__ANDROID__)
1531   unsigned int i;
1532   char **dns_servers;
1533   char *domains;
1534   size_t num_servers;
1535
1536   /* Use the Android connectivity manager to get a list
1537    * of DNS servers. As of Android 8 (Oreo) net.dns#
1538    * system properties are no longer available. Google claims this
1539    * improves privacy. Apps now need the ACCESS_NETWORK_STATE
1540    * permission and must use the ConnectivityManager which
1541    * is Java only. */
1542   dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers);
1543   if (dns_servers != NULL)
1544   {
1545     for (i = 0; i < num_servers; i++)
1546     {
1547       status = config_nameserver(&servers, &nservers, dns_servers[i]);
1548       if (status != ARES_SUCCESS)
1549         break;
1550       status = ARES_EOF;
1551     }
1552     for (i = 0; i < num_servers; i++)
1553     {
1554       ares_free(dns_servers[i]);
1555     }
1556     ares_free(dns_servers);
1557   }
1558   if (channel->ndomains == -1)
1559   {
1560     domains = ares_get_android_search_domains_list();
1561     set_search(channel, domains);
1562     ares_free(domains);
1563   }
1564
1565 #  ifdef HAVE___SYSTEM_PROPERTY_GET
1566   /* Old way using the system property still in place as
1567    * a fallback. Older android versions can still use this.
1568    * it's possible for older apps not not have added the new
1569    * permission and we want to try to avoid breaking those.
1570    *
1571    * We'll only run this if we don't have any dns servers
1572    * because this will get the same ones (if it works). */
1573   if (status != ARES_EOF) {
1574     char propname[PROP_NAME_MAX];
1575     char propvalue[PROP_VALUE_MAX]="";
1576     for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1577       snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1578       if (__system_property_get(propname, propvalue) < 1) {
1579         status = ARES_EOF;
1580         break;
1581       }
1582
1583       status = config_nameserver(&servers, &nservers, propvalue);
1584       if (status != ARES_SUCCESS)
1585         break;
1586       status = ARES_EOF;
1587     }
1588   }
1589 #  endif /* HAVE___SYSTEM_PROPERTY_GET */
1590 #elif defined(CARES_USE_LIBRESOLV)
1591   struct __res_state res;
1592   memset(&res, 0, sizeof(res));
1593   int result = res_ninit(&res);
1594   if (result == 0 && (res.options & RES_INIT)) {
1595     status = ARES_EOF;
1596
1597     if (channel->nservers == -1) {
1598       union res_sockaddr_union addr[MAXNS];
1599       int nscount = res_getservers(&res, addr, MAXNS);
1600       int i;
1601       for (i = 0; i < nscount; ++i) {
1602         char str[INET6_ADDRSTRLEN];
1603         int config_status;
1604         sa_family_t family = addr[i].sin.sin_family;
1605         if (family == AF_INET) {
1606           ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
1607         } else if (family == AF_INET6) {
1608           ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
1609         } else {
1610           continue;
1611         }
1612
1613         config_status = config_nameserver(&servers, &nservers, str);
1614         if (config_status != ARES_SUCCESS) {
1615           status = config_status;
1616           break;
1617         }
1618       }
1619     }
1620     if (channel->ndomains == -1) {
1621       int entries = 0;
1622       while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1623         entries++;
1624
1625       channel->domains = ares_malloc(entries * sizeof(char *));
1626       if (!channel->domains) {
1627         status = ARES_ENOMEM;
1628       } else {
1629         int i;
1630         channel->ndomains = entries;
1631         for (i = 0; i < channel->ndomains; ++i) {
1632           channel->domains[i] = ares_strdup(res.dnsrch[i]);
1633           if (!channel->domains[i])
1634             status = ARES_ENOMEM;
1635         }
1636       }
1637     }
1638     if (channel->ndots == -1)
1639       channel->ndots = res.ndots;
1640     if (channel->tries == -1)
1641       channel->tries = res.retry;
1642     if (channel->rotate == -1)
1643       channel->rotate = res.options & RES_ROTATE;
1644     if (channel->timeout == -1)
1645       channel->timeout = res.retrans * 1000;
1646
1647     res_ndestroy(&res);
1648   }
1649 #else
1650   {
1651     char *p;
1652     FILE *fp;
1653     size_t linesize;
1654     int error;
1655     int update_domains;
1656     const char *resolvconf_path;
1657
1658     /* Don't read resolv.conf and friends if we don't have to */
1659     if (ARES_CONFIG_CHECK(channel))
1660         return ARES_SUCCESS;
1661
1662     /* Only update search domains if they're not already specified */
1663     update_domains = (channel->ndomains == -1);
1664
1665     /* Support path for resolvconf filename set by ares_init_options */
1666     if(channel->resolvconf_path) {
1667       resolvconf_path = channel->resolvconf_path;
1668     } else {
1669       resolvconf_path = PATH_RESOLV_CONF;
1670     }
1671
1672     fp = fopen(resolvconf_path, "r");
1673     if (fp) {
1674       while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1675       {
1676         if ((p = try_config(line, "domain", ';')) && update_domains)
1677           status = config_domain(channel, p);
1678         else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1679           status = config_lookup(channel, p, "bind", NULL, "file");
1680         else if ((p = try_config(line, "search", ';')) && update_domains)
1681           status = set_search(channel, p);
1682         else if ((p = try_config(line, "nameserver", ';')) &&
1683                 channel->nservers == -1)
1684           status = config_nameserver(&servers, &nservers, p);
1685         else if ((p = try_config(line, "sortlist", ';')) &&
1686                 channel->nsort == -1)
1687           status = config_sortlist(&sortlist, &nsort, p);
1688         else if ((p = try_config(line, "options", ';')))
1689           status = set_options(channel, p);
1690         else
1691           status = ARES_SUCCESS;
1692         if (status != ARES_SUCCESS)
1693           break;
1694       }
1695       fclose(fp);
1696     }
1697     else {
1698       error = ERRNO;
1699       switch(error) {
1700       case ENOENT:
1701       case ESRCH:
1702         status = ARES_EOF;
1703         break;
1704       default:
1705         DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1706                       error, strerror(error)));
1707         DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1708         status = ARES_EFILE;
1709       }
1710     }
1711
1712     if ((status == ARES_EOF) && (!channel->lookups)) {
1713       /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1714       fp = fopen("/etc/nsswitch.conf", "r");
1715       if (fp) {
1716         while ((status = ares__read_line(fp, &line, &linesize)) ==
1717                ARES_SUCCESS)
1718         {
1719           if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1720             (void)config_lookup(channel, p, "dns", "resolve", "files");
1721         }
1722         fclose(fp);
1723       }
1724       else {
1725         error = ERRNO;
1726         switch(error) {
1727         case ENOENT:
1728         case ESRCH:
1729           break;
1730         default:
1731           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1732                          error, strerror(error)));
1733           DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1734                          "/etc/nsswitch.conf"));
1735         }
1736
1737         /* ignore error, maybe we will get luck in next if clause */
1738         status = ARES_EOF;
1739       }
1740     }
1741
1742     if ((status == ARES_EOF) && (!channel->lookups)) {
1743       /* Linux / GNU libc 2.x and possibly others have host.conf */
1744       fp = fopen("/etc/host.conf", "r");
1745       if (fp) {
1746         while ((status = ares__read_line(fp, &line, &linesize)) ==
1747                ARES_SUCCESS)
1748         {
1749           if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1750             /* ignore errors */
1751             (void)config_lookup(channel, p, "bind", NULL, "hosts");
1752         }
1753         fclose(fp);
1754       }
1755       else {
1756         error = ERRNO;
1757         switch(error) {
1758         case ENOENT:
1759         case ESRCH:
1760           break;
1761         default:
1762           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1763                          error, strerror(error)));
1764           DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1765                          "/etc/host.conf"));
1766         }
1767
1768         /* ignore error, maybe we will get luck in next if clause */
1769         status = ARES_EOF;
1770       }
1771     }
1772
1773     if ((status == ARES_EOF) && (!channel->lookups)) {
1774       /* Tru64 uses /etc/svc.conf */
1775       fp = fopen("/etc/svc.conf", "r");
1776       if (fp) {
1777         while ((status = ares__read_line(fp, &line, &linesize)) ==
1778                ARES_SUCCESS)
1779         {
1780           if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1781             /* ignore errors */
1782             (void)config_lookup(channel, p, "bind", NULL, "local");
1783         }
1784         fclose(fp);
1785       }
1786       else {
1787         error = ERRNO;
1788         switch(error) {
1789         case ENOENT:
1790         case ESRCH:
1791           break;
1792         default:
1793           DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1794                          error, strerror(error)));
1795           DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1796         }
1797
1798         /* ignore error, default value will be chosen for `channel->lookups` */
1799         status = ARES_EOF;
1800       }
1801     }
1802
1803     if(line)
1804       ares_free(line);
1805   }
1806
1807 #endif
1808
1809   /* Handle errors. */
1810   if (status != ARES_EOF)
1811     {
1812       if (servers != NULL)
1813         ares_free(servers);
1814       if (sortlist != NULL)
1815         ares_free(sortlist);
1816       return status;
1817     }
1818
1819   /* If we got any name server entries, fill them in. */
1820   if (servers)
1821     {
1822       channel->servers = servers;
1823       channel->nservers = nservers;
1824     }
1825
1826   /* If we got any sortlist entries, fill them in. */
1827   if (sortlist)
1828     {
1829       channel->sortlist = sortlist;
1830       channel->nsort = nsort;
1831     }
1832
1833   return ARES_SUCCESS;
1834 }
1835
1836 static int init_by_defaults(ares_channel channel)
1837 {
1838   char *hostname = NULL;
1839   int rc = ARES_SUCCESS;
1840 #ifdef HAVE_GETHOSTNAME
1841   char *dot;
1842 #endif
1843
1844   if (channel->flags == -1)
1845     channel->flags = 0;
1846   if (channel->timeout == -1)
1847     channel->timeout = DEFAULT_TIMEOUT;
1848   if (channel->tries == -1)
1849     channel->tries = DEFAULT_TRIES;
1850   if (channel->ndots == -1)
1851     channel->ndots = 1;
1852   if (channel->rotate == -1)
1853     channel->rotate = 0;
1854   if (channel->udp_port == -1)
1855     channel->udp_port = htons(NAMESERVER_PORT);
1856   if (channel->tcp_port == -1)
1857     channel->tcp_port = htons(NAMESERVER_PORT);
1858
1859   if (channel->ednspsz == -1)
1860     channel->ednspsz = EDNSPACKETSZ;
1861
1862   if (channel->nservers == -1) {
1863     /* If nobody specified servers, try a local named. */
1864     channel->servers = ares_malloc(sizeof(struct server_state));
1865     if (!channel->servers) {
1866       rc = ARES_ENOMEM;
1867       goto error;
1868     }
1869     channel->servers[0].addr.family = AF_INET;
1870     channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1871     channel->servers[0].addr.udp_port = 0;
1872     channel->servers[0].addr.tcp_port = 0;
1873     channel->nservers = 1;
1874   }
1875
1876 #if defined(USE_WINSOCK)
1877 #define toolong(x) (x == -1) &&  (SOCKERRNO == WSAEFAULT)
1878 #elif defined(ENAMETOOLONG)
1879 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1880                                  (SOCKERRNO == EINVAL))
1881 #else
1882 #define toolong(x) (x == -1) &&  (SOCKERRNO == EINVAL)
1883 #endif
1884
1885   if (channel->ndomains == -1) {
1886     /* Derive a default domain search list from the kernel hostname,
1887      * or set it to empty if the hostname isn't helpful.
1888      */
1889 #ifndef HAVE_GETHOSTNAME
1890     channel->ndomains = 0; /* default to none */
1891 #else
1892     GETHOSTNAME_TYPE_ARG2 lenv = 64;
1893     size_t len = 64;
1894     int res;
1895     channel->ndomains = 0; /* default to none */
1896
1897     hostname = ares_malloc(len);
1898     if(!hostname) {
1899       rc = ARES_ENOMEM;
1900       goto error;
1901     }
1902
1903     do {
1904       res = gethostname(hostname, lenv);
1905
1906       if(toolong(res)) {
1907         char *p;
1908         len *= 2;
1909         lenv *= 2;
1910         p = ares_realloc(hostname, len);
1911         if(!p) {
1912           rc = ARES_ENOMEM;
1913           goto error;
1914         }
1915         hostname = p;
1916         continue;
1917       }
1918       else if(res) {
1919         /* Lets not treat a gethostname failure as critical, since we
1920          * are ok if gethostname doesn't even exist */
1921         *hostname = '\0';
1922         break;
1923       }
1924
1925     } while (res != 0);
1926
1927     dot = strchr(hostname, '.');
1928     if (dot) {
1929       /* a dot was found */
1930       channel->domains = ares_malloc(sizeof(char *));
1931       if (!channel->domains) {
1932         rc = ARES_ENOMEM;
1933         goto error;
1934       }
1935       channel->domains[0] = ares_strdup(dot + 1);
1936       if (!channel->domains[0]) {
1937         rc = ARES_ENOMEM;
1938         goto error;
1939       }
1940       channel->ndomains = 1;
1941     }
1942 #endif
1943   }
1944
1945   if (channel->nsort == -1) {
1946     channel->sortlist = NULL;
1947     channel->nsort = 0;
1948   }
1949
1950   if (!channel->lookups) {
1951     channel->lookups = ares_strdup("fb");
1952     if (!channel->lookups)
1953       rc = ARES_ENOMEM;
1954   }
1955
1956   error:
1957   if(rc) {
1958     if(channel->servers) {
1959       ares_free(channel->servers);
1960       channel->servers = NULL;
1961     }
1962
1963     if(channel->domains && channel->domains[0])
1964       ares_free(channel->domains[0]);
1965     if(channel->domains) {
1966       ares_free(channel->domains);
1967       channel->domains = NULL;
1968     }
1969
1970     if(channel->lookups) {
1971       ares_free(channel->lookups);
1972       channel->lookups = NULL;
1973     }
1974
1975     if(channel->resolvconf_path) {
1976       ares_free(channel->resolvconf_path);
1977       channel->resolvconf_path = NULL;
1978     }
1979   }
1980
1981   if(hostname)
1982     ares_free(hostname);
1983
1984   return rc;
1985 }
1986
1987 #if !defined(WIN32) && !defined(WATT32) && \
1988     !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1989 static int config_domain(ares_channel channel, char *str)
1990 {
1991   char *q;
1992
1993   /* Set a single search domain. */
1994   q = str;
1995   while (*q && !ISSPACE(*q))
1996     q++;
1997   *q = '\0';
1998   return set_search(channel, str);
1999 }
2000
2001 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
2002     defined(__OPTIMIZE__) && defined(__unix__) &&  defined(__i386__)
2003   /* workaround icc 9.1 optimizer issue */
2004 # define vqualifier volatile
2005 #else
2006 # define vqualifier
2007 #endif
2008
2009 static int config_lookup(ares_channel channel, const char *str,
2010                          const char *bindch, const char *altbindch,
2011                          const char *filech)
2012 {
2013   char lookups[3], *l;
2014   const char *vqualifier p;
2015   int found;
2016
2017   if (altbindch == NULL)
2018     altbindch = bindch;
2019
2020   /* Set the lookup order.  Only the first letter of each work
2021    * is relevant, and it has to be "b" for DNS or "f" for the
2022    * host file.  Ignore everything else.
2023    */
2024   l = lookups;
2025   p = str;
2026   found = 0;
2027   while (*p)
2028     {
2029       if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
2030         if (*p == *bindch || *p == *altbindch) *l++ = 'b';
2031         else *l++ = 'f';
2032         found = 1;
2033       }
2034       while (*p && !ISSPACE(*p) && (*p != ','))
2035         p++;
2036       while (*p && (ISSPACE(*p) || (*p == ',')))
2037         p++;
2038     }
2039   if (!found)
2040     return ARES_ENOTINITIALIZED;
2041   *l = '\0';
2042   channel->lookups = ares_strdup(lookups);
2043   return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
2044 }
2045 #endif  /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
2046
2047 #ifndef WATT32
2048 /* Validate that the ip address matches the subnet (network base and network
2049  * mask) specified. Addresses are specified in standard Network Byte Order as
2050  * 16 bytes, and the netmask is 0 to 128 (bits).
2051  */
2052 static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
2053                                     unsigned char netmask,
2054                                     const unsigned char ipaddr[16])
2055 {
2056   unsigned char mask[16] = { 0 };
2057   unsigned char i;
2058
2059   /* Misuse */
2060   if (netmask > 128)
2061     return 0;
2062
2063   /* Quickly set whole bytes */
2064   memset(mask, 0xFF, netmask / 8);
2065
2066   /* Set remaining bits */
2067   if(netmask % 8) {
2068     mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
2069   }
2070
2071   for (i=0; i<16; i++) {
2072     if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
2073       return 0;
2074   }
2075
2076   return 1;
2077 }
2078
2079 /* Return true iff the IPv6 ipaddr is blacklisted. */
2080 static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
2081 {
2082   /* A list of blacklisted IPv6 subnets. */
2083   const struct {
2084     const unsigned char netbase[16];
2085     unsigned char netmask;
2086   } blacklist[] = {
2087     /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
2088      * Site-Local scoped address prefix.  These are never valid DNS servers,
2089      * but are known to be returned at least sometimes on Windows and Android.
2090      */
2091     {
2092       {
2093         0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2094         0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2095       },
2096       10
2097     }
2098   };
2099   size_t i;
2100
2101   /* See if ipaddr matches any of the entries in the blacklist. */
2102   for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
2103     if (ares_ipv6_subnet_matches(
2104           blacklist[i].netbase, blacklist[i].netmask, ipaddr))
2105       return 1;
2106   }
2107   return 0;
2108 }
2109
2110 /* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
2111  * servers list, updating servers and nservers as required.
2112  *
2113  * This will silently ignore blacklisted IPv6 nameservers as detected by
2114  * ares_ipv6_server_blacklisted().
2115  *
2116  * Returns an error code on failure, else ARES_SUCCESS.
2117  */
2118 static int config_nameserver(struct server_state **servers, int *nservers,
2119                              char *str)
2120 {
2121   struct ares_addr host;
2122   struct server_state *newserv;
2123   char *p, *txtaddr;
2124   /* On Windows, there may be more than one nameserver specified in the same
2125    * registry key, so we parse input as a space or comma seperated list.
2126    */
2127   for (p = str; p;)
2128     {
2129       /* Skip whitespace and commas. */
2130       while (*p && (ISSPACE(*p) || (*p == ',')))
2131         p++;
2132       if (!*p)
2133         /* No more input, done. */
2134         break;
2135
2136       /* Pointer to start of IPv4 or IPv6 address part. */
2137       txtaddr = p;
2138
2139       /* Advance past this address. */
2140       while (*p && !ISSPACE(*p) && (*p != ','))
2141         p++;
2142       if (*p)
2143         /* Null terminate this address. */
2144         *p++ = '\0';
2145       else
2146         /* Reached end of input, done when this address is processed. */
2147         p = NULL;
2148
2149       /* Convert textual address to binary format. */
2150       if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
2151         host.family = AF_INET;
2152       else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1
2153                /* Silently skip blacklisted IPv6 servers. */
2154                && !ares_ipv6_server_blacklisted(
2155                     (const unsigned char *)&host.addrV6))
2156         host.family = AF_INET6;
2157       else
2158         continue;
2159
2160       /* Resize servers state array. */
2161       newserv = ares_realloc(*servers, (*nservers + 1) *
2162                              sizeof(struct server_state));
2163       if (!newserv)
2164         return ARES_ENOMEM;
2165
2166       /* Store address data. */
2167       newserv[*nservers].addr.family = host.family;
2168       newserv[*nservers].addr.udp_port = 0;
2169       newserv[*nservers].addr.tcp_port = 0;
2170       if (host.family == AF_INET)
2171         memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
2172                sizeof(host.addrV4));
2173       else
2174         memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
2175                sizeof(host.addrV6));
2176
2177       /* Update arguments. */
2178       *servers = newserv;
2179       *nservers += 1;
2180     }
2181
2182   return ARES_SUCCESS;
2183 }
2184 #endif  /* !WATT32 */
2185
2186 static int config_sortlist(struct apattern **sortlist, int *nsort,
2187                            const char *str)
2188 {
2189   struct apattern pat;
2190   const char *q;
2191
2192   /* Add sortlist entries. */
2193   while (*str && *str != ';')
2194     {
2195       int bits;
2196       char ipbuf[16], ipbufpfx[32];
2197       /* Find just the IP */
2198       q = str;
2199       while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
2200         q++;
2201       memcpy(ipbuf, str, q-str);
2202       ipbuf[q-str] = '\0';
2203       /* Find the prefix */
2204       if (*q == '/')
2205         {
2206           const char *str2 = q+1;
2207           while (*q && *q != ';' && !ISSPACE(*q))
2208             q++;
2209           memcpy(ipbufpfx, str, q-str);
2210           ipbufpfx[q-str] = '\0';
2211           str = str2;
2212         }
2213       else
2214         ipbufpfx[0] = '\0';
2215       /* Lets see if it is CIDR */
2216       /* First we'll try IPv6 */
2217       if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
2218                                      &pat.addrV6,
2219                                      sizeof(pat.addrV6))) > 0)
2220         {
2221           pat.type = PATTERN_CIDR;
2222           pat.mask.bits = (unsigned short)bits;
2223           pat.family = AF_INET6;
2224           if (!sortlist_alloc(sortlist, nsort, &pat)) {
2225             ares_free(*sortlist);
2226             *sortlist = NULL;
2227             return ARES_ENOMEM;
2228           }
2229         }
2230       else if (ipbufpfx[0] &&
2231                (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
2232                                           sizeof(pat.addrV4))) > 0)
2233         {
2234           pat.type = PATTERN_CIDR;
2235           pat.mask.bits = (unsigned short)bits;
2236           pat.family = AF_INET;
2237           if (!sortlist_alloc(sortlist, nsort, &pat)) {
2238             ares_free(*sortlist);
2239             *sortlist = NULL;
2240             return ARES_ENOMEM;
2241           }
2242         }
2243       /* See if it is just a regular IP */
2244       else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
2245         {
2246           if (ipbufpfx[0])
2247             {
2248               memcpy(ipbuf, str, q-str);
2249               ipbuf[q-str] = '\0';
2250               if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
2251                 natural_mask(&pat);
2252             }
2253           else
2254             natural_mask(&pat);
2255           pat.family = AF_INET;
2256           pat.type = PATTERN_MASK;
2257           if (!sortlist_alloc(sortlist, nsort, &pat)) {
2258             ares_free(*sortlist);
2259             *sortlist = NULL;
2260             return ARES_ENOMEM;
2261           }
2262         }
2263       else
2264         {
2265           while (*q && *q != ';' && !ISSPACE(*q))
2266             q++;
2267         }
2268       str = q;
2269       while (ISSPACE(*str))
2270         str++;
2271     }
2272
2273   return ARES_SUCCESS;
2274 }
2275
2276 static int set_search(ares_channel channel, const char *str)
2277 {
2278   size_t cnt;
2279
2280   if(channel->ndomains != -1) {
2281     /* LCOV_EXCL_START: all callers check ndomains == -1 */
2282     /* if we already have some domains present, free them first */
2283     ares_strsplit_free(channel->domains, channel->ndomains);
2284     channel->domains = NULL;
2285     channel->ndomains = -1;
2286   } /* LCOV_EXCL_STOP */
2287
2288   channel->domains  = ares_strsplit(str, ", ", 1, &cnt);
2289   channel->ndomains = (int)cnt;
2290   if (channel->domains == NULL || channel->ndomains == 0) {
2291     channel->domains  = NULL;
2292     channel->ndomains = -1;
2293   }
2294
2295   return ARES_SUCCESS;
2296 }
2297
2298 static int set_options(ares_channel channel, const char *str)
2299 {
2300   const char *p, *q, *val;
2301
2302   p = str;
2303   while (*p)
2304     {
2305       q = p;
2306       while (*q && !ISSPACE(*q))
2307         q++;
2308       val = try_option(p, q, "ndots:");
2309       if (val && channel->ndots == -1)
2310         channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
2311       val = try_option(p, q, "retrans:");
2312       if (val && channel->timeout == -1)
2313         channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
2314       val = try_option(p, q, "retry:");
2315       if (val && channel->tries == -1)
2316         channel->tries = aresx_sltosi(strtol(val, NULL, 10));
2317       val = try_option(p, q, "rotate");
2318       if (val && channel->rotate == -1)
2319         channel->rotate = 1;
2320       p = q;
2321       while (ISSPACE(*p))
2322         p++;
2323     }
2324
2325   return ARES_SUCCESS;
2326 }
2327
2328 static const char *try_option(const char *p, const char *q, const char *opt)
2329 {
2330   size_t len = strlen(opt);
2331   return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
2332 }
2333
2334 #if !defined(WIN32) && !defined(WATT32) && \
2335     !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
2336 static char *try_config(char *s, const char *opt, char scc)
2337 {
2338   size_t len;
2339   char *p;
2340   char *q;
2341
2342   if (!s || !opt)
2343     /* no line or no option */
2344     return NULL;  /* LCOV_EXCL_LINE */
2345
2346   /* Hash '#' character is always used as primary comment char, additionally
2347      a not-NUL secondary comment char will be considered when specified. */
2348
2349   /* trim line comment */
2350   p = s;
2351   if(scc)
2352     while (*p && (*p != '#') && (*p != scc))
2353       p++;
2354   else
2355     while (*p && (*p != '#'))
2356       p++;
2357   *p = '\0';
2358
2359   /* trim trailing whitespace */
2360   q = p - 1;
2361   while ((q >= s) && ISSPACE(*q))
2362     q--;
2363   *++q = '\0';
2364
2365   /* skip leading whitespace */
2366   p = s;
2367   while (*p && ISSPACE(*p))
2368     p++;
2369
2370   if (!*p)
2371     /* empty line */
2372     return NULL;
2373
2374   if ((len = strlen(opt)) == 0)
2375     /* empty option */
2376     return NULL;  /* LCOV_EXCL_LINE */
2377
2378   if (strncmp(p, opt, len) != 0)
2379     /* line and option do not match */
2380     return NULL;
2381
2382   /* skip over given option name */
2383   p += len;
2384
2385   if (!*p)
2386     /* no option value */
2387     return NULL;  /* LCOV_EXCL_LINE */
2388
2389   if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
2390     /* whitespace between option name and value is mandatory
2391        for given option names which do not end with ':' or '=' */
2392     return NULL;
2393
2394   /* skip over whitespace */
2395   while (*p && ISSPACE(*p))
2396     p++;
2397
2398   if (!*p)
2399     /* no option value */
2400     return NULL;
2401
2402   /* return pointer to option value */
2403   return p;
2404 }
2405 #endif  /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
2406
2407 static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
2408 {
2409
2410   /* Four octets and three periods yields at most 15 characters. */
2411   if (len > 15)
2412     return -1;
2413
2414   if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
2415     return -1;
2416
2417   return 0;
2418 }
2419
2420 static void natural_mask(struct apattern *pat)
2421 {
2422   struct in_addr addr;
2423
2424   /* Store a host-byte-order copy of pat in a struct in_addr.  Icky,
2425    * but portable.
2426    */
2427   addr.s_addr = ntohl(pat->addrV4.s_addr);
2428
2429   /* This is out of date in the CIDR world, but some people might
2430    * still rely on it.
2431    */
2432   if (IN_CLASSA(addr.s_addr))
2433     pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
2434   else if (IN_CLASSB(addr.s_addr))
2435     pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
2436   else
2437     pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
2438 }
2439
2440 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
2441                           struct apattern *pat)
2442 {
2443   struct apattern *newsort;
2444   newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
2445   if (!newsort)
2446     return 0;
2447   newsort[*nsort] = *pat;
2448   *sortlist = newsort;
2449   (*nsort)++;
2450   return 1;
2451 }
2452
2453 /* initialize an rc4 key. If possible a cryptographically secure random key
2454    is generated using a suitable function (for example win32's RtlGenRandom as
2455    described in
2456    http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
2457    otherwise the code defaults to cross-platform albeit less secure mechanism
2458    using rand
2459 */
2460 static void randomize_key(unsigned char* key,int key_data_len)
2461 {
2462   int randomized = 0;
2463   int counter=0;
2464 #ifdef WIN32
2465   BOOLEAN res;
2466   if (ares_fpSystemFunction036)
2467     {
2468       res = (*ares_fpSystemFunction036) (key, key_data_len);
2469       if (res)
2470         randomized = 1;
2471     }
2472 #else /* !WIN32 */
2473 #ifdef RANDOM_FILE
2474   FILE *f = fopen(RANDOM_FILE, "rb");
2475   if(f) {
2476     counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2477     fclose(f);
2478   }
2479 #endif
2480 #endif /* WIN32 */
2481
2482   if (!randomized) {
2483     for (;counter<key_data_len;counter++)
2484       key[counter]=(unsigned char)(rand() % 256);  /* LCOV_EXCL_LINE */
2485   }
2486 }
2487
2488 static int init_id_key(rc4_key* key,int key_data_len)
2489 {
2490   unsigned char index1;
2491   unsigned char index2;
2492   unsigned char* state;
2493   short counter;
2494   unsigned char *key_data_ptr = 0;
2495
2496   key_data_ptr = ares_malloc(key_data_len);
2497   if (!key_data_ptr)
2498     return ARES_ENOMEM;
2499   memset(key_data_ptr, 0, key_data_len);
2500
2501   state = &key->state[0];
2502   for(counter = 0; counter < 256; counter++)
2503     /* unnecessary AND but it keeps some compilers happier */
2504     state[counter] = (unsigned char)(counter & 0xff);
2505   randomize_key(key->state,key_data_len);
2506   key->x = 0;
2507   key->y = 0;
2508   index1 = 0;
2509   index2 = 0;
2510   for(counter = 0; counter < 256; counter++)
2511   {
2512     index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2513                               index2) % 256);
2514     ARES_SWAP_BYTE(&state[counter], &state[index2]);
2515
2516     index1 = (unsigned char)((index1 + 1) % key_data_len);
2517   }
2518   ares_free(key_data_ptr);
2519   return ARES_SUCCESS;
2520 }
2521
2522 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2523 {
2524   channel->local_ip4 = local_ip;
2525 }
2526
2527 /* local_ip6 should be 16 bytes in length */
2528 void ares_set_local_ip6(ares_channel channel,
2529                         const unsigned char* local_ip6)
2530 {
2531   memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2532 }
2533
2534 /* local_dev_name should be null terminated. */
2535 void ares_set_local_dev(ares_channel channel,
2536                         const char* local_dev_name)
2537 {
2538   strncpy(channel->local_dev_name, local_dev_name,
2539           sizeof(channel->local_dev_name));
2540   channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
2541 }
2542
2543
2544 void ares_set_socket_callback(ares_channel channel,
2545                               ares_sock_create_callback cb,
2546                               void *data)
2547 {
2548   channel->sock_create_cb = cb;
2549   channel->sock_create_cb_data = data;
2550 }
2551
2552 void ares_set_socket_configure_callback(ares_channel channel,
2553                                         ares_sock_config_callback cb,
2554                                         void *data)
2555 {
2556   channel->sock_config_cb = cb;
2557   channel->sock_config_cb_data = data;
2558 }
2559
2560 void ares_set_socket_functions(ares_channel channel,
2561                                const struct ares_socket_functions * funcs,
2562                                void *data)
2563 {
2564   channel->sock_funcs = funcs;
2565   channel->sock_func_cb_data = data;
2566 }
2567
2568 int ares_set_sortlist(ares_channel channel, const char *sortstr)
2569 {
2570   int nsort = 0;
2571   struct apattern *sortlist = NULL;
2572   int status;
2573
2574   if (!channel)
2575     return ARES_ENODATA;
2576
2577   status = config_sortlist(&sortlist, &nsort, sortstr);
2578   if (status == ARES_SUCCESS && sortlist) {
2579     if (channel->sortlist)
2580       ares_free(channel->sortlist);
2581     channel->sortlist = sortlist;
2582     channel->nsort = nsort;
2583   }
2584   return status;
2585 }
2586
2587 void ares__init_servers_state(ares_channel channel)
2588 {
2589   struct server_state *server;
2590   int i;
2591
2592   for (i = 0; i < channel->nservers; i++)
2593     {
2594       server = &channel->servers[i];
2595       server->udp_socket = ARES_SOCKET_BAD;
2596       server->tcp_socket = ARES_SOCKET_BAD;
2597       server->tcp_connection_generation = ++channel->tcp_connection_generation;
2598       server->tcp_lenbuf_pos = 0;
2599       server->tcp_buffer_pos = 0;
2600       server->tcp_buffer = NULL;
2601       server->tcp_length = 0;
2602       server->qhead = NULL;
2603       server->qtail = NULL;
2604       ares__init_list_head(&server->queries_to_server);
2605       server->channel = channel;
2606       server->is_broken = 0;
2607     }
2608 }