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}\
707 win_platform platform;
709 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
712 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
714 status = config_nameserver(&servers, &nservers, buf);
715 if (status == ARES_SUCCESS)
719 platform = getplatform();
721 if (platform == WIN_NT)
724 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
728 RegOpenKeyEx(mykey, "Interfaces", 0,
729 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
730 if (get_res_nt(mykey, NAMESERVER, &line))
732 status = config_nameserver(&servers, &nservers, line);
735 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
737 status = config_nameserver(&servers, &nservers, line);
740 /* Try the interfaces */
741 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
743 status = config_nameserver(&servers, &nservers, line);
746 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
748 status = config_nameserver(&servers, &nservers, line);
755 else if (platform == WIN_9X)
758 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
762 if ((result = RegQueryValueEx(
763 mykey, NAMESERVER, NULL, &data_type,
766 ) == ERROR_SUCCESS ||
767 result == ERROR_MORE_DATA)
771 line = malloc(bytes+1);
772 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
773 (unsigned char *)line, &bytes) ==
776 status = config_nameserver(&servers, &nservers, line);
785 if (status == ARES_SUCCESS)
788 /* Catch the case when all the above checks fail (which happens when there
789 is no network card or the cable is unplugged) */
792 #elif defined(__riscos__)
794 /* Under RISC OS, name servers are listed in the
795 system variable Inet$Resolvers, space separated. */
797 line = getenv("Inet$Resolvers");
800 char *resolvers = strdup(line), *pos, *space;
807 space = strchr(pos, ' ');
810 status = config_nameserver(&servers, &nservers, pos);
811 if (status != ARES_SUCCESS)
816 if (status == ARES_SUCCESS)
822 #elif defined(WATT32)
826 for (i = 0; def_nameservers[i]; i++)
829 return ARES_SUCCESS; /* use localhost DNS server */
832 servers = calloc(i, sizeof(struct server_state));
836 for (i = 0; def_nameservers[i]; i++)
838 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
839 servers[i].addr.family = AF_INET;
843 #elif defined(ANDROID)
844 char value[PROP_VALUE_MAX]="";
845 __system_property_get("net.dns1", value);
846 status = config_nameserver(&servers, &nservers, value);
847 if (status == ARES_SUCCESS)
856 /* Don't read resolv.conf and friends if we don't have to */
857 if (ARES_CONFIG_CHECK(channel))
860 fp = fopen(PATH_RESOLV_CONF, "r");
862 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
864 if ((p = try_config(line, "domain", ';')))
865 status = config_domain(channel, p);
866 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
867 status = config_lookup(channel, p, "bind", "file");
868 else if ((p = try_config(line, "search", ';')))
869 status = set_search(channel, p);
870 else if ((p = try_config(line, "nameserver", ';')) &&
871 channel->nservers == -1)
872 status = config_nameserver(&servers, &nservers, p);
873 else if ((p = try_config(line, "sortlist", ';')) &&
874 channel->nsort == -1)
875 status = config_sortlist(&sortlist, &nsort, p);
876 else if ((p = try_config(line, "options", ';')))
877 status = set_options(channel, p);
879 status = ARES_SUCCESS;
880 if (status != ARES_SUCCESS)
893 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
894 error, strerror(error)));
895 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
900 if ((status == ARES_EOF) && (!channel->lookups)) {
901 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
902 fp = fopen("/etc/nsswitch.conf", "r");
904 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
906 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
908 (void)config_lookup(channel, p, "dns", "files");
920 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
921 error, strerror(error)));
922 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
928 if ((status == ARES_EOF) && (!channel->lookups)) {
929 /* Linux / GNU libc 2.x and possibly others have host.conf */
930 fp = fopen("/etc/host.conf", "r");
932 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
934 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
936 (void)config_lookup(channel, p, "bind", "hosts");
948 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
949 error, strerror(error)));
950 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
956 if ((status == ARES_EOF) && (!channel->lookups)) {
957 /* Tru64 uses /etc/svc.conf */
958 fp = fopen("/etc/svc.conf", "r");
960 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
962 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
964 (void)config_lookup(channel, p, "bind", "local");
976 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
977 error, strerror(error)));
978 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
991 if (status != ARES_EOF)
995 if (sortlist != NULL)
1000 /* If we got any name server entries, fill them in. */
1006 channel->servers = servers;
1007 channel->nservers = nservers;
1010 /* If we got any sortlist entries, fill them in. */
1013 channel->sortlist = sortlist;
1014 channel->nsort = nsort;
1017 return ARES_SUCCESS;
1020 static int init_by_defaults(ares_channel channel)
1022 char *hostname = NULL;
1023 int rc = ARES_SUCCESS;
1024 #ifdef HAVE_GETHOSTNAME
1028 if (channel->flags == -1)
1030 if (channel->timeout == -1)
1031 channel->timeout = DEFAULT_TIMEOUT;
1032 if (channel->tries == -1)
1033 channel->tries = DEFAULT_TRIES;
1034 if (channel->ndots == -1)
1036 if (channel->rotate == -1)
1037 channel->rotate = 0;
1038 if (channel->udp_port == -1)
1039 channel->udp_port = htons(NAMESERVER_PORT);
1040 if (channel->tcp_port == -1)
1041 channel->tcp_port = htons(NAMESERVER_PORT);
1043 if (channel->nservers == -1) {
1044 /* If nobody specified servers, try a local named. */
1045 channel->servers = malloc(sizeof(struct server_state));
1046 if (!channel->servers) {
1050 channel->servers[0].addr.family = AF_INET;
1051 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1052 channel->nservers = 1;
1055 #if defined(USE_WINSOCK)
1056 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1057 #elif defined(ENAMETOOLONG)
1058 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1059 (SOCKERRNO == EINVAL))
1061 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1064 if (channel->ndomains == -1) {
1065 /* Derive a default domain search list from the kernel hostname,
1066 * or set it to empty if the hostname isn't helpful.
1070 channel->ndomains = 0; /* default to none */
1072 #ifdef HAVE_GETHOSTNAME
1073 hostname = malloc(len);
1080 res = gethostname(hostname, len);
1085 p = realloc(hostname, len);
1100 dot = strchr(hostname, '.');
1102 /* a dot was found */
1103 channel->domains = malloc(sizeof(char *));
1104 if (!channel->domains) {
1108 channel->domains[0] = strdup(dot + 1);
1109 if (!channel->domains[0]) {
1113 channel->ndomains = 1;
1118 if (channel->nsort == -1) {
1119 channel->sortlist = NULL;
1123 if (!channel->lookups) {
1124 channel->lookups = strdup("fb");
1125 if (!channel->lookups)
1131 if(channel->servers)
1132 free(channel->servers);
1134 if(channel->domains && channel->domains[0])
1135 free(channel->domains[0]);
1136 if(channel->domains)
1137 free(channel->domains);
1138 if(channel->lookups)
1139 free(channel->lookups);
1148 #if !defined(WIN32) && !defined(WATT32)
1149 static int config_domain(ares_channel channel, char *str)
1153 /* Set a single search domain. */
1155 while (*q && !ISSPACE(*q))
1158 return set_search(channel, str);
1161 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1162 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1163 /* workaround icc 9.1 optimizer issue */
1164 # define vqualifier volatile
1169 static int config_lookup(ares_channel channel, const char *str,
1170 const char *bindch, const char *filech)
1172 char lookups[3], *l;
1173 const char *vqualifier p;
1175 /* Set the lookup order. Only the first letter of each work
1176 * is relevant, and it has to be "b" for DNS or "f" for the
1177 * host file. Ignore everything else.
1183 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1184 if (*p == *bindch) *l++ = 'b';
1187 while (*p && !ISSPACE(*p) && (*p != ','))
1189 while (*p && (ISSPACE(*p) || (*p == ',')))
1193 channel->lookups = strdup(lookups);
1194 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1196 #endif /* !WIN32 & !WATT32 */
1199 static int config_nameserver(struct server_state **servers, int *nservers,
1202 struct ares_addr host;
1203 struct server_state *newserv;
1205 /* On Windows, there may be more than one nameserver specified in the same
1206 * registry key, so we parse input as a space or comma seperated list.
1210 /* Skip whitespace and commas. */
1211 while (*p && (ISSPACE(*p) || (*p == ',')))
1214 /* No more input, done. */
1217 /* Pointer to start of IPv4 or IPv6 address part. */
1220 /* Advance past this address. */
1221 while (*p && !ISSPACE(*p) && (*p != ','))
1224 /* Null terminate this address. */
1227 /* Reached end of input, done when this address is processed. */
1230 /* Convert textual address to binary format. */
1231 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1232 host.family = AF_INET;
1233 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1234 host.family = AF_INET6;
1238 /* Resize servers state array. */
1239 newserv = realloc(*servers, (*nservers + 1) *
1240 sizeof(struct server_state));
1244 /* Store address data. */
1245 newserv[*nservers].addr.family = host.family;
1246 if (host.family == AF_INET)
1247 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1248 sizeof(host.addrV4));
1250 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1251 sizeof(host.addrV6));
1253 /* Update arguments. */
1258 return ARES_SUCCESS;
1262 static int config_sortlist(struct apattern **sortlist, int *nsort,
1265 struct apattern pat;
1268 /* Add sortlist entries. */
1269 while (*str && *str != ';')
1272 char ipbuf[16], ipbufpfx[32];
1273 /* Find just the IP */
1275 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1277 memcpy(ipbuf, str, q-str);
1278 ipbuf[q-str] = '\0';
1279 /* Find the prefix */
1282 const char *str2 = q+1;
1283 while (*q && *q != ';' && !ISSPACE(*q))
1285 memcpy(ipbufpfx, str, q-str);
1286 ipbufpfx[q-str] = '\0';
1291 /* Lets see if it is CIDR */
1292 /* First we'll try IPv6 */
1293 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1295 sizeof(pat.addrV6))) > 0)
1297 pat.type = PATTERN_CIDR;
1298 pat.mask.bits = (unsigned short)bits;
1299 pat.family = AF_INET6;
1300 if (!sortlist_alloc(sortlist, nsort, &pat))
1303 else if (ipbufpfx[0] &&
1304 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1305 sizeof(pat.addrV4))) > 0)
1307 pat.type = PATTERN_CIDR;
1308 pat.mask.bits = (unsigned short)bits;
1309 pat.family = AF_INET;
1310 if (!sortlist_alloc(sortlist, nsort, &pat))
1313 /* See if it is just a regular IP */
1314 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1318 memcpy(ipbuf, str, q-str);
1319 ipbuf[q-str] = '\0';
1320 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1325 pat.family = AF_INET;
1326 pat.type = PATTERN_MASK;
1327 if (!sortlist_alloc(sortlist, nsort, &pat))
1332 while (*q && *q != ';' && !ISSPACE(*q))
1336 while (ISSPACE(*str))
1340 return ARES_SUCCESS;
1343 #endif /* !WATT32 */
1345 static int set_search(ares_channel channel, const char *str)
1350 if(channel->ndomains != -1) {
1351 /* if we already have some domains present, free them first */
1352 for(n=0; n < channel->ndomains; n++)
1353 free(channel->domains[n]);
1354 free(channel->domains);
1355 channel->domains = NULL;
1356 channel->ndomains = -1;
1359 /* Count the domains given. */
1364 while (*p && !ISSPACE(*p))
1373 channel->ndomains = 0;
1374 return ARES_SUCCESS;
1377 channel->domains = malloc(n * sizeof(char *));
1378 if (!channel->domains)
1381 /* Now copy the domains. */
1386 channel->ndomains = n;
1388 while (*q && !ISSPACE(*q))
1390 channel->domains[n] = malloc(q - p + 1);
1391 if (!channel->domains[n])
1393 memcpy(channel->domains[n], p, q - p);
1394 channel->domains[n][q - p] = 0;
1400 channel->ndomains = n;
1402 return ARES_SUCCESS;
1405 static int set_options(ares_channel channel, const char *str)
1407 const char *p, *q, *val;
1413 while (*q && !ISSPACE(*q))
1415 val = try_option(p, q, "ndots:");
1416 if (val && channel->ndots == -1)
1417 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1418 val = try_option(p, q, "retrans:");
1419 if (val && channel->timeout == -1)
1420 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1421 val = try_option(p, q, "retry:");
1422 if (val && channel->tries == -1)
1423 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1424 val = try_option(p, q, "rotate");
1425 if (val && channel->rotate == -1)
1426 channel->rotate = 1;
1432 return ARES_SUCCESS;
1435 static const char *try_option(const char *p, const char *q, const char *opt)
1437 size_t len = strlen(opt);
1438 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1441 #if !defined(WIN32) && !defined(WATT32)
1442 static char *try_config(char *s, const char *opt, char scc)
1449 /* no line or no option */
1452 /* Hash '#' character is always used as primary comment char, additionally
1453 a not-NUL secondary comment char will be considered when specified. */
1455 /* trim line comment */
1458 while (*p && (*p != '#') && (*p != scc))
1461 while (*p && (*p != '#'))
1465 /* trim trailing whitespace */
1467 while ((q >= s) && ISSPACE(*q))
1471 /* skip leading whitespace */
1473 while (*p && ISSPACE(*p))
1480 if ((len = strlen(opt)) == 0)
1484 if (strncmp(p, opt, len) != 0)
1485 /* line and option do not match */
1488 /* skip over given option name */
1492 /* no option value */
1495 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1496 /* whitespace between option name and value is mandatory
1497 for given option names which do not end with ':' or '=' */
1500 /* skip over whitespace */
1501 while (*p && ISSPACE(*p))
1505 /* no option value */
1508 /* return pointer to option value */
1512 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1513 struct apattern *pat)
1515 struct apattern *newsort;
1516 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1519 newsort[*nsort] = *pat;
1520 *sortlist = newsort;
1525 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1528 /* Four octets and three periods yields at most 15 characters. */
1532 addr->s_addr = inet_addr(ipbuf);
1533 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1538 static void natural_mask(struct apattern *pat)
1540 struct in_addr addr;
1542 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1545 addr.s_addr = ntohl(pat->addrV4.s_addr);
1547 /* This is out of date in the CIDR world, but some people might
1550 if (IN_CLASSA(addr.s_addr))
1551 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1552 else if (IN_CLASSB(addr.s_addr))
1553 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1555 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1557 #endif /* !WIN32 && !WATT32 */
1559 /* initialize an rc4 key. If possible a cryptographically secure random key
1560 is generated using a suitable function (for example win32's RtlGenRandom as
1562 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1563 otherwise the code defaults to cross-platform albeit less secure mechanism
1566 static void randomize_key(unsigned char* key,int key_data_len)
1572 if (ares_fpSystemFunction036)
1574 res = (*ares_fpSystemFunction036) (key, key_data_len);
1580 FILE *f = fopen(RANDOM_FILE, "rb");
1582 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1588 if ( !randomized ) {
1589 for (;counter<key_data_len;counter++)
1590 key[counter]=(unsigned char)(rand() % 256);
1594 static int init_id_key(rc4_key* key,int key_data_len)
1596 unsigned char index1;
1597 unsigned char index2;
1598 unsigned char* state;
1600 unsigned char *key_data_ptr = 0;
1602 key_data_ptr = calloc(1,key_data_len);
1606 state = &key->state[0];
1607 for(counter = 0; counter < 256; counter++)
1608 /* unnecessary AND but it keeps some compilers happier */
1609 state[counter] = (unsigned char)(counter & 0xff);
1610 randomize_key(key->state,key_data_len);
1615 for(counter = 0; counter < 256; counter++)
1617 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1619 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1621 index1 = (unsigned char)((index1 + 1) % key_data_len);
1624 return ARES_SUCCESS;
1627 unsigned short ares__generate_new_id(rc4_key* key)
1630 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1634 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1636 channel->local_ip4 = local_ip;
1639 /* local_ip6 should be 16 bytes in length */
1640 void ares_set_local_ip6(ares_channel channel,
1641 const unsigned char* local_ip6)
1643 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1646 /* local_dev_name should be null terminated. */
1647 void ares_set_local_dev(ares_channel channel,
1648 const char* local_dev_name)
1650 strncpy(channel->local_dev_name, local_dev_name,
1651 sizeof(channel->local_dev_name));
1652 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1656 void ares_set_socket_callback(ares_channel channel,
1657 ares_sock_create_callback cb,
1660 channel->sock_create_cb = cb;
1661 channel->sock_create_cb_data = data;
1664 void ares__init_servers_state(ares_channel channel)
1666 struct server_state *server;
1669 for (i = 0; i < channel->nservers; i++)
1671 server = &channel->servers[i];
1672 server->udp_socket = ARES_SOCKET_BAD;
1673 server->tcp_socket = ARES_SOCKET_BAD;
1674 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1675 server->tcp_lenbuf_pos = 0;
1676 server->tcp_buffer_pos = 0;
1677 server->tcp_buffer = NULL;
1678 server->tcp_length = 0;
1679 server->qhead = NULL;
1680 server->qtail = NULL;
1681 ares__init_list_head(&server->queries_to_server);
1682 server->channel = channel;
1683 server->is_broken = 0;