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>
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 static int config_domain(ares_channel channel, char *str);
101 static int config_lookup(ares_channel channel, const char *str,
102 const char *bindch, const char *filech);
103 static int config_sortlist(struct apattern **sortlist, int *nsort,
105 static char *try_config(char *s, const char *opt, char scc);
108 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
109 x->nservers > -1 && \
110 x->ndomains > -1 && \
111 x->ndots > -1 && x->timeout > -1 && \
114 int ares_init(ares_channel *channelptr)
116 return ares_init_options(channelptr, NULL, 0);
119 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
122 ares_channel channel;
124 int status = ARES_SUCCESS;
128 const char *env = getenv("CARES_MEMDEBUG");
132 env = getenv("CARES_MEMLIMIT");
135 long num = strtol(env, &endptr, 10);
136 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
141 if (ares_library_initialized() != ARES_SUCCESS)
142 return ARES_ENOTINITIALIZED;
144 channel = malloc(sizeof(struct ares_channeldata));
152 /* Set everything to distinguished values so we know they haven't
156 channel->timeout = -1;
159 channel->rotate = -1;
160 channel->udp_port = -1;
161 channel->tcp_port = -1;
162 channel->socket_send_buffer_size = -1;
163 channel->socket_receive_buffer_size = -1;
164 channel->nservers = -1;
165 channel->ndomains = -1;
167 channel->tcp_connection_generation = 0;
168 channel->lookups = NULL;
169 channel->domains = NULL;
170 channel->sortlist = NULL;
171 channel->servers = NULL;
172 channel->sock_state_cb = NULL;
173 channel->sock_state_cb_data = NULL;
174 channel->sock_create_cb = NULL;
175 channel->sock_create_cb_data = NULL;
177 channel->last_server = 0;
178 channel->last_timeout_processed = (time_t)now.tv_sec;
180 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
181 channel->local_ip4 = 0;
182 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
184 /* Initialize our lists of queries */
185 ares__init_list_head(&(channel->all_queries));
186 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
188 ares__init_list_head(&(channel->queries_by_qid[i]));
190 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
192 ares__init_list_head(&(channel->queries_by_timeout[i]));
195 /* Initialize configuration by each of the four sources, from highest
196 * precedence to lowest.
199 if (status == ARES_SUCCESS) {
200 status = init_by_options(channel, options, optmask);
201 if (status != ARES_SUCCESS)
202 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
203 ares_strerror(status)));
205 if (status == ARES_SUCCESS) {
206 status = init_by_environment(channel);
207 if (status != ARES_SUCCESS)
208 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
209 ares_strerror(status)));
211 if (status == ARES_SUCCESS) {
212 status = init_by_resolv_conf(channel);
213 if (status != ARES_SUCCESS)
214 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
215 ares_strerror(status)));
219 * No matter what failed or succeeded, seed defaults to provide
220 * useful behavior for things that we missed.
222 status = init_by_defaults(channel);
223 if (status != ARES_SUCCESS)
224 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
225 ares_strerror(status)));
227 /* Generate random key */
229 if (status == ARES_SUCCESS) {
230 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
231 if (status == ARES_SUCCESS)
232 channel->next_id = ares__generate_new_id(&channel->id_key);
234 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
235 ares_strerror(status)));
238 if (status != ARES_SUCCESS)
240 /* Something failed; clean up memory we may have allocated. */
241 if (channel->servers)
242 free(channel->servers);
243 if (channel->domains)
245 for (i = 0; i < channel->ndomains; i++)
246 free(channel->domains[i]);
247 free(channel->domains);
249 if (channel->sortlist)
250 free(channel->sortlist);
252 free(channel->lookups);
257 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
258 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
259 channel->nservers = 1;
261 ares__init_servers_state(channel);
263 *channelptr = channel;
267 /* ares_dup() duplicates a channel handle with all its options and returns a
268 new channel handle */
269 int ares_dup(ares_channel *dest, ares_channel src)
271 struct ares_options opts;
272 struct ares_addr_node *servers;
273 int ipv6_nservers = 0;
277 *dest = NULL; /* in case of failure return NULL explicitly */
279 /* First get the options supported by the old ares_save_options() function,
280 which is most of them */
281 rc = ares_save_options(src, &opts, &optmask);
285 /* Then create the new channel with those options */
286 rc = ares_init_options(dest, &opts, optmask);
288 /* destroy the options copy to not leak any memory */
289 ares_destroy_options(&opts);
294 /* Now clone the options that ares_save_options() doesn't support. */
295 (*dest)->sock_create_cb = src->sock_create_cb;
296 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
298 strncpy((*dest)->local_dev_name, src->local_dev_name,
299 sizeof(src->local_dev_name));
300 (*dest)->local_ip4 = src->local_ip4;
301 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
303 /* Full name server cloning required when not all are IPv4 */
304 for (i = 0; i < src->nservers; i++)
306 if (src->servers[i].addr.family != AF_INET) {
312 rc = ares_get_servers(src, &servers);
313 if (rc != ARES_SUCCESS)
315 rc = ares_set_servers(*dest, servers);
316 ares_free_data(servers);
317 if (rc != ARES_SUCCESS)
321 return ARES_SUCCESS; /* everything went fine */
324 /* Save options from initialized channel */
325 int ares_save_options(ares_channel channel, struct ares_options *options,
329 int ipv4_nservers = 0;
331 /* Zero everything out */
332 memset(options, 0, sizeof(struct ares_options));
334 if (!ARES_CONFIG_CHECK(channel))
337 /* Traditionally the optmask wasn't saved in the channel struct so it was
338 recreated here. ROTATE is the first option that has no struct field of
339 its own in the public config struct */
340 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
341 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
342 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
343 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
344 (channel->optmask & ARES_OPT_ROTATE);
346 /* Copy easy stuff */
347 options->flags = channel->flags;
349 /* We return full millisecond resolution but that's only because we don't
350 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
351 options->timeout = channel->timeout;
352 options->tries = channel->tries;
353 options->ndots = channel->ndots;
354 options->udp_port = (unsigned short)channel->udp_port;
355 options->tcp_port = (unsigned short)channel->tcp_port;
356 options->sock_state_cb = channel->sock_state_cb;
357 options->sock_state_cb_data = channel->sock_state_cb_data;
359 /* Copy IPv4 servers */
360 if (channel->nservers) {
361 for (i = 0; i < channel->nservers; i++)
363 if (channel->servers[i].addr.family == AF_INET)
367 options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
368 if (!options->servers)
370 for (i = j = 0; i < channel->nservers; i++)
372 if (channel->servers[i].addr.family == AF_INET)
373 memcpy(&options->servers[j++],
374 &channel->servers[i].addr.addrV4,
375 sizeof(channel->servers[i].addr.addrV4));
379 options->nservers = ipv4_nservers;
382 if (channel->ndomains) {
383 options->domains = malloc(channel->ndomains * sizeof(char *));
384 if (!options->domains)
387 for (i = 0; i < channel->ndomains; i++)
389 options->ndomains = i;
390 options->domains[i] = strdup(channel->domains[i]);
391 if (!options->domains[i])
395 options->ndomains = channel->ndomains;
398 if (channel->lookups) {
399 options->lookups = strdup(channel->lookups);
400 if (!options->lookups && channel->lookups)
405 if (channel->nsort) {
406 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
407 if (!options->sortlist)
409 for (i = 0; i < channel->nsort; i++)
410 options->sortlist[i] = channel->sortlist[i];
412 options->nsort = channel->nsort;
417 static int init_by_options(ares_channel channel,
418 const struct ares_options *options,
424 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
425 channel->flags = options->flags;
426 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
427 channel->timeout = options->timeout;
428 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
429 channel->timeout = options->timeout * 1000;
430 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
431 channel->tries = options->tries;
432 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
433 channel->ndots = options->ndots;
434 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
436 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
437 channel->udp_port = htons(options->udp_port);
438 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
439 channel->tcp_port = htons(options->tcp_port);
440 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
442 channel->sock_state_cb = options->sock_state_cb;
443 channel->sock_state_cb_data = options->sock_state_cb_data;
445 if ((optmask & ARES_OPT_SOCK_SNDBUF)
446 && channel->socket_send_buffer_size == -1)
447 channel->socket_send_buffer_size = options->socket_send_buffer_size;
448 if ((optmask & ARES_OPT_SOCK_RCVBUF)
449 && channel->socket_receive_buffer_size == -1)
450 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
452 /* Copy the IPv4 servers, if given. */
453 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
455 /* Avoid zero size allocations at any cost */
456 if (options->nservers > 0)
459 malloc(options->nservers * sizeof(struct server_state));
460 if (!channel->servers)
462 for (i = 0; i < options->nservers; i++)
464 channel->servers[i].addr.family = AF_INET;
465 memcpy(&channel->servers[i].addr.addrV4,
466 &options->servers[i],
467 sizeof(channel->servers[i].addr.addrV4));
470 channel->nservers = options->nservers;
473 /* Copy the domains, if given. Keep channel->ndomains consistent so
474 * we can clean up in case of error.
476 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
478 /* Avoid zero size allocations at any cost */
479 if (options->ndomains > 0)
481 channel->domains = malloc(options->ndomains * sizeof(char *));
482 if (!channel->domains)
484 for (i = 0; i < options->ndomains; i++)
486 channel->ndomains = i;
487 channel->domains[i] = strdup(options->domains[i]);
488 if (!channel->domains[i])
492 channel->ndomains = options->ndomains;
495 /* Set lookups, if given. */
496 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
498 channel->lookups = strdup(options->lookups);
499 if (!channel->lookups)
504 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
505 (options->nsort>0)) {
506 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
507 if (!channel->sortlist)
509 for (i = 0; i < options->nsort; i++)
510 channel->sortlist[i] = options->sortlist[i];
511 channel->nsort = options->nsort;
514 channel->optmask = optmask;
519 static int init_by_environment(ares_channel channel)
521 const char *localdomain, *res_options;
524 localdomain = getenv("LOCALDOMAIN");
525 if (localdomain && channel->ndomains == -1)
527 status = set_search(channel, localdomain);
528 if (status != ARES_SUCCESS)
532 res_options = getenv("RES_OPTIONS");
535 status = set_options(channel, res_options);
536 if (status != ARES_SUCCESS)
545 * Warning: returns a dynamically allocated buffer, the user MUST
546 * use free() if the function returns 1
548 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
550 /* Test for the size we need */
554 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
555 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
557 *obuf = malloc(size+1);
561 if (RegQueryValueEx(hKey, subkey, 0, NULL,
562 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
575 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
577 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
578 DWORD enum_size = 39;
582 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
583 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
588 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
591 rc = get_res_nt(hVal, subkey, obuf);
600 * The desired output for this method is that we set "ret_buf" to
603 * 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
605 * The only ordering requirement is that primary servers are listed
606 * before secondary. There is no requirement that IPv4 addresses should
607 * necessarily be before IPv6.
609 * Note that ret_size should ideally be big enough to hold around
610 * 2-3 IPv4 and 2-3 IPv6 addresses.
612 * Finally, we need to return the total number of DNS servers located.
614 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
616 const size_t ipv4_size = INET_ADDRSTRLEN + 1; /* +1 for ',' at end */
617 const size_t ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," */
618 long left = ret_size;
622 /* Use the GetAdaptersAddresses method if it's available, otherwise
623 fall back to GetNetworkParams. */
624 if (ares_fpGetAdaptersAddresses != ZERO_NULL)
626 const ULONG working_buf_size = 15000;
627 IP_ADAPTER_ADDRESSES *pFirstEntry = NULL;
628 IP_ADAPTER_ADDRESSES *pEntry = NULL;
632 /* According to MSDN, the recommended way to do this is to use a temporary
633 buffer of 15K, to "dramatically reduce the chance that the
634 GetAdaptersAddresses method returns ERROR_BUFFER_OVERFLOW" */
635 pFirstEntry = (IP_ADAPTER_ADDRESSES *) malloc(working_buf_size);
636 bufSize = working_buf_size;
640 /* Call the method one time */
641 result = (*ares_fpGetAdaptersAddresses)(AF_UNSPEC, 0, 0, pFirstEntry,
643 if(result == ERROR_BUFFER_OVERFLOW)
645 /* Reallocate, bufSize should now be set to the required size */
646 pFirstEntry = (IP_ADAPTER_ADDRESSES *) realloc(pFirstEntry, bufSize);
650 /* Call the method a second time */
651 result = (*ares_fpGetAdaptersAddresses)(AF_UNSPEC, 0, 0, pFirstEntry,
653 if(result == ERROR_BUFFER_OVERFLOW)
655 /* Reallocate, bufSize should now be set to the required size */
656 pFirstEntry = (IP_ADAPTER_ADDRESSES *)realloc(pFirstEntry, bufSize);
660 /* Call the method a third time. The maximum number of times we're
661 going to do this is 3. Three shall be the number thou shalt count,
662 and the number of the counting shall be three. Five is right
664 result = (*ares_fpGetAdaptersAddresses)(AF_UNSPEC, 0, 0, pFirstEntry,
669 /* Check the current result for failure */
670 if(result != ERROR_SUCCESS)
676 /* process the results */
677 for(pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next)
679 IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
680 for(; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next)
682 struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
683 size_t stringlen = 0;
685 if(pGenericAddr->sa_family == AF_INET && left > ipv4_size)
687 /* Handle the v4 case */
688 struct sockaddr_in *pIPv4Addr = (struct sockaddr_in *) pGenericAddr;
690 ares_inet_ntop(AF_INET, &pIPv4Addr->sin_addr, ret,
691 ipv4_size - 1); /* -1 for comma */
693 /* Append a comma to the end, THEN NULL. Should be OK because we
694 already tested the size at the top of the if statement. */
695 stringlen = strlen(ret);
696 ret[ stringlen ] = ',';
697 ret[ stringlen + 1 ] = '\0';
698 ret += stringlen + 1;
699 left -= stringlen + 1;
702 else if(pGenericAddr->sa_family == AF_INET6 && left > ipv6_size)
704 /* Handle the v6 case */
705 struct sockaddr_in6 *pIPv6Addr = (struct sockaddr_in6 *)pGenericAddr;
706 ares_inet_ntop(AF_INET6, &pIPv6Addr->sin6_addr, ret,
707 ipv6_size - 1); /* -1 for comma */
709 /* Append a comma to the end, THEN NULL. Should be OK because we
710 already tested the size at the top of the if statement. */
711 stringlen = strlen(ret);
712 ret[ stringlen ] = ',';
713 ret[ stringlen + 1 ] = '\0';
714 ret += stringlen + 1;
715 left -= stringlen + 1;
718 /* NB on Windows this also returns stuff in the fec0::/10 range,
719 seems to be hard-coded somehow. Do we need to ignore them? */
732 FIXED_INFO *fi, *newfi;
733 DWORD size = sizeof (*fi);
734 IP_ADDR_STRING *ipAddr;
743 res = (*ares_fpGetNetworkParams) (fi, &size);
744 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
747 newfi = realloc(fi, size);
752 res = (*ares_fpGetNetworkParams) (fi, &size);
753 if (res != ERROR_SUCCESS)
758 printf ("Host Name: %s\n", fi->HostName);
759 printf ("Domain Name: %s\n", fi->DomainName);
760 printf ("DNS Servers:\n"
761 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
763 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
764 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
767 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
768 left -= ret - ret_buf;
772 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
773 ipAddr = ipAddr->Next, i++)
775 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
777 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
778 left -= ret - ret_buf;
782 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
789 if (debug && left <= ipv4_size)
790 printf ("Too many nameservers. Truncating to %d addressess", count);
798 static int init_by_resolv_conf(ares_channel channel)
803 int status = -1, nservers = 0, nsort = 0;
804 struct server_state *servers = NULL;
805 struct apattern *sortlist = NULL;
810 NameServer info via IPHLPAPI (IP helper API):
811 GetNetworkParams() should be the trusted source for this.
812 Available in Win-98/2000 and later. If that fail, fall-back to
813 registry information.
817 On Windows 9X, the DNS server can be found in:
818 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
820 On Windows NT/2000/XP/2003:
821 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
823 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
825 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
828 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
838 win_platform platform;
840 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
843 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
845 status = config_nameserver(&servers, &nservers, buf);
846 if (status == ARES_SUCCESS)
850 platform = ares__getplatform();
852 if (platform == WIN_NT)
855 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
859 RegOpenKeyEx(mykey, "Interfaces", 0,
860 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
861 if (get_res_nt(mykey, NAMESERVER, &line))
863 status = config_nameserver(&servers, &nservers, line);
866 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
868 status = config_nameserver(&servers, &nservers, line);
871 /* Try the interfaces */
872 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
874 status = config_nameserver(&servers, &nservers, line);
877 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
879 status = config_nameserver(&servers, &nservers, line);
886 else if (platform == WIN_9X)
889 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
893 if ((result = RegQueryValueEx(
894 mykey, NAMESERVER, NULL, &data_type,
897 ) == ERROR_SUCCESS ||
898 result == ERROR_MORE_DATA)
902 line = malloc(bytes+1);
903 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
904 (unsigned char *)line, &bytes) ==
907 status = config_nameserver(&servers, &nservers, line);
916 if (status == ARES_SUCCESS)
919 /* Catch the case when all the above checks fail (which happens when there
920 is no network card or the cable is unplugged) */
923 #elif defined(__riscos__)
925 /* Under RISC OS, name servers are listed in the
926 system variable Inet$Resolvers, space separated. */
928 line = getenv("Inet$Resolvers");
931 char *resolvers = strdup(line), *pos, *space;
938 space = strchr(pos, ' ');
941 status = config_nameserver(&servers, &nservers, pos);
942 if (status != ARES_SUCCESS)
947 if (status == ARES_SUCCESS)
953 #elif defined(WATT32)
957 for (i = 0; def_nameservers[i]; i++)
960 return ARES_SUCCESS; /* use localhost DNS server */
963 servers = calloc(i, sizeof(struct server_state));
967 for (i = 0; def_nameservers[i]; i++)
969 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
970 servers[i].addr.family = AF_INET;
974 #elif defined(ANDROID)
975 char value[PROP_VALUE_MAX]="";
976 __system_property_get("net.dns1", value);
977 status = config_nameserver(&servers, &nservers, value);
978 if (status == ARES_SUCCESS)
987 /* Don't read resolv.conf and friends if we don't have to */
988 if (ARES_CONFIG_CHECK(channel))
991 fp = fopen(PATH_RESOLV_CONF, "r");
993 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
995 if ((p = try_config(line, "domain", ';')))
996 status = config_domain(channel, p);
997 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
998 status = config_lookup(channel, p, "bind", "file");
999 else if ((p = try_config(line, "search", ';')))
1000 status = set_search(channel, p);
1001 else if ((p = try_config(line, "nameserver", ';')) &&
1002 channel->nservers == -1)
1003 status = config_nameserver(&servers, &nservers, p);
1004 else if ((p = try_config(line, "sortlist", ';')) &&
1005 channel->nsort == -1)
1006 status = config_sortlist(&sortlist, &nsort, p);
1007 else if ((p = try_config(line, "options", ';')))
1008 status = set_options(channel, p);
1010 status = ARES_SUCCESS;
1011 if (status != ARES_SUCCESS)
1024 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1025 error, strerror(error)));
1026 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1027 status = ARES_EFILE;
1031 if ((status == ARES_EOF) && (!channel->lookups)) {
1032 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1033 fp = fopen("/etc/nsswitch.conf", "r");
1035 while ((status = ares__read_line(fp, &line, &linesize)) ==
1038 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1040 (void)config_lookup(channel, p, "dns", "files");
1052 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1053 error, strerror(error)));
1054 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1055 "/etc/nsswitch.conf"));
1056 status = ARES_EFILE;
1061 if ((status == ARES_EOF) && (!channel->lookups)) {
1062 /* Linux / GNU libc 2.x and possibly others have host.conf */
1063 fp = fopen("/etc/host.conf", "r");
1065 while ((status = ares__read_line(fp, &line, &linesize)) ==
1068 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1070 (void)config_lookup(channel, p, "bind", "hosts");
1082 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1083 error, strerror(error)));
1084 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1086 status = ARES_EFILE;
1091 if ((status == ARES_EOF) && (!channel->lookups)) {
1092 /* Tru64 uses /etc/svc.conf */
1093 fp = fopen("/etc/svc.conf", "r");
1095 while ((status = ares__read_line(fp, &line, &linesize)) ==
1098 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1100 (void)config_lookup(channel, p, "bind", "local");
1112 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1113 error, strerror(error)));
1114 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1115 status = ARES_EFILE;
1126 /* Handle errors. */
1127 if (status != ARES_EOF)
1129 if (servers != NULL)
1131 if (sortlist != NULL)
1136 /* If we got any name server entries, fill them in. */
1142 channel->servers = servers;
1143 channel->nservers = nservers;
1146 /* If we got any sortlist entries, fill them in. */
1149 channel->sortlist = sortlist;
1150 channel->nsort = nsort;
1153 return ARES_SUCCESS;
1156 static int init_by_defaults(ares_channel channel)
1158 char *hostname = NULL;
1159 int rc = ARES_SUCCESS;
1160 #ifdef HAVE_GETHOSTNAME
1164 if (channel->flags == -1)
1166 if (channel->timeout == -1)
1167 channel->timeout = DEFAULT_TIMEOUT;
1168 if (channel->tries == -1)
1169 channel->tries = DEFAULT_TRIES;
1170 if (channel->ndots == -1)
1172 if (channel->rotate == -1)
1173 channel->rotate = 0;
1174 if (channel->udp_port == -1)
1175 channel->udp_port = htons(NAMESERVER_PORT);
1176 if (channel->tcp_port == -1)
1177 channel->tcp_port = htons(NAMESERVER_PORT);
1179 if (channel->nservers == -1) {
1180 /* If nobody specified servers, try a local named. */
1181 channel->servers = malloc(sizeof(struct server_state));
1182 if (!channel->servers) {
1186 channel->servers[0].addr.family = AF_INET;
1187 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1188 channel->nservers = 1;
1191 #if defined(USE_WINSOCK)
1192 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1193 #elif defined(ENAMETOOLONG)
1194 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1195 (SOCKERRNO == EINVAL))
1197 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1200 if (channel->ndomains == -1) {
1201 /* Derive a default domain search list from the kernel hostname,
1202 * or set it to empty if the hostname isn't helpful.
1204 #ifndef HAVE_GETHOSTNAME
1205 channel->ndomains = 0; /* default to none */
1207 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1210 channel->ndomains = 0; /* default to none */
1212 hostname = malloc(len);
1219 res = gethostname(hostname, lenv);
1225 p = realloc(hostname, len);
1240 dot = strchr(hostname, '.');
1242 /* a dot was found */
1243 channel->domains = malloc(sizeof(char *));
1244 if (!channel->domains) {
1248 channel->domains[0] = strdup(dot + 1);
1249 if (!channel->domains[0]) {
1253 channel->ndomains = 1;
1258 if (channel->nsort == -1) {
1259 channel->sortlist = NULL;
1263 if (!channel->lookups) {
1264 channel->lookups = strdup("fb");
1265 if (!channel->lookups)
1271 if(channel->servers) {
1272 free(channel->servers);
1273 channel->servers = NULL;
1276 if(channel->domains && channel->domains[0])
1277 free(channel->domains[0]);
1278 if(channel->domains) {
1279 free(channel->domains);
1280 channel->domains = NULL;
1283 if(channel->lookups) {
1284 free(channel->lookups);
1285 channel->lookups = NULL;
1295 #if !defined(WIN32) && !defined(WATT32)
1296 static int config_domain(ares_channel channel, char *str)
1300 /* Set a single search domain. */
1302 while (*q && !ISSPACE(*q))
1305 return set_search(channel, str);
1308 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1309 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1310 /* workaround icc 9.1 optimizer issue */
1311 # define vqualifier volatile
1316 static int config_lookup(ares_channel channel, const char *str,
1317 const char *bindch, const char *filech)
1319 char lookups[3], *l;
1320 const char *vqualifier p;
1322 /* Set the lookup order. Only the first letter of each work
1323 * is relevant, and it has to be "b" for DNS or "f" for the
1324 * host file. Ignore everything else.
1330 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1331 if (*p == *bindch) *l++ = 'b';
1334 while (*p && !ISSPACE(*p) && (*p != ','))
1336 while (*p && (ISSPACE(*p) || (*p == ',')))
1340 channel->lookups = strdup(lookups);
1341 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1343 #endif /* !WIN32 & !WATT32 */
1346 static int config_nameserver(struct server_state **servers, int *nservers,
1349 struct ares_addr host;
1350 struct server_state *newserv;
1352 /* On Windows, there may be more than one nameserver specified in the same
1353 * registry key, so we parse input as a space or comma seperated list.
1357 /* Skip whitespace and commas. */
1358 while (*p && (ISSPACE(*p) || (*p == ',')))
1361 /* No more input, done. */
1364 /* Pointer to start of IPv4 or IPv6 address part. */
1367 /* Advance past this address. */
1368 while (*p && !ISSPACE(*p) && (*p != ','))
1371 /* Null terminate this address. */
1374 /* Reached end of input, done when this address is processed. */
1377 /* Convert textual address to binary format. */
1378 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1379 host.family = AF_INET;
1380 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1381 host.family = AF_INET6;
1385 /* Resize servers state array. */
1386 newserv = realloc(*servers, (*nservers + 1) *
1387 sizeof(struct server_state));
1391 /* Store address data. */
1392 newserv[*nservers].addr.family = host.family;
1393 if (host.family == AF_INET)
1394 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1395 sizeof(host.addrV4));
1397 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1398 sizeof(host.addrV6));
1400 /* Update arguments. */
1405 return ARES_SUCCESS;
1409 static int config_sortlist(struct apattern **sortlist, int *nsort,
1412 struct apattern pat;
1415 /* Add sortlist entries. */
1416 while (*str && *str != ';')
1419 char ipbuf[16], ipbufpfx[32];
1420 /* Find just the IP */
1422 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1424 memcpy(ipbuf, str, q-str);
1425 ipbuf[q-str] = '\0';
1426 /* Find the prefix */
1429 const char *str2 = q+1;
1430 while (*q && *q != ';' && !ISSPACE(*q))
1432 memcpy(ipbufpfx, str, q-str);
1433 ipbufpfx[q-str] = '\0';
1438 /* Lets see if it is CIDR */
1439 /* First we'll try IPv6 */
1440 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1442 sizeof(pat.addrV6))) > 0)
1444 pat.type = PATTERN_CIDR;
1445 pat.mask.bits = (unsigned short)bits;
1446 pat.family = AF_INET6;
1447 if (!sortlist_alloc(sortlist, nsort, &pat))
1450 else if (ipbufpfx[0] &&
1451 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1452 sizeof(pat.addrV4))) > 0)
1454 pat.type = PATTERN_CIDR;
1455 pat.mask.bits = (unsigned short)bits;
1456 pat.family = AF_INET;
1457 if (!sortlist_alloc(sortlist, nsort, &pat))
1460 /* See if it is just a regular IP */
1461 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1465 memcpy(ipbuf, str, q-str);
1466 ipbuf[q-str] = '\0';
1467 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1472 pat.family = AF_INET;
1473 pat.type = PATTERN_MASK;
1474 if (!sortlist_alloc(sortlist, nsort, &pat))
1479 while (*q && *q != ';' && !ISSPACE(*q))
1483 while (ISSPACE(*str))
1487 return ARES_SUCCESS;
1490 #endif /* !WATT32 */
1492 static int set_search(ares_channel channel, const char *str)
1497 if(channel->ndomains != -1) {
1498 /* if we already have some domains present, free them first */
1499 for(n=0; n < channel->ndomains; n++)
1500 free(channel->domains[n]);
1501 free(channel->domains);
1502 channel->domains = NULL;
1503 channel->ndomains = -1;
1506 /* Count the domains given. */
1511 while (*p && !ISSPACE(*p))
1520 channel->ndomains = 0;
1521 return ARES_SUCCESS;
1524 channel->domains = malloc(n * sizeof(char *));
1525 if (!channel->domains)
1528 /* Now copy the domains. */
1533 channel->ndomains = n;
1535 while (*q && !ISSPACE(*q))
1537 channel->domains[n] = malloc(q - p + 1);
1538 if (!channel->domains[n])
1540 memcpy(channel->domains[n], p, q - p);
1541 channel->domains[n][q - p] = 0;
1547 channel->ndomains = n;
1549 return ARES_SUCCESS;
1552 static int set_options(ares_channel channel, const char *str)
1554 const char *p, *q, *val;
1560 while (*q && !ISSPACE(*q))
1562 val = try_option(p, q, "ndots:");
1563 if (val && channel->ndots == -1)
1564 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1565 val = try_option(p, q, "retrans:");
1566 if (val && channel->timeout == -1)
1567 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1568 val = try_option(p, q, "retry:");
1569 if (val && channel->tries == -1)
1570 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1571 val = try_option(p, q, "rotate");
1572 if (val && channel->rotate == -1)
1573 channel->rotate = 1;
1579 return ARES_SUCCESS;
1582 static const char *try_option(const char *p, const char *q, const char *opt)
1584 size_t len = strlen(opt);
1585 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1588 #if !defined(WIN32) && !defined(WATT32)
1589 static char *try_config(char *s, const char *opt, char scc)
1596 /* no line or no option */
1599 /* Hash '#' character is always used as primary comment char, additionally
1600 a not-NUL secondary comment char will be considered when specified. */
1602 /* trim line comment */
1605 while (*p && (*p != '#') && (*p != scc))
1608 while (*p && (*p != '#'))
1612 /* trim trailing whitespace */
1614 while ((q >= s) && ISSPACE(*q))
1618 /* skip leading whitespace */
1620 while (*p && ISSPACE(*p))
1627 if ((len = strlen(opt)) == 0)
1631 if (strncmp(p, opt, len) != 0)
1632 /* line and option do not match */
1635 /* skip over given option name */
1639 /* no option value */
1642 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1643 /* whitespace between option name and value is mandatory
1644 for given option names which do not end with ':' or '=' */
1647 /* skip over whitespace */
1648 while (*p && ISSPACE(*p))
1652 /* no option value */
1655 /* return pointer to option value */
1659 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1660 struct apattern *pat)
1662 struct apattern *newsort;
1663 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1666 newsort[*nsort] = *pat;
1667 *sortlist = newsort;
1672 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1675 /* Four octets and three periods yields at most 15 characters. */
1679 addr->s_addr = inet_addr(ipbuf);
1680 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1685 static void natural_mask(struct apattern *pat)
1687 struct in_addr addr;
1689 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1692 addr.s_addr = ntohl(pat->addrV4.s_addr);
1694 /* This is out of date in the CIDR world, but some people might
1697 if (IN_CLASSA(addr.s_addr))
1698 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1699 else if (IN_CLASSB(addr.s_addr))
1700 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1702 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1704 #endif /* !WIN32 && !WATT32 */
1706 /* initialize an rc4 key. If possible a cryptographically secure random key
1707 is generated using a suitable function (for example win32's RtlGenRandom as
1709 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1710 otherwise the code defaults to cross-platform albeit less secure mechanism
1713 static void randomize_key(unsigned char* key,int key_data_len)
1719 if (ares_fpSystemFunction036)
1721 res = (*ares_fpSystemFunction036) (key, key_data_len);
1727 FILE *f = fopen(RANDOM_FILE, "rb");
1729 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1736 for (;counter<key_data_len;counter++)
1737 key[counter]=(unsigned char)(rand() % 256);
1741 static int init_id_key(rc4_key* key,int key_data_len)
1743 unsigned char index1;
1744 unsigned char index2;
1745 unsigned char* state;
1747 unsigned char *key_data_ptr = 0;
1749 key_data_ptr = calloc(1,key_data_len);
1753 state = &key->state[0];
1754 for(counter = 0; counter < 256; counter++)
1755 /* unnecessary AND but it keeps some compilers happier */
1756 state[counter] = (unsigned char)(counter & 0xff);
1757 randomize_key(key->state,key_data_len);
1762 for(counter = 0; counter < 256; counter++)
1764 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1766 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1768 index1 = (unsigned char)((index1 + 1) % key_data_len);
1771 return ARES_SUCCESS;
1774 unsigned short ares__generate_new_id(rc4_key* key)
1777 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1781 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1783 channel->local_ip4 = local_ip;
1786 /* local_ip6 should be 16 bytes in length */
1787 void ares_set_local_ip6(ares_channel channel,
1788 const unsigned char* local_ip6)
1790 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1793 /* local_dev_name should be null terminated. */
1794 void ares_set_local_dev(ares_channel channel,
1795 const char* local_dev_name)
1797 strncpy(channel->local_dev_name, local_dev_name,
1798 sizeof(channel->local_dev_name));
1799 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1803 void ares_set_socket_callback(ares_channel channel,
1804 ares_sock_create_callback cb,
1807 channel->sock_create_cb = cb;
1808 channel->sock_create_cb_data = data;
1811 void ares__init_servers_state(ares_channel channel)
1813 struct server_state *server;
1816 for (i = 0; i < channel->nservers; i++)
1818 server = &channel->servers[i];
1819 server->udp_socket = ARES_SOCKET_BAD;
1820 server->tcp_socket = ARES_SOCKET_BAD;
1821 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1822 server->tcp_lenbuf_pos = 0;
1823 server->tcp_buffer_pos = 0;
1824 server->tcp_buffer = NULL;
1825 server->tcp_length = 0;
1826 server->qhead = NULL;
1827 server->qtail = NULL;
1828 ares__init_list_head(&server->queries_to_server);
1829 server->channel = channel;
1830 server->is_broken = 0;