3 /* Copyright 1998 by the Massachusetts Institute of Technology.
4 * Copyright (C) 2007-2008 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)
26 #ifdef HAVE_SYS_PARAM_H
27 #include <sys/param.h>
30 #ifdef HAVE_SYS_TIME_H
34 #ifdef HAVE_SYS_SOCKET_H
35 #include <sys/socket.h>
38 #ifdef HAVE_NETINET_IN_H
39 #include <netinet/in.h>
46 #ifdef HAVE_ARPA_INET_H
47 #include <arpa/inet.h>
50 #ifdef HAVE_ARPA_NAMESER_H
51 # include <arpa/nameser.h>
55 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
56 # include <arpa/nameser_compat.h>
70 #include "inet_net_pton.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);
83 static int config_nameserver(struct server_state **servers, int *nservers,
85 static int set_search(ares_channel channel, const char *str);
86 static int set_options(ares_channel channel, const char *str);
87 static const char *try_option(const char *p, const char *q, const char *opt);
88 static int init_id_key(rc4_key* key,int key_data_len);
91 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
92 static int ip_addr(const char *s, int len, struct in_addr *addr);
93 static void natural_mask(struct apattern *pat);
94 static int config_domain(ares_channel channel, char *str);
95 static int config_lookup(ares_channel channel, const char *str,
96 const char *bindch, const char *filech);
97 static int config_sortlist(struct apattern **sortlist, int *nsort,
99 static char *try_config(char *s, const char *opt);
102 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
103 x->nservers > -1 && \
104 x->ndomains > -1 && \
105 x->ndots > -1 && x->timeout > -1 && \
108 int ares_init(ares_channel *channelptr)
110 return ares_init_options(channelptr, NULL, 0);
113 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
116 ares_channel channel;
118 int status = ARES_SUCCESS;
119 struct server_state *server;
123 const char *env = getenv("CARES_MEMDEBUG");
127 env = getenv("CARES_MEMLIMIT");
129 curl_memlimit(atoi(env));
132 channel = malloc(sizeof(struct ares_channeldata));
140 /* Set everything to distinguished values so we know they haven't
144 channel->timeout = -1;
147 channel->rotate = -1;
148 channel->udp_port = -1;
149 channel->tcp_port = -1;
150 channel->socket_send_buffer_size = -1;
151 channel->socket_receive_buffer_size = -1;
152 channel->nservers = -1;
153 channel->ndomains = -1;
155 channel->tcp_connection_generation = 0;
156 channel->lookups = NULL;
157 channel->domains = NULL;
158 channel->sortlist = NULL;
159 channel->servers = NULL;
160 channel->sock_state_cb = NULL;
161 channel->sock_state_cb_data = NULL;
163 channel->last_server = 0;
164 channel->last_timeout_processed = (time_t)now.tv_sec;
166 /* Initialize our lists of queries */
167 ares__init_list_head(&(channel->all_queries));
168 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
170 ares__init_list_head(&(channel->queries_by_qid[i]));
172 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
174 ares__init_list_head(&(channel->queries_by_timeout[i]));
177 /* Initialize configuration by each of the four sources, from highest
178 * precedence to lowest.
181 if (status == ARES_SUCCESS) {
182 status = init_by_options(channel, options, optmask);
183 if (status != ARES_SUCCESS)
184 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
185 ares_strerror(status)));
187 if (status == ARES_SUCCESS) {
188 status = init_by_environment(channel);
189 if (status != ARES_SUCCESS)
190 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
191 ares_strerror(status)));
193 if (status == ARES_SUCCESS) {
194 status = init_by_resolv_conf(channel);
195 if (status != ARES_SUCCESS)
196 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
197 ares_strerror(status)));
199 if (status == ARES_SUCCESS) {
200 status = init_by_defaults(channel);
201 if (status != ARES_SUCCESS)
202 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
203 ares_strerror(status)));
206 /* Generate random key */
208 if (status == ARES_SUCCESS) {
209 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
210 if (status == ARES_SUCCESS)
211 channel->next_id = ares__generate_new_id(&channel->id_key);
213 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
214 ares_strerror(status)));
217 if (status != ARES_SUCCESS)
219 /* Something failed; clean up memory we may have allocated. */
220 if (channel->servers)
221 free(channel->servers);
222 if (channel->domains)
224 for (i = 0; i < channel->ndomains; i++)
225 free(channel->domains[i]);
226 free(channel->domains);
228 if (channel->sortlist)
229 free(channel->sortlist);
231 free(channel->lookups);
236 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
237 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
238 channel->nservers = 1;
240 /* Initialize server states. */
241 for (i = 0; i < channel->nservers; i++)
243 server = &channel->servers[i];
244 server->udp_socket = ARES_SOCKET_BAD;
245 server->tcp_socket = ARES_SOCKET_BAD;
246 server->tcp_connection_generation = ++channel->tcp_connection_generation;
247 server->tcp_lenbuf_pos = 0;
248 server->tcp_buffer = NULL;
249 server->qhead = NULL;
250 server->qtail = NULL;
251 ares__init_list_head(&(server->queries_to_server));
252 server->channel = channel;
253 server->is_broken = 0;
256 *channelptr = channel;
260 /* ares_dup() duplicates a channel handle with all its options and returns a
261 new channel handle */
262 int ares_dup(ares_channel *dest, ares_channel src)
264 struct ares_options opts;
268 *dest = NULL; /* in case of failure return NULL explicitly */
270 /* First get the options supported by the old ares_save_options() function,
271 which is most of them */
272 rc = ares_save_options(src, &opts, &optmask);
276 /* Then create the new channel with those options */
277 rc = ares_init_options(dest, &opts, optmask);
279 /* destroy the options copy to not leak any memory */
280 ares_destroy_options(&opts);
285 /* Now clone the options that ares_save_options() doesn't support. */
287 /* No such options available yet */
289 return ARES_SUCCESS; /* everything went fine */
293 /* Save options from initialized channel */
294 int ares_save_options(ares_channel channel, struct ares_options *options,
299 /* Zero everything out */
300 memset(options, 0, sizeof(struct ares_options));
302 if (!ARES_CONFIG_CHECK(channel))
305 /* Traditionally the optmask wasn't saved in the channel struct so it was
306 recreated here. ROTATE is the first option that has no struct field of
307 its own in the public config struct */
308 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
309 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
310 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
311 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
312 (channel->optmask & ARES_OPT_ROTATE);
314 /* Copy easy stuff */
315 options->flags = channel->flags;
317 /* We return full millisecond resolution but that's only because we don't
318 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
319 options->timeout = channel->timeout;
320 options->tries = channel->tries;
321 options->ndots = channel->ndots;
322 options->udp_port = (unsigned short)channel->udp_port;
323 options->tcp_port = (unsigned short)channel->tcp_port;
324 options->sock_state_cb = channel->sock_state_cb;
325 options->sock_state_cb_data = channel->sock_state_cb_data;
328 if (channel->nservers) {
330 malloc(channel->nservers * sizeof(struct server_state));
331 if (!options->servers && channel->nservers != 0)
333 for (i = 0; i < channel->nservers; i++)
334 options->servers[i] = channel->servers[i].addr;
336 options->nservers = channel->nservers;
339 if (channel->ndomains) {
340 options->domains = malloc(channel->ndomains * sizeof(char *));
341 if (!options->domains)
344 for (i = 0; i < channel->ndomains; i++)
346 options->ndomains = i;
347 options->domains[i] = strdup(channel->domains[i]);
348 if (!options->domains[i])
352 options->ndomains = channel->ndomains;
355 if (channel->lookups) {
356 options->lookups = strdup(channel->lookups);
357 if (!options->lookups && channel->lookups)
362 if (channel->nsort) {
363 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
364 if (!options->sortlist)
366 for (i = 0; i < channel->nsort; i++)
368 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
369 sizeof(struct apattern));
372 options->nsort = channel->nsort;
377 static int init_by_options(ares_channel channel,
378 const struct ares_options *options,
384 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
385 channel->flags = options->flags;
386 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
387 channel->timeout = options->timeout;
388 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
389 channel->timeout = options->timeout * 1000;
390 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
391 channel->tries = options->tries;
392 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
393 channel->ndots = options->ndots;
394 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
396 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
397 channel->udp_port = options->udp_port;
398 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
399 channel->tcp_port = options->tcp_port;
400 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
402 channel->sock_state_cb = options->sock_state_cb;
403 channel->sock_state_cb_data = options->sock_state_cb_data;
405 if ((optmask & ARES_OPT_SOCK_SNDBUF)
406 && channel->socket_send_buffer_size == -1)
407 channel->socket_send_buffer_size = options->socket_send_buffer_size;
408 if ((optmask & ARES_OPT_SOCK_RCVBUF)
409 && channel->socket_receive_buffer_size == -1)
410 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
412 /* Copy the servers, if given. */
413 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
415 /* Avoid zero size allocations at any cost */
416 if (options->nservers > 0)
419 malloc(options->nservers * sizeof(struct server_state));
420 if (!channel->servers)
422 for (i = 0; i < options->nservers; i++)
423 channel->servers[i].addr = options->servers[i];
425 channel->nservers = options->nservers;
428 /* Copy the domains, if given. Keep channel->ndomains consistent so
429 * we can clean up in case of error.
431 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
433 /* Avoid zero size allocations at any cost */
434 if (options->ndomains > 0)
436 channel->domains = malloc(options->ndomains * sizeof(char *));
437 if (!channel->domains)
439 for (i = 0; i < options->ndomains; i++)
441 channel->ndomains = i;
442 channel->domains[i] = strdup(options->domains[i]);
443 if (!channel->domains[i])
447 channel->ndomains = options->ndomains;
450 /* Set lookups, if given. */
451 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
453 channel->lookups = strdup(options->lookups);
454 if (!channel->lookups)
459 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
461 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
462 if (!channel->sortlist)
464 for (i = 0; i < options->nsort; i++)
466 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
467 sizeof(struct apattern));
469 channel->nsort = options->nsort;
472 channel->optmask = optmask;
477 static int init_by_environment(ares_channel channel)
479 const char *localdomain, *res_options;
482 localdomain = getenv("LOCALDOMAIN");
483 if (localdomain && channel->ndomains == -1)
485 status = set_search(channel, localdomain);
486 if (status != ARES_SUCCESS)
490 res_options = getenv("RES_OPTIONS");
493 status = set_options(channel, res_options);
494 if (status != ARES_SUCCESS)
503 * Warning: returns a dynamically allocated buffer, the user MUST
504 * use free() if the function returns 1
506 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
508 /* Test for the size we need */
512 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
513 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
515 *obuf = malloc(size+1);
519 if (RegQueryValueEx(hKey, subkey, 0, NULL,
520 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
533 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
535 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
536 DWORD enum_size = 39;
540 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
541 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
546 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
549 rc = get_res_nt(hVal, subkey, obuf);
557 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
559 FIXED_INFO *fi = alloca (sizeof(*fi));
560 DWORD size = sizeof (*fi);
561 typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*);
562 get_net_param_func fpGetNetworkParams; /* available only on Win-98/2000+ */
564 IP_ADDR_STRING *ipAddr;
567 size_t ip_size = sizeof("255.255.255.255,")-1;
568 size_t left = ret_size;
575 handle = LoadLibrary ("iphlpapi.dll");
579 fpGetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
580 if (!fpGetNetworkParams)
583 res = (*fpGetNetworkParams) (fi, &size);
584 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
588 if (!fi || (*fpGetNetworkParams) (fi, &size) != ERROR_SUCCESS)
593 printf ("Host Name: %s\n", fi->HostName);
594 printf ("Domain Name: %s\n", fi->DomainName);
595 printf ("DNS Servers:\n"
596 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
598 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
599 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
602 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
603 left -= ret - ret_buf;
607 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
608 ipAddr = ipAddr->Next, i++)
610 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
612 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
613 left -= ret - ret_buf;
617 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
622 FreeLibrary (handle);
624 if (debug && left <= ip_size)
625 printf ("Too many nameservers. Truncating to %d addressess", count);
632 static int init_by_resolv_conf(ares_channel channel)
635 int status = -1, nservers = 0, nsort = 0;
636 struct server_state *servers = NULL;
637 struct apattern *sortlist = NULL;
642 NameServer info via IPHLPAPI (IP helper API):
643 GetNetworkParams() should be the trusted source for this.
644 Available in Win-98/2000 and later. If that fail, fall-back to
645 registry information.
649 On Windows 9X, the DNS server can be found in:
650 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
652 On Windows NT/2000/XP/2003:
653 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
655 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
657 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
660 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
671 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
674 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
676 status = config_nameserver(&servers, &nservers, buf);
677 if (status == ARES_SUCCESS)
684 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
688 RegOpenKeyEx(mykey, "Interfaces", 0,
689 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
690 if (get_res_nt(mykey, NAMESERVER, &line))
692 status = config_nameserver(&servers, &nservers, line);
695 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
697 status = config_nameserver(&servers, &nservers, line);
700 /* Try the interfaces */
701 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
703 status = config_nameserver(&servers, &nservers, line);
706 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
708 status = config_nameserver(&servers, &nservers, line);
718 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
722 if ((result = RegQueryValueEx(
723 mykey, NAMESERVER, NULL, &data_type,
726 ) == ERROR_SUCCESS ||
727 result == ERROR_MORE_DATA)
731 line = malloc(bytes+1);
732 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
733 (unsigned char *)line, &bytes) ==
736 status = config_nameserver(&servers, &nservers, line);
745 if (status == ARES_SUCCESS)
748 /* Catch the case when all the above checks fail (which happens when there
749 is no network card or the cable is unplugged) */
752 #elif defined(__riscos__)
754 /* Under RISC OS, name servers are listed in the
755 system variable Inet$Resolvers, space separated. */
757 line = getenv("Inet$Resolvers");
760 char *resolvers = strdup(line), *pos, *space;
767 space = strchr(pos, ' ');
770 status = config_nameserver(&servers, &nservers, pos);
771 if (status != ARES_SUCCESS)
776 if (status == ARES_SUCCESS)
782 #elif defined(WATT32)
786 for (i = 0; def_nameservers[i]; i++)
789 return ARES_SUCCESS; /* use localhost DNS server */
792 servers = calloc(sizeof(*servers), i);
796 for (i = 0; def_nameservers[i]; i++)
797 servers[i].addr.s_addr = htonl(def_nameservers[i]);
807 /* Don't read resolv.conf and friends if we don't have to */
808 if (ARES_CONFIG_CHECK(channel))
811 fp = fopen(PATH_RESOLV_CONF, "r");
813 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
815 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
816 status = config_domain(channel, p);
817 else if ((p = try_config(line, "lookup")) && !channel->lookups)
818 status = config_lookup(channel, p, "bind", "file");
819 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
820 status = set_search(channel, p);
821 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
822 status = config_nameserver(&servers, &nservers, p);
823 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
824 status = config_sortlist(&sortlist, &nsort, p);
825 else if ((p = try_config(line, "options")))
826 status = set_options(channel, p);
828 status = ARES_SUCCESS;
829 if (status != ARES_SUCCESS)
842 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
843 error, strerror(error)));
844 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
849 if ((status == ARES_EOF) && (!channel->lookups)) {
850 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
851 fp = fopen("/etc/nsswitch.conf", "r");
853 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
855 if ((p = try_config(line, "hosts:")) && !channel->lookups)
856 status = config_lookup(channel, p, "dns", "files");
868 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
869 error, strerror(error)));
870 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
876 if ((status == ARES_EOF) && (!channel->lookups)) {
877 /* Linux / GNU libc 2.x and possibly others have host.conf */
878 fp = fopen("/etc/host.conf", "r");
880 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
882 if ((p = try_config(line, "order")) && !channel->lookups)
883 status = config_lookup(channel, p, "bind", "hosts");
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/host.conf"));
903 if ((status == ARES_EOF) && (!channel->lookups)) {
904 /* Tru64 uses /etc/svc.conf */
905 fp = fopen("/etc/svc.conf", "r");
907 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
909 if ((p = try_config(line, "hosts=")) && !channel->lookups)
910 status = config_lookup(channel, p, "bind", "local");
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/svc.conf"));
937 if (status != ARES_EOF)
941 if (sortlist != NULL)
946 /* If we got any name server entries, fill them in. */
952 channel->servers = servers;
953 channel->nservers = nservers;
956 /* If we got any sortlist entries, fill them in. */
959 channel->sortlist = sortlist;
960 channel->nsort = nsort;
966 static int init_by_defaults(ares_channel channel)
968 char *hostname = NULL;
969 int rc = ARES_SUCCESS;
971 if (channel->flags == -1)
973 if (channel->timeout == -1)
974 channel->timeout = DEFAULT_TIMEOUT;
975 if (channel->tries == -1)
976 channel->tries = DEFAULT_TRIES;
977 if (channel->ndots == -1)
979 if (channel->rotate == -1)
981 if (channel->udp_port == -1)
982 channel->udp_port = htons(NAMESERVER_PORT);
983 if (channel->tcp_port == -1)
984 channel->tcp_port = htons(NAMESERVER_PORT);
986 if (channel->nservers == -1) {
987 /* If nobody specified servers, try a local named. */
988 channel->servers = malloc(sizeof(struct server_state));
989 if (!channel->servers) {
993 channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
994 channel->nservers = 1;
998 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1000 #define toolong(x) (x == -1) && (EINVAL == errno)
1003 if (channel->ndomains == -1) {
1004 /* Derive a default domain search list from the kernel hostname,
1005 * or set it to empty if the hostname isn't helpful.
1009 channel->ndomains = 0; /* default to none */
1011 #ifdef HAVE_GETHOSTNAME
1012 hostname = malloc(len);
1019 res = gethostname(hostname, len);
1024 p = realloc(hostname, len);
1039 if (strchr(hostname, '.')) {
1040 /* a dot was found */
1042 channel->domains = malloc(sizeof(char *));
1043 if (!channel->domains) {
1047 channel->domains[0] = strdup(strchr(hostname, '.') + 1);
1048 if (!channel->domains[0]) {
1052 channel->ndomains = 1;
1057 if (channel->nsort == -1) {
1058 channel->sortlist = NULL;
1062 if (!channel->lookups) {
1063 channel->lookups = strdup("fb");
1064 if (!channel->lookups)
1070 if(channel->servers)
1071 free(channel->servers);
1073 if(channel->domains && channel->domains[0])
1074 free(channel->domains[0]);
1075 if(channel->domains)
1076 free(channel->domains);
1077 if(channel->lookups)
1078 free(channel->lookups);
1088 static int config_domain(ares_channel channel, char *str)
1092 /* Set a single search domain. */
1094 while (*q && !ISSPACE(*q))
1097 return set_search(channel, str);
1100 static int config_lookup(ares_channel channel, const char *str,
1101 const char *bindch, const char *filech)
1103 char lookups[3], *l;
1106 /* Set the lookup order. Only the first letter of each work
1107 * is relevant, and it has to be "b" for DNS or "f" for the
1108 * host file. Ignore everything else.
1114 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1115 if (*p == *bindch) *l++ = 'b';
1118 while (*p && !ISSPACE(*p) && (*p != ','))
1120 while (*p && (ISSPACE(*p) || (*p == ',')))
1124 channel->lookups = strdup(lookups);
1125 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1130 static int config_nameserver(struct server_state **servers, int *nservers,
1133 struct in_addr addr;
1134 struct server_state *newserv;
1135 /* On Windows, there may be more than one nameserver specified in the same
1136 * registry key, so we parse it as a space or comma seperated list.
1145 while (*p && !ISSPACE(*p) && *p != ',')
1154 /* Skip multiple spaces or trailing spaces */
1161 /* This is the part that actually sets the nameserver */
1162 addr.s_addr = inet_addr(begin);
1163 if (addr.s_addr == INADDR_NONE)
1165 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1168 newserv[*nservers].addr = addr;
1177 /* Add a nameserver entry, if this is a valid address. */
1178 addr.s_addr = inet_addr(str);
1179 if (addr.s_addr == INADDR_NONE)
1180 return ARES_SUCCESS;
1181 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1184 newserv[*nservers].addr = addr;
1188 return ARES_SUCCESS;
1192 static int config_sortlist(struct apattern **sortlist, int *nsort,
1195 struct apattern pat;
1198 /* Add sortlist entries. */
1199 while (*str && *str != ';')
1202 char ipbuf[16], ipbufpfx[32];
1203 /* Find just the IP */
1205 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1207 memcpy(ipbuf, str, (int)(q-str));
1208 ipbuf[(int)(q-str)] = '\0';
1209 /* Find the prefix */
1212 const char *str2 = q+1;
1213 while (*q && *q != ';' && !ISSPACE(*q))
1215 memcpy(ipbufpfx, str, (int)(q-str));
1216 ipbufpfx[(int)(q-str)] = '\0';
1221 /* Lets see if it is CIDR */
1222 /* First we'll try IPv6 */
1223 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1225 sizeof(pat.addrV6))) > 0)
1227 pat.type = PATTERN_CIDR;
1228 pat.mask.bits = (unsigned short)bits;
1229 pat.family = AF_INET6;
1230 if (!sortlist_alloc(sortlist, nsort, &pat))
1234 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1235 sizeof(pat.addrV4))) > 0)
1237 pat.type = PATTERN_CIDR;
1238 pat.mask.bits = (unsigned short)bits;
1239 pat.family = AF_INET;
1240 if (!sortlist_alloc(sortlist, nsort, &pat))
1243 /* See if it is just a regular IP */
1244 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1248 memcpy(ipbuf, str, (int)(q-str));
1249 ipbuf[(int)(q-str)] = '\0';
1250 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1255 pat.family = AF_INET;
1256 pat.type = PATTERN_MASK;
1257 if (!sortlist_alloc(sortlist, nsort, &pat))
1262 while (*q && *q != ';' && !ISSPACE(*q))
1266 while (ISSPACE(*str))
1270 return ARES_SUCCESS;
1274 static int set_search(ares_channel channel, const char *str)
1279 if(channel->ndomains != -1) {
1280 /* if we already have some domains present, free them first */
1281 for(n=0; n < channel->ndomains; n++)
1282 free(channel->domains[n]);
1283 free(channel->domains);
1284 channel->domains = NULL;
1285 channel->ndomains = -1;
1288 /* Count the domains given. */
1293 while (*p && !ISSPACE(*p))
1302 channel->ndomains = 0;
1303 return ARES_SUCCESS;
1306 channel->domains = malloc(n * sizeof(char *));
1307 if (!channel->domains)
1310 /* Now copy the domains. */
1315 channel->ndomains = n;
1317 while (*q && !ISSPACE(*q))
1319 channel->domains[n] = malloc(q - p + 1);
1320 if (!channel->domains[n])
1322 memcpy(channel->domains[n], p, q - p);
1323 channel->domains[n][q - p] = 0;
1329 channel->ndomains = n;
1331 return ARES_SUCCESS;
1334 static int set_options(ares_channel channel, const char *str)
1336 const char *p, *q, *val;
1342 while (*q && !ISSPACE(*q))
1344 val = try_option(p, q, "ndots:");
1345 if (val && channel->ndots == -1)
1346 channel->ndots = atoi(val);
1347 val = try_option(p, q, "retrans:");
1348 if (val && channel->timeout == -1)
1349 channel->timeout = atoi(val);
1350 val = try_option(p, q, "retry:");
1351 if (val && channel->tries == -1)
1352 channel->tries = atoi(val);
1353 val = try_option(p, q, "rotate");
1354 if (val && channel->rotate == -1)
1355 channel->rotate = 1;
1361 return ARES_SUCCESS;
1365 static char *try_config(char *s, const char *opt)
1373 /* no line or no option */
1376 /* trim line comment */
1377 for (i = 0; s[i] && s[i] != '#'; ++i);
1380 /* trim trailing whitespace */
1381 for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
1384 /* skip leading whitespace */
1385 for (i = 0; s[i] && ISSPACE(s[i]); ++i);
1392 if ((len = strlen(opt)) == 0)
1396 if (strncmp(p, opt, len) != 0)
1397 /* line and option do not match */
1400 /* skip over given option name */
1404 /* no option value */
1407 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1408 /* whitespace between option name and value is mandatory
1409 for given option names which do not end with ':' or '=' */
1412 /* skip over whitespace */
1413 while (*p && ISSPACE(*p))
1417 /* no option value */
1420 /* return pointer to option value */
1425 static const char *try_option(const char *p, const char *q, const char *opt)
1427 size_t len = strlen(opt);
1428 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1432 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1433 struct apattern *pat)
1435 struct apattern *newsort;
1436 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1439 newsort[*nsort] = *pat;
1440 *sortlist = newsort;
1445 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1448 /* Four octets and three periods yields at most 15 characters. */
1452 addr->s_addr = inet_addr(ipbuf);
1453 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1458 static void natural_mask(struct apattern *pat)
1460 struct in_addr addr;
1462 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1465 addr.s_addr = ntohl(pat->addrV4.s_addr);
1467 /* This is out of date in the CIDR world, but some people might
1470 if (IN_CLASSA(addr.s_addr))
1471 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1472 else if (IN_CLASSB(addr.s_addr))
1473 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1475 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1478 /* initialize an rc4 key. If possible a cryptographically secure random key
1479 is generated using a suitable function (for example win32's RtlGenRandom as
1481 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1482 otherwise the code defaults to cross-platform albeit less secure mechanism
1485 static void randomize_key(unsigned char* key,int key_data_len)
1490 HMODULE lib=LoadLibrary("ADVAPI32.DLL");
1492 BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
1493 (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(lib,"SystemFunction036");
1494 if (pfn && pfn(key,key_data_len) )
1501 FILE *f = fopen(RANDOM_FILE, "rb");
1503 counter = fread(key, 1, key_data_len, f);
1509 if ( !randomized ) {
1510 for (;counter<key_data_len;counter++)
1511 key[counter]=(unsigned char)(rand() % 256);
1515 static int init_id_key(rc4_key* key,int key_data_len)
1517 unsigned char index1;
1518 unsigned char index2;
1519 unsigned char* state;
1521 unsigned char *key_data_ptr = 0;
1523 key_data_ptr = calloc(1,key_data_len);
1527 state = &key->state[0];
1528 for(counter = 0; counter < 256; counter++)
1529 /* unnecessary AND but it keeps some compilers happier */
1530 state[counter] = (unsigned char)(counter & 0xff);
1531 randomize_key(key->state,key_data_len);
1536 for(counter = 0; counter < 256; counter++)
1538 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1540 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1542 index1 = (unsigned char)((index1 + 1) % key_data_len);
1545 return ARES_SUCCESS;
1548 unsigned short ares__generate_new_id(rc4_key* key)
1551 ares__rc4(key, (unsigned char *)&r, sizeof(r));