2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Copyright (C) 2007-2012 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_SYS_TIME_H
28 #ifdef HAVE_SYS_SOCKET_H
29 #include <sys/socket.h>
32 #ifdef HAVE_NETINET_IN_H
33 #include <netinet/in.h>
40 #ifdef HAVE_ARPA_INET_H
41 #include <arpa/inet.h>
44 #ifdef HAVE_ARPA_NAMESER_H
45 # include <arpa/nameser.h>
49 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
50 # include <arpa/nameser_compat.h>
63 #if defined(ANDROID) || defined(__ANDROID__)
64 #include <sys/system_properties.h>
68 #include "inet_net_pton.h"
69 #include "ares_library_init.h"
70 #include "ares_nowarn.h"
71 #include "ares_platform.h"
72 #include "inet_ntop.h"
73 #include "ares_private.h"
76 #undef WIN32 /* Redefined in MingW/MSVC headers */
79 static int init_by_options(ares_channel channel,
80 const struct ares_options *options,
82 static int init_by_environment(ares_channel channel);
83 static int init_by_resolv_conf(ares_channel channel);
84 static int init_by_defaults(ares_channel channel);
87 static int config_nameserver(struct server_state **servers, int *nservers,
90 static int set_search(ares_channel channel, const char *str);
91 static int set_options(ares_channel channel, const char *str);
92 static const char *try_option(const char *p, const char *q, const char *opt);
93 static int init_id_key(rc4_key* key,int key_data_len);
95 #if !defined(WIN32) && !defined(WATT32)
96 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
97 struct apattern *pat);
98 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
99 static void natural_mask(struct apattern *pat);
100 #if !defined(ANDROID) && !defined(__ANDROID__)
101 static int config_domain(ares_channel channel, char *str);
102 static int config_lookup(ares_channel channel, const char *str,
103 const char *bindch, const char *filech);
104 static int config_sortlist(struct apattern **sortlist, int *nsort,
106 static char *try_config(char *s, const char *opt, char scc);
110 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
111 x->nservers > -1 && \
112 x->ndomains > -1 && \
113 x->ndots > -1 && x->timeout > -1 && \
116 int ares_init(ares_channel *channelptr)
118 return ares_init_options(channelptr, NULL, 0);
121 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
124 ares_channel channel;
126 int status = ARES_SUCCESS;
130 const char *env = getenv("CARES_MEMDEBUG");
134 env = getenv("CARES_MEMLIMIT");
137 long num = strtol(env, &endptr, 10);
138 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
143 if (ares_library_initialized() != ARES_SUCCESS)
144 return ARES_ENOTINITIALIZED;
146 channel = malloc(sizeof(struct ares_channeldata));
154 /* Set everything to distinguished values so we know they haven't
158 channel->timeout = -1;
161 channel->rotate = -1;
162 channel->udp_port = -1;
163 channel->tcp_port = -1;
164 channel->socket_send_buffer_size = -1;
165 channel->socket_receive_buffer_size = -1;
166 channel->nservers = -1;
167 channel->ndomains = -1;
169 channel->tcp_connection_generation = 0;
170 channel->lookups = NULL;
171 channel->domains = NULL;
172 channel->sortlist = NULL;
173 channel->servers = NULL;
174 channel->sock_state_cb = NULL;
175 channel->sock_state_cb_data = NULL;
176 channel->sock_create_cb = NULL;
177 channel->sock_create_cb_data = NULL;
179 channel->last_server = 0;
180 channel->last_timeout_processed = (time_t)now.tv_sec;
182 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
183 channel->local_ip4 = 0;
184 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
186 /* Initialize our lists of queries */
187 ares__init_list_head(&(channel->all_queries));
188 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
190 ares__init_list_head(&(channel->queries_by_qid[i]));
192 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
194 ares__init_list_head(&(channel->queries_by_timeout[i]));
197 /* Initialize configuration by each of the four sources, from highest
198 * precedence to lowest.
201 if (status == ARES_SUCCESS) {
202 status = init_by_options(channel, options, optmask);
203 if (status != ARES_SUCCESS)
204 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
205 ares_strerror(status)));
207 if (status == ARES_SUCCESS) {
208 status = init_by_environment(channel);
209 if (status != ARES_SUCCESS)
210 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
211 ares_strerror(status)));
213 if (status == ARES_SUCCESS) {
214 status = init_by_resolv_conf(channel);
215 if (status != ARES_SUCCESS)
216 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
217 ares_strerror(status)));
221 * No matter what failed or succeeded, seed defaults to provide
222 * useful behavior for things that we missed.
224 status = init_by_defaults(channel);
225 if (status != ARES_SUCCESS)
226 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
227 ares_strerror(status)));
229 /* Generate random key */
231 if (status == ARES_SUCCESS) {
232 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
233 if (status == ARES_SUCCESS)
234 channel->next_id = ares__generate_new_id(&channel->id_key);
236 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
237 ares_strerror(status)));
240 if (status != ARES_SUCCESS)
242 /* Something failed; clean up memory we may have allocated. */
243 if (channel->servers)
244 free(channel->servers);
245 if (channel->domains)
247 for (i = 0; i < channel->ndomains; i++)
248 free(channel->domains[i]);
249 free(channel->domains);
251 if (channel->sortlist)
252 free(channel->sortlist);
254 free(channel->lookups);
259 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
260 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
261 channel->nservers = 1;
263 ares__init_servers_state(channel);
265 *channelptr = channel;
269 /* ares_dup() duplicates a channel handle with all its options and returns a
270 new channel handle */
271 int ares_dup(ares_channel *dest, ares_channel src)
273 struct ares_options opts;
274 struct ares_addr_node *servers;
275 int ipv6_nservers = 0;
279 *dest = NULL; /* in case of failure return NULL explicitly */
281 /* First get the options supported by the old ares_save_options() function,
282 which is most of them */
283 rc = ares_save_options(src, &opts, &optmask);
287 /* Then create the new channel with those options */
288 rc = ares_init_options(dest, &opts, optmask);
290 /* destroy the options copy to not leak any memory */
291 ares_destroy_options(&opts);
296 /* Now clone the options that ares_save_options() doesn't support. */
297 (*dest)->sock_create_cb = src->sock_create_cb;
298 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
300 strncpy((*dest)->local_dev_name, src->local_dev_name,
301 sizeof(src->local_dev_name));
302 (*dest)->local_ip4 = src->local_ip4;
303 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
305 /* Full name server cloning required when not all are IPv4 */
306 for (i = 0; i < src->nservers; i++)
308 if (src->servers[i].addr.family != AF_INET) {
314 rc = ares_get_servers(src, &servers);
315 if (rc != ARES_SUCCESS)
317 rc = ares_set_servers(*dest, servers);
318 ares_free_data(servers);
319 if (rc != ARES_SUCCESS)
323 return ARES_SUCCESS; /* everything went fine */
326 /* Save options from initialized channel */
327 int ares_save_options(ares_channel channel, struct ares_options *options,
331 int ipv4_nservers = 0;
333 /* Zero everything out */
334 memset(options, 0, sizeof(struct ares_options));
336 if (!ARES_CONFIG_CHECK(channel))
339 /* Traditionally the optmask wasn't saved in the channel struct so it was
340 recreated here. ROTATE is the first option that has no struct field of
341 its own in the public config struct */
342 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
343 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
344 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
345 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
346 (channel->optmask & ARES_OPT_ROTATE);
348 /* Copy easy stuff */
349 options->flags = channel->flags;
351 /* We return full millisecond resolution but that's only because we don't
352 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
353 options->timeout = channel->timeout;
354 options->tries = channel->tries;
355 options->ndots = channel->ndots;
356 options->udp_port = (unsigned short)channel->udp_port;
357 options->tcp_port = (unsigned short)channel->tcp_port;
358 options->sock_state_cb = channel->sock_state_cb;
359 options->sock_state_cb_data = channel->sock_state_cb_data;
361 /* Copy IPv4 servers */
362 if (channel->nservers) {
363 for (i = 0; i < channel->nservers; i++)
365 if (channel->servers[i].addr.family == AF_INET)
369 options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
370 if (!options->servers)
372 for (i = j = 0; i < channel->nservers; i++)
374 if (channel->servers[i].addr.family == AF_INET)
375 memcpy(&options->servers[j++],
376 &channel->servers[i].addr.addrV4,
377 sizeof(channel->servers[i].addr.addrV4));
381 options->nservers = ipv4_nservers;
384 if (channel->ndomains) {
385 options->domains = malloc(channel->ndomains * sizeof(char *));
386 if (!options->domains)
389 for (i = 0; i < channel->ndomains; i++)
391 options->ndomains = i;
392 options->domains[i] = strdup(channel->domains[i]);
393 if (!options->domains[i])
397 options->ndomains = channel->ndomains;
400 if (channel->lookups) {
401 options->lookups = strdup(channel->lookups);
402 if (!options->lookups && channel->lookups)
407 if (channel->nsort) {
408 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
409 if (!options->sortlist)
411 for (i = 0; i < channel->nsort; i++)
412 options->sortlist[i] = channel->sortlist[i];
414 options->nsort = channel->nsort;
419 static int init_by_options(ares_channel channel,
420 const struct ares_options *options,
426 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
427 channel->flags = options->flags;
428 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
429 channel->timeout = options->timeout;
430 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
431 channel->timeout = options->timeout * 1000;
432 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
433 channel->tries = options->tries;
434 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
435 channel->ndots = options->ndots;
436 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
438 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
439 channel->udp_port = htons(options->udp_port);
440 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
441 channel->tcp_port = htons(options->tcp_port);
442 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
444 channel->sock_state_cb = options->sock_state_cb;
445 channel->sock_state_cb_data = options->sock_state_cb_data;
447 if ((optmask & ARES_OPT_SOCK_SNDBUF)
448 && channel->socket_send_buffer_size == -1)
449 channel->socket_send_buffer_size = options->socket_send_buffer_size;
450 if ((optmask & ARES_OPT_SOCK_RCVBUF)
451 && channel->socket_receive_buffer_size == -1)
452 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
454 /* Copy the IPv4 servers, if given. */
455 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
457 /* Avoid zero size allocations at any cost */
458 if (options->nservers > 0)
461 malloc(options->nservers * sizeof(struct server_state));
462 if (!channel->servers)
464 for (i = 0; i < options->nservers; i++)
466 channel->servers[i].addr.family = AF_INET;
467 memcpy(&channel->servers[i].addr.addrV4,
468 &options->servers[i],
469 sizeof(channel->servers[i].addr.addrV4));
472 channel->nservers = options->nservers;
475 /* Copy the domains, if given. Keep channel->ndomains consistent so
476 * we can clean up in case of error.
478 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
480 /* Avoid zero size allocations at any cost */
481 if (options->ndomains > 0)
483 channel->domains = malloc(options->ndomains * sizeof(char *));
484 if (!channel->domains)
486 for (i = 0; i < options->ndomains; i++)
488 channel->ndomains = i;
489 channel->domains[i] = strdup(options->domains[i]);
490 if (!channel->domains[i])
494 channel->ndomains = options->ndomains;
497 /* Set lookups, if given. */
498 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
500 channel->lookups = strdup(options->lookups);
501 if (!channel->lookups)
506 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
507 (options->nsort>0)) {
508 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
509 if (!channel->sortlist)
511 for (i = 0; i < options->nsort; i++)
512 channel->sortlist[i] = options->sortlist[i];
513 channel->nsort = options->nsort;
516 channel->optmask = optmask;
521 static int init_by_environment(ares_channel channel)
523 const char *localdomain, *res_options;
526 localdomain = getenv("LOCALDOMAIN");
527 if (localdomain && channel->ndomains == -1)
529 status = set_search(channel, localdomain);
530 if (status != ARES_SUCCESS)
534 res_options = getenv("RES_OPTIONS");
537 status = set_options(channel, res_options);
538 if (status != ARES_SUCCESS)
547 * Warning: returns a dynamically allocated buffer, the user MUST
548 * use free() if the function returns 1
550 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
552 /* Test for the size we need */
556 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
557 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
559 *obuf = malloc(size+1);
563 if (RegQueryValueEx(hKey, subkey, 0, NULL,
564 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
577 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
579 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
580 DWORD enum_size = 39;
584 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
585 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
590 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
593 rc = get_res_nt(hVal, subkey, obuf);
602 * The desired output for this method is that we set "ret_buf" to
605 * 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
607 * The only ordering requirement is that primary servers are listed
608 * before secondary. There is no requirement that IPv4 addresses should
609 * necessarily be before IPv6.
611 * Note that ret_size should ideally be big enough to hold around
612 * 2-3 IPv4 and 2-3 IPv6 addresses.
614 * Finally, we need to return the total number of DNS servers located.
616 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
618 const size_t ipv4_size = INET_ADDRSTRLEN + 1; /* +1 for ',' at end */
619 const size_t ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," */
620 long left = ret_size;
624 /* Use the GetAdaptersAddresses method if it's available, otherwise
625 fall back to GetNetworkParams. */
626 if (ares_fpGetAdaptersAddresses != ZERO_NULL)
628 const ULONG working_buf_size = 15000;
629 IP_ADAPTER_ADDRESSES *pFirstEntry = NULL;
630 IP_ADAPTER_ADDRESSES *pEntry = NULL;
634 /* According to MSDN, the recommended way to do this is to use a temporary
635 buffer of 15K, to "dramatically reduce the chance that the
636 GetAdaptersAddresses method returns ERROR_BUFFER_OVERFLOW" */
637 pFirstEntry = (IP_ADAPTER_ADDRESSES *) malloc(working_buf_size);
638 bufSize = working_buf_size;
642 /* Call the method one time */
643 result = (*ares_fpGetAdaptersAddresses)(AF_UNSPEC, 0, 0, pFirstEntry,
645 if(result == ERROR_BUFFER_OVERFLOW)
647 /* Reallocate, bufSize should now be set to the required size */
648 pFirstEntry = (IP_ADAPTER_ADDRESSES *) realloc(pFirstEntry, bufSize);
652 /* Call the method a second time */
653 result = (*ares_fpGetAdaptersAddresses)(AF_UNSPEC, 0, 0, pFirstEntry,
655 if(result == ERROR_BUFFER_OVERFLOW)
657 /* Reallocate, bufSize should now be set to the required size */
658 pFirstEntry = (IP_ADAPTER_ADDRESSES *)realloc(pFirstEntry, bufSize);
662 /* Call the method a third time. The maximum number of times we're
663 going to do this is 3. Three shall be the number thou shalt count,
664 and the number of the counting shall be three. Five is right
666 result = (*ares_fpGetAdaptersAddresses)(AF_UNSPEC, 0, 0, pFirstEntry,
671 /* Check the current result for failure */
672 if(result != ERROR_SUCCESS)
678 /* process the results */
679 for(pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next)
681 IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
682 for(; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next)
684 struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
685 size_t stringlen = 0;
687 if(pGenericAddr->sa_family == AF_INET && left > ipv4_size)
689 /* Handle the v4 case */
690 struct sockaddr_in *pIPv4Addr = (struct sockaddr_in *) pGenericAddr;
692 ares_inet_ntop(AF_INET, &pIPv4Addr->sin_addr, ret,
693 ipv4_size - 1); /* -1 for comma */
695 /* Append a comma to the end, THEN NULL. Should be OK because we
696 already tested the size at the top of the if statement. */
697 stringlen = strlen(ret);
698 ret[ stringlen ] = ',';
699 ret[ stringlen + 1 ] = '\0';
700 ret += stringlen + 1;
701 left -= stringlen + 1;
704 else if(pGenericAddr->sa_family == AF_INET6 && left > ipv6_size)
706 /* Handle the v6 case */
707 struct sockaddr_in6 *pIPv6Addr = (struct sockaddr_in6 *)pGenericAddr;
708 ares_inet_ntop(AF_INET6, &pIPv6Addr->sin6_addr, ret,
709 ipv6_size - 1); /* -1 for comma */
711 /* Append a comma to the end, THEN NULL. Should be OK because we
712 already tested the size at the top of the if statement. */
713 stringlen = strlen(ret);
714 ret[ stringlen ] = ',';
715 ret[ stringlen + 1 ] = '\0';
716 ret += stringlen + 1;
717 left -= stringlen + 1;
720 /* NB on Windows this also returns stuff in the fec0::/10 range,
721 seems to be hard-coded somehow. Do we need to ignore them? */
734 FIXED_INFO *fi, *newfi;
735 DWORD size = sizeof (*fi);
736 IP_ADDR_STRING *ipAddr;
745 res = (*ares_fpGetNetworkParams) (fi, &size);
746 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
749 newfi = realloc(fi, size);
754 res = (*ares_fpGetNetworkParams) (fi, &size);
755 if (res != ERROR_SUCCESS)
760 printf ("Host Name: %s\n", fi->HostName);
761 printf ("Domain Name: %s\n", fi->DomainName);
762 printf ("DNS Servers:\n"
763 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
765 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
766 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
769 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
770 left -= ret - ret_buf;
774 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
775 ipAddr = ipAddr->Next, i++)
777 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
779 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
780 left -= ret - ret_buf;
784 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
791 if (debug && left <= ipv4_size)
792 printf ("Too many nameservers. Truncating to %d addressess", count);
800 static int init_by_resolv_conf(ares_channel channel)
802 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32)
805 int status = -1, nservers = 0, nsort = 0;
806 struct server_state *servers = NULL;
807 struct apattern *sortlist = NULL;
812 NameServer info via IPHLPAPI (IP helper API):
813 GetNetworkParams() should be the trusted source for this.
814 Available in Win-98/2000 and later. If that fail, fall-back to
815 registry information.
819 On Windows 9X, the DNS server can be found in:
820 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
822 On Windows NT/2000/XP/2003:
823 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
825 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
827 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
830 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
840 win_platform platform;
842 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
845 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
847 status = config_nameserver(&servers, &nservers, buf);
848 if (status == ARES_SUCCESS)
852 platform = ares__getplatform();
854 if (platform == WIN_NT)
857 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
861 RegOpenKeyEx(mykey, "Interfaces", 0,
862 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
863 if (get_res_nt(mykey, NAMESERVER, &line))
865 status = config_nameserver(&servers, &nservers, line);
868 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
870 status = config_nameserver(&servers, &nservers, line);
873 /* Try the interfaces */
874 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
876 status = config_nameserver(&servers, &nservers, line);
879 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
881 status = config_nameserver(&servers, &nservers, line);
888 else if (platform == WIN_9X)
891 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
895 if ((result = RegQueryValueEx(
896 mykey, NAMESERVER, NULL, &data_type,
899 ) == ERROR_SUCCESS ||
900 result == ERROR_MORE_DATA)
904 line = malloc(bytes+1);
905 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
906 (unsigned char *)line, &bytes) ==
909 status = config_nameserver(&servers, &nservers, line);
918 if (status == ARES_SUCCESS)
921 /* Catch the case when all the above checks fail (which happens when there
922 is no network card or the cable is unplugged) */
925 #elif defined(__riscos__)
927 /* Under RISC OS, name servers are listed in the
928 system variable Inet$Resolvers, space separated. */
930 line = getenv("Inet$Resolvers");
933 char *resolvers = strdup(line), *pos, *space;
940 space = strchr(pos, ' ');
943 status = config_nameserver(&servers, &nservers, pos);
944 if (status != ARES_SUCCESS)
949 if (status == ARES_SUCCESS)
955 #elif defined(WATT32)
959 for (i = 0; def_nameservers[i]; i++)
962 return ARES_SUCCESS; /* use localhost DNS server */
965 servers = calloc(i, sizeof(struct server_state));
969 for (i = 0; def_nameservers[i]; i++)
971 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
972 servers[i].addr.family = AF_INET;
976 #elif defined(ANDROID) || defined(__ANDROID__)
977 char value[PROP_VALUE_MAX]="";
978 __system_property_get("net.dns1", value);
979 status = config_nameserver(&servers, &nservers, value);
980 if (status == ARES_SUCCESS)
989 /* Don't read resolv.conf and friends if we don't have to */
990 if (ARES_CONFIG_CHECK(channel))
993 fp = fopen(PATH_RESOLV_CONF, "r");
995 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
997 if ((p = try_config(line, "domain", ';')))
998 status = config_domain(channel, p);
999 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1000 status = config_lookup(channel, p, "bind", "file");
1001 else if ((p = try_config(line, "search", ';')))
1002 status = set_search(channel, p);
1003 else if ((p = try_config(line, "nameserver", ';')) &&
1004 channel->nservers == -1)
1005 status = config_nameserver(&servers, &nservers, p);
1006 else if ((p = try_config(line, "sortlist", ';')) &&
1007 channel->nsort == -1)
1008 status = config_sortlist(&sortlist, &nsort, p);
1009 else if ((p = try_config(line, "options", ';')))
1010 status = set_options(channel, p);
1012 status = ARES_SUCCESS;
1013 if (status != ARES_SUCCESS)
1026 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1027 error, strerror(error)));
1028 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1029 status = ARES_EFILE;
1033 if ((status == ARES_EOF) && (!channel->lookups)) {
1034 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1035 fp = fopen("/etc/nsswitch.conf", "r");
1037 while ((status = ares__read_line(fp, &line, &linesize)) ==
1040 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1042 (void)config_lookup(channel, p, "dns", "files");
1054 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1055 error, strerror(error)));
1056 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1057 "/etc/nsswitch.conf"));
1058 status = ARES_EFILE;
1063 if ((status == ARES_EOF) && (!channel->lookups)) {
1064 /* Linux / GNU libc 2.x and possibly others have host.conf */
1065 fp = fopen("/etc/host.conf", "r");
1067 while ((status = ares__read_line(fp, &line, &linesize)) ==
1070 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1072 (void)config_lookup(channel, p, "bind", "hosts");
1084 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1085 error, strerror(error)));
1086 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1088 status = ARES_EFILE;
1093 if ((status == ARES_EOF) && (!channel->lookups)) {
1094 /* Tru64 uses /etc/svc.conf */
1095 fp = fopen("/etc/svc.conf", "r");
1097 while ((status = ares__read_line(fp, &line, &linesize)) ==
1100 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1102 (void)config_lookup(channel, p, "bind", "local");
1114 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1115 error, strerror(error)));
1116 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1117 status = ARES_EFILE;
1128 /* Handle errors. */
1129 if (status != ARES_EOF)
1131 if (servers != NULL)
1133 if (sortlist != NULL)
1138 /* If we got any name server entries, fill them in. */
1144 channel->servers = servers;
1145 channel->nservers = nservers;
1148 /* If we got any sortlist entries, fill them in. */
1151 channel->sortlist = sortlist;
1152 channel->nsort = nsort;
1155 return ARES_SUCCESS;
1158 static int init_by_defaults(ares_channel channel)
1160 char *hostname = NULL;
1161 int rc = ARES_SUCCESS;
1162 #ifdef HAVE_GETHOSTNAME
1166 if (channel->flags == -1)
1168 if (channel->timeout == -1)
1169 channel->timeout = DEFAULT_TIMEOUT;
1170 if (channel->tries == -1)
1171 channel->tries = DEFAULT_TRIES;
1172 if (channel->ndots == -1)
1174 if (channel->rotate == -1)
1175 channel->rotate = 0;
1176 if (channel->udp_port == -1)
1177 channel->udp_port = htons(NAMESERVER_PORT);
1178 if (channel->tcp_port == -1)
1179 channel->tcp_port = htons(NAMESERVER_PORT);
1181 if (channel->nservers == -1) {
1182 /* If nobody specified servers, try a local named. */
1183 channel->servers = malloc(sizeof(struct server_state));
1184 if (!channel->servers) {
1188 channel->servers[0].addr.family = AF_INET;
1189 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1190 channel->nservers = 1;
1193 #if defined(USE_WINSOCK)
1194 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1195 #elif defined(ENAMETOOLONG)
1196 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1197 (SOCKERRNO == EINVAL))
1199 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1202 if (channel->ndomains == -1) {
1203 /* Derive a default domain search list from the kernel hostname,
1204 * or set it to empty if the hostname isn't helpful.
1206 #ifndef HAVE_GETHOSTNAME
1207 channel->ndomains = 0; /* default to none */
1209 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1212 channel->ndomains = 0; /* default to none */
1214 hostname = malloc(len);
1221 res = gethostname(hostname, lenv);
1227 p = realloc(hostname, len);
1242 dot = strchr(hostname, '.');
1244 /* a dot was found */
1245 channel->domains = malloc(sizeof(char *));
1246 if (!channel->domains) {
1250 channel->domains[0] = strdup(dot + 1);
1251 if (!channel->domains[0]) {
1255 channel->ndomains = 1;
1260 if (channel->nsort == -1) {
1261 channel->sortlist = NULL;
1265 if (!channel->lookups) {
1266 channel->lookups = strdup("fb");
1267 if (!channel->lookups)
1273 if(channel->servers) {
1274 free(channel->servers);
1275 channel->servers = NULL;
1278 if(channel->domains && channel->domains[0])
1279 free(channel->domains[0]);
1280 if(channel->domains) {
1281 free(channel->domains);
1282 channel->domains = NULL;
1285 if(channel->lookups) {
1286 free(channel->lookups);
1287 channel->lookups = NULL;
1297 #if !defined(WIN32) && !defined(WATT32)
1298 static int config_domain(ares_channel channel, char *str)
1302 /* Set a single search domain. */
1304 while (*q && !ISSPACE(*q))
1307 return set_search(channel, str);
1310 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1311 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1312 /* workaround icc 9.1 optimizer issue */
1313 # define vqualifier volatile
1318 static int config_lookup(ares_channel channel, const char *str,
1319 const char *bindch, const char *filech)
1321 char lookups[3], *l;
1322 const char *vqualifier p;
1324 /* Set the lookup order. Only the first letter of each work
1325 * is relevant, and it has to be "b" for DNS or "f" for the
1326 * host file. Ignore everything else.
1332 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1333 if (*p == *bindch) *l++ = 'b';
1336 while (*p && !ISSPACE(*p) && (*p != ','))
1338 while (*p && (ISSPACE(*p) || (*p == ',')))
1342 channel->lookups = strdup(lookups);
1343 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1345 #endif /* !WIN32 & !WATT32 */
1348 static int config_nameserver(struct server_state **servers, int *nservers,
1351 struct ares_addr host;
1352 struct server_state *newserv;
1354 /* On Windows, there may be more than one nameserver specified in the same
1355 * registry key, so we parse input as a space or comma seperated list.
1359 /* Skip whitespace and commas. */
1360 while (*p && (ISSPACE(*p) || (*p == ',')))
1363 /* No more input, done. */
1366 /* Pointer to start of IPv4 or IPv6 address part. */
1369 /* Advance past this address. */
1370 while (*p && !ISSPACE(*p) && (*p != ','))
1373 /* Null terminate this address. */
1376 /* Reached end of input, done when this address is processed. */
1379 /* Convert textual address to binary format. */
1380 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1381 host.family = AF_INET;
1382 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1383 host.family = AF_INET6;
1387 /* Resize servers state array. */
1388 newserv = realloc(*servers, (*nservers + 1) *
1389 sizeof(struct server_state));
1393 /* Store address data. */
1394 newserv[*nservers].addr.family = host.family;
1395 if (host.family == AF_INET)
1396 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1397 sizeof(host.addrV4));
1399 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1400 sizeof(host.addrV6));
1402 /* Update arguments. */
1407 return ARES_SUCCESS;
1411 static int config_sortlist(struct apattern **sortlist, int *nsort,
1414 struct apattern pat;
1417 /* Add sortlist entries. */
1418 while (*str && *str != ';')
1421 char ipbuf[16], ipbufpfx[32];
1422 /* Find just the IP */
1424 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1426 memcpy(ipbuf, str, q-str);
1427 ipbuf[q-str] = '\0';
1428 /* Find the prefix */
1431 const char *str2 = q+1;
1432 while (*q && *q != ';' && !ISSPACE(*q))
1434 memcpy(ipbufpfx, str, q-str);
1435 ipbufpfx[q-str] = '\0';
1440 /* Lets see if it is CIDR */
1441 /* First we'll try IPv6 */
1442 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1444 sizeof(pat.addrV6))) > 0)
1446 pat.type = PATTERN_CIDR;
1447 pat.mask.bits = (unsigned short)bits;
1448 pat.family = AF_INET6;
1449 if (!sortlist_alloc(sortlist, nsort, &pat))
1452 else if (ipbufpfx[0] &&
1453 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1454 sizeof(pat.addrV4))) > 0)
1456 pat.type = PATTERN_CIDR;
1457 pat.mask.bits = (unsigned short)bits;
1458 pat.family = AF_INET;
1459 if (!sortlist_alloc(sortlist, nsort, &pat))
1462 /* See if it is just a regular IP */
1463 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1467 memcpy(ipbuf, str, q-str);
1468 ipbuf[q-str] = '\0';
1469 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1474 pat.family = AF_INET;
1475 pat.type = PATTERN_MASK;
1476 if (!sortlist_alloc(sortlist, nsort, &pat))
1481 while (*q && *q != ';' && !ISSPACE(*q))
1485 while (ISSPACE(*str))
1489 return ARES_SUCCESS;
1492 #endif /* !WATT32 */
1494 static int set_search(ares_channel channel, const char *str)
1499 if(channel->ndomains != -1) {
1500 /* if we already have some domains present, free them first */
1501 for(n=0; n < channel->ndomains; n++)
1502 free(channel->domains[n]);
1503 free(channel->domains);
1504 channel->domains = NULL;
1505 channel->ndomains = -1;
1508 /* Count the domains given. */
1513 while (*p && !ISSPACE(*p))
1522 channel->ndomains = 0;
1523 return ARES_SUCCESS;
1526 channel->domains = malloc(n * sizeof(char *));
1527 if (!channel->domains)
1530 /* Now copy the domains. */
1535 channel->ndomains = n;
1537 while (*q && !ISSPACE(*q))
1539 channel->domains[n] = malloc(q - p + 1);
1540 if (!channel->domains[n])
1542 memcpy(channel->domains[n], p, q - p);
1543 channel->domains[n][q - p] = 0;
1549 channel->ndomains = n;
1551 return ARES_SUCCESS;
1554 static int set_options(ares_channel channel, const char *str)
1556 const char *p, *q, *val;
1562 while (*q && !ISSPACE(*q))
1564 val = try_option(p, q, "ndots:");
1565 if (val && channel->ndots == -1)
1566 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1567 val = try_option(p, q, "retrans:");
1568 if (val && channel->timeout == -1)
1569 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1570 val = try_option(p, q, "retry:");
1571 if (val && channel->tries == -1)
1572 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1573 val = try_option(p, q, "rotate");
1574 if (val && channel->rotate == -1)
1575 channel->rotate = 1;
1581 return ARES_SUCCESS;
1584 static const char *try_option(const char *p, const char *q, const char *opt)
1586 size_t len = strlen(opt);
1587 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1590 #if !defined(WIN32) && !defined(WATT32)
1591 static char *try_config(char *s, const char *opt, char scc)
1598 /* no line or no option */
1601 /* Hash '#' character is always used as primary comment char, additionally
1602 a not-NUL secondary comment char will be considered when specified. */
1604 /* trim line comment */
1607 while (*p && (*p != '#') && (*p != scc))
1610 while (*p && (*p != '#'))
1614 /* trim trailing whitespace */
1616 while ((q >= s) && ISSPACE(*q))
1620 /* skip leading whitespace */
1622 while (*p && ISSPACE(*p))
1629 if ((len = strlen(opt)) == 0)
1633 if (strncmp(p, opt, len) != 0)
1634 /* line and option do not match */
1637 /* skip over given option name */
1641 /* no option value */
1644 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1645 /* whitespace between option name and value is mandatory
1646 for given option names which do not end with ':' or '=' */
1649 /* skip over whitespace */
1650 while (*p && ISSPACE(*p))
1654 /* no option value */
1657 /* return pointer to option value */
1661 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1662 struct apattern *pat)
1664 struct apattern *newsort;
1665 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1668 newsort[*nsort] = *pat;
1669 *sortlist = newsort;
1674 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1677 /* Four octets and three periods yields at most 15 characters. */
1681 addr->s_addr = inet_addr(ipbuf);
1682 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1687 static void natural_mask(struct apattern *pat)
1689 struct in_addr addr;
1691 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1694 addr.s_addr = ntohl(pat->addrV4.s_addr);
1696 /* This is out of date in the CIDR world, but some people might
1699 if (IN_CLASSA(addr.s_addr))
1700 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1701 else if (IN_CLASSB(addr.s_addr))
1702 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1704 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1706 #endif /* !WIN32 && !WATT32 */
1708 /* initialize an rc4 key. If possible a cryptographically secure random key
1709 is generated using a suitable function (for example win32's RtlGenRandom as
1711 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1712 otherwise the code defaults to cross-platform albeit less secure mechanism
1715 static void randomize_key(unsigned char* key,int key_data_len)
1721 if (ares_fpSystemFunction036)
1723 res = (*ares_fpSystemFunction036) (key, key_data_len);
1729 FILE *f = fopen(RANDOM_FILE, "rb");
1731 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1738 for (;counter<key_data_len;counter++)
1739 key[counter]=(unsigned char)(rand() % 256);
1743 static int init_id_key(rc4_key* key,int key_data_len)
1745 unsigned char index1;
1746 unsigned char index2;
1747 unsigned char* state;
1749 unsigned char *key_data_ptr = 0;
1751 key_data_ptr = calloc(1,key_data_len);
1755 state = &key->state[0];
1756 for(counter = 0; counter < 256; counter++)
1757 /* unnecessary AND but it keeps some compilers happier */
1758 state[counter] = (unsigned char)(counter & 0xff);
1759 randomize_key(key->state,key_data_len);
1764 for(counter = 0; counter < 256; counter++)
1766 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1768 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1770 index1 = (unsigned char)((index1 + 1) % key_data_len);
1773 return ARES_SUCCESS;
1776 unsigned short ares__generate_new_id(rc4_key* key)
1779 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1783 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1785 channel->local_ip4 = local_ip;
1788 /* local_ip6 should be 16 bytes in length */
1789 void ares_set_local_ip6(ares_channel channel,
1790 const unsigned char* local_ip6)
1792 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1795 /* local_dev_name should be null terminated. */
1796 void ares_set_local_dev(ares_channel channel,
1797 const char* local_dev_name)
1799 strncpy(channel->local_dev_name, local_dev_name,
1800 sizeof(channel->local_dev_name));
1801 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1805 void ares_set_socket_callback(ares_channel channel,
1806 ares_sock_create_callback cb,
1809 channel->sock_create_cb = cb;
1810 channel->sock_create_cb_data = data;
1813 void ares__init_servers_state(ares_channel channel)
1815 struct server_state *server;
1818 for (i = 0; i < channel->nservers; i++)
1820 server = &channel->servers[i];
1821 server->udp_socket = ARES_SOCKET_BAD;
1822 server->tcp_socket = ARES_SOCKET_BAD;
1823 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1824 server->tcp_lenbuf_pos = 0;
1825 server->tcp_buffer_pos = 0;
1826 server->tcp_buffer = NULL;
1827 server->tcp_length = 0;
1828 server->qhead = NULL;
1829 server->qtail = NULL;
1830 ares__init_list_head(&server->queries_to_server);
1831 server->channel = channel;
1832 server->is_broken = 0;