2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Copyright (C) 2007-2011 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, const struct ares_options *options,
81 static int init_by_environment(ares_channel channel);
82 static int init_by_resolv_conf(ares_channel channel);
83 static int init_by_defaults(ares_channel channel);
86 static int config_nameserver(struct server_state **servers, int *nservers,
89 static int set_search(ares_channel channel, const char *str);
90 static int set_options(ares_channel channel, const char *str);
91 static const char *try_option(const char *p, const char *q, const char *opt);
92 static int init_id_key(rc4_key* key,int key_data_len);
94 #if !defined(WIN32) && !defined(WATT32)
95 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
96 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
97 static void natural_mask(struct apattern *pat);
98 static int config_domain(ares_channel channel, char *str);
99 static int config_lookup(ares_channel channel, const char *str,
100 const char *bindch, const char *filech);
101 static int config_sortlist(struct apattern **sortlist, int *nsort,
103 static char *try_config(char *s, const char *opt, char scc);
106 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
107 x->nservers > -1 && \
108 x->ndomains > -1 && \
109 x->ndots > -1 && x->timeout > -1 && \
112 int ares_init(ares_channel *channelptr)
114 return ares_init_options(channelptr, NULL, 0);
117 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
120 ares_channel channel;
122 int status = ARES_SUCCESS;
126 const char *env = getenv("CARES_MEMDEBUG");
130 env = getenv("CARES_MEMLIMIT");
133 long num = strtol(env, &endptr, 10);
134 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
139 if (ares_library_initialized() != ARES_SUCCESS)
140 return ARES_ENOTINITIALIZED;
142 channel = malloc(sizeof(struct ares_channeldata));
150 /* Set everything to distinguished values so we know they haven't
154 channel->timeout = -1;
157 channel->rotate = -1;
158 channel->udp_port = -1;
159 channel->tcp_port = -1;
160 channel->socket_send_buffer_size = -1;
161 channel->socket_receive_buffer_size = -1;
162 channel->nservers = -1;
163 channel->ndomains = -1;
165 channel->tcp_connection_generation = 0;
166 channel->lookups = NULL;
167 channel->domains = NULL;
168 channel->sortlist = NULL;
169 channel->servers = NULL;
170 channel->sock_state_cb = NULL;
171 channel->sock_state_cb_data = NULL;
172 channel->sock_create_cb = NULL;
173 channel->sock_create_cb_data = NULL;
175 channel->last_server = 0;
176 channel->last_timeout_processed = (time_t)now.tv_sec;
178 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
179 channel->local_ip4 = 0;
180 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
182 /* Initialize our lists of queries */
183 ares__init_list_head(&(channel->all_queries));
184 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
186 ares__init_list_head(&(channel->queries_by_qid[i]));
188 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
190 ares__init_list_head(&(channel->queries_by_timeout[i]));
193 /* Initialize configuration by each of the four sources, from highest
194 * precedence to lowest.
197 if (status == ARES_SUCCESS) {
198 status = init_by_options(channel, options, optmask);
199 if (status != ARES_SUCCESS)
200 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
201 ares_strerror(status)));
203 if (status == ARES_SUCCESS) {
204 status = init_by_environment(channel);
205 if (status != ARES_SUCCESS)
206 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
207 ares_strerror(status)));
209 if (status == ARES_SUCCESS) {
210 status = init_by_resolv_conf(channel);
211 if (status != ARES_SUCCESS)
212 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
213 ares_strerror(status)));
217 * No matter what failed or succeeded, seed defaults to provide
218 * useful behavior for things that we missed.
220 status = init_by_defaults(channel);
221 if (status != ARES_SUCCESS)
222 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
223 ares_strerror(status)));
225 /* Generate random key */
227 if (status == ARES_SUCCESS) {
228 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
229 if (status == ARES_SUCCESS)
230 channel->next_id = ares__generate_new_id(&channel->id_key);
232 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
233 ares_strerror(status)));
236 if (status != ARES_SUCCESS)
238 /* Something failed; clean up memory we may have allocated. */
239 if (channel->servers)
240 free(channel->servers);
241 if (channel->domains)
243 for (i = 0; i < channel->ndomains; i++)
244 free(channel->domains[i]);
245 free(channel->domains);
247 if (channel->sortlist)
248 free(channel->sortlist);
250 free(channel->lookups);
255 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
256 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
257 channel->nservers = 1;
259 ares__init_servers_state(channel);
261 *channelptr = channel;
265 /* ares_dup() duplicates a channel handle with all its options and returns a
266 new channel handle */
267 int ares_dup(ares_channel *dest, ares_channel src)
269 struct ares_options opts;
270 struct ares_addr_node *servers;
271 int ipv6_nservers = 0;
275 *dest = NULL; /* in case of failure return NULL explicitly */
277 /* First get the options supported by the old ares_save_options() function,
278 which is most of them */
279 rc = ares_save_options(src, &opts, &optmask);
283 /* Then create the new channel with those options */
284 rc = ares_init_options(dest, &opts, optmask);
286 /* destroy the options copy to not leak any memory */
287 ares_destroy_options(&opts);
292 /* Now clone the options that ares_save_options() doesn't support. */
293 (*dest)->sock_create_cb = src->sock_create_cb;
294 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
296 strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name));
297 (*dest)->local_ip4 = src->local_ip4;
298 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
300 /* Full name server cloning required when not all are IPv4 */
301 for (i = 0; i < src->nservers; i++)
303 if (src->servers[i].addr.family != AF_INET) {
309 rc = ares_get_servers(src, &servers);
310 if (rc != ARES_SUCCESS)
312 rc = ares_set_servers(*dest, servers);
313 ares_free_data(servers);
314 if (rc != ARES_SUCCESS)
318 return ARES_SUCCESS; /* everything went fine */
321 /* Save options from initialized channel */
322 int ares_save_options(ares_channel channel, struct ares_options *options,
326 int ipv4_nservers = 0;
328 /* Zero everything out */
329 memset(options, 0, sizeof(struct ares_options));
331 if (!ARES_CONFIG_CHECK(channel))
334 /* Traditionally the optmask wasn't saved in the channel struct so it was
335 recreated here. ROTATE is the first option that has no struct field of
336 its own in the public config struct */
337 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
338 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
339 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
340 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
341 (channel->optmask & ARES_OPT_ROTATE);
343 /* Copy easy stuff */
344 options->flags = channel->flags;
346 /* We return full millisecond resolution but that's only because we don't
347 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
348 options->timeout = channel->timeout;
349 options->tries = channel->tries;
350 options->ndots = channel->ndots;
351 options->udp_port = (unsigned short)channel->udp_port;
352 options->tcp_port = (unsigned short)channel->tcp_port;
353 options->sock_state_cb = channel->sock_state_cb;
354 options->sock_state_cb_data = channel->sock_state_cb_data;
356 /* Copy IPv4 servers */
357 if (channel->nservers) {
358 for (i = 0; i < channel->nservers; i++)
360 if (channel->servers[i].addr.family == AF_INET)
364 options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
365 if (!options->servers)
367 for (i = j = 0; i < channel->nservers; i++)
369 if (channel->servers[i].addr.family == AF_INET)
370 memcpy(&options->servers[j++],
371 &channel->servers[i].addr.addrV4,
372 sizeof(channel->servers[i].addr.addrV4));
376 options->nservers = ipv4_nservers;
379 if (channel->ndomains) {
380 options->domains = malloc(channel->ndomains * sizeof(char *));
381 if (!options->domains)
384 for (i = 0; i < channel->ndomains; i++)
386 options->ndomains = i;
387 options->domains[i] = strdup(channel->domains[i]);
388 if (!options->domains[i])
392 options->ndomains = channel->ndomains;
395 if (channel->lookups) {
396 options->lookups = strdup(channel->lookups);
397 if (!options->lookups && channel->lookups)
402 if (channel->nsort) {
403 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
404 if (!options->sortlist)
406 for (i = 0; i < channel->nsort; i++)
407 options->sortlist[i] = channel->sortlist[i];
409 options->nsort = channel->nsort;
414 static int init_by_options(ares_channel channel,
415 const struct ares_options *options,
421 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
422 channel->flags = options->flags;
423 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
424 channel->timeout = options->timeout;
425 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
426 channel->timeout = options->timeout * 1000;
427 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
428 channel->tries = options->tries;
429 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
430 channel->ndots = options->ndots;
431 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
433 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
434 channel->udp_port = options->udp_port;
435 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
436 channel->tcp_port = options->tcp_port;
437 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
439 channel->sock_state_cb = options->sock_state_cb;
440 channel->sock_state_cb_data = options->sock_state_cb_data;
442 if ((optmask & ARES_OPT_SOCK_SNDBUF)
443 && channel->socket_send_buffer_size == -1)
444 channel->socket_send_buffer_size = options->socket_send_buffer_size;
445 if ((optmask & ARES_OPT_SOCK_RCVBUF)
446 && channel->socket_receive_buffer_size == -1)
447 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
449 /* Copy the IPv4 servers, if given. */
450 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
452 /* Avoid zero size allocations at any cost */
453 if (options->nservers > 0)
456 malloc(options->nservers * sizeof(struct server_state));
457 if (!channel->servers)
459 for (i = 0; i < options->nservers; i++)
461 channel->servers[i].addr.family = AF_INET;
462 memcpy(&channel->servers[i].addr.addrV4,
463 &options->servers[i],
464 sizeof(channel->servers[i].addr.addrV4));
467 channel->nservers = options->nservers;
470 /* Copy the domains, if given. Keep channel->ndomains consistent so
471 * we can clean up in case of error.
473 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
475 /* Avoid zero size allocations at any cost */
476 if (options->ndomains > 0)
478 channel->domains = malloc(options->ndomains * sizeof(char *));
479 if (!channel->domains)
481 for (i = 0; i < options->ndomains; i++)
483 channel->ndomains = i;
484 channel->domains[i] = strdup(options->domains[i]);
485 if (!channel->domains[i])
489 channel->ndomains = options->ndomains;
492 /* Set lookups, if given. */
493 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
495 channel->lookups = strdup(options->lookups);
496 if (!channel->lookups)
501 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
502 (options->nsort>0)) {
503 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
504 if (!channel->sortlist)
506 for (i = 0; i < options->nsort; i++)
507 channel->sortlist[i] = options->sortlist[i];
508 channel->nsort = options->nsort;
511 channel->optmask = optmask;
516 static int init_by_environment(ares_channel channel)
518 const char *localdomain, *res_options;
521 localdomain = getenv("LOCALDOMAIN");
522 if (localdomain && channel->ndomains == -1)
524 status = set_search(channel, localdomain);
525 if (status != ARES_SUCCESS)
529 res_options = getenv("RES_OPTIONS");
532 status = set_options(channel, res_options);
533 if (status != ARES_SUCCESS)
542 * Warning: returns a dynamically allocated buffer, the user MUST
543 * use free() if the function returns 1
545 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
547 /* Test for the size we need */
551 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
552 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
554 *obuf = malloc(size+1);
558 if (RegQueryValueEx(hKey, subkey, 0, NULL,
559 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
572 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
574 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
575 DWORD enum_size = 39;
579 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
580 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
585 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
588 rc = get_res_nt(hVal, subkey, obuf);
597 * The desired output for this method is that we set "ret_buf" to
600 * 192.168.0.1,dns01.my.domain,fe80::200:f8ff:fe21:67cf
602 * The only ordering requirement is that primary servers are listed
603 * before secondary. There is no requirement that IPv4 addresses should
604 * necessarily be before IPv6.
606 * Note that ret_size should ideally be big enough to hold around
607 * 2-3 IPv4 and 2-3 IPv6 addresses.
609 * Finally, we need to return the total number of DNS servers located.
611 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
613 const size_t ipv4_size = INET_ADDRSTRLEN + 1; /* +1 for ',' at end */
614 const size_t ipv6_size = INET6_ADDRSTRLEN + 12; /* +12 for "%0123456789," at end */
615 size_t left = ret_size;
619 /* Use the GetAdaptersAddresses method if it's available, otherwise
620 fall back to GetNetworkParams. */
621 if (ares_fpGetAdaptersAddresses != ZERO_NULL)
623 const ULONG working_buf_size = 15000;
624 IP_ADAPTER_ADDRESSES *pFirstEntry = NULL;
625 IP_ADAPTER_ADDRESSES *pEntry = NULL;
629 /* According to MSDN, the recommended way to do this is to use a temporary
630 buffer of 15K, to "dramatically reduce the chance that the GetAdaptersAddresses
631 method returns ERROR_BUFFER_OVERFLOW" */
632 pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) malloc( working_buf_size );
633 bufSize = working_buf_size;
637 /* Call the method one time */
638 result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
639 if( result == ERROR_BUFFER_OVERFLOW )
641 /* Reallocate, bufSize should now be set to the required size */
642 pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
646 /* Call the method a second time */
647 result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
648 if( result == ERROR_BUFFER_OVERFLOW )
650 /* Reallocate, bufSize should now be set to the required size */
651 pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
655 /* Call the method a third time. The maximum number of times we're going to do
656 this is 3. Three shall be the number thou shalt count, and the number of the
657 counting shall be three. Five is right out. */
658 result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
662 /* Check the current result for failure */
663 if( result != ERROR_SUCCESS )
669 /* process the results */
670 for( pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next )
672 IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
673 for( ; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next )
675 struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
676 size_t stringlen = 0;
678 if( pGenericAddr->sa_family == AF_INET && left > ipv4_size )
680 /* Handle the v4 case */
681 struct sockaddr_in *pIPv4Addr = ( struct sockaddr_in * ) pGenericAddr;
682 ares_inet_ntop( AF_INET, &pIPv4Addr->sin_addr, ret, ipv4_size - 1 ); /* -1 for comma */
684 /* Append a comma to the end, THEN NULL. Should be OK because we
685 already tested the size at the top of the if statement. */
686 stringlen = strlen( ret );
687 ret[ stringlen ] = ',';
688 ret[ stringlen + 1 ] = '\0';
689 ret += stringlen + 1;
690 left -= ret - ret_buf;
693 else if( pGenericAddr->sa_family == AF_INET6 && left > ipv6_size )
695 /* Handle the v6 case */
696 struct sockaddr_in6 *pIPv6Addr = ( struct sockaddr_in6 * ) pGenericAddr;
697 ares_inet_ntop( AF_INET6, &pIPv6Addr->sin6_addr, ret, ipv6_size - 1 ); /* -1 for comma */
699 /* Append a comma to the end, THEN NULL. Should be OK because we
700 already tested the size at the top of the if statement. */
701 stringlen = strlen( ret );
702 ret[ stringlen ] = ',';
703 ret[ stringlen + 1 ] = '\0';
704 ret += stringlen + 1;
705 left -= ret - ret_buf;
708 /* NB on Windows this also returns stuff in the fec0::/10 range,
709 seems to be hard-coded somehow. Do we need to ignore them? */
722 FIXED_INFO *fi, *newfi;
723 DWORD size = sizeof (*fi);
724 IP_ADDR_STRING *ipAddr;
733 res = (*ares_fpGetNetworkParams) (fi, &size);
734 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
737 newfi = realloc(fi, size);
742 res = (*ares_fpGetNetworkParams) (fi, &size);
743 if (res != ERROR_SUCCESS)
748 printf ("Host Name: %s\n", fi->HostName);
749 printf ("Domain Name: %s\n", fi->DomainName);
750 printf ("DNS Servers:\n"
751 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
753 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
754 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
757 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
758 left -= ret - ret_buf;
762 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
763 ipAddr = ipAddr->Next, i++)
765 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
767 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
768 left -= ret - ret_buf;
772 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
779 if (debug && left <= ipv4_size)
780 printf ("Too many nameservers. Truncating to %d addressess", count);
788 static int init_by_resolv_conf(ares_channel channel)
793 int status = -1, nservers = 0, nsort = 0;
794 struct server_state *servers = NULL;
795 struct apattern *sortlist = NULL;
800 NameServer info via IPHLPAPI (IP helper API):
801 GetNetworkParams() should be the trusted source for this.
802 Available in Win-98/2000 and later. If that fail, fall-back to
803 registry information.
807 On Windows 9X, the DNS server can be found in:
808 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
810 On Windows NT/2000/XP/2003:
811 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
813 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
815 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
818 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
828 win_platform platform;
830 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
833 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
835 status = config_nameserver(&servers, &nservers, buf);
836 if (status == ARES_SUCCESS)
840 platform = ares__getplatform();
842 if (platform == WIN_NT)
845 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
849 RegOpenKeyEx(mykey, "Interfaces", 0,
850 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
851 if (get_res_nt(mykey, NAMESERVER, &line))
853 status = config_nameserver(&servers, &nservers, line);
856 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
858 status = config_nameserver(&servers, &nservers, line);
861 /* Try the interfaces */
862 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
864 status = config_nameserver(&servers, &nservers, line);
867 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
869 status = config_nameserver(&servers, &nservers, line);
876 else if (platform == WIN_9X)
879 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
883 if ((result = RegQueryValueEx(
884 mykey, NAMESERVER, NULL, &data_type,
887 ) == ERROR_SUCCESS ||
888 result == ERROR_MORE_DATA)
892 line = malloc(bytes+1);
893 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
894 (unsigned char *)line, &bytes) ==
897 status = config_nameserver(&servers, &nservers, line);
906 if (status == ARES_SUCCESS)
909 /* Catch the case when all the above checks fail (which happens when there
910 is no network card or the cable is unplugged) */
913 #elif defined(__riscos__)
915 /* Under RISC OS, name servers are listed in the
916 system variable Inet$Resolvers, space separated. */
918 line = getenv("Inet$Resolvers");
921 char *resolvers = strdup(line), *pos, *space;
928 space = strchr(pos, ' ');
931 status = config_nameserver(&servers, &nservers, pos);
932 if (status != ARES_SUCCESS)
937 if (status == ARES_SUCCESS)
943 #elif defined(WATT32)
947 for (i = 0; def_nameservers[i]; i++)
950 return ARES_SUCCESS; /* use localhost DNS server */
953 servers = calloc(i, sizeof(struct server_state));
957 for (i = 0; def_nameservers[i]; i++)
959 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
960 servers[i].addr.family = AF_INET;
964 #elif defined(ANDROID)
965 char value[PROP_VALUE_MAX]="";
966 __system_property_get("net.dns1", value);
967 status = config_nameserver(&servers, &nservers, value);
968 if (status == ARES_SUCCESS)
977 /* Don't read resolv.conf and friends if we don't have to */
978 if (ARES_CONFIG_CHECK(channel))
981 fp = fopen(PATH_RESOLV_CONF, "r");
983 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
985 if ((p = try_config(line, "domain", ';')))
986 status = config_domain(channel, p);
987 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
988 status = config_lookup(channel, p, "bind", "file");
989 else if ((p = try_config(line, "search", ';')))
990 status = set_search(channel, p);
991 else if ((p = try_config(line, "nameserver", ';')) &&
992 channel->nservers == -1)
993 status = config_nameserver(&servers, &nservers, p);
994 else if ((p = try_config(line, "sortlist", ';')) &&
995 channel->nsort == -1)
996 status = config_sortlist(&sortlist, &nsort, p);
997 else if ((p = try_config(line, "options", ';')))
998 status = set_options(channel, p);
1000 status = ARES_SUCCESS;
1001 if (status != ARES_SUCCESS)
1014 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1015 error, strerror(error)));
1016 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1017 status = ARES_EFILE;
1021 if ((status == ARES_EOF) && (!channel->lookups)) {
1022 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1023 fp = fopen("/etc/nsswitch.conf", "r");
1025 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1027 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1029 (void)config_lookup(channel, p, "dns", "files");
1041 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1042 error, strerror(error)));
1043 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
1044 status = ARES_EFILE;
1049 if ((status == ARES_EOF) && (!channel->lookups)) {
1050 /* Linux / GNU libc 2.x and possibly others have host.conf */
1051 fp = fopen("/etc/host.conf", "r");
1053 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1055 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1057 (void)config_lookup(channel, p, "bind", "hosts");
1069 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1070 error, strerror(error)));
1071 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
1072 status = ARES_EFILE;
1077 if ((status == ARES_EOF) && (!channel->lookups)) {
1078 /* Tru64 uses /etc/svc.conf */
1079 fp = fopen("/etc/svc.conf", "r");
1081 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1083 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1085 (void)config_lookup(channel, p, "bind", "local");
1097 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1098 error, strerror(error)));
1099 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1100 status = ARES_EFILE;
1111 /* Handle errors. */
1112 if (status != ARES_EOF)
1114 if (servers != NULL)
1116 if (sortlist != NULL)
1121 /* If we got any name server entries, fill them in. */
1127 channel->servers = servers;
1128 channel->nservers = nservers;
1131 /* If we got any sortlist entries, fill them in. */
1134 channel->sortlist = sortlist;
1135 channel->nsort = nsort;
1138 return ARES_SUCCESS;
1141 static int init_by_defaults(ares_channel channel)
1143 char *hostname = NULL;
1144 int rc = ARES_SUCCESS;
1145 #ifdef HAVE_GETHOSTNAME
1149 if (channel->flags == -1)
1151 if (channel->timeout == -1)
1152 channel->timeout = DEFAULT_TIMEOUT;
1153 if (channel->tries == -1)
1154 channel->tries = DEFAULT_TRIES;
1155 if (channel->ndots == -1)
1157 if (channel->rotate == -1)
1158 channel->rotate = 0;
1159 if (channel->udp_port == -1)
1160 channel->udp_port = htons(NAMESERVER_PORT);
1161 if (channel->tcp_port == -1)
1162 channel->tcp_port = htons(NAMESERVER_PORT);
1164 if (channel->nservers == -1) {
1165 /* If nobody specified servers, try a local named. */
1166 channel->servers = malloc(sizeof(struct server_state));
1167 if (!channel->servers) {
1171 channel->servers[0].addr.family = AF_INET;
1172 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1173 channel->nservers = 1;
1176 #if defined(USE_WINSOCK)
1177 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1178 #elif defined(ENAMETOOLONG)
1179 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1180 (SOCKERRNO == EINVAL))
1182 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1185 if (channel->ndomains == -1) {
1186 /* Derive a default domain search list from the kernel hostname,
1187 * or set it to empty if the hostname isn't helpful.
1191 channel->ndomains = 0; /* default to none */
1193 #ifdef HAVE_GETHOSTNAME
1194 hostname = malloc(len);
1201 res = gethostname(hostname, len);
1206 p = realloc(hostname, len);
1221 dot = strchr(hostname, '.');
1223 /* a dot was found */
1224 channel->domains = malloc(sizeof(char *));
1225 if (!channel->domains) {
1229 channel->domains[0] = strdup(dot + 1);
1230 if (!channel->domains[0]) {
1234 channel->ndomains = 1;
1239 if (channel->nsort == -1) {
1240 channel->sortlist = NULL;
1244 if (!channel->lookups) {
1245 channel->lookups = strdup("fb");
1246 if (!channel->lookups)
1252 if(channel->servers) {
1253 free(channel->servers);
1254 channel->servers = NULL;
1257 if(channel->domains && channel->domains[0])
1258 free(channel->domains[0]);
1259 if(channel->domains) {
1260 free(channel->domains);
1261 channel->domains = NULL;
1264 if(channel->lookups) {
1265 free(channel->lookups);
1266 channel->lookups = NULL;
1276 #if !defined(WIN32) && !defined(WATT32)
1277 static int config_domain(ares_channel channel, char *str)
1281 /* Set a single search domain. */
1283 while (*q && !ISSPACE(*q))
1286 return set_search(channel, str);
1289 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1290 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1291 /* workaround icc 9.1 optimizer issue */
1292 # define vqualifier volatile
1297 static int config_lookup(ares_channel channel, const char *str,
1298 const char *bindch, const char *filech)
1300 char lookups[3], *l;
1301 const char *vqualifier p;
1303 /* Set the lookup order. Only the first letter of each work
1304 * is relevant, and it has to be "b" for DNS or "f" for the
1305 * host file. Ignore everything else.
1311 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1312 if (*p == *bindch) *l++ = 'b';
1315 while (*p && !ISSPACE(*p) && (*p != ','))
1317 while (*p && (ISSPACE(*p) || (*p == ',')))
1321 channel->lookups = strdup(lookups);
1322 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1324 #endif /* !WIN32 & !WATT32 */
1327 static int config_nameserver(struct server_state **servers, int *nservers,
1330 struct ares_addr host;
1331 struct server_state *newserv;
1333 /* On Windows, there may be more than one nameserver specified in the same
1334 * registry key, so we parse input as a space or comma seperated list.
1338 /* Skip whitespace and commas. */
1339 while (*p && (ISSPACE(*p) || (*p == ',')))
1342 /* No more input, done. */
1345 /* Pointer to start of IPv4 or IPv6 address part. */
1348 /* Advance past this address. */
1349 while (*p && !ISSPACE(*p) && (*p != ','))
1352 /* Null terminate this address. */
1355 /* Reached end of input, done when this address is processed. */
1358 /* Convert textual address to binary format. */
1359 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1360 host.family = AF_INET;
1361 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1362 host.family = AF_INET6;
1366 /* Resize servers state array. */
1367 newserv = realloc(*servers, (*nservers + 1) *
1368 sizeof(struct server_state));
1372 /* Store address data. */
1373 newserv[*nservers].addr.family = host.family;
1374 if (host.family == AF_INET)
1375 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1376 sizeof(host.addrV4));
1378 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1379 sizeof(host.addrV6));
1381 /* Update arguments. */
1386 return ARES_SUCCESS;
1390 static int config_sortlist(struct apattern **sortlist, int *nsort,
1393 struct apattern pat;
1396 /* Add sortlist entries. */
1397 while (*str && *str != ';')
1400 char ipbuf[16], ipbufpfx[32];
1401 /* Find just the IP */
1403 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1405 memcpy(ipbuf, str, q-str);
1406 ipbuf[q-str] = '\0';
1407 /* Find the prefix */
1410 const char *str2 = q+1;
1411 while (*q && *q != ';' && !ISSPACE(*q))
1413 memcpy(ipbufpfx, str, q-str);
1414 ipbufpfx[q-str] = '\0';
1419 /* Lets see if it is CIDR */
1420 /* First we'll try IPv6 */
1421 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1423 sizeof(pat.addrV6))) > 0)
1425 pat.type = PATTERN_CIDR;
1426 pat.mask.bits = (unsigned short)bits;
1427 pat.family = AF_INET6;
1428 if (!sortlist_alloc(sortlist, nsort, &pat))
1431 else if (ipbufpfx[0] &&
1432 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1433 sizeof(pat.addrV4))) > 0)
1435 pat.type = PATTERN_CIDR;
1436 pat.mask.bits = (unsigned short)bits;
1437 pat.family = AF_INET;
1438 if (!sortlist_alloc(sortlist, nsort, &pat))
1441 /* See if it is just a regular IP */
1442 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1446 memcpy(ipbuf, str, q-str);
1447 ipbuf[q-str] = '\0';
1448 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1453 pat.family = AF_INET;
1454 pat.type = PATTERN_MASK;
1455 if (!sortlist_alloc(sortlist, nsort, &pat))
1460 while (*q && *q != ';' && !ISSPACE(*q))
1464 while (ISSPACE(*str))
1468 return ARES_SUCCESS;
1471 #endif /* !WATT32 */
1473 static int set_search(ares_channel channel, const char *str)
1478 if(channel->ndomains != -1) {
1479 /* if we already have some domains present, free them first */
1480 for(n=0; n < channel->ndomains; n++)
1481 free(channel->domains[n]);
1482 free(channel->domains);
1483 channel->domains = NULL;
1484 channel->ndomains = -1;
1487 /* Count the domains given. */
1492 while (*p && !ISSPACE(*p))
1501 channel->ndomains = 0;
1502 return ARES_SUCCESS;
1505 channel->domains = malloc(n * sizeof(char *));
1506 if (!channel->domains)
1509 /* Now copy the domains. */
1514 channel->ndomains = n;
1516 while (*q && !ISSPACE(*q))
1518 channel->domains[n] = malloc(q - p + 1);
1519 if (!channel->domains[n])
1521 memcpy(channel->domains[n], p, q - p);
1522 channel->domains[n][q - p] = 0;
1528 channel->ndomains = n;
1530 return ARES_SUCCESS;
1533 static int set_options(ares_channel channel, const char *str)
1535 const char *p, *q, *val;
1541 while (*q && !ISSPACE(*q))
1543 val = try_option(p, q, "ndots:");
1544 if (val && channel->ndots == -1)
1545 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1546 val = try_option(p, q, "retrans:");
1547 if (val && channel->timeout == -1)
1548 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1549 val = try_option(p, q, "retry:");
1550 if (val && channel->tries == -1)
1551 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1552 val = try_option(p, q, "rotate");
1553 if (val && channel->rotate == -1)
1554 channel->rotate = 1;
1560 return ARES_SUCCESS;
1563 static const char *try_option(const char *p, const char *q, const char *opt)
1565 size_t len = strlen(opt);
1566 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1569 #if !defined(WIN32) && !defined(WATT32)
1570 static char *try_config(char *s, const char *opt, char scc)
1577 /* no line or no option */
1580 /* Hash '#' character is always used as primary comment char, additionally
1581 a not-NUL secondary comment char will be considered when specified. */
1583 /* trim line comment */
1586 while (*p && (*p != '#') && (*p != scc))
1589 while (*p && (*p != '#'))
1593 /* trim trailing whitespace */
1595 while ((q >= s) && ISSPACE(*q))
1599 /* skip leading whitespace */
1601 while (*p && ISSPACE(*p))
1608 if ((len = strlen(opt)) == 0)
1612 if (strncmp(p, opt, len) != 0)
1613 /* line and option do not match */
1616 /* skip over given option name */
1620 /* no option value */
1623 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1624 /* whitespace between option name and value is mandatory
1625 for given option names which do not end with ':' or '=' */
1628 /* skip over whitespace */
1629 while (*p && ISSPACE(*p))
1633 /* no option value */
1636 /* return pointer to option value */
1640 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1641 struct apattern *pat)
1643 struct apattern *newsort;
1644 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1647 newsort[*nsort] = *pat;
1648 *sortlist = newsort;
1653 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1656 /* Four octets and three periods yields at most 15 characters. */
1660 addr->s_addr = inet_addr(ipbuf);
1661 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1666 static void natural_mask(struct apattern *pat)
1668 struct in_addr addr;
1670 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1673 addr.s_addr = ntohl(pat->addrV4.s_addr);
1675 /* This is out of date in the CIDR world, but some people might
1678 if (IN_CLASSA(addr.s_addr))
1679 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1680 else if (IN_CLASSB(addr.s_addr))
1681 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1683 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1685 #endif /* !WIN32 && !WATT32 */
1687 /* initialize an rc4 key. If possible a cryptographically secure random key
1688 is generated using a suitable function (for example win32's RtlGenRandom as
1690 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1691 otherwise the code defaults to cross-platform albeit less secure mechanism
1694 static void randomize_key(unsigned char* key,int key_data_len)
1700 if (ares_fpSystemFunction036)
1702 res = (*ares_fpSystemFunction036) (key, key_data_len);
1708 FILE *f = fopen(RANDOM_FILE, "rb");
1710 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1716 if ( !randomized ) {
1717 for (;counter<key_data_len;counter++)
1718 key[counter]=(unsigned char)(rand() % 256);
1722 static int init_id_key(rc4_key* key,int key_data_len)
1724 unsigned char index1;
1725 unsigned char index2;
1726 unsigned char* state;
1728 unsigned char *key_data_ptr = 0;
1730 key_data_ptr = calloc(1,key_data_len);
1734 state = &key->state[0];
1735 for(counter = 0; counter < 256; counter++)
1736 /* unnecessary AND but it keeps some compilers happier */
1737 state[counter] = (unsigned char)(counter & 0xff);
1738 randomize_key(key->state,key_data_len);
1743 for(counter = 0; counter < 256; counter++)
1745 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1747 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1749 index1 = (unsigned char)((index1 + 1) % key_data_len);
1752 return ARES_SUCCESS;
1755 unsigned short ares__generate_new_id(rc4_key* key)
1758 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1762 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1764 channel->local_ip4 = local_ip;
1767 /* local_ip6 should be 16 bytes in length */
1768 void ares_set_local_ip6(ares_channel channel,
1769 const unsigned char* local_ip6)
1771 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1774 /* local_dev_name should be null terminated. */
1775 void ares_set_local_dev(ares_channel channel,
1776 const char* local_dev_name)
1778 strncpy(channel->local_dev_name, local_dev_name,
1779 sizeof(channel->local_dev_name));
1780 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1784 void ares_set_socket_callback(ares_channel channel,
1785 ares_sock_create_callback cb,
1788 channel->sock_create_cb = cb;
1789 channel->sock_create_cb_data = data;
1792 void ares__init_servers_state(ares_channel channel)
1794 struct server_state *server;
1797 for (i = 0; i < channel->nservers; i++)
1799 server = &channel->servers[i];
1800 server->udp_socket = ARES_SOCKET_BAD;
1801 server->tcp_socket = ARES_SOCKET_BAD;
1802 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1803 server->tcp_lenbuf_pos = 0;
1804 server->tcp_buffer_pos = 0;
1805 server->tcp_buffer = NULL;
1806 server->tcp_length = 0;
1807 server->qhead = NULL;
1808 server->qtail = NULL;
1809 ares__init_list_head(&server->queries_to_server);
1810 server->channel = channel;
1811 server->is_broken = 0;