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_private.h"
73 #include <sys/system_properties.h>
77 #undef WIN32 /* Redefined in MingW/MSVC headers */
80 static int init_by_options(ares_channel channel, const struct ares_options *options,
82 static int init_by_environment(ares_channel channel);
83 static int init_by_resolv_conf(ares_channel channel);
84 static int init_by_defaults(ares_channel channel);
87 static int config_nameserver(struct server_state **servers, int *nservers,
90 static int set_search(ares_channel channel, const char *str);
91 static int set_options(ares_channel channel, const char *str);
92 static const char *try_option(const char *p, const char *q, const char *opt);
93 static int init_id_key(rc4_key* key,int key_data_len);
95 #if !defined(WIN32) && !defined(WATT32)
96 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
97 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
98 static void natural_mask(struct apattern *pat);
99 static int config_domain(ares_channel channel, char *str);
100 static int config_lookup(ares_channel channel, const char *str,
101 const char *bindch, const char *filech);
102 static int config_sortlist(struct apattern **sortlist, int *nsort,
104 static char *try_config(char *s, const char *opt, char scc);
107 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
108 x->nservers > -1 && \
109 x->ndomains > -1 && \
110 x->ndots > -1 && x->timeout > -1 && \
113 int ares_init(ares_channel *channelptr)
115 return ares_init_options(channelptr, NULL, 0);
118 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
121 ares_channel channel;
123 int status = ARES_SUCCESS;
127 const char *env = getenv("CARES_MEMDEBUG");
131 env = getenv("CARES_MEMLIMIT");
134 long num = strtol(env, &endptr, 10);
135 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
140 if (ares_library_initialized() != ARES_SUCCESS)
141 return ARES_ENOTINITIALIZED;
143 channel = malloc(sizeof(struct ares_channeldata));
151 /* Set everything to distinguished values so we know they haven't
155 channel->timeout = -1;
158 channel->rotate = -1;
159 channel->udp_port = -1;
160 channel->tcp_port = -1;
161 channel->socket_send_buffer_size = -1;
162 channel->socket_receive_buffer_size = -1;
163 channel->nservers = -1;
164 channel->ndomains = -1;
166 channel->tcp_connection_generation = 0;
167 channel->lookups = NULL;
168 channel->domains = NULL;
169 channel->sortlist = NULL;
170 channel->servers = NULL;
171 channel->sock_state_cb = NULL;
172 channel->sock_state_cb_data = NULL;
173 channel->sock_create_cb = NULL;
174 channel->sock_create_cb_data = NULL;
176 channel->last_server = 0;
177 channel->last_timeout_processed = (time_t)now.tv_sec;
179 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
180 channel->local_ip4 = 0;
181 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
183 /* Initialize our lists of queries */
184 ares__init_list_head(&(channel->all_queries));
185 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
187 ares__init_list_head(&(channel->queries_by_qid[i]));
189 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
191 ares__init_list_head(&(channel->queries_by_timeout[i]));
194 /* Initialize configuration by each of the four sources, from highest
195 * precedence to lowest.
198 if (status == ARES_SUCCESS) {
199 status = init_by_options(channel, options, optmask);
200 if (status != ARES_SUCCESS)
201 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
202 ares_strerror(status)));
204 if (status == ARES_SUCCESS) {
205 status = init_by_environment(channel);
206 if (status != ARES_SUCCESS)
207 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
208 ares_strerror(status)));
210 if (status == ARES_SUCCESS) {
211 status = init_by_resolv_conf(channel);
212 if (status != ARES_SUCCESS)
213 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
214 ares_strerror(status)));
218 * No matter what failed or succeeded, seed defaults to provide
219 * useful behavior for things that we missed.
221 status = init_by_defaults(channel);
222 if (status != ARES_SUCCESS)
223 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
224 ares_strerror(status)));
226 /* Generate random key */
228 if (status == ARES_SUCCESS) {
229 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
230 if (status == ARES_SUCCESS)
231 channel->next_id = ares__generate_new_id(&channel->id_key);
233 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
234 ares_strerror(status)));
237 if (status != ARES_SUCCESS)
239 /* Something failed; clean up memory we may have allocated. */
240 if (channel->servers)
241 free(channel->servers);
242 if (channel->domains)
244 for (i = 0; i < channel->ndomains; i++)
245 free(channel->domains[i]);
246 free(channel->domains);
248 if (channel->sortlist)
249 free(channel->sortlist);
251 free(channel->lookups);
256 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
257 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
258 channel->nservers = 1;
260 ares__init_servers_state(channel);
262 *channelptr = channel;
266 /* ares_dup() duplicates a channel handle with all its options and returns a
267 new channel handle */
268 int ares_dup(ares_channel *dest, ares_channel src)
270 struct ares_options opts;
271 struct ares_addr_node *servers;
272 int ipv6_nservers = 0;
276 *dest = NULL; /* in case of failure return NULL explicitly */
278 /* First get the options supported by the old ares_save_options() function,
279 which is most of them */
280 rc = ares_save_options(src, &opts, &optmask);
284 /* Then create the new channel with those options */
285 rc = ares_init_options(dest, &opts, optmask);
287 /* destroy the options copy to not leak any memory */
288 ares_destroy_options(&opts);
293 /* Now clone the options that ares_save_options() doesn't support. */
294 (*dest)->sock_create_cb = src->sock_create_cb;
295 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
297 strncpy((*dest)->local_dev_name, src->local_dev_name, sizeof(src->local_dev_name));
298 (*dest)->local_ip4 = src->local_ip4;
299 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
301 /* Full name server cloning required when not all are IPv4 */
302 for (i = 0; i < src->nservers; i++)
304 if (src->servers[i].addr.family != AF_INET) {
310 rc = ares_get_servers(src, &servers);
311 if (rc != ARES_SUCCESS)
313 rc = ares_set_servers(*dest, servers);
314 ares_free_data(servers);
315 if (rc != ARES_SUCCESS)
319 return ARES_SUCCESS; /* everything went fine */
322 /* Save options from initialized channel */
323 int ares_save_options(ares_channel channel, struct ares_options *options,
327 int ipv4_nservers = 0;
329 /* Zero everything out */
330 memset(options, 0, sizeof(struct ares_options));
332 if (!ARES_CONFIG_CHECK(channel))
335 /* Traditionally the optmask wasn't saved in the channel struct so it was
336 recreated here. ROTATE is the first option that has no struct field of
337 its own in the public config struct */
338 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
339 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
340 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
341 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
342 (channel->optmask & ARES_OPT_ROTATE);
344 /* Copy easy stuff */
345 options->flags = channel->flags;
347 /* We return full millisecond resolution but that's only because we don't
348 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
349 options->timeout = channel->timeout;
350 options->tries = channel->tries;
351 options->ndots = channel->ndots;
352 options->udp_port = (unsigned short)channel->udp_port;
353 options->tcp_port = (unsigned short)channel->tcp_port;
354 options->sock_state_cb = channel->sock_state_cb;
355 options->sock_state_cb_data = channel->sock_state_cb_data;
357 /* Copy IPv4 servers */
358 if (channel->nservers) {
359 for (i = 0; i < channel->nservers; i++)
361 if (channel->servers[i].addr.family == AF_INET)
365 options->servers = malloc(ipv4_nservers * sizeof(struct server_state));
366 if (!options->servers)
368 for (i = j = 0; i < channel->nservers; i++)
370 if (channel->servers[i].addr.family == AF_INET)
371 memcpy(&options->servers[j++],
372 &channel->servers[i].addr.addrV4,
373 sizeof(channel->servers[i].addr.addrV4));
377 options->nservers = ipv4_nservers;
380 if (channel->ndomains) {
381 options->domains = malloc(channel->ndomains * sizeof(char *));
382 if (!options->domains)
385 for (i = 0; i < channel->ndomains; i++)
387 options->ndomains = i;
388 options->domains[i] = strdup(channel->domains[i]);
389 if (!options->domains[i])
393 options->ndomains = channel->ndomains;
396 if (channel->lookups) {
397 options->lookups = strdup(channel->lookups);
398 if (!options->lookups && channel->lookups)
403 if (channel->nsort) {
404 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
405 if (!options->sortlist)
407 for (i = 0; i < channel->nsort; i++)
408 options->sortlist[i] = channel->sortlist[i];
410 options->nsort = channel->nsort;
415 static int init_by_options(ares_channel channel,
416 const struct ares_options *options,
422 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
423 channel->flags = options->flags;
424 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
425 channel->timeout = options->timeout;
426 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
427 channel->timeout = options->timeout * 1000;
428 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
429 channel->tries = options->tries;
430 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
431 channel->ndots = options->ndots;
432 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
434 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
435 channel->udp_port = options->udp_port;
436 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
437 channel->tcp_port = options->tcp_port;
438 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
440 channel->sock_state_cb = options->sock_state_cb;
441 channel->sock_state_cb_data = options->sock_state_cb_data;
443 if ((optmask & ARES_OPT_SOCK_SNDBUF)
444 && channel->socket_send_buffer_size == -1)
445 channel->socket_send_buffer_size = options->socket_send_buffer_size;
446 if ((optmask & ARES_OPT_SOCK_RCVBUF)
447 && channel->socket_receive_buffer_size == -1)
448 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
450 /* Copy the IPv4 servers, if given. */
451 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
453 /* Avoid zero size allocations at any cost */
454 if (options->nservers > 0)
457 malloc(options->nservers * sizeof(struct server_state));
458 if (!channel->servers)
460 for (i = 0; i < options->nservers; i++)
462 channel->servers[i].addr.family = AF_INET;
463 memcpy(&channel->servers[i].addr.addrV4,
464 &options->servers[i],
465 sizeof(channel->servers[i].addr.addrV4));
468 channel->nservers = options->nservers;
471 /* Copy the domains, if given. Keep channel->ndomains consistent so
472 * we can clean up in case of error.
474 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
476 /* Avoid zero size allocations at any cost */
477 if (options->ndomains > 0)
479 channel->domains = malloc(options->ndomains * sizeof(char *));
480 if (!channel->domains)
482 for (i = 0; i < options->ndomains; i++)
484 channel->ndomains = i;
485 channel->domains[i] = strdup(options->domains[i]);
486 if (!channel->domains[i])
490 channel->ndomains = options->ndomains;
493 /* Set lookups, if given. */
494 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
496 channel->lookups = strdup(options->lookups);
497 if (!channel->lookups)
502 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
503 (options->nsort>0)) {
504 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
505 if (!channel->sortlist)
507 for (i = 0; i < options->nsort; i++)
508 channel->sortlist[i] = options->sortlist[i];
509 channel->nsort = options->nsort;
512 channel->optmask = optmask;
517 static int init_by_environment(ares_channel channel)
519 const char *localdomain, *res_options;
522 localdomain = getenv("LOCALDOMAIN");
523 if (localdomain && channel->ndomains == -1)
525 status = set_search(channel, localdomain);
526 if (status != ARES_SUCCESS)
530 res_options = getenv("RES_OPTIONS");
533 status = set_options(channel, res_options);
534 if (status != ARES_SUCCESS)
543 * Warning: returns a dynamically allocated buffer, the user MUST
544 * use free() if the function returns 1
546 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
548 /* Test for the size we need */
552 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
553 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
555 *obuf = malloc(size+1);
559 if (RegQueryValueEx(hKey, subkey, 0, NULL,
560 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
573 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
575 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
576 DWORD enum_size = 39;
580 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
581 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
586 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
589 rc = get_res_nt(hVal, subkey, obuf);
597 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
599 FIXED_INFO *fi, *newfi;
600 DWORD size = sizeof (*fi);
601 IP_ADDR_STRING *ipAddr;
604 size_t ip_size = sizeof("255.255.255.255,")-1;
605 size_t left = ret_size;
613 res = (*ares_fpGetNetworkParams) (fi, &size);
614 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
617 newfi = realloc(fi, size);
622 res = (*ares_fpGetNetworkParams) (fi, &size);
623 if (res != ERROR_SUCCESS)
628 printf ("Host Name: %s\n", fi->HostName);
629 printf ("Domain Name: %s\n", fi->DomainName);
630 printf ("DNS Servers:\n"
631 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
633 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
634 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
637 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
638 left -= ret - ret_buf;
642 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
643 ipAddr = ipAddr->Next, i++)
645 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
647 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
648 left -= ret - ret_buf;
652 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
659 if (debug && left <= ip_size)
660 printf ("Too many nameservers. Truncating to %d addressess", count);
667 static int init_by_resolv_conf(ares_channel channel)
672 int status = -1, nservers = 0, nsort = 0;
673 struct server_state *servers = NULL;
674 struct apattern *sortlist = NULL;
679 NameServer info via IPHLPAPI (IP helper API):
680 GetNetworkParams() should be the trusted source for this.
681 Available in Win-98/2000 and later. If that fail, fall-back to
682 registry information.
686 On Windows 9X, the DNS server can be found in:
687 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
689 On Windows NT/2000/XP/2003:
690 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
692 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
694 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
697 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
708 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
711 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
713 status = config_nameserver(&servers, &nservers, buf);
714 if (status == ARES_SUCCESS)
721 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
725 RegOpenKeyEx(mykey, "Interfaces", 0,
726 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
727 if (get_res_nt(mykey, NAMESERVER, &line))
729 status = config_nameserver(&servers, &nservers, line);
732 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
734 status = config_nameserver(&servers, &nservers, line);
737 /* Try the interfaces */
738 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
740 status = config_nameserver(&servers, &nservers, line);
743 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
745 status = config_nameserver(&servers, &nservers, line);
755 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
759 if ((result = RegQueryValueEx(
760 mykey, NAMESERVER, NULL, &data_type,
763 ) == ERROR_SUCCESS ||
764 result == ERROR_MORE_DATA)
768 line = malloc(bytes+1);
769 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
770 (unsigned char *)line, &bytes) ==
773 status = config_nameserver(&servers, &nservers, line);
782 if (status == ARES_SUCCESS)
785 /* Catch the case when all the above checks fail (which happens when there
786 is no network card or the cable is unplugged) */
789 #elif defined(__riscos__)
791 /* Under RISC OS, name servers are listed in the
792 system variable Inet$Resolvers, space separated. */
794 line = getenv("Inet$Resolvers");
797 char *resolvers = strdup(line), *pos, *space;
804 space = strchr(pos, ' ');
807 status = config_nameserver(&servers, &nservers, pos);
808 if (status != ARES_SUCCESS)
813 if (status == ARES_SUCCESS)
819 #elif defined(WATT32)
823 for (i = 0; def_nameservers[i]; i++)
826 return ARES_SUCCESS; /* use localhost DNS server */
829 servers = calloc(i, sizeof(struct server_state));
833 for (i = 0; def_nameservers[i]; i++)
835 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
836 servers[i].addr.family = AF_INET;
840 #elif defined(ANDROID)
841 char value[PROP_VALUE_MAX]="";
842 __system_property_get("net.dns1", value);
843 status = config_nameserver(&servers, &nservers, value);
844 if (status == ARES_SUCCESS)
853 /* Don't read resolv.conf and friends if we don't have to */
854 if (ARES_CONFIG_CHECK(channel))
857 fp = fopen(PATH_RESOLV_CONF, "r");
859 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
861 if ((p = try_config(line, "domain", ';')))
862 status = config_domain(channel, p);
863 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
864 status = config_lookup(channel, p, "bind", "file");
865 else if ((p = try_config(line, "search", ';')))
866 status = set_search(channel, p);
867 else if ((p = try_config(line, "nameserver", ';')) &&
868 channel->nservers == -1)
869 status = config_nameserver(&servers, &nservers, p);
870 else if ((p = try_config(line, "sortlist", ';')) &&
871 channel->nsort == -1)
872 status = config_sortlist(&sortlist, &nsort, p);
873 else if ((p = try_config(line, "options", ';')))
874 status = set_options(channel, p);
876 status = ARES_SUCCESS;
877 if (status != ARES_SUCCESS)
890 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
891 error, strerror(error)));
892 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
897 if ((status == ARES_EOF) && (!channel->lookups)) {
898 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
899 fp = fopen("/etc/nsswitch.conf", "r");
901 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
903 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
905 (void)config_lookup(channel, p, "dns", "files");
917 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
918 error, strerror(error)));
919 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
925 if ((status == ARES_EOF) && (!channel->lookups)) {
926 /* Linux / GNU libc 2.x and possibly others have host.conf */
927 fp = fopen("/etc/host.conf", "r");
929 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
931 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
933 (void)config_lookup(channel, p, "bind", "hosts");
945 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
946 error, strerror(error)));
947 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
953 if ((status == ARES_EOF) && (!channel->lookups)) {
954 /* Tru64 uses /etc/svc.conf */
955 fp = fopen("/etc/svc.conf", "r");
957 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
959 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
961 (void)config_lookup(channel, p, "bind", "local");
973 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
974 error, strerror(error)));
975 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
988 if (status != ARES_EOF)
992 if (sortlist != NULL)
997 /* If we got any name server entries, fill them in. */
1003 channel->servers = servers;
1004 channel->nservers = nservers;
1007 /* If we got any sortlist entries, fill them in. */
1010 channel->sortlist = sortlist;
1011 channel->nsort = nsort;
1014 return ARES_SUCCESS;
1017 static int init_by_defaults(ares_channel channel)
1019 char *hostname = NULL;
1020 int rc = ARES_SUCCESS;
1021 #ifdef HAVE_GETHOSTNAME
1025 if (channel->flags == -1)
1027 if (channel->timeout == -1)
1028 channel->timeout = DEFAULT_TIMEOUT;
1029 if (channel->tries == -1)
1030 channel->tries = DEFAULT_TRIES;
1031 if (channel->ndots == -1)
1033 if (channel->rotate == -1)
1034 channel->rotate = 0;
1035 if (channel->udp_port == -1)
1036 channel->udp_port = htons(NAMESERVER_PORT);
1037 if (channel->tcp_port == -1)
1038 channel->tcp_port = htons(NAMESERVER_PORT);
1040 if (channel->nservers == -1) {
1041 /* If nobody specified servers, try a local named. */
1042 channel->servers = malloc(sizeof(struct server_state));
1043 if (!channel->servers) {
1047 channel->servers[0].addr.family = AF_INET;
1048 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1049 channel->nservers = 1;
1052 #if defined(USE_WINSOCK)
1053 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1054 #elif defined(ENAMETOOLONG)
1055 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1056 (SOCKERRNO == EINVAL))
1058 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1061 if (channel->ndomains == -1) {
1062 /* Derive a default domain search list from the kernel hostname,
1063 * or set it to empty if the hostname isn't helpful.
1067 channel->ndomains = 0; /* default to none */
1069 #ifdef HAVE_GETHOSTNAME
1070 hostname = malloc(len);
1077 res = gethostname(hostname, len);
1082 p = realloc(hostname, len);
1097 dot = strchr(hostname, '.');
1099 /* a dot was found */
1100 channel->domains = malloc(sizeof(char *));
1101 if (!channel->domains) {
1105 channel->domains[0] = strdup(dot + 1);
1106 if (!channel->domains[0]) {
1110 channel->ndomains = 1;
1115 if (channel->nsort == -1) {
1116 channel->sortlist = NULL;
1120 if (!channel->lookups) {
1121 channel->lookups = strdup("fb");
1122 if (!channel->lookups)
1128 if(channel->servers)
1129 free(channel->servers);
1131 if(channel->domains && channel->domains[0])
1132 free(channel->domains[0]);
1133 if(channel->domains)
1134 free(channel->domains);
1135 if(channel->lookups)
1136 free(channel->lookups);
1145 #if !defined(WIN32) && !defined(WATT32)
1146 static int config_domain(ares_channel channel, char *str)
1150 /* Set a single search domain. */
1152 while (*q && !ISSPACE(*q))
1155 return set_search(channel, str);
1158 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1159 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1160 /* workaround icc 9.1 optimizer issue */
1161 # define vqualifier volatile
1166 static int config_lookup(ares_channel channel, const char *str,
1167 const char *bindch, const char *filech)
1169 char lookups[3], *l;
1170 const char *vqualifier p;
1172 /* Set the lookup order. Only the first letter of each work
1173 * is relevant, and it has to be "b" for DNS or "f" for the
1174 * host file. Ignore everything else.
1180 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1181 if (*p == *bindch) *l++ = 'b';
1184 while (*p && !ISSPACE(*p) && (*p != ','))
1186 while (*p && (ISSPACE(*p) || (*p == ',')))
1190 channel->lookups = strdup(lookups);
1191 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1193 #endif /* !WIN32 & !WATT32 */
1196 static int config_nameserver(struct server_state **servers, int *nservers,
1199 struct ares_addr host;
1200 struct server_state *newserv;
1202 /* On Windows, there may be more than one nameserver specified in the same
1203 * registry key, so we parse input as a space or comma seperated list.
1207 /* Skip whitespace and commas. */
1208 while (*p && (ISSPACE(*p) || (*p == ',')))
1211 /* No more input, done. */
1214 /* Pointer to start of IPv4 or IPv6 address part. */
1217 /* Advance past this address. */
1218 while (*p && !ISSPACE(*p) && (*p != ','))
1221 /* Null terminate this address. */
1224 /* Reached end of input, done when this address is processed. */
1227 /* Convert textual address to binary format. */
1228 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1229 host.family = AF_INET;
1230 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1231 host.family = AF_INET6;
1235 /* Resize servers state array. */
1236 newserv = realloc(*servers, (*nservers + 1) *
1237 sizeof(struct server_state));
1241 /* Store address data. */
1242 newserv[*nservers].addr.family = host.family;
1243 if (host.family == AF_INET)
1244 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1245 sizeof(host.addrV4));
1247 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1248 sizeof(host.addrV6));
1250 /* Update arguments. */
1255 return ARES_SUCCESS;
1259 static int config_sortlist(struct apattern **sortlist, int *nsort,
1262 struct apattern pat;
1265 /* Add sortlist entries. */
1266 while (*str && *str != ';')
1269 char ipbuf[16], ipbufpfx[32];
1270 /* Find just the IP */
1272 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1274 memcpy(ipbuf, str, q-str);
1275 ipbuf[q-str] = '\0';
1276 /* Find the prefix */
1279 const char *str2 = q+1;
1280 while (*q && *q != ';' && !ISSPACE(*q))
1282 memcpy(ipbufpfx, str, q-str);
1283 ipbufpfx[q-str] = '\0';
1288 /* Lets see if it is CIDR */
1289 /* First we'll try IPv6 */
1290 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1292 sizeof(pat.addrV6))) > 0)
1294 pat.type = PATTERN_CIDR;
1295 pat.mask.bits = (unsigned short)bits;
1296 pat.family = AF_INET6;
1297 if (!sortlist_alloc(sortlist, nsort, &pat))
1300 else if (ipbufpfx[0] &&
1301 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1302 sizeof(pat.addrV4))) > 0)
1304 pat.type = PATTERN_CIDR;
1305 pat.mask.bits = (unsigned short)bits;
1306 pat.family = AF_INET;
1307 if (!sortlist_alloc(sortlist, nsort, &pat))
1310 /* See if it is just a regular IP */
1311 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1315 memcpy(ipbuf, str, q-str);
1316 ipbuf[q-str] = '\0';
1317 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1322 pat.family = AF_INET;
1323 pat.type = PATTERN_MASK;
1324 if (!sortlist_alloc(sortlist, nsort, &pat))
1329 while (*q && *q != ';' && !ISSPACE(*q))
1333 while (ISSPACE(*str))
1337 return ARES_SUCCESS;
1340 #endif /* !WATT32 */
1342 static int set_search(ares_channel channel, const char *str)
1347 if(channel->ndomains != -1) {
1348 /* if we already have some domains present, free them first */
1349 for(n=0; n < channel->ndomains; n++)
1350 free(channel->domains[n]);
1351 free(channel->domains);
1352 channel->domains = NULL;
1353 channel->ndomains = -1;
1356 /* Count the domains given. */
1361 while (*p && !ISSPACE(*p))
1370 channel->ndomains = 0;
1371 return ARES_SUCCESS;
1374 channel->domains = malloc(n * sizeof(char *));
1375 if (!channel->domains)
1378 /* Now copy the domains. */
1383 channel->ndomains = n;
1385 while (*q && !ISSPACE(*q))
1387 channel->domains[n] = malloc(q - p + 1);
1388 if (!channel->domains[n])
1390 memcpy(channel->domains[n], p, q - p);
1391 channel->domains[n][q - p] = 0;
1397 channel->ndomains = n;
1399 return ARES_SUCCESS;
1402 static int set_options(ares_channel channel, const char *str)
1404 const char *p, *q, *val;
1410 while (*q && !ISSPACE(*q))
1412 val = try_option(p, q, "ndots:");
1413 if (val && channel->ndots == -1)
1414 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1415 val = try_option(p, q, "retrans:");
1416 if (val && channel->timeout == -1)
1417 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1418 val = try_option(p, q, "retry:");
1419 if (val && channel->tries == -1)
1420 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1421 val = try_option(p, q, "rotate");
1422 if (val && channel->rotate == -1)
1423 channel->rotate = 1;
1429 return ARES_SUCCESS;
1432 static const char *try_option(const char *p, const char *q, const char *opt)
1434 size_t len = strlen(opt);
1435 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1438 #if !defined(WIN32) && !defined(WATT32)
1439 static char *try_config(char *s, const char *opt, char scc)
1446 /* no line or no option */
1449 /* Hash '#' character is always used as primary comment char, additionally
1450 a not-NUL secondary comment char will be considered when specified. */
1452 /* trim line comment */
1455 while (*p && (*p != '#') && (*p != scc))
1458 while (*p && (*p != '#'))
1462 /* trim trailing whitespace */
1464 while ((q >= s) && ISSPACE(*q))
1468 /* skip leading whitespace */
1470 while (*p && ISSPACE(*p))
1477 if ((len = strlen(opt)) == 0)
1481 if (strncmp(p, opt, len) != 0)
1482 /* line and option do not match */
1485 /* skip over given option name */
1489 /* no option value */
1492 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1493 /* whitespace between option name and value is mandatory
1494 for given option names which do not end with ':' or '=' */
1497 /* skip over whitespace */
1498 while (*p && ISSPACE(*p))
1502 /* no option value */
1505 /* return pointer to option value */
1509 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1510 struct apattern *pat)
1512 struct apattern *newsort;
1513 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1516 newsort[*nsort] = *pat;
1517 *sortlist = newsort;
1522 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1525 /* Four octets and three periods yields at most 15 characters. */
1529 addr->s_addr = inet_addr(ipbuf);
1530 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1535 static void natural_mask(struct apattern *pat)
1537 struct in_addr addr;
1539 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1542 addr.s_addr = ntohl(pat->addrV4.s_addr);
1544 /* This is out of date in the CIDR world, but some people might
1547 if (IN_CLASSA(addr.s_addr))
1548 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1549 else if (IN_CLASSB(addr.s_addr))
1550 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1552 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1554 #endif /* !WIN32 && !WATT32 */
1556 /* initialize an rc4 key. If possible a cryptographically secure random key
1557 is generated using a suitable function (for example win32's RtlGenRandom as
1559 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1560 otherwise the code defaults to cross-platform albeit less secure mechanism
1563 static void randomize_key(unsigned char* key,int key_data_len)
1569 if (ares_fpSystemFunction036)
1571 res = (*ares_fpSystemFunction036) (key, key_data_len);
1577 FILE *f = fopen(RANDOM_FILE, "rb");
1579 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1585 if ( !randomized ) {
1586 for (;counter<key_data_len;counter++)
1587 key[counter]=(unsigned char)(rand() % 256);
1591 static int init_id_key(rc4_key* key,int key_data_len)
1593 unsigned char index1;
1594 unsigned char index2;
1595 unsigned char* state;
1597 unsigned char *key_data_ptr = 0;
1599 key_data_ptr = calloc(1,key_data_len);
1603 state = &key->state[0];
1604 for(counter = 0; counter < 256; counter++)
1605 /* unnecessary AND but it keeps some compilers happier */
1606 state[counter] = (unsigned char)(counter & 0xff);
1607 randomize_key(key->state,key_data_len);
1612 for(counter = 0; counter < 256; counter++)
1614 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1616 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1618 index1 = (unsigned char)((index1 + 1) % key_data_len);
1621 return ARES_SUCCESS;
1624 unsigned short ares__generate_new_id(rc4_key* key)
1627 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1631 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1633 channel->local_ip4 = local_ip;
1636 /* local_ip6 should be 16 bytes in length */
1637 void ares_set_local_ip6(ares_channel channel,
1638 const unsigned char* local_ip6)
1640 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1643 /* local_dev_name should be null terminated. */
1644 void ares_set_local_dev(ares_channel channel,
1645 const char* local_dev_name)
1647 strncpy(channel->local_dev_name, local_dev_name,
1648 sizeof(channel->local_dev_name));
1649 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1653 void ares_set_socket_callback(ares_channel channel,
1654 ares_sock_create_callback cb,
1657 channel->sock_create_cb = cb;
1658 channel->sock_create_cb_data = data;
1661 void ares__init_servers_state(ares_channel channel)
1663 struct server_state *server;
1666 for (i = 0; i < channel->nservers; i++)
1668 server = &channel->servers[i];
1669 server->udp_socket = ARES_SOCKET_BAD;
1670 server->tcp_socket = ARES_SOCKET_BAD;
1671 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1672 server->tcp_lenbuf_pos = 0;
1673 server->tcp_buffer_pos = 0;
1674 server->tcp_buffer = NULL;
1675 server->tcp_length = 0;
1676 server->qhead = NULL;
1677 server->qtail = NULL;
1678 ares__init_list_head(&server->queries_to_server);
1679 server->channel = channel;
1680 server->is_broken = 0;