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, int 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");
133 curl_memlimit(atoi(env));
136 if (ares_library_initialized() != ARES_SUCCESS)
137 return ARES_ENOTINITIALIZED;
139 channel = malloc(sizeof(struct ares_channeldata));
147 /* Set everything to distinguished values so we know they haven't
151 channel->timeout = -1;
154 channel->rotate = -1;
155 channel->udp_port = -1;
156 channel->tcp_port = -1;
157 channel->socket_send_buffer_size = -1;
158 channel->socket_receive_buffer_size = -1;
159 channel->nservers = -1;
160 channel->ndomains = -1;
162 channel->tcp_connection_generation = 0;
163 channel->lookups = NULL;
164 channel->domains = NULL;
165 channel->sortlist = NULL;
166 channel->servers = NULL;
167 channel->sock_state_cb = NULL;
168 channel->sock_state_cb_data = NULL;
169 channel->sock_create_cb = NULL;
170 channel->sock_create_cb_data = NULL;
172 channel->last_server = 0;
173 channel->last_timeout_processed = (time_t)now.tv_sec;
175 /* Initialize our lists of queries */
176 ares__init_list_head(&(channel->all_queries));
177 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
179 ares__init_list_head(&(channel->queries_by_qid[i]));
181 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
183 ares__init_list_head(&(channel->queries_by_timeout[i]));
186 /* Initialize configuration by each of the four sources, from highest
187 * precedence to lowest.
190 if (status == ARES_SUCCESS) {
191 status = init_by_options(channel, options, optmask);
192 if (status != ARES_SUCCESS)
193 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
194 ares_strerror(status)));
196 if (status == ARES_SUCCESS) {
197 status = init_by_environment(channel);
198 if (status != ARES_SUCCESS)
199 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
200 ares_strerror(status)));
202 if (status == ARES_SUCCESS) {
203 status = init_by_resolv_conf(channel);
204 if (status != ARES_SUCCESS)
205 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
206 ares_strerror(status)));
210 * No matter what failed or succeeded, seed defaults to provide
211 * useful behavior for things that we missed.
213 status = init_by_defaults(channel);
214 if (status != ARES_SUCCESS)
215 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
216 ares_strerror(status)));
218 /* Generate random key */
220 if (status == ARES_SUCCESS) {
221 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
222 if (status == ARES_SUCCESS)
223 channel->next_id = ares__generate_new_id(&channel->id_key);
225 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
226 ares_strerror(status)));
229 if (status != ARES_SUCCESS)
231 /* Something failed; clean up memory we may have allocated. */
232 if (channel->servers)
233 free(channel->servers);
234 if (channel->domains)
236 for (i = 0; i < channel->ndomains; i++)
237 free(channel->domains[i]);
238 free(channel->domains);
240 if (channel->sortlist)
241 free(channel->sortlist);
243 free(channel->lookups);
248 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
249 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
250 channel->nservers = 1;
252 ares__init_servers_state(channel);
254 *channelptr = channel;
258 /* ares_dup() duplicates a channel handle with all its options and returns a
259 new channel handle */
260 int ares_dup(ares_channel *dest, ares_channel src)
262 struct ares_options opts;
263 struct ares_addr_node *servers;
264 int ipv6_nservers = 0;
268 *dest = NULL; /* in case of failure return NULL explicitly */
270 /* First get the options supported by the old ares_save_options() function,
271 which is most of them */
272 rc = ares_save_options(src, &opts, &optmask);
276 /* Then create the new channel with those options */
277 rc = ares_init_options(dest, &opts, optmask);
279 /* destroy the options copy to not leak any memory */
280 ares_destroy_options(&opts);
285 /* Now clone the options that ares_save_options() doesn't support. */
286 (*dest)->sock_create_cb = src->sock_create_cb;
287 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
289 /* Full name server cloning required when not all are IPv4 */
290 for (i = 0; i < src->nservers; i++)
292 if (src->servers[i].addr.family != AF_INET) {
298 rc = ares_get_servers(src, &servers);
299 if (rc != ARES_SUCCESS)
301 rc = ares_set_servers(*dest, servers);
302 ares_free_data(servers);
303 if (rc != ARES_SUCCESS)
307 return ARES_SUCCESS; /* everything went fine */
310 /* Save options from initialized channel */
311 int ares_save_options(ares_channel channel, struct ares_options *options,
315 int ipv4_nservers = 0;
317 /* Zero everything out */
318 memset(options, 0, sizeof(struct ares_options));
320 if (!ARES_CONFIG_CHECK(channel))
323 /* Traditionally the optmask wasn't saved in the channel struct so it was
324 recreated here. ROTATE is the first option that has no struct field of
325 its own in the public config struct */
326 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
327 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
328 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
329 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
330 (channel->optmask & ARES_OPT_ROTATE);
332 /* Copy easy stuff */
333 options->flags = channel->flags;
335 /* We return full millisecond resolution but that's only because we don't
336 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
337 options->timeout = channel->timeout;
338 options->tries = channel->tries;
339 options->ndots = channel->ndots;
340 options->udp_port = (unsigned short)channel->udp_port;
341 options->tcp_port = (unsigned short)channel->tcp_port;
342 options->sock_state_cb = channel->sock_state_cb;
343 options->sock_state_cb_data = channel->sock_state_cb_data;
345 /* Copy IPv4 servers */
346 if (channel->nservers) {
347 for (i = 0; i < channel->nservers; i++)
349 if (channel->servers[i].addr.family == AF_INET)
353 options->servers = malloc(ipv4_nservers * sizeof(struct server_state));
354 if (!options->servers)
356 for (i = j = 0; i < channel->nservers; i++)
358 if (channel->servers[i].addr.family == AF_INET)
359 memcpy(&options->servers[j++],
360 &channel->servers[i].addr.addrV4,
361 sizeof(channel->servers[i].addr.addrV4));
365 options->nservers = ipv4_nservers;
368 if (channel->ndomains) {
369 options->domains = malloc(channel->ndomains * sizeof(char *));
370 if (!options->domains)
373 for (i = 0; i < channel->ndomains; i++)
375 options->ndomains = i;
376 options->domains[i] = strdup(channel->domains[i]);
377 if (!options->domains[i])
381 options->ndomains = channel->ndomains;
384 if (channel->lookups) {
385 options->lookups = strdup(channel->lookups);
386 if (!options->lookups && channel->lookups)
391 if (channel->nsort) {
392 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
393 if (!options->sortlist)
395 for (i = 0; i < channel->nsort; i++)
397 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
398 sizeof(struct apattern));
401 options->nsort = channel->nsort;
406 static int init_by_options(ares_channel channel,
407 const struct ares_options *options,
413 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
414 channel->flags = options->flags;
415 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
416 channel->timeout = options->timeout;
417 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
418 channel->timeout = options->timeout * 1000;
419 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
420 channel->tries = options->tries;
421 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
422 channel->ndots = options->ndots;
423 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
425 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
426 channel->udp_port = options->udp_port;
427 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
428 channel->tcp_port = options->tcp_port;
429 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
431 channel->sock_state_cb = options->sock_state_cb;
432 channel->sock_state_cb_data = options->sock_state_cb_data;
434 if ((optmask & ARES_OPT_SOCK_SNDBUF)
435 && channel->socket_send_buffer_size == -1)
436 channel->socket_send_buffer_size = options->socket_send_buffer_size;
437 if ((optmask & ARES_OPT_SOCK_RCVBUF)
438 && channel->socket_receive_buffer_size == -1)
439 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
441 /* Copy the IPv4 servers, if given. */
442 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
444 /* Avoid zero size allocations at any cost */
445 if (options->nservers > 0)
448 malloc(options->nservers * sizeof(struct server_state));
449 if (!channel->servers)
451 for (i = 0; i < options->nservers; i++)
453 channel->servers[i].addr.family = AF_INET;
454 memcpy(&channel->servers[i].addr.addrV4,
455 &options->servers[i],
456 sizeof(channel->servers[i].addr.addrV4));
459 channel->nservers = options->nservers;
462 /* Copy the domains, if given. Keep channel->ndomains consistent so
463 * we can clean up in case of error.
465 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
467 /* Avoid zero size allocations at any cost */
468 if (options->ndomains > 0)
470 channel->domains = malloc(options->ndomains * sizeof(char *));
471 if (!channel->domains)
473 for (i = 0; i < options->ndomains; i++)
475 channel->ndomains = i;
476 channel->domains[i] = strdup(options->domains[i]);
477 if (!channel->domains[i])
481 channel->ndomains = options->ndomains;
484 /* Set lookups, if given. */
485 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
487 channel->lookups = strdup(options->lookups);
488 if (!channel->lookups)
493 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
495 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
496 if (!channel->sortlist)
498 for (i = 0; i < options->nsort; i++)
500 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
501 sizeof(struct apattern));
503 channel->nsort = options->nsort;
506 channel->optmask = optmask;
511 static int init_by_environment(ares_channel channel)
513 const char *localdomain, *res_options;
516 localdomain = getenv("LOCALDOMAIN");
517 if (localdomain && channel->ndomains == -1)
519 status = set_search(channel, localdomain);
520 if (status != ARES_SUCCESS)
524 res_options = getenv("RES_OPTIONS");
527 status = set_options(channel, res_options);
528 if (status != ARES_SUCCESS)
537 * Warning: returns a dynamically allocated buffer, the user MUST
538 * use free() if the function returns 1
540 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
542 /* Test for the size we need */
546 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
547 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
549 *obuf = malloc(size+1);
553 if (RegQueryValueEx(hKey, subkey, 0, NULL,
554 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
567 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
569 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
570 DWORD enum_size = 39;
574 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
575 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
580 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
583 rc = get_res_nt(hVal, subkey, obuf);
591 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
593 FIXED_INFO *fi, *newfi;
594 DWORD size = sizeof (*fi);
595 IP_ADDR_STRING *ipAddr;
598 size_t ip_size = sizeof("255.255.255.255,")-1;
599 size_t left = ret_size;
607 res = (*ares_fpGetNetworkParams) (fi, &size);
608 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
611 newfi = realloc(fi, size);
616 res = (*ares_fpGetNetworkParams) (fi, &size);
617 if (res != ERROR_SUCCESS)
622 printf ("Host Name: %s\n", fi->HostName);
623 printf ("Domain Name: %s\n", fi->DomainName);
624 printf ("DNS Servers:\n"
625 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
627 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
628 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
631 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
632 left -= ret - ret_buf;
636 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
637 ipAddr = ipAddr->Next, i++)
639 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
641 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
642 left -= ret - ret_buf;
646 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
653 if (debug && left <= ip_size)
654 printf ("Too many nameservers. Truncating to %d addressess", count);
661 static int init_by_resolv_conf(ares_channel channel)
666 int status = -1, nservers = 0, nsort = 0;
667 struct server_state *servers = NULL;
668 struct apattern *sortlist = NULL;
673 NameServer info via IPHLPAPI (IP helper API):
674 GetNetworkParams() should be the trusted source for this.
675 Available in Win-98/2000 and later. If that fail, fall-back to
676 registry information.
680 On Windows 9X, the DNS server can be found in:
681 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
683 On Windows NT/2000/XP/2003:
684 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
686 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
688 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
691 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
702 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
705 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
707 status = config_nameserver(&servers, &nservers, buf);
708 if (status == ARES_SUCCESS)
715 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
719 RegOpenKeyEx(mykey, "Interfaces", 0,
720 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
721 if (get_res_nt(mykey, NAMESERVER, &line))
723 status = config_nameserver(&servers, &nservers, line);
726 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
728 status = config_nameserver(&servers, &nservers, line);
731 /* Try the interfaces */
732 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
734 status = config_nameserver(&servers, &nservers, line);
737 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
739 status = config_nameserver(&servers, &nservers, line);
749 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
753 if ((result = RegQueryValueEx(
754 mykey, NAMESERVER, NULL, &data_type,
757 ) == ERROR_SUCCESS ||
758 result == ERROR_MORE_DATA)
762 line = malloc(bytes+1);
763 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
764 (unsigned char *)line, &bytes) ==
767 status = config_nameserver(&servers, &nservers, line);
776 if (status == ARES_SUCCESS)
779 /* Catch the case when all the above checks fail (which happens when there
780 is no network card or the cable is unplugged) */
783 #elif defined(__riscos__)
785 /* Under RISC OS, name servers are listed in the
786 system variable Inet$Resolvers, space separated. */
788 line = getenv("Inet$Resolvers");
791 char *resolvers = strdup(line), *pos, *space;
798 space = strchr(pos, ' ');
801 status = config_nameserver(&servers, &nservers, pos);
802 if (status != ARES_SUCCESS)
807 if (status == ARES_SUCCESS)
813 #elif defined(WATT32)
817 for (i = 0; def_nameservers[i]; i++)
820 return ARES_SUCCESS; /* use localhost DNS server */
823 servers = calloc(i, sizeof(struct server_state));
827 for (i = 0; def_nameservers[i]; i++)
828 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
831 #elif defined(ANDROID)
832 char value[PROP_VALUE_MAX]="";
833 __system_property_get("net.dns1", value);
834 status = config_nameserver(&servers, &nservers, value);
835 if (status == ARES_SUCCESS)
844 /* Don't read resolv.conf and friends if we don't have to */
845 if (ARES_CONFIG_CHECK(channel))
848 fp = fopen(PATH_RESOLV_CONF, "r");
850 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
852 if ((p = try_config(line, "domain")))
853 status = config_domain(channel, p);
854 else if ((p = try_config(line, "lookup")) && !channel->lookups)
855 status = config_lookup(channel, p, "bind", "file");
856 else if ((p = try_config(line, "search")))
857 status = set_search(channel, p);
858 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
859 status = config_nameserver(&servers, &nservers, p);
860 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
861 status = config_sortlist(&sortlist, &nsort, p);
862 else if ((p = try_config(line, "options")))
863 status = set_options(channel, p);
865 status = ARES_SUCCESS;
866 if (status != ARES_SUCCESS)
879 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
880 error, strerror(error)));
881 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
886 if ((status == ARES_EOF) && (!channel->lookups)) {
887 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
888 fp = fopen("/etc/nsswitch.conf", "r");
890 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
892 if ((p = try_config(line, "hosts:")) && !channel->lookups)
893 status = config_lookup(channel, p, "dns", "files");
905 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
906 error, strerror(error)));
907 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
913 if ((status == ARES_EOF) && (!channel->lookups)) {
914 /* Linux / GNU libc 2.x and possibly others have host.conf */
915 fp = fopen("/etc/host.conf", "r");
917 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
919 if ((p = try_config(line, "order")) && !channel->lookups)
920 status = config_lookup(channel, p, "bind", "hosts");
932 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
933 error, strerror(error)));
934 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
940 if ((status == ARES_EOF) && (!channel->lookups)) {
941 /* Tru64 uses /etc/svc.conf */
942 fp = fopen("/etc/svc.conf", "r");
944 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
946 if ((p = try_config(line, "hosts=")) && !channel->lookups)
947 status = config_lookup(channel, p, "bind", "local");
959 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
960 error, strerror(error)));
961 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
974 if (status != ARES_EOF)
978 if (sortlist != NULL)
983 /* If we got any name server entries, fill them in. */
989 channel->servers = servers;
990 channel->nservers = nservers;
993 /* If we got any sortlist entries, fill them in. */
996 channel->sortlist = sortlist;
997 channel->nsort = nsort;
1000 return ARES_SUCCESS;
1003 static int init_by_defaults(ares_channel channel)
1005 char *hostname = NULL;
1006 int rc = ARES_SUCCESS;
1007 #ifdef HAVE_GETHOSTNAME
1011 if (channel->flags == -1)
1013 if (channel->timeout == -1)
1014 channel->timeout = DEFAULT_TIMEOUT;
1015 if (channel->tries == -1)
1016 channel->tries = DEFAULT_TRIES;
1017 if (channel->ndots == -1)
1019 if (channel->rotate == -1)
1020 channel->rotate = 0;
1021 if (channel->udp_port == -1)
1022 channel->udp_port = htons(NAMESERVER_PORT);
1023 if (channel->tcp_port == -1)
1024 channel->tcp_port = htons(NAMESERVER_PORT);
1026 if (channel->nservers == -1) {
1027 /* If nobody specified servers, try a local named. */
1028 channel->servers = malloc(sizeof(struct server_state));
1029 if (!channel->servers) {
1033 channel->servers[0].addr.family = AF_INET;
1034 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1035 channel->nservers = 1;
1039 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1041 #define toolong(x) (x == -1) && (EINVAL == errno)
1044 if (channel->ndomains == -1) {
1045 /* Derive a default domain search list from the kernel hostname,
1046 * or set it to empty if the hostname isn't helpful.
1050 channel->ndomains = 0; /* default to none */
1052 #ifdef HAVE_GETHOSTNAME
1053 hostname = malloc(len);
1060 res = gethostname(hostname, len);
1065 p = realloc(hostname, len);
1080 dot = strchr(hostname, '.');
1082 /* a dot was found */
1083 channel->domains = malloc(sizeof(char *));
1084 if (!channel->domains) {
1088 channel->domains[0] = strdup(dot + 1);
1089 if (!channel->domains[0]) {
1093 channel->ndomains = 1;
1098 if (channel->nsort == -1) {
1099 channel->sortlist = NULL;
1103 if (!channel->lookups) {
1104 channel->lookups = strdup("fb");
1105 if (!channel->lookups)
1111 if(channel->servers)
1112 free(channel->servers);
1114 if(channel->domains && channel->domains[0])
1115 free(channel->domains[0]);
1116 if(channel->domains)
1117 free(channel->domains);
1118 if(channel->lookups)
1119 free(channel->lookups);
1128 #if !defined(WIN32) && !defined(WATT32)
1129 static int config_domain(ares_channel channel, char *str)
1133 /* Set a single search domain. */
1135 while (*q && !ISSPACE(*q))
1138 return set_search(channel, str);
1141 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1142 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1143 /* workaround icc 9.1 optimizer issue */
1144 # define vqualifier volatile
1149 static int config_lookup(ares_channel channel, const char *str,
1150 const char *bindch, const char *filech)
1152 char lookups[3], *l;
1153 const char *vqualifier p;
1155 /* Set the lookup order. Only the first letter of each work
1156 * is relevant, and it has to be "b" for DNS or "f" for the
1157 * host file. Ignore everything else.
1163 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1164 if (*p == *bindch) *l++ = 'b';
1167 while (*p && !ISSPACE(*p) && (*p != ','))
1169 while (*p && (ISSPACE(*p) || (*p == ',')))
1173 channel->lookups = strdup(lookups);
1174 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1176 #endif /* !WIN32 & !WATT32 */
1179 static int config_nameserver(struct server_state **servers, int *nservers,
1182 struct ares_addr host;
1183 struct server_state *newserv;
1185 /* On Windows, there may be more than one nameserver specified in the same
1186 * registry key, so we parse input as a space or comma seperated list.
1190 /* Skip whitespace and commas. */
1191 while (*p && (ISSPACE(*p) || (*p == ',')))
1194 /* No more input, done. */
1197 /* Pointer to start of IPv4 or IPv6 address part. */
1200 /* Advance past this address. */
1201 while (*p && !ISSPACE(*p) && (*p != ','))
1204 /* Null terminate this address. */
1207 /* Reached end of input, done when this address is processed. */
1210 /* Convert textual address to binary format. */
1211 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1212 host.family = AF_INET;
1213 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1214 host.family = AF_INET6;
1218 /* Resize servers state array. */
1219 newserv = realloc(*servers, (*nservers + 1) *
1220 sizeof(struct server_state));
1224 /* Store address data. */
1225 newserv[*nservers].addr.family = host.family;
1226 if (host.family == AF_INET)
1227 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1228 sizeof(host.addrV4));
1230 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1231 sizeof(host.addrV6));
1233 /* Update arguments. */
1238 return ARES_SUCCESS;
1242 static int config_sortlist(struct apattern **sortlist, int *nsort,
1245 struct apattern pat;
1248 /* Add sortlist entries. */
1249 while (*str && *str != ';')
1252 char ipbuf[16], ipbufpfx[32];
1253 /* Find just the IP */
1255 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1257 memcpy(ipbuf, str, (int)(q-str));
1258 ipbuf[(int)(q-str)] = '\0';
1259 /* Find the prefix */
1262 const char *str2 = q+1;
1263 while (*q && *q != ';' && !ISSPACE(*q))
1265 memcpy(ipbufpfx, str, (int)(q-str));
1266 ipbufpfx[(int)(q-str)] = '\0';
1271 /* Lets see if it is CIDR */
1272 /* First we'll try IPv6 */
1273 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1275 sizeof(pat.addrV6))) > 0)
1277 pat.type = PATTERN_CIDR;
1278 pat.mask.bits = (unsigned short)bits;
1279 pat.family = AF_INET6;
1280 if (!sortlist_alloc(sortlist, nsort, &pat))
1284 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1285 sizeof(pat.addrV4))) > 0)
1287 pat.type = PATTERN_CIDR;
1288 pat.mask.bits = (unsigned short)bits;
1289 pat.family = AF_INET;
1290 if (!sortlist_alloc(sortlist, nsort, &pat))
1293 /* See if it is just a regular IP */
1294 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1298 memcpy(ipbuf, str, (int)(q-str));
1299 ipbuf[(int)(q-str)] = '\0';
1300 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1305 pat.family = AF_INET;
1306 pat.type = PATTERN_MASK;
1307 if (!sortlist_alloc(sortlist, nsort, &pat))
1312 while (*q && *q != ';' && !ISSPACE(*q))
1316 while (ISSPACE(*str))
1320 return ARES_SUCCESS;
1323 #endif /* !WATT32 */
1325 static int set_search(ares_channel channel, const char *str)
1330 if(channel->ndomains != -1) {
1331 /* if we already have some domains present, free them first */
1332 for(n=0; n < channel->ndomains; n++)
1333 free(channel->domains[n]);
1334 free(channel->domains);
1335 channel->domains = NULL;
1336 channel->ndomains = -1;
1339 /* Count the domains given. */
1344 while (*p && !ISSPACE(*p))
1353 channel->ndomains = 0;
1354 return ARES_SUCCESS;
1357 channel->domains = malloc(n * sizeof(char *));
1358 if (!channel->domains)
1361 /* Now copy the domains. */
1366 channel->ndomains = n;
1368 while (*q && !ISSPACE(*q))
1370 channel->domains[n] = malloc(q - p + 1);
1371 if (!channel->domains[n])
1373 memcpy(channel->domains[n], p, q - p);
1374 channel->domains[n][q - p] = 0;
1380 channel->ndomains = n;
1382 return ARES_SUCCESS;
1385 static int set_options(ares_channel channel, const char *str)
1387 const char *p, *q, *val;
1393 while (*q && !ISSPACE(*q))
1395 val = try_option(p, q, "ndots:");
1396 if (val && channel->ndots == -1)
1397 channel->ndots = atoi(val);
1398 val = try_option(p, q, "retrans:");
1399 if (val && channel->timeout == -1)
1400 channel->timeout = atoi(val);
1401 val = try_option(p, q, "retry:");
1402 if (val && channel->tries == -1)
1403 channel->tries = atoi(val);
1404 val = try_option(p, q, "rotate");
1405 if (val && channel->rotate == -1)
1406 channel->rotate = 1;
1412 return ARES_SUCCESS;
1415 static const char *try_option(const char *p, const char *q, const char *opt)
1417 size_t len = strlen(opt);
1418 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1421 #if !defined(WIN32) && !defined(WATT32)
1422 static char *try_config(char *s, const char *opt)
1429 /* no line or no option */
1432 /* trim line comment */
1434 while (*p && (*p != '#'))
1438 /* trim trailing whitespace */
1440 while ((q >= s) && ISSPACE(*q))
1444 /* skip leading whitespace */
1446 while (*p && ISSPACE(*p))
1453 if ((len = strlen(opt)) == 0)
1457 if (strncmp(p, opt, len) != 0)
1458 /* line and option do not match */
1461 /* skip over given option name */
1465 /* no option value */
1468 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1469 /* whitespace between option name and value is mandatory
1470 for given option names which do not end with ':' or '=' */
1473 /* skip over whitespace */
1474 while (*p && ISSPACE(*p))
1478 /* no option value */
1481 /* return pointer to option value */
1485 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1486 struct apattern *pat)
1488 struct apattern *newsort;
1489 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1492 newsort[*nsort] = *pat;
1493 *sortlist = newsort;
1498 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1501 /* Four octets and three periods yields at most 15 characters. */
1505 addr->s_addr = inet_addr(ipbuf);
1506 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1511 static void natural_mask(struct apattern *pat)
1513 struct in_addr addr;
1515 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1518 addr.s_addr = ntohl(pat->addrV4.s_addr);
1520 /* This is out of date in the CIDR world, but some people might
1523 if (IN_CLASSA(addr.s_addr))
1524 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1525 else if (IN_CLASSB(addr.s_addr))
1526 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1528 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1530 #endif /* !WIN32 && !WATT32 */
1532 /* initialize an rc4 key. If possible a cryptographically secure random key
1533 is generated using a suitable function (for example win32's RtlGenRandom as
1535 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1536 otherwise the code defaults to cross-platform albeit less secure mechanism
1539 static void randomize_key(unsigned char* key,int key_data_len)
1545 if (ares_fpSystemFunction036)
1547 res = (*ares_fpSystemFunction036) (key, key_data_len);
1553 FILE *f = fopen(RANDOM_FILE, "rb");
1555 counter = fread(key, 1, key_data_len, f);
1561 if ( !randomized ) {
1562 for (;counter<key_data_len;counter++)
1563 key[counter]=(unsigned char)(rand() % 256);
1567 static int init_id_key(rc4_key* key,int key_data_len)
1569 unsigned char index1;
1570 unsigned char index2;
1571 unsigned char* state;
1573 unsigned char *key_data_ptr = 0;
1575 key_data_ptr = calloc(1,key_data_len);
1579 state = &key->state[0];
1580 for(counter = 0; counter < 256; counter++)
1581 /* unnecessary AND but it keeps some compilers happier */
1582 state[counter] = (unsigned char)(counter & 0xff);
1583 randomize_key(key->state,key_data_len);
1588 for(counter = 0; counter < 256; counter++)
1590 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1592 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1594 index1 = (unsigned char)((index1 + 1) % key_data_len);
1597 return ARES_SUCCESS;
1600 unsigned short ares__generate_new_id(rc4_key* key)
1603 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1607 void ares_set_socket_callback(ares_channel channel,
1608 ares_sock_create_callback cb,
1611 channel->sock_create_cb = cb;
1612 channel->sock_create_cb_data = data;
1615 void ares__init_servers_state(ares_channel channel)
1617 struct server_state *server;
1620 for (i = 0; i < channel->nservers; i++)
1622 server = &channel->servers[i];
1623 server->udp_socket = ARES_SOCKET_BAD;
1624 server->tcp_socket = ARES_SOCKET_BAD;
1625 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1626 server->tcp_lenbuf_pos = 0;
1627 server->tcp_buffer_pos = 0;
1628 server->tcp_buffer = NULL;
1629 server->tcp_length = 0;
1630 server->qhead = NULL;
1631 server->qtail = NULL;
1632 ares__init_list_head(&server->queries_to_server);
1633 server->channel = channel;
1634 server->is_broken = 0;