3 /* Copyright 1998 by the Massachusetts Institute of Technology.
4 * Copyright (C) 2007-2008 by Daniel Stenberg
6 * Permission to use, copy, modify, and distribute this
7 * software and its documentation for any purpose and without
8 * fee is hereby granted, provided that the above copyright
9 * notice appear in all copies and that both that copyright
10 * notice and this permission notice appear in supporting
11 * documentation, and that the name of M.I.T. not be used in
12 * advertising or publicity pertaining to distribution of the
13 * software without specific, written prior permission.
14 * M.I.T. makes no representations about the suitability of
15 * this software for any purpose. It is provided "as is"
16 * without express or implied warranty.
21 #if defined(WIN32) && !defined(WATT32)
26 #ifdef HAVE_SYS_PARAM_H
27 #include <sys/param.h>
30 #ifdef HAVE_SYS_TIME_H
34 #ifdef HAVE_SYS_SOCKET_H
35 #include <sys/socket.h>
38 #ifdef HAVE_NETINET_IN_H
39 #include <netinet/in.h>
46 #ifdef HAVE_ARPA_INET_H
47 #include <arpa/inet.h>
50 #ifdef HAVE_ARPA_NAMESER_H
51 # include <arpa/nameser.h>
55 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
56 # include <arpa/nameser_compat.h>
70 #include "inet_net_pton.h"
71 #include "ares_private.h"
74 #undef WIN32 /* Redefined in MingW/MSVC headers */
77 static int init_by_options(ares_channel channel, const struct ares_options *options,
79 static int init_by_environment(ares_channel channel);
80 static int init_by_resolv_conf(ares_channel channel);
81 static int init_by_defaults(ares_channel channel);
83 static int config_nameserver(struct server_state **servers, int *nservers,
85 static int set_search(ares_channel channel, const char *str);
86 static int set_options(ares_channel channel, const char *str);
87 static const char *try_option(const char *p, const char *q, const char *opt);
88 static int init_id_key(rc4_key* key,int key_data_len);
91 static int sortlist_alloc(struct apattern **sortlist, int *nsort, struct apattern *pat);
92 static int ip_addr(const char *s, int len, struct in_addr *addr);
93 static void natural_mask(struct apattern *pat);
94 static int config_domain(ares_channel channel, char *str);
95 static int config_lookup(ares_channel channel, const char *str,
96 const char *bindch, const char *filech);
97 static int config_sortlist(struct apattern **sortlist, int *nsort,
99 static char *try_config(char *s, const char *opt);
102 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
103 x->nservers > -1 && \
104 x->ndomains > -1 && \
105 x->ndots > -1 && x->timeout > -1 && \
108 int ares_init(ares_channel *channelptr)
110 return ares_init_options(channelptr, NULL, 0);
113 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
116 ares_channel channel;
118 int status = ARES_SUCCESS;
119 struct server_state *server;
123 const char *env = getenv("CARES_MEMDEBUG");
127 env = getenv("CARES_MEMLIMIT");
129 curl_memlimit(atoi(env));
132 channel = malloc(sizeof(struct ares_channeldata));
140 /* Set everything to distinguished values so we know they haven't
144 channel->timeout = -1;
147 channel->rotate = -1;
148 channel->udp_port = -1;
149 channel->tcp_port = -1;
150 channel->socket_send_buffer_size = -1;
151 channel->socket_receive_buffer_size = -1;
152 channel->nservers = -1;
153 channel->ndomains = -1;
155 channel->tcp_connection_generation = 0;
156 channel->lookups = NULL;
157 channel->domains = NULL;
158 channel->sortlist = NULL;
159 channel->servers = NULL;
160 channel->sock_state_cb = NULL;
161 channel->sock_state_cb_data = NULL;
163 channel->last_server = 0;
164 channel->last_timeout_processed = (time_t)now.tv_sec;
166 /* Initialize our lists of queries */
167 ares__init_list_head(&(channel->all_queries));
168 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
170 ares__init_list_head(&(channel->queries_by_qid[i]));
172 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
174 ares__init_list_head(&(channel->queries_by_timeout[i]));
177 /* Initialize configuration by each of the four sources, from highest
178 * precedence to lowest.
181 if (status == ARES_SUCCESS) {
182 status = init_by_options(channel, options, optmask);
183 if (status != ARES_SUCCESS)
184 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
185 ares_strerror(status)));
187 if (status == ARES_SUCCESS) {
188 status = init_by_environment(channel);
189 if (status != ARES_SUCCESS)
190 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
191 ares_strerror(status)));
193 if (status == ARES_SUCCESS) {
194 status = init_by_resolv_conf(channel);
195 if (status != ARES_SUCCESS)
196 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
197 ares_strerror(status)));
199 if (status == ARES_SUCCESS) {
200 status = init_by_defaults(channel);
201 if (status != ARES_SUCCESS)
202 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
203 ares_strerror(status)));
206 /* Generate random key */
208 if (status == ARES_SUCCESS) {
209 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
210 if (status == ARES_SUCCESS)
211 channel->next_id = ares__generate_new_id(&channel->id_key);
213 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
214 ares_strerror(status)));
217 if (status != ARES_SUCCESS)
219 /* Something failed; clean up memory we may have allocated. */
220 if (channel->servers)
221 free(channel->servers);
222 if (channel->domains)
224 for (i = 0; i < channel->ndomains; i++)
225 free(channel->domains[i]);
226 free(channel->domains);
228 if (channel->sortlist)
229 free(channel->sortlist);
231 free(channel->lookups);
236 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
237 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
238 channel->nservers = 1;
240 /* Initialize server states. */
241 for (i = 0; i < channel->nservers; i++)
243 server = &channel->servers[i];
244 server->udp_socket = ARES_SOCKET_BAD;
245 server->tcp_socket = ARES_SOCKET_BAD;
246 server->tcp_connection_generation = ++channel->tcp_connection_generation;
247 server->tcp_lenbuf_pos = 0;
248 server->tcp_buffer = NULL;
249 server->qhead = NULL;
250 server->qtail = NULL;
251 ares__init_list_head(&(server->queries_to_server));
252 server->channel = channel;
253 server->is_broken = 0;
256 *channelptr = channel;
260 /* Save options from initialized channel */
261 int ares_save_options(ares_channel channel, struct ares_options *options,
266 /* Zero everything out */
267 memset(options, 0, sizeof(struct ares_options));
269 if (!ARES_CONFIG_CHECK(channel))
272 /* Traditionally the optmask wasn't saved in the channel struct so it was
273 recreated here. ROTATE is the first option that has no struct field of
274 its own in the public config struct */
275 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
276 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
277 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
278 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
279 (channel->optmask & ARES_OPT_ROTATE);
281 /* Copy easy stuff */
282 options->flags = channel->flags;
284 /* We return full millisecond resolution but that's only because we don't
285 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
286 options->timeout = channel->timeout;
287 options->tries = channel->tries;
288 options->ndots = channel->ndots;
289 options->udp_port = (unsigned short)channel->udp_port;
290 options->tcp_port = (unsigned short)channel->tcp_port;
291 options->sock_state_cb = channel->sock_state_cb;
292 options->sock_state_cb_data = channel->sock_state_cb_data;
295 if (channel->nservers) {
297 malloc(channel->nservers * sizeof(struct server_state));
298 if (!options->servers && channel->nservers != 0)
300 for (i = 0; i < channel->nservers; i++)
301 options->servers[i] = channel->servers[i].addr;
303 options->nservers = channel->nservers;
306 if (channel->ndomains) {
307 options->domains = malloc(channel->ndomains * sizeof(char *));
308 if (!options->domains)
311 for (i = 0; i < channel->ndomains; i++)
313 options->ndomains = i;
314 options->domains[i] = strdup(channel->domains[i]);
315 if (!options->domains[i])
319 options->ndomains = channel->ndomains;
322 if (channel->lookups) {
323 options->lookups = strdup(channel->lookups);
324 if (!options->lookups && channel->lookups)
329 if (channel->nsort) {
330 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
331 if (!options->sortlist)
333 for (i = 0; i < channel->nsort; i++)
335 memcpy(&(options->sortlist[i]), &(channel->sortlist[i]),
336 sizeof(struct apattern));
339 options->nsort = channel->nsort;
344 static int init_by_options(ares_channel channel,
345 const struct ares_options *options,
351 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
352 channel->flags = options->flags;
353 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
354 channel->timeout = options->timeout;
355 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
356 channel->timeout = options->timeout * 1000;
357 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
358 channel->tries = options->tries;
359 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
360 channel->ndots = options->ndots;
361 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
363 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
364 channel->udp_port = options->udp_port;
365 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
366 channel->tcp_port = options->tcp_port;
367 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
369 channel->sock_state_cb = options->sock_state_cb;
370 channel->sock_state_cb_data = options->sock_state_cb_data;
372 if ((optmask & ARES_OPT_SOCK_SNDBUF)
373 && channel->socket_send_buffer_size == -1)
374 channel->socket_send_buffer_size = options->socket_send_buffer_size;
375 if ((optmask & ARES_OPT_SOCK_RCVBUF)
376 && channel->socket_receive_buffer_size == -1)
377 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
379 /* Copy the servers, if given. */
380 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
382 /* Avoid zero size allocations at any cost */
383 if (options->nservers > 0)
386 malloc(options->nservers * sizeof(struct server_state));
387 if (!channel->servers)
389 for (i = 0; i < options->nservers; i++)
390 channel->servers[i].addr = options->servers[i];
392 channel->nservers = options->nservers;
395 /* Copy the domains, if given. Keep channel->ndomains consistent so
396 * we can clean up in case of error.
398 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
400 /* Avoid zero size allocations at any cost */
401 if (options->ndomains > 0)
403 channel->domains = malloc(options->ndomains * sizeof(char *));
404 if (!channel->domains)
406 for (i = 0; i < options->ndomains; i++)
408 channel->ndomains = i;
409 channel->domains[i] = strdup(options->domains[i]);
410 if (!channel->domains[i])
414 channel->ndomains = options->ndomains;
417 /* Set lookups, if given. */
418 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
420 channel->lookups = strdup(options->lookups);
421 if (!channel->lookups)
426 if ((optmask & ARES_OPT_SORTLIST) && channel->nsort == -1)
428 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
429 if (!channel->sortlist)
431 for (i = 0; i < options->nsort; i++)
433 memcpy(&(channel->sortlist[i]), &(options->sortlist[i]),
434 sizeof(struct apattern));
436 channel->nsort = options->nsort;
439 channel->optmask = optmask;
444 static int init_by_environment(ares_channel channel)
446 const char *localdomain, *res_options;
449 localdomain = getenv("LOCALDOMAIN");
450 if (localdomain && channel->ndomains == -1)
452 status = set_search(channel, localdomain);
453 if (status != ARES_SUCCESS)
457 res_options = getenv("RES_OPTIONS");
460 status = set_options(channel, res_options);
461 if (status != ARES_SUCCESS)
470 * Warning: returns a dynamically allocated buffer, the user MUST
471 * use free() if the function returns 1
473 static int get_res_nt(HKEY hKey, const char *subkey, char **obuf)
475 /* Test for the size we need */
479 result = RegQueryValueEx(hKey, subkey, 0, NULL, NULL, &size);
480 if ((result != ERROR_SUCCESS && result != ERROR_MORE_DATA) || !size)
482 *obuf = malloc(size+1);
486 if (RegQueryValueEx(hKey, subkey, 0, NULL,
487 (LPBYTE)*obuf, &size) != ERROR_SUCCESS)
500 static int get_res_interfaces_nt(HKEY hKey, const char *subkey, char **obuf)
502 char enumbuf[39]; /* GUIDs are 38 chars + 1 for NULL */
503 DWORD enum_size = 39;
507 while (RegEnumKeyEx(hKey, idx++, enumbuf, &enum_size, 0,
508 NULL, NULL, NULL) != ERROR_NO_MORE_ITEMS)
513 if (RegOpenKeyEx(hKey, enumbuf, 0, KEY_QUERY_VALUE, &hVal) !=
516 rc = get_res_nt(hVal, subkey, obuf);
524 static int get_iphlpapi_dns_info (char *ret_buf, size_t ret_size)
526 FIXED_INFO *fi = alloca (sizeof(*fi));
527 DWORD size = sizeof (*fi);
528 typedef DWORD (WINAPI* get_net_param_func) (FIXED_INFO*, DWORD*);
529 get_net_param_func fpGetNetworkParams; /* available only on Win-98/2000+ */
531 IP_ADDR_STRING *ipAddr;
534 size_t ip_size = sizeof("255.255.255.255,")-1;
535 size_t left = ret_size;
542 handle = LoadLibrary ("iphlpapi.dll");
546 fpGetNetworkParams = (get_net_param_func) GetProcAddress (handle, "GetNetworkParams");
547 if (!fpGetNetworkParams)
550 res = (*fpGetNetworkParams) (fi, &size);
551 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
555 if (!fi || (*fpGetNetworkParams) (fi, &size) != ERROR_SUCCESS)
560 printf ("Host Name: %s\n", fi->HostName);
561 printf ("Domain Name: %s\n", fi->DomainName);
562 printf ("DNS Servers:\n"
563 " %s (primary)\n", fi->DnsServerList.IpAddress.String);
565 if (strlen(fi->DnsServerList.IpAddress.String) > 0 &&
566 inet_addr(fi->DnsServerList.IpAddress.String) != INADDR_NONE &&
569 ret += sprintf (ret, "%s,", fi->DnsServerList.IpAddress.String);
570 left -= ret - ret_buf;
574 for (i = 0, ipAddr = fi->DnsServerList.Next; ipAddr && left > ip_size;
575 ipAddr = ipAddr->Next, i++)
577 if (inet_addr(ipAddr->IpAddress.String) != INADDR_NONE)
579 ret += sprintf (ret, "%s,", ipAddr->IpAddress.String);
580 left -= ret - ret_buf;
584 printf (" %s (secondary %d)\n", ipAddr->IpAddress.String, i+1);
589 FreeLibrary (handle);
591 if (debug && left <= ip_size)
592 printf ("Too many nameservers. Truncating to %d addressess", count);
599 static int init_by_resolv_conf(ares_channel channel)
602 int status = -1, nservers = 0, nsort = 0;
603 struct server_state *servers = NULL;
604 struct apattern *sortlist = NULL;
609 NameServer info via IPHLPAPI (IP helper API):
610 GetNetworkParams() should be the trusted source for this.
611 Available in Win-98/2000 and later. If that fail, fall-back to
612 registry information.
616 On Windows 9X, the DNS server can be found in:
617 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\VxD\MSTCP\NameServer
619 On Windows NT/2000/XP/2003:
620 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\NameServer
622 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\DhcpNameServer
624 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
627 HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\{AdapterID}\
638 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
641 if (get_iphlpapi_dns_info(buf,sizeof(buf)) > 0)
643 status = config_nameserver(&servers, &nservers, buf);
644 if (status == ARES_SUCCESS)
651 HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0,
655 RegOpenKeyEx(mykey, "Interfaces", 0,
656 KEY_QUERY_VALUE|KEY_ENUMERATE_SUB_KEYS, &subkey);
657 if (get_res_nt(mykey, NAMESERVER, &line))
659 status = config_nameserver(&servers, &nservers, line);
662 else if (get_res_nt(mykey, DHCPNAMESERVER, &line))
664 status = config_nameserver(&servers, &nservers, line);
667 /* Try the interfaces */
668 else if (get_res_interfaces_nt(subkey, NAMESERVER, &line))
670 status = config_nameserver(&servers, &nservers, line);
673 else if (get_res_interfaces_nt(subkey, DHCPNAMESERVER, &line))
675 status = config_nameserver(&servers, &nservers, line);
685 HKEY_LOCAL_MACHINE, WIN_NS_9X, 0,
689 if ((result = RegQueryValueEx(
690 mykey, NAMESERVER, NULL, &data_type,
693 ) == ERROR_SUCCESS ||
694 result == ERROR_MORE_DATA)
698 line = malloc(bytes+1);
699 if (RegQueryValueEx(mykey, NAMESERVER, NULL, &data_type,
700 (unsigned char *)line, &bytes) ==
703 status = config_nameserver(&servers, &nservers, line);
712 if (status == ARES_SUCCESS)
715 /* Catch the case when all the above checks fail (which happens when there
716 is no network card or the cable is unplugged) */
719 #elif defined(__riscos__)
721 /* Under RISC OS, name servers are listed in the
722 system variable Inet$Resolvers, space separated. */
724 line = getenv("Inet$Resolvers");
727 char *resolvers = strdup(line), *pos, *space;
734 space = strchr(pos, ' ');
737 status = config_nameserver(&servers, &nservers, pos);
738 if (status != ARES_SUCCESS)
743 if (status == ARES_SUCCESS)
749 #elif defined(WATT32)
753 for (i = 0; def_nameservers[i]; i++)
756 return ARES_SUCCESS; /* use localhost DNS server */
759 servers = calloc(sizeof(*servers), i);
763 for (i = 0; def_nameservers[i]; i++)
764 servers[i].addr.s_addr = htonl(def_nameservers[i]);
774 /* Don't read resolv.conf and friends if we don't have to */
775 if (ARES_CONFIG_CHECK(channel))
778 fp = fopen(PATH_RESOLV_CONF, "r");
780 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
782 if ((p = try_config(line, "domain")) && channel->ndomains == -1)
783 status = config_domain(channel, p);
784 else if ((p = try_config(line, "lookup")) && !channel->lookups)
785 status = config_lookup(channel, p, "bind", "file");
786 else if ((p = try_config(line, "search")) && channel->ndomains == -1)
787 status = set_search(channel, p);
788 else if ((p = try_config(line, "nameserver")) && channel->nservers == -1)
789 status = config_nameserver(&servers, &nservers, p);
790 else if ((p = try_config(line, "sortlist")) && channel->nsort == -1)
791 status = config_sortlist(&sortlist, &nsort, p);
792 else if ((p = try_config(line, "options")))
793 status = set_options(channel, p);
795 status = ARES_SUCCESS;
796 if (status != ARES_SUCCESS)
809 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
810 error, strerror(error)));
811 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
816 if ((status == ARES_EOF) && (!channel->lookups)) {
817 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
818 fp = fopen("/etc/nsswitch.conf", "r");
820 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
822 if ((p = try_config(line, "hosts:")) && !channel->lookups)
823 status = config_lookup(channel, p, "dns", "files");
835 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
836 error, strerror(error)));
837 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/nsswitch.conf"));
843 if ((status == ARES_EOF) && (!channel->lookups)) {
844 /* Linux / GNU libc 2.x and possibly others have host.conf */
845 fp = fopen("/etc/host.conf", "r");
847 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
849 if ((p = try_config(line, "order")) && !channel->lookups)
850 status = config_lookup(channel, p, "bind", "hosts");
862 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
863 error, strerror(error)));
864 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/host.conf"));
870 if ((status == ARES_EOF) && (!channel->lookups)) {
871 /* Tru64 uses /etc/svc.conf */
872 fp = fopen("/etc/svc.conf", "r");
874 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
876 if ((p = try_config(line, "hosts=")) && !channel->lookups)
877 status = config_lookup(channel, p, "bind", "local");
889 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
890 error, strerror(error)));
891 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
904 if (status != ARES_EOF)
908 if (sortlist != NULL)
913 /* If we got any name server entries, fill them in. */
919 channel->servers = servers;
920 channel->nservers = nservers;
923 /* If we got any sortlist entries, fill them in. */
926 channel->sortlist = sortlist;
927 channel->nsort = nsort;
933 static int init_by_defaults(ares_channel channel)
935 char *hostname = NULL;
936 int rc = ARES_SUCCESS;
938 if (channel->flags == -1)
940 if (channel->timeout == -1)
941 channel->timeout = DEFAULT_TIMEOUT;
942 if (channel->tries == -1)
943 channel->tries = DEFAULT_TRIES;
944 if (channel->ndots == -1)
946 if (channel->rotate == -1)
948 if (channel->udp_port == -1)
949 channel->udp_port = htons(NAMESERVER_PORT);
950 if (channel->tcp_port == -1)
951 channel->tcp_port = htons(NAMESERVER_PORT);
953 if (channel->nservers == -1) {
954 /* If nobody specified servers, try a local named. */
955 channel->servers = malloc(sizeof(struct server_state));
956 if (!channel->servers) {
960 channel->servers[0].addr.s_addr = htonl(INADDR_LOOPBACK);
961 channel->nservers = 1;
965 #define toolong(x) (x == -1) && ((ENAMETOOLONG == errno) || (EINVAL == errno))
967 #define toolong(x) (x == -1) && (EINVAL == errno)
970 if (channel->ndomains == -1) {
971 /* Derive a default domain search list from the kernel hostname,
972 * or set it to empty if the hostname isn't helpful.
976 channel->ndomains = 0; /* default to none */
978 #ifdef HAVE_GETHOSTNAME
979 hostname = malloc(len);
986 res = gethostname(hostname, len);
991 p = realloc(hostname, len);
1006 if (strchr(hostname, '.')) {
1007 /* a dot was found */
1009 channel->domains = malloc(sizeof(char *));
1010 if (!channel->domains) {
1014 channel->domains[0] = strdup(strchr(hostname, '.') + 1);
1015 if (!channel->domains[0]) {
1019 channel->ndomains = 1;
1024 if (channel->nsort == -1) {
1025 channel->sortlist = NULL;
1029 if (!channel->lookups) {
1030 channel->lookups = strdup("fb");
1031 if (!channel->lookups)
1037 if(channel->servers)
1038 free(channel->servers);
1040 if(channel->domains && channel->domains[0])
1041 free(channel->domains[0]);
1042 if(channel->domains)
1043 free(channel->domains);
1044 if(channel->lookups)
1045 free(channel->lookups);
1055 static int config_domain(ares_channel channel, char *str)
1059 /* Set a single search domain. */
1061 while (*q && !ISSPACE(*q))
1064 return set_search(channel, str);
1067 static int config_lookup(ares_channel channel, const char *str,
1068 const char *bindch, const char *filech)
1070 char lookups[3], *l;
1073 /* Set the lookup order. Only the first letter of each work
1074 * is relevant, and it has to be "b" for DNS or "f" for the
1075 * host file. Ignore everything else.
1081 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1082 if (*p == *bindch) *l++ = 'b';
1085 while (*p && !ISSPACE(*p) && (*p != ','))
1087 while (*p && (ISSPACE(*p) || (*p == ',')))
1091 channel->lookups = strdup(lookups);
1092 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1097 static int config_nameserver(struct server_state **servers, int *nservers,
1100 struct in_addr addr;
1101 struct server_state *newserv;
1102 /* On Windows, there may be more than one nameserver specified in the same
1103 * registry key, so we parse it as a space or comma seperated list.
1112 while (*p && !ISSPACE(*p) && *p != ',')
1121 /* Skip multiple spaces or trailing spaces */
1128 /* This is the part that actually sets the nameserver */
1129 addr.s_addr = inet_addr(begin);
1130 if (addr.s_addr == INADDR_NONE)
1132 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1135 newserv[*nservers].addr = addr;
1144 /* Add a nameserver entry, if this is a valid address. */
1145 addr.s_addr = inet_addr(str);
1146 if (addr.s_addr == INADDR_NONE)
1147 return ARES_SUCCESS;
1148 newserv = realloc(*servers, (*nservers + 1) * sizeof(struct server_state));
1151 newserv[*nservers].addr = addr;
1155 return ARES_SUCCESS;
1159 static int config_sortlist(struct apattern **sortlist, int *nsort,
1162 struct apattern pat;
1165 /* Add sortlist entries. */
1166 while (*str && *str != ';')
1169 char ipbuf[16], ipbufpfx[32];
1170 /* Find just the IP */
1172 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1174 memcpy(ipbuf, str, (int)(q-str));
1175 ipbuf[(int)(q-str)] = '\0';
1176 /* Find the prefix */
1179 const char *str2 = q+1;
1180 while (*q && *q != ';' && !ISSPACE(*q))
1182 memcpy(ipbufpfx, str, (int)(q-str));
1183 ipbufpfx[(int)(q-str)] = '\0';
1188 /* Lets see if it is CIDR */
1189 /* First we'll try IPv6 */
1190 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1192 sizeof(pat.addrV6))) > 0)
1194 pat.type = PATTERN_CIDR;
1195 pat.mask.bits = (unsigned short)bits;
1196 pat.family = AF_INET6;
1197 if (!sortlist_alloc(sortlist, nsort, &pat))
1201 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1202 sizeof(pat.addrV4))) > 0)
1204 pat.type = PATTERN_CIDR;
1205 pat.mask.bits = (unsigned short)bits;
1206 pat.family = AF_INET;
1207 if (!sortlist_alloc(sortlist, nsort, &pat))
1210 /* See if it is just a regular IP */
1211 else if (ip_addr(ipbuf, (int)(q-str), &pat.addrV4) == 0)
1215 memcpy(ipbuf, str, (int)(q-str));
1216 ipbuf[(int)(q-str)] = '\0';
1217 if (ip_addr(ipbuf, (int)(q - str), &pat.mask.addr4) != 0)
1222 pat.family = AF_INET;
1223 pat.type = PATTERN_MASK;
1224 if (!sortlist_alloc(sortlist, nsort, &pat))
1229 while (*q && *q != ';' && !ISSPACE(*q))
1233 while (ISSPACE(*str))
1237 return ARES_SUCCESS;
1241 static int set_search(ares_channel channel, const char *str)
1246 if(channel->ndomains != -1) {
1247 /* if we already have some domains present, free them first */
1248 for(n=0; n < channel->ndomains; n++)
1249 free(channel->domains[n]);
1250 free(channel->domains);
1251 channel->domains = NULL;
1252 channel->ndomains = -1;
1255 /* Count the domains given. */
1260 while (*p && !ISSPACE(*p))
1269 channel->ndomains = 0;
1270 return ARES_SUCCESS;
1273 channel->domains = malloc(n * sizeof(char *));
1274 if (!channel->domains)
1277 /* Now copy the domains. */
1282 channel->ndomains = n;
1284 while (*q && !ISSPACE(*q))
1286 channel->domains[n] = malloc(q - p + 1);
1287 if (!channel->domains[n])
1289 memcpy(channel->domains[n], p, q - p);
1290 channel->domains[n][q - p] = 0;
1296 channel->ndomains = n;
1298 return ARES_SUCCESS;
1301 static int set_options(ares_channel channel, const char *str)
1303 const char *p, *q, *val;
1309 while (*q && !ISSPACE(*q))
1311 val = try_option(p, q, "ndots:");
1312 if (val && channel->ndots == -1)
1313 channel->ndots = atoi(val);
1314 val = try_option(p, q, "retrans:");
1315 if (val && channel->timeout == -1)
1316 channel->timeout = atoi(val);
1317 val = try_option(p, q, "retry:");
1318 if (val && channel->tries == -1)
1319 channel->tries = atoi(val);
1320 val = try_option(p, q, "rotate");
1321 if (val && channel->rotate == -1)
1322 channel->rotate = 1;
1328 return ARES_SUCCESS;
1332 static char *try_config(char *s, const char *opt)
1340 /* no line or no option */
1343 /* trim line comment */
1344 for (i = 0; s[i] && s[i] != '#'; ++i);
1347 /* trim trailing whitespace */
1348 for (j = i-1; j >= 0 && ISSPACE(s[j]); --j);
1351 /* skip leading whitespace */
1352 for (i = 0; s[i] && ISSPACE(s[i]); ++i);
1359 if ((len = strlen(opt)) == 0)
1363 if (strncmp(p, opt, len) != 0)
1364 /* line and option do not match */
1367 /* skip over given option name */
1371 /* no option value */
1374 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1375 /* whitespace between option name and value is mandatory
1376 for given option names which do not end with ':' or '=' */
1379 /* skip over whitespace */
1380 while (*p && ISSPACE(*p))
1384 /* no option value */
1387 /* return pointer to option value */
1392 static const char *try_option(const char *p, const char *q, const char *opt)
1394 size_t len = strlen(opt);
1395 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1399 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1400 struct apattern *pat)
1402 struct apattern *newsort;
1403 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1406 newsort[*nsort] = *pat;
1407 *sortlist = newsort;
1412 static int ip_addr(const char *ipbuf, int len, struct in_addr *addr)
1415 /* Four octets and three periods yields at most 15 characters. */
1419 addr->s_addr = inet_addr(ipbuf);
1420 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1425 static void natural_mask(struct apattern *pat)
1427 struct in_addr addr;
1429 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1432 addr.s_addr = ntohl(pat->addrV4.s_addr);
1434 /* This is out of date in the CIDR world, but some people might
1437 if (IN_CLASSA(addr.s_addr))
1438 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1439 else if (IN_CLASSB(addr.s_addr))
1440 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1442 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1445 /* initialize an rc4 key. If possible a cryptographically secure random key
1446 is generated using a suitable function (for example win32's RtlGenRandom as
1448 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1449 otherwise the code defaults to cross-platform albeit less secure mechanism
1452 static void randomize_key(unsigned char* key,int key_data_len)
1457 HMODULE lib=LoadLibrary("ADVAPI32.DLL");
1459 BOOLEAN (APIENTRY *pfn)(void*, ULONG) =
1460 (BOOLEAN (APIENTRY *)(void*,ULONG))GetProcAddress(lib,"SystemFunction036");
1461 if (pfn && pfn(key,key_data_len) )
1468 FILE *f = fopen(RANDOM_FILE, "rb");
1470 counter = fread(key, 1, key_data_len, f);
1476 if ( !randomized ) {
1477 for (;counter<key_data_len;counter++)
1478 key[counter]=(unsigned char)(rand() % 256);
1482 static int init_id_key(rc4_key* key,int key_data_len)
1484 unsigned char index1;
1485 unsigned char index2;
1486 unsigned char* state;
1488 unsigned char *key_data_ptr = 0;
1490 key_data_ptr = calloc(1,key_data_len);
1494 state = &key->state[0];
1495 for(counter = 0; counter < 256; counter++)
1496 /* unnecessary AND but it keeps some compilers happier */
1497 state[counter] = (unsigned char)(counter & 0xff);
1498 randomize_key(key->state,key_data_len);
1503 for(counter = 0; counter < 256; counter++)
1505 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1507 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1509 index1 = (unsigned char)((index1 + 1) % key_data_len);
1512 return ARES_SUCCESS;
1515 unsigned short ares__generate_new_id(rc4_key* key)
1518 ares__rc4(key, (unsigned char *)&r, sizeof(r));