2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Copyright (C) 2007-2013 by Daniel Stenberg
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.
18 #include "ares_setup.h"
20 #ifdef HAVE_SYS_PARAM_H
21 #include <sys/param.h>
24 #ifdef HAVE_NETINET_IN_H
25 #include <netinet/in.h>
32 #ifdef HAVE_ARPA_INET_H
33 #include <arpa/inet.h>
36 #ifdef HAVE_ARPA_NAMESER_H
37 # include <arpa/nameser.h>
41 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
42 # include <arpa/nameser_compat.h>
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
53 #if defined(CARES_USE_LIBRESOLV)
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"
65 #undef WIN32 /* Redefined in MingW/MSVC headers */
68 static int init_by_options(ares_channel channel,
69 const struct ares_options *options,
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);
76 static int config_nameserver(struct server_state **servers, int *nservers,
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);
84 static int config_sortlist(struct apattern **sortlist, int *nsort,
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,
96 static char *try_config(char *s, const char *opt, char scc);
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 && \
105 int ares_init(ares_channel *channelptr)
107 return ares_init_options(channelptr, NULL, 0);
110 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
113 ares_channel channel;
115 int status = ARES_SUCCESS;
119 const char *env = getenv("CARES_MEMDEBUG");
123 env = getenv("CARES_MEMLIMIT");
126 long num = strtol(env, &endptr, 10);
127 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
132 if (ares_library_initialized() != ARES_SUCCESS)
133 return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
135 channel = ares_malloc(sizeof(struct ares_channeldata));
143 /* Set everything to distinguished values so we know they haven't
147 channel->timeout = -1;
150 channel->rotate = -1;
151 channel->udp_port = -1;
152 channel->tcp_port = -1;
153 channel->ednspsz = -1;
154 channel->socket_send_buffer_size = -1;
155 channel->socket_receive_buffer_size = -1;
156 channel->nservers = -1;
157 channel->ndomains = -1;
159 channel->tcp_connection_generation = 0;
160 channel->lookups = NULL;
161 channel->domains = NULL;
162 channel->sortlist = NULL;
163 channel->servers = NULL;
164 channel->sock_state_cb = NULL;
165 channel->sock_state_cb_data = NULL;
166 channel->sock_create_cb = NULL;
167 channel->sock_create_cb_data = NULL;
168 channel->sock_config_cb = NULL;
169 channel->sock_config_cb_data = NULL;
170 channel->sock_funcs = NULL;
171 channel->sock_func_cb_data = NULL;
172 channel->resolvconf_path = NULL;
174 channel->last_server = 0;
175 channel->last_timeout_processed = (time_t)now.tv_sec;
177 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
178 channel->local_ip4 = 0;
179 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
181 /* Initialize our lists of queries */
182 ares__init_list_head(&(channel->all_queries));
183 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
185 ares__init_list_head(&(channel->queries_by_qid[i]));
187 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
189 ares__init_list_head(&(channel->queries_by_timeout[i]));
192 /* Initialize configuration by each of the four sources, from highest
193 * precedence to lowest.
196 status = init_by_options(channel, options, optmask);
197 if (status != ARES_SUCCESS) {
198 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
199 ares_strerror(status)));
200 /* If we fail to apply user-specified options, fail the whole init process */
203 status = init_by_environment(channel);
204 if (status != ARES_SUCCESS)
205 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
206 ares_strerror(status)));
207 if (status == ARES_SUCCESS) {
208 status = init_by_resolv_conf(channel);
209 if (status != ARES_SUCCESS)
210 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
211 ares_strerror(status)));
215 * No matter what failed or succeeded, seed defaults to provide
216 * useful behavior for things that we missed.
218 status = init_by_defaults(channel);
219 if (status != ARES_SUCCESS)
220 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
221 ares_strerror(status)));
223 /* Generate random key */
225 if (status == ARES_SUCCESS) {
226 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
227 if (status == ARES_SUCCESS)
228 channel->next_id = ares__generate_new_id(&channel->id_key);
230 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
231 ares_strerror(status)));
235 if (status != ARES_SUCCESS)
237 /* Something failed; clean up memory we may have allocated. */
238 if (channel->servers)
239 ares_free(channel->servers);
240 if (channel->ndomains != -1)
241 ares_strsplit_free(channel->domains, channel->ndomains);
242 if (channel->sortlist)
243 ares_free(channel->sortlist);
245 ares_free(channel->lookups);
246 if(channel->resolvconf_path)
247 ares_free(channel->resolvconf_path);
252 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
253 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
254 channel->nservers = 1;
256 ares__init_servers_state(channel);
258 *channelptr = channel;
262 /* ares_dup() duplicates a channel handle with all its options and returns a
263 new channel handle */
264 int ares_dup(ares_channel *dest, ares_channel src)
266 struct ares_options opts;
267 struct ares_addr_port_node *servers;
268 int non_v4_default_port = 0;
272 *dest = NULL; /* in case of failure return NULL explicitly */
274 /* First get the options supported by the old ares_save_options() function,
275 which is most of them */
276 rc = ares_save_options(src, &opts, &optmask);
279 ares_destroy_options(&opts);
283 /* Then create the new channel with those options */
284 rc = ares_init_options(dest, &opts, optmask);
286 /* destroy the options copy to not leak any memory */
287 ares_destroy_options(&opts);
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 (*dest)->sock_config_cb = src->sock_config_cb;
296 (*dest)->sock_config_cb_data = src->sock_config_cb_data;
297 (*dest)->sock_funcs = src->sock_funcs;
298 (*dest)->sock_func_cb_data = src->sock_func_cb_data;
300 strncpy((*dest)->local_dev_name, src->local_dev_name,
301 sizeof((*dest)->local_dev_name));
302 (*dest)->local_ip4 = src->local_ip4;
303 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
305 /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
306 for (i = 0; i < src->nservers; i++)
308 if ((src->servers[i].addr.family != AF_INET) ||
309 (src->servers[i].addr.udp_port != 0) ||
310 (src->servers[i].addr.tcp_port != 0)) {
311 non_v4_default_port++;
315 if (non_v4_default_port) {
316 rc = ares_get_servers_ports(src, &servers);
317 if (rc != ARES_SUCCESS) {
322 rc = ares_set_servers_ports(*dest, servers);
323 ares_free_data(servers);
324 if (rc != ARES_SUCCESS) {
331 return ARES_SUCCESS; /* everything went fine */
334 /* Save options from initialized channel */
335 int ares_save_options(ares_channel channel, struct ares_options *options,
339 int ipv4_nservers = 0;
341 /* Zero everything out */
342 memset(options, 0, sizeof(struct ares_options));
344 if (!ARES_CONFIG_CHECK(channel))
347 /* Traditionally the optmask wasn't saved in the channel struct so it was
348 recreated here. ROTATE is the first option that has no struct field of
349 its own in the public config struct */
350 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
351 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
352 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
353 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
354 (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
356 if (channel->resolvconf_path)
357 (*optmask) |= ARES_OPT_RESOLVCONF;
359 /* Copy easy stuff */
360 options->flags = channel->flags;
362 /* We return full millisecond resolution but that's only because we don't
363 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
364 options->timeout = channel->timeout;
365 options->tries = channel->tries;
366 options->ndots = channel->ndots;
367 options->udp_port = ntohs(aresx_sitous(channel->udp_port));
368 options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
369 options->sock_state_cb = channel->sock_state_cb;
370 options->sock_state_cb_data = channel->sock_state_cb_data;
372 /* Copy IPv4 servers that use the default port */
373 if (channel->nservers) {
374 for (i = 0; i < channel->nservers; i++)
376 if ((channel->servers[i].addr.family == AF_INET) &&
377 (channel->servers[i].addr.udp_port == 0) &&
378 (channel->servers[i].addr.tcp_port == 0))
382 options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
383 if (!options->servers)
385 for (i = j = 0; i < channel->nservers; i++)
387 if ((channel->servers[i].addr.family == AF_INET) &&
388 (channel->servers[i].addr.udp_port == 0) &&
389 (channel->servers[i].addr.tcp_port == 0))
390 memcpy(&options->servers[j++],
391 &channel->servers[i].addr.addrV4,
392 sizeof(channel->servers[i].addr.addrV4));
396 options->nservers = ipv4_nservers;
399 if (channel->ndomains) {
400 options->domains = ares_malloc(channel->ndomains * sizeof(char *));
401 if (!options->domains)
404 for (i = 0; i < channel->ndomains; i++)
406 options->ndomains = i;
407 options->domains[i] = ares_strdup(channel->domains[i]);
408 if (!options->domains[i])
412 options->ndomains = channel->ndomains;
415 if (channel->lookups) {
416 options->lookups = ares_strdup(channel->lookups);
417 if (!options->lookups && channel->lookups)
422 if (channel->nsort) {
423 options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
424 if (!options->sortlist)
426 for (i = 0; i < channel->nsort; i++)
427 options->sortlist[i] = channel->sortlist[i];
429 options->nsort = channel->nsort;
431 /* copy path for resolv.conf file */
432 if (channel->resolvconf_path) {
433 options->resolvconf_path = ares_strdup(channel->resolvconf_path);
434 if (!options->resolvconf_path)
441 static int init_by_options(ares_channel channel,
442 const struct ares_options *options,
448 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
449 channel->flags = options->flags;
450 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
451 channel->timeout = options->timeout;
452 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
453 channel->timeout = options->timeout * 1000;
454 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
455 channel->tries = options->tries;
456 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
457 channel->ndots = options->ndots;
458 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
460 if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
462 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
463 channel->udp_port = htons(options->udp_port);
464 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
465 channel->tcp_port = htons(options->tcp_port);
466 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
468 channel->sock_state_cb = options->sock_state_cb;
469 channel->sock_state_cb_data = options->sock_state_cb_data;
471 if ((optmask & ARES_OPT_SOCK_SNDBUF)
472 && channel->socket_send_buffer_size == -1)
473 channel->socket_send_buffer_size = options->socket_send_buffer_size;
474 if ((optmask & ARES_OPT_SOCK_RCVBUF)
475 && channel->socket_receive_buffer_size == -1)
476 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
478 if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
479 channel->ednspsz = options->ednspsz;
481 /* Copy the IPv4 servers, if given. */
482 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
484 /* Avoid zero size allocations at any cost */
485 if (options->nservers > 0)
488 ares_malloc(options->nservers * sizeof(struct server_state));
489 if (!channel->servers)
491 for (i = 0; i < options->nservers; i++)
493 channel->servers[i].addr.family = AF_INET;
494 channel->servers[i].addr.udp_port = 0;
495 channel->servers[i].addr.tcp_port = 0;
496 memcpy(&channel->servers[i].addr.addrV4,
497 &options->servers[i],
498 sizeof(channel->servers[i].addr.addrV4));
501 channel->nservers = options->nservers;
504 /* Copy the domains, if given. Keep channel->ndomains consistent so
505 * we can clean up in case of error.
507 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
509 /* Avoid zero size allocations at any cost */
510 if (options->ndomains > 0)
512 channel->domains = ares_malloc(options->ndomains * sizeof(char *));
513 if (!channel->domains)
515 for (i = 0; i < options->ndomains; i++)
517 channel->ndomains = i;
518 channel->domains[i] = ares_strdup(options->domains[i]);
519 if (!channel->domains[i])
523 channel->ndomains = options->ndomains;
526 /* Set lookups, if given. */
527 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
529 channel->lookups = ares_strdup(options->lookups);
530 if (!channel->lookups)
535 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1)) {
536 if (options->nsort > 0) {
537 channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
538 if (!channel->sortlist)
540 for (i = 0; i < options->nsort; i++)
541 channel->sortlist[i] = options->sortlist[i];
543 channel->nsort = options->nsort;
546 /* Set path for resolv.conf file, if given. */
547 if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
549 channel->resolvconf_path = ares_strdup(options->resolvconf_path);
550 if (!channel->resolvconf_path && options->resolvconf_path)
554 channel->optmask = optmask;
559 static int init_by_environment(ares_channel channel)
561 const char *localdomain, *res_options;
564 localdomain = getenv("LOCALDOMAIN");
565 if (localdomain && channel->ndomains == -1)
567 status = set_search(channel, localdomain);
568 if (status != ARES_SUCCESS)
572 res_options = getenv("RES_OPTIONS");
575 status = set_options(channel, res_options);
576 if (status != ARES_SUCCESS)
577 return status; /* LCOV_EXCL_LINE: set_options() never fails */
587 * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
588 * to the name of the registry leaf key to be queried, fetch it's string
589 * value and return a pointer in *outptr to a newly allocated memory area
590 * holding it as a null-terminated string.
592 * Returns 0 and nullifies *outptr upon inability to return a string value.
594 * Returns 1 and sets *outptr when returning a dynamically allocated string.
596 * Supported on Windows NT 3.5 and newer.
598 static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
605 /* Find out size of string stored in registry */
606 res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size);
607 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
610 /* Allocate buffer of indicated size plus one given that string
611 might have been stored without null termination */
612 *outptr = ares_malloc(size+1);
616 /* Get the value for real */
617 res = RegQueryValueExA(hKey, leafKeyName, 0, NULL,
618 (unsigned char *)*outptr, &size);
619 if ((res != ERROR_SUCCESS) || (size == 1))
626 /* Null terminate buffer allways */
627 *(*outptr + size) = '\0';
635 * Functionally identical to get_REG_SZ()
637 * Supported on Windows 95, 98 and ME.
639 static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
647 /* Find out size of string stored in registry */
648 res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, NULL, &size);
649 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
652 /* Allocate buffer of indicated size plus one given that string
653 might have been stored without null termination */
654 *outptr = ares_malloc(size+1);
658 /* Get the value for real */
659 res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType,
660 (unsigned char *)*outptr, &size);
661 if ((res != ERROR_SUCCESS) || (size == 1))
668 /* Null terminate buffer allways */
669 *(*outptr + size) = '\0';
677 * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
678 * pointer to the name of the registry leaf key to be queried, parent key
679 * is enumerated searching in child keys for given leaf key name and its
680 * associated string value. When located, this returns a pointer in *outptr
681 * to a newly allocated memory area holding it as a null-terminated string.
683 * Returns 0 and nullifies *outptr upon inability to return a string value.
685 * Returns 1 and sets *outptr when returning a dynamically allocated string.
687 * Supported on Windows NT 3.5 and newer.
689 static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
692 char enumKeyName[256];
693 DWORD enumKeyNameBuffSize;
694 DWORD enumKeyIdx = 0;
703 enumKeyNameBuffSize = sizeof(enumKeyName);
704 res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName,
705 &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
706 if (res != ERROR_SUCCESS)
708 res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
710 if (res != ERROR_SUCCESS)
712 gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
713 RegCloseKey(hKeyEnum);
725 * get_DNS_Registry_9X()
727 * Functionally identical to get_DNS_Registry()
729 * Implementation supports Windows 95, 98 and ME.
731 static int get_DNS_Registry_9X(char **outptr)
739 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
741 if (res != ERROR_SUCCESS)
744 gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
745 RegCloseKey(hKey_VxD_MStcp);
747 if (!gotString || !*outptr)
754 * get_DNS_Registry_NT()
756 * Functionally identical to get_DNS_Registry()
758 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
760 * Implementation supports Windows NT 3.5 and newer.
762 static int get_DNS_Registry_NT(char **outptr)
764 HKEY hKey_Interfaces = NULL;
765 HKEY hKey_Tcpip_Parameters;
771 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
772 &hKey_Tcpip_Parameters);
773 if (res != ERROR_SUCCESS)
777 ** Global DNS settings override adapter specific parameters when both
778 ** are set. Additionally static DNS settings override DHCP-configured
779 ** parameters when both are set.
782 /* Global DNS static parameters */
783 gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
787 /* Global DNS DHCP-configured parameters */
788 gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
792 /* Try adapter specific parameters */
793 res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0,
794 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
796 if (res != ERROR_SUCCESS)
798 hKey_Interfaces = NULL;
802 /* Adapter specific DNS static parameters */
803 gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
807 /* Adapter specific DNS DHCP-configured parameters */
808 gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
812 RegCloseKey(hKey_Interfaces);
814 RegCloseKey(hKey_Tcpip_Parameters);
816 if (!gotString || !*outptr)
825 * Locates DNS info in the registry. When located, this returns a pointer
826 * in *outptr to a newly allocated memory area holding a null-terminated
827 * string with a space or comma seperated list of DNS IP addresses.
829 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
831 * Returns 1 and sets *outptr when returning a dynamically allocated string.
833 static int get_DNS_Registry(char **outptr)
835 win_platform platform;
840 platform = ares__getplatform();
842 if (platform == WIN_NT)
843 gotString = get_DNS_Registry_NT(outptr);
844 else if (platform == WIN_9X)
845 gotString = get_DNS_Registry_9X(outptr);
853 static void commanjoin(char** dst, const char* const src, const size_t len)
858 /* 1 for terminating 0 and 2 for , and terminating 0 */
859 newsize = len + (*dst ? (strlen(*dst) + 2) : 1);
860 newbuf = ares_realloc(*dst, newsize);
866 if (strlen(*dst) != 0)
868 strncat(*dst, src, len);
876 static void commajoin(char **dst, const char *src)
878 commanjoin(dst, src, strlen(src));
882 * get_DNS_NetworkParams()
884 * Locates DNS info using GetNetworkParams() function from the Internet
885 * Protocol Helper (IP Helper) API. When located, this returns a pointer
886 * in *outptr to a newly allocated memory area holding a null-terminated
887 * string with a space or comma seperated list of DNS IP addresses.
889 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
891 * Returns 1 and sets *outptr when returning a dynamically allocated string.
893 * Implementation supports Windows 98 and newer.
895 * Note: Ancient PSDK required in order to build a W98 target.
897 static int get_DNS_NetworkParams(char **outptr)
899 FIXED_INFO *fi, *newfi;
900 struct ares_addr namesrvr;
902 IP_ADDR_STRING *ipAddr;
904 DWORD size = sizeof (*fi);
908 /* Verify run-time availability of GetNetworkParams() */
909 if (ares_fpGetNetworkParams == ZERO_NULL)
912 fi = ares_malloc(size);
916 res = (*ares_fpGetNetworkParams) (fi, &size);
917 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
920 newfi = ares_realloc(fi, size);
925 res = (*ares_fpGetNetworkParams) (fi, &size);
926 if (res != ERROR_SUCCESS)
929 for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
931 txtaddr = &ipAddr->IpAddress.String[0];
933 /* Validate converting textual address to binary format. */
934 if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
936 if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
937 (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
940 else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
942 if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
943 sizeof(namesrvr.addrV6)) == 0)
949 commajoin(outptr, txtaddr);
965 static BOOL ares_IsWindowsVistaOrGreater(void)
968 memset(&vinfo, 0, sizeof(vinfo));
969 vinfo.dwOSVersionInfoSize = sizeof(vinfo);
971 #pragma warning(push)
972 #pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */
974 if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
982 /* A structure to hold the string form of IPv4 and IPv6 addresses so we can
983 * sort them by a metric.
987 /* The metric we sort them by. */
990 /* Original index of the item, used as a secondary sort parameter to make
991 * qsort() stable if the metrics are equal */
994 /* Room enough for the string form of any IPv4 or IPv6 address that
995 * ares_inet_ntop() will create. Based on the existing c-ares practice.
997 char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
1000 /* Sort Address values \a left and \a right by metric, returning the usual
1001 * indicators for qsort().
1003 static int compareAddresses(const void *arg1,
1006 const Address * const left = arg1;
1007 const Address * const right = arg2;
1008 /* Lower metric the more preferred */
1009 if(left->metric < right->metric) return -1;
1010 if(left->metric > right->metric) return 1;
1011 /* If metrics are equal, lower original index more preferred */
1012 if(left->orig_idx < right->orig_idx) return -1;
1013 if(left->orig_idx > right->orig_idx) return 1;
1017 /* There can be multiple routes to "the Internet". And there can be different
1018 * DNS servers associated with each of the interfaces that offer those routes.
1019 * We have to assume that any DNS server can serve any request. But, some DNS
1020 * servers may only respond if requested over their associated interface. But
1021 * we also want to use "the preferred route to the Internet" whenever possible
1022 * (and not use DNS servers on a non-preferred route even by forcing request
1023 * to go out on the associated non-preferred interface). i.e. We want to use
1024 * the DNS servers associated with the same interface that we would use to
1025 * make a general request to anything else.
1027 * But, Windows won't sort the DNS servers by the metrics associated with the
1028 * routes and interfaces _even_ though it obviously sends IP packets based on
1029 * those same routes and metrics. So, we must do it ourselves.
1031 * So, we sort the DNS servers by the same metric values used to determine how
1032 * an outgoing IP packet will go, thus effectively using the DNS servers
1033 * associated with the interface that the DNS requests themselves will
1034 * travel. This gives us optimal routing and avoids issues where DNS servers
1035 * won't respond to requests that don't arrive via some specific subnetwork
1036 * (and thus some specific interface).
1038 * This function computes the metric we use to sort. On the interface
1039 * identified by \a luid, it determines the best route to \a dest and combines
1040 * that route's metric with \a interfaceMetric to compute a metric for the
1041 * destination address on that interface. This metric can be used as a weight
1042 * to sort the DNS server addresses associated with each interface (lower is
1045 * Note that by restricting the route search to the specific interface with
1046 * which the DNS servers are associated, this function asks the question "What
1047 * is the metric for sending IP packets to this DNS server?" which allows us
1048 * to sort the DNS servers correctly.
1050 static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
1051 const SOCKADDR_INET * const dest,
1052 const ULONG interfaceMetric)
1054 /* On this interface, get the best route to that destination. */
1055 MIB_IPFORWARD_ROW2 row;
1056 SOCKADDR_INET ignored;
1057 if(!ares_fpGetBestRoute2 ||
1058 ares_fpGetBestRoute2(/* The interface to use. The index is ignored since we are
1062 /* No specific source address. */
1064 /* Our destination address. */
1068 /* The route row. */
1070 /* The best source address, which we don't need. */
1071 &ignored) != NO_ERROR
1072 /* If the metric is "unused" (-1) or too large for us to add the two
1073 * metrics, use the worst possible, thus sorting this last.
1075 || row.Metric == (ULONG)-1
1076 || row.Metric > ((ULONG)-1) - interfaceMetric) {
1077 /* Return the worst possible metric. */
1081 /* Return the metric value from that row, plus the interface metric.
1084 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
1085 * which describes the combination as a "sum".
1087 return row.Metric + interfaceMetric;
1091 * get_DNS_AdaptersAddresses()
1093 * Locates DNS info using GetAdaptersAddresses() function from the Internet
1094 * Protocol Helper (IP Helper) API. When located, this returns a pointer
1095 * in *outptr to a newly allocated memory area holding a null-terminated
1096 * string with a space or comma seperated list of DNS IP addresses.
1098 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1100 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1102 * Implementation supports Windows XP and newer.
1104 #define IPAA_INITIAL_BUF_SZ 15 * 1024
1105 #define IPAA_MAX_TRIES 3
1106 static int get_DNS_AdaptersAddresses(char **outptr)
1108 IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
1109 IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
1110 ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
1111 ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
1112 ULONG AddrFlags = 0;
1113 int trying = IPAA_MAX_TRIES;
1116 /* The capacity of addresses, in elements. */
1117 size_t addressesSize;
1118 /* The number of elements in addresses. */
1119 size_t addressesIndex = 0;
1120 /* The addresses we will sort. */
1124 struct sockaddr *sa;
1125 struct sockaddr_in *sa4;
1126 struct sockaddr_in6 *sa6;
1131 /* Verify run-time availability of GetAdaptersAddresses() */
1132 if (ares_fpGetAdaptersAddresses == ZERO_NULL)
1135 ipaa = ares_malloc(Bufsz);
1139 /* Start with enough room for a few DNS server addresses and we'll grow it
1140 * as we encounter more.
1143 addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
1144 if(addresses == NULL) {
1145 /* We need room for at least some addresses to function. */
1150 /* Usually this call suceeds with initial buffer size */
1151 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1153 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
1156 while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
1158 if (Bufsz < ReqBufsz)
1160 newipaa = ares_realloc(ipaa, ReqBufsz);
1166 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1168 if (res == ERROR_SUCCESS)
1171 if (res != ERROR_SUCCESS)
1174 for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1176 if(ipaaEntry->OperStatus != IfOperStatusUp)
1179 /* For each interface, find any associated DNS servers as IPv4 or IPv6
1180 * addresses. For each found address, find the best route to that DNS
1181 * server address _on_ _that_ _interface_ (at this moment in time) and
1182 * compute the resulting total metric, just as Windows routing will do.
1183 * Then, sort all the addresses found by the metric.
1185 for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1187 ipaDNSAddr = ipaDNSAddr->Next)
1189 namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1191 if (namesrvr.sa->sa_family == AF_INET)
1193 if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1194 (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
1197 /* Allocate room for another address, if necessary, else skip. */
1198 if(addressesIndex == addressesSize) {
1199 const size_t newSize = addressesSize + 4;
1200 Address * const newMem =
1201 (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
1202 if(newMem == NULL) {
1206 addressesSize = newSize;
1209 /* Vista required for Luid or Ipv4Metric */
1210 if (ares_IsWindowsVistaOrGreater())
1212 /* Save the address as the next element in addresses. */
1213 addresses[addressesIndex].metric =
1214 getBestRouteMetric(&ipaaEntry->Luid,
1215 (SOCKADDR_INET*)(namesrvr.sa),
1216 ipaaEntry->Ipv4Metric);
1220 addresses[addressesIndex].metric = (ULONG)-1;
1223 /* Record insertion index to make qsort stable */
1224 addresses[addressesIndex].orig_idx = addressesIndex;
1226 if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1227 addresses[addressesIndex].text,
1228 sizeof(addresses[0].text))) {
1233 else if (namesrvr.sa->sa_family == AF_INET6)
1235 if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1236 sizeof(namesrvr.sa6->sin6_addr)) == 0)
1239 /* Allocate room for another address, if necessary, else skip. */
1240 if(addressesIndex == addressesSize) {
1241 const size_t newSize = addressesSize + 4;
1242 Address * const newMem =
1243 (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
1244 if(newMem == NULL) {
1248 addressesSize = newSize;
1251 /* Vista required for Luid or Ipv4Metric */
1252 if (ares_IsWindowsVistaOrGreater())
1254 /* Save the address as the next element in addresses. */
1255 addresses[addressesIndex].metric =
1256 getBestRouteMetric(&ipaaEntry->Luid,
1257 (SOCKADDR_INET*)(namesrvr.sa),
1258 ipaaEntry->Ipv6Metric);
1262 addresses[addressesIndex].metric = (ULONG)-1;
1265 /* Record insertion index to make qsort stable */
1266 addresses[addressesIndex].orig_idx = addressesIndex;
1268 if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1269 addresses[addressesIndex].text,
1270 sizeof(addresses[0].text))) {
1276 /* Skip non-IPv4/IPv6 addresses completely. */
1282 /* Sort all of the textual addresses by their metric (and original index if
1283 * metrics are equal). */
1284 qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses);
1286 /* Join them all into a single string, removing duplicates. */
1289 for(i = 0; i < addressesIndex; ++i) {
1291 /* Look for this address text appearing previously in the results. */
1292 for(j = 0; j < i; ++j) {
1293 if(strcmp(addresses[j].text, addresses[i].text) == 0) {
1297 /* Iff we didn't emit this address already, emit it now. */
1299 /* Add that to outptr (if we can). */
1300 commajoin(outptr, addresses[i].text);
1306 ares_free(addresses);
1321 * Locates DNS info from Windows employing most suitable methods available at
1322 * run-time no matter which Windows version it is. When located, this returns
1323 * a pointer in *outptr to a newly allocated memory area holding a string with
1324 * a space or comma seperated list of DNS IP addresses, null-terminated.
1326 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1328 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1330 * Implementation supports Windows 95 and newer.
1332 static int get_DNS_Windows(char **outptr)
1334 /* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts
1335 * DNS servers by interface route metrics to try to use the best DNS server. */
1336 if (get_DNS_AdaptersAddresses(outptr))
1339 /* Try using IP helper API GetNetworkParams(). IPv4 only. */
1340 if (get_DNS_NetworkParams(outptr))
1343 /* Fall-back to registry information */
1344 return get_DNS_Registry(outptr);
1348 * get_SuffixList_Windows()
1350 * Reads the "DNS Suffix Search List" from registry and writes the list items
1351 * whitespace separated to outptr. If the Search List is empty, the
1352 * "Primary Dns Suffix" is written to outptr.
1354 * Returns 0 and nullifies *outptr upon inability to return the suffix list.
1356 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1358 * Implementation supports Windows Server 2003 and newer
1360 static int get_SuffixList_Windows(char **outptr)
1362 HKEY hKey, hKeyEnum;
1364 DWORD keyNameBuffSize;
1370 if (ares__getplatform() != WIN_NT)
1373 /* 1. Global DNS Suffix Search List */
1374 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
1375 KEY_READ, &hKey) == ERROR_SUCCESS)
1377 get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
1378 if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
1380 commajoin(outptr, p);
1387 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
1388 KEY_READ, &hKey) == ERROR_SUCCESS)
1390 if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
1392 commajoin(outptr, p);
1399 /* 2. Connection Specific Search List composed of:
1400 * a. Primary DNS Suffix */
1401 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
1402 KEY_READ, &hKey) == ERROR_SUCCESS)
1404 if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
1406 commajoin(outptr, p);
1413 /* b. Interface SearchList, Domain, DhcpDomain */
1414 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
1415 KEY_READ, &hKey) == ERROR_SUCCESS)
1419 keyNameBuffSize = sizeof(keyName);
1420 if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
1421 0, NULL, NULL, NULL)
1424 if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
1427 /* p can be comma separated (SearchList) */
1428 if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
1430 commajoin(outptr, p);
1434 if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
1436 commajoin(outptr, p);
1440 if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
1442 commajoin(outptr, p);
1446 RegCloseKey(hKeyEnum);
1451 return *outptr != NULL;
1456 static int init_by_resolv_conf(ares_channel channel)
1458 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1459 !defined(CARES_USE_LIBRESOLV)
1462 int status = -1, nservers = 0, nsort = 0;
1463 struct server_state *servers = NULL;
1464 struct apattern *sortlist = NULL;
1468 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1469 return ARES_SUCCESS;
1471 if (get_DNS_Windows(&line))
1473 status = config_nameserver(&servers, &nservers, line);
1477 if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
1479 status = set_search(channel, line);
1483 if (status == ARES_SUCCESS)
1486 /* Catch the case when all the above checks fail (which happens when there
1487 is no network card or the cable is unplugged) */
1488 status = ARES_EFILE;
1490 #elif defined(__riscos__)
1492 /* Under RISC OS, name servers are listed in the
1493 system variable Inet$Resolvers, space separated. */
1495 line = getenv("Inet$Resolvers");
1498 char *resolvers = ares_strdup(line), *pos, *space;
1505 space = strchr(pos, ' ');
1508 status = config_nameserver(&servers, &nservers, pos);
1509 if (status != ARES_SUCCESS)
1514 if (status == ARES_SUCCESS)
1517 ares_free(resolvers);
1520 #elif defined(WATT32)
1524 for (i = 0; def_nameservers[i]; i++)
1527 return ARES_SUCCESS; /* use localhost DNS server */
1530 servers = ares_malloc(sizeof(struct server_state));
1533 memset(servers, 0, sizeof(struct server_state));
1535 for (i = 0; def_nameservers[i]; i++)
1537 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1538 servers[i].addr.family = AF_INET;
1539 servers[i].addr.udp_port = 0;
1540 servers[i].addr.tcp_port = 0;
1544 #elif defined(ANDROID) || defined(__ANDROID__)
1546 char propname[PROP_NAME_MAX];
1547 char propvalue[PROP_VALUE_MAX]="";
1552 /* Use the Android connectivity manager to get a list
1553 * of DNS servers. As of Android 8 (Oreo) net.dns#
1554 * system properties are no longer available. Google claims this
1555 * improves privacy. Apps now need the ACCESS_NETWORK_STATE
1556 * permission and must use the ConnectivityManager which
1558 dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers);
1559 if (dns_servers != NULL)
1561 for (i = 0; i < num_servers; i++)
1563 status = config_nameserver(&servers, &nservers, dns_servers[i]);
1564 if (status != ARES_SUCCESS)
1568 for (i = 0; i < num_servers; i++)
1570 ares_free(dns_servers[i]);
1572 ares_free(dns_servers);
1574 if (channel->ndomains == -1)
1576 domains = ares_get_android_search_domains_list();
1577 set_search(channel, domains);
1581 # ifdef HAVE___SYSTEM_PROPERTY_GET
1582 /* Old way using the system property still in place as
1583 * a fallback. Older android versions can still use this.
1584 * it's possible for older apps not not have added the new
1585 * permission and we want to try to avoid breaking those.
1587 * We'll only run this if we don't have any dns servers
1588 * because this will get the same ones (if it works). */
1589 if (status != ARES_EOF) {
1590 for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1591 snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1592 if (__system_property_get(propname, propvalue) < 1) {
1597 status = config_nameserver(&servers, &nservers, propvalue);
1598 if (status != ARES_SUCCESS)
1603 # endif /* HAVE___SYSTEM_PROPERTY_GET */
1604 #elif defined(CARES_USE_LIBRESOLV)
1605 struct __res_state res;
1606 memset(&res, 0, sizeof(res));
1607 int result = res_ninit(&res);
1608 if (result == 0 && (res.options & RES_INIT)) {
1611 if (channel->nservers == -1) {
1612 union res_sockaddr_union addr[MAXNS];
1613 int nscount = res_getservers(&res, addr, MAXNS);
1614 for (int i = 0; i < nscount; ++i) {
1615 char str[INET6_ADDRSTRLEN];
1617 sa_family_t family = addr[i].sin.sin_family;
1618 if (family == AF_INET) {
1619 ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
1620 } else if (family == AF_INET6) {
1621 ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
1626 config_status = config_nameserver(&servers, &nservers, str);
1627 if (config_status != ARES_SUCCESS) {
1628 status = config_status;
1633 if (channel->ndomains == -1) {
1635 while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1638 channel->domains = ares_malloc(entries * sizeof(char *));
1639 if (!channel->domains) {
1640 status = ARES_ENOMEM;
1642 channel->ndomains = entries;
1643 for (int i = 0; i < channel->ndomains; ++i) {
1644 channel->domains[i] = ares_strdup(res.dnsrch[i]);
1645 if (!channel->domains[i])
1646 status = ARES_ENOMEM;
1650 if (channel->ndots == -1)
1651 channel->ndots = res.ndots;
1652 if (channel->tries == -1)
1653 channel->tries = res.retry;
1654 if (channel->rotate == -1)
1655 channel->rotate = res.options & RES_ROTATE;
1656 if (channel->timeout == -1)
1657 channel->timeout = res.retrans * 1000;
1668 const char *resolvconf_path;
1670 /* Don't read resolv.conf and friends if we don't have to */
1671 if (ARES_CONFIG_CHECK(channel))
1672 return ARES_SUCCESS;
1674 /* Only update search domains if they're not already specified */
1675 update_domains = (channel->ndomains == -1);
1677 /* Support path for resolvconf filename set by ares_init_options */
1678 if(channel->resolvconf_path) {
1679 resolvconf_path = channel->resolvconf_path;
1681 resolvconf_path = PATH_RESOLV_CONF;
1684 fp = fopen(resolvconf_path, "r");
1686 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1688 if ((p = try_config(line, "domain", ';')) && update_domains)
1689 status = config_domain(channel, p);
1690 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1691 status = config_lookup(channel, p, "bind", NULL, "file");
1692 else if ((p = try_config(line, "search", ';')) && update_domains)
1693 status = set_search(channel, p);
1694 else if ((p = try_config(line, "nameserver", ';')) &&
1695 channel->nservers == -1)
1696 status = config_nameserver(&servers, &nservers, p);
1697 else if ((p = try_config(line, "sortlist", ';')) &&
1698 channel->nsort == -1)
1699 status = config_sortlist(&sortlist, &nsort, p);
1700 else if ((p = try_config(line, "options", ';')))
1701 status = set_options(channel, p);
1703 status = ARES_SUCCESS;
1704 if (status != ARES_SUCCESS)
1717 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1718 error, strerror(error)));
1719 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1720 status = ARES_EFILE;
1724 if ((status == ARES_EOF) && (!channel->lookups)) {
1725 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1726 fp = fopen("/etc/nsswitch.conf", "r");
1728 while ((status = ares__read_line(fp, &line, &linesize)) ==
1731 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1732 (void)config_lookup(channel, p, "dns", "resolve", "files");
1743 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1744 error, strerror(error)));
1745 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1746 "/etc/nsswitch.conf"));
1749 /* ignore error, maybe we will get luck in next if clause */
1754 if ((status == ARES_EOF) && (!channel->lookups)) {
1755 /* Linux / GNU libc 2.x and possibly others have host.conf */
1756 fp = fopen("/etc/host.conf", "r");
1758 while ((status = ares__read_line(fp, &line, &linesize)) ==
1761 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1763 (void)config_lookup(channel, p, "bind", NULL, "hosts");
1774 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1775 error, strerror(error)));
1776 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1780 /* ignore error, maybe we will get luck in next if clause */
1785 if ((status == ARES_EOF) && (!channel->lookups)) {
1786 /* Tru64 uses /etc/svc.conf */
1787 fp = fopen("/etc/svc.conf", "r");
1789 while ((status = ares__read_line(fp, &line, &linesize)) ==
1792 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1794 (void)config_lookup(channel, p, "bind", NULL, "local");
1805 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1806 error, strerror(error)));
1807 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1810 /* ignore error, default value will be chosen for `channel->lookups` */
1821 /* Handle errors. */
1822 if (status != ARES_EOF)
1824 if (servers != NULL)
1826 if (sortlist != NULL)
1827 ares_free(sortlist);
1831 /* If we got any name server entries, fill them in. */
1834 channel->servers = servers;
1835 channel->nservers = nservers;
1838 /* If we got any sortlist entries, fill them in. */
1841 channel->sortlist = sortlist;
1842 channel->nsort = nsort;
1845 return ARES_SUCCESS;
1848 static int init_by_defaults(ares_channel channel)
1850 char *hostname = NULL;
1851 int rc = ARES_SUCCESS;
1852 #ifdef HAVE_GETHOSTNAME
1856 if (channel->flags == -1)
1858 if (channel->timeout == -1)
1859 channel->timeout = DEFAULT_TIMEOUT;
1860 if (channel->tries == -1)
1861 channel->tries = DEFAULT_TRIES;
1862 if (channel->ndots == -1)
1864 if (channel->rotate == -1)
1865 channel->rotate = 0;
1866 if (channel->udp_port == -1)
1867 channel->udp_port = htons(NAMESERVER_PORT);
1868 if (channel->tcp_port == -1)
1869 channel->tcp_port = htons(NAMESERVER_PORT);
1871 if (channel->ednspsz == -1)
1872 channel->ednspsz = EDNSPACKETSZ;
1874 if (channel->nservers == -1) {
1875 /* If nobody specified servers, try a local named. */
1876 channel->servers = ares_malloc(sizeof(struct server_state));
1877 if (!channel->servers) {
1881 channel->servers[0].addr.family = AF_INET;
1882 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1883 channel->servers[0].addr.udp_port = 0;
1884 channel->servers[0].addr.tcp_port = 0;
1885 channel->nservers = 1;
1888 #if defined(USE_WINSOCK)
1889 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1890 #elif defined(ENAMETOOLONG)
1891 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1892 (SOCKERRNO == EINVAL))
1894 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1897 if (channel->ndomains == -1) {
1898 /* Derive a default domain search list from the kernel hostname,
1899 * or set it to empty if the hostname isn't helpful.
1901 #ifndef HAVE_GETHOSTNAME
1902 channel->ndomains = 0; /* default to none */
1904 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1907 channel->ndomains = 0; /* default to none */
1909 hostname = ares_malloc(len);
1916 res = gethostname(hostname, lenv);
1922 p = ares_realloc(hostname, len);
1931 /* Lets not treat a gethostname failure as critical, since we
1932 * are ok if gethostname doesn't even exist */
1939 dot = strchr(hostname, '.');
1941 /* a dot was found */
1942 channel->domains = ares_malloc(sizeof(char *));
1943 if (!channel->domains) {
1947 channel->domains[0] = ares_strdup(dot + 1);
1948 if (!channel->domains[0]) {
1952 channel->ndomains = 1;
1957 if (channel->nsort == -1) {
1958 channel->sortlist = NULL;
1962 if (!channel->lookups) {
1963 channel->lookups = ares_strdup("fb");
1964 if (!channel->lookups)
1970 if(channel->servers) {
1971 ares_free(channel->servers);
1972 channel->servers = NULL;
1975 if(channel->domains && channel->domains[0])
1976 ares_free(channel->domains[0]);
1977 if(channel->domains) {
1978 ares_free(channel->domains);
1979 channel->domains = NULL;
1982 if(channel->lookups) {
1983 ares_free(channel->lookups);
1984 channel->lookups = NULL;
1987 if(channel->resolvconf_path) {
1988 ares_free(channel->resolvconf_path);
1989 channel->resolvconf_path = NULL;
1994 ares_free(hostname);
1999 #if !defined(WIN32) && !defined(WATT32) && \
2000 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
2001 static int config_domain(ares_channel channel, char *str)
2005 /* Set a single search domain. */
2007 while (*q && !ISSPACE(*q))
2010 return set_search(channel, str);
2013 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
2014 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
2015 /* workaround icc 9.1 optimizer issue */
2016 # define vqualifier volatile
2021 static int config_lookup(ares_channel channel, const char *str,
2022 const char *bindch, const char *altbindch,
2025 char lookups[3], *l;
2026 const char *vqualifier p;
2028 if (altbindch == NULL)
2031 /* Set the lookup order. Only the first letter of each work
2032 * is relevant, and it has to be "b" for DNS or "f" for the
2033 * host file. Ignore everything else.
2039 if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
2040 if (*p == *bindch || *p == *altbindch) *l++ = 'b';
2043 while (*p && !ISSPACE(*p) && (*p != ','))
2045 while (*p && (ISSPACE(*p) || (*p == ',')))
2049 channel->lookups = ares_strdup(lookups);
2050 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
2052 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
2055 /* Validate that the ip address matches the subnet (network base and network
2056 * mask) specified. Addresses are specified in standard Network Byte Order as
2057 * 16 bytes, and the netmask is 0 to 128 (bits).
2059 static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
2060 unsigned char netmask,
2061 const unsigned char ipaddr[16])
2063 unsigned char mask[16] = { 0 };
2070 /* Quickly set whole bytes */
2071 memset(mask, 0xFF, netmask / 8);
2073 /* Set remaining bits */
2075 mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
2078 for (i=0; i<16; i++) {
2079 if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
2086 /* Return true iff the IPv6 ipaddr is blacklisted. */
2087 static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
2089 /* A list of blacklisted IPv6 subnets. */
2091 const unsigned char netbase[16];
2092 unsigned char netmask;
2094 /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
2095 * Site-Local scoped address prefix. These are never valid DNS servers,
2096 * but are known to be returned at least sometimes on Windows and Android.
2100 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2101 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2108 /* See if ipaddr matches any of the entries in the blacklist. */
2109 for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
2110 if (ares_ipv6_subnet_matches(
2111 blacklist[i].netbase, blacklist[i].netmask, ipaddr))
2117 /* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
2118 * servers list, updating servers and nservers as required.
2120 * This will silently ignore blacklisted IPv6 nameservers as detected by
2121 * ares_ipv6_server_blacklisted().
2123 * Returns an error code on failure, else ARES_SUCCESS.
2125 static int config_nameserver(struct server_state **servers, int *nservers,
2128 struct ares_addr host;
2129 struct server_state *newserv;
2131 /* On Windows, there may be more than one nameserver specified in the same
2132 * registry key, so we parse input as a space or comma seperated list.
2136 /* Skip whitespace and commas. */
2137 while (*p && (ISSPACE(*p) || (*p == ',')))
2140 /* No more input, done. */
2143 /* Pointer to start of IPv4 or IPv6 address part. */
2146 /* Advance past this address. */
2147 while (*p && !ISSPACE(*p) && (*p != ','))
2150 /* Null terminate this address. */
2153 /* Reached end of input, done when this address is processed. */
2156 /* Convert textual address to binary format. */
2157 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
2158 host.family = AF_INET;
2159 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1
2160 /* Silently skip blacklisted IPv6 servers. */
2161 && !ares_ipv6_server_blacklisted(
2162 (const unsigned char *)&host.addrV6))
2163 host.family = AF_INET6;
2167 /* Resize servers state array. */
2168 newserv = ares_realloc(*servers, (*nservers + 1) *
2169 sizeof(struct server_state));
2173 /* Store address data. */
2174 newserv[*nservers].addr.family = host.family;
2175 newserv[*nservers].addr.udp_port = 0;
2176 newserv[*nservers].addr.tcp_port = 0;
2177 if (host.family == AF_INET)
2178 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
2179 sizeof(host.addrV4));
2181 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
2182 sizeof(host.addrV6));
2184 /* Update arguments. */
2189 return ARES_SUCCESS;
2191 #endif /* !WATT32 */
2193 static int config_sortlist(struct apattern **sortlist, int *nsort,
2196 struct apattern pat;
2199 /* Add sortlist entries. */
2200 while (*str && *str != ';')
2203 char ipbuf[16], ipbufpfx[32];
2204 /* Find just the IP */
2206 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
2208 memcpy(ipbuf, str, q-str);
2209 ipbuf[q-str] = '\0';
2210 /* Find the prefix */
2213 const char *str2 = q+1;
2214 while (*q && *q != ';' && !ISSPACE(*q))
2216 memcpy(ipbufpfx, str, q-str);
2217 ipbufpfx[q-str] = '\0';
2222 /* Lets see if it is CIDR */
2223 /* First we'll try IPv6 */
2224 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
2226 sizeof(pat.addrV6))) > 0)
2228 pat.type = PATTERN_CIDR;
2229 pat.mask.bits = (unsigned short)bits;
2230 pat.family = AF_INET6;
2231 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2232 ares_free(*sortlist);
2237 else if (ipbufpfx[0] &&
2238 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
2239 sizeof(pat.addrV4))) > 0)
2241 pat.type = PATTERN_CIDR;
2242 pat.mask.bits = (unsigned short)bits;
2243 pat.family = AF_INET;
2244 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2245 ares_free(*sortlist);
2250 /* See if it is just a regular IP */
2251 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
2255 memcpy(ipbuf, str, q-str);
2256 ipbuf[q-str] = '\0';
2257 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
2262 pat.family = AF_INET;
2263 pat.type = PATTERN_MASK;
2264 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2265 ares_free(*sortlist);
2272 while (*q && *q != ';' && !ISSPACE(*q))
2276 while (ISSPACE(*str))
2280 return ARES_SUCCESS;
2283 static int set_search(ares_channel channel, const char *str)
2287 if(channel->ndomains != -1) {
2288 /* LCOV_EXCL_START: all callers check ndomains == -1 */
2289 /* if we already have some domains present, free them first */
2290 ares_strsplit_free(channel->domains, channel->ndomains);
2291 channel->domains = NULL;
2292 channel->ndomains = -1;
2293 } /* LCOV_EXCL_STOP */
2295 channel->domains = ares_strsplit(str, ", ", 1, &cnt);
2296 channel->ndomains = (int)cnt;
2297 if (channel->domains == NULL || channel->ndomains == 0) {
2298 channel->domains = NULL;
2299 channel->ndomains = -1;
2302 return ARES_SUCCESS;
2305 static int set_options(ares_channel channel, const char *str)
2307 const char *p, *q, *val;
2313 while (*q && !ISSPACE(*q))
2315 val = try_option(p, q, "ndots:");
2316 if (val && channel->ndots == -1)
2317 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
2318 val = try_option(p, q, "retrans:");
2319 if (val && channel->timeout == -1)
2320 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
2321 val = try_option(p, q, "retry:");
2322 if (val && channel->tries == -1)
2323 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
2324 val = try_option(p, q, "rotate");
2325 if (val && channel->rotate == -1)
2326 channel->rotate = 1;
2332 return ARES_SUCCESS;
2335 static const char *try_option(const char *p, const char *q, const char *opt)
2337 size_t len = strlen(opt);
2338 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
2341 #if !defined(WIN32) && !defined(WATT32) && \
2342 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
2343 static char *try_config(char *s, const char *opt, char scc)
2350 /* no line or no option */
2351 return NULL; /* LCOV_EXCL_LINE */
2353 /* Hash '#' character is always used as primary comment char, additionally
2354 a not-NUL secondary comment char will be considered when specified. */
2356 /* trim line comment */
2359 while (*p && (*p != '#') && (*p != scc))
2362 while (*p && (*p != '#'))
2366 /* trim trailing whitespace */
2368 while ((q >= s) && ISSPACE(*q))
2372 /* skip leading whitespace */
2374 while (*p && ISSPACE(*p))
2381 if ((len = strlen(opt)) == 0)
2383 return NULL; /* LCOV_EXCL_LINE */
2385 if (strncmp(p, opt, len) != 0)
2386 /* line and option do not match */
2389 /* skip over given option name */
2393 /* no option value */
2394 return NULL; /* LCOV_EXCL_LINE */
2396 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
2397 /* whitespace between option name and value is mandatory
2398 for given option names which do not end with ':' or '=' */
2401 /* skip over whitespace */
2402 while (*p && ISSPACE(*p))
2406 /* no option value */
2409 /* return pointer to option value */
2412 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
2414 static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
2417 /* Four octets and three periods yields at most 15 characters. */
2421 addr->s_addr = inet_addr(ipbuf);
2422 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
2427 static void natural_mask(struct apattern *pat)
2429 struct in_addr addr;
2431 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
2434 addr.s_addr = ntohl(pat->addrV4.s_addr);
2436 /* This is out of date in the CIDR world, but some people might
2439 if (IN_CLASSA(addr.s_addr))
2440 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
2441 else if (IN_CLASSB(addr.s_addr))
2442 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
2444 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
2447 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
2448 struct apattern *pat)
2450 struct apattern *newsort;
2451 newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
2454 newsort[*nsort] = *pat;
2455 *sortlist = newsort;
2460 /* initialize an rc4 key. If possible a cryptographically secure random key
2461 is generated using a suitable function (for example win32's RtlGenRandom as
2463 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
2464 otherwise the code defaults to cross-platform albeit less secure mechanism
2467 static void randomize_key(unsigned char* key,int key_data_len)
2473 if (ares_fpSystemFunction036)
2475 res = (*ares_fpSystemFunction036) (key, key_data_len);
2481 FILE *f = fopen(RANDOM_FILE, "rb");
2483 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2490 for (;counter<key_data_len;counter++)
2491 key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2495 static int init_id_key(rc4_key* key,int key_data_len)
2497 unsigned char index1;
2498 unsigned char index2;
2499 unsigned char* state;
2501 unsigned char *key_data_ptr = 0;
2503 key_data_ptr = ares_malloc(key_data_len);
2506 memset(key_data_ptr, 0, key_data_len);
2508 state = &key->state[0];
2509 for(counter = 0; counter < 256; counter++)
2510 /* unnecessary AND but it keeps some compilers happier */
2511 state[counter] = (unsigned char)(counter & 0xff);
2512 randomize_key(key->state,key_data_len);
2517 for(counter = 0; counter < 256; counter++)
2519 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2521 ARES_SWAP_BYTE(&state[counter], &state[index2]);
2523 index1 = (unsigned char)((index1 + 1) % key_data_len);
2525 ares_free(key_data_ptr);
2526 return ARES_SUCCESS;
2529 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2531 channel->local_ip4 = local_ip;
2534 /* local_ip6 should be 16 bytes in length */
2535 void ares_set_local_ip6(ares_channel channel,
2536 const unsigned char* local_ip6)
2538 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2541 /* local_dev_name should be null terminated. */
2542 void ares_set_local_dev(ares_channel channel,
2543 const char* local_dev_name)
2545 strncpy(channel->local_dev_name, local_dev_name,
2546 sizeof(channel->local_dev_name));
2547 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
2551 void ares_set_socket_callback(ares_channel channel,
2552 ares_sock_create_callback cb,
2555 channel->sock_create_cb = cb;
2556 channel->sock_create_cb_data = data;
2559 void ares_set_socket_configure_callback(ares_channel channel,
2560 ares_sock_config_callback cb,
2563 channel->sock_config_cb = cb;
2564 channel->sock_config_cb_data = data;
2567 void ares_set_socket_functions(ares_channel channel,
2568 const struct ares_socket_functions * funcs,
2571 channel->sock_funcs = funcs;
2572 channel->sock_func_cb_data = data;
2575 int ares_set_sortlist(ares_channel channel, const char *sortstr)
2578 struct apattern *sortlist = NULL;
2582 return ARES_ENODATA;
2584 status = config_sortlist(&sortlist, &nsort, sortstr);
2585 if (status == ARES_SUCCESS && sortlist) {
2586 if (channel->sortlist)
2587 ares_free(channel->sortlist);
2588 channel->sortlist = sortlist;
2589 channel->nsort = nsort;
2594 void ares__init_servers_state(ares_channel channel)
2596 struct server_state *server;
2599 for (i = 0; i < channel->nservers; i++)
2601 server = &channel->servers[i];
2602 server->udp_socket = ARES_SOCKET_BAD;
2603 server->tcp_socket = ARES_SOCKET_BAD;
2604 server->tcp_connection_generation = ++channel->tcp_connection_generation;
2605 server->tcp_lenbuf_pos = 0;
2606 server->tcp_buffer_pos = 0;
2607 server->tcp_buffer = NULL;
2608 server->tcp_length = 0;
2609 server->qhead = NULL;
2610 server->qtail = NULL;
2611 ares__init_list_head(&server->queries_to_server);
2612 server->channel = channel;
2613 server->is_broken = 0;