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 server_state));
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);
1255 if(channel->domains && channel->domains[0])
1256 free(channel->domains[0]);
1257 if(channel->domains)
1258 free(channel->domains);
1259 if(channel->lookups)
1260 free(channel->lookups);
1269 #if !defined(WIN32) && !defined(WATT32)
1270 static int config_domain(ares_channel channel, char *str)
1274 /* Set a single search domain. */
1276 while (*q && !ISSPACE(*q))
1279 return set_search(channel, str);
1282 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1283 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1284 /* workaround icc 9.1 optimizer issue */
1285 # define vqualifier volatile
1290 static int config_lookup(ares_channel channel, const char *str,
1291 const char *bindch, const char *filech)
1293 char lookups[3], *l;
1294 const char *vqualifier p;
1296 /* Set the lookup order. Only the first letter of each work
1297 * is relevant, and it has to be "b" for DNS or "f" for the
1298 * host file. Ignore everything else.
1304 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1305 if (*p == *bindch) *l++ = 'b';
1308 while (*p && !ISSPACE(*p) && (*p != ','))
1310 while (*p && (ISSPACE(*p) || (*p == ',')))
1314 channel->lookups = strdup(lookups);
1315 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1317 #endif /* !WIN32 & !WATT32 */
1320 static int config_nameserver(struct server_state **servers, int *nservers,
1323 struct ares_addr host;
1324 struct server_state *newserv;
1326 /* On Windows, there may be more than one nameserver specified in the same
1327 * registry key, so we parse input as a space or comma seperated list.
1331 /* Skip whitespace and commas. */
1332 while (*p && (ISSPACE(*p) || (*p == ',')))
1335 /* No more input, done. */
1338 /* Pointer to start of IPv4 or IPv6 address part. */
1341 /* Advance past this address. */
1342 while (*p && !ISSPACE(*p) && (*p != ','))
1345 /* Null terminate this address. */
1348 /* Reached end of input, done when this address is processed. */
1351 /* Convert textual address to binary format. */
1352 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1353 host.family = AF_INET;
1354 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1355 host.family = AF_INET6;
1359 /* Resize servers state array. */
1360 newserv = realloc(*servers, (*nservers + 1) *
1361 sizeof(struct server_state));
1365 /* Store address data. */
1366 newserv[*nservers].addr.family = host.family;
1367 if (host.family == AF_INET)
1368 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1369 sizeof(host.addrV4));
1371 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1372 sizeof(host.addrV6));
1374 /* Update arguments. */
1379 return ARES_SUCCESS;
1383 static int config_sortlist(struct apattern **sortlist, int *nsort,
1386 struct apattern pat;
1389 /* Add sortlist entries. */
1390 while (*str && *str != ';')
1393 char ipbuf[16], ipbufpfx[32];
1394 /* Find just the IP */
1396 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1398 memcpy(ipbuf, str, q-str);
1399 ipbuf[q-str] = '\0';
1400 /* Find the prefix */
1403 const char *str2 = q+1;
1404 while (*q && *q != ';' && !ISSPACE(*q))
1406 memcpy(ipbufpfx, str, q-str);
1407 ipbufpfx[q-str] = '\0';
1412 /* Lets see if it is CIDR */
1413 /* First we'll try IPv6 */
1414 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1416 sizeof(pat.addrV6))) > 0)
1418 pat.type = PATTERN_CIDR;
1419 pat.mask.bits = (unsigned short)bits;
1420 pat.family = AF_INET6;
1421 if (!sortlist_alloc(sortlist, nsort, &pat))
1424 else if (ipbufpfx[0] &&
1425 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1426 sizeof(pat.addrV4))) > 0)
1428 pat.type = PATTERN_CIDR;
1429 pat.mask.bits = (unsigned short)bits;
1430 pat.family = AF_INET;
1431 if (!sortlist_alloc(sortlist, nsort, &pat))
1434 /* See if it is just a regular IP */
1435 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1439 memcpy(ipbuf, str, q-str);
1440 ipbuf[q-str] = '\0';
1441 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1446 pat.family = AF_INET;
1447 pat.type = PATTERN_MASK;
1448 if (!sortlist_alloc(sortlist, nsort, &pat))
1453 while (*q && *q != ';' && !ISSPACE(*q))
1457 while (ISSPACE(*str))
1461 return ARES_SUCCESS;
1464 #endif /* !WATT32 */
1466 static int set_search(ares_channel channel, const char *str)
1471 if(channel->ndomains != -1) {
1472 /* if we already have some domains present, free them first */
1473 for(n=0; n < channel->ndomains; n++)
1474 free(channel->domains[n]);
1475 free(channel->domains);
1476 channel->domains = NULL;
1477 channel->ndomains = -1;
1480 /* Count the domains given. */
1485 while (*p && !ISSPACE(*p))
1494 channel->ndomains = 0;
1495 return ARES_SUCCESS;
1498 channel->domains = malloc(n * sizeof(char *));
1499 if (!channel->domains)
1502 /* Now copy the domains. */
1507 channel->ndomains = n;
1509 while (*q && !ISSPACE(*q))
1511 channel->domains[n] = malloc(q - p + 1);
1512 if (!channel->domains[n])
1514 memcpy(channel->domains[n], p, q - p);
1515 channel->domains[n][q - p] = 0;
1521 channel->ndomains = n;
1523 return ARES_SUCCESS;
1526 static int set_options(ares_channel channel, const char *str)
1528 const char *p, *q, *val;
1534 while (*q && !ISSPACE(*q))
1536 val = try_option(p, q, "ndots:");
1537 if (val && channel->ndots == -1)
1538 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1539 val = try_option(p, q, "retrans:");
1540 if (val && channel->timeout == -1)
1541 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1542 val = try_option(p, q, "retry:");
1543 if (val && channel->tries == -1)
1544 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1545 val = try_option(p, q, "rotate");
1546 if (val && channel->rotate == -1)
1547 channel->rotate = 1;
1553 return ARES_SUCCESS;
1556 static const char *try_option(const char *p, const char *q, const char *opt)
1558 size_t len = strlen(opt);
1559 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1562 #if !defined(WIN32) && !defined(WATT32)
1563 static char *try_config(char *s, const char *opt, char scc)
1570 /* no line or no option */
1573 /* Hash '#' character is always used as primary comment char, additionally
1574 a not-NUL secondary comment char will be considered when specified. */
1576 /* trim line comment */
1579 while (*p && (*p != '#') && (*p != scc))
1582 while (*p && (*p != '#'))
1586 /* trim trailing whitespace */
1588 while ((q >= s) && ISSPACE(*q))
1592 /* skip leading whitespace */
1594 while (*p && ISSPACE(*p))
1601 if ((len = strlen(opt)) == 0)
1605 if (strncmp(p, opt, len) != 0)
1606 /* line and option do not match */
1609 /* skip over given option name */
1613 /* no option value */
1616 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1617 /* whitespace between option name and value is mandatory
1618 for given option names which do not end with ':' or '=' */
1621 /* skip over whitespace */
1622 while (*p && ISSPACE(*p))
1626 /* no option value */
1629 /* return pointer to option value */
1633 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1634 struct apattern *pat)
1636 struct apattern *newsort;
1637 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1640 newsort[*nsort] = *pat;
1641 *sortlist = newsort;
1646 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1649 /* Four octets and three periods yields at most 15 characters. */
1653 addr->s_addr = inet_addr(ipbuf);
1654 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1659 static void natural_mask(struct apattern *pat)
1661 struct in_addr addr;
1663 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1666 addr.s_addr = ntohl(pat->addrV4.s_addr);
1668 /* This is out of date in the CIDR world, but some people might
1671 if (IN_CLASSA(addr.s_addr))
1672 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1673 else if (IN_CLASSB(addr.s_addr))
1674 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1676 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1678 #endif /* !WIN32 && !WATT32 */
1680 /* initialize an rc4 key. If possible a cryptographically secure random key
1681 is generated using a suitable function (for example win32's RtlGenRandom as
1683 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1684 otherwise the code defaults to cross-platform albeit less secure mechanism
1687 static void randomize_key(unsigned char* key,int key_data_len)
1693 if (ares_fpSystemFunction036)
1695 res = (*ares_fpSystemFunction036) (key, key_data_len);
1701 FILE *f = fopen(RANDOM_FILE, "rb");
1703 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1709 if ( !randomized ) {
1710 for (;counter<key_data_len;counter++)
1711 key[counter]=(unsigned char)(rand() % 256);
1715 static int init_id_key(rc4_key* key,int key_data_len)
1717 unsigned char index1;
1718 unsigned char index2;
1719 unsigned char* state;
1721 unsigned char *key_data_ptr = 0;
1723 key_data_ptr = calloc(1,key_data_len);
1727 state = &key->state[0];
1728 for(counter = 0; counter < 256; counter++)
1729 /* unnecessary AND but it keeps some compilers happier */
1730 state[counter] = (unsigned char)(counter & 0xff);
1731 randomize_key(key->state,key_data_len);
1736 for(counter = 0; counter < 256; counter++)
1738 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1740 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1742 index1 = (unsigned char)((index1 + 1) % key_data_len);
1745 return ARES_SUCCESS;
1748 unsigned short ares__generate_new_id(rc4_key* key)
1751 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1755 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1757 channel->local_ip4 = local_ip;
1760 /* local_ip6 should be 16 bytes in length */
1761 void ares_set_local_ip6(ares_channel channel,
1762 const unsigned char* local_ip6)
1764 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1767 /* local_dev_name should be null terminated. */
1768 void ares_set_local_dev(ares_channel channel,
1769 const char* local_dev_name)
1771 strncpy(channel->local_dev_name, local_dev_name,
1772 sizeof(channel->local_dev_name));
1773 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1777 void ares_set_socket_callback(ares_channel channel,
1778 ares_sock_create_callback cb,
1781 channel->sock_create_cb = cb;
1782 channel->sock_create_cb_data = data;
1785 void ares__init_servers_state(ares_channel channel)
1787 struct server_state *server;
1790 for (i = 0; i < channel->nservers; i++)
1792 server = &channel->servers[i];
1793 server->udp_socket = ARES_SOCKET_BAD;
1794 server->tcp_socket = ARES_SOCKET_BAD;
1795 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1796 server->tcp_lenbuf_pos = 0;
1797 server->tcp_buffer_pos = 0;
1798 server->tcp_buffer = NULL;
1799 server->tcp_length = 0;
1800 server->qhead = NULL;
1801 server->qtail = NULL;
1802 ares__init_list_head(&server->queries_to_server);
1803 server->channel = channel;
1804 server->is_broken = 0;