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_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);
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 if (ares_library_initialized() != ARES_SUCCESS)
133 return ARES_ENOTINITIALIZED;
135 channel = malloc(sizeof(struct ares_channeldata));
143 /* Set everything to distinguished values so we know they haven't
147 channel->timeout = -1;
150 channel->rotate = -1;
151 channel->udp_port = -1;
152 channel->tcp_port = -1;
153 channel->socket_send_buffer_size = -1;
154 channel->socket_receive_buffer_size = -1;
155 channel->nservers = -1;
156 channel->ndomains = -1;
158 channel->tcp_connection_generation = 0;
159 channel->lookups = NULL;
160 channel->domains = NULL;
161 channel->sortlist = NULL;
162 channel->servers = NULL;
163 channel->sock_state_cb = NULL;
164 channel->sock_state_cb_data = NULL;
165 channel->sock_create_cb = NULL;
166 channel->sock_create_cb_data = NULL;
168 channel->last_server = 0;
169 channel->last_timeout_processed = (time_t)now.tv_sec;
171 /* Initialize our lists of queries */
172 ares__init_list_head(&(channel->all_queries));
173 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
175 ares__init_list_head(&(channel->queries_by_qid[i]));
177 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
179 ares__init_list_head(&(channel->queries_by_timeout[i]));
182 /* Initialize configuration by each of the four sources, from highest
183 * precedence to lowest.
186 if (status == ARES_SUCCESS) {
187 status = init_by_options(channel, options, optmask);
188 if (status != ARES_SUCCESS)
189 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
190 ares_strerror(status)));
192 if (status == ARES_SUCCESS) {
193 status = init_by_environment(channel);
194 if (status != ARES_SUCCESS)
195 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
196 ares_strerror(status)));
198 if (status == ARES_SUCCESS) {
199 status = init_by_resolv_conf(channel);
200 if (status != ARES_SUCCESS)
201 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
202 ares_strerror(status)));
204 if (status == ARES_SUCCESS) {
205 status = init_by_defaults(channel);
206 if (status != ARES_SUCCESS)
207 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
208 ares_strerror(status)));
211 /* Generate random key */
213 if (status == ARES_SUCCESS) {
214 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
215 if (status == ARES_SUCCESS)
216 channel->next_id = ares__generate_new_id(&channel->id_key);
218 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
219 ares_strerror(status)));
222 if (status != ARES_SUCCESS)
224 /* Something failed; clean up memory we may have allocated. */
225 if (channel->servers)
226 free(channel->servers);
227 if (channel->domains)
229 for (i = 0; i < channel->ndomains; i++)
230 free(channel->domains[i]);
231 free(channel->domains);
233 if (channel->sortlist)
234 free(channel->sortlist);
236 free(channel->lookups);
241 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
242 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
243 channel->nservers = 1;
245 /* Initialize server states. */
246 for (i = 0; i < channel->nservers; i++)
248 server = &channel->servers[i];
249 server->udp_socket = ARES_SOCKET_BAD;
250 server->tcp_socket = ARES_SOCKET_BAD;
251 server->tcp_connection_generation = ++channel->tcp_connection_generation;
252 server->tcp_lenbuf_pos = 0;
253 server->tcp_buffer = NULL;
254 server->qhead = NULL;
255 server->qtail = NULL;
256 ares__init_list_head(&(server->queries_to_server));
257 server->channel = channel;
258 server->is_broken = 0;
261 *channelptr = channel;
265 /* ares_dup() duplicates a channel handle with all its options and returns a
266 new channel handle */
267 int ares_dup(ares_channel *dest, ares_channel src)
269 struct ares_options opts;
273 *dest = NULL; /* in case of failure return NULL explicitly */
275 /* First get the options supported by the old ares_save_options() function,
276 which is most of them */
277 rc = ares_save_options(src, &opts, &optmask);
281 /* Then create the new channel with those options */
282 rc = ares_init_options(dest, &opts, optmask);
284 /* destroy the options copy to not leak any memory */
285 ares_destroy_options(&opts);
290 /* Now clone the options that ares_save_options() doesn't support. */
291 (*dest)->sock_create_cb = src->sock_create_cb;
292 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
295 return ARES_SUCCESS; /* everything went fine */
299 /* Save options from initialized channel */
300 int ares_save_options(ares_channel channel, struct ares_options *options,
305 /* Zero everything out */
306 memset(options, 0, sizeof(struct ares_options));
308 if (!ARES_CONFIG_CHECK(channel))
311 /* Traditionally the optmask wasn't saved in the channel struct so it was
312 recreated here. ROTATE is the first option that has no struct field of
313 its own in the public config struct */
314 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
315 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
316 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
317 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
318 (channel->optmask & ARES_OPT_ROTATE);
320 /* Copy easy stuff */
321 options->flags = channel->flags;
323 /* We return full millisecond resolution but that's only because we don't
324 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
325 options->timeout = channel->timeout;
326 options->tries = channel->tries;
327 options->ndots = channel->ndots;
328 options->udp_port = (unsigned short)channel->udp_port;
329 options->tcp_port = (unsigned short)channel->tcp_port;
330 options->sock_state_cb = channel->sock_state_cb;
331 options->sock_state_cb_data = channel->sock_state_cb_data;
334 if (channel->nservers) {
336 malloc(channel->nservers * sizeof(struct server_state));
337 if (!options->servers && channel->nservers != 0)
339 for (i = 0; i < channel->nservers; i++)
340 options->servers[i] = channel->servers[i].addr;
342 options->nservers = channel->nservers;
345 if (channel->ndomains) {
346 options->domains = malloc(channel->ndomains * sizeof(char *));
347 if (!options->domains)
350 for (i = 0; i < channel->ndomains; i++)
352 options->ndomains = i;
353 options->domains[i] = strdup(channel->domains[i]);
354 if (!options->domains[i])
358 options->ndomains = channel->ndomains;
361 if (channel->lookups) {
362 options->lookups = strdup(channel->lookups);
363 if (!options->lookups && channel->lookups)
368 if (channel->nsort) {
369 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
370 if (!options->sortlist)
372 for (i = 0; i < channel->nsort; i++)
374 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
375 sizeof(struct apattern));
378 options->nsort = channel->nsort;
383 static int init_by_options(ares_channel channel,
384 const struct ares_options *options,
390 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
391 channel->flags = options->flags;
392 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
393 channel->timeout = options->timeout;
394 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
395 channel->timeout = options->timeout * 1000;
396 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
397 channel->tries = options->tries;
398 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
399 channel->ndots = options->ndots;
400 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
402 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
403 channel->udp_port = options->udp_port;
404 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
405 channel->tcp_port = options->tcp_port;
406 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
408 channel->sock_state_cb = options->sock_state_cb;
409 channel->sock_state_cb_data = options->sock_state_cb_data;
411 if ((optmask & ARES_OPT_SOCK_SNDBUF)
412 && channel->socket_send_buffer_size == -1)
413 channel->socket_send_buffer_size = options->socket_send_buffer_size;
414 if ((optmask & ARES_OPT_SOCK_RCVBUF)
415 && channel->socket_receive_buffer_size == -1)
416 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
418 /* Copy the servers, if given. */
419 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
421 /* Avoid zero size allocations at any cost */
422 if (options->nservers > 0)
425 malloc(options->nservers * sizeof(struct server_state));
426 if (!channel->servers)
428 for (i = 0; i < options->nservers; i++)
429 channel->servers[i].addr = options->servers[i];
431 channel->nservers = options->nservers;
434 /* Copy the domains, if given. Keep channel->ndomains consistent so
435 * we can clean up in case of error.
437 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
439 /* Avoid zero size allocations at any cost */
440 if (options->ndomains > 0)
442 channel->domains = malloc(options->ndomains * sizeof(char *));
443 if (!channel->domains)
445 for (i = 0; i < options->ndomains; i++)
447 channel->ndomains = i;
448 channel->domains[i] = strdup(options->domains[i]);
449 if (!channel->domains[i])
453 channel->ndomains = options->ndomains;
456 /* Set lookups, if given. */
457 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
459 channel->lookups = strdup(options->lookups);
460 if (!channel->lookups)
465 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
467 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
468 if (!channel->sortlist)
470 for (i = 0; i < options->nsort; i++)
472 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
473 sizeof(struct apattern));
475 channel->nsort = options->nsort;
478 channel->optmask = optmask;
483 static int init_by_environment(ares_channel channel)
485 const char *localdomain, *res_options;
488 localdomain = getenv("LOCALDOMAIN");
489 if (localdomain && channel->ndomains == -1)
491 status = set_search(channel, localdomain);
492 if (status != ARES_SUCCESS)
496 res_options = getenv("RES_OPTIONS");
499 status = set_options(channel, res_options);
500 if (status != ARES_SUCCESS)
509 * Warning: returns a dynamically allocated buffer, the user MUST
510 * use free() if the function returns 1
512 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
514 /* Test for the size we need */
518 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
519 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
521 *obuf = malloc(size+1);
525 if (RegQueryValueEx(hKey, subkey, 0, NULL,
526 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
539 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
541 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
542 DWORD enum_size = 39;
546 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
547 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
552 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
555 rc = get_res_nt(hVal, subkey, obuf);
563 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
565 FIXED_INFO *fi, *newfi;
566 DWORD size = sizeof (*fi);
567 IP_ADDR_STRING *ipAddr;
570 size_t ip_size = sizeof("255.255.255.255,")-1;
571 size_t left = ret_size;
579 res = (*fpGetNetworkParams) (fi, &size);
580 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
583 newfi = realloc(fi, size);
588 res = (*fpGetNetworkParams) (fi, &size);
589 if (res != ERROR_SUCCESS)
594 printf ("Host Name: %s\n", fi->HostName);
595 printf ("Domain Name: %s\n", fi->DomainName);
596 printf ("DNS Servers:\n"
597 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
599 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
600 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
603 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
604 left -= ret - ret_buf;
608 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
609 ipAddr = ipAddr->Next, i++)
611 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
613 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
614 left -= ret - ret_buf;
618 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
625 if (debug && left <= ip_size)
626 printf ("Too many nameservers. Truncating to %d addressess", count);
633 static int init_by_resolv_conf(ares_channel channel)
636 int status = -1, nservers = 0, nsort = 0;
637 struct server_state *servers = NULL;
638 struct apattern *sortlist = NULL;
643 NameServer info via IPHLPAPI (IP helper API):
644 GetNetworkParams() should be the trusted source for this.
645 Available in Win-98/2000 and later. If that fail, fall-back to
646 registry information.
650 On Windows 9X, the DNS server can be found in:
651 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
653 On Windows NT/2000/XP/2003:
654 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
656 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
658 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
661 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
672 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
675 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
677 status = config_nameserver(&servers, &nservers, buf);
678 if (status == ARES_SUCCESS)
685 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
689 RegOpenKeyEx(mykey, "Interfaces", 0,
690 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
691 if (get_res_nt(mykey, NAMESERVER, &line))
693 status = config_nameserver(&servers, &nservers, line);
696 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
698 status = config_nameserver(&servers, &nservers, line);
701 /* Try the interfaces */
702 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
704 status = config_nameserver(&servers, &nservers, line);
707 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
709 status = config_nameserver(&servers, &nservers, line);
719 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
723 if ((result = RegQueryValueEx(
724 mykey, NAMESERVER, NULL, &data_type,
727 ) == ERROR_SUCCESS ||
728 result == ERROR_MORE_DATA)
732 line = malloc(bytes+1);
733 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
734 (unsigned char *)line, &bytes) ==
737 status = config_nameserver(&servers, &nservers, line);
746 if (status == ARES_SUCCESS)
749 /* Catch the case when all the above checks fail (which happens when there
750 is no network card or the cable is unplugged) */
753 #elif defined(__riscos__)
755 /* Under RISC OS, name servers are listed in the
756 system variable Inet$Resolvers, space separated. */
758 line = getenv("Inet$Resolvers");
761 char *resolvers = strdup(line), *pos, *space;
768 space = strchr(pos, ' ');
771 status = config_nameserver(&servers, &nservers, pos);
772 if (status != ARES_SUCCESS)
777 if (status == ARES_SUCCESS)
783 #elif defined(WATT32)
787 for (i = 0; def_nameservers[i]; i++)
790 return ARES_SUCCESS; /* use localhost DNS server */
793 servers = calloc(sizeof(*servers), i);
797 for (i = 0; def_nameservers[i]; i++)
798 servers[i].addr.s_addr = htonl(def_nameservers[i]);
808 /* Don't read resolv.conf and friends if we don't have to */
809 if (ARES_CONFIG_CHECK(channel))
812 fp = fopen(PATH_RESOLV_CONF, "r");
814 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
816 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
817 status = config_domain(channel, p);
818 else if ((p = try_config(line, "lookup")) && !channel->lookups)
819 status = config_lookup(channel, p, "bind", "file");
820 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
821 status = set_search(channel, p);
822 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
823 status = config_nameserver(&servers, &nservers, p);
824 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
825 status = config_sortlist(&sortlist, &nsort, p);
826 else if ((p = try_config(line, "options")))
827 status = set_options(channel, p);
829 status = ARES_SUCCESS;
830 if (status != ARES_SUCCESS)
843 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
844 error, strerror(error)));
845 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
850 if ((status == ARES_EOF) && (!channel->lookups)) {
851 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
852 fp = fopen("/etc/nsswitch.conf", "r");
854 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
856 if ((p = try_config(line, "hosts:")) && !channel->lookups)
857 status = config_lookup(channel, p, "dns", "files");
869 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
870 error, strerror(error)));
871 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
877 if ((status == ARES_EOF) && (!channel->lookups)) {
878 /* Linux / GNU libc 2.x and possibly others have host.conf */
879 fp = fopen("/etc/host.conf", "r");
881 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
883 if ((p = try_config(line, "order")) && !channel->lookups)
884 status = config_lookup(channel, p, "bind", "hosts");
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/host.conf"));
904 if ((status == ARES_EOF) && (!channel->lookups)) {
905 /* Tru64 uses /etc/svc.conf */
906 fp = fopen("/etc/svc.conf", "r");
908 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
910 if ((p = try_config(line, "hosts=")) && !channel->lookups)
911 status = config_lookup(channel, p, "bind", "local");
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/svc.conf"));
938 if (status != ARES_EOF)
942 if (sortlist != NULL)
947 /* If we got any name server entries, fill them in. */
953 channel->servers = servers;
954 channel->nservers = nservers;
957 /* If we got any sortlist entries, fill them in. */
960 channel->sortlist = sortlist;
961 channel->nsort = nsort;
967 static int init_by_defaults(ares_channel channel)
969 char *hostname = NULL;
970 int rc = ARES_SUCCESS;
972 if (channel->flags == -1)
974 if (channel->timeout == -1)
975 channel->timeout = DEFAULT_TIMEOUT;
976 if (channel->tries == -1)
977 channel->tries = DEFAULT_TRIES;
978 if (channel->ndots == -1)
980 if (channel->rotate == -1)
982 if (channel->udp_port == -1)
983 channel->udp_port = htons(NAMESERVER_PORT);
984 if (channel->tcp_port == -1)
985 channel->tcp_port = htons(NAMESERVER_PORT);
987 if (channel->nservers == -1) {
988 /* If nobody specified servers, try a local named. */
989 channel->servers = malloc(sizeof(struct server_state));
990 if (!channel->servers) {
994 channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
995 channel->nservers = 1;
999 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1001 #define toolong(x) (x == -1) && (EINVAL == errno)
1004 if (channel->ndomains == -1) {
1005 /* Derive a default domain search list from the kernel hostname,
1006 * or set it to empty if the hostname isn't helpful.
1010 channel->ndomains = 0; /* default to none */
1012 #ifdef HAVE_GETHOSTNAME
1013 hostname = malloc(len);
1020 res = gethostname(hostname, len);
1025 p = realloc(hostname, len);
1040 if (strchr(hostname, '.')) {
1041 /* a dot was found */
1043 channel->domains = malloc(sizeof(char *));
1044 if (!channel->domains) {
1048 channel->domains[0] = strdup(strchr(hostname, '.') + 1);
1049 if (!channel->domains[0]) {
1053 channel->ndomains = 1;
1058 if (channel->nsort == -1) {
1059 channel->sortlist = NULL;
1063 if (!channel->lookups) {
1064 channel->lookups = strdup("fb");
1065 if (!channel->lookups)
1071 if(channel->servers)
1072 free(channel->servers);
1074 if(channel->domains && channel->domains[0])
1075 free(channel->domains[0]);
1076 if(channel->domains)
1077 free(channel->domains);
1078 if(channel->lookups)
1079 free(channel->lookups);
1089 static int config_domain(ares_channel channel, char *str)
1093 /* Set a single search domain. */
1095 while (*q && !ISSPACE(*q))
1098 return set_search(channel, str);
1101 static int config_lookup(ares_channel channel, const char *str,
1102 const char *bindch, const char *filech)
1104 char lookups[3], *l;
1107 /* Set the lookup order. Only the first letter of each work
1108 * is relevant, and it has to be "b" for DNS or "f" for the
1109 * host file. Ignore everything else.
1115 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1116 if (*p == *bindch) *l++ = 'b';
1119 while (*p && !ISSPACE(*p) && (*p != ','))
1121 while (*p && (ISSPACE(*p) || (*p == ',')))
1125 channel->lookups = strdup(lookups);
1126 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1131 static int config_nameserver(struct server_state **servers, int *nservers,
1134 struct in_addr addr;
1135 struct server_state *newserv;
1136 /* On Windows, there may be more than one nameserver specified in the same
1137 * registry key, so we parse it as a space or comma seperated list.
1146 while (*p && !ISSPACE(*p) && *p != ',')
1155 /* Skip multiple spaces or trailing spaces */
1162 /* This is the part that actually sets the nameserver */
1163 addr.s_addr = inet_addr(begin);
1164 if (addr.s_addr == INADDR_NONE)
1166 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1169 newserv[*nservers].addr = addr;
1178 /* Add a nameserver entry, if this is a valid address. */
1179 addr.s_addr = inet_addr(str);
1180 if (addr.s_addr == INADDR_NONE)
1181 return ARES_SUCCESS;
1182 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1185 newserv[*nservers].addr = addr;
1189 return ARES_SUCCESS;
1193 static int config_sortlist(struct apattern **sortlist, int *nsort,
1196 struct apattern pat;
1199 /* Add sortlist entries. */
1200 while (*str && *str != ';')
1203 char ipbuf[16], ipbufpfx[32];
1204 /* Find just the IP */
1206 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1208 memcpy(ipbuf, str, (int)(q-str));
1209 ipbuf[(int)(q-str)] = '\0';
1210 /* Find the prefix */
1213 const char *str2 = q+1;
1214 while (*q && *q != ';' && !ISSPACE(*q))
1216 memcpy(ipbufpfx, str, (int)(q-str));
1217 ipbufpfx[(int)(q-str)] = '\0';
1222 /* Lets see if it is CIDR */
1223 /* First we'll try IPv6 */
1224 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1226 sizeof(pat.addrV6))) > 0)
1228 pat.type = PATTERN_CIDR;
1229 pat.mask.bits = (unsigned short)bits;
1230 pat.family = AF_INET6;
1231 if (!sortlist_alloc(sortlist, nsort, &pat))
1235 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1236 sizeof(pat.addrV4))) > 0)
1238 pat.type = PATTERN_CIDR;
1239 pat.mask.bits = (unsigned short)bits;
1240 pat.family = AF_INET;
1241 if (!sortlist_alloc(sortlist, nsort, &pat))
1244 /* See if it is just a regular IP */
1245 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1249 memcpy(ipbuf, str, (int)(q-str));
1250 ipbuf[(int)(q-str)] = '\0';
1251 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1256 pat.family = AF_INET;
1257 pat.type = PATTERN_MASK;
1258 if (!sortlist_alloc(sortlist, nsort, &pat))
1263 while (*q && *q != ';' && !ISSPACE(*q))
1267 while (ISSPACE(*str))
1271 return ARES_SUCCESS;
1275 static int set_search(ares_channel channel, const char *str)
1280 if(channel->ndomains != -1) {
1281 /* if we already have some domains present, free them first */
1282 for(n=0; n < channel->ndomains; n++)
1283 free(channel->domains[n]);
1284 free(channel->domains);
1285 channel->domains = NULL;
1286 channel->ndomains = -1;
1289 /* Count the domains given. */
1294 while (*p && !ISSPACE(*p))
1303 channel->ndomains = 0;
1304 return ARES_SUCCESS;
1307 channel->domains = malloc(n * sizeof(char *));
1308 if (!channel->domains)
1311 /* Now copy the domains. */
1316 channel->ndomains = n;
1318 while (*q && !ISSPACE(*q))
1320 channel->domains[n] = malloc(q - p + 1);
1321 if (!channel->domains[n])
1323 memcpy(channel->domains[n], p, q - p);
1324 channel->domains[n][q - p] = 0;
1330 channel->ndomains = n;
1332 return ARES_SUCCESS;
1335 static int set_options(ares_channel channel, const char *str)
1337 const char *p, *q, *val;
1343 while (*q && !ISSPACE(*q))
1345 val = try_option(p, q, "ndots:");
1346 if (val && channel->ndots == -1)
1347 channel->ndots = atoi(val);
1348 val = try_option(p, q, "retrans:");
1349 if (val && channel->timeout == -1)
1350 channel->timeout = atoi(val);
1351 val = try_option(p, q, "retry:");
1352 if (val && channel->tries == -1)
1353 channel->tries = atoi(val);
1354 val = try_option(p, q, "rotate");
1355 if (val && channel->rotate == -1)
1356 channel->rotate = 1;
1362 return ARES_SUCCESS;
1366 static char *try_config(char *s, const char *opt)
1374 /* no line or no option */
1377 /* trim line comment */
1378 for (i = 0; s[i] && s[i] != '#'; ++i);
1381 /* trim trailing whitespace */
1382 for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
1385 /* skip leading whitespace */
1386 for (i = 0; s[i] && ISSPACE(s[i]); ++i);
1393 if ((len = strlen(opt)) == 0)
1397 if (strncmp(p, opt, len) != 0)
1398 /* line and option do not match */
1401 /* skip over given option name */
1405 /* no option value */
1408 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1409 /* whitespace between option name and value is mandatory
1410 for given option names which do not end with ':' or '=' */
1413 /* skip over whitespace */
1414 while (*p && ISSPACE(*p))
1418 /* no option value */
1421 /* return pointer to option value */
1426 static const char *try_option(const char *p, const char *q, const char *opt)
1428 size_t len = strlen(opt);
1429 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1433 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1434 struct apattern *pat)
1436 struct apattern *newsort;
1437 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1440 newsort[*nsort] = *pat;
1441 *sortlist = newsort;
1446 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1449 /* Four octets and three periods yields at most 15 characters. */
1453 addr->s_addr = inet_addr(ipbuf);
1454 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1459 static void natural_mask(struct apattern *pat)
1461 struct in_addr addr;
1463 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1466 addr.s_addr = ntohl(pat->addrV4.s_addr);
1468 /* This is out of date in the CIDR world, but some people might
1471 if (IN_CLASSA(addr.s_addr))
1472 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1473 else if (IN_CLASSB(addr.s_addr))
1474 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1476 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1479 /* initialize an rc4 key. If possible a cryptographically secure random key
1480 is generated using a suitable function (for example win32's RtlGenRandom as
1482 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1483 otherwise the code defaults to cross-platform albeit less secure mechanism
1486 static void randomize_key(unsigned char* key,int key_data_len)
1492 if (fpSystemFunction036)
1494 res = (*fpSystemFunction036) (key, key_data_len);
1500 FILE *f = fopen(RANDOM_FILE, "rb");
1502 counter = fread(key, 1, key_data_len, f);
1508 if ( !randomized ) {
1509 for (;counter<key_data_len;counter++)
1510 key[counter]=(unsigned char)(rand() % 256);
1514 static int init_id_key(rc4_key* key,int key_data_len)
1516 unsigned char index1;
1517 unsigned char index2;
1518 unsigned char* state;
1520 unsigned char *key_data_ptr = 0;
1522 key_data_ptr = calloc(1,key_data_len);
1526 state = &key->state[0];
1527 for(counter = 0; counter < 256; counter++)
1528 /* unnecessary AND but it keeps some compilers happier */
1529 state[counter] = (unsigned char)(counter & 0xff);
1530 randomize_key(key->state,key_data_len);
1535 for(counter = 0; counter < 256; counter++)
1537 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1539 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1541 index1 = (unsigned char)((index1 + 1) % key_data_len);
1544 return ARES_SUCCESS;
1547 unsigned short ares__generate_new_id(rc4_key* key)
1550 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1554 void ares_set_socket_callback(ares_channel channel,
1555 ares_sock_create_callback cb,
1558 channel->sock_create_cb = cb;
1559 channel->sock_create_cb_data = data;