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"
74 #include <sys/system_properties.h>
78 #undef WIN32 /* Redefined in MingW/MSVC headers */
81 static int init_by_options(ares_channel channel, const struct ares_options *options,
83 static int init_by_environment(ares_channel channel);
84 static int init_by_resolv_conf(ares_channel channel);
85 static int init_by_defaults(ares_channel channel);
88 static int config_nameserver(struct server_state **servers, int *nservers,
91 static int set_search(ares_channel channel, const char *str);
92 static int set_options(ares_channel channel, const char *str);
93 static const char *try_option(const char *p, const char *q, const char *opt);
94 static int init_id_key(rc4_key* key,int key_data_len);
96 #if !defined(WIN32) && !defined(WATT32)
97 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
98 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
99 static void natural_mask(struct apattern *pat);
100 static int config_domain(ares_channel channel, char *str);
101 static int config_lookup(ares_channel channel, const char *str,
102 const char *bindch, const char *filech);
103 static int config_sortlist(struct apattern **sortlist, int *nsort,
105 static char *try_config(char *s, const char *opt, char scc);
108 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
109 x->nservers > -1 && \
110 x->ndomains > -1 && \
111 x->ndots > -1 && x->timeout > -1 && \
114 int ares_init(ares_channel *channelptr)
116 return ares_init_options(channelptr, NULL, 0);
119 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
122 ares_channel channel;
124 int status = ARES_SUCCESS;
128 const char *env = getenv("CARES_MEMDEBUG");
132 env = getenv("CARES_MEMLIMIT");
135 long num = strtol(env, &endptr, 10);
136 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
141 if (ares_library_initialized() != ARES_SUCCESS)
142 return ARES_ENOTINITIALIZED;
144 channel = malloc(sizeof(struct ares_channeldata));
152 /* Set everything to distinguished values so we know they haven't
156 channel->timeout = -1;
159 channel->rotate = -1;
160 channel->udp_port = -1;
161 channel->tcp_port = -1;
162 channel->socket_send_buffer_size = -1;
163 channel->socket_receive_buffer_size = -1;
164 channel->nservers = -1;
165 channel->ndomains = -1;
167 channel->tcp_connection_generation = 0;
168 channel->lookups = NULL;
169 channel->domains = NULL;
170 channel->sortlist = NULL;
171 channel->servers = NULL;
172 channel->sock_state_cb = NULL;
173 channel->sock_state_cb_data = NULL;
174 channel->sock_create_cb = NULL;
175 channel->sock_create_cb_data = NULL;
177 channel->last_server = 0;
178 channel->last_timeout_processed = (time_t)now.tv_sec;
180 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
181 channel->local_ip4 = 0;
182 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
184 /* Initialize our lists of queries */
185 ares__init_list_head(&(channel->all_queries));
186 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
188 ares__init_list_head(&(channel->queries_by_qid[i]));
190 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
192 ares__init_list_head(&(channel->queries_by_timeout[i]));
195 /* Initialize configuration by each of the four sources, from highest
196 * precedence to lowest.
199 if (status == ARES_SUCCESS) {
200 status = init_by_options(channel, options, optmask);
201 if (status != ARES_SUCCESS)
202 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
203 ares_strerror(status)));
205 if (status == ARES_SUCCESS) {
206 status = init_by_environment(channel);
207 if (status != ARES_SUCCESS)
208 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
209 ares_strerror(status)));
211 if (status == ARES_SUCCESS) {
212 status = init_by_resolv_conf(channel);
213 if (status != ARES_SUCCESS)
214 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
215 ares_strerror(status)));
219 * No matter what failed or succeeded, seed defaults to provide
220 * useful behavior for things that we missed.
222 status = init_by_defaults(channel);
223 if (status != ARES_SUCCESS)
224 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
225 ares_strerror(status)));
227 /* Generate random key */
229 if (status == ARES_SUCCESS) {
230 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
231 if (status == ARES_SUCCESS)
232 channel->next_id = ares__generate_new_id(&channel->id_key);
234 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
235 ares_strerror(status)));
238 if (status != ARES_SUCCESS)
240 /* Something failed; clean up memory we may have allocated. */
241 if (channel->servers)
242 free(channel->servers);
243 if (channel->domains)
245 for (i = 0; i < channel->ndomains; i++)
246 free(channel->domains[i]);
247 free(channel->domains);
249 if (channel->sortlist)
250 free(channel->sortlist);
252 free(channel->lookups);
257 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
258 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
259 channel->nservers = 1;
261 ares__init_servers_state(channel);
263 *channelptr = channel;
267 /* ares_dup() duplicates a channel handle with all its options and returns a
268 new channel handle */
269 int ares_dup(ares_channel *dest, ares_channel src)
271 struct ares_options opts;
272 struct ares_addr_node *servers;
273 int ipv6_nservers = 0;
277 *dest = NULL; /* in case of failure return NULL explicitly */
279 /* First get the options supported by the old ares_save_options() function,
280 which is most of them */
281 rc = ares_save_options(src, &opts, &optmask);
285 /* Then create the new channel with those options */
286 rc = ares_init_options(dest, &opts, optmask);
288 /* destroy the options copy to not leak any memory */
289 ares_destroy_options(&opts);
294 /* Now clone the options that ares_save_options() doesn't support. */
295 (*dest)->sock_create_cb = src->sock_create_cb;
296 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
298 strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name));
299 (*dest)->local_ip4 = src->local_ip4;
300 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
302 /* Full name server cloning required when not all are IPv4 */
303 for (i = 0; i < src->nservers; i++)
305 if (src->servers[i].addr.family != AF_INET) {
311 rc = ares_get_servers(src, &servers);
312 if (rc != ARES_SUCCESS)
314 rc = ares_set_servers(*dest, servers);
315 ares_free_data(servers);
316 if (rc != ARES_SUCCESS)
320 return ARES_SUCCESS; /* everything went fine */
323 /* Save options from initialized channel */
324 int ares_save_options(ares_channel channel, struct ares_options *options,
328 int ipv4_nservers = 0;
330 /* Zero everything out */
331 memset(options, 0, sizeof(struct ares_options));
333 if (!ARES_CONFIG_CHECK(channel))
336 /* Traditionally the optmask wasn't saved in the channel struct so it was
337 recreated here. ROTATE is the first option that has no struct field of
338 its own in the public config struct */
339 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
340 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
341 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
342 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
343 (channel->optmask & ARES_OPT_ROTATE);
345 /* Copy easy stuff */
346 options->flags = channel->flags;
348 /* We return full millisecond resolution but that's only because we don't
349 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
350 options->timeout = channel->timeout;
351 options->tries = channel->tries;
352 options->ndots = channel->ndots;
353 options->udp_port = (unsigned short)channel->udp_port;
354 options->tcp_port = (unsigned short)channel->tcp_port;
355 options->sock_state_cb = channel->sock_state_cb;
356 options->sock_state_cb_data = channel->sock_state_cb_data;
358 /* Copy IPv4 servers */
359 if (channel->nservers) {
360 for (i = 0; i < channel->nservers; i++)
362 if (channel->servers[i].addr.family == AF_INET)
366 options->servers = malloc(ipv4_nservers * sizeof(struct server_state));
367 if (!options->servers)
369 for (i = j = 0; i < channel->nservers; i++)
371 if (channel->servers[i].addr.family == AF_INET)
372 memcpy(&options->servers[j++],
373 &channel->servers[i].addr.addrV4,
374 sizeof(channel->servers[i].addr.addrV4));
378 options->nservers = ipv4_nservers;
381 if (channel->ndomains) {
382 options->domains = malloc(channel->ndomains * sizeof(char *));
383 if (!options->domains)
386 for (i = 0; i < channel->ndomains; i++)
388 options->ndomains = i;
389 options->domains[i] = strdup(channel->domains[i]);
390 if (!options->domains[i])
394 options->ndomains = channel->ndomains;
397 if (channel->lookups) {
398 options->lookups = strdup(channel->lookups);
399 if (!options->lookups && channel->lookups)
404 if (channel->nsort) {
405 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
406 if (!options->sortlist)
408 for (i = 0; i < channel->nsort; i++)
409 options->sortlist[i] = channel->sortlist[i];
411 options->nsort = channel->nsort;
416 static int init_by_options(ares_channel channel,
417 const struct ares_options *options,
423 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
424 channel->flags = options->flags;
425 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
426 channel->timeout = options->timeout;
427 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
428 channel->timeout = options->timeout * 1000;
429 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
430 channel->tries = options->tries;
431 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
432 channel->ndots = options->ndots;
433 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
435 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
436 channel->udp_port = options->udp_port;
437 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
438 channel->tcp_port = options->tcp_port;
439 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
441 channel->sock_state_cb = options->sock_state_cb;
442 channel->sock_state_cb_data = options->sock_state_cb_data;
444 if ((optmask & ARES_OPT_SOCK_SNDBUF)
445 && channel->socket_send_buffer_size == -1)
446 channel->socket_send_buffer_size = options->socket_send_buffer_size;
447 if ((optmask & ARES_OPT_SOCK_RCVBUF)
448 && channel->socket_receive_buffer_size == -1)
449 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
451 /* Copy the IPv4 servers, if given. */
452 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
454 /* Avoid zero size allocations at any cost */
455 if (options->nservers > 0)
458 malloc(options->nservers * sizeof(struct server_state));
459 if (!channel->servers)
461 for (i = 0; i < options->nservers; i++)
463 channel->servers[i].addr.family = AF_INET;
464 memcpy(&channel->servers[i].addr.addrV4,
465 &options->servers[i],
466 sizeof(channel->servers[i].addr.addrV4));
469 channel->nservers = options->nservers;
472 /* Copy the domains, if given. Keep channel->ndomains consistent so
473 * we can clean up in case of error.
475 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
477 /* Avoid zero size allocations at any cost */
478 if (options->ndomains > 0)
480 channel->domains = malloc(options->ndomains * sizeof(char *));
481 if (!channel->domains)
483 for (i = 0; i < options->ndomains; i++)
485 channel->ndomains = i;
486 channel->domains[i] = strdup(options->domains[i]);
487 if (!channel->domains[i])
491 channel->ndomains = options->ndomains;
494 /* Set lookups, if given. */
495 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
497 channel->lookups = strdup(options->lookups);
498 if (!channel->lookups)
503 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
504 (options->nsort>0)) {
505 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
506 if (!channel->sortlist)
508 for (i = 0; i < options->nsort; i++)
509 channel->sortlist[i] = options->sortlist[i];
510 channel->nsort = options->nsort;
513 channel->optmask = optmask;
518 static int init_by_environment(ares_channel channel)
520 const char *localdomain, *res_options;
523 localdomain = getenv("LOCALDOMAIN");
524 if (localdomain && channel->ndomains == -1)
526 status = set_search(channel, localdomain);
527 if (status != ARES_SUCCESS)
531 res_options = getenv("RES_OPTIONS");
534 status = set_options(channel, res_options);
535 if (status != ARES_SUCCESS)
544 * Warning: returns a dynamically allocated buffer, the user MUST
545 * use free() if the function returns 1
547 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
549 /* Test for the size we need */
553 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
554 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
556 *obuf = malloc(size+1);
560 if (RegQueryValueEx(hKey, subkey, 0, NULL,
561 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
574 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
576 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
577 DWORD enum_size = 39;
581 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
582 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
587 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
590 rc = get_res_nt(hVal, subkey, obuf);
598 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
600 FIXED_INFO *fi, *newfi;
601 DWORD size = sizeof (*fi);
602 IP_ADDR_STRING *ipAddr;
605 size_t ip_size = sizeof("255.255.255.255,")-1;
606 size_t left = ret_size;
614 res = (*ares_fpGetNetworkParams) (fi, &size);
615 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
618 newfi = realloc(fi, size);
623 res = (*ares_fpGetNetworkParams) (fi, &size);
624 if (res != ERROR_SUCCESS)
629 printf ("Host Name: %s\n", fi->HostName);
630 printf ("Domain Name: %s\n", fi->DomainName);
631 printf ("DNS Servers:\n"
632 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
634 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
635 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
638 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
639 left -= ret - ret_buf;
643 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
644 ipAddr = ipAddr->Next, i++)
646 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
648 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
649 left -= ret - ret_buf;
653 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
660 if (debug && left <= ip_size)
661 printf ("Too many nameservers. Truncating to %d addressess", count);
668 static int init_by_resolv_conf(ares_channel channel)
673 int status = -1, nservers = 0, nsort = 0;
674 struct server_state *servers = NULL;
675 struct apattern *sortlist = NULL;
680 NameServer info via IPHLPAPI (IP helper API):
681 GetNetworkParams() should be the trusted source for this.
682 Available in Win-98/2000 and later. If that fail, fall-back to
683 registry information.
687 On Windows 9X, the DNS server can be found in:
688 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
690 On Windows NT/2000/XP/2003:
691 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
693 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
695 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
698 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
708 win_platform platform;
710 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
713 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
715 status = config_nameserver(&servers, &nservers, buf);
716 if (status == ARES_SUCCESS)
720 platform = ares__getplatform();
722 if (platform == WIN_NT)
725 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
729 RegOpenKeyEx(mykey, "Interfaces", 0,
730 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
731 if (get_res_nt(mykey, NAMESERVER, &line))
733 status = config_nameserver(&servers, &nservers, line);
736 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
738 status = config_nameserver(&servers, &nservers, line);
741 /* Try the interfaces */
742 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
744 status = config_nameserver(&servers, &nservers, line);
747 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
749 status = config_nameserver(&servers, &nservers, line);
756 else if (platform == WIN_9X)
759 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
763 if ((result = RegQueryValueEx(
764 mykey, NAMESERVER, NULL, &data_type,
767 ) == ERROR_SUCCESS ||
768 result == ERROR_MORE_DATA)
772 line = malloc(bytes+1);
773 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
774 (unsigned char *)line, &bytes) ==
777 status = config_nameserver(&servers, &nservers, line);
786 if (status == ARES_SUCCESS)
789 /* Catch the case when all the above checks fail (which happens when there
790 is no network card or the cable is unplugged) */
793 #elif defined(__riscos__)
795 /* Under RISC OS, name servers are listed in the
796 system variable Inet$Resolvers, space separated. */
798 line = getenv("Inet$Resolvers");
801 char *resolvers = strdup(line), *pos, *space;
808 space = strchr(pos, ' ');
811 status = config_nameserver(&servers, &nservers, pos);
812 if (status != ARES_SUCCESS)
817 if (status == ARES_SUCCESS)
823 #elif defined(WATT32)
827 for (i = 0; def_nameservers[i]; i++)
830 return ARES_SUCCESS; /* use localhost DNS server */
833 servers = calloc(i, sizeof(struct server_state));
837 for (i = 0; def_nameservers[i]; i++)
839 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
840 servers[i].addr.family = AF_INET;
844 #elif defined(ANDROID)
845 char value[PROP_VALUE_MAX]="";
846 __system_property_get("net.dns1", value);
847 status = config_nameserver(&servers, &nservers, value);
848 if (status == ARES_SUCCESS)
857 /* Don't read resolv.conf and friends if we don't have to */
858 if (ARES_CONFIG_CHECK(channel))
861 fp = fopen(PATH_RESOLV_CONF, "r");
863 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
865 if ((p = try_config(line, "domain", ';')))
866 status = config_domain(channel, p);
867 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
868 status = config_lookup(channel, p, "bind", "file");
869 else if ((p = try_config(line, "search", ';')))
870 status = set_search(channel, p);
871 else if ((p = try_config(line, "nameserver", ';')) &&
872 channel->nservers == -1)
873 status = config_nameserver(&servers, &nservers, p);
874 else if ((p = try_config(line, "sortlist", ';')) &&
875 channel->nsort == -1)
876 status = config_sortlist(&sortlist, &nsort, p);
877 else if ((p = try_config(line, "options", ';')))
878 status = set_options(channel, p);
880 status = ARES_SUCCESS;
881 if (status != ARES_SUCCESS)
894 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
895 error, strerror(error)));
896 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
901 if ((status == ARES_EOF) && (!channel->lookups)) {
902 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
903 fp = fopen("/etc/nsswitch.conf", "r");
905 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
907 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
909 (void)config_lookup(channel, p, "dns", "files");
921 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
922 error, strerror(error)));
923 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
929 if ((status == ARES_EOF) && (!channel->lookups)) {
930 /* Linux / GNU libc 2.x and possibly others have host.conf */
931 fp = fopen("/etc/host.conf", "r");
933 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
935 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
937 (void)config_lookup(channel, p, "bind", "hosts");
949 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
950 error, strerror(error)));
951 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
957 if ((status == ARES_EOF) && (!channel->lookups)) {
958 /* Tru64 uses /etc/svc.conf */
959 fp = fopen("/etc/svc.conf", "r");
961 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
963 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
965 (void)config_lookup(channel, p, "bind", "local");
977 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
978 error, strerror(error)));
979 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
992 if (status != ARES_EOF)
996 if (sortlist != NULL)
1001 /* If we got any name server entries, fill them in. */
1007 channel->servers = servers;
1008 channel->nservers = nservers;
1011 /* If we got any sortlist entries, fill them in. */
1014 channel->sortlist = sortlist;
1015 channel->nsort = nsort;
1018 return ARES_SUCCESS;
1021 static int init_by_defaults(ares_channel channel)
1023 char *hostname = NULL;
1024 int rc = ARES_SUCCESS;
1025 #ifdef HAVE_GETHOSTNAME
1029 if (channel->flags == -1)
1031 if (channel->timeout == -1)
1032 channel->timeout = DEFAULT_TIMEOUT;
1033 if (channel->tries == -1)
1034 channel->tries = DEFAULT_TRIES;
1035 if (channel->ndots == -1)
1037 if (channel->rotate == -1)
1038 channel->rotate = 0;
1039 if (channel->udp_port == -1)
1040 channel->udp_port = htons(NAMESERVER_PORT);
1041 if (channel->tcp_port == -1)
1042 channel->tcp_port = htons(NAMESERVER_PORT);
1044 if (channel->nservers == -1) {
1045 /* If nobody specified servers, try a local named. */
1046 channel->servers = malloc(sizeof(struct server_state));
1047 if (!channel->servers) {
1051 channel->servers[0].addr.family = AF_INET;
1052 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1053 channel->nservers = 1;
1056 #if defined(USE_WINSOCK)
1057 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1058 #elif defined(ENAMETOOLONG)
1059 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1060 (SOCKERRNO == EINVAL))
1062 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1065 if (channel->ndomains == -1) {
1066 /* Derive a default domain search list from the kernel hostname,
1067 * or set it to empty if the hostname isn't helpful.
1071 channel->ndomains = 0; /* default to none */
1073 #ifdef HAVE_GETHOSTNAME
1074 hostname = malloc(len);
1081 res = gethostname(hostname, len);
1086 p = realloc(hostname, len);
1101 dot = strchr(hostname, '.');
1103 /* a dot was found */
1104 channel->domains = malloc(sizeof(char *));
1105 if (!channel->domains) {
1109 channel->domains[0] = strdup(dot + 1);
1110 if (!channel->domains[0]) {
1114 channel->ndomains = 1;
1119 if (channel->nsort == -1) {
1120 channel->sortlist = NULL;
1124 if (!channel->lookups) {
1125 channel->lookups = strdup("fb");
1126 if (!channel->lookups)
1132 if(channel->servers)
1133 free(channel->servers);
1135 if(channel->domains && channel->domains[0])
1136 free(channel->domains[0]);
1137 if(channel->domains)
1138 free(channel->domains);
1139 if(channel->lookups)
1140 free(channel->lookups);
1149 #if !defined(WIN32) && !defined(WATT32)
1150 static int config_domain(ares_channel channel, char *str)
1154 /* Set a single search domain. */
1156 while (*q && !ISSPACE(*q))
1159 return set_search(channel, str);
1162 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1163 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1164 /* workaround icc 9.1 optimizer issue */
1165 # define vqualifier volatile
1170 static int config_lookup(ares_channel channel, const char *str,
1171 const char *bindch, const char *filech)
1173 char lookups[3], *l;
1174 const char *vqualifier p;
1176 /* Set the lookup order. Only the first letter of each work
1177 * is relevant, and it has to be "b" for DNS or "f" for the
1178 * host file. Ignore everything else.
1184 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1185 if (*p == *bindch) *l++ = 'b';
1188 while (*p && !ISSPACE(*p) && (*p != ','))
1190 while (*p && (ISSPACE(*p) || (*p == ',')))
1194 channel->lookups = strdup(lookups);
1195 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1197 #endif /* !WIN32 & !WATT32 */
1200 static int config_nameserver(struct server_state **servers, int *nservers,
1203 struct ares_addr host;
1204 struct server_state *newserv;
1206 /* On Windows, there may be more than one nameserver specified in the same
1207 * registry key, so we parse input as a space or comma seperated list.
1211 /* Skip whitespace and commas. */
1212 while (*p && (ISSPACE(*p) || (*p == ',')))
1215 /* No more input, done. */
1218 /* Pointer to start of IPv4 or IPv6 address part. */
1221 /* Advance past this address. */
1222 while (*p && !ISSPACE(*p) && (*p != ','))
1225 /* Null terminate this address. */
1228 /* Reached end of input, done when this address is processed. */
1231 /* Convert textual address to binary format. */
1232 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1233 host.family = AF_INET;
1234 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1235 host.family = AF_INET6;
1239 /* Resize servers state array. */
1240 newserv = realloc(*servers, (*nservers + 1) *
1241 sizeof(struct server_state));
1245 /* Store address data. */
1246 newserv[*nservers].addr.family = host.family;
1247 if (host.family == AF_INET)
1248 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1249 sizeof(host.addrV4));
1251 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1252 sizeof(host.addrV6));
1254 /* Update arguments. */
1259 return ARES_SUCCESS;
1263 static int config_sortlist(struct apattern **sortlist, int *nsort,
1266 struct apattern pat;
1269 /* Add sortlist entries. */
1270 while (*str && *str != ';')
1273 char ipbuf[16], ipbufpfx[32];
1274 /* Find just the IP */
1276 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1278 memcpy(ipbuf, str, q-str);
1279 ipbuf[q-str] = '\0';
1280 /* Find the prefix */
1283 const char *str2 = q+1;
1284 while (*q && *q != ';' && !ISSPACE(*q))
1286 memcpy(ipbufpfx, str, q-str);
1287 ipbufpfx[q-str] = '\0';
1292 /* Lets see if it is CIDR */
1293 /* First we'll try IPv6 */
1294 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1296 sizeof(pat.addrV6))) > 0)
1298 pat.type = PATTERN_CIDR;
1299 pat.mask.bits = (unsigned short)bits;
1300 pat.family = AF_INET6;
1301 if (!sortlist_alloc(sortlist, nsort, &pat))
1304 else if (ipbufpfx[0] &&
1305 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1306 sizeof(pat.addrV4))) > 0)
1308 pat.type = PATTERN_CIDR;
1309 pat.mask.bits = (unsigned short)bits;
1310 pat.family = AF_INET;
1311 if (!sortlist_alloc(sortlist, nsort, &pat))
1314 /* See if it is just a regular IP */
1315 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1319 memcpy(ipbuf, str, q-str);
1320 ipbuf[q-str] = '\0';
1321 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1326 pat.family = AF_INET;
1327 pat.type = PATTERN_MASK;
1328 if (!sortlist_alloc(sortlist, nsort, &pat))
1333 while (*q && *q != ';' && !ISSPACE(*q))
1337 while (ISSPACE(*str))
1341 return ARES_SUCCESS;
1344 #endif /* !WATT32 */
1346 static int set_search(ares_channel channel, const char *str)
1351 if(channel->ndomains != -1) {
1352 /* if we already have some domains present, free them first */
1353 for(n=0; n < channel->ndomains; n++)
1354 free(channel->domains[n]);
1355 free(channel->domains);
1356 channel->domains = NULL;
1357 channel->ndomains = -1;
1360 /* Count the domains given. */
1365 while (*p && !ISSPACE(*p))
1374 channel->ndomains = 0;
1375 return ARES_SUCCESS;
1378 channel->domains = malloc(n * sizeof(char *));
1379 if (!channel->domains)
1382 /* Now copy the domains. */
1387 channel->ndomains = n;
1389 while (*q && !ISSPACE(*q))
1391 channel->domains[n] = malloc(q - p + 1);
1392 if (!channel->domains[n])
1394 memcpy(channel->domains[n], p, q - p);
1395 channel->domains[n][q - p] = 0;
1401 channel->ndomains = n;
1403 return ARES_SUCCESS;
1406 static int set_options(ares_channel channel, const char *str)
1408 const char *p, *q, *val;
1414 while (*q && !ISSPACE(*q))
1416 val = try_option(p, q, "ndots:");
1417 if (val && channel->ndots == -1)
1418 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1419 val = try_option(p, q, "retrans:");
1420 if (val && channel->timeout == -1)
1421 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1422 val = try_option(p, q, "retry:");
1423 if (val && channel->tries == -1)
1424 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1425 val = try_option(p, q, "rotate");
1426 if (val && channel->rotate == -1)
1427 channel->rotate = 1;
1433 return ARES_SUCCESS;
1436 static const char *try_option(const char *p, const char *q, const char *opt)
1438 size_t len = strlen(opt);
1439 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1442 #if !defined(WIN32) && !defined(WATT32)
1443 static char *try_config(char *s, const char *opt, char scc)
1450 /* no line or no option */
1453 /* Hash '#' character is always used as primary comment char, additionally
1454 a not-NUL secondary comment char will be considered when specified. */
1456 /* trim line comment */
1459 while (*p && (*p != '#') && (*p != scc))
1462 while (*p && (*p != '#'))
1466 /* trim trailing whitespace */
1468 while ((q >= s) && ISSPACE(*q))
1472 /* skip leading whitespace */
1474 while (*p && ISSPACE(*p))
1481 if ((len = strlen(opt)) == 0)
1485 if (strncmp(p, opt, len) != 0)
1486 /* line and option do not match */
1489 /* skip over given option name */
1493 /* no option value */
1496 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1497 /* whitespace between option name and value is mandatory
1498 for given option names which do not end with ':' or '=' */
1501 /* skip over whitespace */
1502 while (*p && ISSPACE(*p))
1506 /* no option value */
1509 /* return pointer to option value */
1513 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1514 struct apattern *pat)
1516 struct apattern *newsort;
1517 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1520 newsort[*nsort] = *pat;
1521 *sortlist = newsort;
1526 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1529 /* Four octets and three periods yields at most 15 characters. */
1533 addr->s_addr = inet_addr(ipbuf);
1534 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1539 static void natural_mask(struct apattern *pat)
1541 struct in_addr addr;
1543 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1546 addr.s_addr = ntohl(pat->addrV4.s_addr);
1548 /* This is out of date in the CIDR world, but some people might
1551 if (IN_CLASSA(addr.s_addr))
1552 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1553 else if (IN_CLASSB(addr.s_addr))
1554 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1556 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1558 #endif /* !WIN32 && !WATT32 */
1560 /* initialize an rc4 key. If possible a cryptographically secure random key
1561 is generated using a suitable function (for example win32's RtlGenRandom as
1563 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1564 otherwise the code defaults to cross-platform albeit less secure mechanism
1567 static void randomize_key(unsigned char* key,int key_data_len)
1573 if (ares_fpSystemFunction036)
1575 res = (*ares_fpSystemFunction036) (key, key_data_len);
1581 FILE *f = fopen(RANDOM_FILE, "rb");
1583 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1589 if ( !randomized ) {
1590 for (;counter<key_data_len;counter++)
1591 key[counter]=(unsigned char)(rand() % 256);
1595 static int init_id_key(rc4_key* key,int key_data_len)
1597 unsigned char index1;
1598 unsigned char index2;
1599 unsigned char* state;
1601 unsigned char *key_data_ptr = 0;
1603 key_data_ptr = calloc(1,key_data_len);
1607 state = &key->state[0];
1608 for(counter = 0; counter < 256; counter++)
1609 /* unnecessary AND but it keeps some compilers happier */
1610 state[counter] = (unsigned char)(counter & 0xff);
1611 randomize_key(key->state,key_data_len);
1616 for(counter = 0; counter < 256; counter++)
1618 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1620 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1622 index1 = (unsigned char)((index1 + 1) % key_data_len);
1625 return ARES_SUCCESS;
1628 unsigned short ares__generate_new_id(rc4_key* key)
1631 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1635 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1637 channel->local_ip4 = local_ip;
1640 /* local_ip6 should be 16 bytes in length */
1641 void ares_set_local_ip6(ares_channel channel,
1642 const unsigned char* local_ip6)
1644 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1647 /* local_dev_name should be null terminated. */
1648 void ares_set_local_dev(ares_channel channel,
1649 const char* local_dev_name)
1651 strncpy(channel->local_dev_name, local_dev_name,
1652 sizeof(channel->local_dev_name));
1653 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1657 void ares_set_socket_callback(ares_channel channel,
1658 ares_sock_create_callback cb,
1661 channel->sock_create_cb = cb;
1662 channel->sock_create_cb_data = data;
1665 void ares__init_servers_state(ares_channel channel)
1667 struct server_state *server;
1670 for (i = 0; i < channel->nservers; i++)
1672 server = &channel->servers[i];
1673 server->udp_socket = ARES_SOCKET_BAD;
1674 server->tcp_socket = ARES_SOCKET_BAD;
1675 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1676 server->tcp_lenbuf_pos = 0;
1677 server->tcp_buffer_pos = 0;
1678 server->tcp_buffer = NULL;
1679 server->tcp_length = 0;
1680 server->qhead = NULL;
1681 server->qtail = NULL;
1682 ares__init_list_head(&server->queries_to_server);
1683 server->channel = channel;
1684 server->is_broken = 0;