3 /* Copyright 1998 by the Massachusetts Institute of Technology.
4 * Copyright (C) 2007-2009 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.
21 #if defined(WIN32) && !defined(WATT32)
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_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);
82 static int config_nameserver(struct server_state **servers, int *nservers,
84 static int set_search(ares_channel channel, const char *str);
85 static int set_options(ares_channel channel, const char *str);
86 static const char *try_option(const char *p, const char *q, const char *opt);
87 static int init_id_key(rc4_key* key,int key_data_len);
90 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
91 static int ip_addr(const char *s, int len, struct in_addr *addr);
92 static void natural_mask(struct apattern *pat);
93 static int config_domain(ares_channel channel, char *str);
94 static int config_lookup(ares_channel channel, const char *str,
95 const char *bindch, const char *filech);
96 static int config_sortlist(struct apattern **sortlist, int *nsort,
98 static char *try_config(char *s, const char *opt);
101 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
102 x->nservers > -1 && \
103 x->ndomains > -1 && \
104 x->ndots > -1 && x->timeout > -1 && \
107 int ares_init(ares_channel *channelptr)
109 return ares_init_options(channelptr, NULL, 0);
112 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
115 ares_channel channel;
117 int status = ARES_SUCCESS;
118 struct server_state *server;
122 const char *env = getenv("CARES_MEMDEBUG");
126 env = getenv("CARES_MEMLIMIT");
128 curl_memlimit(atoi(env));
131 channel = malloc(sizeof(struct ares_channeldata));
139 /* Set everything to distinguished values so we know they haven't
143 channel->timeout = -1;
146 channel->rotate = -1;
147 channel->udp_port = -1;
148 channel->tcp_port = -1;
149 channel->socket_send_buffer_size = -1;
150 channel->socket_receive_buffer_size = -1;
151 channel->nservers = -1;
152 channel->ndomains = -1;
154 channel->tcp_connection_generation = 0;
155 channel->lookups = NULL;
156 channel->domains = NULL;
157 channel->sortlist = NULL;
158 channel->servers = NULL;
159 channel->sock_state_cb = NULL;
160 channel->sock_state_cb_data = NULL;
161 channel->sock_create_cb = NULL;
162 channel->sock_create_cb_data = NULL;
164 channel->last_server = 0;
165 channel->last_timeout_processed = (time_t)now.tv_sec;
167 /* Initialize our lists of queries */
168 ares__init_list_head(&(channel->all_queries));
169 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
171 ares__init_list_head(&(channel->queries_by_qid[i]));
173 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
175 ares__init_list_head(&(channel->queries_by_timeout[i]));
178 /* Initialize configuration by each of the four sources, from highest
179 * precedence to lowest.
182 if (status == ARES_SUCCESS) {
183 status = init_by_options(channel, options, optmask);
184 if (status != ARES_SUCCESS)
185 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
186 ares_strerror(status)));
188 if (status == ARES_SUCCESS) {
189 status = init_by_environment(channel);
190 if (status != ARES_SUCCESS)
191 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
192 ares_strerror(status)));
194 if (status == ARES_SUCCESS) {
195 status = init_by_resolv_conf(channel);
196 if (status != ARES_SUCCESS)
197 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
198 ares_strerror(status)));
200 if (status == ARES_SUCCESS) {
201 status = init_by_defaults(channel);
202 if (status != ARES_SUCCESS)
203 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
204 ares_strerror(status)));
207 /* Generate random key */
209 if (status == ARES_SUCCESS) {
210 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
211 if (status == ARES_SUCCESS)
212 channel->next_id = ares__generate_new_id(&channel->id_key);
214 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
215 ares_strerror(status)));
218 if (status != ARES_SUCCESS)
220 /* Something failed; clean up memory we may have allocated. */
221 if (channel->servers)
222 free(channel->servers);
223 if (channel->domains)
225 for (i = 0; i < channel->ndomains; i++)
226 free(channel->domains[i]);
227 free(channel->domains);
229 if (channel->sortlist)
230 free(channel->sortlist);
232 free(channel->lookups);
237 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
238 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
239 channel->nservers = 1;
241 /* Initialize server states. */
242 for (i = 0; i < channel->nservers; i++)
244 server = &channel->servers[i];
245 server->udp_socket = ARES_SOCKET_BAD;
246 server->tcp_socket = ARES_SOCKET_BAD;
247 server->tcp_connection_generation = ++channel->tcp_connection_generation;
248 server->tcp_lenbuf_pos = 0;
249 server->tcp_buffer = NULL;
250 server->qhead = NULL;
251 server->qtail = NULL;
252 ares__init_list_head(&(server->queries_to_server));
253 server->channel = channel;
254 server->is_broken = 0;
257 *channelptr = channel;
261 /* ares_dup() duplicates a channel handle with all its options and returns a
262 new channel handle */
263 int ares_dup(ares_channel *dest, ares_channel src)
265 struct ares_options opts;
269 *dest = NULL; /* in case of failure return NULL explicitly */
271 /* First get the options supported by the old ares_save_options() function,
272 which is most of them */
273 rc = ares_save_options(src, &opts, &optmask);
277 /* Then create the new channel with those options */
278 rc = ares_init_options(dest, &opts, optmask);
280 /* destroy the options copy to not leak any memory */
281 ares_destroy_options(&opts);
286 /* Now clone the options that ares_save_options() doesn't support. */
287 (*dest)->sock_create_cb = src->sock_create_cb;
288 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
291 return ARES_SUCCESS; /* everything went fine */
295 /* Save options from initialized channel */
296 int ares_save_options(ares_channel channel, struct ares_options *options,
301 /* Zero everything out */
302 memset(options, 0, sizeof(struct ares_options));
304 if (!ARES_CONFIG_CHECK(channel))
307 /* Traditionally the optmask wasn't saved in the channel struct so it was
308 recreated here. ROTATE is the first option that has no struct field of
309 its own in the public config struct */
310 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
311 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
312 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
313 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
314 (channel->optmask & ARES_OPT_ROTATE);
316 /* Copy easy stuff */
317 options->flags = channel->flags;
319 /* We return full millisecond resolution but that's only because we don't
320 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
321 options->timeout = channel->timeout;
322 options->tries = channel->tries;
323 options->ndots = channel->ndots;
324 options->udp_port = (unsigned short)channel->udp_port;
325 options->tcp_port = (unsigned short)channel->tcp_port;
326 options->sock_state_cb = channel->sock_state_cb;
327 options->sock_state_cb_data = channel->sock_state_cb_data;
330 if (channel->nservers) {
332 malloc(channel->nservers * sizeof(struct server_state));
333 if (!options->servers && channel->nservers != 0)
335 for (i = 0; i < channel->nservers; i++)
336 options->servers[i] = channel->servers[i].addr;
338 options->nservers = channel->nservers;
341 if (channel->ndomains) {
342 options->domains = malloc(channel->ndomains * sizeof(char *));
343 if (!options->domains)
346 for (i = 0; i < channel->ndomains; i++)
348 options->ndomains = i;
349 options->domains[i] = strdup(channel->domains[i]);
350 if (!options->domains[i])
354 options->ndomains = channel->ndomains;
357 if (channel->lookups) {
358 options->lookups = strdup(channel->lookups);
359 if (!options->lookups && channel->lookups)
364 if (channel->nsort) {
365 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
366 if (!options->sortlist)
368 for (i = 0; i < channel->nsort; i++)
370 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
371 sizeof(struct apattern));
374 options->nsort = channel->nsort;
379 static int init_by_options(ares_channel channel,
380 const struct ares_options *options,
386 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
387 channel->flags = options->flags;
388 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
389 channel->timeout = options->timeout;
390 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
391 channel->timeout = options->timeout * 1000;
392 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
393 channel->tries = options->tries;
394 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
395 channel->ndots = options->ndots;
396 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
398 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
399 channel->udp_port = options->udp_port;
400 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
401 channel->tcp_port = options->tcp_port;
402 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
404 channel->sock_state_cb = options->sock_state_cb;
405 channel->sock_state_cb_data = options->sock_state_cb_data;
407 if ((optmask & ARES_OPT_SOCK_SNDBUF)
408 && channel->socket_send_buffer_size == -1)
409 channel->socket_send_buffer_size = options->socket_send_buffer_size;
410 if ((optmask & ARES_OPT_SOCK_RCVBUF)
411 && channel->socket_receive_buffer_size == -1)
412 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
414 /* Copy the servers, if given. */
415 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
417 /* Avoid zero size allocations at any cost */
418 if (options->nservers > 0)
421 malloc(options->nservers * sizeof(struct server_state));
422 if (!channel->servers)
424 for (i = 0; i < options->nservers; i++)
425 channel->servers[i].addr = options->servers[i];
427 channel->nservers = options->nservers;
430 /* Copy the domains, if given. Keep channel->ndomains consistent so
431 * we can clean up in case of error.
433 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
435 /* Avoid zero size allocations at any cost */
436 if (options->ndomains > 0)
438 channel->domains = malloc(options->ndomains * sizeof(char *));
439 if (!channel->domains)
441 for (i = 0; i < options->ndomains; i++)
443 channel->ndomains = i;
444 channel->domains[i] = strdup(options->domains[i]);
445 if (!channel->domains[i])
449 channel->ndomains = options->ndomains;
452 /* Set lookups, if given. */
453 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
455 channel->lookups = strdup(options->lookups);
456 if (!channel->lookups)
461 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
463 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
464 if (!channel->sortlist)
466 for (i = 0; i < options->nsort; i++)
468 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
469 sizeof(struct apattern));
471 channel->nsort = options->nsort;
474 channel->optmask = optmask;
479 static int init_by_environment(ares_channel channel)
481 const char *localdomain, *res_options;
484 localdomain = getenv("LOCALDOMAIN");
485 if (localdomain && channel->ndomains == -1)
487 status = set_search(channel, localdomain);
488 if (status != ARES_SUCCESS)
492 res_options = getenv("RES_OPTIONS");
495 status = set_options(channel, res_options);
496 if (status != ARES_SUCCESS)
505 * Warning: returns a dynamically allocated buffer, the user MUST
506 * use free() if the function returns 1
508 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
510 /* Test for the size we need */
514 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
515 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
517 *obuf = malloc(size+1);
521 if (RegQueryValueEx(hKey, subkey, 0, NULL,
522 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
535 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
537 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
538 DWORD enum_size = 39;
542 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
543 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
548 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
551 rc = get_res_nt(hVal, subkey, obuf);
559 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
561 FIXED_INFO *fi = alloca (sizeof(*fi));
562 DWORD size = sizeof (*fi);
563 typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*);
564 get_net_param_func fpGetNetworkParams; /* available only on Win-98/2000+ */
566 IP_ADDR_STRING *ipAddr;
569 size_t ip_size = sizeof("255.255.255.255,")-1;
570 size_t left = ret_size;
577 handle = LoadLibrary ("iphlpapi.dll");
581 fpGetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
582 if (!fpGetNetworkParams)
585 res = (*fpGetNetworkParams) (fi, &size);
586 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
590 if (!fi || (*fpGetNetworkParams) (fi, &size) != ERROR_SUCCESS)
595 printf ("Host Name: %s\n", fi->HostName);
596 printf ("Domain Name: %s\n", fi->DomainName);
597 printf ("DNS Servers:\n"
598 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
600 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
601 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
604 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
605 left -= ret - ret_buf;
609 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
610 ipAddr = ipAddr->Next, i++)
612 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
614 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
615 left -= ret - ret_buf;
619 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
624 FreeLibrary (handle);
626 if (debug && left <= ip_size)
627 printf ("Too many nameservers. Truncating to %d addressess", count);
634 static int init_by_resolv_conf(ares_channel channel)
637 int status = -1, nservers = 0, nsort = 0;
638 struct server_state *servers = NULL;
639 struct apattern *sortlist = NULL;
644 NameServer info via IPHLPAPI (IP helper API):
645 GetNetworkParams() should be the trusted source for this.
646 Available in Win-98/2000 and later. If that fail, fall-back to
647 registry information.
651 On Windows 9X, the DNS server can be found in:
652 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
654 On Windows NT/2000/XP/2003:
655 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
657 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
659 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
662 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
673 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
676 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
678 status = config_nameserver(&servers, &nservers, buf);
679 if (status == ARES_SUCCESS)
686 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
690 RegOpenKeyEx(mykey, "Interfaces", 0,
691 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
692 if (get_res_nt(mykey, NAMESERVER, &line))
694 status = config_nameserver(&servers, &nservers, line);
697 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
699 status = config_nameserver(&servers, &nservers, line);
702 /* Try the interfaces */
703 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
705 status = config_nameserver(&servers, &nservers, line);
708 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
710 status = config_nameserver(&servers, &nservers, line);
720 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
724 if ((result = RegQueryValueEx(
725 mykey, NAMESERVER, NULL, &data_type,
728 ) == ERROR_SUCCESS ||
729 result == ERROR_MORE_DATA)
733 line = malloc(bytes+1);
734 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
735 (unsigned char *)line, &bytes) ==
738 status = config_nameserver(&servers, &nservers, line);
747 if (status == ARES_SUCCESS)
750 /* Catch the case when all the above checks fail (which happens when there
751 is no network card or the cable is unplugged) */
754 #elif defined(__riscos__)
756 /* Under RISC OS, name servers are listed in the
757 system variable Inet$Resolvers, space separated. */
759 line = getenv("Inet$Resolvers");
762 char *resolvers = strdup(line), *pos, *space;
769 space = strchr(pos, ' ');
772 status = config_nameserver(&servers, &nservers, pos);
773 if (status != ARES_SUCCESS)
778 if (status == ARES_SUCCESS)
784 #elif defined(WATT32)
788 for (i = 0; def_nameservers[i]; i++)
791 return ARES_SUCCESS; /* use localhost DNS server */
794 servers = calloc(sizeof(*servers), i);
798 for (i = 0; def_nameservers[i]; i++)
799 servers[i].addr.s_addr = htonl(def_nameservers[i]);
809 /* Don't read resolv.conf and friends if we don't have to */
810 if (ARES_CONFIG_CHECK(channel))
813 fp = fopen(PATH_RESOLV_CONF, "r");
815 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
817 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
818 status = config_domain(channel, p);
819 else if ((p = try_config(line, "lookup")) && !channel->lookups)
820 status = config_lookup(channel, p, "bind", "file");
821 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
822 status = set_search(channel, p);
823 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
824 status = config_nameserver(&servers, &nservers, p);
825 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
826 status = config_sortlist(&sortlist, &nsort, p);
827 else if ((p = try_config(line, "options")))
828 status = set_options(channel, p);
830 status = ARES_SUCCESS;
831 if (status != ARES_SUCCESS)
844 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
845 error, strerror(error)));
846 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
851 if ((status == ARES_EOF) && (!channel->lookups)) {
852 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
853 fp = fopen("/etc/nsswitch.conf", "r");
855 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
857 if ((p = try_config(line, "hosts:")) && !channel->lookups)
858 status = config_lookup(channel, p, "dns", "files");
870 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
871 error, strerror(error)));
872 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
878 if ((status == ARES_EOF) && (!channel->lookups)) {
879 /* Linux / GNU libc 2.x and possibly others have host.conf */
880 fp = fopen("/etc/host.conf", "r");
882 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
884 if ((p = try_config(line, "order")) && !channel->lookups)
885 status = config_lookup(channel, p, "bind", "hosts");
897 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
898 error, strerror(error)));
899 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
905 if ((status == ARES_EOF) && (!channel->lookups)) {
906 /* Tru64 uses /etc/svc.conf */
907 fp = fopen("/etc/svc.conf", "r");
909 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
911 if ((p = try_config(line, "hosts=")) && !channel->lookups)
912 status = config_lookup(channel, p, "bind", "local");
924 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
925 error, strerror(error)));
926 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
939 if (status != ARES_EOF)
943 if (sortlist != NULL)
948 /* If we got any name server entries, fill them in. */
954 channel->servers = servers;
955 channel->nservers = nservers;
958 /* If we got any sortlist entries, fill them in. */
961 channel->sortlist = sortlist;
962 channel->nsort = nsort;
968 static int init_by_defaults(ares_channel channel)
970 char *hostname = NULL;
971 int rc = ARES_SUCCESS;
973 if (channel->flags == -1)
975 if (channel->timeout == -1)
976 channel->timeout = DEFAULT_TIMEOUT;
977 if (channel->tries == -1)
978 channel->tries = DEFAULT_TRIES;
979 if (channel->ndots == -1)
981 if (channel->rotate == -1)
983 if (channel->udp_port == -1)
984 channel->udp_port = htons(NAMESERVER_PORT);
985 if (channel->tcp_port == -1)
986 channel->tcp_port = htons(NAMESERVER_PORT);
988 if (channel->nservers == -1) {
989 /* If nobody specified servers, try a local named. */
990 channel->servers = malloc(sizeof(struct server_state));
991 if (!channel->servers) {
995 channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
996 channel->nservers = 1;
1000 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1002 #define toolong(x) (x == -1) && (EINVAL == errno)
1005 if (channel->ndomains == -1) {
1006 /* Derive a default domain search list from the kernel hostname,
1007 * or set it to empty if the hostname isn't helpful.
1011 channel->ndomains = 0; /* default to none */
1013 #ifdef HAVE_GETHOSTNAME
1014 hostname = malloc(len);
1021 res = gethostname(hostname, len);
1026 p = realloc(hostname, len);
1041 if (strchr(hostname, '.')) {
1042 /* a dot was found */
1044 channel->domains = malloc(sizeof(char *));
1045 if (!channel->domains) {
1049 channel->domains[0] = strdup(strchr(hostname, '.') + 1);
1050 if (!channel->domains[0]) {
1054 channel->ndomains = 1;
1059 if (channel->nsort == -1) {
1060 channel->sortlist = NULL;
1064 if (!channel->lookups) {
1065 channel->lookups = strdup("fb");
1066 if (!channel->lookups)
1072 if(channel->servers)
1073 free(channel->servers);
1075 if(channel->domains && channel->domains[0])
1076 free(channel->domains[0]);
1077 if(channel->domains)
1078 free(channel->domains);
1079 if(channel->lookups)
1080 free(channel->lookups);
1090 static int config_domain(ares_channel channel, char *str)
1094 /* Set a single search domain. */
1096 while (*q && !ISSPACE(*q))
1099 return set_search(channel, str);
1102 static int config_lookup(ares_channel channel, const char *str,
1103 const char *bindch, const char *filech)
1105 char lookups[3], *l;
1108 /* Set the lookup order. Only the first letter of each work
1109 * is relevant, and it has to be "b" for DNS or "f" for the
1110 * host file. Ignore everything else.
1116 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1117 if (*p == *bindch) *l++ = 'b';
1120 while (*p && !ISSPACE(*p) && (*p != ','))
1122 while (*p && (ISSPACE(*p) || (*p == ',')))
1126 channel->lookups = strdup(lookups);
1127 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1132 static int config_nameserver(struct server_state **servers, int *nservers,
1135 struct in_addr addr;
1136 struct server_state *newserv;
1137 /* On Windows, there may be more than one nameserver specified in the same
1138 * registry key, so we parse it as a space or comma seperated list.
1147 while (*p && !ISSPACE(*p) && *p != ',')
1156 /* Skip multiple spaces or trailing spaces */
1163 /* This is the part that actually sets the nameserver */
1164 addr.s_addr = inet_addr(begin);
1165 if (addr.s_addr == INADDR_NONE)
1167 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1170 newserv[*nservers].addr = addr;
1179 /* Add a nameserver entry, if this is a valid address. */
1180 addr.s_addr = inet_addr(str);
1181 if (addr.s_addr == INADDR_NONE)
1182 return ARES_SUCCESS;
1183 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1186 newserv[*nservers].addr = addr;
1190 return ARES_SUCCESS;
1194 static int config_sortlist(struct apattern **sortlist, int *nsort,
1197 struct apattern pat;
1200 /* Add sortlist entries. */
1201 while (*str && *str != ';')
1204 char ipbuf[16], ipbufpfx[32];
1205 /* Find just the IP */
1207 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1209 memcpy(ipbuf, str, (int)(q-str));
1210 ipbuf[(int)(q-str)] = '\0';
1211 /* Find the prefix */
1214 const char *str2 = q+1;
1215 while (*q && *q != ';' && !ISSPACE(*q))
1217 memcpy(ipbufpfx, str, (int)(q-str));
1218 ipbufpfx[(int)(q-str)] = '\0';
1223 /* Lets see if it is CIDR */
1224 /* First we'll try IPv6 */
1225 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1227 sizeof(pat.addrV6))) > 0)
1229 pat.type = PATTERN_CIDR;
1230 pat.mask.bits = (unsigned short)bits;
1231 pat.family = AF_INET6;
1232 if (!sortlist_alloc(sortlist, nsort, &pat))
1236 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1237 sizeof(pat.addrV4))) > 0)
1239 pat.type = PATTERN_CIDR;
1240 pat.mask.bits = (unsigned short)bits;
1241 pat.family = AF_INET;
1242 if (!sortlist_alloc(sortlist, nsort, &pat))
1245 /* See if it is just a regular IP */
1246 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1250 memcpy(ipbuf, str, (int)(q-str));
1251 ipbuf[(int)(q-str)] = '\0';
1252 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1257 pat.family = AF_INET;
1258 pat.type = PATTERN_MASK;
1259 if (!sortlist_alloc(sortlist, nsort, &pat))
1264 while (*q && *q != ';' && !ISSPACE(*q))
1268 while (ISSPACE(*str))
1272 return ARES_SUCCESS;
1276 static int set_search(ares_channel channel, const char *str)
1281 if(channel->ndomains != -1) {
1282 /* if we already have some domains present, free them first */
1283 for(n=0; n < channel->ndomains; n++)
1284 free(channel->domains[n]);
1285 free(channel->domains);
1286 channel->domains = NULL;
1287 channel->ndomains = -1;
1290 /* Count the domains given. */
1295 while (*p && !ISSPACE(*p))
1304 channel->ndomains = 0;
1305 return ARES_SUCCESS;
1308 channel->domains = malloc(n * sizeof(char *));
1309 if (!channel->domains)
1312 /* Now copy the domains. */
1317 channel->ndomains = n;
1319 while (*q && !ISSPACE(*q))
1321 channel->domains[n] = malloc(q - p + 1);
1322 if (!channel->domains[n])
1324 memcpy(channel->domains[n], p, q - p);
1325 channel->domains[n][q - p] = 0;
1331 channel->ndomains = n;
1333 return ARES_SUCCESS;
1336 static int set_options(ares_channel channel, const char *str)
1338 const char *p, *q, *val;
1344 while (*q && !ISSPACE(*q))
1346 val = try_option(p, q, "ndots:");
1347 if (val && channel->ndots == -1)
1348 channel->ndots = atoi(val);
1349 val = try_option(p, q, "retrans:");
1350 if (val && channel->timeout == -1)
1351 channel->timeout = atoi(val);
1352 val = try_option(p, q, "retry:");
1353 if (val && channel->tries == -1)
1354 channel->tries = atoi(val);
1355 val = try_option(p, q, "rotate");
1356 if (val && channel->rotate == -1)
1357 channel->rotate = 1;
1363 return ARES_SUCCESS;
1367 static char *try_config(char *s, const char *opt)
1375 /* no line or no option */
1378 /* trim line comment */
1379 for (i = 0; s[i] && s[i] != '#'; ++i);
1382 /* trim trailing whitespace */
1383 for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
1386 /* skip leading whitespace */
1387 for (i = 0; s[i] && ISSPACE(s[i]); ++i);
1394 if ((len = strlen(opt)) == 0)
1398 if (strncmp(p, opt, len) != 0)
1399 /* line and option do not match */
1402 /* skip over given option name */
1406 /* no option value */
1409 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1410 /* whitespace between option name and value is mandatory
1411 for given option names which do not end with ':' or '=' */
1414 /* skip over whitespace */
1415 while (*p && ISSPACE(*p))
1419 /* no option value */
1422 /* return pointer to option value */
1427 static const char *try_option(const char *p, const char *q, const char *opt)
1429 size_t len = strlen(opt);
1430 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1434 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1435 struct apattern *pat)
1437 struct apattern *newsort;
1438 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1441 newsort[*nsort] = *pat;
1442 *sortlist = newsort;
1447 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1450 /* Four octets and three periods yields at most 15 characters. */
1454 addr->s_addr = inet_addr(ipbuf);
1455 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1460 static void natural_mask(struct apattern *pat)
1462 struct in_addr addr;
1464 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1467 addr.s_addr = ntohl(pat->addrV4.s_addr);
1469 /* This is out of date in the CIDR world, but some people might
1472 if (IN_CLASSA(addr.s_addr))
1473 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1474 else if (IN_CLASSB(addr.s_addr))
1475 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1477 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1480 /* initialize an rc4 key. If possible a cryptographically secure random key
1481 is generated using a suitable function (for example win32's RtlGenRandom as
1483 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1484 otherwise the code defaults to cross-platform albeit less secure mechanism
1487 static void randomize_key(unsigned char* key,int key_data_len)
1492 HMODULE lib=LoadLibrary("ADVAPI32.DLL");
1494 BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
1495 (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(lib,"SystemFunction036");
1496 if (pfn && pfn(key,key_data_len) )
1503 FILE *f = fopen(RANDOM_FILE, "rb");
1505 counter = fread(key, 1, key_data_len, f);
1511 if ( !randomized ) {
1512 for (;counter<key_data_len;counter++)
1513 key[counter]=(unsigned char)(rand() % 256);
1517 static int init_id_key(rc4_key* key,int key_data_len)
1519 unsigned char index1;
1520 unsigned char index2;
1521 unsigned char* state;
1523 unsigned char *key_data_ptr = 0;
1525 key_data_ptr = calloc(1,key_data_len);
1529 state = &key->state[0];
1530 for(counter = 0; counter < 256; counter++)
1531 /* unnecessary AND but it keeps some compilers happier */
1532 state[counter] = (unsigned char)(counter & 0xff);
1533 randomize_key(key->state,key_data_len);
1538 for(counter = 0; counter < 256; counter++)
1540 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1542 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1544 index1 = (unsigned char)((index1 + 1) % key_data_len);
1547 return ARES_SUCCESS;
1550 unsigned short ares__generate_new_id(rc4_key* key)
1553 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1557 void ares_set_socket_callback(ares_channel channel,
1558 ares_sock_create_callback cb,
1561 channel->sock_create_cb = cb;
1562 channel->sock_create_cb_data = data;