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, *newfi;
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;
578 handle = LoadLibrary ("iphlpapi.dll");
582 fpGetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
583 if (!fpGetNetworkParams)
586 res = (*fpGetNetworkParams) (fi, &size);
587 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
590 newfi = realloc(fi, size);
595 res = (*fpGetNetworkParams) (fi, &size);
596 if (res != ERROR_SUCCESS)
601 printf ("Host Name: %s\n", fi->HostName);
602 printf ("Domain Name: %s\n", fi->DomainName);
603 printf ("DNS Servers:\n"
604 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
606 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
607 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
610 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
611 left -= ret - ret_buf;
615 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
616 ipAddr = ipAddr->Next, i++)
618 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
620 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
621 left -= ret - ret_buf;
625 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
632 FreeLibrary (handle);
634 if (debug && left <= ip_size)
635 printf ("Too many nameservers. Truncating to %d addressess", count);
642 static int init_by_resolv_conf(ares_channel channel)
645 int status = -1, nservers = 0, nsort = 0;
646 struct server_state *servers = NULL;
647 struct apattern *sortlist = NULL;
652 NameServer info via IPHLPAPI (IP helper API):
653 GetNetworkParams() should be the trusted source for this.
654 Available in Win-98/2000 and later. If that fail, fall-back to
655 registry information.
659 On Windows 9X, the DNS server can be found in:
660 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
662 On Windows NT/2000/XP/2003:
663 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
665 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
667 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
670 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
681 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
684 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
686 status = config_nameserver(&servers, &nservers, buf);
687 if (status == ARES_SUCCESS)
694 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
698 RegOpenKeyEx(mykey, "Interfaces", 0,
699 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
700 if (get_res_nt(mykey, NAMESERVER, &line))
702 status = config_nameserver(&servers, &nservers, line);
705 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
707 status = config_nameserver(&servers, &nservers, line);
710 /* Try the interfaces */
711 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
713 status = config_nameserver(&servers, &nservers, line);
716 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
718 status = config_nameserver(&servers, &nservers, line);
728 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
732 if ((result = RegQueryValueEx(
733 mykey, NAMESERVER, NULL, &data_type,
736 ) == ERROR_SUCCESS ||
737 result == ERROR_MORE_DATA)
741 line = malloc(bytes+1);
742 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
743 (unsigned char *)line, &bytes) ==
746 status = config_nameserver(&servers, &nservers, line);
755 if (status == ARES_SUCCESS)
758 /* Catch the case when all the above checks fail (which happens when there
759 is no network card or the cable is unplugged) */
762 #elif defined(__riscos__)
764 /* Under RISC OS, name servers are listed in the
765 system variable Inet$Resolvers, space separated. */
767 line = getenv("Inet$Resolvers");
770 char *resolvers = strdup(line), *pos, *space;
777 space = strchr(pos, ' ');
780 status = config_nameserver(&servers, &nservers, pos);
781 if (status != ARES_SUCCESS)
786 if (status == ARES_SUCCESS)
792 #elif defined(WATT32)
796 for (i = 0; def_nameservers[i]; i++)
799 return ARES_SUCCESS; /* use localhost DNS server */
802 servers = calloc(sizeof(*servers), i);
806 for (i = 0; def_nameservers[i]; i++)
807 servers[i].addr.s_addr = htonl(def_nameservers[i]);
817 /* Don't read resolv.conf and friends if we don't have to */
818 if (ARES_CONFIG_CHECK(channel))
821 fp = fopen(PATH_RESOLV_CONF, "r");
823 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
825 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
826 status = config_domain(channel, p);
827 else if ((p = try_config(line, "lookup")) && !channel->lookups)
828 status = config_lookup(channel, p, "bind", "file");
829 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
830 status = set_search(channel, p);
831 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
832 status = config_nameserver(&servers, &nservers, p);
833 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
834 status = config_sortlist(&sortlist, &nsort, p);
835 else if ((p = try_config(line, "options")))
836 status = set_options(channel, p);
838 status = ARES_SUCCESS;
839 if (status != ARES_SUCCESS)
852 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
853 error, strerror(error)));
854 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
859 if ((status == ARES_EOF) && (!channel->lookups)) {
860 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
861 fp = fopen("/etc/nsswitch.conf", "r");
863 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
865 if ((p = try_config(line, "hosts:")) && !channel->lookups)
866 status = config_lookup(channel, p, "dns", "files");
878 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
879 error, strerror(error)));
880 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
886 if ((status == ARES_EOF) && (!channel->lookups)) {
887 /* Linux / GNU libc 2.x and possibly others have host.conf */
888 fp = fopen("/etc/host.conf", "r");
890 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
892 if ((p = try_config(line, "order")) && !channel->lookups)
893 status = config_lookup(channel, p, "bind", "hosts");
905 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
906 error, strerror(error)));
907 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
913 if ((status == ARES_EOF) && (!channel->lookups)) {
914 /* Tru64 uses /etc/svc.conf */
915 fp = fopen("/etc/svc.conf", "r");
917 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
919 if ((p = try_config(line, "hosts=")) && !channel->lookups)
920 status = config_lookup(channel, p, "bind", "local");
932 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
933 error, strerror(error)));
934 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
947 if (status != ARES_EOF)
951 if (sortlist != NULL)
956 /* If we got any name server entries, fill them in. */
962 channel->servers = servers;
963 channel->nservers = nservers;
966 /* If we got any sortlist entries, fill them in. */
969 channel->sortlist = sortlist;
970 channel->nsort = nsort;
976 static int init_by_defaults(ares_channel channel)
978 char *hostname = NULL;
979 int rc = ARES_SUCCESS;
981 if (channel->flags == -1)
983 if (channel->timeout == -1)
984 channel->timeout = DEFAULT_TIMEOUT;
985 if (channel->tries == -1)
986 channel->tries = DEFAULT_TRIES;
987 if (channel->ndots == -1)
989 if (channel->rotate == -1)
991 if (channel->udp_port == -1)
992 channel->udp_port = htons(NAMESERVER_PORT);
993 if (channel->tcp_port == -1)
994 channel->tcp_port = htons(NAMESERVER_PORT);
996 if (channel->nservers == -1) {
997 /* If nobody specified servers, try a local named. */
998 channel->servers = malloc(sizeof(struct server_state));
999 if (!channel->servers) {
1003 channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
1004 channel->nservers = 1;
1008 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1010 #define toolong(x) (x == -1) && (EINVAL == errno)
1013 if (channel->ndomains == -1) {
1014 /* Derive a default domain search list from the kernel hostname,
1015 * or set it to empty if the hostname isn't helpful.
1019 channel->ndomains = 0; /* default to none */
1021 #ifdef HAVE_GETHOSTNAME
1022 hostname = malloc(len);
1029 res = gethostname(hostname, len);
1034 p = realloc(hostname, len);
1049 if (strchr(hostname, '.')) {
1050 /* a dot was found */
1052 channel->domains = malloc(sizeof(char *));
1053 if (!channel->domains) {
1057 channel->domains[0] = strdup(strchr(hostname, '.') + 1);
1058 if (!channel->domains[0]) {
1062 channel->ndomains = 1;
1067 if (channel->nsort == -1) {
1068 channel->sortlist = NULL;
1072 if (!channel->lookups) {
1073 channel->lookups = strdup("fb");
1074 if (!channel->lookups)
1080 if(channel->servers)
1081 free(channel->servers);
1083 if(channel->domains && channel->domains[0])
1084 free(channel->domains[0]);
1085 if(channel->domains)
1086 free(channel->domains);
1087 if(channel->lookups)
1088 free(channel->lookups);
1098 static int config_domain(ares_channel channel, char *str)
1102 /* Set a single search domain. */
1104 while (*q && !ISSPACE(*q))
1107 return set_search(channel, str);
1110 static int config_lookup(ares_channel channel, const char *str,
1111 const char *bindch, const char *filech)
1113 char lookups[3], *l;
1116 /* Set the lookup order. Only the first letter of each work
1117 * is relevant, and it has to be "b" for DNS or "f" for the
1118 * host file. Ignore everything else.
1124 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1125 if (*p == *bindch) *l++ = 'b';
1128 while (*p && !ISSPACE(*p) && (*p != ','))
1130 while (*p && (ISSPACE(*p) || (*p == ',')))
1134 channel->lookups = strdup(lookups);
1135 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1140 static int config_nameserver(struct server_state **servers, int *nservers,
1143 struct in_addr addr;
1144 struct server_state *newserv;
1145 /* On Windows, there may be more than one nameserver specified in the same
1146 * registry key, so we parse it as a space or comma seperated list.
1155 while (*p && !ISSPACE(*p) && *p != ',')
1164 /* Skip multiple spaces or trailing spaces */
1171 /* This is the part that actually sets the nameserver */
1172 addr.s_addr = inet_addr(begin);
1173 if (addr.s_addr == INADDR_NONE)
1175 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1178 newserv[*nservers].addr = addr;
1187 /* Add a nameserver entry, if this is a valid address. */
1188 addr.s_addr = inet_addr(str);
1189 if (addr.s_addr == INADDR_NONE)
1190 return ARES_SUCCESS;
1191 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1194 newserv[*nservers].addr = addr;
1198 return ARES_SUCCESS;
1202 static int config_sortlist(struct apattern **sortlist, int *nsort,
1205 struct apattern pat;
1208 /* Add sortlist entries. */
1209 while (*str && *str != ';')
1212 char ipbuf[16], ipbufpfx[32];
1213 /* Find just the IP */
1215 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1217 memcpy(ipbuf, str, (int)(q-str));
1218 ipbuf[(int)(q-str)] = '\0';
1219 /* Find the prefix */
1222 const char *str2 = q+1;
1223 while (*q && *q != ';' && !ISSPACE(*q))
1225 memcpy(ipbufpfx, str, (int)(q-str));
1226 ipbufpfx[(int)(q-str)] = '\0';
1231 /* Lets see if it is CIDR */
1232 /* First we'll try IPv6 */
1233 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1235 sizeof(pat.addrV6))) > 0)
1237 pat.type = PATTERN_CIDR;
1238 pat.mask.bits = (unsigned short)bits;
1239 pat.family = AF_INET6;
1240 if (!sortlist_alloc(sortlist, nsort, &pat))
1244 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1245 sizeof(pat.addrV4))) > 0)
1247 pat.type = PATTERN_CIDR;
1248 pat.mask.bits = (unsigned short)bits;
1249 pat.family = AF_INET;
1250 if (!sortlist_alloc(sortlist, nsort, &pat))
1253 /* See if it is just a regular IP */
1254 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1258 memcpy(ipbuf, str, (int)(q-str));
1259 ipbuf[(int)(q-str)] = '\0';
1260 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1265 pat.family = AF_INET;
1266 pat.type = PATTERN_MASK;
1267 if (!sortlist_alloc(sortlist, nsort, &pat))
1272 while (*q && *q != ';' && !ISSPACE(*q))
1276 while (ISSPACE(*str))
1280 return ARES_SUCCESS;
1284 static int set_search(ares_channel channel, const char *str)
1289 if(channel->ndomains != -1) {
1290 /* if we already have some domains present, free them first */
1291 for(n=0; n < channel->ndomains; n++)
1292 free(channel->domains[n]);
1293 free(channel->domains);
1294 channel->domains = NULL;
1295 channel->ndomains = -1;
1298 /* Count the domains given. */
1303 while (*p && !ISSPACE(*p))
1312 channel->ndomains = 0;
1313 return ARES_SUCCESS;
1316 channel->domains = malloc(n * sizeof(char *));
1317 if (!channel->domains)
1320 /* Now copy the domains. */
1325 channel->ndomains = n;
1327 while (*q && !ISSPACE(*q))
1329 channel->domains[n] = malloc(q - p + 1);
1330 if (!channel->domains[n])
1332 memcpy(channel->domains[n], p, q - p);
1333 channel->domains[n][q - p] = 0;
1339 channel->ndomains = n;
1341 return ARES_SUCCESS;
1344 static int set_options(ares_channel channel, const char *str)
1346 const char *p, *q, *val;
1352 while (*q && !ISSPACE(*q))
1354 val = try_option(p, q, "ndots:");
1355 if (val && channel->ndots == -1)
1356 channel->ndots = atoi(val);
1357 val = try_option(p, q, "retrans:");
1358 if (val && channel->timeout == -1)
1359 channel->timeout = atoi(val);
1360 val = try_option(p, q, "retry:");
1361 if (val && channel->tries == -1)
1362 channel->tries = atoi(val);
1363 val = try_option(p, q, "rotate");
1364 if (val && channel->rotate == -1)
1365 channel->rotate = 1;
1371 return ARES_SUCCESS;
1375 static char *try_config(char *s, const char *opt)
1383 /* no line or no option */
1386 /* trim line comment */
1387 for (i = 0; s[i] && s[i] != '#'; ++i);
1390 /* trim trailing whitespace */
1391 for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
1394 /* skip leading whitespace */
1395 for (i = 0; s[i] && ISSPACE(s[i]); ++i);
1402 if ((len = strlen(opt)) == 0)
1406 if (strncmp(p, opt, len) != 0)
1407 /* line and option do not match */
1410 /* skip over given option name */
1414 /* no option value */
1417 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1418 /* whitespace between option name and value is mandatory
1419 for given option names which do not end with ':' or '=' */
1422 /* skip over whitespace */
1423 while (*p && ISSPACE(*p))
1427 /* no option value */
1430 /* return pointer to option value */
1435 static const char *try_option(const char *p, const char *q, const char *opt)
1437 size_t len = strlen(opt);
1438 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1442 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1443 struct apattern *pat)
1445 struct apattern *newsort;
1446 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1449 newsort[*nsort] = *pat;
1450 *sortlist = newsort;
1455 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1458 /* Four octets and three periods yields at most 15 characters. */
1462 addr->s_addr = inet_addr(ipbuf);
1463 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1468 static void natural_mask(struct apattern *pat)
1470 struct in_addr addr;
1472 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1475 addr.s_addr = ntohl(pat->addrV4.s_addr);
1477 /* This is out of date in the CIDR world, but some people might
1480 if (IN_CLASSA(addr.s_addr))
1481 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1482 else if (IN_CLASSB(addr.s_addr))
1483 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1485 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1488 /* initialize an rc4 key. If possible a cryptographically secure random key
1489 is generated using a suitable function (for example win32's RtlGenRandom as
1491 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1492 otherwise the code defaults to cross-platform albeit less secure mechanism
1495 static void randomize_key(unsigned char* key,int key_data_len)
1500 HMODULE lib=LoadLibrary("ADVAPI32.DLL");
1502 BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
1503 (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(lib,"SystemFunction036");
1504 if (pfn && pfn(key,key_data_len) )
1511 FILE *f = fopen(RANDOM_FILE, "rb");
1513 counter = fread(key, 1, key_data_len, f);
1519 if ( !randomized ) {
1520 for (;counter<key_data_len;counter++)
1521 key[counter]=(unsigned char)(rand() % 256);
1525 static int init_id_key(rc4_key* key,int key_data_len)
1527 unsigned char index1;
1528 unsigned char index2;
1529 unsigned char* state;
1531 unsigned char *key_data_ptr = 0;
1533 key_data_ptr = calloc(1,key_data_len);
1537 state = &key->state[0];
1538 for(counter = 0; counter < 256; counter++)
1539 /* unnecessary AND but it keeps some compilers happier */
1540 state[counter] = (unsigned char)(counter & 0xff);
1541 randomize_key(key->state,key_data_len);
1546 for(counter = 0; counter < 256; counter++)
1548 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1550 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1552 index1 = (unsigned char)((index1 + 1) % key_data_len);
1555 return ARES_SUCCESS;
1558 unsigned short ares__generate_new_id(rc4_key* key)
1561 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1565 void ares_set_socket_callback(ares_channel channel,
1566 ares_sock_create_callback cb,
1569 channel->sock_create_cb = cb;
1570 channel->sock_create_cb_data = data;