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 #undef WIN32 /* Redefined in MingW/MSVC headers */
76 static int init_by_options(ares_channel channel, const struct ares_options *options,
78 static int init_by_environment(ares_channel channel);
79 static int init_by_resolv_conf(ares_channel channel);
80 static int init_by_defaults(ares_channel channel);
83 static int config_nameserver(struct server_state **servers, int *nservers,
86 static int set_search(ares_channel channel, const char *str);
87 static int set_options(ares_channel channel, const char *str);
88 static const char *try_option(const char *p, const char *q, const char *opt);
89 static int init_id_key(rc4_key* key,int key_data_len);
91 #if !defined(WIN32) && !defined(WATT32)
92 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
93 static int ip_addr(const char *s, int len, struct in_addr *addr);
94 static void natural_mask(struct apattern *pat);
95 static int config_domain(ares_channel channel, char *str);
96 static int config_lookup(ares_channel channel, const char *str,
97 const char *bindch, const char *filech);
98 static int config_sortlist(struct apattern **sortlist, int *nsort,
100 static char *try_config(char *s, const char *opt);
103 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
104 x->nservers > -1 && \
105 x->ndomains > -1 && \
106 x->ndots > -1 && x->timeout > -1 && \
109 int ares_init(ares_channel *channelptr)
111 return ares_init_options(channelptr, NULL, 0);
114 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
117 ares_channel channel;
119 int status = ARES_SUCCESS;
123 const char *env = getenv("CARES_MEMDEBUG");
127 env = getenv("CARES_MEMLIMIT");
129 curl_memlimit(atoi(env));
132 if (ares_library_initialized() != ARES_SUCCESS)
133 return ARES_ENOTINITIALIZED;
135 channel = malloc(sizeof(struct ares_channeldata));
143 /* Set everything to distinguished values so we know they haven't
147 channel->timeout = -1;
150 channel->rotate = -1;
151 channel->udp_port = -1;
152 channel->tcp_port = -1;
153 channel->socket_send_buffer_size = -1;
154 channel->socket_receive_buffer_size = -1;
155 channel->nservers = -1;
156 channel->ndomains = -1;
158 channel->tcp_connection_generation = 0;
159 channel->lookups = NULL;
160 channel->domains = NULL;
161 channel->sortlist = NULL;
162 channel->servers = NULL;
163 channel->sock_state_cb = NULL;
164 channel->sock_state_cb_data = NULL;
165 channel->sock_create_cb = NULL;
166 channel->sock_create_cb_data = NULL;
168 channel->last_server = 0;
169 channel->last_timeout_processed = (time_t)now.tv_sec;
171 /* Initialize our lists of queries */
172 ares__init_list_head(&(channel->all_queries));
173 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
175 ares__init_list_head(&(channel->queries_by_qid[i]));
177 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
179 ares__init_list_head(&(channel->queries_by_timeout[i]));
182 /* Initialize configuration by each of the four sources, from highest
183 * precedence to lowest.
186 if (status == ARES_SUCCESS) {
187 status = init_by_options(channel, options, optmask);
188 if (status != ARES_SUCCESS)
189 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
190 ares_strerror(status)));
192 if (status == ARES_SUCCESS) {
193 status = init_by_environment(channel);
194 if (status != ARES_SUCCESS)
195 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
196 ares_strerror(status)));
198 if (status == ARES_SUCCESS) {
199 status = init_by_resolv_conf(channel);
200 if (status != ARES_SUCCESS)
201 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
202 ares_strerror(status)));
206 * No matter what failed or succeeded, seed defaults to provide
207 * useful behavior for things that we missed.
209 status = init_by_defaults(channel);
210 if (status != ARES_SUCCESS)
211 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
212 ares_strerror(status)));
214 /* Generate random key */
216 if (status == ARES_SUCCESS) {
217 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
218 if (status == ARES_SUCCESS)
219 channel->next_id = ares__generate_new_id(&channel->id_key);
221 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
222 ares_strerror(status)));
225 if (status != ARES_SUCCESS)
227 /* Something failed; clean up memory we may have allocated. */
228 if (channel->servers)
229 free(channel->servers);
230 if (channel->domains)
232 for (i = 0; i < channel->ndomains; i++)
233 free(channel->domains[i]);
234 free(channel->domains);
236 if (channel->sortlist)
237 free(channel->sortlist);
239 free(channel->lookups);
244 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
245 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
246 channel->nservers = 1;
248 ares__init_servers_state(channel);
250 *channelptr = channel;
254 /* ares_dup() duplicates a channel handle with all its options and returns a
255 new channel handle */
256 int ares_dup(ares_channel *dest, ares_channel src)
258 struct ares_options opts;
259 struct ares_addr_node *servers;
260 int ipv6_nservers = 0;
264 *dest = NULL; /* in case of failure return NULL explicitly */
266 /* First get the options supported by the old ares_save_options() function,
267 which is most of them */
268 rc = ares_save_options(src, &opts, &optmask);
272 /* Then create the new channel with those options */
273 rc = ares_init_options(dest, &opts, optmask);
275 /* destroy the options copy to not leak any memory */
276 ares_destroy_options(&opts);
281 /* Now clone the options that ares_save_options() doesn't support. */
282 (*dest)->sock_create_cb = src->sock_create_cb;
283 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
285 /* Full name server cloning required when not all are IPv4 */
286 for (i = 0; i < src->nservers; i++)
288 if (src->servers[i].addr.family != AF_INET) {
294 rc = ares_get_servers(src, &servers);
295 if (rc != ARES_SUCCESS)
297 rc = ares_set_servers(*dest, servers);
298 ares_free_data(servers);
299 if (rc != ARES_SUCCESS)
303 return ARES_SUCCESS; /* everything went fine */
306 /* Save options from initialized channel */
307 int ares_save_options(ares_channel channel, struct ares_options *options,
311 int ipv4_nservers = 0;
313 /* Zero everything out */
314 memset(options, 0, sizeof(struct ares_options));
316 if (!ARES_CONFIG_CHECK(channel))
319 /* Traditionally the optmask wasn't saved in the channel struct so it was
320 recreated here. ROTATE is the first option that has no struct field of
321 its own in the public config struct */
322 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
323 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
324 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
325 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
326 (channel->optmask & ARES_OPT_ROTATE);
328 /* Copy easy stuff */
329 options->flags = channel->flags;
331 /* We return full millisecond resolution but that's only because we don't
332 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
333 options->timeout = channel->timeout;
334 options->tries = channel->tries;
335 options->ndots = channel->ndots;
336 options->udp_port = (unsigned short)channel->udp_port;
337 options->tcp_port = (unsigned short)channel->tcp_port;
338 options->sock_state_cb = channel->sock_state_cb;
339 options->sock_state_cb_data = channel->sock_state_cb_data;
341 /* Copy IPv4 servers */
342 if (channel->nservers) {
343 for (i = 0; i < channel->nservers; i++)
345 if (channel->servers[i].addr.family == AF_INET)
349 options->servers = malloc(ipv4_nservers * sizeof(struct server_state));
350 if (!options->servers)
352 for (i = j = 0; i < channel->nservers; i++)
354 if (channel->servers[i].addr.family == AF_INET)
355 memcpy(&options->servers[j++],
356 &channel->servers[i].addr.addrV4,
357 sizeof(channel->servers[i].addr.addrV4));
361 options->nservers = ipv4_nservers;
364 if (channel->ndomains) {
365 options->domains = malloc(channel->ndomains * sizeof(char *));
366 if (!options->domains)
369 for (i = 0; i < channel->ndomains; i++)
371 options->ndomains = i;
372 options->domains[i] = strdup(channel->domains[i]);
373 if (!options->domains[i])
377 options->ndomains = channel->ndomains;
380 if (channel->lookups) {
381 options->lookups = strdup(channel->lookups);
382 if (!options->lookups && channel->lookups)
387 if (channel->nsort) {
388 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
389 if (!options->sortlist)
391 for (i = 0; i < channel->nsort; i++)
393 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
394 sizeof(struct apattern));
397 options->nsort = channel->nsort;
402 static int init_by_options(ares_channel channel,
403 const struct ares_options *options,
409 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
410 channel->flags = options->flags;
411 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
412 channel->timeout = options->timeout;
413 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
414 channel->timeout = options->timeout * 1000;
415 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
416 channel->tries = options->tries;
417 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
418 channel->ndots = options->ndots;
419 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
421 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
422 channel->udp_port = options->udp_port;
423 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
424 channel->tcp_port = options->tcp_port;
425 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
427 channel->sock_state_cb = options->sock_state_cb;
428 channel->sock_state_cb_data = options->sock_state_cb_data;
430 if ((optmask & ARES_OPT_SOCK_SNDBUF)
431 && channel->socket_send_buffer_size == -1)
432 channel->socket_send_buffer_size = options->socket_send_buffer_size;
433 if ((optmask & ARES_OPT_SOCK_RCVBUF)
434 && channel->socket_receive_buffer_size == -1)
435 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
437 /* Copy the IPv4 servers, if given. */
438 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
440 /* Avoid zero size allocations at any cost */
441 if (options->nservers > 0)
444 malloc(options->nservers * sizeof(struct server_state));
445 if (!channel->servers)
447 for (i = 0; i < options->nservers; i++)
449 channel->servers[i].addr.family = AF_INET;
450 memcpy(&channel->servers[i].addr.addrV4,
451 &options->servers[i],
452 sizeof(channel->servers[i].addr.addrV4));
455 channel->nservers = options->nservers;
458 /* Copy the domains, if given. Keep channel->ndomains consistent so
459 * we can clean up in case of error.
461 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
463 /* Avoid zero size allocations at any cost */
464 if (options->ndomains > 0)
466 channel->domains = malloc(options->ndomains * sizeof(char *));
467 if (!channel->domains)
469 for (i = 0; i < options->ndomains; i++)
471 channel->ndomains = i;
472 channel->domains[i] = strdup(options->domains[i]);
473 if (!channel->domains[i])
477 channel->ndomains = options->ndomains;
480 /* Set lookups, if given. */
481 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
483 channel->lookups = strdup(options->lookups);
484 if (!channel->lookups)
489 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
491 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
492 if (!channel->sortlist)
494 for (i = 0; i < options->nsort; i++)
496 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
497 sizeof(struct apattern));
499 channel->nsort = options->nsort;
502 channel->optmask = optmask;
507 static int init_by_environment(ares_channel channel)
509 const char *localdomain, *res_options;
512 localdomain = getenv("LOCALDOMAIN");
513 if (localdomain && channel->ndomains == -1)
515 status = set_search(channel, localdomain);
516 if (status != ARES_SUCCESS)
520 res_options = getenv("RES_OPTIONS");
523 status = set_options(channel, res_options);
524 if (status != ARES_SUCCESS)
533 * Warning: returns a dynamically allocated buffer, the user MUST
534 * use free() if the function returns 1
536 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
538 /* Test for the size we need */
542 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
543 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
545 *obuf = malloc(size+1);
549 if (RegQueryValueEx(hKey, subkey, 0, NULL,
550 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
563 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
565 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
566 DWORD enum_size = 39;
570 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
571 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
576 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
579 rc = get_res_nt(hVal, subkey, obuf);
587 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
589 FIXED_INFO *fi, *newfi;
590 DWORD size = sizeof (*fi);
591 IP_ADDR_STRING *ipAddr;
594 size_t ip_size = sizeof("255.255.255.255,")-1;
595 size_t left = ret_size;
603 res = (*ares_fpGetNetworkParams) (fi, &size);
604 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
607 newfi = realloc(fi, size);
612 res = (*ares_fpGetNetworkParams) (fi, &size);
613 if (res != ERROR_SUCCESS)
618 printf ("Host Name: %s\n", fi->HostName);
619 printf ("Domain Name: %s\n", fi->DomainName);
620 printf ("DNS Servers:\n"
621 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
623 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
624 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
627 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
628 left -= ret - ret_buf;
632 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
633 ipAddr = ipAddr->Next, i++)
635 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
637 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
638 left -= ret - ret_buf;
642 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
649 if (debug && left <= ip_size)
650 printf ("Too many nameservers. Truncating to %d addressess", count);
657 static int init_by_resolv_conf(ares_channel channel)
662 int status = -1, nservers = 0, nsort = 0;
663 struct server_state *servers = NULL;
664 struct apattern *sortlist = NULL;
669 NameServer info via IPHLPAPI (IP helper API):
670 GetNetworkParams() should be the trusted source for this.
671 Available in Win-98/2000 and later. If that fail, fall-back to
672 registry information.
676 On Windows 9X, the DNS server can be found in:
677 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
679 On Windows NT/2000/XP/2003:
680 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
682 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
684 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
687 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
698 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
701 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
703 status = config_nameserver(&servers, &nservers, buf);
704 if (status == ARES_SUCCESS)
711 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
715 RegOpenKeyEx(mykey, "Interfaces", 0,
716 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
717 if (get_res_nt(mykey, NAMESERVER, &line))
719 status = config_nameserver(&servers, &nservers, line);
722 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
724 status = config_nameserver(&servers, &nservers, line);
727 /* Try the interfaces */
728 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
730 status = config_nameserver(&servers, &nservers, line);
733 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
735 status = config_nameserver(&servers, &nservers, line);
745 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
749 if ((result = RegQueryValueEx(
750 mykey, NAMESERVER, NULL, &data_type,
753 ) == ERROR_SUCCESS ||
754 result == ERROR_MORE_DATA)
758 line = malloc(bytes+1);
759 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
760 (unsigned char *)line, &bytes) ==
763 status = config_nameserver(&servers, &nservers, line);
772 if (status == ARES_SUCCESS)
775 /* Catch the case when all the above checks fail (which happens when there
776 is no network card or the cable is unplugged) */
779 #elif defined(__riscos__)
781 /* Under RISC OS, name servers are listed in the
782 system variable Inet$Resolvers, space separated. */
784 line = getenv("Inet$Resolvers");
787 char *resolvers = strdup(line), *pos, *space;
794 space = strchr(pos, ' ');
797 status = config_nameserver(&servers, &nservers, pos);
798 if (status != ARES_SUCCESS)
803 if (status == ARES_SUCCESS)
809 #elif defined(WATT32)
813 for (i = 0; def_nameservers[i]; i++)
816 return ARES_SUCCESS; /* use localhost DNS server */
819 servers = calloc(i, sizeof(struct server_state));
823 for (i = 0; def_nameservers[i]; i++)
824 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
834 /* Don't read resolv.conf and friends if we don't have to */
835 if (ARES_CONFIG_CHECK(channel))
838 fp = fopen(PATH_RESOLV_CONF, "r");
840 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
842 if ((p = try_config(line, "domain")))
843 status = config_domain(channel, p);
844 else if ((p = try_config(line, "lookup")) && !channel->lookups)
845 status = config_lookup(channel, p, "bind", "file");
846 else if ((p = try_config(line, "search")))
847 status = set_search(channel, p);
848 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
849 status = config_nameserver(&servers, &nservers, p);
850 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
851 status = config_sortlist(&sortlist, &nsort, p);
852 else if ((p = try_config(line, "options")))
853 status = set_options(channel, p);
855 status = ARES_SUCCESS;
856 if (status != ARES_SUCCESS)
869 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
870 error, strerror(error)));
871 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
876 if ((status == ARES_EOF) && (!channel->lookups)) {
877 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
878 fp = fopen("/etc/nsswitch.conf", "r");
880 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
882 if ((p = try_config(line, "hosts:")) && !channel->lookups)
883 status = config_lookup(channel, p, "dns", "files");
895 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
896 error, strerror(error)));
897 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
903 if ((status == ARES_EOF) && (!channel->lookups)) {
904 /* Linux / GNU libc 2.x and possibly others have host.conf */
905 fp = fopen("/etc/host.conf", "r");
907 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
909 if ((p = try_config(line, "order")) && !channel->lookups)
910 status = config_lookup(channel, p, "bind", "hosts");
922 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
923 error, strerror(error)));
924 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
930 if ((status == ARES_EOF) && (!channel->lookups)) {
931 /* Tru64 uses /etc/svc.conf */
932 fp = fopen("/etc/svc.conf", "r");
934 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
936 if ((p = try_config(line, "hosts=")) && !channel->lookups)
937 status = config_lookup(channel, p, "bind", "local");
949 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
950 error, strerror(error)));
951 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
964 if (status != ARES_EOF)
968 if (sortlist != NULL)
973 /* If we got any name server entries, fill them in. */
979 channel->servers = servers;
980 channel->nservers = nservers;
983 /* If we got any sortlist entries, fill them in. */
986 channel->sortlist = sortlist;
987 channel->nsort = nsort;
993 static int init_by_defaults(ares_channel channel)
995 char *hostname = NULL;
996 int rc = ARES_SUCCESS;
997 #ifdef HAVE_GETHOSTNAME
1001 if (channel->flags == -1)
1003 if (channel->timeout == -1)
1004 channel->timeout = DEFAULT_TIMEOUT;
1005 if (channel->tries == -1)
1006 channel->tries = DEFAULT_TRIES;
1007 if (channel->ndots == -1)
1009 if (channel->rotate == -1)
1010 channel->rotate = 0;
1011 if (channel->udp_port == -1)
1012 channel->udp_port = htons(NAMESERVER_PORT);
1013 if (channel->tcp_port == -1)
1014 channel->tcp_port = htons(NAMESERVER_PORT);
1016 if (channel->nservers == -1) {
1017 /* If nobody specified servers, try a local named. */
1018 channel->servers = malloc(sizeof(struct server_state));
1019 if (!channel->servers) {
1023 channel->servers[0].addr.family = AF_INET;
1024 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1025 channel->nservers = 1;
1029 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1031 #define toolong(x) (x == -1) && (EINVAL == errno)
1034 if (channel->ndomains == -1) {
1035 /* Derive a default domain search list from the kernel hostname,
1036 * or set it to empty if the hostname isn't helpful.
1040 channel->ndomains = 0; /* default to none */
1042 #ifdef HAVE_GETHOSTNAME
1043 hostname = malloc(len);
1050 res = gethostname(hostname, len);
1055 p = realloc(hostname, len);
1070 dot = strchr(hostname, '.');
1072 /* a dot was found */
1073 channel->domains = malloc(sizeof(char *));
1074 if (!channel->domains) {
1078 channel->domains[0] = strdup(dot + 1);
1079 if (!channel->domains[0]) {
1083 channel->ndomains = 1;
1088 if (channel->nsort == -1) {
1089 channel->sortlist = NULL;
1093 if (!channel->lookups) {
1094 channel->lookups = strdup("fb");
1095 if (!channel->lookups)
1101 if(channel->servers)
1102 free(channel->servers);
1104 if(channel->domains && channel->domains[0])
1105 free(channel->domains[0]);
1106 if(channel->domains)
1107 free(channel->domains);
1108 if(channel->lookups)
1109 free(channel->lookups);
1118 #if !defined(WIN32) && !defined(WATT32)
1119 static int config_domain(ares_channel channel, char *str)
1123 /* Set a single search domain. */
1125 while (*q && !ISSPACE(*q))
1128 return set_search(channel, str);
1131 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1132 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1133 /* workaround icc 9.1 optimizer issue */
1134 # define vqualifier volatile
1139 static int config_lookup(ares_channel channel, const char *str,
1140 const char *bindch, const char *filech)
1142 char lookups[3], *l;
1143 const char *vqualifier p;
1145 /* Set the lookup order. Only the first letter of each work
1146 * is relevant, and it has to be "b" for DNS or "f" for the
1147 * host file. Ignore everything else.
1153 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1154 if (*p == *bindch) *l++ = 'b';
1157 while (*p && !ISSPACE(*p) && (*p != ','))
1159 while (*p && (ISSPACE(*p) || (*p == ',')))
1163 channel->lookups = strdup(lookups);
1164 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1166 #endif /* !WIN32 & !WATT32 */
1169 static int config_nameserver(struct server_state **servers, int *nservers,
1172 struct ares_addr host;
1173 struct server_state *newserv;
1175 /* On Windows, there may be more than one nameserver specified in the same
1176 * registry key, so we parse input as a space or comma seperated list.
1180 /* Skip whitespace and commas. */
1181 while (*p && (ISSPACE(*p) || (*p == ',')))
1184 /* No more input, done. */
1187 /* Pointer to start of IPv4 or IPv6 address part. */
1190 /* Advance past this address. */
1191 while (*p && !ISSPACE(*p) && (*p != ','))
1194 /* Null terminate this address. */
1197 /* Reached end of input, done when this address is processed. */
1200 /* Convert textual address to binary format. */
1201 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1202 host.family = AF_INET;
1203 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1204 host.family = AF_INET6;
1208 /* Resize servers state array. */
1209 newserv = realloc(*servers, (*nservers + 1) *
1210 sizeof(struct server_state));
1214 /* Store address data. */
1215 newserv[*nservers].addr.family = host.family;
1216 if (host.family == AF_INET)
1217 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1218 sizeof(host.addrV4));
1220 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1221 sizeof(host.addrV6));
1223 /* Update arguments. */
1228 return ARES_SUCCESS;
1232 static int config_sortlist(struct apattern **sortlist, int *nsort,
1235 struct apattern pat;
1238 /* Add sortlist entries. */
1239 while (*str && *str != ';')
1242 char ipbuf[16], ipbufpfx[32];
1243 /* Find just the IP */
1245 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1247 memcpy(ipbuf, str, (int)(q-str));
1248 ipbuf[(int)(q-str)] = '\0';
1249 /* Find the prefix */
1252 const char *str2 = q+1;
1253 while (*q && *q != ';' && !ISSPACE(*q))
1255 memcpy(ipbufpfx, str, (int)(q-str));
1256 ipbufpfx[(int)(q-str)] = '\0';
1261 /* Lets see if it is CIDR */
1262 /* First we'll try IPv6 */
1263 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1265 sizeof(pat.addrV6))) > 0)
1267 pat.type = PATTERN_CIDR;
1268 pat.mask.bits = (unsigned short)bits;
1269 pat.family = AF_INET6;
1270 if (!sortlist_alloc(sortlist, nsort, &pat))
1274 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1275 sizeof(pat.addrV4))) > 0)
1277 pat.type = PATTERN_CIDR;
1278 pat.mask.bits = (unsigned short)bits;
1279 pat.family = AF_INET;
1280 if (!sortlist_alloc(sortlist, nsort, &pat))
1283 /* See if it is just a regular IP */
1284 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1288 memcpy(ipbuf, str, (int)(q-str));
1289 ipbuf[(int)(q-str)] = '\0';
1290 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1295 pat.family = AF_INET;
1296 pat.type = PATTERN_MASK;
1297 if (!sortlist_alloc(sortlist, nsort, &pat))
1302 while (*q && *q != ';' && !ISSPACE(*q))
1306 while (ISSPACE(*str))
1310 return ARES_SUCCESS;
1313 #endif /* !WATT32 */
1315 static int set_search(ares_channel channel, const char *str)
1320 if(channel->ndomains != -1) {
1321 /* if we already have some domains present, free them first */
1322 for(n=0; n < channel->ndomains; n++)
1323 free(channel->domains[n]);
1324 free(channel->domains);
1325 channel->domains = NULL;
1326 channel->ndomains = -1;
1329 /* Count the domains given. */
1334 while (*p && !ISSPACE(*p))
1343 channel->ndomains = 0;
1344 return ARES_SUCCESS;
1347 channel->domains = malloc(n * sizeof(char *));
1348 if (!channel->domains)
1351 /* Now copy the domains. */
1356 channel->ndomains = n;
1358 while (*q && !ISSPACE(*q))
1360 channel->domains[n] = malloc(q - p + 1);
1361 if (!channel->domains[n])
1363 memcpy(channel->domains[n], p, q - p);
1364 channel->domains[n][q - p] = 0;
1370 channel->ndomains = n;
1372 return ARES_SUCCESS;
1375 static int set_options(ares_channel channel, const char *str)
1377 const char *p, *q, *val;
1383 while (*q && !ISSPACE(*q))
1385 val = try_option(p, q, "ndots:");
1386 if (val && channel->ndots == -1)
1387 channel->ndots = atoi(val);
1388 val = try_option(p, q, "retrans:");
1389 if (val && channel->timeout == -1)
1390 channel->timeout = atoi(val);
1391 val = try_option(p, q, "retry:");
1392 if (val && channel->tries == -1)
1393 channel->tries = atoi(val);
1394 val = try_option(p, q, "rotate");
1395 if (val && channel->rotate == -1)
1396 channel->rotate = 1;
1402 return ARES_SUCCESS;
1405 static const char *try_option(const char *p, const char *q, const char *opt)
1407 size_t len = strlen(opt);
1408 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1411 #if !defined(WIN32) && !defined(WATT32)
1412 static char *try_config(char *s, const char *opt)
1419 /* no line or no option */
1422 /* trim line comment */
1424 while (*p && (*p != '#'))
1428 /* trim trailing whitespace */
1430 while ((q >= s) && ISSPACE(*q))
1434 /* skip leading whitespace */
1436 while (*p && ISSPACE(*p))
1443 if ((len = strlen(opt)) == 0)
1447 if (strncmp(p, opt, len) != 0)
1448 /* line and option do not match */
1451 /* skip over given option name */
1455 /* no option value */
1458 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1459 /* whitespace between option name and value is mandatory
1460 for given option names which do not end with ':' or '=' */
1463 /* skip over whitespace */
1464 while (*p && ISSPACE(*p))
1468 /* no option value */
1471 /* return pointer to option value */
1475 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1476 struct apattern *pat)
1478 struct apattern *newsort;
1479 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1482 newsort[*nsort] = *pat;
1483 *sortlist = newsort;
1488 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1491 /* Four octets and three periods yields at most 15 characters. */
1495 addr->s_addr = inet_addr(ipbuf);
1496 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1501 static void natural_mask(struct apattern *pat)
1503 struct in_addr addr;
1505 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1508 addr.s_addr = ntohl(pat->addrV4.s_addr);
1510 /* This is out of date in the CIDR world, but some people might
1513 if (IN_CLASSA(addr.s_addr))
1514 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1515 else if (IN_CLASSB(addr.s_addr))
1516 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1518 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1520 #endif /* !WIN32 && !WATT32 */
1522 /* initialize an rc4 key. If possible a cryptographically secure random key
1523 is generated using a suitable function (for example win32's RtlGenRandom as
1525 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1526 otherwise the code defaults to cross-platform albeit less secure mechanism
1529 static void randomize_key(unsigned char* key,int key_data_len)
1535 if (ares_fpSystemFunction036)
1537 res = (*ares_fpSystemFunction036) (key, key_data_len);
1543 FILE *f = fopen(RANDOM_FILE, "rb");
1545 counter = fread(key, 1, key_data_len, f);
1551 if ( !randomized ) {
1552 for (;counter<key_data_len;counter++)
1553 key[counter]=(unsigned char)(rand() % 256);
1557 static int init_id_key(rc4_key* key,int key_data_len)
1559 unsigned char index1;
1560 unsigned char index2;
1561 unsigned char* state;
1563 unsigned char *key_data_ptr = 0;
1565 key_data_ptr = calloc(1,key_data_len);
1569 state = &key->state[0];
1570 for(counter = 0; counter < 256; counter++)
1571 /* unnecessary AND but it keeps some compilers happier */
1572 state[counter] = (unsigned char)(counter & 0xff);
1573 randomize_key(key->state,key_data_len);
1578 for(counter = 0; counter < 256; counter++)
1580 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1582 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1584 index1 = (unsigned char)((index1 + 1) % key_data_len);
1587 return ARES_SUCCESS;
1590 unsigned short ares__generate_new_id(rc4_key* key)
1593 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1597 void ares_set_socket_callback(ares_channel channel,
1598 ares_sock_create_callback cb,
1601 channel->sock_create_cb = cb;
1602 channel->sock_create_cb_data = data;
1605 void ares__init_servers_state(ares_channel channel)
1607 struct server_state *server;
1610 for (i = 0; i < channel->nservers; i++)
1612 server = &channel->servers[i];
1613 server->udp_socket = ARES_SOCKET_BAD;
1614 server->tcp_socket = ARES_SOCKET_BAD;
1615 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1616 server->tcp_lenbuf_pos = 0;
1617 server->tcp_buffer_pos = 0;
1618 server->tcp_buffer = NULL;
1619 server->tcp_length = 0;
1620 server->qhead = NULL;
1621 server->qtail = NULL;
1622 ares__init_list_head(&server->queries_to_server);
1623 server->channel = channel;
1624 server->is_broken = 0;