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);
84 static int config_nameserver(struct server_state **servers, int *nservers,
87 static int set_search(ares_channel channel, const char *str);
88 static int set_options(ares_channel channel, const char *str);
89 static const char *try_option(const char *p, const char *q, const char *opt);
90 static int init_id_key(rc4_key* key,int key_data_len);
92 #if !defined(WIN32) && !defined(WATT32)
93 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
94 static int ip_addr(const char *s, int len, struct in_addr *addr);
95 static void natural_mask(struct apattern *pat);
96 static int config_domain(ares_channel channel, char *str);
97 static int config_lookup(ares_channel channel, const char *str,
98 const char *bindch, const char *filech);
99 static int config_sortlist(struct apattern **sortlist, int *nsort,
101 static char *try_config(char *s, const char *opt);
104 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
105 x->nservers > -1 && \
106 x->ndomains > -1 && \
107 x->ndots > -1 && x->timeout > -1 && \
110 int ares_init(ares_channel *channelptr)
112 return ares_init_options(channelptr, NULL, 0);
115 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
118 ares_channel channel;
120 int status = ARES_SUCCESS;
121 struct server_state *server;
125 const char *env = getenv("CARES_MEMDEBUG");
129 env = getenv("CARES_MEMLIMIT");
131 curl_memlimit(atoi(env));
134 if (ares_library_initialized() != ARES_SUCCESS)
135 return ARES_ENOTINITIALIZED;
137 channel = malloc(sizeof(struct ares_channeldata));
145 /* Set everything to distinguished values so we know they haven't
149 channel->timeout = -1;
152 channel->rotate = -1;
153 channel->udp_port = -1;
154 channel->tcp_port = -1;
155 channel->socket_send_buffer_size = -1;
156 channel->socket_receive_buffer_size = -1;
157 channel->nservers = -1;
158 channel->ndomains = -1;
160 channel->tcp_connection_generation = 0;
161 channel->lookups = NULL;
162 channel->domains = NULL;
163 channel->sortlist = NULL;
164 channel->servers = NULL;
165 channel->sock_state_cb = NULL;
166 channel->sock_state_cb_data = NULL;
167 channel->sock_create_cb = NULL;
168 channel->sock_create_cb_data = NULL;
170 channel->last_server = 0;
171 channel->last_timeout_processed = (time_t)now.tv_sec;
173 /* Initialize our lists of queries */
174 ares__init_list_head(&(channel->all_queries));
175 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
177 ares__init_list_head(&(channel->queries_by_qid[i]));
179 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
181 ares__init_list_head(&(channel->queries_by_timeout[i]));
184 /* Initialize configuration by each of the four sources, from highest
185 * precedence to lowest.
188 if (status == ARES_SUCCESS) {
189 status = init_by_options(channel, options, optmask);
190 if (status != ARES_SUCCESS)
191 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
192 ares_strerror(status)));
194 if (status == ARES_SUCCESS) {
195 status = init_by_environment(channel);
196 if (status != ARES_SUCCESS)
197 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
198 ares_strerror(status)));
200 if (status == ARES_SUCCESS) {
201 status = init_by_resolv_conf(channel);
202 if (status != ARES_SUCCESS)
203 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
204 ares_strerror(status)));
208 * No matter what failed or succeeded, seed defaults to provide
209 * useful behavior for things that we missed.
211 status = init_by_defaults(channel);
212 if (status != ARES_SUCCESS)
213 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
214 ares_strerror(status)));
216 /* Generate random key */
218 if (status == ARES_SUCCESS) {
219 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
220 if (status == ARES_SUCCESS)
221 channel->next_id = ares__generate_new_id(&channel->id_key);
223 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
224 ares_strerror(status)));
227 if (status != ARES_SUCCESS)
229 /* Something failed; clean up memory we may have allocated. */
230 if (channel->servers)
231 free(channel->servers);
232 if (channel->domains)
234 for (i = 0; i < channel->ndomains; i++)
235 free(channel->domains[i]);
236 free(channel->domains);
238 if (channel->sortlist)
239 free(channel->sortlist);
241 free(channel->lookups);
246 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
247 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
248 channel->nservers = 1;
250 /* Initialize server states. */
251 for (i = 0; i < channel->nservers; i++)
253 server = &channel->servers[i];
254 server->udp_socket = ARES_SOCKET_BAD;
255 server->tcp_socket = ARES_SOCKET_BAD;
256 server->tcp_connection_generation = ++channel->tcp_connection_generation;
257 server->tcp_lenbuf_pos = 0;
258 server->tcp_buffer = NULL;
259 server->qhead = NULL;
260 server->qtail = NULL;
261 ares__init_list_head(&(server->queries_to_server));
262 server->channel = channel;
263 server->is_broken = 0;
266 *channelptr = channel;
270 /* ares_dup() duplicates a channel handle with all its options and returns a
271 new channel handle */
272 int ares_dup(ares_channel *dest, ares_channel src)
274 struct ares_options opts;
278 *dest = NULL; /* in case of failure return NULL explicitly */
280 /* First get the options supported by the old ares_save_options() function,
281 which is most of them */
282 rc = ares_save_options(src, &opts, &optmask);
286 /* Then create the new channel with those options */
287 rc = ares_init_options(dest, &opts, optmask);
289 /* destroy the options copy to not leak any memory */
290 ares_destroy_options(&opts);
295 /* Now clone the options that ares_save_options() doesn't support. */
296 (*dest)->sock_create_cb = src->sock_create_cb;
297 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
300 return ARES_SUCCESS; /* everything went fine */
304 /* Save options from initialized channel */
305 int ares_save_options(ares_channel channel, struct ares_options *options,
310 /* Zero everything out */
311 memset(options, 0, sizeof(struct ares_options));
313 if (!ARES_CONFIG_CHECK(channel))
316 /* Traditionally the optmask wasn't saved in the channel struct so it was
317 recreated here. ROTATE is the first option that has no struct field of
318 its own in the public config struct */
319 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
320 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
321 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
322 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
323 (channel->optmask & ARES_OPT_ROTATE);
325 /* Copy easy stuff */
326 options->flags = channel->flags;
328 /* We return full millisecond resolution but that's only because we don't
329 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
330 options->timeout = channel->timeout;
331 options->tries = channel->tries;
332 options->ndots = channel->ndots;
333 options->udp_port = (unsigned short)channel->udp_port;
334 options->tcp_port = (unsigned short)channel->tcp_port;
335 options->sock_state_cb = channel->sock_state_cb;
336 options->sock_state_cb_data = channel->sock_state_cb_data;
339 if (channel->nservers) {
341 malloc(channel->nservers * sizeof(struct server_state));
342 if (!options->servers && channel->nservers != 0)
344 for (i = 0; i < channel->nservers; i++)
345 options->servers[i] = channel->servers[i].addr;
347 options->nservers = channel->nservers;
350 if (channel->ndomains) {
351 options->domains = malloc(channel->ndomains * sizeof(char *));
352 if (!options->domains)
355 for (i = 0; i < channel->ndomains; i++)
357 options->ndomains = i;
358 options->domains[i] = strdup(channel->domains[i]);
359 if (!options->domains[i])
363 options->ndomains = channel->ndomains;
366 if (channel->lookups) {
367 options->lookups = strdup(channel->lookups);
368 if (!options->lookups && channel->lookups)
373 if (channel->nsort) {
374 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
375 if (!options->sortlist)
377 for (i = 0; i < channel->nsort; i++)
379 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
380 sizeof(struct apattern));
383 options->nsort = channel->nsort;
388 static int init_by_options(ares_channel channel,
389 const struct ares_options *options,
395 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
396 channel->flags = options->flags;
397 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
398 channel->timeout = options->timeout;
399 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
400 channel->timeout = options->timeout * 1000;
401 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
402 channel->tries = options->tries;
403 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
404 channel->ndots = options->ndots;
405 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
407 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
408 channel->udp_port = options->udp_port;
409 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
410 channel->tcp_port = options->tcp_port;
411 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
413 channel->sock_state_cb = options->sock_state_cb;
414 channel->sock_state_cb_data = options->sock_state_cb_data;
416 if ((optmask & ARES_OPT_SOCK_SNDBUF)
417 && channel->socket_send_buffer_size == -1)
418 channel->socket_send_buffer_size = options->socket_send_buffer_size;
419 if ((optmask & ARES_OPT_SOCK_RCVBUF)
420 && channel->socket_receive_buffer_size == -1)
421 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
423 /* Copy the servers, if given. */
424 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
426 /* Avoid zero size allocations at any cost */
427 if (options->nservers > 0)
430 malloc(options->nservers * sizeof(struct server_state));
431 if (!channel->servers)
433 for (i = 0; i < options->nservers; i++)
434 channel->servers[i].addr = options->servers[i];
436 channel->nservers = options->nservers;
439 /* Copy the domains, if given. Keep channel->ndomains consistent so
440 * we can clean up in case of error.
442 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
444 /* Avoid zero size allocations at any cost */
445 if (options->ndomains > 0)
447 channel->domains = malloc(options->ndomains * sizeof(char *));
448 if (!channel->domains)
450 for (i = 0; i < options->ndomains; i++)
452 channel->ndomains = i;
453 channel->domains[i] = strdup(options->domains[i]);
454 if (!channel->domains[i])
458 channel->ndomains = options->ndomains;
461 /* Set lookups, if given. */
462 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
464 channel->lookups = strdup(options->lookups);
465 if (!channel->lookups)
470 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
472 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
473 if (!channel->sortlist)
475 for (i = 0; i < options->nsort; i++)
477 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
478 sizeof(struct apattern));
480 channel->nsort = options->nsort;
483 channel->optmask = optmask;
488 static int init_by_environment(ares_channel channel)
490 const char *localdomain, *res_options;
493 localdomain = getenv("LOCALDOMAIN");
494 if (localdomain && channel->ndomains == -1)
496 status = set_search(channel, localdomain);
497 if (status != ARES_SUCCESS)
501 res_options = getenv("RES_OPTIONS");
504 status = set_options(channel, res_options);
505 if (status != ARES_SUCCESS)
514 * Warning: returns a dynamically allocated buffer, the user MUST
515 * use free() if the function returns 1
517 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
519 /* Test for the size we need */
523 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
524 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
526 *obuf = malloc(size+1);
530 if (RegQueryValueEx(hKey, subkey, 0, NULL,
531 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
544 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
546 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
547 DWORD enum_size = 39;
551 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
552 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
557 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
560 rc = get_res_nt(hVal, subkey, obuf);
568 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
570 FIXED_INFO *fi, *newfi;
571 DWORD size = sizeof (*fi);
572 IP_ADDR_STRING *ipAddr;
575 size_t ip_size = sizeof("255.255.255.255,")-1;
576 size_t left = ret_size;
584 res = (*fpGetNetworkParams) (fi, &size);
585 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
588 newfi = realloc(fi, size);
593 res = (*fpGetNetworkParams) (fi, &size);
594 if (res != ERROR_SUCCESS)
599 printf ("Host Name: %s\n", fi->HostName);
600 printf ("Domain Name: %s\n", fi->DomainName);
601 printf ("DNS Servers:\n"
602 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
604 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
605 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
608 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
609 left -= ret - ret_buf;
613 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
614 ipAddr = ipAddr->Next, i++)
616 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
618 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
619 left -= ret - ret_buf;
623 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
630 if (debug && left <= ip_size)
631 printf ("Too many nameservers. Truncating to %d addressess", count);
638 static int init_by_resolv_conf(ares_channel channel)
643 int status = -1, nservers = 0, nsort = 0;
644 struct server_state *servers = NULL;
645 struct apattern *sortlist = NULL;
650 NameServer info via IPHLPAPI (IP helper API):
651 GetNetworkParams() should be the trusted source for this.
652 Available in Win-98/2000 and later. If that fail, fall-back to
653 registry information.
657 On Windows 9X, the DNS server can be found in:
658 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
660 On Windows NT/2000/XP/2003:
661 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
663 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
665 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
668 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
679 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
682 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
684 status = config_nameserver(&servers, &nservers, buf);
685 if (status == ARES_SUCCESS)
692 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
696 RegOpenKeyEx(mykey, "Interfaces", 0,
697 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
698 if (get_res_nt(mykey, NAMESERVER, &line))
700 status = config_nameserver(&servers, &nservers, line);
703 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
705 status = config_nameserver(&servers, &nservers, line);
708 /* Try the interfaces */
709 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
711 status = config_nameserver(&servers, &nservers, line);
714 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
716 status = config_nameserver(&servers, &nservers, line);
726 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
730 if ((result = RegQueryValueEx(
731 mykey, NAMESERVER, NULL, &data_type,
734 ) == ERROR_SUCCESS ||
735 result == ERROR_MORE_DATA)
739 line = malloc(bytes+1);
740 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
741 (unsigned char *)line, &bytes) ==
744 status = config_nameserver(&servers, &nservers, line);
753 if (status == ARES_SUCCESS)
756 /* Catch the case when all the above checks fail (which happens when there
757 is no network card or the cable is unplugged) */
760 #elif defined(__riscos__)
762 /* Under RISC OS, name servers are listed in the
763 system variable Inet$Resolvers, space separated. */
765 line = getenv("Inet$Resolvers");
768 char *resolvers = strdup(line), *pos, *space;
775 space = strchr(pos, ' ');
778 status = config_nameserver(&servers, &nservers, pos);
779 if (status != ARES_SUCCESS)
784 if (status == ARES_SUCCESS)
790 #elif defined(WATT32)
794 for (i = 0; def_nameservers[i]; i++)
797 return ARES_SUCCESS; /* use localhost DNS server */
800 servers = calloc(sizeof(*servers), i);
804 for (i = 0; def_nameservers[i]; i++)
805 servers[i].addr.s_addr = htonl(def_nameservers[i]);
815 /* Don't read resolv.conf and friends if we don't have to */
816 if (ARES_CONFIG_CHECK(channel))
819 fp = fopen(PATH_RESOLV_CONF, "r");
821 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
823 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
824 status = config_domain(channel, p);
825 else if ((p = try_config(line, "lookup")) && !channel->lookups)
826 status = config_lookup(channel, p, "bind", "file");
827 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
828 status = set_search(channel, p);
829 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
830 status = config_nameserver(&servers, &nservers, p);
831 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
832 status = config_sortlist(&sortlist, &nsort, p);
833 else if ((p = try_config(line, "options")))
834 status = set_options(channel, p);
836 status = ARES_SUCCESS;
837 if (status != ARES_SUCCESS)
850 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
851 error, strerror(error)));
852 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
857 if ((status == ARES_EOF) && (!channel->lookups)) {
858 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
859 fp = fopen("/etc/nsswitch.conf", "r");
861 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
863 if ((p = try_config(line, "hosts:")) && !channel->lookups)
864 status = config_lookup(channel, p, "dns", "files");
876 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
877 error, strerror(error)));
878 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
884 if ((status == ARES_EOF) && (!channel->lookups)) {
885 /* Linux / GNU libc 2.x and possibly others have host.conf */
886 fp = fopen("/etc/host.conf", "r");
888 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
890 if ((p = try_config(line, "order")) && !channel->lookups)
891 status = config_lookup(channel, p, "bind", "hosts");
903 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
904 error, strerror(error)));
905 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
911 if ((status == ARES_EOF) && (!channel->lookups)) {
912 /* Tru64 uses /etc/svc.conf */
913 fp = fopen("/etc/svc.conf", "r");
915 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
917 if ((p = try_config(line, "hosts=")) && !channel->lookups)
918 status = config_lookup(channel, p, "bind", "local");
930 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
931 error, strerror(error)));
932 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
945 if (status != ARES_EOF)
949 if (sortlist != NULL)
954 /* If we got any name server entries, fill them in. */
960 channel->servers = servers;
961 channel->nservers = nservers;
964 /* If we got any sortlist entries, fill them in. */
967 channel->sortlist = sortlist;
968 channel->nsort = nsort;
974 static int init_by_defaults(ares_channel channel)
976 char *hostname = NULL;
977 int rc = ARES_SUCCESS;
978 #ifdef HAVE_GETHOSTNAME
982 if (channel->flags == -1)
984 if (channel->timeout == -1)
985 channel->timeout = DEFAULT_TIMEOUT;
986 if (channel->tries == -1)
987 channel->tries = DEFAULT_TRIES;
988 if (channel->ndots == -1)
990 if (channel->rotate == -1)
992 if (channel->udp_port == -1)
993 channel->udp_port = htons(NAMESERVER_PORT);
994 if (channel->tcp_port == -1)
995 channel->tcp_port = htons(NAMESERVER_PORT);
997 if (channel->nservers == -1) {
998 /* If nobody specified servers, try a local named. */
999 channel->servers = malloc(sizeof(struct server_state));
1000 if (!channel->servers) {
1004 channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
1005 channel->nservers = 1;
1009 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
1011 #define toolong(x) (x == -1) && (EINVAL == errno)
1014 if (channel->ndomains == -1) {
1015 /* Derive a default domain search list from the kernel hostname,
1016 * or set it to empty if the hostname isn't helpful.
1020 channel->ndomains = 0; /* default to none */
1022 #ifdef HAVE_GETHOSTNAME
1023 hostname = malloc(len);
1030 res = gethostname(hostname, len);
1035 p = realloc(hostname, len);
1050 dot = strchr(hostname, '.');
1052 /* a dot was found */
1053 channel->domains = malloc(sizeof(char *));
1054 if (!channel->domains) {
1058 channel->domains[0] = strdup(dot + 1);
1059 if (!channel->domains[0]) {
1063 channel->ndomains = 1;
1068 if (channel->nsort == -1) {
1069 channel->sortlist = NULL;
1073 if (!channel->lookups) {
1074 channel->lookups = strdup("fb");
1075 if (!channel->lookups)
1081 if(channel->servers)
1082 free(channel->servers);
1084 if(channel->domains && channel->domains[0])
1085 free(channel->domains[0]);
1086 if(channel->domains)
1087 free(channel->domains);
1088 if(channel->lookups)
1089 free(channel->lookups);
1098 #if !defined(WIN32) && !defined(WATT32)
1099 static int config_domain(ares_channel channel, char *str)
1103 /* Set a single search domain. */
1105 while (*q && !ISSPACE(*q))
1108 return set_search(channel, str);
1111 static int config_lookup(ares_channel channel, const char *str,
1112 const char *bindch, const char *filech)
1114 char lookups[3], *l;
1117 /* Set the lookup order. Only the first letter of each work
1118 * is relevant, and it has to be "b" for DNS or "f" for the
1119 * host file. Ignore everything else.
1125 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1126 if (*p == *bindch) *l++ = 'b';
1129 while (*p && !ISSPACE(*p) && (*p != ','))
1131 while (*p && (ISSPACE(*p) || (*p == ',')))
1135 channel->lookups = strdup(lookups);
1136 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1138 #endif /* !WIN32 & !WATT32 */
1141 static int config_nameserver(struct server_state **servers, int *nservers,
1144 struct in_addr addr;
1145 struct server_state *newserv;
1146 /* On Windows, there may be more than one nameserver specified in the same
1147 * registry key, so we parse it as a space or comma seperated list.
1156 while (*p && !ISSPACE(*p) && *p != ',')
1165 /* Skip multiple spaces or trailing spaces */
1172 /* This is the part that actually sets the nameserver */
1173 addr.s_addr = inet_addr(begin);
1174 if (addr.s_addr == INADDR_NONE)
1176 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1179 newserv[*nservers].addr = addr;
1188 /* Add a nameserver entry, if this is a valid address. */
1189 addr.s_addr = inet_addr(str);
1190 if (addr.s_addr == INADDR_NONE)
1191 return ARES_SUCCESS;
1192 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1195 newserv[*nservers].addr = addr;
1199 return ARES_SUCCESS;
1203 static int config_sortlist(struct apattern **sortlist, int *nsort,
1206 struct apattern pat;
1209 /* Add sortlist entries. */
1210 while (*str && *str != ';')
1213 char ipbuf[16], ipbufpfx[32];
1214 /* Find just the IP */
1216 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1218 memcpy(ipbuf, str, (int)(q-str));
1219 ipbuf[(int)(q-str)] = '\0';
1220 /* Find the prefix */
1223 const char *str2 = q+1;
1224 while (*q && *q != ';' && !ISSPACE(*q))
1226 memcpy(ipbufpfx, str, (int)(q-str));
1227 ipbufpfx[(int)(q-str)] = '\0';
1232 /* Lets see if it is CIDR */
1233 /* First we'll try IPv6 */
1234 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1236 sizeof(pat.addrV6))) > 0)
1238 pat.type = PATTERN_CIDR;
1239 pat.mask.bits = (unsigned short)bits;
1240 pat.family = AF_INET6;
1241 if (!sortlist_alloc(sortlist, nsort, &pat))
1245 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1246 sizeof(pat.addrV4))) > 0)
1248 pat.type = PATTERN_CIDR;
1249 pat.mask.bits = (unsigned short)bits;
1250 pat.family = AF_INET;
1251 if (!sortlist_alloc(sortlist, nsort, &pat))
1254 /* See if it is just a regular IP */
1255 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1259 memcpy(ipbuf, str, (int)(q-str));
1260 ipbuf[(int)(q-str)] = '\0';
1261 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1266 pat.family = AF_INET;
1267 pat.type = PATTERN_MASK;
1268 if (!sortlist_alloc(sortlist, nsort, &pat))
1273 while (*q && *q != ';' && !ISSPACE(*q))
1277 while (ISSPACE(*str))
1281 return ARES_SUCCESS;
1284 #endif /* !WATT32 */
1286 static int set_search(ares_channel channel, const char *str)
1291 if(channel->ndomains != -1) {
1292 /* if we already have some domains present, free them first */
1293 for(n=0; n < channel->ndomains; n++)
1294 free(channel->domains[n]);
1295 free(channel->domains);
1296 channel->domains = NULL;
1297 channel->ndomains = -1;
1300 /* Count the domains given. */
1305 while (*p && !ISSPACE(*p))
1314 channel->ndomains = 0;
1315 return ARES_SUCCESS;
1318 channel->domains = malloc(n * sizeof(char *));
1319 if (!channel->domains)
1322 /* Now copy the domains. */
1327 channel->ndomains = n;
1329 while (*q && !ISSPACE(*q))
1331 channel->domains[n] = malloc(q - p + 1);
1332 if (!channel->domains[n])
1334 memcpy(channel->domains[n], p, q - p);
1335 channel->domains[n][q - p] = 0;
1341 channel->ndomains = n;
1343 return ARES_SUCCESS;
1346 static int set_options(ares_channel channel, const char *str)
1348 const char *p, *q, *val;
1354 while (*q && !ISSPACE(*q))
1356 val = try_option(p, q, "ndots:");
1357 if (val && channel->ndots == -1)
1358 channel->ndots = atoi(val);
1359 val = try_option(p, q, "retrans:");
1360 if (val && channel->timeout == -1)
1361 channel->timeout = atoi(val);
1362 val = try_option(p, q, "retry:");
1363 if (val && channel->tries == -1)
1364 channel->tries = atoi(val);
1365 val = try_option(p, q, "rotate");
1366 if (val && channel->rotate == -1)
1367 channel->rotate = 1;
1373 return ARES_SUCCESS;
1376 static const char *try_option(const char *p, const char *q, const char *opt)
1378 size_t len = strlen(opt);
1379 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1382 #if !defined(WIN32) && !defined(WATT32)
1383 static char *try_config(char *s, const char *opt)
1391 /* no line or no option */
1394 /* trim line comment */
1395 for (i = 0; s[i] && s[i] != '#'; ++i);
1398 /* trim trailing whitespace */
1399 for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
1402 /* skip leading whitespace */
1403 for (i = 0; s[i] && ISSPACE(s[i]); ++i);
1410 if ((len = strlen(opt)) == 0)
1414 if (strncmp(p, opt, len) != 0)
1415 /* line and option do not match */
1418 /* skip over given option name */
1422 /* no option value */
1425 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1426 /* whitespace between option name and value is mandatory
1427 for given option names which do not end with ':' or '=' */
1430 /* skip over whitespace */
1431 while (*p && ISSPACE(*p))
1435 /* no option value */
1438 /* return pointer to option value */
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);
1487 #endif /* !WIN32 && !WATT32 */
1489 /* initialize an rc4 key. If possible a cryptographically secure random key
1490 is generated using a suitable function (for example win32's RtlGenRandom as
1492 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1493 otherwise the code defaults to cross-platform albeit less secure mechanism
1496 static void randomize_key(unsigned char* key,int key_data_len)
1502 if (fpSystemFunction036)
1504 res = (*fpSystemFunction036) (key, key_data_len);
1510 FILE *f = fopen(RANDOM_FILE, "rb");
1512 counter = fread(key, 1, key_data_len, f);
1518 if ( !randomized ) {
1519 for (;counter<key_data_len;counter++)
1520 key[counter]=(unsigned char)(rand() % 256);
1524 static int init_id_key(rc4_key* key,int key_data_len)
1526 unsigned char index1;
1527 unsigned char index2;
1528 unsigned char* state;
1530 unsigned char *key_data_ptr = 0;
1532 key_data_ptr = calloc(1,key_data_len);
1536 state = &key->state[0];
1537 for(counter = 0; counter < 256; counter++)
1538 /* unnecessary AND but it keeps some compilers happier */
1539 state[counter] = (unsigned char)(counter & 0xff);
1540 randomize_key(key->state,key_data_len);
1545 for(counter = 0; counter < 256; counter++)
1547 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1549 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1551 index1 = (unsigned char)((index1 + 1) % key_data_len);
1554 return ARES_SUCCESS;
1557 unsigned short ares__generate_new_id(rc4_key* key)
1560 ares__rc4(key, (unsigned char *)&r, sizeof(r));
1564 void ares_set_socket_callback(ares_channel channel,
1565 ares_sock_create_callback cb,
1568 channel->sock_create_cb = cb;
1569 channel->sock_create_cb_data = data;