2 /* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Copyright (C) 2007-2013 by Daniel Stenberg
5 * Permission to use, copy, modify, and distribute this
6 * software and its documentation for any purpose and without
7 * fee is hereby granted, provided that the above copyright
8 * notice appear in all copies and that both that copyright
9 * notice and this permission notice appear in supporting
10 * documentation, and that the name of M.I.T. not be used in
11 * advertising or publicity pertaining to distribution of the
12 * software without specific, written prior permission.
13 * M.I.T. makes no representations about the suitability of
14 * this software for any purpose. It is provided "as is"
15 * without express or implied warranty.
18 #include "ares_setup.h"
20 #ifdef HAVE_SYS_PARAM_H
21 #include <sys/param.h>
24 #ifdef HAVE_NETINET_IN_H
25 #include <netinet/in.h>
32 #ifdef HAVE_ARPA_INET_H
33 #include <arpa/inet.h>
36 #ifdef HAVE_ARPA_NAMESER_H
37 # include <arpa/nameser.h>
41 #ifdef HAVE_ARPA_NAMESER_COMPAT_H
42 # include <arpa/nameser_compat.h>
45 #if defined(ANDROID) || defined(__ANDROID__)
46 #include <sys/system_properties.h>
47 /* From the Bionic sources */
48 #define DNS_PROP_NAME_PREFIX "net.dns"
49 #define MAX_DNS_PROPERTIES 8
53 #include "ares_inet_net_pton.h"
54 #include "ares_library_init.h"
55 #include "ares_nowarn.h"
56 #include "ares_platform.h"
57 #include "ares_private.h"
60 #undef WIN32 /* Redefined in MingW/MSVC headers */
63 static int init_by_options(ares_channel channel,
64 const struct ares_options *options,
66 static int init_by_environment(ares_channel channel);
67 static int init_by_resolv_conf(ares_channel channel);
68 static int init_by_defaults(ares_channel channel);
71 static int config_nameserver(struct server_state **servers, int *nservers,
74 static int set_search(ares_channel channel, const char *str);
75 static int set_options(ares_channel channel, const char *str);
76 static const char *try_option(const char *p, const char *q, const char *opt);
77 static int init_id_key(rc4_key* key,int key_data_len);
79 #if !defined(WIN32) && !defined(WATT32) && \
80 !defined(ANDROID) && !defined(__ANDROID__)
81 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
82 struct apattern *pat);
83 static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
84 static void natural_mask(struct apattern *pat);
85 static int config_domain(ares_channel channel, char *str);
86 static int config_lookup(ares_channel channel, const char *str,
87 const char *bindch, const char *filech);
88 static int config_sortlist(struct apattern **sortlist, int *nsort,
90 static char *try_config(char *s, const char *opt, char scc);
93 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
96 x->ndots > -1 && x->timeout > -1 && \
99 int ares_init(ares_channel *channelptr)
101 return ares_init_options(channelptr, NULL, 0);
104 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
107 ares_channel channel;
109 int status = ARES_SUCCESS;
113 const char *env = getenv("CARES_MEMDEBUG");
117 env = getenv("CARES_MEMLIMIT");
120 long num = strtol(env, &endptr, 10);
121 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
126 if (ares_library_initialized() != ARES_SUCCESS)
127 return ARES_ENOTINITIALIZED;
129 channel = malloc(sizeof(struct ares_channeldata));
137 /* Set everything to distinguished values so we know they haven't
141 channel->timeout = -1;
144 channel->rotate = -1;
145 channel->udp_port = -1;
146 channel->tcp_port = -1;
147 channel->ednspsz = -1;
148 channel->socket_send_buffer_size = -1;
149 channel->socket_receive_buffer_size = -1;
150 channel->nservers = -1;
151 channel->ndomains = -1;
153 channel->tcp_connection_generation = 0;
154 channel->lookups = NULL;
155 channel->domains = NULL;
156 channel->sortlist = NULL;
157 channel->servers = NULL;
158 channel->sock_state_cb = NULL;
159 channel->sock_state_cb_data = NULL;
160 channel->sock_create_cb = NULL;
161 channel->sock_create_cb_data = NULL;
163 channel->last_server = 0;
164 channel->last_timeout_processed = (time_t)now.tv_sec;
166 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
167 channel->local_ip4 = 0;
168 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
170 /* Initialize our lists of queries */
171 ares__init_list_head(&(channel->all_queries));
172 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
174 ares__init_list_head(&(channel->queries_by_qid[i]));
176 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
178 ares__init_list_head(&(channel->queries_by_timeout[i]));
181 /* Initialize configuration by each of the four sources, from highest
182 * precedence to lowest.
185 if (status == ARES_SUCCESS) {
186 status = init_by_options(channel, options, optmask);
187 if (status != ARES_SUCCESS)
188 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
189 ares_strerror(status)));
191 if (status == ARES_SUCCESS) {
192 status = init_by_environment(channel);
193 if (status != ARES_SUCCESS)
194 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
195 ares_strerror(status)));
197 if (status == ARES_SUCCESS) {
198 status = init_by_resolv_conf(channel);
199 if (status != ARES_SUCCESS)
200 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
201 ares_strerror(status)));
205 * No matter what failed or succeeded, seed defaults to provide
206 * useful behavior for things that we missed.
208 status = init_by_defaults(channel);
209 if (status != ARES_SUCCESS)
210 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
211 ares_strerror(status)));
213 /* Generate random key */
215 if (status == ARES_SUCCESS) {
216 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
217 if (status == ARES_SUCCESS)
218 channel->next_id = ares__generate_new_id(&channel->id_key);
220 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
221 ares_strerror(status)));
224 if (status != ARES_SUCCESS)
226 /* Something failed; clean up memory we may have allocated. */
227 if (channel->servers)
228 free(channel->servers);
229 if (channel->domains)
231 for (i = 0; i < channel->ndomains; i++)
232 free(channel->domains[i]);
233 free(channel->domains);
235 if (channel->sortlist)
236 free(channel->sortlist);
238 free(channel->lookups);
243 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
244 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
245 channel->nservers = 1;
247 ares__init_servers_state(channel);
249 *channelptr = channel;
253 /* ares_dup() duplicates a channel handle with all its options and returns a
254 new channel handle */
255 int ares_dup(ares_channel *dest, ares_channel src)
257 struct ares_options opts;
258 struct ares_addr_node *servers;
259 int ipv6_nservers = 0;
263 *dest = NULL; /* in case of failure return NULL explicitly */
265 /* First get the options supported by the old ares_save_options() function,
266 which is most of them */
267 rc = ares_save_options(src, &opts, &optmask);
271 /* Then create the new channel with those options */
272 rc = ares_init_options(dest, &opts, optmask);
274 /* destroy the options copy to not leak any memory */
275 ares_destroy_options(&opts);
280 /* Now clone the options that ares_save_options() doesn't support. */
281 (*dest)->sock_create_cb = src->sock_create_cb;
282 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
284 strncpy((*dest)->local_dev_name, src->local_dev_name,
285 sizeof(src->local_dev_name));
286 (*dest)->local_ip4 = src->local_ip4;
287 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
289 /* Full name server cloning required when not all are IPv4 */
290 for (i = 0; i < src->nservers; i++)
292 if (src->servers[i].addr.family != AF_INET) {
298 rc = ares_get_servers(src, &servers);
299 if (rc != ARES_SUCCESS)
301 rc = ares_set_servers(*dest, servers);
302 ares_free_data(servers);
303 if (rc != ARES_SUCCESS)
307 return ARES_SUCCESS; /* everything went fine */
310 /* Save options from initialized channel */
311 int ares_save_options(ares_channel channel, struct ares_options *options,
315 int ipv4_nservers = 0;
317 /* Zero everything out */
318 memset(options, 0, sizeof(struct ares_options));
320 if (!ARES_CONFIG_CHECK(channel))
323 /* Traditionally the optmask wasn't saved in the channel struct so it was
324 recreated here. ROTATE is the first option that has no struct field of
325 its own in the public config struct */
326 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
327 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
328 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
329 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS) |
330 (channel->optmask & ARES_OPT_ROTATE);
332 /* Copy easy stuff */
333 options->flags = channel->flags;
335 /* We return full millisecond resolution but that's only because we don't
336 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
337 options->timeout = channel->timeout;
338 options->tries = channel->tries;
339 options->ndots = channel->ndots;
340 options->udp_port = ntohs(aresx_sitous(channel->udp_port));
341 options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
342 options->sock_state_cb = channel->sock_state_cb;
343 options->sock_state_cb_data = channel->sock_state_cb_data;
345 /* Copy IPv4 servers */
346 if (channel->nservers) {
347 for (i = 0; i < channel->nservers; i++)
349 if (channel->servers[i].addr.family == AF_INET)
353 options->servers = malloc(ipv4_nservers * sizeof(struct in_addr));
354 if (!options->servers)
356 for (i = j = 0; i < channel->nservers; i++)
358 if (channel->servers[i].addr.family == AF_INET)
359 memcpy(&options->servers[j++],
360 &channel->servers[i].addr.addrV4,
361 sizeof(channel->servers[i].addr.addrV4));
365 options->nservers = ipv4_nservers;
368 if (channel->ndomains) {
369 options->domains = malloc(channel->ndomains * sizeof(char *));
370 if (!options->domains)
373 for (i = 0; i < channel->ndomains; i++)
375 options->ndomains = i;
376 options->domains[i] = strdup(channel->domains[i]);
377 if (!options->domains[i])
381 options->ndomains = channel->ndomains;
384 if (channel->lookups) {
385 options->lookups = strdup(channel->lookups);
386 if (!options->lookups && channel->lookups)
391 if (channel->nsort) {
392 options->sortlist = malloc(channel->nsort * sizeof(struct apattern));
393 if (!options->sortlist)
395 for (i = 0; i < channel->nsort; i++)
396 options->sortlist[i] = channel->sortlist[i];
398 options->nsort = channel->nsort;
403 static int init_by_options(ares_channel channel,
404 const struct ares_options *options,
410 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
411 channel->flags = options->flags;
412 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
413 channel->timeout = options->timeout;
414 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
415 channel->timeout = options->timeout * 1000;
416 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
417 channel->tries = options->tries;
418 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
419 channel->ndots = options->ndots;
420 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
422 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
423 channel->udp_port = htons(options->udp_port);
424 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
425 channel->tcp_port = htons(options->tcp_port);
426 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
428 channel->sock_state_cb = options->sock_state_cb;
429 channel->sock_state_cb_data = options->sock_state_cb_data;
431 if ((optmask & ARES_OPT_SOCK_SNDBUF)
432 && channel->socket_send_buffer_size == -1)
433 channel->socket_send_buffer_size = options->socket_send_buffer_size;
434 if ((optmask & ARES_OPT_SOCK_RCVBUF)
435 && channel->socket_receive_buffer_size == -1)
436 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
438 if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
439 channel->ednspsz = options->ednspsz;
441 /* Copy the IPv4 servers, if given. */
442 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
444 /* Avoid zero size allocations at any cost */
445 if (options->nservers > 0)
448 malloc(options->nservers * sizeof(struct server_state));
449 if (!channel->servers)
451 for (i = 0; i < options->nservers; i++)
453 channel->servers[i].addr.family = AF_INET;
454 memcpy(&channel->servers[i].addr.addrV4,
455 &options->servers[i],
456 sizeof(channel->servers[i].addr.addrV4));
459 channel->nservers = options->nservers;
462 /* Copy the domains, if given. Keep channel->ndomains consistent so
463 * we can clean up in case of error.
465 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
467 /* Avoid zero size allocations at any cost */
468 if (options->ndomains > 0)
470 channel->domains = malloc(options->ndomains * sizeof(char *));
471 if (!channel->domains)
473 for (i = 0; i < options->ndomains; i++)
475 channel->ndomains = i;
476 channel->domains[i] = strdup(options->domains[i]);
477 if (!channel->domains[i])
481 channel->ndomains = options->ndomains;
484 /* Set lookups, if given. */
485 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
487 channel->lookups = strdup(options->lookups);
488 if (!channel->lookups)
493 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1) &&
494 (options->nsort>0)) {
495 channel->sortlist = malloc(options->nsort * sizeof(struct apattern));
496 if (!channel->sortlist)
498 for (i = 0; i < options->nsort; i++)
499 channel->sortlist[i] = options->sortlist[i];
500 channel->nsort = options->nsort;
503 channel->optmask = optmask;
508 static int init_by_environment(ares_channel channel)
510 const char *localdomain, *res_options;
513 localdomain = getenv("LOCALDOMAIN");
514 if (localdomain && channel->ndomains == -1)
516 status = set_search(channel, localdomain);
517 if (status != ARES_SUCCESS)
521 res_options = getenv("RES_OPTIONS");
524 status = set_options(channel, res_options);
525 if (status != ARES_SUCCESS)
536 * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
537 * to the name of the registry leaf key to be queried, fetch it's string
538 * value and return a pointer in *outptr to a newly allocated memory area
539 * holding it as a null-terminated string.
541 * Returns 0 and nullifies *outptr upon inability to return a string value.
543 * Returns 1 and sets *outptr when returning a dynamically allocated string.
545 * Supported on Windows NT 3.5 and newer.
547 static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
554 /* Find out size of string stored in registry */
555 res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size);
556 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
559 /* Allocate buffer of indicated size plus one given that string
560 might have been stored without null termination */
561 *outptr = malloc(size+1);
565 /* Get the value for real */
566 res = RegQueryValueEx(hKey, leafKeyName, 0, NULL,
567 (unsigned char *)*outptr, &size);
568 if ((res != ERROR_SUCCESS) || (size == 1))
575 /* Null terminate buffer allways */
576 *(*outptr + size) = '\0';
584 * Functionally identical to get_REG_SZ()
586 * Supported on Windows 95, 98 and ME.
588 static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
596 /* Find out size of string stored in registry */
597 res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size);
598 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
601 /* Allocate buffer of indicated size plus one given that string
602 might have been stored without null termination */
603 *outptr = malloc(size+1);
607 /* Get the value for real */
608 res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType,
609 (unsigned char *)*outptr, &size);
610 if ((res != ERROR_SUCCESS) || (size == 1))
617 /* Null terminate buffer allways */
618 *(*outptr + size) = '\0';
626 * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
627 * pointer to the name of the registry leaf key to be queried, parent key
628 * is enumerated searching in child keys for given leaf key name and its
629 * associated string value. When located, this returns a pointer in *outptr
630 * to a newly allocated memory area holding it as a null-terminated string.
632 * Returns 0 and nullifies *outptr upon inability to return a string value.
634 * Returns 1 and sets *outptr when returning a dynamically allocated string.
636 * Supported on Windows NT 3.5 and newer.
638 static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
641 char enumKeyName[256];
642 DWORD enumKeyNameBuffSize;
643 DWORD enumKeyIdx = 0;
652 enumKeyNameBuffSize = sizeof(enumKeyName);
653 res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName,
654 &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
655 if (res != ERROR_SUCCESS)
657 res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
659 if (res != ERROR_SUCCESS)
661 gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
662 RegCloseKey(hKeyEnum);
674 * get_DNS_Registry_9X()
676 * Functionally identical to get_DNS_Registry()
678 * Implementation supports Windows 95, 98 and ME.
680 static int get_DNS_Registry_9X(char **outptr)
688 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
690 if (res != ERROR_SUCCESS)
693 gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
694 RegCloseKey(hKey_VxD_MStcp);
696 if (!gotString || !*outptr)
703 * get_DNS_Registry_NT()
705 * Functionally identical to get_DNS_Registry()
707 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
709 * Implementation supports Windows NT 3.5 and newer.
711 static int get_DNS_Registry_NT(char **outptr)
713 HKEY hKey_Interfaces = NULL;
714 HKEY hKey_Tcpip_Parameters;
720 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
721 &hKey_Tcpip_Parameters);
722 if (res != ERROR_SUCCESS)
726 ** Global DNS settings override adapter specific parameters when both
727 ** are set. Additionally static DNS settings override DHCP-configured
728 ** parameters when both are set.
731 /* Global DNS static parameters */
732 gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
736 /* Global DNS DHCP-configured parameters */
737 gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
741 /* Try adapter specific parameters */
742 res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0,
743 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
745 if (res != ERROR_SUCCESS)
747 hKey_Interfaces = NULL;
751 /* Adapter specific DNS static parameters */
752 gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
756 /* Adapter specific DNS DHCP-configured parameters */
757 gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
761 RegCloseKey(hKey_Interfaces);
763 RegCloseKey(hKey_Tcpip_Parameters);
765 if (!gotString || !*outptr)
774 * Locates DNS info in the registry. When located, this returns a pointer
775 * in *outptr to a newly allocated memory area holding a null-terminated
776 * string with a space or comma seperated list of DNS IP addresses.
778 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
780 * Returns 1 and sets *outptr when returning a dynamically allocated string.
782 static int get_DNS_Registry(char **outptr)
784 win_platform platform;
789 platform = ares__getplatform();
791 if (platform == WIN_NT)
792 gotString = get_DNS_Registry_NT(outptr);
793 else if (platform == WIN_9X)
794 gotString = get_DNS_Registry_9X(outptr);
807 static void commajoin(char **dst, const char *src)
813 tmp = malloc(strlen(*dst) + strlen(src) + 2);
816 sprintf(tmp, "%s,%s", *dst, src);
822 *dst = malloc(strlen(src) + 1);
830 * get_DNS_NetworkParams()
832 * Locates DNS info using GetNetworkParams() function from the Internet
833 * Protocol Helper (IP Helper) API. When located, this returns a pointer
834 * in *outptr to a newly allocated memory area holding a null-terminated
835 * string with a space or comma seperated list of DNS IP addresses.
837 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
839 * Returns 1 and sets *outptr when returning a dynamically allocated string.
841 * Implementation supports Windows 98 and newer.
843 * Note: Ancient PSDK required in order to build a W98 target.
845 static int get_DNS_NetworkParams(char **outptr)
847 FIXED_INFO *fi, *newfi;
848 struct ares_addr namesrvr;
850 IP_ADDR_STRING *ipAddr;
852 DWORD size = sizeof (*fi);
856 /* Verify run-time availability of GetNetworkParams() */
857 if (ares_fpGetNetworkParams == ZERO_NULL)
864 res = (*ares_fpGetNetworkParams) (fi, &size);
865 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
868 newfi = realloc(fi, size);
873 res = (*ares_fpGetNetworkParams) (fi, &size);
874 if (res != ERROR_SUCCESS)
877 for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
879 txtaddr = &ipAddr->IpAddress.String[0];
881 /* Validate converting textual address to binary format. */
882 if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
884 if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
885 (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
888 else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
890 if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
891 sizeof(namesrvr.addrV6)) == 0)
897 commajoin(outptr, txtaddr);
914 * get_DNS_AdaptersAddresses()
916 * Locates DNS info using GetAdaptersAddresses() function from the Internet
917 * Protocol Helper (IP Helper) API. When located, this returns a pointer
918 * in *outptr to a newly allocated memory area holding a null-terminated
919 * string with a space or comma seperated list of DNS IP addresses.
921 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
923 * Returns 1 and sets *outptr when returning a dynamically allocated string.
925 * Implementation supports Windows XP and newer.
927 #define IPAA_INITIAL_BUF_SZ 15 * 1024
928 #define IPAA_MAX_TRIES 3
929 static int get_DNS_AdaptersAddresses(char **outptr)
931 IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
932 IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
933 ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
934 ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
936 int trying = IPAA_MAX_TRIES;
941 struct sockaddr_in *sa4;
942 struct sockaddr_in6 *sa6;
945 char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
949 /* Verify run-time availability of GetAdaptersAddresses() */
950 if (ares_fpGetAdaptersAddresses == ZERO_NULL)
953 ipaa = malloc(Bufsz);
957 /* Usually this call suceeds with initial buffer size */
958 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
960 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
963 while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
965 if (Bufsz < ReqBufsz)
967 newipaa = realloc(ipaa, ReqBufsz);
973 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
975 if (res == ERROR_SUCCESS)
978 if (res != ERROR_SUCCESS)
981 for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
983 for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
985 ipaDNSAddr = ipaDNSAddr->Next)
987 namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
989 if (namesrvr.sa->sa_family == AF_INET)
991 if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
992 (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
994 if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
995 txtaddr, sizeof(txtaddr)))
998 else if (namesrvr.sa->sa_family == AF_INET6)
1000 if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1001 sizeof(namesrvr.sa6->sin6_addr)) == 0)
1003 if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1004 txtaddr, sizeof(txtaddr)))
1010 commajoin(outptr, txtaddr);
1030 * Locates DNS info from Windows employing most suitable methods available at
1031 * run-time no matter which Windows version it is. When located, this returns
1032 * a pointer in *outptr to a newly allocated memory area holding a string with
1033 * a space or comma seperated list of DNS IP addresses, null-terminated.
1035 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1037 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1039 * Implementation supports Windows 95 and newer.
1041 static int get_DNS_Windows(char **outptr)
1043 /* Try using IP helper API GetAdaptersAddresses() */
1044 if (get_DNS_AdaptersAddresses(outptr))
1047 /* Try using IP helper API GetNetworkParams() */
1048 if (get_DNS_NetworkParams(outptr))
1051 /* Fall-back to registry information */
1052 return get_DNS_Registry(outptr);
1056 static int init_by_resolv_conf(ares_channel channel)
1058 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32)
1061 int status = -1, nservers = 0, nsort = 0;
1062 struct server_state *servers = NULL;
1063 struct apattern *sortlist = NULL;
1067 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1068 return ARES_SUCCESS;
1070 if (get_DNS_Windows(&line))
1072 status = config_nameserver(&servers, &nservers, line);
1076 if (status == ARES_SUCCESS)
1079 /* Catch the case when all the above checks fail (which happens when there
1080 is no network card or the cable is unplugged) */
1081 status = ARES_EFILE;
1083 #elif defined(__riscos__)
1085 /* Under RISC OS, name servers are listed in the
1086 system variable Inet$Resolvers, space separated. */
1088 line = getenv("Inet$Resolvers");
1091 char *resolvers = strdup(line), *pos, *space;
1098 space = strchr(pos, ' ');
1101 status = config_nameserver(&servers, &nservers, pos);
1102 if (status != ARES_SUCCESS)
1107 if (status == ARES_SUCCESS)
1113 #elif defined(WATT32)
1117 for (i = 0; def_nameservers[i]; i++)
1120 return ARES_SUCCESS; /* use localhost DNS server */
1123 servers = calloc(i, sizeof(struct server_state));
1127 for (i = 0; def_nameservers[i]; i++)
1129 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1130 servers[i].addr.family = AF_INET;
1134 #elif defined(ANDROID) || defined(__ANDROID__)
1136 char propname[PROP_NAME_MAX];
1137 char propvalue[PROP_VALUE_MAX]="";
1139 for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1140 snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1141 if (__system_property_get(propname, propvalue) < 1) {
1145 status = config_nameserver(&servers, &nservers, propvalue);
1146 if (status != ARES_SUCCESS)
1157 /* Don't read resolv.conf and friends if we don't have to */
1158 if (ARES_CONFIG_CHECK(channel))
1159 return ARES_SUCCESS;
1161 fp = fopen(PATH_RESOLV_CONF, "r");
1163 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1165 if ((p = try_config(line, "domain", ';')))
1166 status = config_domain(channel, p);
1167 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1168 status = config_lookup(channel, p, "bind", "file");
1169 else if ((p = try_config(line, "search", ';')))
1170 status = set_search(channel, p);
1171 else if ((p = try_config(line, "nameserver", ';')) &&
1172 channel->nservers == -1)
1173 status = config_nameserver(&servers, &nservers, p);
1174 else if ((p = try_config(line, "sortlist", ';')) &&
1175 channel->nsort == -1)
1176 status = config_sortlist(&sortlist, &nsort, p);
1177 else if ((p = try_config(line, "options", ';')))
1178 status = set_options(channel, p);
1180 status = ARES_SUCCESS;
1181 if (status != ARES_SUCCESS)
1194 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1195 error, strerror(error)));
1196 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1197 status = ARES_EFILE;
1201 if ((status == ARES_EOF) && (!channel->lookups)) {
1202 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1203 fp = fopen("/etc/nsswitch.conf", "r");
1205 while ((status = ares__read_line(fp, &line, &linesize)) ==
1208 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1210 (void)config_lookup(channel, p, "dns", "files");
1222 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1223 error, strerror(error)));
1224 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1225 "/etc/nsswitch.conf"));
1226 status = ARES_EFILE;
1231 if ((status == ARES_EOF) && (!channel->lookups)) {
1232 /* Linux / GNU libc 2.x and possibly others have host.conf */
1233 fp = fopen("/etc/host.conf", "r");
1235 while ((status = ares__read_line(fp, &line, &linesize)) ==
1238 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1240 (void)config_lookup(channel, p, "bind", "hosts");
1252 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1253 error, strerror(error)));
1254 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1256 status = ARES_EFILE;
1261 if ((status == ARES_EOF) && (!channel->lookups)) {
1262 /* Tru64 uses /etc/svc.conf */
1263 fp = fopen("/etc/svc.conf", "r");
1265 while ((status = ares__read_line(fp, &line, &linesize)) ==
1268 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1270 (void)config_lookup(channel, p, "bind", "local");
1282 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1283 error, strerror(error)));
1284 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1285 status = ARES_EFILE;
1296 /* Handle errors. */
1297 if (status != ARES_EOF)
1299 if (servers != NULL)
1301 if (sortlist != NULL)
1306 /* If we got any name server entries, fill them in. */
1309 channel->servers = servers;
1310 channel->nservers = nservers;
1313 /* If we got any sortlist entries, fill them in. */
1316 channel->sortlist = sortlist;
1317 channel->nsort = nsort;
1320 return ARES_SUCCESS;
1323 static int init_by_defaults(ares_channel channel)
1325 char *hostname = NULL;
1326 int rc = ARES_SUCCESS;
1327 #ifdef HAVE_GETHOSTNAME
1331 if (channel->flags == -1)
1333 if (channel->timeout == -1)
1334 channel->timeout = DEFAULT_TIMEOUT;
1335 if (channel->tries == -1)
1336 channel->tries = DEFAULT_TRIES;
1337 if (channel->ndots == -1)
1339 if (channel->rotate == -1)
1340 channel->rotate = 0;
1341 if (channel->udp_port == -1)
1342 channel->udp_port = htons(NAMESERVER_PORT);
1343 if (channel->tcp_port == -1)
1344 channel->tcp_port = htons(NAMESERVER_PORT);
1346 if (channel->ednspsz == -1)
1347 channel->ednspsz = EDNSPACKETSZ;
1349 if (channel->nservers == -1) {
1350 /* If nobody specified servers, try a local named. */
1351 channel->servers = malloc(sizeof(struct server_state));
1352 if (!channel->servers) {
1356 channel->servers[0].addr.family = AF_INET;
1357 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1358 channel->nservers = 1;
1361 #if defined(USE_WINSOCK)
1362 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1363 #elif defined(ENAMETOOLONG)
1364 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1365 (SOCKERRNO == EINVAL))
1367 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1370 if (channel->ndomains == -1) {
1371 /* Derive a default domain search list from the kernel hostname,
1372 * or set it to empty if the hostname isn't helpful.
1374 #ifndef HAVE_GETHOSTNAME
1375 channel->ndomains = 0; /* default to none */
1377 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1380 channel->ndomains = 0; /* default to none */
1382 hostname = malloc(len);
1389 res = gethostname(hostname, lenv);
1395 p = realloc(hostname, len);
1410 dot = strchr(hostname, '.');
1412 /* a dot was found */
1413 channel->domains = malloc(sizeof(char *));
1414 if (!channel->domains) {
1418 channel->domains[0] = strdup(dot + 1);
1419 if (!channel->domains[0]) {
1423 channel->ndomains = 1;
1428 if (channel->nsort == -1) {
1429 channel->sortlist = NULL;
1433 if (!channel->lookups) {
1434 channel->lookups = strdup("fb");
1435 if (!channel->lookups)
1441 if(channel->servers) {
1442 free(channel->servers);
1443 channel->servers = NULL;
1446 if(channel->domains && channel->domains[0])
1447 free(channel->domains[0]);
1448 if(channel->domains) {
1449 free(channel->domains);
1450 channel->domains = NULL;
1453 if(channel->lookups) {
1454 free(channel->lookups);
1455 channel->lookups = NULL;
1465 #if !defined(WIN32) && !defined(WATT32) && \
1466 !defined(ANDROID) && !defined(__ANDROID__)
1467 static int config_domain(ares_channel channel, char *str)
1471 /* Set a single search domain. */
1473 while (*q && !ISSPACE(*q))
1476 return set_search(channel, str);
1479 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1480 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1481 /* workaround icc 9.1 optimizer issue */
1482 # define vqualifier volatile
1487 static int config_lookup(ares_channel channel, const char *str,
1488 const char *bindch, const char *filech)
1490 char lookups[3], *l;
1491 const char *vqualifier p;
1493 /* Set the lookup order. Only the first letter of each work
1494 * is relevant, and it has to be "b" for DNS or "f" for the
1495 * host file. Ignore everything else.
1501 if ((*p == *bindch || *p == *filech) && l < lookups + 2) {
1502 if (*p == *bindch) *l++ = 'b';
1505 while (*p && !ISSPACE(*p) && (*p != ','))
1507 while (*p && (ISSPACE(*p) || (*p == ',')))
1511 channel->lookups = strdup(lookups);
1512 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1514 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1517 static int config_nameserver(struct server_state **servers, int *nservers,
1520 struct ares_addr host;
1521 struct server_state *newserv;
1523 /* On Windows, there may be more than one nameserver specified in the same
1524 * registry key, so we parse input as a space or comma seperated list.
1528 /* Skip whitespace and commas. */
1529 while (*p && (ISSPACE(*p) || (*p == ',')))
1532 /* No more input, done. */
1535 /* Pointer to start of IPv4 or IPv6 address part. */
1538 /* Advance past this address. */
1539 while (*p && !ISSPACE(*p) && (*p != ','))
1542 /* Null terminate this address. */
1545 /* Reached end of input, done when this address is processed. */
1548 /* Convert textual address to binary format. */
1549 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1550 host.family = AF_INET;
1551 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1552 host.family = AF_INET6;
1556 /* Resize servers state array. */
1557 newserv = realloc(*servers, (*nservers + 1) *
1558 sizeof(struct server_state));
1562 /* Store address data. */
1563 newserv[*nservers].addr.family = host.family;
1564 if (host.family == AF_INET)
1565 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1566 sizeof(host.addrV4));
1568 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1569 sizeof(host.addrV6));
1571 /* Update arguments. */
1576 return ARES_SUCCESS;
1579 #if !defined(WIN32) && !defined(ANDROID) && !defined(__ANDROID__)
1580 static int config_sortlist(struct apattern **sortlist, int *nsort,
1583 struct apattern pat;
1586 /* Add sortlist entries. */
1587 while (*str && *str != ';')
1590 char ipbuf[16], ipbufpfx[32];
1591 /* Find just the IP */
1593 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1595 memcpy(ipbuf, str, q-str);
1596 ipbuf[q-str] = '\0';
1597 /* Find the prefix */
1600 const char *str2 = q+1;
1601 while (*q && *q != ';' && !ISSPACE(*q))
1603 memcpy(ipbufpfx, str, q-str);
1604 ipbufpfx[q-str] = '\0';
1609 /* Lets see if it is CIDR */
1610 /* First we'll try IPv6 */
1611 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1613 sizeof(pat.addrV6))) > 0)
1615 pat.type = PATTERN_CIDR;
1616 pat.mask.bits = (unsigned short)bits;
1617 pat.family = AF_INET6;
1618 if (!sortlist_alloc(sortlist, nsort, &pat))
1621 else if (ipbufpfx[0] &&
1622 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1623 sizeof(pat.addrV4))) > 0)
1625 pat.type = PATTERN_CIDR;
1626 pat.mask.bits = (unsigned short)bits;
1627 pat.family = AF_INET;
1628 if (!sortlist_alloc(sortlist, nsort, &pat))
1631 /* See if it is just a regular IP */
1632 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1636 memcpy(ipbuf, str, q-str);
1637 ipbuf[q-str] = '\0';
1638 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1643 pat.family = AF_INET;
1644 pat.type = PATTERN_MASK;
1645 if (!sortlist_alloc(sortlist, nsort, &pat))
1650 while (*q && *q != ';' && !ISSPACE(*q))
1654 while (ISSPACE(*str))
1658 return ARES_SUCCESS;
1660 #endif /* !WIN32 & !ANDROID & !__ANDROID__ */
1661 #endif /* !WATT32 */
1663 static int set_search(ares_channel channel, const char *str)
1668 if(channel->ndomains != -1) {
1669 /* if we already have some domains present, free them first */
1670 for(n=0; n < channel->ndomains; n++)
1671 free(channel->domains[n]);
1672 free(channel->domains);
1673 channel->domains = NULL;
1674 channel->ndomains = -1;
1677 /* Count the domains given. */
1682 while (*p && !ISSPACE(*p))
1691 channel->ndomains = 0;
1692 return ARES_SUCCESS;
1695 channel->domains = malloc(n * sizeof(char *));
1696 if (!channel->domains)
1699 /* Now copy the domains. */
1704 channel->ndomains = n;
1706 while (*q && !ISSPACE(*q))
1708 channel->domains[n] = malloc(q - p + 1);
1709 if (!channel->domains[n])
1711 memcpy(channel->domains[n], p, q - p);
1712 channel->domains[n][q - p] = 0;
1718 channel->ndomains = n;
1720 return ARES_SUCCESS;
1723 static int set_options(ares_channel channel, const char *str)
1725 const char *p, *q, *val;
1731 while (*q && !ISSPACE(*q))
1733 val = try_option(p, q, "ndots:");
1734 if (val && channel->ndots == -1)
1735 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1736 val = try_option(p, q, "retrans:");
1737 if (val && channel->timeout == -1)
1738 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1739 val = try_option(p, q, "retry:");
1740 if (val && channel->tries == -1)
1741 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1742 val = try_option(p, q, "rotate");
1743 if (val && channel->rotate == -1)
1744 channel->rotate = 1;
1750 return ARES_SUCCESS;
1753 static const char *try_option(const char *p, const char *q, const char *opt)
1755 size_t len = strlen(opt);
1756 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1759 #if !defined(WIN32) && !defined(WATT32) && \
1760 !defined(ANDROID) && !defined(__ANDROID__)
1761 static char *try_config(char *s, const char *opt, char scc)
1768 /* no line or no option */
1771 /* Hash '#' character is always used as primary comment char, additionally
1772 a not-NUL secondary comment char will be considered when specified. */
1774 /* trim line comment */
1777 while (*p && (*p != '#') && (*p != scc))
1780 while (*p && (*p != '#'))
1784 /* trim trailing whitespace */
1786 while ((q >= s) && ISSPACE(*q))
1790 /* skip leading whitespace */
1792 while (*p && ISSPACE(*p))
1799 if ((len = strlen(opt)) == 0)
1803 if (strncmp(p, opt, len) != 0)
1804 /* line and option do not match */
1807 /* skip over given option name */
1811 /* no option value */
1814 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1815 /* whitespace between option name and value is mandatory
1816 for given option names which do not end with ':' or '=' */
1819 /* skip over whitespace */
1820 while (*p && ISSPACE(*p))
1824 /* no option value */
1827 /* return pointer to option value */
1831 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1832 struct apattern *pat)
1834 struct apattern *newsort;
1835 newsort = realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1838 newsort[*nsort] = *pat;
1839 *sortlist = newsort;
1844 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1847 /* Four octets and three periods yields at most 15 characters. */
1851 addr->s_addr = inet_addr(ipbuf);
1852 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1857 static void natural_mask(struct apattern *pat)
1859 struct in_addr addr;
1861 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1864 addr.s_addr = ntohl(pat->addrV4.s_addr);
1866 /* This is out of date in the CIDR world, but some people might
1869 if (IN_CLASSA(addr.s_addr))
1870 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1871 else if (IN_CLASSB(addr.s_addr))
1872 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1874 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1876 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1878 /* initialize an rc4 key. If possible a cryptographically secure random key
1879 is generated using a suitable function (for example win32's RtlGenRandom as
1881 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
1882 otherwise the code defaults to cross-platform albeit less secure mechanism
1885 static void randomize_key(unsigned char* key,int key_data_len)
1891 if (ares_fpSystemFunction036)
1893 res = (*ares_fpSystemFunction036) (key, key_data_len);
1899 FILE *f = fopen(RANDOM_FILE, "rb");
1901 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
1908 for (;counter<key_data_len;counter++)
1909 key[counter]=(unsigned char)(rand() % 256);
1913 static int init_id_key(rc4_key* key,int key_data_len)
1915 unsigned char index1;
1916 unsigned char index2;
1917 unsigned char* state;
1919 unsigned char *key_data_ptr = 0;
1921 key_data_ptr = calloc(1,key_data_len);
1925 state = &key->state[0];
1926 for(counter = 0; counter < 256; counter++)
1927 /* unnecessary AND but it keeps some compilers happier */
1928 state[counter] = (unsigned char)(counter & 0xff);
1929 randomize_key(key->state,key_data_len);
1934 for(counter = 0; counter < 256; counter++)
1936 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
1938 ARES_SWAP_BYTE(&state[counter], &state[index2]);
1940 index1 = (unsigned char)((index1 + 1) % key_data_len);
1943 return ARES_SUCCESS;
1946 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
1948 channel->local_ip4 = local_ip;
1951 /* local_ip6 should be 16 bytes in length */
1952 void ares_set_local_ip6(ares_channel channel,
1953 const unsigned char* local_ip6)
1955 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
1958 /* local_dev_name should be null terminated. */
1959 void ares_set_local_dev(ares_channel channel,
1960 const char* local_dev_name)
1962 strncpy(channel->local_dev_name, local_dev_name,
1963 sizeof(channel->local_dev_name));
1964 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
1968 void ares_set_socket_callback(ares_channel channel,
1969 ares_sock_create_callback cb,
1972 channel->sock_create_cb = cb;
1973 channel->sock_create_cb_data = data;
1976 void ares__init_servers_state(ares_channel channel)
1978 struct server_state *server;
1981 for (i = 0; i < channel->nservers; i++)
1983 server = &channel->servers[i];
1984 server->udp_socket = ARES_SOCKET_BAD;
1985 server->tcp_socket = ARES_SOCKET_BAD;
1986 server->tcp_connection_generation = ++channel->tcp_connection_generation;
1987 server->tcp_lenbuf_pos = 0;
1988 server->tcp_buffer_pos = 0;
1989 server->tcp_buffer = NULL;
1990 server->tcp_length = 0;
1991 server->qhead = NULL;
1992 server->qtail = NULL;
1993 ares__init_list_head(&server->queries_to_server);
1994 server->channel = channel;
1995 server->is_broken = 0;