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 #include "ares_nameser.h"
38 #if defined(ANDROID) || defined(__ANDROID__)
39 #include <sys/system_properties.h>
40 #include "ares_android.h"
41 /* From the Bionic sources */
42 #define DNS_PROP_NAME_PREFIX "net.dns"
43 #define MAX_DNS_PROPERTIES 8
46 #if defined(CARES_USE_LIBRESOLV)
51 #include "ares_inet_net_pton.h"
52 #include "ares_library_init.h"
53 #include "ares_nowarn.h"
54 #include "ares_platform.h"
55 #include "ares_private.h"
58 #undef WIN32 /* Redefined in MingW/MSVC headers */
61 static int init_by_options(ares_channel channel,
62 const struct ares_options *options,
64 static int init_by_environment(ares_channel channel);
65 static int init_by_resolv_conf(ares_channel channel);
66 static int init_by_defaults(ares_channel channel);
69 static int config_nameserver(struct server_state **servers, int *nservers,
72 static int set_search(ares_channel channel, const char *str);
73 static int set_options(ares_channel channel, const char *str);
74 static const char *try_option(const char *p, const char *q, const char *opt);
75 static int init_id_key(rc4_key* key,int key_data_len);
77 static int config_sortlist(struct apattern **sortlist, int *nsort,
79 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
80 struct apattern *pat);
81 static int ip_addr(const char *s, ares_ssize_t len, struct in_addr *addr);
82 static void natural_mask(struct apattern *pat);
83 #if !defined(WIN32) && !defined(WATT32) && \
84 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
85 static int config_domain(ares_channel channel, char *str);
86 static int config_lookup(ares_channel channel, const char *str,
87 const char *bindch, const char *altbindch,
89 static char *try_config(char *s, const char *opt, char scc);
92 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
95 x->ndots > -1 && x->timeout > -1 && \
98 int ares_init(ares_channel *channelptr)
100 return ares_init_options(channelptr, NULL, 0);
103 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
106 ares_channel channel;
108 int status = ARES_SUCCESS;
111 if (ares_library_initialized() != ARES_SUCCESS)
112 return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
114 channel = ares_malloc(sizeof(struct ares_channeldata));
122 /* Set everything to distinguished values so we know they haven't
126 channel->timeout = -1;
129 channel->rotate = -1;
130 channel->udp_port = -1;
131 channel->tcp_port = -1;
132 channel->ednspsz = -1;
133 channel->socket_send_buffer_size = -1;
134 channel->socket_receive_buffer_size = -1;
135 channel->nservers = -1;
136 channel->ndomains = -1;
138 channel->tcp_connection_generation = 0;
139 channel->lookups = NULL;
140 channel->domains = NULL;
141 channel->sortlist = NULL;
142 channel->servers = NULL;
143 channel->sock_state_cb = NULL;
144 channel->sock_state_cb_data = NULL;
145 channel->sock_create_cb = NULL;
146 channel->sock_create_cb_data = NULL;
147 channel->sock_config_cb = NULL;
148 channel->sock_config_cb_data = NULL;
149 channel->sock_funcs = NULL;
150 channel->sock_func_cb_data = NULL;
151 channel->resolvconf_path = NULL;
153 channel->last_server = 0;
154 channel->last_timeout_processed = (time_t)now.tv_sec;
156 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
157 channel->local_ip4 = 0;
158 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
160 /* Initialize our lists of queries */
161 ares__init_list_head(&(channel->all_queries));
162 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
164 ares__init_list_head(&(channel->queries_by_qid[i]));
166 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
168 ares__init_list_head(&(channel->queries_by_timeout[i]));
171 /* Initialize configuration by each of the four sources, from highest
172 * precedence to lowest.
175 status = init_by_options(channel, options, optmask);
176 if (status != ARES_SUCCESS) {
177 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
178 ares_strerror(status)));
179 /* If we fail to apply user-specified options, fail the whole init process */
182 status = init_by_environment(channel);
183 if (status != ARES_SUCCESS)
184 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
185 ares_strerror(status)));
186 if (status == ARES_SUCCESS) {
187 status = init_by_resolv_conf(channel);
188 if (status != ARES_SUCCESS)
189 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
190 ares_strerror(status)));
194 * No matter what failed or succeeded, seed defaults to provide
195 * useful behavior for things that we missed.
197 status = init_by_defaults(channel);
198 if (status != ARES_SUCCESS)
199 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
200 ares_strerror(status)));
202 /* Generate random key */
204 if (status == ARES_SUCCESS) {
205 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
206 if (status == ARES_SUCCESS)
207 channel->next_id = ares__generate_new_id(&channel->id_key);
209 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
210 ares_strerror(status)));
214 if (status != ARES_SUCCESS)
216 /* Something failed; clean up memory we may have allocated. */
217 if (channel->servers)
218 ares_free(channel->servers);
219 if (channel->ndomains != -1)
220 ares_strsplit_free(channel->domains, channel->ndomains);
221 if (channel->sortlist)
222 ares_free(channel->sortlist);
224 ares_free(channel->lookups);
225 if(channel->resolvconf_path)
226 ares_free(channel->resolvconf_path);
231 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
232 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
233 channel->nservers = 1;
235 ares__init_servers_state(channel);
237 *channelptr = channel;
241 /* ares_dup() duplicates a channel handle with all its options and returns a
242 new channel handle */
243 int ares_dup(ares_channel *dest, ares_channel src)
245 struct ares_options opts;
246 struct ares_addr_port_node *servers;
247 int non_v4_default_port = 0;
251 *dest = NULL; /* in case of failure return NULL explicitly */
253 /* First get the options supported by the old ares_save_options() function,
254 which is most of them */
255 rc = ares_save_options(src, &opts, &optmask);
258 ares_destroy_options(&opts);
262 /* Then create the new channel with those options */
263 rc = ares_init_options(dest, &opts, optmask);
265 /* destroy the options copy to not leak any memory */
266 ares_destroy_options(&opts);
271 /* Now clone the options that ares_save_options() doesn't support. */
272 (*dest)->sock_create_cb = src->sock_create_cb;
273 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
274 (*dest)->sock_config_cb = src->sock_config_cb;
275 (*dest)->sock_config_cb_data = src->sock_config_cb_data;
276 (*dest)->sock_funcs = src->sock_funcs;
277 (*dest)->sock_func_cb_data = src->sock_func_cb_data;
279 strncpy((*dest)->local_dev_name, src->local_dev_name,
280 sizeof((*dest)->local_dev_name));
281 (*dest)->local_ip4 = src->local_ip4;
282 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
284 /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
285 for (i = 0; i < src->nservers; i++)
287 if ((src->servers[i].addr.family != AF_INET) ||
288 (src->servers[i].addr.udp_port != 0) ||
289 (src->servers[i].addr.tcp_port != 0)) {
290 non_v4_default_port++;
294 if (non_v4_default_port) {
295 rc = ares_get_servers_ports(src, &servers);
296 if (rc != ARES_SUCCESS) {
301 rc = ares_set_servers_ports(*dest, servers);
302 ares_free_data(servers);
303 if (rc != ARES_SUCCESS) {
310 return ARES_SUCCESS; /* everything went fine */
313 /* Save options from initialized channel */
314 int ares_save_options(ares_channel channel, struct ares_options *options,
318 int ipv4_nservers = 0;
320 /* Zero everything out */
321 memset(options, 0, sizeof(struct ares_options));
323 if (!ARES_CONFIG_CHECK(channel))
326 /* Traditionally the optmask wasn't saved in the channel struct so it was
327 recreated here. ROTATE is the first option that has no struct field of
328 its own in the public config struct */
329 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
330 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
331 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
332 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
333 (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
335 if (channel->resolvconf_path)
336 (*optmask) |= ARES_OPT_RESOLVCONF;
338 /* Copy easy stuff */
339 options->flags = channel->flags;
341 /* We return full millisecond resolution but that's only because we don't
342 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
343 options->timeout = channel->timeout;
344 options->tries = channel->tries;
345 options->ndots = channel->ndots;
346 options->udp_port = ntohs(aresx_sitous(channel->udp_port));
347 options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
348 options->sock_state_cb = channel->sock_state_cb;
349 options->sock_state_cb_data = channel->sock_state_cb_data;
351 /* Copy IPv4 servers that use the default port */
352 if (channel->nservers) {
353 for (i = 0; i < channel->nservers; i++)
355 if ((channel->servers[i].addr.family == AF_INET) &&
356 (channel->servers[i].addr.udp_port == 0) &&
357 (channel->servers[i].addr.tcp_port == 0))
361 options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
362 if (!options->servers)
364 for (i = j = 0; i < channel->nservers; i++)
366 if ((channel->servers[i].addr.family == AF_INET) &&
367 (channel->servers[i].addr.udp_port == 0) &&
368 (channel->servers[i].addr.tcp_port == 0))
369 memcpy(&options->servers[j++],
370 &channel->servers[i].addr.addrV4,
371 sizeof(channel->servers[i].addr.addrV4));
375 options->nservers = ipv4_nservers;
378 if (channel->ndomains) {
379 options->domains = ares_malloc(channel->ndomains * sizeof(char *));
380 if (!options->domains)
383 for (i = 0; i < channel->ndomains; i++)
385 options->ndomains = i;
386 options->domains[i] = ares_strdup(channel->domains[i]);
387 if (!options->domains[i])
391 options->ndomains = channel->ndomains;
394 if (channel->lookups) {
395 options->lookups = ares_strdup(channel->lookups);
396 if (!options->lookups && channel->lookups)
401 if (channel->nsort) {
402 options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
403 if (!options->sortlist)
405 for (i = 0; i < channel->nsort; i++)
406 options->sortlist[i] = channel->sortlist[i];
408 options->nsort = channel->nsort;
410 /* copy path for resolv.conf file */
411 if (channel->resolvconf_path) {
412 options->resolvconf_path = ares_strdup(channel->resolvconf_path);
413 if (!options->resolvconf_path)
420 static int init_by_options(ares_channel channel,
421 const struct ares_options *options,
427 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
428 channel->flags = options->flags;
429 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
430 channel->timeout = options->timeout;
431 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
432 channel->timeout = options->timeout * 1000;
433 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
434 channel->tries = options->tries;
435 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
436 channel->ndots = options->ndots;
437 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
439 if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
441 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
442 channel->udp_port = htons(options->udp_port);
443 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
444 channel->tcp_port = htons(options->tcp_port);
445 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
447 channel->sock_state_cb = options->sock_state_cb;
448 channel->sock_state_cb_data = options->sock_state_cb_data;
450 if ((optmask & ARES_OPT_SOCK_SNDBUF)
451 && channel->socket_send_buffer_size == -1)
452 channel->socket_send_buffer_size = options->socket_send_buffer_size;
453 if ((optmask & ARES_OPT_SOCK_RCVBUF)
454 && channel->socket_receive_buffer_size == -1)
455 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
457 if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
458 channel->ednspsz = options->ednspsz;
460 /* Copy the IPv4 servers, if given. */
461 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
463 /* Avoid zero size allocations at any cost */
464 if (options->nservers > 0)
467 ares_malloc(options->nservers * sizeof(struct server_state));
468 if (!channel->servers)
470 for (i = 0; i < options->nservers; i++)
472 channel->servers[i].addr.family = AF_INET;
473 channel->servers[i].addr.udp_port = 0;
474 channel->servers[i].addr.tcp_port = 0;
475 memcpy(&channel->servers[i].addr.addrV4,
476 &options->servers[i],
477 sizeof(channel->servers[i].addr.addrV4));
480 channel->nservers = options->nservers;
483 /* Copy the domains, if given. Keep channel->ndomains consistent so
484 * we can clean up in case of error.
486 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
488 /* Avoid zero size allocations at any cost */
489 if (options->ndomains > 0)
491 channel->domains = ares_malloc(options->ndomains * sizeof(char *));
492 if (!channel->domains)
494 for (i = 0; i < options->ndomains; i++)
496 channel->ndomains = i;
497 channel->domains[i] = ares_strdup(options->domains[i]);
498 if (!channel->domains[i])
502 channel->ndomains = options->ndomains;
505 /* Set lookups, if given. */
506 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
508 channel->lookups = ares_strdup(options->lookups);
509 if (!channel->lookups)
514 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1)) {
515 if (options->nsort > 0) {
516 channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
517 if (!channel->sortlist)
519 for (i = 0; i < options->nsort; i++)
520 channel->sortlist[i] = options->sortlist[i];
522 channel->nsort = options->nsort;
525 /* Set path for resolv.conf file, if given. */
526 if ((optmask & ARES_OPT_RESOLVCONF) && !channel->resolvconf_path)
528 channel->resolvconf_path = ares_strdup(options->resolvconf_path);
529 if (!channel->resolvconf_path && options->resolvconf_path)
533 channel->optmask = optmask;
538 static int init_by_environment(ares_channel channel)
540 const char *localdomain, *res_options;
543 localdomain = getenv("LOCALDOMAIN");
544 if (localdomain && channel->ndomains == -1)
546 status = set_search(channel, localdomain);
547 if (status != ARES_SUCCESS)
551 res_options = getenv("RES_OPTIONS");
554 status = set_options(channel, res_options);
555 if (status != ARES_SUCCESS)
556 return status; /* LCOV_EXCL_LINE: set_options() never fails */
566 * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
567 * to the name of the registry leaf key to be queried, fetch it's string
568 * value and return a pointer in *outptr to a newly allocated memory area
569 * holding it as a null-terminated string.
571 * Returns 0 and nullifies *outptr upon inability to return a string value.
573 * Returns 1 and sets *outptr when returning a dynamically allocated string.
575 * Supported on Windows NT 3.5 and newer.
577 static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
584 /* Find out size of string stored in registry */
585 res = RegQueryValueExA(hKey, leafKeyName, 0, NULL, NULL, &size);
586 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
589 /* Allocate buffer of indicated size plus one given that string
590 might have been stored without null termination */
591 *outptr = ares_malloc(size+1);
595 /* Get the value for real */
596 res = RegQueryValueExA(hKey, leafKeyName, 0, NULL,
597 (unsigned char *)*outptr, &size);
598 if ((res != ERROR_SUCCESS) || (size == 1))
605 /* Null terminate buffer allways */
606 *(*outptr + size) = '\0';
614 * Functionally identical to get_REG_SZ()
616 * Supported on Windows 95, 98 and ME.
618 static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
626 /* Find out size of string stored in registry */
627 res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType, NULL, &size);
628 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
631 /* Allocate buffer of indicated size plus one given that string
632 might have been stored without null termination */
633 *outptr = ares_malloc(size+1);
637 /* Get the value for real */
638 res = RegQueryValueExA(hKey, leafKeyName, 0, &dataType,
639 (unsigned char *)*outptr, &size);
640 if ((res != ERROR_SUCCESS) || (size == 1))
647 /* Null terminate buffer allways */
648 *(*outptr + size) = '\0';
656 * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
657 * pointer to the name of the registry leaf key to be queried, parent key
658 * is enumerated searching in child keys for given leaf key name and its
659 * associated string value. When located, this returns a pointer in *outptr
660 * to a newly allocated memory area holding it as a null-terminated string.
662 * Returns 0 and nullifies *outptr upon inability to return a string value.
664 * Returns 1 and sets *outptr when returning a dynamically allocated string.
666 * Supported on Windows NT 3.5 and newer.
668 static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
671 char enumKeyName[256];
672 DWORD enumKeyNameBuffSize;
673 DWORD enumKeyIdx = 0;
682 enumKeyNameBuffSize = sizeof(enumKeyName);
683 res = RegEnumKeyExA(hKeyParent, enumKeyIdx++, enumKeyName,
684 &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
685 if (res != ERROR_SUCCESS)
687 res = RegOpenKeyExA(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
689 if (res != ERROR_SUCCESS)
691 gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
692 RegCloseKey(hKeyEnum);
704 * get_DNS_Registry_9X()
706 * Functionally identical to get_DNS_Registry()
708 * Implementation supports Windows 95, 98 and ME.
710 static int get_DNS_Registry_9X(char **outptr)
718 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
720 if (res != ERROR_SUCCESS)
723 gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
724 RegCloseKey(hKey_VxD_MStcp);
726 if (!gotString || !*outptr)
733 * get_DNS_Registry_NT()
735 * Functionally identical to get_DNS_Registry()
737 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
739 * Implementation supports Windows NT 3.5 and newer.
741 static int get_DNS_Registry_NT(char **outptr)
743 HKEY hKey_Interfaces = NULL;
744 HKEY hKey_Tcpip_Parameters;
750 res = RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
751 &hKey_Tcpip_Parameters);
752 if (res != ERROR_SUCCESS)
756 ** Global DNS settings override adapter specific parameters when both
757 ** are set. Additionally static DNS settings override DHCP-configured
758 ** parameters when both are set.
761 /* Global DNS static parameters */
762 gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
766 /* Global DNS DHCP-configured parameters */
767 gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
771 /* Try adapter specific parameters */
772 res = RegOpenKeyExA(hKey_Tcpip_Parameters, "Interfaces", 0,
773 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
775 if (res != ERROR_SUCCESS)
777 hKey_Interfaces = NULL;
781 /* Adapter specific DNS static parameters */
782 gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
786 /* Adapter specific DNS DHCP-configured parameters */
787 gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
791 RegCloseKey(hKey_Interfaces);
793 RegCloseKey(hKey_Tcpip_Parameters);
795 if (!gotString || !*outptr)
804 * Locates DNS info in the registry. When located, this returns a pointer
805 * in *outptr to a newly allocated memory area holding a null-terminated
806 * string with a space or comma seperated list of DNS IP addresses.
808 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
810 * Returns 1 and sets *outptr when returning a dynamically allocated string.
812 static int get_DNS_Registry(char **outptr)
814 win_platform platform;
819 platform = ares__getplatform();
821 if (platform == WIN_NT)
822 gotString = get_DNS_Registry_NT(outptr);
823 else if (platform == WIN_9X)
824 gotString = get_DNS_Registry_9X(outptr);
832 static void commanjoin(char** dst, const char* const src, const size_t len)
837 /* 1 for terminating 0 and 2 for , and terminating 0 */
838 newsize = len + (*dst ? (strlen(*dst) + 2) : 1);
839 newbuf = ares_realloc(*dst, newsize);
845 if (strlen(*dst) != 0)
847 strncat(*dst, src, len);
855 static void commajoin(char **dst, const char *src)
857 commanjoin(dst, src, strlen(src));
861 * get_DNS_NetworkParams()
863 * Locates DNS info using GetNetworkParams() function from the Internet
864 * Protocol Helper (IP Helper) API. When located, this returns a pointer
865 * in *outptr to a newly allocated memory area holding a null-terminated
866 * string with a space or comma seperated list of DNS IP addresses.
868 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
870 * Returns 1 and sets *outptr when returning a dynamically allocated string.
872 * Implementation supports Windows 98 and newer.
874 * Note: Ancient PSDK required in order to build a W98 target.
876 static int get_DNS_NetworkParams(char **outptr)
878 FIXED_INFO *fi, *newfi;
879 struct ares_addr namesrvr;
881 IP_ADDR_STRING *ipAddr;
883 DWORD size = sizeof (*fi);
887 /* Verify run-time availability of GetNetworkParams() */
888 if (ares_fpGetNetworkParams == ZERO_NULL)
891 fi = ares_malloc(size);
895 res = (*ares_fpGetNetworkParams) (fi, &size);
896 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
899 newfi = ares_realloc(fi, size);
904 res = (*ares_fpGetNetworkParams) (fi, &size);
905 if (res != ERROR_SUCCESS)
908 for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
910 txtaddr = &ipAddr->IpAddress.String[0];
912 /* Validate converting textual address to binary format. */
913 if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
915 if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
916 (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
919 else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
921 if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
922 sizeof(namesrvr.addrV6)) == 0)
928 commajoin(outptr, txtaddr);
944 static BOOL ares_IsWindowsVistaOrGreater(void)
947 memset(&vinfo, 0, sizeof(vinfo));
948 vinfo.dwOSVersionInfoSize = sizeof(vinfo);
950 #pragma warning(push)
951 #pragma warning(disable:4996) /* warning C4996: 'GetVersionExW': was declared deprecated */
953 if (!GetVersionEx(&vinfo) || vinfo.dwMajorVersion < 6)
961 /* A structure to hold the string form of IPv4 and IPv6 addresses so we can
962 * sort them by a metric.
966 /* The metric we sort them by. */
969 /* Original index of the item, used as a secondary sort parameter to make
970 * qsort() stable if the metrics are equal */
973 /* Room enough for the string form of any IPv4 or IPv6 address that
974 * ares_inet_ntop() will create. Based on the existing c-ares practice.
976 char text[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
979 /* Sort Address values \a left and \a right by metric, returning the usual
980 * indicators for qsort().
982 static int compareAddresses(const void *arg1,
985 const Address * const left = arg1;
986 const Address * const right = arg2;
987 /* Lower metric the more preferred */
988 if(left->metric < right->metric) return -1;
989 if(left->metric > right->metric) return 1;
990 /* If metrics are equal, lower original index more preferred */
991 if(left->orig_idx < right->orig_idx) return -1;
992 if(left->orig_idx > right->orig_idx) return 1;
996 /* There can be multiple routes to "the Internet". And there can be different
997 * DNS servers associated with each of the interfaces that offer those routes.
998 * We have to assume that any DNS server can serve any request. But, some DNS
999 * servers may only respond if requested over their associated interface. But
1000 * we also want to use "the preferred route to the Internet" whenever possible
1001 * (and not use DNS servers on a non-preferred route even by forcing request
1002 * to go out on the associated non-preferred interface). i.e. We want to use
1003 * the DNS servers associated with the same interface that we would use to
1004 * make a general request to anything else.
1006 * But, Windows won't sort the DNS servers by the metrics associated with the
1007 * routes and interfaces _even_ though it obviously sends IP packets based on
1008 * those same routes and metrics. So, we must do it ourselves.
1010 * So, we sort the DNS servers by the same metric values used to determine how
1011 * an outgoing IP packet will go, thus effectively using the DNS servers
1012 * associated with the interface that the DNS requests themselves will
1013 * travel. This gives us optimal routing and avoids issues where DNS servers
1014 * won't respond to requests that don't arrive via some specific subnetwork
1015 * (and thus some specific interface).
1017 * This function computes the metric we use to sort. On the interface
1018 * identified by \a luid, it determines the best route to \a dest and combines
1019 * that route's metric with \a interfaceMetric to compute a metric for the
1020 * destination address on that interface. This metric can be used as a weight
1021 * to sort the DNS server addresses associated with each interface (lower is
1024 * Note that by restricting the route search to the specific interface with
1025 * which the DNS servers are associated, this function asks the question "What
1026 * is the metric for sending IP packets to this DNS server?" which allows us
1027 * to sort the DNS servers correctly.
1029 static ULONG getBestRouteMetric(IF_LUID * const luid, /* Can't be const :( */
1030 const SOCKADDR_INET * const dest,
1031 const ULONG interfaceMetric)
1033 /* On this interface, get the best route to that destination. */
1034 MIB_IPFORWARD_ROW2 row;
1035 SOCKADDR_INET ignored;
1036 if(!ares_fpGetBestRoute2 ||
1037 ares_fpGetBestRoute2(/* The interface to use. The index is ignored since we are
1041 /* No specific source address. */
1043 /* Our destination address. */
1047 /* The route row. */
1049 /* The best source address, which we don't need. */
1050 &ignored) != NO_ERROR
1051 /* If the metric is "unused" (-1) or too large for us to add the two
1052 * metrics, use the worst possible, thus sorting this last.
1054 || row.Metric == (ULONG)-1
1055 || row.Metric > ((ULONG)-1) - interfaceMetric) {
1056 /* Return the worst possible metric. */
1060 /* Return the metric value from that row, plus the interface metric.
1063 * http://msdn.microsoft.com/en-us/library/windows/desktop/aa814494(v=vs.85).aspx
1064 * which describes the combination as a "sum".
1066 return row.Metric + interfaceMetric;
1070 * get_DNS_AdaptersAddresses()
1072 * Locates DNS info using GetAdaptersAddresses() function from the Internet
1073 * Protocol Helper (IP Helper) API. When located, this returns a pointer
1074 * in *outptr to a newly allocated memory area holding a null-terminated
1075 * string with a space or comma seperated list of DNS IP addresses.
1077 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1079 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1081 * Implementation supports Windows XP and newer.
1083 #define IPAA_INITIAL_BUF_SZ 15 * 1024
1084 #define IPAA_MAX_TRIES 3
1085 static int get_DNS_AdaptersAddresses(char **outptr)
1087 IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
1088 IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
1089 ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
1090 ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
1091 ULONG AddrFlags = 0;
1092 int trying = IPAA_MAX_TRIES;
1095 /* The capacity of addresses, in elements. */
1096 size_t addressesSize;
1097 /* The number of elements in addresses. */
1098 size_t addressesIndex = 0;
1099 /* The addresses we will sort. */
1103 struct sockaddr *sa;
1104 struct sockaddr_in *sa4;
1105 struct sockaddr_in6 *sa6;
1110 /* Verify run-time availability of GetAdaptersAddresses() */
1111 if (ares_fpGetAdaptersAddresses == ZERO_NULL)
1114 ipaa = ares_malloc(Bufsz);
1118 /* Start with enough room for a few DNS server addresses and we'll grow it
1119 * as we encounter more.
1122 addresses = (Address*)ares_malloc(sizeof(Address) * addressesSize);
1123 if(addresses == NULL) {
1124 /* We need room for at least some addresses to function. */
1129 /* Usually this call suceeds with initial buffer size */
1130 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1132 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
1135 while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
1137 if (Bufsz < ReqBufsz)
1139 newipaa = ares_realloc(ipaa, ReqBufsz);
1145 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1147 if (res == ERROR_SUCCESS)
1150 if (res != ERROR_SUCCESS)
1153 for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1155 if(ipaaEntry->OperStatus != IfOperStatusUp)
1158 /* For each interface, find any associated DNS servers as IPv4 or IPv6
1159 * addresses. For each found address, find the best route to that DNS
1160 * server address _on_ _that_ _interface_ (at this moment in time) and
1161 * compute the resulting total metric, just as Windows routing will do.
1162 * Then, sort all the addresses found by the metric.
1164 for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1166 ipaDNSAddr = ipaDNSAddr->Next)
1168 namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1170 if (namesrvr.sa->sa_family == AF_INET)
1172 if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1173 (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
1176 /* Allocate room for another address, if necessary, else skip. */
1177 if(addressesIndex == addressesSize) {
1178 const size_t newSize = addressesSize + 4;
1179 Address * const newMem =
1180 (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
1181 if(newMem == NULL) {
1185 addressesSize = newSize;
1188 /* Vista required for Luid or Ipv4Metric */
1189 if (ares_IsWindowsVistaOrGreater())
1191 /* Save the address as the next element in addresses. */
1192 addresses[addressesIndex].metric =
1193 getBestRouteMetric(&ipaaEntry->Luid,
1194 (SOCKADDR_INET*)(namesrvr.sa),
1195 ipaaEntry->Ipv4Metric);
1199 addresses[addressesIndex].metric = (ULONG)-1;
1202 /* Record insertion index to make qsort stable */
1203 addresses[addressesIndex].orig_idx = addressesIndex;
1205 if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1206 addresses[addressesIndex].text,
1207 sizeof(addresses[0].text))) {
1212 else if (namesrvr.sa->sa_family == AF_INET6)
1214 if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1215 sizeof(namesrvr.sa6->sin6_addr)) == 0)
1218 /* Allocate room for another address, if necessary, else skip. */
1219 if(addressesIndex == addressesSize) {
1220 const size_t newSize = addressesSize + 4;
1221 Address * const newMem =
1222 (Address*)ares_realloc(addresses, sizeof(Address) * newSize);
1223 if(newMem == NULL) {
1227 addressesSize = newSize;
1230 /* Vista required for Luid or Ipv4Metric */
1231 if (ares_IsWindowsVistaOrGreater())
1233 /* Save the address as the next element in addresses. */
1234 addresses[addressesIndex].metric =
1235 getBestRouteMetric(&ipaaEntry->Luid,
1236 (SOCKADDR_INET*)(namesrvr.sa),
1237 ipaaEntry->Ipv6Metric);
1241 addresses[addressesIndex].metric = (ULONG)-1;
1244 /* Record insertion index to make qsort stable */
1245 addresses[addressesIndex].orig_idx = addressesIndex;
1247 if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1248 addresses[addressesIndex].text,
1249 sizeof(addresses[0].text))) {
1255 /* Skip non-IPv4/IPv6 addresses completely. */
1261 /* Sort all of the textual addresses by their metric (and original index if
1262 * metrics are equal). */
1263 qsort(addresses, addressesIndex, sizeof(*addresses), compareAddresses);
1265 /* Join them all into a single string, removing duplicates. */
1268 for(i = 0; i < addressesIndex; ++i) {
1270 /* Look for this address text appearing previously in the results. */
1271 for(j = 0; j < i; ++j) {
1272 if(strcmp(addresses[j].text, addresses[i].text) == 0) {
1276 /* Iff we didn't emit this address already, emit it now. */
1278 /* Add that to outptr (if we can). */
1279 commajoin(outptr, addresses[i].text);
1285 ares_free(addresses);
1300 * Locates DNS info from Windows employing most suitable methods available at
1301 * run-time no matter which Windows version it is. When located, this returns
1302 * a pointer in *outptr to a newly allocated memory area holding a string with
1303 * a space or comma seperated list of DNS IP addresses, null-terminated.
1305 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1307 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1309 * Implementation supports Windows 95 and newer.
1311 static int get_DNS_Windows(char **outptr)
1313 /* Try using IP helper API GetAdaptersAddresses(). IPv4 + IPv6, also sorts
1314 * DNS servers by interface route metrics to try to use the best DNS server. */
1315 if (get_DNS_AdaptersAddresses(outptr))
1318 /* Try using IP helper API GetNetworkParams(). IPv4 only. */
1319 if (get_DNS_NetworkParams(outptr))
1322 /* Fall-back to registry information */
1323 return get_DNS_Registry(outptr);
1327 * get_SuffixList_Windows()
1329 * Reads the "DNS Suffix Search List" from registry and writes the list items
1330 * whitespace separated to outptr. If the Search List is empty, the
1331 * "Primary Dns Suffix" is written to outptr.
1333 * Returns 0 and nullifies *outptr upon inability to return the suffix list.
1335 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1337 * Implementation supports Windows Server 2003 and newer
1339 static int get_SuffixList_Windows(char **outptr)
1341 HKEY hKey, hKeyEnum;
1343 DWORD keyNameBuffSize;
1349 if (ares__getplatform() != WIN_NT)
1352 /* 1. Global DNS Suffix Search List */
1353 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
1354 KEY_READ, &hKey) == ERROR_SUCCESS)
1356 get_REG_SZ(hKey, SEARCHLIST_KEY, outptr);
1357 if (get_REG_SZ(hKey, DOMAIN_KEY, &p))
1359 commajoin(outptr, p);
1366 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NT_DNSCLIENT, 0,
1367 KEY_READ, &hKey) == ERROR_SUCCESS)
1369 if (get_REG_SZ(hKey, SEARCHLIST_KEY, &p))
1371 commajoin(outptr, p);
1378 /* 2. Connection Specific Search List composed of:
1379 * a. Primary DNS Suffix */
1380 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_DNSCLIENT, 0,
1381 KEY_READ, &hKey) == ERROR_SUCCESS)
1383 if (get_REG_SZ(hKey, PRIMARYDNSSUFFIX_KEY, &p))
1385 commajoin(outptr, p);
1392 /* b. Interface SearchList, Domain, DhcpDomain */
1393 if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY "\\" INTERFACES_KEY, 0,
1394 KEY_READ, &hKey) == ERROR_SUCCESS)
1398 keyNameBuffSize = sizeof(keyName);
1399 if (RegEnumKeyExA(hKey, keyIdx++, keyName, &keyNameBuffSize,
1400 0, NULL, NULL, NULL)
1403 if (RegOpenKeyExA(hKey, keyName, 0, KEY_QUERY_VALUE, &hKeyEnum)
1406 /* p can be comma separated (SearchList) */
1407 if (get_REG_SZ(hKeyEnum, SEARCHLIST_KEY, &p))
1409 commajoin(outptr, p);
1413 if (get_REG_SZ(hKeyEnum, DOMAIN_KEY, &p))
1415 commajoin(outptr, p);
1419 if (get_REG_SZ(hKeyEnum, DHCPDOMAIN_KEY, &p))
1421 commajoin(outptr, p);
1425 RegCloseKey(hKeyEnum);
1430 return *outptr != NULL;
1435 static int init_by_resolv_conf(ares_channel channel)
1437 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1438 !defined(CARES_USE_LIBRESOLV)
1441 int status = -1, nservers = 0, nsort = 0;
1442 struct server_state *servers = NULL;
1443 struct apattern *sortlist = NULL;
1447 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1448 return ARES_SUCCESS;
1450 if (get_DNS_Windows(&line))
1452 status = config_nameserver(&servers, &nservers, line);
1456 if (channel->ndomains == -1 && get_SuffixList_Windows(&line))
1458 status = set_search(channel, line);
1462 if (status == ARES_SUCCESS)
1465 /* Catch the case when all the above checks fail (which happens when there
1466 is no network card or the cable is unplugged) */
1467 status = ARES_EFILE;
1468 #elif defined(__MVS__)
1470 struct __res_state *res = 0;
1473 struct server_state *pserver;
1475 int rc = res_init();
1476 while (rc == -1 && h_errno == TRY_AGAIN) {
1485 v6 = res->__res_extIPv6;
1486 count4 = res->nscount;
1488 count6 = v6->__stat_nscount;
1493 nservers = count4 + count6;
1494 servers = ares_malloc(nservers * sizeof(struct server_state));
1498 memset(servers, 0, nservers * sizeof(struct server_state));
1501 for (int i = 0; i < count4; ++i, ++pserver) {
1502 struct sockaddr_in *addr_in = &(res->nsaddr_list[i]);
1503 pserver->addr.addrV4.s_addr = addr_in->sin_addr.s_addr;
1504 pserver->addr.family = AF_INET;
1505 pserver->addr.udp_port = addr_in->sin_port;
1506 pserver->addr.tcp_port = addr_in->sin_port;
1509 for (int j = 0; j < count6; ++j, ++pserver) {
1510 struct sockaddr_in6 *addr_in = &(v6->__stat_nsaddr_list[j]);
1511 memcpy(&(pserver->addr.addr.addr6), &(addr_in->sin6_addr),
1512 sizeof(addr_in->sin6_addr));
1513 pserver->addr.family = AF_INET6;
1514 pserver->addr.udp_port = addr_in->sin6_port;
1515 pserver->addr.tcp_port = addr_in->sin6_port;
1520 #elif defined(__riscos__)
1522 /* Under RISC OS, name servers are listed in the
1523 system variable Inet$Resolvers, space separated. */
1525 line = getenv("Inet$Resolvers");
1528 char *resolvers = ares_strdup(line), *pos, *space;
1535 space = strchr(pos, ' ');
1538 status = config_nameserver(&servers, &nservers, pos);
1539 if (status != ARES_SUCCESS)
1544 if (status == ARES_SUCCESS)
1547 ares_free(resolvers);
1550 #elif defined(WATT32)
1554 for (i = 0; def_nameservers[i]; i++)
1557 return ARES_SUCCESS; /* use localhost DNS server */
1560 servers = ares_malloc(sizeof(struct server_state));
1563 memset(servers, 0, sizeof(struct server_state));
1565 for (i = 0; def_nameservers[i]; i++)
1567 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1568 servers[i].addr.family = AF_INET;
1569 servers[i].addr.udp_port = 0;
1570 servers[i].addr.tcp_port = 0;
1574 #elif defined(ANDROID) || defined(__ANDROID__)
1580 /* Use the Android connectivity manager to get a list
1581 * of DNS servers. As of Android 8 (Oreo) net.dns#
1582 * system properties are no longer available. Google claims this
1583 * improves privacy. Apps now need the ACCESS_NETWORK_STATE
1584 * permission and must use the ConnectivityManager which
1586 dns_servers = ares_get_android_server_list(MAX_DNS_PROPERTIES, &num_servers);
1587 if (dns_servers != NULL)
1589 for (i = 0; i < num_servers; i++)
1591 status = config_nameserver(&servers, &nservers, dns_servers[i]);
1592 if (status != ARES_SUCCESS)
1596 for (i = 0; i < num_servers; i++)
1598 ares_free(dns_servers[i]);
1600 ares_free(dns_servers);
1602 if (channel->ndomains == -1)
1604 domains = ares_get_android_search_domains_list();
1605 set_search(channel, domains);
1609 # ifdef HAVE___SYSTEM_PROPERTY_GET
1610 /* Old way using the system property still in place as
1611 * a fallback. Older android versions can still use this.
1612 * it's possible for older apps not not have added the new
1613 * permission and we want to try to avoid breaking those.
1615 * We'll only run this if we don't have any dns servers
1616 * because this will get the same ones (if it works). */
1617 if (status != ARES_EOF) {
1618 char propname[PROP_NAME_MAX];
1619 char propvalue[PROP_VALUE_MAX]="";
1620 for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1621 snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1622 if (__system_property_get(propname, propvalue) < 1) {
1627 status = config_nameserver(&servers, &nservers, propvalue);
1628 if (status != ARES_SUCCESS)
1633 # endif /* HAVE___SYSTEM_PROPERTY_GET */
1634 #elif defined(CARES_USE_LIBRESOLV)
1635 struct __res_state res;
1636 memset(&res, 0, sizeof(res));
1637 int result = res_ninit(&res);
1638 if (result == 0 && (res.options & RES_INIT)) {
1641 if (channel->nservers == -1) {
1642 union res_sockaddr_union addr[MAXNS];
1643 int nscount = res_getservers(&res, addr, MAXNS);
1645 for (i = 0; i < nscount; ++i) {
1646 char str[INET6_ADDRSTRLEN];
1648 sa_family_t family = addr[i].sin.sin_family;
1649 if (family == AF_INET) {
1650 ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
1651 } else if (family == AF_INET6) {
1652 ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
1657 config_status = config_nameserver(&servers, &nservers, str);
1658 if (config_status != ARES_SUCCESS) {
1659 status = config_status;
1664 if (channel->ndomains == -1) {
1666 while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1669 channel->domains = ares_malloc(entries * sizeof(char *));
1670 if (!channel->domains) {
1671 status = ARES_ENOMEM;
1674 channel->ndomains = entries;
1675 for (i = 0; i < channel->ndomains; ++i) {
1676 channel->domains[i] = ares_strdup(res.dnsrch[i]);
1677 if (!channel->domains[i])
1678 status = ARES_ENOMEM;
1683 if (channel->ndots == -1)
1684 channel->ndots = res.ndots;
1685 if (channel->tries == -1)
1686 channel->tries = res.retry;
1687 if (channel->rotate == -1)
1688 channel->rotate = res.options & RES_ROTATE;
1689 if (channel->timeout == -1)
1690 channel->timeout = res.retrans * 1000;
1701 const char *resolvconf_path;
1703 /* Don't read resolv.conf and friends if we don't have to */
1704 if (ARES_CONFIG_CHECK(channel))
1705 return ARES_SUCCESS;
1707 /* Only update search domains if they're not already specified */
1708 update_domains = (channel->ndomains == -1);
1710 /* Support path for resolvconf filename set by ares_init_options */
1711 if(channel->resolvconf_path) {
1712 resolvconf_path = channel->resolvconf_path;
1714 resolvconf_path = PATH_RESOLV_CONF;
1717 fp = fopen(resolvconf_path, "r");
1719 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1721 if ((p = try_config(line, "domain", ';')) && update_domains)
1722 status = config_domain(channel, p);
1723 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1724 status = config_lookup(channel, p, "bind", NULL, "file");
1725 else if ((p = try_config(line, "search", ';')) && update_domains)
1726 status = set_search(channel, p);
1727 else if ((p = try_config(line, "nameserver", ';')) &&
1728 channel->nservers == -1)
1729 status = config_nameserver(&servers, &nservers, p);
1730 else if ((p = try_config(line, "sortlist", ';')) &&
1731 channel->nsort == -1)
1732 status = config_sortlist(&sortlist, &nsort, p);
1733 else if ((p = try_config(line, "options", ';')))
1734 status = set_options(channel, p);
1736 status = ARES_SUCCESS;
1737 if (status != ARES_SUCCESS)
1750 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1751 error, strerror(error)));
1752 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1753 status = ARES_EFILE;
1757 if ((status == ARES_EOF) && (!channel->lookups)) {
1758 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1759 fp = fopen("/etc/nsswitch.conf", "r");
1761 while ((status = ares__read_line(fp, &line, &linesize)) ==
1764 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1765 (void)config_lookup(channel, p, "dns", "resolve", "files");
1776 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1777 error, strerror(error)));
1778 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1779 "/etc/nsswitch.conf"));
1782 /* ignore error, maybe we will get luck in next if clause */
1787 if ((status == ARES_EOF) && (!channel->lookups)) {
1788 /* Linux / GNU libc 2.x and possibly others have host.conf */
1789 fp = fopen("/etc/host.conf", "r");
1791 while ((status = ares__read_line(fp, &line, &linesize)) ==
1794 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1796 (void)config_lookup(channel, p, "bind", NULL, "hosts");
1807 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1808 error, strerror(error)));
1809 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1813 /* ignore error, maybe we will get luck in next if clause */
1818 if ((status == ARES_EOF) && (!channel->lookups)) {
1819 /* Tru64 uses /etc/svc.conf */
1820 fp = fopen("/etc/svc.conf", "r");
1822 while ((status = ares__read_line(fp, &line, &linesize)) ==
1825 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1827 (void)config_lookup(channel, p, "bind", NULL, "local");
1838 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1839 error, strerror(error)));
1840 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1843 /* ignore error, default value will be chosen for `channel->lookups` */
1854 /* Handle errors. */
1855 if (status != ARES_EOF)
1857 if (servers != NULL)
1859 if (sortlist != NULL)
1860 ares_free(sortlist);
1864 /* If we got any name server entries, fill them in. */
1867 channel->servers = servers;
1868 channel->nservers = nservers;
1871 /* If we got any sortlist entries, fill them in. */
1874 channel->sortlist = sortlist;
1875 channel->nsort = nsort;
1878 return ARES_SUCCESS;
1881 static int init_by_defaults(ares_channel channel)
1883 char *hostname = NULL;
1884 int rc = ARES_SUCCESS;
1885 #ifdef HAVE_GETHOSTNAME
1889 if (channel->flags == -1)
1891 if (channel->timeout == -1)
1892 channel->timeout = DEFAULT_TIMEOUT;
1893 if (channel->tries == -1)
1894 channel->tries = DEFAULT_TRIES;
1895 if (channel->ndots == -1)
1897 if (channel->rotate == -1)
1898 channel->rotate = 0;
1899 if (channel->udp_port == -1)
1900 channel->udp_port = htons(NAMESERVER_PORT);
1901 if (channel->tcp_port == -1)
1902 channel->tcp_port = htons(NAMESERVER_PORT);
1904 if (channel->ednspsz == -1)
1905 channel->ednspsz = EDNSPACKETSZ;
1907 if (channel->nservers == -1) {
1908 /* If nobody specified servers, try a local named. */
1909 channel->servers = ares_malloc(sizeof(struct server_state));
1910 if (!channel->servers) {
1914 channel->servers[0].addr.family = AF_INET;
1915 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1916 channel->servers[0].addr.udp_port = 0;
1917 channel->servers[0].addr.tcp_port = 0;
1918 channel->nservers = 1;
1921 #if defined(USE_WINSOCK)
1922 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1923 #elif defined(ENAMETOOLONG)
1924 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1925 (SOCKERRNO == EINVAL))
1927 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1930 if (channel->ndomains == -1) {
1931 /* Derive a default domain search list from the kernel hostname,
1932 * or set it to empty if the hostname isn't helpful.
1934 #ifndef HAVE_GETHOSTNAME
1935 channel->ndomains = 0; /* default to none */
1937 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1940 channel->ndomains = 0; /* default to none */
1942 hostname = ares_malloc(len);
1949 res = gethostname(hostname, lenv);
1955 p = ares_realloc(hostname, len);
1964 /* Lets not treat a gethostname failure as critical, since we
1965 * are ok if gethostname doesn't even exist */
1972 dot = strchr(hostname, '.');
1974 /* a dot was found */
1975 channel->domains = ares_malloc(sizeof(char *));
1976 if (!channel->domains) {
1980 channel->domains[0] = ares_strdup(dot + 1);
1981 if (!channel->domains[0]) {
1985 channel->ndomains = 1;
1990 if (channel->nsort == -1) {
1991 channel->sortlist = NULL;
1995 if (!channel->lookups) {
1996 channel->lookups = ares_strdup("fb");
1997 if (!channel->lookups)
2003 if(channel->servers) {
2004 ares_free(channel->servers);
2005 channel->servers = NULL;
2008 if(channel->domains && channel->domains[0])
2009 ares_free(channel->domains[0]);
2010 if(channel->domains) {
2011 ares_free(channel->domains);
2012 channel->domains = NULL;
2015 if(channel->lookups) {
2016 ares_free(channel->lookups);
2017 channel->lookups = NULL;
2020 if(channel->resolvconf_path) {
2021 ares_free(channel->resolvconf_path);
2022 channel->resolvconf_path = NULL;
2027 ares_free(hostname);
2032 #if !defined(WIN32) && !defined(WATT32) && \
2033 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
2034 static int config_domain(ares_channel channel, char *str)
2038 /* Set a single search domain. */
2040 while (*q && !ISSPACE(*q))
2043 return set_search(channel, str);
2046 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
2047 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
2048 /* workaround icc 9.1 optimizer issue */
2049 # define vqualifier volatile
2054 static int config_lookup(ares_channel channel, const char *str,
2055 const char *bindch, const char *altbindch,
2058 char lookups[3], *l;
2059 const char *vqualifier p;
2062 if (altbindch == NULL)
2065 /* Set the lookup order. Only the first letter of each work
2066 * is relevant, and it has to be "b" for DNS or "f" for the
2067 * host file. Ignore everything else.
2074 if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
2075 if (*p == *bindch || *p == *altbindch) *l++ = 'b';
2079 while (*p && !ISSPACE(*p) && (*p != ','))
2081 while (*p && (ISSPACE(*p) || (*p == ',')))
2085 return ARES_ENOTINITIALIZED;
2087 channel->lookups = ares_strdup(lookups);
2088 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
2090 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
2093 /* Validate that the ip address matches the subnet (network base and network
2094 * mask) specified. Addresses are specified in standard Network Byte Order as
2095 * 16 bytes, and the netmask is 0 to 128 (bits).
2097 static int ares_ipv6_subnet_matches(const unsigned char netbase[16],
2098 unsigned char netmask,
2099 const unsigned char ipaddr[16])
2101 unsigned char mask[16] = { 0 };
2108 /* Quickly set whole bytes */
2109 memset(mask, 0xFF, netmask / 8);
2111 /* Set remaining bits */
2113 mask[netmask / 8] = (unsigned char)(0xff << (8 - (netmask % 8)));
2116 for (i=0; i<16; i++) {
2117 if ((netbase[i] & mask[i]) != (ipaddr[i] & mask[i]))
2124 /* Return true iff the IPv6 ipaddr is blacklisted. */
2125 static int ares_ipv6_server_blacklisted(const unsigned char ipaddr[16])
2127 /* A list of blacklisted IPv6 subnets. */
2129 const unsigned char netbase[16];
2130 unsigned char netmask;
2132 /* fec0::/10 was deprecated by [RFC3879] in September 2004. Formerly a
2133 * Site-Local scoped address prefix. These are never valid DNS servers,
2134 * but are known to be returned at least sometimes on Windows and Android.
2138 0xfe, 0xc0, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
2139 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
2146 /* See if ipaddr matches any of the entries in the blacklist. */
2147 for (i = 0; i < sizeof(blacklist) / sizeof(blacklist[0]); ++i) {
2148 if (ares_ipv6_subnet_matches(
2149 blacklist[i].netbase, blacklist[i].netmask, ipaddr))
2155 /* Add the IPv4 or IPv6 nameservers in str (separated by commas) to the
2156 * servers list, updating servers and nservers as required.
2158 * This will silently ignore blacklisted IPv6 nameservers as detected by
2159 * ares_ipv6_server_blacklisted().
2161 * Returns an error code on failure, else ARES_SUCCESS.
2163 static int config_nameserver(struct server_state **servers, int *nservers,
2166 struct ares_addr host;
2167 struct server_state *newserv;
2169 /* On Windows, there may be more than one nameserver specified in the same
2170 * registry key, so we parse input as a space or comma seperated list.
2174 /* Skip whitespace and commas. */
2175 while (*p && (ISSPACE(*p) || (*p == ',')))
2178 /* No more input, done. */
2181 /* Pointer to start of IPv4 or IPv6 address part. */
2184 /* Advance past this address. */
2185 while (*p && !ISSPACE(*p) && (*p != ','))
2188 /* Null terminate this address. */
2191 /* Reached end of input, done when this address is processed. */
2194 /* Convert textual address to binary format. */
2195 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
2196 host.family = AF_INET;
2197 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1
2198 /* Silently skip blacklisted IPv6 servers. */
2199 && !ares_ipv6_server_blacklisted(
2200 (const unsigned char *)&host.addrV6))
2201 host.family = AF_INET6;
2205 /* Resize servers state array. */
2206 newserv = ares_realloc(*servers, (*nservers + 1) *
2207 sizeof(struct server_state));
2211 /* Store address data. */
2212 newserv[*nservers].addr.family = host.family;
2213 newserv[*nservers].addr.udp_port = 0;
2214 newserv[*nservers].addr.tcp_port = 0;
2215 if (host.family == AF_INET)
2216 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
2217 sizeof(host.addrV4));
2219 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
2220 sizeof(host.addrV6));
2222 /* Update arguments. */
2227 return ARES_SUCCESS;
2229 #endif /* !WATT32 */
2231 static int config_sortlist(struct apattern **sortlist, int *nsort,
2234 struct apattern pat;
2237 /* Add sortlist entries. */
2238 while (*str && *str != ';')
2241 char ipbuf[16], ipbufpfx[32];
2242 /* Find just the IP */
2244 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
2246 memcpy(ipbuf, str, q-str);
2247 ipbuf[q-str] = '\0';
2248 /* Find the prefix */
2251 const char *str2 = q+1;
2252 while (*q && *q != ';' && !ISSPACE(*q))
2254 memcpy(ipbufpfx, str, q-str);
2255 ipbufpfx[q-str] = '\0';
2260 /* Lets see if it is CIDR */
2261 /* First we'll try IPv6 */
2262 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
2264 sizeof(pat.addrV6))) > 0)
2266 pat.type = PATTERN_CIDR;
2267 pat.mask.bits = (unsigned short)bits;
2268 pat.family = AF_INET6;
2269 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2270 ares_free(*sortlist);
2275 else if (ipbufpfx[0] &&
2276 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
2277 sizeof(pat.addrV4))) > 0)
2279 pat.type = PATTERN_CIDR;
2280 pat.mask.bits = (unsigned short)bits;
2281 pat.family = AF_INET;
2282 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2283 ares_free(*sortlist);
2288 /* See if it is just a regular IP */
2289 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
2293 memcpy(ipbuf, str, q-str);
2294 ipbuf[q-str] = '\0';
2295 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
2300 pat.family = AF_INET;
2301 pat.type = PATTERN_MASK;
2302 if (!sortlist_alloc(sortlist, nsort, &pat)) {
2303 ares_free(*sortlist);
2310 while (*q && *q != ';' && !ISSPACE(*q))
2314 while (ISSPACE(*str))
2318 return ARES_SUCCESS;
2321 static int set_search(ares_channel channel, const char *str)
2325 if(channel->ndomains != -1) {
2326 /* LCOV_EXCL_START: all callers check ndomains == -1 */
2327 /* if we already have some domains present, free them first */
2328 ares_strsplit_free(channel->domains, channel->ndomains);
2329 channel->domains = NULL;
2330 channel->ndomains = -1;
2331 } /* LCOV_EXCL_STOP */
2333 channel->domains = ares_strsplit(str, ", ", 1, &cnt);
2334 channel->ndomains = (int)cnt;
2335 if (channel->domains == NULL || channel->ndomains == 0) {
2336 channel->domains = NULL;
2337 channel->ndomains = -1;
2340 return ARES_SUCCESS;
2343 static int set_options(ares_channel channel, const char *str)
2345 const char *p, *q, *val;
2351 while (*q && !ISSPACE(*q))
2353 val = try_option(p, q, "ndots:");
2354 if (val && channel->ndots == -1)
2355 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
2356 val = try_option(p, q, "retrans:");
2357 if (val && channel->timeout == -1)
2358 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
2359 val = try_option(p, q, "retry:");
2360 if (val && channel->tries == -1)
2361 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
2362 val = try_option(p, q, "rotate");
2363 if (val && channel->rotate == -1)
2364 channel->rotate = 1;
2370 return ARES_SUCCESS;
2373 static const char *try_option(const char *p, const char *q, const char *opt)
2375 size_t len = strlen(opt);
2376 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
2379 #if !defined(WIN32) && !defined(WATT32) && \
2380 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
2381 static char *try_config(char *s, const char *opt, char scc)
2388 /* no line or no option */
2389 return NULL; /* LCOV_EXCL_LINE */
2391 /* Hash '#' character is always used as primary comment char, additionally
2392 a not-NUL secondary comment char will be considered when specified. */
2394 /* trim line comment */
2397 while (*p && (*p != '#') && (*p != scc))
2400 while (*p && (*p != '#'))
2404 /* trim trailing whitespace */
2406 while ((q >= s) && ISSPACE(*q))
2410 /* skip leading whitespace */
2412 while (*p && ISSPACE(*p))
2419 if ((len = strlen(opt)) == 0)
2421 return NULL; /* LCOV_EXCL_LINE */
2423 if (strncmp(p, opt, len) != 0)
2424 /* line and option do not match */
2427 /* skip over given option name */
2431 /* no option value */
2432 return NULL; /* LCOV_EXCL_LINE */
2434 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
2435 /* whitespace between option name and value is mandatory
2436 for given option names which do not end with ':' or '=' */
2439 /* skip over whitespace */
2440 while (*p && ISSPACE(*p))
2444 /* no option value */
2447 /* return pointer to option value */
2450 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
2452 static int ip_addr(const char *ipbuf, ares_ssize_t len, struct in_addr *addr)
2455 /* Four octets and three periods yields at most 15 characters. */
2459 if (ares_inet_pton(AF_INET, ipbuf, addr) < 1)
2465 static void natural_mask(struct apattern *pat)
2467 struct in_addr addr;
2469 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
2472 addr.s_addr = ntohl(pat->addrV4.s_addr);
2474 /* This is out of date in the CIDR world, but some people might
2477 if (IN_CLASSA(addr.s_addr))
2478 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
2479 else if (IN_CLASSB(addr.s_addr))
2480 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
2482 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
2485 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
2486 struct apattern *pat)
2488 struct apattern *newsort;
2489 newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
2492 newsort[*nsort] = *pat;
2493 *sortlist = newsort;
2498 /* initialize an rc4 key. If possible a cryptographically secure random key
2499 is generated using a suitable function (for example win32's RtlGenRandom as
2501 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
2502 otherwise the code defaults to cross-platform albeit less secure mechanism
2505 static void randomize_key(unsigned char* key,int key_data_len)
2511 if (ares_fpSystemFunction036)
2513 res = (*ares_fpSystemFunction036) (key, key_data_len);
2518 #ifdef CARES_RANDOM_FILE
2519 FILE *f = fopen(CARES_RANDOM_FILE, "rb");
2521 setvbuf(f, NULL, _IONBF, 0);
2522 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2529 for (;counter<key_data_len;counter++)
2530 key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2534 static int init_id_key(rc4_key* key,int key_data_len)
2536 unsigned char index1;
2537 unsigned char index2;
2538 unsigned char* state;
2540 unsigned char *key_data_ptr = 0;
2542 key_data_ptr = ares_malloc(key_data_len);
2545 memset(key_data_ptr, 0, key_data_len);
2547 state = &key->state[0];
2548 for(counter = 0; counter < 256; counter++)
2549 /* unnecessary AND but it keeps some compilers happier */
2550 state[counter] = (unsigned char)(counter & 0xff);
2551 randomize_key(key->state,key_data_len);
2556 for(counter = 0; counter < 256; counter++)
2558 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2560 ARES_SWAP_BYTE(&state[counter], &state[index2]);
2562 index1 = (unsigned char)((index1 + 1) % key_data_len);
2564 ares_free(key_data_ptr);
2565 return ARES_SUCCESS;
2568 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2570 channel->local_ip4 = local_ip;
2573 /* local_ip6 should be 16 bytes in length */
2574 void ares_set_local_ip6(ares_channel channel,
2575 const unsigned char* local_ip6)
2577 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2580 /* local_dev_name should be null terminated. */
2581 void ares_set_local_dev(ares_channel channel,
2582 const char* local_dev_name)
2584 strncpy(channel->local_dev_name, local_dev_name,
2585 sizeof(channel->local_dev_name));
2586 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
2590 void ares_set_socket_callback(ares_channel channel,
2591 ares_sock_create_callback cb,
2594 channel->sock_create_cb = cb;
2595 channel->sock_create_cb_data = data;
2598 void ares_set_socket_configure_callback(ares_channel channel,
2599 ares_sock_config_callback cb,
2602 channel->sock_config_cb = cb;
2603 channel->sock_config_cb_data = data;
2606 void ares_set_socket_functions(ares_channel channel,
2607 const struct ares_socket_functions * funcs,
2610 channel->sock_funcs = funcs;
2611 channel->sock_func_cb_data = data;
2614 int ares_set_sortlist(ares_channel channel, const char *sortstr)
2617 struct apattern *sortlist = NULL;
2621 return ARES_ENODATA;
2623 status = config_sortlist(&sortlist, &nsort, sortstr);
2624 if (status == ARES_SUCCESS && sortlist) {
2625 if (channel->sortlist)
2626 ares_free(channel->sortlist);
2627 channel->sortlist = sortlist;
2628 channel->nsort = nsort;
2633 void ares__init_servers_state(ares_channel channel)
2635 struct server_state *server;
2638 for (i = 0; i < channel->nservers; i++)
2640 server = &channel->servers[i];
2641 server->udp_socket = ARES_SOCKET_BAD;
2642 server->tcp_socket = ARES_SOCKET_BAD;
2643 server->tcp_connection_generation = ++channel->tcp_connection_generation;
2644 server->tcp_lenbuf_pos = 0;
2645 server->tcp_buffer_pos = 0;
2646 server->tcp_buffer = NULL;
2647 server->tcp_length = 0;
2648 server->qhead = NULL;
2649 server->qtail = NULL;
2650 ares__init_list_head(&server->queries_to_server);
2651 server->channel = channel;
2652 server->is_broken = 0;