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"
24 #ifdef HAVE_SYS_PARAM_H
25 #include <sys/param.h>
28 #ifdef HAVE_SYS_TIME_H
32 #ifdef HAVE_SYS_SOCKET_H
33 #include <sys/socket.h>
36 #ifdef HAVE_NETINET_IN_H
37 #include <netinet/in.h>
44 #ifdef HAVE_ARPA_INET_H
45 #include <arpa/inet.h>
48 #ifdef HAVE_ARPA_NAMESER_H
49 # include <arpa/nameser.h>
53 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
54 # include <arpa/nameser_compat.h>
67 #include "inet_net_pton.h"
68 #include "ares_library_init.h"
69 #include "ares_nowarn.h"
70 #include "ares_platform.h"
71 #include "ares_private.h"
72 #include "inet_ntop.h"
75 #include <sys/system_properties.h>
79 #undef WIN32 /* Redefined in MingW/MSVC headers */
82 static int init_by_options(ares_channel channel, const struct ares_options *options,
84 static int init_by_environment(ares_channel channel);
85 static int init_by_resolv_conf(ares_channel channel);
86 static int init_by_defaults(ares_channel channel);
89 static int config_nameserver(struct server_state **servers, int *nservers,
92 static int set_search(ares_channel channel, const char *str);
93 static int set_options(ares_channel channel, const char *str);
94 static const char *try_option(const char *p, const char *q, const char *opt);
95 static int init_id_key(rc4_key* key,int key_data_len);
97 #if !defined(WIN32) && !defined(WATT32)
98 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
99 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
100 static void natural_mask(struct apattern *pat);
101 static int config_domain(ares_channel channel, char *str);
102 static int config_lookup(ares_channel channel, const char *str,
103 const char *bindch, const char *filech);
104 static int config_sortlist(struct apattern **sortlist, int *nsort,
106 static char *try_config(char *s, const char *opt, char scc);
109 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
110 x->nservers > -1 && \
111 x->ndomains > -1 && \
112 x->ndots > -1 && x->timeout > -1 && \
115 int ares_init(ares_channel *channelptr)
117 return ares_init_options(channelptr, NULL, 0);
120 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
123 ares_channel channel;
125 int status = ARES_SUCCESS;
129 const char *env = getenv("CARES_MEMDEBUG");
133 env = getenv("CARES_MEMLIMIT");
136 long num = strtol(env, &endptr, 10);
137 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
142 if (ares_library_initialized() != ARES_SUCCESS)
143 return ARES_ENOTINITIALIZED;
145 channel = malloc(sizeof(struct ares_channeldata));
153 /* Set everything to distinguished values so we know they haven't
157 channel->timeout = -1;
160 channel->rotate = -1;
161 channel->udp_port = -1;
162 channel->tcp_port = -1;
163 channel->socket_send_buffer_size = -1;
164 channel->socket_receive_buffer_size = -1;
165 channel->nservers = -1;
166 channel->ndomains = -1;
168 channel->tcp_connection_generation = 0;
169 channel->lookups = NULL;
170 channel->domains = NULL;
171 channel->sortlist = NULL;
172 channel->servers = NULL;
173 channel->sock_state_cb = NULL;
174 channel->sock_state_cb_data = NULL;
175 channel->sock_create_cb = NULL;
176 channel->sock_create_cb_data = NULL;
178 channel->last_server = 0;
179 channel->last_timeout_processed = (time_t)now.tv_sec;
181 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
182 channel->local_ip4 = 0;
183 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
185 /* Initialize our lists of queries */
186 ares__init_list_head(&(channel->all_queries));
187 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
189 ares__init_list_head(&(channel->queries_by_qid[i]));
191 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
193 ares__init_list_head(&(channel->queries_by_timeout[i]));
196 /* Initialize configuration by each of the four sources, from highest
197 * precedence to lowest.
200 if (status == ARES_SUCCESS) {
201 status = init_by_options(channel, options, optmask);
202 if (status != ARES_SUCCESS)
203 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
204 ares_strerror(status)));
206 if (status == ARES_SUCCESS) {
207 status = init_by_environment(channel);
208 if (status != ARES_SUCCESS)
209 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
210 ares_strerror(status)));
212 if (status == ARES_SUCCESS) {
213 status = init_by_resolv_conf(channel);
214 if (status != ARES_SUCCESS)
215 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
216 ares_strerror(status)));
220 * No matter what failed or succeeded, seed defaults to provide
221 * useful behavior for things that we missed.
223 status = init_by_defaults(channel);
224 if (status != ARES_SUCCESS)
225 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
226 ares_strerror(status)));
228 /* Generate random key */
230 if (status == ARES_SUCCESS) {
231 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
232 if (status == ARES_SUCCESS)
233 channel->next_id = ares__generate_new_id(&channel->id_key);
235 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
236 ares_strerror(status)));
239 if (status != ARES_SUCCESS)
241 /* Something failed; clean up memory we may have allocated. */
242 if (channel->servers)
243 free(channel->servers);
244 if (channel->domains)
246 for (i = 0; i < channel->ndomains; i++)
247 free(channel->domains[i]);
248 free(channel->domains);
250 if (channel->sortlist)
251 free(channel->sortlist);
253 free(channel->lookups);
258 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
259 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
260 channel->nservers = 1;
262 ares__init_servers_state(channel);
264 *channelptr = channel;
268 /* ares_dup() duplicates a channel handle with all its options and returns a
269 new channel handle */
270 int ares_dup(ares_channel *dest, ares_channel src)
272 struct ares_options opts;
273 struct ares_addr_node *servers;
274 int ipv6_nservers = 0;
278 *dest = NULL; /* in case of failure return NULL explicitly */
280 /* First get the options supported by the old ares_save_options() function,
281 which is most of them */
282 rc = ares_save_options(src, &opts, &optmask);
286 /* Then create the new channel with those options */
287 rc = ares_init_options(dest, &opts, optmask);
289 /* destroy the options copy to not leak any memory */
290 ares_destroy_options(&opts);
295 /* Now clone the options that ares_save_options() doesn't support. */
296 (*dest)->sock_create_cb = src->sock_create_cb;
297 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
299 strncpy((*dest)->local_dev_name, src->local_dev_name, 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 server_state));
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 = options->udp_port;
438 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
439 channel->tcp_port = 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," at end */
618 size_t 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 GetAdaptersAddresses
634 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, &bufSize );
642 if( result == ERROR_BUFFER_OVERFLOW )
644 /* Reallocate, bufSize should now be set to the required size */
645 pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
649 /* Call the method a second time */
650 result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
651 if( result == ERROR_BUFFER_OVERFLOW )
653 /* Reallocate, bufSize should now be set to the required size */
654 pFirstEntry = ( IP_ADAPTER_ADDRESSES * ) realloc( pFirstEntry, bufSize );
658 /* Call the method a third time. The maximum number of times we're going to do
659 this is 3. Three shall be the number thou shalt count, and the number of the
660 counting shall be three. Five is right out. */
661 result = ( *ares_fpGetAdaptersAddresses )( AF_UNSPEC, 0, 0, pFirstEntry, &bufSize );
665 /* Check the current result for failure */
666 if( result != ERROR_SUCCESS )
672 /* process the results */
673 for( pEntry = pFirstEntry ; pEntry != NULL ; pEntry = pEntry->Next )
675 IP_ADAPTER_DNS_SERVER_ADDRESS* pDNSAddr = pEntry->FirstDnsServerAddress;
676 for( ; pDNSAddr != NULL ; pDNSAddr = pDNSAddr->Next )
678 struct sockaddr *pGenericAddr = pDNSAddr->Address.lpSockaddr;
681 if( pGenericAddr->sa_family == AF_INET && left > ipv4_size )
683 /* Handle the v4 case */
684 struct sockaddr_in *pIPv4Addr = ( struct sockaddr_in * ) pGenericAddr;
685 ares_inet_ntop( AF_INET, &pIPv4Addr->sin_addr, ret, ipv4_size - 1 ); /* -1 for comma */
687 /* Append a comma to the end, THEN NULL. Should be OK because we
688 already tested the size at the top of the if statement. */
689 stringlen = strlen( ret );
690 ret[ stringlen ] = ',';
691 ret[ stringlen + 1 ] = '\0';
692 ret += stringlen + 1;
693 left -= ret - ret_buf;
696 else if( pGenericAddr->sa_family == AF_INET6 && left > ipv6_size )
698 /* Handle the v6 case */
699 struct sockaddr_in6 *pIPv6Addr = ( struct sockaddr_in6 * ) pGenericAddr;
700 ares_inet_ntop( AF_INET6, &pIPv6Addr->sin6_addr, ret, ipv6_size - 1 ); /* -1 for comma */
702 /* Append a comma to the end, THEN NULL. Should be OK because we
703 already tested the size at the top of the if statement. */
704 stringlen = strlen( ret );
705 ret[ stringlen ] = ',';
706 ret[ stringlen + 1 ] = '\0';
707 ret += stringlen + 1;
708 left -= ret - ret_buf;
711 /* NB on Windows this also returns stuff in the fec0::/10 range,
712 seems to be hard-coded somehow. Do we need to ignore them? */
725 FIXED_INFO *fi, *newfi;
726 DWORD size = sizeof (*fi);
727 IP_ADDR_STRING *ipAddr;
736 res = (*ares_fpGetNetworkParams) (fi, &size);
737 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
740 newfi = realloc(fi, size);
745 res = (*ares_fpGetNetworkParams) (fi, &size);
746 if (res != ERROR_SUCCESS)
751 printf ("Host Name: %s\n", fi->HostName);
752 printf ("Domain Name: %s\n", fi->DomainName);
753 printf ("DNS Servers:\n"
754 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
756 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
757 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
760 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
761 left -= ret - ret_buf;
765 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ipv4_size;
766 ipAddr = ipAddr->Next, i++)
768 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
770 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
771 left -= ret - ret_buf;
775 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
782 if (debug && left <= ipv4_size)
783 printf ("Too many nameservers. Truncating to %d addressess", count);
791 static int init_by_resolv_conf(ares_channel channel)
796 int status = -1, nservers = 0, nsort = 0;
797 struct server_state *servers = NULL;
798 struct apattern *sortlist = NULL;
803 NameServer info via IPHLPAPI (IP helper API):
804 GetNetworkParams() should be the trusted source for this.
805 Available in Win-98/2000 and later. If that fail, fall-back to
806 registry information.
810 On Windows 9X, the DNS server can be found in:
811 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
813 On Windows NT/2000/XP/2003:
814 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
816 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
818 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
821 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
831 win_platform platform;
833 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
836 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
838 status = config_nameserver(&servers, &nservers, buf);
839 if (status == ARES_SUCCESS)
843 platform = ares__getplatform();
845 if (platform == WIN_NT)
848 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
852 RegOpenKeyEx(mykey, "Interfaces", 0,
853 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
854 if (get_res_nt(mykey, NAMESERVER, &line))
856 status = config_nameserver(&servers, &nservers, line);
859 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
861 status = config_nameserver(&servers, &nservers, line);
864 /* Try the interfaces */
865 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
867 status = config_nameserver(&servers, &nservers, line);
870 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
872 status = config_nameserver(&servers, &nservers, line);
879 else if (platform == WIN_9X)
882 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
886 if ((result = RegQueryValueEx(
887 mykey, NAMESERVER, NULL, &data_type,
890 ) == ERROR_SUCCESS ||
891 result == ERROR_MORE_DATA)
895 line = malloc(bytes+1);
896 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
897 (unsigned char *)line, &bytes) ==
900 status = config_nameserver(&servers, &nservers, line);
909 if (status == ARES_SUCCESS)
912 /* Catch the case when all the above checks fail (which happens when there
913 is no network card or the cable is unplugged) */
916 #elif defined(__riscos__)
918 /* Under RISC OS, name servers are listed in the
919 system variable Inet$Resolvers, space separated. */
921 line = getenv("Inet$Resolvers");
924 char *resolvers = strdup(line), *pos, *space;
931 space = strchr(pos, ' ');
934 status = config_nameserver(&servers, &nservers, pos);
935 if (status != ARES_SUCCESS)
940 if (status == ARES_SUCCESS)
946 #elif defined(WATT32)
950 for (i = 0; def_nameservers[i]; i++)
953 return ARES_SUCCESS; /* use localhost DNS server */
956 servers = calloc(i, sizeof(struct server_state));
960 for (i = 0; def_nameservers[i]; i++)
962 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
963 servers[i].addr.family = AF_INET;
967 #elif defined(ANDROID)
968 char value[PROP_VALUE_MAX]="";
969 __system_property_get("net.dns1", value);
970 status = config_nameserver(&servers, &nservers, value);
971 if (status == ARES_SUCCESS)
980 /* Don't read resolv.conf and friends if we don't have to */
981 if (ARES_CONFIG_CHECK(channel))
984 fp = fopen(PATH_RESOLV_CONF, "r");
986 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
988 if ((p = try_config(line, "domain", ';')))
989 status = config_domain(channel, p);
990 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
991 status = config_lookup(channel, p, "bind", "file");
992 else if ((p = try_config(line, "search", ';')))
993 status = set_search(channel, p);
994 else if ((p = try_config(line, "nameserver", ';')) &&
995 channel->nservers == -1)
996 status = config_nameserver(&servers, &nservers, p);
997 else if ((p = try_config(line, "sortlist", ';')) &&
998 channel->nsort == -1)
999 status = config_sortlist(&sortlist, &nsort, p);
1000 else if ((p = try_config(line, "options", ';')))
1001 status = set_options(channel, p);
1003 status = ARES_SUCCESS;
1004 if (status != ARES_SUCCESS)
1017 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1018 error, strerror(error)));
1019 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1020 status = ARES_EFILE;
1024 if ((status == ARES_EOF) && (!channel->lookups)) {
1025 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1026 fp = fopen("/etc/nsswitch.conf", "r");
1028 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1030 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1032 (void)config_lookup(channel, p, "dns", "files");
1044 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1045 error, strerror(error)));
1046 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
1047 status = ARES_EFILE;
1052 if ((status == ARES_EOF) && (!channel->lookups)) {
1053 /* Linux / GNU libc 2.x and possibly others have host.conf */
1054 fp = fopen("/etc/host.conf", "r");
1056 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1058 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1060 (void)config_lookup(channel, p, "bind", "hosts");
1072 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1073 error, strerror(error)));
1074 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
1075 status = ARES_EFILE;
1080 if ((status == ARES_EOF) && (!channel->lookups)) {
1081 /* Tru64 uses /etc/svc.conf */
1082 fp = fopen("/etc/svc.conf", "r");
1084 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1086 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1088 (void)config_lookup(channel, p, "bind", "local");
1100 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1101 error, strerror(error)));
1102 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1103 status = ARES_EFILE;
1114 /* Handle errors. */
1115 if (status != ARES_EOF)
1117 if (servers != NULL)
1119 if (sortlist != NULL)
1124 /* If we got any name server entries, fill them in. */
1130 channel->servers = servers;
1131 channel->nservers = nservers;
1134 /* If we got any sortlist entries, fill them in. */
1137 channel->sortlist = sortlist;
1138 channel->nsort = nsort;
1141 return ARES_SUCCESS;
1144 static int init_by_defaults(ares_channel channel)
1146 char *hostname = NULL;
1147 int rc = ARES_SUCCESS;
1148 #ifdef HAVE_GETHOSTNAME
1152 if (channel->flags == -1)
1154 if (channel->timeout == -1)
1155 channel->timeout = DEFAULT_TIMEOUT;
1156 if (channel->tries == -1)
1157 channel->tries = DEFAULT_TRIES;
1158 if (channel->ndots == -1)
1160 if (channel->rotate == -1)
1161 channel->rotate = 0;
1162 if (channel->udp_port == -1)
1163 channel->udp_port = htons(NAMESERVER_PORT);
1164 if (channel->tcp_port == -1)
1165 channel->tcp_port = htons(NAMESERVER_PORT);
1167 if (channel->nservers == -1) {
1168 /* If nobody specified servers, try a local named. */
1169 channel->servers = malloc(sizeof(struct server_state));
1170 if (!channel->servers) {
1174 channel->servers[0].addr.family = AF_INET;
1175 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1176 channel->nservers = 1;
1179 #if defined(USE_WINSOCK)
1180 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1181 #elif defined(ENAMETOOLONG)
1182 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1183 (SOCKERRNO == EINVAL))
1185 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1188 if (channel->ndomains == -1) {
1189 /* Derive a default domain search list from the kernel hostname,
1190 * or set it to empty if the hostname isn't helpful.
1194 channel->ndomains = 0; /* default to none */
1196 #ifdef HAVE_GETHOSTNAME
1197 hostname = malloc(len);
1204 res = gethostname(hostname, len);
1209 p = realloc(hostname, len);
1224 dot = strchr(hostname, '.');
1226 /* a dot was found */
1227 channel->domains = malloc(sizeof(char *));
1228 if (!channel->domains) {
1232 channel->domains[0] = strdup(dot + 1);
1233 if (!channel->domains[0]) {
1237 channel->ndomains = 1;
1242 if (channel->nsort == -1) {
1243 channel->sortlist = NULL;
1247 if (!channel->lookups) {
1248 channel->lookups = strdup("fb");
1249 if (!channel->lookups)
1255 if(channel->servers)
1256 free(channel->servers);
1258 if(channel->domains && channel->domains[0])
1259 free(channel->domains[0]);
1260 if(channel->domains)
1261 free(channel->domains);
1262 if(channel->lookups)
1263 free(channel->lookups);
1272 #if !defined(WIN32) && !defined(WATT32)
1273 static int config_domain(ares_channel channel, char *str)
1277 /* Set a single search domain. */
1279 while (*q && !ISSPACE(*q))
1282 return set_search(channel, str);
1285 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1286 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1287 /* workaround icc 9.1 optimizer issue */
1288 # define vqualifier volatile
1293 static int config_lookup(ares_channel channel, const char *str,
1294 const char *bindch, const char *filech)
1296 char lookups[3], *l;
1297 const char *vqualifier p;
1299 /* Set the lookup order. Only the first letter of each work
1300 * is relevant, and it has to be "b" for DNS or "f" for the
1301 * host file. Ignore everything else.
1307 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1308 if (*p == *bindch) *l++ = 'b';
1311 while (*p && !ISSPACE(*p) && (*p != ','))
1313 while (*p && (ISSPACE(*p) || (*p == ',')))
1317 channel->lookups = strdup(lookups);
1318 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1320 #endif /* !WIN32 & !WATT32 */
1323 static int config_nameserver(struct server_state **servers, int *nservers,
1326 struct ares_addr host;
1327 struct server_state *newserv;
1329 /* On Windows, there may be more than one nameserver specified in the same
1330 * registry key, so we parse input as a space or comma seperated list.
1334 /* Skip whitespace and commas. */
1335 while (*p && (ISSPACE(*p) || (*p == ',')))
1338 /* No more input, done. */
1341 /* Pointer to start of IPv4 or IPv6 address part. */
1344 /* Advance past this address. */
1345 while (*p && !ISSPACE(*p) && (*p != ','))
1348 /* Null terminate this address. */
1351 /* Reached end of input, done when this address is processed. */
1354 /* Convert textual address to binary format. */
1355 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1356 host.family = AF_INET;
1357 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1358 host.family = AF_INET6;
1362 /* Resize servers state array. */
1363 newserv = realloc(*servers, (*nservers + 1) *
1364 sizeof(struct server_state));
1368 /* Store address data. */
1369 newserv[*nservers].addr.family = host.family;
1370 if (host.family == AF_INET)
1371 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1372 sizeof(host.addrV4));
1374 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1375 sizeof(host.addrV6));
1377 /* Update arguments. */
1382 return ARES_SUCCESS;
1386 static int config_sortlist(struct apattern **sortlist, int *nsort,
1389 struct apattern pat;
1392 /* Add sortlist entries. */
1393 while (*str && *str != ';')
1396 char ipbuf[16], ipbufpfx[32];
1397 /* Find just the IP */
1399 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1401 memcpy(ipbuf, str, q-str);
1402 ipbuf[q-str] = '\0';
1403 /* Find the prefix */
1406 const char *str2 = q+1;
1407 while (*q && *q != ';' && !ISSPACE(*q))
1409 memcpy(ipbufpfx, str, q-str);
1410 ipbufpfx[q-str] = '\0';
1415 /* Lets see if it is CIDR */
1416 /* First we'll try IPv6 */
1417 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1419 sizeof(pat.addrV6))) > 0)
1421 pat.type = PATTERN_CIDR;
1422 pat.mask.bits = (unsigned short)bits;
1423 pat.family = AF_INET6;
1424 if (!sortlist_alloc(sortlist, nsort, &pat))
1427 else if (ipbufpfx[0] &&
1428 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1429 sizeof(pat.addrV4))) > 0)
1431 pat.type = PATTERN_CIDR;
1432 pat.mask.bits = (unsigned short)bits;
1433 pat.family = AF_INET;
1434 if (!sortlist_alloc(sortlist, nsort, &pat))
1437 /* See if it is just a regular IP */
1438 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1442 memcpy(ipbuf, str, q-str);
1443 ipbuf[q-str] = '\0';
1444 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1449 pat.family = AF_INET;
1450 pat.type = PATTERN_MASK;
1451 if (!sortlist_alloc(sortlist, nsort, &pat))
1456 while (*q && *q != ';' && !ISSPACE(*q))
1460 while (ISSPACE(*str))
1464 return ARES_SUCCESS;
1467 #endif /* !WATT32 */
1469 static int set_search(ares_channel channel, const char *str)
1474 if(channel->ndomains != -1) {
1475 /* if we already have some domains present, free them first */
1476 for(n=0; n < channel->ndomains; n++)
1477 free(channel->domains[n]);
1478 free(channel->domains);
1479 channel->domains = NULL;
1480 channel->ndomains = -1;
1483 /* Count the domains given. */
1488 while (*p && !ISSPACE(*p))
1497 channel->ndomains = 0;
1498 return ARES_SUCCESS;
1501 channel->domains = malloc(n * sizeof(char *));
1502 if (!channel->domains)
1505 /* Now copy the domains. */
1510 channel->ndomains = n;
1512 while (*q && !ISSPACE(*q))
1514 channel->domains[n] = malloc(q - p + 1);
1515 if (!channel->domains[n])
1517 memcpy(channel->domains[n], p, q - p);
1518 channel->domains[n][q - p] = 0;
1524 channel->ndomains = n;
1526 return ARES_SUCCESS;
1529 static int set_options(ares_channel channel, const char *str)
1531 const char *p, *q, *val;
1537 while (*q && !ISSPACE(*q))
1539 val = try_option(p, q, "ndots:");
1540 if (val && channel->ndots == -1)
1541 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1542 val = try_option(p, q, "retrans:");
1543 if (val && channel->timeout == -1)
1544 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1545 val = try_option(p, q, "retry:");
1546 if (val && channel->tries == -1)
1547 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1548 val = try_option(p, q, "rotate");
1549 if (val && channel->rotate == -1)
1550 channel->rotate = 1;
1556 return ARES_SUCCESS;
1559 static const char *try_option(const char *p, const char *q, const char *opt)
1561 size_t len = strlen(opt);
1562 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1565 #if !defined(WIN32) && !defined(WATT32)
1566 static char *try_config(char *s, const char *opt, char scc)
1573 /* no line or no option */
1576 /* Hash '#' character is always used as primary comment char, additionally
1577 a not-NUL secondary comment char will be considered when specified. */
1579 /* trim line comment */
1582 while (*p && (*p != '#') && (*p != scc))
1585 while (*p && (*p != '#'))
1589 /* trim trailing whitespace */
1591 while ((q >= s) && ISSPACE(*q))
1595 /* skip leading whitespace */
1597 while (*p && ISSPACE(*p))
1604 if ((len = strlen(opt)) == 0)
1608 if (strncmp(p, opt, len) != 0)
1609 /* line and option do not match */
1612 /* skip over given option name */
1616 /* no option value */
1619 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1620 /* whitespace between option name and value is mandatory
1621 for given option names which do not end with ':' or '=' */
1624 /* skip over whitespace */
1625 while (*p && ISSPACE(*p))
1629 /* no option value */
1632 /* return pointer to option value */
1636 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1637 struct apattern *pat)
1639 struct apattern *newsort;
1640 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1643 newsort[*nsort] = *pat;
1644 *sortlist = newsort;
1649 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1652 /* Four octets and three periods yields at most 15 characters. */
1656 addr->s_addr = inet_addr(ipbuf);
1657 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1662 static void natural_mask(struct apattern *pat)
1664 struct in_addr addr;
1666 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1669 addr.s_addr = ntohl(pat->addrV4.s_addr);
1671 /* This is out of date in the CIDR world, but some people might
1674 if (IN_CLASSA(addr.s_addr))
1675 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1676 else if (IN_CLASSB(addr.s_addr))
1677 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1679 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1681 #endif /* !WIN32 && !WATT32 */
1683 /* initialize an rc4 key. If possible a cryptographically secure random key
1684 is generated using a suitable function (for example win32's RtlGenRandom as
1686 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1687 otherwise the code defaults to cross-platform albeit less secure mechanism
1690 static void randomize_key(unsigned char* key,int key_data_len)
1696 if (ares_fpSystemFunction036)
1698 res = (*ares_fpSystemFunction036) (key, key_data_len);
1704 FILE *f = fopen(RANDOM_FILE, "rb");
1706 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1712 if ( !randomized ) {
1713 for (;counter<key_data_len;counter++)
1714 key[counter]=(unsigned char)(rand() % 256);
1718 static int init_id_key(rc4_key* key,int key_data_len)
1720 unsigned char index1;
1721 unsigned char index2;
1722 unsigned char* state;
1724 unsigned char *key_data_ptr = 0;
1726 key_data_ptr = calloc(1,key_data_len);
1730 state = &key->state[0];
1731 for(counter = 0; counter < 256; counter++)
1732 /* unnecessary AND but it keeps some compilers happier */
1733 state[counter] = (unsigned char)(counter & 0xff);
1734 randomize_key(key->state,key_data_len);
1739 for(counter = 0; counter < 256; counter++)
1741 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1743 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1745 index1 = (unsigned char)((index1 + 1) % key_data_len);
1748 return ARES_SUCCESS;
1751 unsigned short ares__generate_new_id(rc4_key* key)
1754 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1758 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1760 channel->local_ip4 = local_ip;
1763 /* local_ip6 should be 16 bytes in length */
1764 void ares_set_local_ip6(ares_channel channel,
1765 const unsigned char* local_ip6)
1767 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1770 /* local_dev_name should be null terminated. */
1771 void ares_set_local_dev(ares_channel channel,
1772 const char* local_dev_name)
1774 strncpy(channel->local_dev_name, local_dev_name,
1775 sizeof(channel->local_dev_name));
1776 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1780 void ares_set_socket_callback(ares_channel channel,
1781 ares_sock_create_callback cb,
1784 channel->sock_create_cb = cb;
1785 channel->sock_create_cb_data = data;
1788 void ares__init_servers_state(ares_channel channel)
1790 struct server_state *server;
1793 for (i = 0; i < channel->nservers; i++)
1795 server = &channel->servers[i];
1796 server->udp_socket = ARES_SOCKET_BAD;
1797 server->tcp_socket = ARES_SOCKET_BAD;
1798 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1799 server->tcp_lenbuf_pos = 0;
1800 server->tcp_buffer_pos = 0;
1801 server->tcp_buffer = NULL;
1802 server->tcp_length = 0;
1803 server->qhead = NULL;
1804 server->qtail = NULL;
1805 ares__init_list_head(&server->queries_to_server);
1806 server->channel = channel;
1807 server->is_broken = 0;