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;
118 if (ares_library_initialized() != ARES_SUCCESS)
119 return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
121 channel = ares_malloc(sizeof(struct ares_channeldata));
129 /* Set everything to distinguished values so we know they haven't
133 channel->timeout = -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;
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;
160 channel->last_server = 0;
161 channel->last_timeout_processed = (time_t)now.tv_sec;
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));
167 /* Initialize our lists of queries */
168 ares__init_list_head(&(channel->all_queries));
169 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
171 ares__init_list_head(&(channel->queries_by_qid[i]));
173 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
175 ares__init_list_head(&(channel->queries_by_timeout[i]));
178 /* Initialize configuration by each of the four sources, from highest
179 * precedence to lowest.
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 */
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)));
201 * No matter what failed or succeeded, seed defaults to provide
202 * useful behavior for things that we missed.
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)));
209 /* Generate random key */
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);
216 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
217 ares_strerror(status)));
221 if (status != ARES_SUCCESS)
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);
231 ares_free(channel->lookups);
232 if(channel->resolvconf_path)
233 ares_free(channel->resolvconf_path);
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;
242 ares__init_servers_state(channel);
244 *channelptr = channel;
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)
252 struct ares_options opts;
253 struct ares_addr_port_node *servers;
254 int non_v4_default_port = 0;
258 *dest = NULL; /* in case of failure return NULL explicitly */
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);
265 ares_destroy_options(&opts);
269 /* Then create the new channel with those options */
270 rc = ares_init_options(dest, &opts, optmask);
272 /* destroy the options copy to not leak any memory */
273 ares_destroy_options(&opts);
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;
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));
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++)
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++;
301 if (non_v4_default_port) {
302 rc = ares_get_servers_ports(src, &servers);
303 if (rc != ARES_SUCCESS) {
308 rc = ares_set_servers_ports(*dest, servers);
309 ares_free_data(servers);
310 if (rc != ARES_SUCCESS) {
317 return ARES_SUCCESS; /* everything went fine */
320 /* Save options from initialized channel */
321 int ares_save_options(ares_channel channel, struct ares_options *options,
325 int ipv4_nservers = 0;
327 /* Zero everything out */
328 memset(options, 0, sizeof(struct ares_options));
330 if (!ARES_CONFIG_CHECK(channel))
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);
342 if (channel->resolvconf_path)
343 (*optmask) |= ARES_OPT_RESOLVCONF;
345 /* Copy easy stuff */
346 options->flags = channel->flags;
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;
358 /* Copy IPv4 servers that use the default port */
359 if (channel->nservers) {
360 for (i = 0; i < channel->nservers; i++)
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))
368 options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
369 if (!options->servers)
371 for (i = j = 0; i < channel->nservers; i++)
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));
382 options->nservers = ipv4_nservers;
385 if (channel->ndomains) {
386 options->domains = ares_malloc(channel->ndomains * sizeof(char *));
387 if (!options->domains)
390 for (i = 0; i < channel->ndomains; i++)
392 options->ndomains = i;
393 options->domains[i] = ares_strdup(channel->domains[i]);
394 if (!options->domains[i])
398 options->ndomains = channel->ndomains;
401 if (channel->lookups) {
402 options->lookups = ares_strdup(channel->lookups);
403 if (!options->lookups && channel->lookups)
408 if (channel->nsort) {
409 options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
410 if (!options->sortlist)
412 for (i = 0; i < channel->nsort; i++)
413 options->sortlist[i] = channel->sortlist[i];
415 options->nsort = channel->nsort;
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)
427 static int init_by_options(ares_channel channel,
428 const struct ares_options *options,
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)
446 if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
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)
454 channel->sock_state_cb = options->sock_state_cb;
455 channel->sock_state_cb_data = options->sock_state_cb_data;
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;
464 if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
465 channel->ednspsz = options->ednspsz;
467 /* Copy the IPv4 servers, if given. */
468 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
470 /* Avoid zero size allocations at any cost */
471 if (options->nservers > 0)
474 ares_malloc(options->nservers * sizeof(struct server_state));
475 if (!channel->servers)
477 for (i = 0; i < options->nservers; i++)
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));
487 channel->nservers = options->nservers;
490 /* Copy the domains, if given. Keep channel->ndomains consistent so
491 * we can clean up in case of error.
493 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
495 /* Avoid zero size allocations at any cost */
496 if (options->ndomains > 0)
498 channel->domains = ares_malloc(options->ndomains * sizeof(char *));
499 if (!channel->domains)
501 for (i = 0; i < options->ndomains; i++)
503 channel->ndomains = i;
504 channel->domains[i] = ares_strdup(options->domains[i]);
505 if (!channel->domains[i])
509 channel->ndomains = options->ndomains;
512 /* Set lookups, if given. */
513 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
515 channel->lookups = ares_strdup(options->lookups);
516 if (!channel->lookups)
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)
526 for (i = 0; i < options->nsort; i++)
527 channel->sortlist[i] = options->sortlist[i];
529 channel->nsort = options->nsort;
532 /* Set path for resolv.conf file, if given. */
533 if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
535 channel->resolvconf_path = ares_strdup(options->resolvconf_path);
536 if (!channel->resolvconf_path && options->resolvconf_path)
540 channel->optmask = optmask;
545 static int init_by_environment(ares_channel channel)
547 const char *localdomain, *res_options;
550 localdomain = getenv("LOCALDOMAIN");
551 if (localdomain && channel->ndomains == -1)
553 status = set_search(channel, localdomain);
554 if (status != ARES_SUCCESS)
558 res_options = getenv("RES_OPTIONS");
561 status = set_options(channel, res_options);
562 if (status != ARES_SUCCESS)
563 return status; /* LCOV_EXCL_LINE: set_options() never fails */
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.
578 * Returns 0 and nullifies *outptr upon inability to return a string value.
580 * Returns 1 and sets *outptr when returning a dynamically allocated string.
582 * Supported on Windows NT 3.5 and newer.
584 static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
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)
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);
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))
612 /* Null terminate buffer allways */
613 *(*outptr + size) = '\0';
621 * Functionally identical to get_REG_SZ()
623 * Supported on Windows 95, 98 and ME.
625 static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
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)
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);
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))
654 /* Null terminate buffer allways */
655 *(*outptr + size) = '\0';
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.
669 * Returns 0 and nullifies *outptr upon inability to return a string value.
671 * Returns 1 and sets *outptr when returning a dynamically allocated string.
673 * Supported on Windows NT 3.5 and newer.
675 static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
678 char enumKeyName[256];
679 DWORD enumKeyNameBuffSize;
680 DWORD enumKeyIdx = 0;
689 enumKeyNameBuffSize = sizeof(enumKeyName);
690 res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName,
691 &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
692 if (res != ERROR_SUCCESS)
694 res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
696 if (res != ERROR_SUCCESS)
698 gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
699 RegCloseKey(hKeyEnum);
711 * get_DNS_Registry_9X()
713 * Functionally identical to get_DNS_Registry()
715 * Implementation supports Windows 95, 98 and ME.
717 static int get_DNS_Registry_9X(char **outptr)
725 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
727 if (res != ERROR_SUCCESS)
730 gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
731 RegCloseKey(hKey_VxD_MStcp);
733 if (!gotString || !*outptr)
740 * get_DNS_Registry_NT()
742 * Functionally identical to get_DNS_Registry()
744 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
746 * Implementation supports Windows NT 3.5 and newer.
748 static int get_DNS_Registry_NT(char **outptr)
750 HKEY hKey_Interfaces = NULL;
751 HKEY hKey_Tcpip_Parameters;
757 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
758 &hKey_Tcpip_Parameters);
759 if (res != ERROR_SUCCESS)
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.
768 /* Global DNS static parameters */
769 gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
773 /* Global DNS DHCP-configured parameters */
774 gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
778 /* Try adapter specific parameters */
779 res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0,
780 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
782 if (res != ERROR_SUCCESS)
784 hKey_Interfaces = NULL;
788 /* Adapter specific DNS static parameters */
789 gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
793 /* Adapter specific DNS DHCP-configured parameters */
794 gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
798 RegCloseKey(hKey_Interfaces);
800 RegCloseKey(hKey_Tcpip_Parameters);
802 if (!gotString || !*outptr)
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.
815 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
817 * Returns 1 and sets *outptr when returning a dynamically allocated string.
819 static int get_DNS_Registry(char **outptr)
821 win_platform platform;
826 platform = ares__getplatform();
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);
839 static void commanjoin(char** dst, const char* const src, const size_t len)
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);
852 if (strlen(*dst) != 0)
854 strncat(*dst, src, len);
862 static void commajoin(char **dst, const char *src)
864 commanjoin(dst, src, strlen(src));
868 * get_DNS_NetworkParams()
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.
875 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
877 * Returns 1 and sets *outptr when returning a dynamically allocated string.
879 * Implementation supports Windows 98 and newer.
881 * Note: Ancient PSDK required in order to build a W98 target.
883 static int get_DNS_NetworkParams(char **outptr)
885 FIXED_INFO *fi, *newfi;
886 struct ares_addr namesrvr;
888 IP_ADDR_STRING *ipAddr;
890 DWORD size = sizeof (*fi);
894 /* Verify run-time availability of GetNetworkParams() */
895 if (ares_fpGetNetworkParams == ZERO_NULL)
898 fi = ares_malloc(size);
902 res = (*ares_fpGetNetworkParams) (fi, &size);
903 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
906 newfi = ares_realloc(fi, size);
911 res = (*ares_fpGetNetworkParams) (fi, &size);
912 if (res != ERROR_SUCCESS)
915 for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
917 txtaddr = &ipAddr->IpAddress.String[0];
919 /* Validate converting textual address to binary format. */
920 if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
922 if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
923 (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
926 else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
928 if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
929 sizeof(namesrvr.addrV6)) == 0)
935 commajoin(outptr, txtaddr);
951 static BOOL ares_IsWindowsVistaOrGreater(void)
954 memset(&vinfo, 0, sizeof(vinfo));
955 vinfo.dwOSVersionInfoSize = sizeof(vinfo);
957 #pragma warning(push)
958 #pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */
960 if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
968 /* A structure to hold the string form of IPv4 and IPv6 addresses so we can
969 * sort them by a metric.
973 /* The metric we sort them by. */
976 /* Original index of the item, used as a secondary sort parameter to make
977 * qsort() stable if the metrics are equal */
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.
983 char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
986 /* Sort Address values \a left and \a right by metric, returning the usual
987 * indicators for qsort().
989 static int compareAddresses(const void *arg1,
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;
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.
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.
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).
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
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.
1036 static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
1037 const SOCKADDR_INET * const dest,
1038 const ULONG interfaceMetric)
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
1048 /* No specific source address. */
1050 /* Our destination address. */
1054 /* The route 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.
1061 || row.Metric == (ULONG)-1
1062 || row.Metric > ((ULONG)-1) - interfaceMetric) {
1063 /* Return the worst possible metric. */
1067 /* Return the metric value from that row, plus the interface metric.
1070 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
1071 * which describes the combination as a "sum".
1073 return row.Metric + interfaceMetric;
1077 * get_DNS_AdaptersAddresses()
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.
1084 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1086 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1088 * Implementation supports Windows XP and newer.
1090 #define IPAA_INITIAL_BUF_SZ 15 * 1024
1091 #define IPAA_MAX_TRIES 3
1092 static int get_DNS_AdaptersAddresses(char **outptr)
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;
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. */
1110 struct sockaddr *sa;
1111 struct sockaddr_in *sa4;
1112 struct sockaddr_in6 *sa6;
1117 /* Verify run-time availability of GetAdaptersAddresses() */
1118 if (ares_fpGetAdaptersAddresses == ZERO_NULL)
1121 ipaa = ares_malloc(Bufsz);
1125 /* Start with enough room for a few DNS server addresses and we'll grow it
1126 * as we encounter more.
1129 addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
1130 if(addresses == NULL) {
1131 /* We need room for at least some addresses to function. */
1136 /* Usually this call suceeds with initial buffer size */
1137 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1139 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
1142 while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
1144 if (Bufsz < ReqBufsz)
1146 newipaa = ares_realloc(ipaa, ReqBufsz);
1152 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1154 if (res == ERROR_SUCCESS)
1157 if (res != ERROR_SUCCESS)
1160 for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1162 if(ipaaEntry->OperStatus != IfOperStatusUp)
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.
1171 for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1173 ipaDNSAddr = ipaDNSAddr->Next)
1175 namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1177 if (namesrvr.sa->sa_family == AF_INET)
1179 if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1180 (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
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) {
1192 addressesSize = newSize;
1195 /* Vista required for Luid or Ipv4Metric */
1196 if (ares_IsWindowsVistaOrGreater())
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);
1206 addresses[addressesIndex].metric = (ULONG)-1;
1209 /* Record insertion index to make qsort stable */
1210 addresses[addressesIndex].orig_idx = addressesIndex;
1212 if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1213 addresses[addressesIndex].text,
1214 sizeof(addresses[0].text))) {
1219 else if (namesrvr.sa->sa_family == AF_INET6)
1221 if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1222 sizeof(namesrvr.sa6->sin6_addr)) == 0)
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) {
1234 addressesSize = newSize;
1237 /* Vista required for Luid or Ipv4Metric */
1238 if (ares_IsWindowsVistaOrGreater())
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);
1248 addresses[addressesIndex].metric = (ULONG)-1;
1251 /* Record insertion index to make qsort stable */
1252 addresses[addressesIndex].orig_idx = addressesIndex;
1254 if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1255 addresses[addressesIndex].text,
1256 sizeof(addresses[0].text))) {
1262 /* Skip non-IPv4/IPv6 addresses completely. */
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);
1272 /* Join them all into a single string, removing duplicates. */
1275 for(i = 0; i < addressesIndex; ++i) {
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) {
1283 /* Iff we didn't emit this address already, emit it now. */
1285 /* Add that to outptr (if we can). */
1286 commajoin(outptr, addresses[i].text);
1292 ares_free(addresses);
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.
1312 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1314 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1316 * Implementation supports Windows 95 and newer.
1318 static int get_DNS_Windows(char **outptr)
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))
1325 /* Try using IP helper API GetNetworkParams(). IPv4 only. */
1326 if (get_DNS_NetworkParams(outptr))
1329 /* Fall-back to registry information */
1330 return get_DNS_Registry(outptr);
1334 * get_SuffixList_Windows()
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.
1340 * Returns 0 and nullifies *outptr upon inability to return the suffix list.
1342 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1344 * Implementation supports Windows Server 2003 and newer
1346 static int get_SuffixList_Windows(char **outptr)
1348 HKEY hKey, hKeyEnum;
1350 DWORD keyNameBuffSize;
1356 if (ares__getplatform() != WIN_NT)
1359 /* 1. Global DNS Suffix Search List */
1360 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
1361 KEY_READ, &hKey) == ERROR_SUCCESS)
1363 get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
1364 if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
1366 commajoin(outptr, p);
1373 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
1374 KEY_READ, &hKey) == ERROR_SUCCESS)
1376 if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
1378 commajoin(outptr, p);
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)
1390 if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
1392 commajoin(outptr, p);
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)
1405 keyNameBuffSize = sizeof(keyName);
1406 if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
1407 0, NULL, NULL, NULL)
1410 if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
1413 /* p can be comma separated (SearchList) */
1414 if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
1416 commajoin(outptr, p);
1420 if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
1422 commajoin(outptr, p);
1426 if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
1428 commajoin(outptr, p);
1432 RegCloseKey(hKeyEnum);
1437 return *outptr != NULL;
1442 static int init_by_resolv_conf(ares_channel channel)
1444 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1445 !defined(CARES_USE_LIBRESOLV)
1448 int status = -1, nservers = 0, nsort = 0;
1449 struct server_state *servers = NULL;
1450 struct apattern *sortlist = NULL;
1454 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1455 return ARES_SUCCESS;
1457 if (get_DNS_Windows(&line))
1459 status = config_nameserver(&servers, &nservers, line);
1463 if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
1465 status = set_search(channel, line);
1469 if (status == ARES_SUCCESS)
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;
1476 #elif defined(__riscos__)
1478 /* Under RISC OS, name servers are listed in the
1479 system variable Inet$Resolvers, space separated. */
1481 line = getenv("Inet$Resolvers");
1484 char *resolvers = ares_strdup(line), *pos, *space;
1491 space = strchr(pos, ' ');
1494 status = config_nameserver(&servers, &nservers, pos);
1495 if (status != ARES_SUCCESS)
1500 if (status == ARES_SUCCESS)
1503 ares_free(resolvers);
1506 #elif defined(WATT32)
1510 for (i = 0; def_nameservers[i]; i++)
1513 return ARES_SUCCESS; /* use localhost DNS server */
1516 servers = ares_malloc(sizeof(struct server_state));
1519 memset(servers, 0, sizeof(struct server_state));
1521 for (i = 0; def_nameservers[i]; i++)
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;
1530 #elif defined(ANDROID) || defined(__ANDROID__)
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
1542 dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers);
1543 if (dns_servers != NULL)
1545 for (i = 0; i < num_servers; i++)
1547 status = config_nameserver(&servers, &nservers, dns_servers[i]);
1548 if (status != ARES_SUCCESS)
1552 for (i = 0; i < num_servers; i++)
1554 ares_free(dns_servers[i]);
1556 ares_free(dns_servers);
1558 if (channel->ndomains == -1)
1560 domains = ares_get_android_search_domains_list();
1561 set_search(channel, domains);
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.
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) {
1583 status = config_nameserver(&servers, &nservers, propvalue);
1584 if (status != ARES_SUCCESS)
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)) {
1597 if (channel->nservers == -1) {
1598 union res_sockaddr_union addr[MAXNS];
1599 int nscount = res_getservers(&res, addr, MAXNS);
1601 for (i = 0; i < nscount; ++i) {
1602 char str[INET6_ADDRSTRLEN];
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));
1613 config_status = config_nameserver(&servers, &nservers, str);
1614 if (config_status != ARES_SUCCESS) {
1615 status = config_status;
1620 if (channel->ndomains == -1) {
1622 while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1625 channel->domains = ares_malloc(entries * sizeof(char *));
1626 if (!channel->domains) {
1627 status = ARES_ENOMEM;
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;
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;
1656 const char *resolvconf_path;
1658 /* Don't read resolv.conf and friends if we don't have to */
1659 if (ARES_CONFIG_CHECK(channel))
1660 return ARES_SUCCESS;
1662 /* Only update search domains if they're not already specified */
1663 update_domains = (channel->ndomains == -1);
1665 /* Support path for resolvconf filename set by ares_init_options */
1666 if(channel->resolvconf_path) {
1667 resolvconf_path = channel->resolvconf_path;
1669 resolvconf_path = PATH_RESOLV_CONF;
1672 fp = fopen(resolvconf_path, "r");
1674 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
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);
1691 status = ARES_SUCCESS;
1692 if (status != ARES_SUCCESS)
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;
1712 if ((status == ARES_EOF) && (!channel->lookups)) {
1713 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1714 fp = fopen("/etc/nsswitch.conf", "r");
1716 while ((status = ares__read_line(fp, &line, &linesize)) ==
1719 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1720 (void)config_lookup(channel, p, "dns", "resolve", "files");
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"));
1737 /* ignore error, maybe we will get luck in next if clause */
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");
1746 while ((status = ares__read_line(fp, &line, &linesize)) ==
1749 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1751 (void)config_lookup(channel, p, "bind", NULL, "hosts");
1762 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1763 error, strerror(error)));
1764 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1768 /* ignore error, maybe we will get luck in next if clause */
1773 if ((status == ARES_EOF) && (!channel->lookups)) {
1774 /* Tru64 uses /etc/svc.conf */
1775 fp = fopen("/etc/svc.conf", "r");
1777 while ((status = ares__read_line(fp, &line, &linesize)) ==
1780 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1782 (void)config_lookup(channel, p, "bind", NULL, "local");
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"));
1798 /* ignore error, default value will be chosen for `channel->lookups` */
1809 /* Handle errors. */
1810 if (status != ARES_EOF)
1812 if (servers != NULL)
1814 if (sortlist != NULL)
1815 ares_free(sortlist);
1819 /* If we got any name server entries, fill them in. */
1822 channel->servers = servers;
1823 channel->nservers = nservers;
1826 /* If we got any sortlist entries, fill them in. */
1829 channel->sortlist = sortlist;
1830 channel->nsort = nsort;
1833 return ARES_SUCCESS;
1836 static int init_by_defaults(ares_channel channel)
1838 char *hostname = NULL;
1839 int rc = ARES_SUCCESS;
1840 #ifdef HAVE_GETHOSTNAME
1844 if (channel->flags == -1)
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)
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);
1859 if (channel->ednspsz == -1)
1860 channel->ednspsz = EDNSPACKETSZ;
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) {
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;
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))
1882 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
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.
1889 #ifndef HAVE_GETHOSTNAME
1890 channel->ndomains = 0; /* default to none */
1892 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1895 channel->ndomains = 0; /* default to none */
1897 hostname = ares_malloc(len);
1904 res = gethostname(hostname, lenv);
1910 p = ares_realloc(hostname, len);
1919 /* Lets not treat a gethostname failure as critical, since we
1920 * are ok if gethostname doesn't even exist */
1927 dot = strchr(hostname, '.');
1929 /* a dot was found */
1930 channel->domains = ares_malloc(sizeof(char *));
1931 if (!channel->domains) {
1935 channel->domains[0] = ares_strdup(dot + 1);
1936 if (!channel->domains[0]) {
1940 channel->ndomains = 1;
1945 if (channel->nsort == -1) {
1946 channel->sortlist = NULL;
1950 if (!channel->lookups) {
1951 channel->lookups = ares_strdup("fb");
1952 if (!channel->lookups)
1958 if(channel->servers) {
1959 ares_free(channel->servers);
1960 channel->servers = NULL;
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;
1970 if(channel->lookups) {
1971 ares_free(channel->lookups);
1972 channel->lookups = NULL;
1975 if(channel->resolvconf_path) {
1976 ares_free(channel->resolvconf_path);
1977 channel->resolvconf_path = NULL;
1982 ares_free(hostname);
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)
1993 /* Set a single search domain. */
1995 while (*q && !ISSPACE(*q))
1998 return set_search(channel, str);
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
2009 static int config_lookup(ares_channel channel, const char *str,
2010 const char *bindch, const char *altbindch,
2013 char lookups[3], *l;
2014 const char *vqualifier p;
2017 if (altbindch == NULL)
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.
2029 if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
2030 if (*p == *bindch || *p == *altbindch) *l++ = 'b';
2034 while (*p && !ISSPACE(*p) && (*p != ','))
2036 while (*p && (ISSPACE(*p) || (*p == ',')))
2040 return ARES_ENOTINITIALIZED;
2042 channel->lookups = ares_strdup(lookups);
2043 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
2045 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
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).
2052 static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
2053 unsigned char netmask,
2054 const unsigned char ipaddr[16])
2056 unsigned char mask[16] = { 0 };
2063 /* Quickly set whole bytes */
2064 memset(mask, 0xFF, netmask / 8);
2066 /* Set remaining bits */
2068 mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
2071 for (i=0; i<16; i++) {
2072 if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
2079 /* Return true iff the IPv6 ipaddr is blacklisted. */
2080 static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
2082 /* A list of blacklisted IPv6 subnets. */
2084 const unsigned char netbase[16];
2085 unsigned char netmask;
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.
2093 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2094 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
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))
2110 /* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
2111 * servers list, updating servers and nservers as required.
2113 * This will silently ignore blacklisted IPv6 nameservers as detected by
2114 * ares_ipv6_server_blacklisted().
2116 * Returns an error code on failure, else ARES_SUCCESS.
2118 static int config_nameserver(struct server_state **servers, int *nservers,
2121 struct ares_addr host;
2122 struct server_state *newserv;
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.
2129 /* Skip whitespace and commas. */
2130 while (*p && (ISSPACE(*p) || (*p == ',')))
2133 /* No more input, done. */
2136 /* Pointer to start of IPv4 or IPv6 address part. */
2139 /* Advance past this address. */
2140 while (*p && !ISSPACE(*p) && (*p != ','))
2143 /* Null terminate this address. */
2146 /* Reached end of input, done when this address is processed. */
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;
2160 /* Resize servers state array. */
2161 newserv = ares_realloc(*servers, (*nservers + 1) *
2162 sizeof(struct server_state));
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));
2174 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
2175 sizeof(host.addrV6));
2177 /* Update arguments. */
2182 return ARES_SUCCESS;
2184 #endif /* !WATT32 */
2186 static int config_sortlist(struct apattern **sortlist, int *nsort,
2189 struct apattern pat;
2192 /* Add sortlist entries. */
2193 while (*str && *str != ';')
2196 char ipbuf[16], ipbufpfx[32];
2197 /* Find just the IP */
2199 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
2201 memcpy(ipbuf, str, q-str);
2202 ipbuf[q-str] = '\0';
2203 /* Find the prefix */
2206 const char *str2 = q+1;
2207 while (*q && *q != ';' && !ISSPACE(*q))
2209 memcpy(ipbufpfx, str, q-str);
2210 ipbufpfx[q-str] = '\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,
2219 sizeof(pat.addrV6))) > 0)
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);
2230 else if (ipbufpfx[0] &&
2231 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
2232 sizeof(pat.addrV4))) > 0)
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);
2243 /* See if it is just a regular IP */
2244 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
2248 memcpy(ipbuf, str, q-str);
2249 ipbuf[q-str] = '\0';
2250 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
2255 pat.family = AF_INET;
2256 pat.type = PATTERN_MASK;
2257 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2258 ares_free(*sortlist);
2265 while (*q && *q != ';' && !ISSPACE(*q))
2269 while (ISSPACE(*str))
2273 return ARES_SUCCESS;
2276 static int set_search(ares_channel channel, const char *str)
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 */
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;
2295 return ARES_SUCCESS;
2298 static int set_options(ares_channel channel, const char *str)
2300 const char *p, *q, *val;
2306 while (*q && !ISSPACE(*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;
2325 return ARES_SUCCESS;
2328 static const char *try_option(const char *p, const char *q, const char *opt)
2330 size_t len = strlen(opt);
2331 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
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)
2343 /* no line or no option */
2344 return NULL; /* LCOV_EXCL_LINE */
2346 /* Hash '#' character is always used as primary comment char, additionally
2347 a not-NUL secondary comment char will be considered when specified. */
2349 /* trim line comment */
2352 while (*p && (*p != '#') && (*p != scc))
2355 while (*p && (*p != '#'))
2359 /* trim trailing whitespace */
2361 while ((q >= s) && ISSPACE(*q))
2365 /* skip leading whitespace */
2367 while (*p && ISSPACE(*p))
2374 if ((len = strlen(opt)) == 0)
2376 return NULL; /* LCOV_EXCL_LINE */
2378 if (strncmp(p, opt, len) != 0)
2379 /* line and option do not match */
2382 /* skip over given option name */
2386 /* no option value */
2387 return NULL; /* LCOV_EXCL_LINE */
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 '=' */
2394 /* skip over whitespace */
2395 while (*p && ISSPACE(*p))
2399 /* no option value */
2402 /* return pointer to option value */
2405 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
2407 static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
2410 /* Four octets and three periods yields at most 15 characters. */
2414 if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
2420 static void natural_mask(struct apattern *pat)
2422 struct in_addr addr;
2424 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
2427 addr.s_addr = ntohl(pat->addrV4.s_addr);
2429 /* This is out of date in the CIDR world, but some people might
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);
2437 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
2440 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
2441 struct apattern *pat)
2443 struct apattern *newsort;
2444 newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
2447 newsort[*nsort] = *pat;
2448 *sortlist = newsort;
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
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
2460 static void randomize_key(unsigned char* key,int key_data_len)
2466 if (ares_fpSystemFunction036)
2468 res = (*ares_fpSystemFunction036) (key, key_data_len);
2474 FILE *f = fopen(RANDOM_FILE, "rb");
2476 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2483 for (;counter<key_data_len;counter++)
2484 key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2488 static int init_id_key(rc4_key* key,int key_data_len)
2490 unsigned char index1;
2491 unsigned char index2;
2492 unsigned char* state;
2494 unsigned char *key_data_ptr = 0;
2496 key_data_ptr = ares_malloc(key_data_len);
2499 memset(key_data_ptr, 0, key_data_len);
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);
2510 for(counter = 0; counter < 256; counter++)
2512 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2514 ARES_SWAP_BYTE(&state[counter], &state[index2]);
2516 index1 = (unsigned char)((index1 + 1) % key_data_len);
2518 ares_free(key_data_ptr);
2519 return ARES_SUCCESS;
2522 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2524 channel->local_ip4 = local_ip;
2527 /* local_ip6 should be 16 bytes in length */
2528 void ares_set_local_ip6(ares_channel channel,
2529 const unsigned char* local_ip6)
2531 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2534 /* local_dev_name should be null terminated. */
2535 void ares_set_local_dev(ares_channel channel,
2536 const char* local_dev_name)
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;
2544 void ares_set_socket_callback(ares_channel channel,
2545 ares_sock_create_callback cb,
2548 channel->sock_create_cb = cb;
2549 channel->sock_create_cb_data = data;
2552 void ares_set_socket_configure_callback(ares_channel channel,
2553 ares_sock_config_callback cb,
2556 channel->sock_config_cb = cb;
2557 channel->sock_config_cb_data = data;
2560 void ares_set_socket_functions(ares_channel channel,
2561 const struct ares_socket_functions * funcs,
2564 channel->sock_funcs = funcs;
2565 channel->sock_func_cb_data = data;
2568 int ares_set_sortlist(ares_channel channel, const char *sortstr)
2571 struct apattern *sortlist = NULL;
2575 return ARES_ENODATA;
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;
2587 void ares__init_servers_state(ares_channel channel)
2589 struct server_state *server;
2592 for (i = 0; i < channel->nservers; i++)
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;