2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Copyright (C) 2007-2010 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>
68 #include "inet_net_pton.h"
69 #include "ares_library_init.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);
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++)
834 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
837 #elif defined(ANDROID)
838 char value[PROP_VALUE_MAX]="";
839 __system_property_get("net.dns1", value);
840 status = config_nameserver(&servers, &nservers, value);
841 if (status == ARES_SUCCESS)
850 /* Don't read resolv.conf and friends if we don't have to */
851 if (ARES_CONFIG_CHECK(channel))
854 fp = fopen(PATH_RESOLV_CONF, "r");
856 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
858 if ((p = try_config(line, "domain")))
859 status = config_domain(channel, p);
860 else if ((p = try_config(line, "lookup")) && !channel->lookups)
861 status = config_lookup(channel, p, "bind", "file");
862 else if ((p = try_config(line, "search")))
863 status = set_search(channel, p);
864 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
865 status = config_nameserver(&servers, &nservers, p);
866 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
867 status = config_sortlist(&sortlist, &nsort, p);
868 else if ((p = try_config(line, "options")))
869 status = set_options(channel, p);
871 status = ARES_SUCCESS;
872 if (status != ARES_SUCCESS)
885 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
886 error, strerror(error)));
887 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
892 if ((status == ARES_EOF) && (!channel->lookups)) {
893 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
894 fp = fopen("/etc/nsswitch.conf", "r");
896 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
898 if ((p = try_config(line, "hosts:")) && !channel->lookups)
899 status = config_lookup(channel, p, "dns", "files");
911 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
912 error, strerror(error)));
913 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
919 if ((status == ARES_EOF) && (!channel->lookups)) {
920 /* Linux / GNU libc 2.x and possibly others have host.conf */
921 fp = fopen("/etc/host.conf", "r");
923 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
925 if ((p = try_config(line, "order")) && !channel->lookups)
926 status = config_lookup(channel, p, "bind", "hosts");
938 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
939 error, strerror(error)));
940 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
946 if ((status == ARES_EOF) && (!channel->lookups)) {
947 /* Tru64 uses /etc/svc.conf */
948 fp = fopen("/etc/svc.conf", "r");
950 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
952 if ((p = try_config(line, "hosts=")) && !channel->lookups)
953 status = config_lookup(channel, p, "bind", "local");
965 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
966 error, strerror(error)));
967 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
980 if (status != ARES_EOF)
984 if (sortlist != NULL)
989 /* If we got any name server entries, fill them in. */
995 channel->servers = servers;
996 channel->nservers = nservers;
999 /* If we got any sortlist entries, fill them in. */
1002 channel->sortlist = sortlist;
1003 channel->nsort = nsort;
1006 return ARES_SUCCESS;
1009 static int init_by_defaults(ares_channel channel)
1011 char *hostname = NULL;
1012 int rc = ARES_SUCCESS;
1013 #ifdef HAVE_GETHOSTNAME
1017 if (channel->flags == -1)
1019 if (channel->timeout == -1)
1020 channel->timeout = DEFAULT_TIMEOUT;
1021 if (channel->tries == -1)
1022 channel->tries = DEFAULT_TRIES;
1023 if (channel->ndots == -1)
1025 if (channel->rotate == -1)
1026 channel->rotate = 0;
1027 if (channel->udp_port == -1)
1028 channel->udp_port = htons(NAMESERVER_PORT);
1029 if (channel->tcp_port == -1)
1030 channel->tcp_port = htons(NAMESERVER_PORT);
1032 if (channel->nservers == -1) {
1033 /* If nobody specified servers, try a local named. */
1034 channel->servers = malloc(sizeof(struct server_state));
1035 if (!channel->servers) {
1039 channel->servers[0].addr.family = AF_INET;
1040 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1041 channel->nservers = 1;
1045 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1047 #define toolong(x) (x == -1) && (EINVAL == errno)
1050 if (channel->ndomains == -1) {
1051 /* Derive a default domain search list from the kernel hostname,
1052 * or set it to empty if the hostname isn't helpful.
1056 channel->ndomains = 0; /* default to none */
1058 #ifdef HAVE_GETHOSTNAME
1059 hostname = malloc(len);
1066 res = gethostname(hostname, len);
1071 p = realloc(hostname, len);
1086 dot = strchr(hostname, '.');
1088 /* a dot was found */
1089 channel->domains = malloc(sizeof(char *));
1090 if (!channel->domains) {
1094 channel->domains[0] = strdup(dot + 1);
1095 if (!channel->domains[0]) {
1099 channel->ndomains = 1;
1104 if (channel->nsort == -1) {
1105 channel->sortlist = NULL;
1109 if (!channel->lookups) {
1110 channel->lookups = strdup("fb");
1111 if (!channel->lookups)
1117 if(channel->servers)
1118 free(channel->servers);
1120 if(channel->domains && channel->domains[0])
1121 free(channel->domains[0]);
1122 if(channel->domains)
1123 free(channel->domains);
1124 if(channel->lookups)
1125 free(channel->lookups);
1134 #if !defined(WIN32) && !defined(WATT32)
1135 static int config_domain(ares_channel channel, char *str)
1139 /* Set a single search domain. */
1141 while (*q && !ISSPACE(*q))
1144 return set_search(channel, str);
1147 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1148 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1149 /* workaround icc 9.1 optimizer issue */
1150 # define vqualifier volatile
1155 static int config_lookup(ares_channel channel, const char *str,
1156 const char *bindch, const char *filech)
1158 char lookups[3], *l;
1159 const char *vqualifier p;
1161 /* Set the lookup order. Only the first letter of each work
1162 * is relevant, and it has to be "b" for DNS or "f" for the
1163 * host file. Ignore everything else.
1169 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1170 if (*p == *bindch) *l++ = 'b';
1173 while (*p && !ISSPACE(*p) && (*p != ','))
1175 while (*p && (ISSPACE(*p) || (*p == ',')))
1179 channel->lookups = strdup(lookups);
1180 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1182 #endif /* !WIN32 & !WATT32 */
1185 static int config_nameserver(struct server_state **servers, int *nservers,
1188 struct ares_addr host;
1189 struct server_state *newserv;
1191 /* On Windows, there may be more than one nameserver specified in the same
1192 * registry key, so we parse input as a space or comma seperated list.
1196 /* Skip whitespace and commas. */
1197 while (*p && (ISSPACE(*p) || (*p == ',')))
1200 /* No more input, done. */
1203 /* Pointer to start of IPv4 or IPv6 address part. */
1206 /* Advance past this address. */
1207 while (*p && !ISSPACE(*p) && (*p != ','))
1210 /* Null terminate this address. */
1213 /* Reached end of input, done when this address is processed. */
1216 /* Convert textual address to binary format. */
1217 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1218 host.family = AF_INET;
1219 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1220 host.family = AF_INET6;
1224 /* Resize servers state array. */
1225 newserv = realloc(*servers, (*nservers + 1) *
1226 sizeof(struct server_state));
1230 /* Store address data. */
1231 newserv[*nservers].addr.family = host.family;
1232 if (host.family == AF_INET)
1233 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1234 sizeof(host.addrV4));
1236 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1237 sizeof(host.addrV6));
1239 /* Update arguments. */
1244 return ARES_SUCCESS;
1248 static int config_sortlist(struct apattern **sortlist, int *nsort,
1251 struct apattern pat;
1254 /* Add sortlist entries. */
1255 while (*str && *str != ';')
1258 char ipbuf[16], ipbufpfx[32];
1259 /* Find just the IP */
1261 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1263 memcpy(ipbuf, str, q-str);
1264 ipbuf[q-str] = '\0';
1265 /* Find the prefix */
1268 const char *str2 = q+1;
1269 while (*q && *q != ';' && !ISSPACE(*q))
1271 memcpy(ipbufpfx, str, q-str);
1272 ipbufpfx[q-str] = '\0';
1277 /* Lets see if it is CIDR */
1278 /* First we'll try IPv6 */
1279 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1281 sizeof(pat.addrV6))) > 0)
1283 pat.type = PATTERN_CIDR;
1284 pat.mask.bits = (unsigned short)bits;
1285 pat.family = AF_INET6;
1286 if (!sortlist_alloc(sortlist, nsort, &pat))
1290 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1291 sizeof(pat.addrV4))) > 0)
1293 pat.type = PATTERN_CIDR;
1294 pat.mask.bits = (unsigned short)bits;
1295 pat.family = AF_INET;
1296 if (!sortlist_alloc(sortlist, nsort, &pat))
1299 /* See if it is just a regular IP */
1300 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1304 memcpy(ipbuf, str, q-str);
1305 ipbuf[q-str] = '\0';
1306 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1311 pat.family = AF_INET;
1312 pat.type = PATTERN_MASK;
1313 if (!sortlist_alloc(sortlist, nsort, &pat))
1318 while (*q && *q != ';' && !ISSPACE(*q))
1322 while (ISSPACE(*str))
1326 return ARES_SUCCESS;
1329 #endif /* !WATT32 */
1331 static int set_search(ares_channel channel, const char *str)
1336 if(channel->ndomains != -1) {
1337 /* if we already have some domains present, free them first */
1338 for(n=0; n < channel->ndomains; n++)
1339 free(channel->domains[n]);
1340 free(channel->domains);
1341 channel->domains = NULL;
1342 channel->ndomains = -1;
1345 /* Count the domains given. */
1350 while (*p && !ISSPACE(*p))
1359 channel->ndomains = 0;
1360 return ARES_SUCCESS;
1363 channel->domains = malloc(n * sizeof(char *));
1364 if (!channel->domains)
1367 /* Now copy the domains. */
1372 channel->ndomains = n;
1374 while (*q && !ISSPACE(*q))
1376 channel->domains[n] = malloc(q - p + 1);
1377 if (!channel->domains[n])
1379 memcpy(channel->domains[n], p, q - p);
1380 channel->domains[n][q - p] = 0;
1386 channel->ndomains = n;
1388 return ARES_SUCCESS;
1391 static int set_options(ares_channel channel, const char *str)
1393 const char *p, *q, *val;
1399 while (*q && !ISSPACE(*q))
1401 val = try_option(p, q, "ndots:");
1402 if (val && channel->ndots == -1)
1403 channel->ndots = (int)strtol(val, NULL, 10);
1404 val = try_option(p, q, "retrans:");
1405 if (val && channel->timeout == -1)
1406 channel->timeout = (int)strtol(val, NULL, 10);
1407 val = try_option(p, q, "retry:");
1408 if (val && channel->tries == -1)
1409 channel->tries = (int)strtol(val, NULL, 10);
1410 val = try_option(p, q, "rotate");
1411 if (val && channel->rotate == -1)
1412 channel->rotate = 1;
1418 return ARES_SUCCESS;
1421 static const char *try_option(const char *p, const char *q, const char *opt)
1423 size_t len = strlen(opt);
1424 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1427 #if !defined(WIN32) && !defined(WATT32)
1428 static char *try_config(char *s, const char *opt)
1435 /* no line or no option */
1438 /* trim line comment */
1440 while (*p && (*p != '#'))
1444 /* trim trailing whitespace */
1446 while ((q >= s) && ISSPACE(*q))
1450 /* skip leading whitespace */
1452 while (*p && ISSPACE(*p))
1459 if ((len = strlen(opt)) == 0)
1463 if (strncmp(p, opt, len) != 0)
1464 /* line and option do not match */
1467 /* skip over given option name */
1471 /* no option value */
1474 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1475 /* whitespace between option name and value is mandatory
1476 for given option names which do not end with ':' or '=' */
1479 /* skip over whitespace */
1480 while (*p && ISSPACE(*p))
1484 /* no option value */
1487 /* return pointer to option value */
1491 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1492 struct apattern *pat)
1494 struct apattern *newsort;
1495 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1498 newsort[*nsort] = *pat;
1499 *sortlist = newsort;
1504 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1507 /* Four octets and three periods yields at most 15 characters. */
1511 addr->s_addr = inet_addr(ipbuf);
1512 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1517 static void natural_mask(struct apattern *pat)
1519 struct in_addr addr;
1521 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1524 addr.s_addr = ntohl(pat->addrV4.s_addr);
1526 /* This is out of date in the CIDR world, but some people might
1529 if (IN_CLASSA(addr.s_addr))
1530 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1531 else if (IN_CLASSB(addr.s_addr))
1532 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1534 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1536 #endif /* !WIN32 && !WATT32 */
1538 /* initialize an rc4 key. If possible a cryptographically secure random key
1539 is generated using a suitable function (for example win32's RtlGenRandom as
1541 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1542 otherwise the code defaults to cross-platform albeit less secure mechanism
1545 static void randomize_key(unsigned char* key,int key_data_len)
1551 if (ares_fpSystemFunction036)
1553 res = (*ares_fpSystemFunction036) (key, key_data_len);
1559 FILE *f = fopen(RANDOM_FILE, "rb");
1561 counter = fread(key, 1, key_data_len, f);
1567 if ( !randomized ) {
1568 for (;counter<key_data_len;counter++)
1569 key[counter]=(unsigned char)(rand() % 256);
1573 static int init_id_key(rc4_key* key,int key_data_len)
1575 unsigned char index1;
1576 unsigned char index2;
1577 unsigned char* state;
1579 unsigned char *key_data_ptr = 0;
1581 key_data_ptr = calloc(1,key_data_len);
1585 state = &key->state[0];
1586 for(counter = 0; counter < 256; counter++)
1587 /* unnecessary AND but it keeps some compilers happier */
1588 state[counter] = (unsigned char)(counter & 0xff);
1589 randomize_key(key->state,key_data_len);
1594 for(counter = 0; counter < 256; counter++)
1596 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1598 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1600 index1 = (unsigned char)((index1 + 1) % key_data_len);
1603 return ARES_SUCCESS;
1606 unsigned short ares__generate_new_id(rc4_key* key)
1609 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1613 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1615 channel->local_ip4 = local_ip;
1618 /* local_ip6 should be 16 bytes in length */
1619 void ares_set_local_ip6(ares_channel channel,
1620 const unsigned char* local_ip6)
1622 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1625 /* local_dev_name should be null terminated. */
1626 void ares_set_local_dev(ares_channel channel,
1627 const char* local_dev_name)
1629 strncpy(channel->local_dev_name, local_dev_name,
1630 sizeof(channel->local_dev_name));
1631 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1635 void ares_set_socket_callback(ares_channel channel,
1636 ares_sock_create_callback cb,
1639 channel->sock_create_cb = cb;
1640 channel->sock_create_cb_data = data;
1643 void ares__init_servers_state(ares_channel channel)
1645 struct server_state *server;
1648 for (i = 0; i < channel->nservers; i++)
1650 server = &channel->servers[i];
1651 server->udp_socket = ARES_SOCKET_BAD;
1652 server->tcp_socket = ARES_SOCKET_BAD;
1653 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1654 server->tcp_lenbuf_pos = 0;
1655 server->tcp_buffer_pos = 0;
1656 server->tcp_buffer = NULL;
1657 server->tcp_length = 0;
1658 server->qhead = NULL;
1659 server->qtail = NULL;
1660 ares__init_list_head(&server->queries_to_server);
1661 server->channel = channel;
1662 server->is_broken = 0;