3 /* Copyright 1998 by the Massachusetts Institute of Technology.
4 * Copyright (C) 2007-2010 by Daniel Stenberg
6 * Permission to use, copy, modify, and distribute this
7 * software and its documentation for any purpose and without
8 * fee is hereby granted, provided that the above copyright
9 * notice appear in all copies and that both that copyright
10 * notice and this permission notice appear in supporting
11 * documentation, and that the name of M.I.T. not be used in
12 * advertising or publicity pertaining to distribution of the
13 * software without specific, written prior permission.
14 * M.I.T. makes no representations about the suitability of
15 * this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
19 #include "ares_setup.h"
25 #ifdef HAVE_SYS_PARAM_H
26 #include <sys/param.h>
29 #ifdef HAVE_SYS_TIME_H
33 #ifdef HAVE_SYS_SOCKET_H
34 #include <sys/socket.h>
37 #ifdef HAVE_NETINET_IN_H
38 #include <netinet/in.h>
45 #ifdef HAVE_ARPA_INET_H
46 #include <arpa/inet.h>
49 #ifdef HAVE_ARPA_NAMESER_H
50 # include <arpa/nameser.h>
54 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
55 # include <arpa/nameser_compat.h>
69 #include "inet_net_pton.h"
70 #include "ares_library_init.h"
71 #include "ares_private.h"
74 #undef WIN32 /* Redefined in MingW/MSVC headers */
77 static int init_by_options(ares_channel channel, const struct ares_options *options,
79 static int init_by_environment(ares_channel channel);
80 static int init_by_resolv_conf(ares_channel channel);
81 static int init_by_defaults(ares_channel channel);
84 static int config_nameserver(struct server_state **servers, int *nservers,
87 static int set_search(ares_channel channel, const char *str);
88 static int set_options(ares_channel channel, const char *str);
89 static const char *try_option(const char *p, const char *q, const char *opt);
90 static int init_id_key(rc4_key* key,int key_data_len);
92 #if !defined(WIN32) && !defined(WATT32)
93 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
94 static int ip_addr(const char *s, int len, struct in_addr *addr);
95 static void natural_mask(struct apattern *pat);
96 static int config_domain(ares_channel channel, char *str);
97 static int config_lookup(ares_channel channel, const char *str,
98 const char *bindch, const char *filech);
99 static int config_sortlist(struct apattern **sortlist, int *nsort,
101 static char *try_config(char *s, const char *opt);
104 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
105 x->nservers > -1 && \
106 x->ndomains > -1 && \
107 x->ndots > -1 && x->timeout > -1 && \
110 int ares_init(ares_channel *channelptr)
112 return ares_init_options(channelptr, NULL, 0);
115 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
118 ares_channel channel;
120 int status = ARES_SUCCESS;
124 const char *env = getenv("CARES_MEMDEBUG");
128 env = getenv("CARES_MEMLIMIT");
130 curl_memlimit(atoi(env));
133 if (ares_library_initialized() != ARES_SUCCESS)
134 return ARES_ENOTINITIALIZED;
136 channel = malloc(sizeof(struct ares_channeldata));
144 /* Set everything to distinguished values so we know they haven't
148 channel->timeout = -1;
151 channel->rotate = -1;
152 channel->udp_port = -1;
153 channel->tcp_port = -1;
154 channel->socket_send_buffer_size = -1;
155 channel->socket_receive_buffer_size = -1;
156 channel->nservers = -1;
157 channel->ndomains = -1;
159 channel->tcp_connection_generation = 0;
160 channel->lookups = NULL;
161 channel->domains = NULL;
162 channel->sortlist = NULL;
163 channel->servers = NULL;
164 channel->sock_state_cb = NULL;
165 channel->sock_state_cb_data = NULL;
166 channel->sock_create_cb = NULL;
167 channel->sock_create_cb_data = NULL;
169 channel->last_server = 0;
170 channel->last_timeout_processed = (time_t)now.tv_sec;
172 /* Initialize our lists of queries */
173 ares__init_list_head(&(channel->all_queries));
174 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
176 ares__init_list_head(&(channel->queries_by_qid[i]));
178 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
180 ares__init_list_head(&(channel->queries_by_timeout[i]));
183 /* Initialize configuration by each of the four sources, from highest
184 * precedence to lowest.
187 if (status == ARES_SUCCESS) {
188 status = init_by_options(channel, options, optmask);
189 if (status != ARES_SUCCESS)
190 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
191 ares_strerror(status)));
193 if (status == ARES_SUCCESS) {
194 status = init_by_environment(channel);
195 if (status != ARES_SUCCESS)
196 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
197 ares_strerror(status)));
199 if (status == ARES_SUCCESS) {
200 status = init_by_resolv_conf(channel);
201 if (status != ARES_SUCCESS)
202 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
203 ares_strerror(status)));
207 * No matter what failed or succeeded, seed defaults to provide
208 * useful behavior for things that we missed.
210 status = init_by_defaults(channel);
211 if (status != ARES_SUCCESS)
212 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
213 ares_strerror(status)));
215 /* Generate random key */
217 if (status == ARES_SUCCESS) {
218 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
219 if (status == ARES_SUCCESS)
220 channel->next_id = ares__generate_new_id(&channel->id_key);
222 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
223 ares_strerror(status)));
226 if (status != ARES_SUCCESS)
228 /* Something failed; clean up memory we may have allocated. */
229 if (channel->servers)
230 free(channel->servers);
231 if (channel->domains)
233 for (i = 0; i < channel->ndomains; i++)
234 free(channel->domains[i]);
235 free(channel->domains);
237 if (channel->sortlist)
238 free(channel->sortlist);
240 free(channel->lookups);
245 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
246 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
247 channel->nservers = 1;
249 ares__init_servers_state(channel);
251 *channelptr = channel;
255 /* ares_dup() duplicates a channel handle with all its options and returns a
256 new channel handle */
257 int ares_dup(ares_channel *dest, ares_channel src)
259 struct ares_options opts;
260 struct ares_addr_node *servers;
261 int ipv6_nservers = 0;
265 *dest = NULL; /* in case of failure return NULL explicitly */
267 /* First get the options supported by the old ares_save_options() function,
268 which is most of them */
269 rc = ares_save_options(src, &opts, &optmask);
273 /* Then create the new channel with those options */
274 rc = ares_init_options(dest, &opts, optmask);
276 /* destroy the options copy to not leak any memory */
277 ares_destroy_options(&opts);
282 /* Now clone the options that ares_save_options() doesn't support. */
283 (*dest)->sock_create_cb = src->sock_create_cb;
284 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
286 /* Full name server cloning required when not all are IPv4 */
287 for (i = 0; i < src->nservers; i++)
289 if (src->servers[i].addr.family != AF_INET) {
295 rc = ares_get_servers(src, &servers);
296 if (rc != ARES_SUCCESS)
298 rc = ares_set_servers(*dest, servers);
299 ares_free_data(servers);
300 if (rc != ARES_SUCCESS)
304 return ARES_SUCCESS; /* everything went fine */
307 /* Save options from initialized channel */
308 int ares_save_options(ares_channel channel, struct ares_options *options,
312 int ipv4_nservers = 0;
314 /* Zero everything out */
315 memset(options, 0, sizeof(struct ares_options));
317 if (!ARES_CONFIG_CHECK(channel))
320 /* Traditionally the optmask wasn't saved in the channel struct so it was
321 recreated here. ROTATE is the first option that has no struct field of
322 its own in the public config struct */
323 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
324 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
325 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
326 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
327 (channel->optmask & ARES_OPT_ROTATE);
329 /* Copy easy stuff */
330 options->flags = channel->flags;
332 /* We return full millisecond resolution but that's only because we don't
333 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
334 options->timeout = channel->timeout;
335 options->tries = channel->tries;
336 options->ndots = channel->ndots;
337 options->udp_port = (unsigned short)channel->udp_port;
338 options->tcp_port = (unsigned short)channel->tcp_port;
339 options->sock_state_cb = channel->sock_state_cb;
340 options->sock_state_cb_data = channel->sock_state_cb_data;
342 /* Copy IPv4 servers */
343 if (channel->nservers) {
344 for (i = 0; i < channel->nservers; i++)
346 if (channel->servers[i].addr.family == AF_INET)
350 options->servers = malloc(ipv4_nservers * sizeof(struct server_state));
351 if (!options->servers)
353 for (i = j = 0; i < channel->nservers; i++)
355 if (channel->servers[i].addr.family == AF_INET)
356 memcpy(&options->servers[j++],
357 &channel->servers[i].addr.addrV4,
358 sizeof(channel->servers[i].addr.addrV4));
362 options->nservers = ipv4_nservers;
365 if (channel->ndomains) {
366 options->domains = malloc(channel->ndomains * sizeof(char *));
367 if (!options->domains)
370 for (i = 0; i < channel->ndomains; i++)
372 options->ndomains = i;
373 options->domains[i] = strdup(channel->domains[i]);
374 if (!options->domains[i])
378 options->ndomains = channel->ndomains;
381 if (channel->lookups) {
382 options->lookups = strdup(channel->lookups);
383 if (!options->lookups && channel->lookups)
388 if (channel->nsort) {
389 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
390 if (!options->sortlist)
392 for (i = 0; i < channel->nsort; i++)
394 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
395 sizeof(struct apattern));
398 options->nsort = channel->nsort;
403 static int init_by_options(ares_channel channel,
404 const struct ares_options *options,
410 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
411 channel->flags = options->flags;
412 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
413 channel->timeout = options->timeout;
414 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
415 channel->timeout = options->timeout * 1000;
416 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
417 channel->tries = options->tries;
418 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
419 channel->ndots = options->ndots;
420 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
422 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
423 channel->udp_port = options->udp_port;
424 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
425 channel->tcp_port = options->tcp_port;
426 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
428 channel->sock_state_cb = options->sock_state_cb;
429 channel->sock_state_cb_data = options->sock_state_cb_data;
431 if ((optmask & ARES_OPT_SOCK_SNDBUF)
432 && channel->socket_send_buffer_size == -1)
433 channel->socket_send_buffer_size = options->socket_send_buffer_size;
434 if ((optmask & ARES_OPT_SOCK_RCVBUF)
435 && channel->socket_receive_buffer_size == -1)
436 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
438 /* Copy the IPv4 servers, if given. */
439 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
441 /* Avoid zero size allocations at any cost */
442 if (options->nservers > 0)
445 malloc(options->nservers * sizeof(struct server_state));
446 if (!channel->servers)
448 for (i = 0; i < options->nservers; i++)
450 channel->servers[i].addr.family = AF_INET;
451 memcpy(&channel->servers[i].addr.addrV4,
452 &options->servers[i],
453 sizeof(channel->servers[i].addr.addrV4));
456 channel->nservers = options->nservers;
459 /* Copy the domains, if given. Keep channel->ndomains consistent so
460 * we can clean up in case of error.
462 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
464 /* Avoid zero size allocations at any cost */
465 if (options->ndomains > 0)
467 channel->domains = malloc(options->ndomains * sizeof(char *));
468 if (!channel->domains)
470 for (i = 0; i < options->ndomains; i++)
472 channel->ndomains = i;
473 channel->domains[i] = strdup(options->domains[i]);
474 if (!channel->domains[i])
478 channel->ndomains = options->ndomains;
481 /* Set lookups, if given. */
482 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
484 channel->lookups = strdup(options->lookups);
485 if (!channel->lookups)
490 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
492 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
493 if (!channel->sortlist)
495 for (i = 0; i < options->nsort; i++)
497 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
498 sizeof(struct apattern));
500 channel->nsort = options->nsort;
503 channel->optmask = optmask;
508 static int init_by_environment(ares_channel channel)
510 const char *localdomain, *res_options;
513 localdomain = getenv("LOCALDOMAIN");
514 if (localdomain && channel->ndomains == -1)
516 status = set_search(channel, localdomain);
517 if (status != ARES_SUCCESS)
521 res_options = getenv("RES_OPTIONS");
524 status = set_options(channel, res_options);
525 if (status != ARES_SUCCESS)
534 * Warning: returns a dynamically allocated buffer, the user MUST
535 * use free() if the function returns 1
537 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
539 /* Test for the size we need */
543 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
544 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
546 *obuf = malloc(size+1);
550 if (RegQueryValueEx(hKey, subkey, 0, NULL,
551 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
564 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
566 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
567 DWORD enum_size = 39;
571 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
572 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
577 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
580 rc = get_res_nt(hVal, subkey, obuf);
588 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
590 FIXED_INFO *fi, *newfi;
591 DWORD size = sizeof (*fi);
592 IP_ADDR_STRING *ipAddr;
595 size_t ip_size = sizeof("255.255.255.255,")-1;
596 size_t left = ret_size;
604 res = (*ares_fpGetNetworkParams) (fi, &size);
605 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
608 newfi = realloc(fi, size);
613 res = (*ares_fpGetNetworkParams) (fi, &size);
614 if (res != ERROR_SUCCESS)
619 printf ("Host Name: %s\n", fi->HostName);
620 printf ("Domain Name: %s\n", fi->DomainName);
621 printf ("DNS Servers:\n"
622 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
624 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
625 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
628 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
629 left -= ret - ret_buf;
633 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
634 ipAddr = ipAddr->Next, i++)
636 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
638 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
639 left -= ret - ret_buf;
643 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
650 if (debug && left <= ip_size)
651 printf ("Too many nameservers. Truncating to %d addressess", count);
658 static int init_by_resolv_conf(ares_channel channel)
663 int status = -1, nservers = 0, nsort = 0;
664 struct server_state *servers = NULL;
665 struct apattern *sortlist = NULL;
670 NameServer info via IPHLPAPI (IP helper API):
671 GetNetworkParams() should be the trusted source for this.
672 Available in Win-98/2000 and later. If that fail, fall-back to
673 registry information.
677 On Windows 9X, the DNS server can be found in:
678 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
680 On Windows NT/2000/XP/2003:
681 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
683 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
685 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
688 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
699 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
702 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
704 status = config_nameserver(&servers, &nservers, buf);
705 if (status == ARES_SUCCESS)
712 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
716 RegOpenKeyEx(mykey, "Interfaces", 0,
717 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
718 if (get_res_nt(mykey, NAMESERVER, &line))
720 status = config_nameserver(&servers, &nservers, line);
723 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
725 status = config_nameserver(&servers, &nservers, line);
728 /* Try the interfaces */
729 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
731 status = config_nameserver(&servers, &nservers, line);
734 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
736 status = config_nameserver(&servers, &nservers, line);
746 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
750 if ((result = RegQueryValueEx(
751 mykey, NAMESERVER, NULL, &data_type,
754 ) == ERROR_SUCCESS ||
755 result == ERROR_MORE_DATA)
759 line = malloc(bytes+1);
760 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
761 (unsigned char *)line, &bytes) ==
764 status = config_nameserver(&servers, &nservers, line);
773 if (status == ARES_SUCCESS)
776 /* Catch the case when all the above checks fail (which happens when there
777 is no network card or the cable is unplugged) */
780 #elif defined(__riscos__)
782 /* Under RISC OS, name servers are listed in the
783 system variable Inet$Resolvers, space separated. */
785 line = getenv("Inet$Resolvers");
788 char *resolvers = strdup(line), *pos, *space;
795 space = strchr(pos, ' ');
798 status = config_nameserver(&servers, &nservers, pos);
799 if (status != ARES_SUCCESS)
804 if (status == ARES_SUCCESS)
810 #elif defined(WATT32)
814 for (i = 0; def_nameservers[i]; i++)
817 return ARES_SUCCESS; /* use localhost DNS server */
820 servers = calloc(i, sizeof(struct server_state));
824 for (i = 0; def_nameservers[i]; i++)
825 servers[i].addr.s_addr = htonl(def_nameservers[i]);
835 /* Don't read resolv.conf and friends if we don't have to */
836 if (ARES_CONFIG_CHECK(channel))
839 fp = fopen(PATH_RESOLV_CONF, "r");
841 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
843 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
844 status = config_domain(channel, p);
845 else if ((p = try_config(line, "lookup")) && !channel->lookups)
846 status = config_lookup(channel, p, "bind", "file");
847 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
848 status = set_search(channel, p);
849 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
850 status = config_nameserver(&servers, &nservers, p);
851 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
852 status = config_sortlist(&sortlist, &nsort, p);
853 else if ((p = try_config(line, "options")))
854 status = set_options(channel, p);
856 status = ARES_SUCCESS;
857 if (status != ARES_SUCCESS)
870 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
871 error, strerror(error)));
872 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
877 if ((status == ARES_EOF) && (!channel->lookups)) {
878 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
879 fp = fopen("/etc/nsswitch.conf", "r");
881 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
883 if ((p = try_config(line, "hosts:")) && !channel->lookups)
884 status = config_lookup(channel, p, "dns", "files");
896 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
897 error, strerror(error)));
898 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
904 if ((status == ARES_EOF) && (!channel->lookups)) {
905 /* Linux / GNU libc 2.x and possibly others have host.conf */
906 fp = fopen("/etc/host.conf", "r");
908 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
910 if ((p = try_config(line, "order")) && !channel->lookups)
911 status = config_lookup(channel, p, "bind", "hosts");
923 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
924 error, strerror(error)));
925 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
931 if ((status == ARES_EOF) && (!channel->lookups)) {
932 /* Tru64 uses /etc/svc.conf */
933 fp = fopen("/etc/svc.conf", "r");
935 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
937 if ((p = try_config(line, "hosts=")) && !channel->lookups)
938 status = config_lookup(channel, p, "bind", "local");
950 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
951 error, strerror(error)));
952 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
965 if (status != ARES_EOF)
969 if (sortlist != NULL)
974 /* If we got any name server entries, fill them in. */
980 channel->servers = servers;
981 channel->nservers = nservers;
984 /* If we got any sortlist entries, fill them in. */
987 channel->sortlist = sortlist;
988 channel->nsort = nsort;
994 static int init_by_defaults(ares_channel channel)
996 char *hostname = NULL;
997 int rc = ARES_SUCCESS;
998 #ifdef HAVE_GETHOSTNAME
1002 if (channel->flags == -1)
1004 if (channel->timeout == -1)
1005 channel->timeout = DEFAULT_TIMEOUT;
1006 if (channel->tries == -1)
1007 channel->tries = DEFAULT_TRIES;
1008 if (channel->ndots == -1)
1010 if (channel->rotate == -1)
1011 channel->rotate = 0;
1012 if (channel->udp_port == -1)
1013 channel->udp_port = htons(NAMESERVER_PORT);
1014 if (channel->tcp_port == -1)
1015 channel->tcp_port = htons(NAMESERVER_PORT);
1017 if (channel->nservers == -1) {
1018 /* If nobody specified servers, try a local named. */
1019 channel->servers = malloc(sizeof(struct server_state));
1020 if (!channel->servers) {
1024 channel->servers[0].addr.family = AF_INET;
1025 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1026 channel->nservers = 1;
1030 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1032 #define toolong(x) (x == -1) && (EINVAL == errno)
1035 if (channel->ndomains == -1) {
1036 /* Derive a default domain search list from the kernel hostname,
1037 * or set it to empty if the hostname isn't helpful.
1041 channel->ndomains = 0; /* default to none */
1043 #ifdef HAVE_GETHOSTNAME
1044 hostname = malloc(len);
1051 res = gethostname(hostname, len);
1056 p = realloc(hostname, len);
1071 dot = strchr(hostname, '.');
1073 /* a dot was found */
1074 channel->domains = malloc(sizeof(char *));
1075 if (!channel->domains) {
1079 channel->domains[0] = strdup(dot + 1);
1080 if (!channel->domains[0]) {
1084 channel->ndomains = 1;
1089 if (channel->nsort == -1) {
1090 channel->sortlist = NULL;
1094 if (!channel->lookups) {
1095 channel->lookups = strdup("fb");
1096 if (!channel->lookups)
1102 if(channel->servers)
1103 free(channel->servers);
1105 if(channel->domains && channel->domains[0])
1106 free(channel->domains[0]);
1107 if(channel->domains)
1108 free(channel->domains);
1109 if(channel->lookups)
1110 free(channel->lookups);
1119 #if !defined(WIN32) && !defined(WATT32)
1120 static int config_domain(ares_channel channel, char *str)
1124 /* Set a single search domain. */
1126 while (*q && !ISSPACE(*q))
1129 return set_search(channel, str);
1132 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1133 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1134 /* workaround icc 9.1 optimizer issue */
1135 # define vqualifier volatile
1140 static int config_lookup(ares_channel channel, const char *str,
1141 const char *bindch, const char *filech)
1143 char lookups[3], *l;
1144 const char *vqualifier p;
1146 /* Set the lookup order. Only the first letter of each work
1147 * is relevant, and it has to be "b" for DNS or "f" for the
1148 * host file. Ignore everything else.
1154 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1155 if (*p == *bindch) *l++ = 'b';
1158 while (*p && !ISSPACE(*p) && (*p != ','))
1160 while (*p && (ISSPACE(*p) || (*p == ',')))
1164 channel->lookups = strdup(lookups);
1165 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1167 #endif /* !WIN32 & !WATT32 */
1170 static int config_nameserver(struct server_state **servers, int *nservers,
1173 struct ares_addr host;
1174 struct server_state *newserv;
1176 /* On Windows, there may be more than one nameserver specified in the same
1177 * registry key, so we parse input as a space or comma seperated list.
1181 /* Skip whitespace and commas. */
1182 while (*p && (ISSPACE(*p) || (*p == ',')))
1185 /* No more input, done. */
1188 /* Pointer to start of IPv4 or IPv6 address part. */
1191 /* Advance past this address. */
1192 while (*p && !ISSPACE(*p) && (*p != ','))
1195 /* Null terminate this address. */
1198 /* Reached end of input, done when this address is processed. */
1201 /* Convert textual address to binary format. */
1202 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1203 host.family = AF_INET;
1204 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1205 host.family = AF_INET6;
1209 /* Resize servers state array. */
1210 newserv = realloc(*servers, (*nservers + 1) *
1211 sizeof(struct server_state));
1215 /* Store address data. */
1216 newserv[*nservers].addr.family = host.family;
1217 if (host.family == AF_INET)
1218 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1219 sizeof(host.addrV4));
1221 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1222 sizeof(host.addrV6));
1224 /* Update arguments. */
1229 return ARES_SUCCESS;
1233 static int config_sortlist(struct apattern **sortlist, int *nsort,
1236 struct apattern pat;
1239 /* Add sortlist entries. */
1240 while (*str && *str != ';')
1243 char ipbuf[16], ipbufpfx[32];
1244 /* Find just the IP */
1246 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1248 memcpy(ipbuf, str, (int)(q-str));
1249 ipbuf[(int)(q-str)] = '\0';
1250 /* Find the prefix */
1253 const char *str2 = q+1;
1254 while (*q && *q != ';' && !ISSPACE(*q))
1256 memcpy(ipbufpfx, str, (int)(q-str));
1257 ipbufpfx[(int)(q-str)] = '\0';
1262 /* Lets see if it is CIDR */
1263 /* First we'll try IPv6 */
1264 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1266 sizeof(pat.addrV6))) > 0)
1268 pat.type = PATTERN_CIDR;
1269 pat.mask.bits = (unsigned short)bits;
1270 pat.family = AF_INET6;
1271 if (!sortlist_alloc(sortlist, nsort, &pat))
1275 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1276 sizeof(pat.addrV4))) > 0)
1278 pat.type = PATTERN_CIDR;
1279 pat.mask.bits = (unsigned short)bits;
1280 pat.family = AF_INET;
1281 if (!sortlist_alloc(sortlist, nsort, &pat))
1284 /* See if it is just a regular IP */
1285 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1289 memcpy(ipbuf, str, (int)(q-str));
1290 ipbuf[(int)(q-str)] = '\0';
1291 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1296 pat.family = AF_INET;
1297 pat.type = PATTERN_MASK;
1298 if (!sortlist_alloc(sortlist, nsort, &pat))
1303 while (*q && *q != ';' && !ISSPACE(*q))
1307 while (ISSPACE(*str))
1311 return ARES_SUCCESS;
1314 #endif /* !WATT32 */
1316 static int set_search(ares_channel channel, const char *str)
1321 if(channel->ndomains != -1) {
1322 /* if we already have some domains present, free them first */
1323 for(n=0; n < channel->ndomains; n++)
1324 free(channel->domains[n]);
1325 free(channel->domains);
1326 channel->domains = NULL;
1327 channel->ndomains = -1;
1330 /* Count the domains given. */
1335 while (*p && !ISSPACE(*p))
1344 channel->ndomains = 0;
1345 return ARES_SUCCESS;
1348 channel->domains = malloc(n * sizeof(char *));
1349 if (!channel->domains)
1352 /* Now copy the domains. */
1357 channel->ndomains = n;
1359 while (*q && !ISSPACE(*q))
1361 channel->domains[n] = malloc(q - p + 1);
1362 if (!channel->domains[n])
1364 memcpy(channel->domains[n], p, q - p);
1365 channel->domains[n][q - p] = 0;
1371 channel->ndomains = n;
1373 return ARES_SUCCESS;
1376 static int set_options(ares_channel channel, const char *str)
1378 const char *p, *q, *val;
1384 while (*q && !ISSPACE(*q))
1386 val = try_option(p, q, "ndots:");
1387 if (val && channel->ndots == -1)
1388 channel->ndots = atoi(val);
1389 val = try_option(p, q, "retrans:");
1390 if (val && channel->timeout == -1)
1391 channel->timeout = atoi(val);
1392 val = try_option(p, q, "retry:");
1393 if (val && channel->tries == -1)
1394 channel->tries = atoi(val);
1395 val = try_option(p, q, "rotate");
1396 if (val && channel->rotate == -1)
1397 channel->rotate = 1;
1403 return ARES_SUCCESS;
1406 static const char *try_option(const char *p, const char *q, const char *opt)
1408 size_t len = strlen(opt);
1409 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1412 #if !defined(WIN32) && !defined(WATT32)
1413 static char *try_config(char *s, const char *opt)
1420 /* no line or no option */
1423 /* trim line comment */
1425 while (*p && (*p != '#'))
1429 /* trim trailing whitespace */
1431 while ((q >= s) && ISSPACE(*q))
1435 /* skip leading whitespace */
1437 while (*p && ISSPACE(*p))
1444 if ((len = strlen(opt)) == 0)
1448 if (strncmp(p, opt, len) != 0)
1449 /* line and option do not match */
1452 /* skip over given option name */
1456 /* no option value */
1459 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1460 /* whitespace between option name and value is mandatory
1461 for given option names which do not end with ':' or '=' */
1464 /* skip over whitespace */
1465 while (*p && ISSPACE(*p))
1469 /* no option value */
1472 /* return pointer to option value */
1476 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1477 struct apattern *pat)
1479 struct apattern *newsort;
1480 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1483 newsort[*nsort] = *pat;
1484 *sortlist = newsort;
1489 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1492 /* Four octets and three periods yields at most 15 characters. */
1496 addr->s_addr = inet_addr(ipbuf);
1497 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1502 static void natural_mask(struct apattern *pat)
1504 struct in_addr addr;
1506 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1509 addr.s_addr = ntohl(pat->addrV4.s_addr);
1511 /* This is out of date in the CIDR world, but some people might
1514 if (IN_CLASSA(addr.s_addr))
1515 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1516 else if (IN_CLASSB(addr.s_addr))
1517 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1519 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1521 #endif /* !WIN32 && !WATT32 */
1523 /* initialize an rc4 key. If possible a cryptographically secure random key
1524 is generated using a suitable function (for example win32's RtlGenRandom as
1526 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1527 otherwise the code defaults to cross-platform albeit less secure mechanism
1530 static void randomize_key(unsigned char* key,int key_data_len)
1536 if (ares_fpSystemFunction036)
1538 res = (*ares_fpSystemFunction036) (key, key_data_len);
1544 FILE *f = fopen(RANDOM_FILE, "rb");
1546 counter = fread(key, 1, key_data_len, f);
1552 if ( !randomized ) {
1553 for (;counter<key_data_len;counter++)
1554 key[counter]=(unsigned char)(rand() % 256);
1558 static int init_id_key(rc4_key* key,int key_data_len)
1560 unsigned char index1;
1561 unsigned char index2;
1562 unsigned char* state;
1564 unsigned char *key_data_ptr = 0;
1566 key_data_ptr = calloc(1,key_data_len);
1570 state = &key->state[0];
1571 for(counter = 0; counter < 256; counter++)
1572 /* unnecessary AND but it keeps some compilers happier */
1573 state[counter] = (unsigned char)(counter & 0xff);
1574 randomize_key(key->state,key_data_len);
1579 for(counter = 0; counter < 256; counter++)
1581 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1583 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1585 index1 = (unsigned char)((index1 + 1) % key_data_len);
1588 return ARES_SUCCESS;
1591 unsigned short ares__generate_new_id(rc4_key* key)
1594 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1598 void ares_set_socket_callback(ares_channel channel,
1599 ares_sock_create_callback cb,
1602 channel->sock_create_cb = cb;
1603 channel->sock_create_cb_data = data;
1606 void ares__init_servers_state(ares_channel channel)
1608 struct server_state *server;
1611 for (i = 0; i < channel->nservers; i++)
1613 server = &channel->servers[i];
1614 server->udp_socket = ARES_SOCKET_BAD;
1615 server->tcp_socket = ARES_SOCKET_BAD;
1616 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1617 server->tcp_lenbuf_pos = 0;
1618 server->tcp_buffer_pos = 0;
1619 server->tcp_buffer = NULL;
1620 server->tcp_length = 0;
1621 server->qhead = NULL;
1622 server->qtail = NULL;
1623 ares__init_list_head(&server->queries_to_server);
1624 server->channel = channel;
1625 server->is_broken = 0;