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
52 #if defined(CARES_USE_LIBRESOLV)
57 #include "ares_inet_net_pton.h"
58 #include "ares_library_init.h"
59 #include "ares_nowarn.h"
60 #include "ares_platform.h"
61 #include "ares_private.h"
64 #undef WIN32 /* Redefined in MingW/MSVC headers */
67 static int init_by_options(ares_channel channel
,
68 const struct ares_options
*options
,
70 static int init_by_environment(ares_channel channel
);
71 static int init_by_resolv_conf(ares_channel channel
);
72 static int init_by_defaults(ares_channel channel
);
75 static int config_nameserver(struct server_state
**servers
, int *nservers
,
78 static int set_search(ares_channel channel
, const char *str
);
79 static int set_options(ares_channel channel
, const char *str
);
80 static const char *try_option(const char *p
, const char *q
, const char *opt
);
81 static int init_id_key(rc4_key
* key
,int key_data_len
);
83 static int config_sortlist(struct apattern
**sortlist
, int *nsort
,
85 static int sortlist_alloc(struct apattern
**sortlist
, int *nsort
,
86 struct apattern
*pat
);
87 static int ip_addr(const char *s
, ssize_t len
, struct in_addr
*addr
);
88 static void natural_mask(struct apattern
*pat
);
89 #if !defined(WIN32) && !defined(WATT32) && \
90 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
91 static int config_domain(ares_channel channel
, char *str
);
92 static int config_lookup(ares_channel channel
, const char *str
,
93 const char *bindch
, const char *altbindch
,
95 static char *try_config(char *s
, const char *opt
, char scc
);
98 #define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
100 x->ndomains > -1 && \
101 x->ndots > -1 && x->timeout > -1 && \
104 int ares_init(ares_channel
*channelptr
)
106 return ares_init_options(channelptr
, NULL
, 0);
109 int ares_init_options(ares_channel
*channelptr
, struct ares_options
*options
,
112 ares_channel channel
;
114 int status
= ARES_SUCCESS
;
118 const char *env
= getenv("CARES_MEMDEBUG");
122 env
= getenv("CARES_MEMLIMIT");
125 long num
= strtol(env
, &endptr
, 10);
126 if((endptr
!= env
) && (endptr
== env
+ strlen(env
)) && (num
> 0))
131 if (ares_library_initialized() != ARES_SUCCESS
)
132 return ARES_ENOTINITIALIZED
; /* LCOV_EXCL_LINE: n/a on non-WinSock */
134 channel
= ares_malloc(sizeof(struct ares_channeldata
));
142 /* Set everything to distinguished values so we know they haven't
146 channel
->timeout
= -1;
149 channel
->rotate
= -1;
150 channel
->udp_port
= -1;
151 channel
->tcp_port
= -1;
152 channel
->ednspsz
= -1;
153 channel
->socket_send_buffer_size
= -1;
154 channel
->socket_receive_buffer_size
= -1;
155 channel
->nservers
= -1;
156 channel
->ndomains
= -1;
158 channel
->tcp_connection_generation
= 0;
159 channel
->lookups
= NULL
;
160 channel
->domains
= NULL
;
161 channel
->sortlist
= NULL
;
162 channel
->servers
= NULL
;
163 channel
->sock_state_cb
= NULL
;
164 channel
->sock_state_cb_data
= NULL
;
165 channel
->sock_create_cb
= NULL
;
166 channel
->sock_create_cb_data
= NULL
;
167 channel
->sock_config_cb
= NULL
;
168 channel
->sock_config_cb_data
= NULL
;
169 channel
->sock_funcs
= NULL
;
170 channel
->sock_func_cb_data
= NULL
;
172 channel
->last_server
= 0;
173 channel
->last_timeout_processed
= (time_t)now
.tv_sec
;
175 memset(&channel
->local_dev_name
, 0, sizeof(channel
->local_dev_name
));
176 channel
->local_ip4
= 0;
177 memset(&channel
->local_ip6
, 0, sizeof(channel
->local_ip6
));
179 /* Initialize our lists of queries */
180 ares__init_list_head(&(channel
->all_queries
));
181 for (i
= 0; i
< ARES_QID_TABLE_SIZE
; i
++)
183 ares__init_list_head(&(channel
->queries_by_qid
[i
]));
185 for (i
= 0; i
< ARES_TIMEOUT_TABLE_SIZE
; i
++)
187 ares__init_list_head(&(channel
->queries_by_timeout
[i
]));
190 /* Initialize configuration by each of the four sources, from highest
191 * precedence to lowest.
194 status
= init_by_options(channel
, options
, optmask
);
195 if (status
!= ARES_SUCCESS
) {
196 DEBUGF(fprintf(stderr
, "Error: init_by_options failed: %s\n",
197 ares_strerror(status
)));
198 /* If we fail to apply user-specified options, fail the whole init process */
201 status
= init_by_environment(channel
);
202 if (status
!= ARES_SUCCESS
)
203 DEBUGF(fprintf(stderr
, "Error: init_by_environment failed: %s\n",
204 ares_strerror(status
)));
205 if (status
== ARES_SUCCESS
) {
206 status
= init_by_resolv_conf(channel
);
207 if (status
!= ARES_SUCCESS
)
208 DEBUGF(fprintf(stderr
, "Error: init_by_resolv_conf failed: %s\n",
209 ares_strerror(status
)));
213 * No matter what failed or succeeded, seed defaults to provide
214 * useful behavior for things that we missed.
216 status
= init_by_defaults(channel
);
217 if (status
!= ARES_SUCCESS
)
218 DEBUGF(fprintf(stderr
, "Error: init_by_defaults failed: %s\n",
219 ares_strerror(status
)));
221 /* Generate random key */
223 if (status
== ARES_SUCCESS
) {
224 status
= init_id_key(&channel
->id_key
, ARES_ID_KEY_LEN
);
225 if (status
== ARES_SUCCESS
)
226 channel
->next_id
= ares__generate_new_id(&channel
->id_key
);
228 DEBUGF(fprintf(stderr
, "Error: init_id_key failed: %s\n",
229 ares_strerror(status
)));
233 if (status
!= ARES_SUCCESS
)
235 /* Something failed; clean up memory we may have allocated. */
236 if (channel
->servers
)
237 ares_free(channel
->servers
);
238 if (channel
->domains
)
240 for (i
= 0; i
< channel
->ndomains
; i
++)
241 ares_free(channel
->domains
[i
]);
242 ares_free(channel
->domains
);
244 if (channel
->sortlist
)
245 ares_free(channel
->sortlist
);
247 ares_free(channel
->lookups
);
252 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
253 if ((channel
->flags
& ARES_FLAG_PRIMARY
) && channel
->nservers
> 1)
254 channel
->nservers
= 1;
256 ares__init_servers_state(channel
);
258 *channelptr
= channel
;
262 /* ares_dup() duplicates a channel handle with all its options and returns a
263 new channel handle */
264 int ares_dup(ares_channel
*dest
, ares_channel src
)
266 struct ares_options opts
;
267 struct ares_addr_port_node
*servers
;
268 int non_v4_default_port
= 0;
272 *dest
= NULL
; /* in case of failure return NULL explicitly */
274 /* First get the options supported by the old ares_save_options() function,
275 which is most of them */
276 rc
= ares_save_options(src
, &opts
, &optmask
);
279 ares_destroy_options(&opts
);
283 /* Then create the new channel with those options */
284 rc
= ares_init_options(dest
, &opts
, optmask
);
286 /* destroy the options copy to not leak any memory */
287 ares_destroy_options(&opts
);
292 /* Now clone the options that ares_save_options() doesn't support. */
293 (*dest
)->sock_create_cb
= src
->sock_create_cb
;
294 (*dest
)->sock_create_cb_data
= src
->sock_create_cb_data
;
295 (*dest
)->sock_config_cb
= src
->sock_config_cb
;
296 (*dest
)->sock_config_cb_data
= src
->sock_config_cb_data
;
297 (*dest
)->sock_funcs
= src
->sock_funcs
;
298 (*dest
)->sock_func_cb_data
= src
->sock_func_cb_data
;
300 strncpy((*dest
)->local_dev_name
, src
->local_dev_name
,
301 sizeof(src
->local_dev_name
));
302 (*dest
)->local_ip4
= src
->local_ip4
;
303 memcpy((*dest
)->local_ip6
, src
->local_ip6
, sizeof(src
->local_ip6
));
305 /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
306 for (i
= 0; i
< src
->nservers
; i
++)
308 if ((src
->servers
[i
].addr
.family
!= AF_INET
) ||
309 (src
->servers
[i
].addr
.udp_port
!= 0) ||
310 (src
->servers
[i
].addr
.tcp_port
!= 0)) {
311 non_v4_default_port
++;
315 if (non_v4_default_port
) {
316 rc
= ares_get_servers_ports(src
, &servers
);
317 if (rc
!= ARES_SUCCESS
) {
322 rc
= ares_set_servers_ports(*dest
, servers
);
323 ares_free_data(servers
);
324 if (rc
!= ARES_SUCCESS
) {
331 return ARES_SUCCESS
; /* everything went fine */
334 /* Save options from initialized channel */
335 int ares_save_options(ares_channel channel
, struct ares_options
*options
,
339 int ipv4_nservers
= 0;
341 /* Zero everything out */
342 memset(options
, 0, sizeof(struct ares_options
));
344 if (!ARES_CONFIG_CHECK(channel
))
347 /* Traditionally the optmask wasn't saved in the channel struct so it was
348 recreated here. ROTATE is the first option that has no struct field of
349 its own in the public config struct */
350 (*optmask
) = (ARES_OPT_FLAGS
|ARES_OPT_TRIES
|ARES_OPT_NDOTS
|
351 ARES_OPT_UDP_PORT
|ARES_OPT_TCP_PORT
|ARES_OPT_SOCK_STATE_CB
|
352 ARES_OPT_SERVERS
|ARES_OPT_DOMAINS
|ARES_OPT_LOOKUPS
|
353 ARES_OPT_SORTLIST
|ARES_OPT_TIMEOUTMS
);
354 (*optmask
) |= (channel
->rotate
? ARES_OPT_ROTATE
: ARES_OPT_NOROTATE
);
356 /* Copy easy stuff */
357 options
->flags
= channel
->flags
;
359 /* We return full millisecond resolution but that's only because we don't
360 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
361 options
->timeout
= channel
->timeout
;
362 options
->tries
= channel
->tries
;
363 options
->ndots
= channel
->ndots
;
364 options
->udp_port
= ntohs(aresx_sitous(channel
->udp_port
));
365 options
->tcp_port
= ntohs(aresx_sitous(channel
->tcp_port
));
366 options
->sock_state_cb
= channel
->sock_state_cb
;
367 options
->sock_state_cb_data
= channel
->sock_state_cb_data
;
369 /* Copy IPv4 servers that use the default port */
370 if (channel
->nservers
) {
371 for (i
= 0; i
< channel
->nservers
; i
++)
373 if ((channel
->servers
[i
].addr
.family
== AF_INET
) &&
374 (channel
->servers
[i
].addr
.udp_port
== 0) &&
375 (channel
->servers
[i
].addr
.tcp_port
== 0))
379 options
->servers
= ares_malloc(ipv4_nservers
* sizeof(struct in_addr
));
380 if (!options
->servers
)
382 for (i
= j
= 0; i
< channel
->nservers
; i
++)
384 if ((channel
->servers
[i
].addr
.family
== AF_INET
) &&
385 (channel
->servers
[i
].addr
.udp_port
== 0) &&
386 (channel
->servers
[i
].addr
.tcp_port
== 0))
387 memcpy(&options
->servers
[j
++],
388 &channel
->servers
[i
].addr
.addrV4
,
389 sizeof(channel
->servers
[i
].addr
.addrV4
));
393 options
->nservers
= ipv4_nservers
;
396 if (channel
->ndomains
) {
397 options
->domains
= ares_malloc(channel
->ndomains
* sizeof(char *));
398 if (!options
->domains
)
401 for (i
= 0; i
< channel
->ndomains
; i
++)
403 options
->ndomains
= i
;
404 options
->domains
[i
] = ares_strdup(channel
->domains
[i
]);
405 if (!options
->domains
[i
])
409 options
->ndomains
= channel
->ndomains
;
412 if (channel
->lookups
) {
413 options
->lookups
= ares_strdup(channel
->lookups
);
414 if (!options
->lookups
&& channel
->lookups
)
419 if (channel
->nsort
) {
420 options
->sortlist
= ares_malloc(channel
->nsort
* sizeof(struct apattern
));
421 if (!options
->sortlist
)
423 for (i
= 0; i
< channel
->nsort
; i
++)
424 options
->sortlist
[i
] = channel
->sortlist
[i
];
426 options
->nsort
= channel
->nsort
;
431 static int init_by_options(ares_channel channel
,
432 const struct ares_options
*options
,
438 if ((optmask
& ARES_OPT_FLAGS
) && channel
->flags
== -1)
439 channel
->flags
= options
->flags
;
440 if ((optmask
& ARES_OPT_TIMEOUTMS
) && channel
->timeout
== -1)
441 channel
->timeout
= options
->timeout
;
442 else if ((optmask
& ARES_OPT_TIMEOUT
) && channel
->timeout
== -1)
443 channel
->timeout
= options
->timeout
* 1000;
444 if ((optmask
& ARES_OPT_TRIES
) && channel
->tries
== -1)
445 channel
->tries
= options
->tries
;
446 if ((optmask
& ARES_OPT_NDOTS
) && channel
->ndots
== -1)
447 channel
->ndots
= options
->ndots
;
448 if ((optmask
& ARES_OPT_ROTATE
) && channel
->rotate
== -1)
450 if ((optmask
& ARES_OPT_NOROTATE
) && channel
->rotate
== -1)
452 if ((optmask
& ARES_OPT_UDP_PORT
) && channel
->udp_port
== -1)
453 channel
->udp_port
= htons(options
->udp_port
);
454 if ((optmask
& ARES_OPT_TCP_PORT
) && channel
->tcp_port
== -1)
455 channel
->tcp_port
= htons(options
->tcp_port
);
456 if ((optmask
& ARES_OPT_SOCK_STATE_CB
) && channel
->sock_state_cb
== NULL
)
458 channel
->sock_state_cb
= options
->sock_state_cb
;
459 channel
->sock_state_cb_data
= options
->sock_state_cb_data
;
461 if ((optmask
& ARES_OPT_SOCK_SNDBUF
)
462 && channel
->socket_send_buffer_size
== -1)
463 channel
->socket_send_buffer_size
= options
->socket_send_buffer_size
;
464 if ((optmask
& ARES_OPT_SOCK_RCVBUF
)
465 && channel
->socket_receive_buffer_size
== -1)
466 channel
->socket_receive_buffer_size
= options
->socket_receive_buffer_size
;
468 if ((optmask
& ARES_OPT_EDNSPSZ
) && channel
->ednspsz
== -1)
469 channel
->ednspsz
= options
->ednspsz
;
471 /* Copy the IPv4 servers, if given. */
472 if ((optmask
& ARES_OPT_SERVERS
) && channel
->nservers
== -1)
474 /* Avoid zero size allocations at any cost */
475 if (options
->nservers
> 0)
478 ares_malloc(options
->nservers
* sizeof(struct server_state
));
479 if (!channel
->servers
)
481 for (i
= 0; i
< options
->nservers
; i
++)
483 channel
->servers
[i
].addr
.family
= AF_INET
;
484 channel
->servers
[i
].addr
.udp_port
= 0;
485 channel
->servers
[i
].addr
.tcp_port
= 0;
486 memcpy(&channel
->servers
[i
].addr
.addrV4
,
487 &options
->servers
[i
],
488 sizeof(channel
->servers
[i
].addr
.addrV4
));
491 channel
->nservers
= options
->nservers
;
494 /* Copy the domains, if given. Keep channel->ndomains consistent so
495 * we can clean up in case of error.
497 if ((optmask
& ARES_OPT_DOMAINS
) && channel
->ndomains
== -1)
499 /* Avoid zero size allocations at any cost */
500 if (options
->ndomains
> 0)
502 channel
->domains
= ares_malloc(options
->ndomains
* sizeof(char *));
503 if (!channel
->domains
)
505 for (i
= 0; i
< options
->ndomains
; i
++)
507 channel
->ndomains
= i
;
508 channel
->domains
[i
] = ares_strdup(options
->domains
[i
]);
509 if (!channel
->domains
[i
])
513 channel
->ndomains
= options
->ndomains
;
516 /* Set lookups, if given. */
517 if ((optmask
& ARES_OPT_LOOKUPS
) && !channel
->lookups
)
519 channel
->lookups
= ares_strdup(options
->lookups
);
520 if (!channel
->lookups
)
525 if ((optmask
& ARES_OPT_SORTLIST
) && (channel
->nsort
== -1)) {
526 if (options
->nsort
> 0) {
527 channel
->sortlist
= ares_malloc(options
->nsort
* sizeof(struct apattern
));
528 if (!channel
->sortlist
)
530 for (i
= 0; i
< options
->nsort
; i
++)
531 channel
->sortlist
[i
] = options
->sortlist
[i
];
533 channel
->nsort
= options
->nsort
;
536 channel
->optmask
= optmask
;
541 static int init_by_environment(ares_channel channel
)
543 const char *localdomain
, *res_options
;
546 localdomain
= getenv("LOCALDOMAIN");
547 if (localdomain
&& channel
->ndomains
== -1)
549 status
= set_search(channel
, localdomain
);
550 if (status
!= ARES_SUCCESS
)
554 res_options
= getenv("RES_OPTIONS");
557 status
= set_options(channel
, res_options
);
558 if (status
!= ARES_SUCCESS
)
559 return status
; /* LCOV_EXCL_LINE: set_options() never fails */
569 * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
570 * to the name of the registry leaf key to be queried, fetch it's string
571 * value and return a pointer in *outptr to a newly allocated memory area
572 * holding it as a null-terminated string.
574 * Returns 0 and nullifies *outptr upon inability to return a string value.
576 * Returns 1 and sets *outptr when returning a dynamically allocated string.
578 * Supported on Windows NT 3.5 and newer.
580 static int get_REG_SZ(HKEY hKey
, const char *leafKeyName
, char **outptr
)
587 /* Find out size of string stored in registry */
588 res
= RegQueryValueEx(hKey
, leafKeyName
, 0, NULL
, NULL
, &size
);
589 if ((res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) || !size
)
592 /* Allocate buffer of indicated size plus one given that string
593 might have been stored without null termination */
594 *outptr
= ares_malloc(size
+1);
598 /* Get the value for real */
599 res
= RegQueryValueEx(hKey
, leafKeyName
, 0, NULL
,
600 (unsigned char *)*outptr
, &size
);
601 if ((res
!= ERROR_SUCCESS
) || (size
== 1))
608 /* Null terminate buffer allways */
609 *(*outptr
+ size
) = '\0';
617 * Functionally identical to get_REG_SZ()
619 * Supported on Windows 95, 98 and ME.
621 static int get_REG_SZ_9X(HKEY hKey
, const char *leafKeyName
, char **outptr
)
629 /* Find out size of string stored in registry */
630 res
= RegQueryValueEx(hKey
, leafKeyName
, 0, &dataType
, NULL
, &size
);
631 if ((res
!= ERROR_SUCCESS
&& res
!= ERROR_MORE_DATA
) || !size
)
634 /* Allocate buffer of indicated size plus one given that string
635 might have been stored without null termination */
636 *outptr
= ares_malloc(size
+1);
640 /* Get the value for real */
641 res
= RegQueryValueEx(hKey
, leafKeyName
, 0, &dataType
,
642 (unsigned char *)*outptr
, &size
);
643 if ((res
!= ERROR_SUCCESS
) || (size
== 1))
650 /* Null terminate buffer allways */
651 *(*outptr
+ size
) = '\0';
659 * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
660 * pointer to the name of the registry leaf key to be queried, parent key
661 * is enumerated searching in child keys for given leaf key name and its
662 * associated string value. When located, this returns a pointer in *outptr
663 * to a newly allocated memory area holding it as a null-terminated string.
665 * Returns 0 and nullifies *outptr upon inability to return a string value.
667 * Returns 1 and sets *outptr when returning a dynamically allocated string.
669 * Supported on Windows NT 3.5 and newer.
671 static int get_enum_REG_SZ(HKEY hKeyParent
, const char *leafKeyName
,
674 char enumKeyName
[256];
675 DWORD enumKeyNameBuffSize
;
676 DWORD enumKeyIdx
= 0;
685 enumKeyNameBuffSize
= sizeof(enumKeyName
);
686 res
= RegEnumKeyEx(hKeyParent
, enumKeyIdx
++, enumKeyName
,
687 &enumKeyNameBuffSize
, 0, NULL
, NULL
, NULL
);
688 if (res
!= ERROR_SUCCESS
)
690 res
= RegOpenKeyEx(hKeyParent
, enumKeyName
, 0, KEY_QUERY_VALUE
,
692 if (res
!= ERROR_SUCCESS
)
694 gotString
= get_REG_SZ(hKeyEnum
, leafKeyName
, outptr
);
695 RegCloseKey(hKeyEnum
);
707 * get_DNS_Registry_9X()
709 * Functionally identical to get_DNS_Registry()
711 * Implementation supports Windows 95, 98 and ME.
713 static int get_DNS_Registry_9X(char **outptr
)
721 res
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, WIN_NS_9X
, 0, KEY_READ
,
723 if (res
!= ERROR_SUCCESS
)
726 gotString
= get_REG_SZ_9X(hKey_VxD_MStcp
, NAMESERVER
, outptr
);
727 RegCloseKey(hKey_VxD_MStcp
);
729 if (!gotString
|| !*outptr
)
736 * get_DNS_Registry_NT()
738 * Functionally identical to get_DNS_Registry()
740 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
742 * Implementation supports Windows NT 3.5 and newer.
744 static int get_DNS_Registry_NT(char **outptr
)
746 HKEY hKey_Interfaces
= NULL
;
747 HKEY hKey_Tcpip_Parameters
;
753 res
= RegOpenKeyEx(HKEY_LOCAL_MACHINE
, WIN_NS_NT_KEY
, 0, KEY_READ
,
754 &hKey_Tcpip_Parameters
);
755 if (res
!= ERROR_SUCCESS
)
759 ** Global DNS settings override adapter specific parameters when both
760 ** are set. Additionally static DNS settings override DHCP-configured
761 ** parameters when both are set.
764 /* Global DNS static parameters */
765 gotString
= get_REG_SZ(hKey_Tcpip_Parameters
, NAMESERVER
, outptr
);
769 /* Global DNS DHCP-configured parameters */
770 gotString
= get_REG_SZ(hKey_Tcpip_Parameters
, DHCPNAMESERVER
, outptr
);
774 /* Try adapter specific parameters */
775 res
= RegOpenKeyEx(hKey_Tcpip_Parameters
, "Interfaces", 0,
776 KEY_QUERY_VALUE
| KEY_ENUMERATE_SUB_KEYS
,
778 if (res
!= ERROR_SUCCESS
)
780 hKey_Interfaces
= NULL
;
784 /* Adapter specific DNS static parameters */
785 gotString
= get_enum_REG_SZ(hKey_Interfaces
, NAMESERVER
, outptr
);
789 /* Adapter specific DNS DHCP-configured parameters */
790 gotString
= get_enum_REG_SZ(hKey_Interfaces
, DHCPNAMESERVER
, outptr
);
794 RegCloseKey(hKey_Interfaces
);
796 RegCloseKey(hKey_Tcpip_Parameters
);
798 if (!gotString
|| !*outptr
)
807 * Locates DNS info in the registry. When located, this returns a pointer
808 * in *outptr to a newly allocated memory area holding a null-terminated
809 * string with a space or comma seperated list of DNS IP addresses.
811 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
813 * Returns 1 and sets *outptr when returning a dynamically allocated string.
815 static int get_DNS_Registry(char **outptr
)
817 win_platform platform
;
822 platform
= ares__getplatform();
824 if (platform
== WIN_NT
)
825 gotString
= get_DNS_Registry_NT(outptr
);
826 else if (platform
== WIN_9X
)
827 gotString
= get_DNS_Registry_9X(outptr
);
840 static void commajoin(char **dst
, const char *src
)
846 tmp
= ares_malloc(strlen(*dst
) + strlen(src
) + 2);
849 sprintf(tmp
, "%s,%s", *dst
, src
);
855 *dst
= ares_malloc(strlen(src
) + 1);
863 * get_DNS_NetworkParams()
865 * Locates DNS info using GetNetworkParams() function from the Internet
866 * Protocol Helper (IP Helper) API. When located, this returns a pointer
867 * in *outptr to a newly allocated memory area holding a null-terminated
868 * string with a space or comma seperated list of DNS IP addresses.
870 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
872 * Returns 1 and sets *outptr when returning a dynamically allocated string.
874 * Implementation supports Windows 98 and newer.
876 * Note: Ancient PSDK required in order to build a W98 target.
878 static int get_DNS_NetworkParams(char **outptr
)
880 FIXED_INFO
*fi
, *newfi
;
881 struct ares_addr namesrvr
;
883 IP_ADDR_STRING
*ipAddr
;
885 DWORD size
= sizeof (*fi
);
889 /* Verify run-time availability of GetNetworkParams() */
890 if (ares_fpGetNetworkParams
== ZERO_NULL
)
893 fi
= ares_malloc(size
);
897 res
= (*ares_fpGetNetworkParams
) (fi
, &size
);
898 if ((res
!= ERROR_BUFFER_OVERFLOW
) && (res
!= ERROR_SUCCESS
))
901 newfi
= ares_realloc(fi
, size
);
906 res
= (*ares_fpGetNetworkParams
) (fi
, &size
);
907 if (res
!= ERROR_SUCCESS
)
910 for (ipAddr
= &fi
->DnsServerList
; ipAddr
; ipAddr
= ipAddr
->Next
)
912 txtaddr
= &ipAddr
->IpAddress
.String
[0];
914 /* Validate converting textual address to binary format. */
915 if (ares_inet_pton(AF_INET
, txtaddr
, &namesrvr
.addrV4
) == 1)
917 if ((namesrvr
.addrV4
.S_un
.S_addr
== INADDR_ANY
) ||
918 (namesrvr
.addrV4
.S_un
.S_addr
== INADDR_NONE
))
921 else if (ares_inet_pton(AF_INET6
, txtaddr
, &namesrvr
.addrV6
) == 1)
923 if (memcmp(&namesrvr
.addrV6
, &ares_in6addr_any
,
924 sizeof(namesrvr
.addrV6
)) == 0)
930 commajoin(outptr
, txtaddr
);
947 * get_DNS_AdaptersAddresses()
949 * Locates DNS info using GetAdaptersAddresses() function from the Internet
950 * Protocol Helper (IP Helper) API. When located, this returns a pointer
951 * in *outptr to a newly allocated memory area holding a null-terminated
952 * string with a space or comma seperated list of DNS IP addresses.
954 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
956 * Returns 1 and sets *outptr when returning a dynamically allocated string.
958 * Implementation supports Windows XP and newer.
960 #define IPAA_INITIAL_BUF_SZ 15 * 1024
961 #define IPAA_MAX_TRIES 3
962 static int get_DNS_AdaptersAddresses(char **outptr
)
964 IP_ADAPTER_DNS_SERVER_ADDRESS
*ipaDNSAddr
;
965 IP_ADAPTER_ADDRESSES
*ipaa
, *newipaa
, *ipaaEntry
;
966 ULONG ReqBufsz
= IPAA_INITIAL_BUF_SZ
;
967 ULONG Bufsz
= IPAA_INITIAL_BUF_SZ
;
969 int trying
= IPAA_MAX_TRIES
;
974 struct sockaddr_in
*sa4
;
975 struct sockaddr_in6
*sa6
;
978 char txtaddr
[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
982 /* Verify run-time availability of GetAdaptersAddresses() */
983 if (ares_fpGetAdaptersAddresses
== ZERO_NULL
)
986 ipaa
= ares_malloc(Bufsz
);
990 /* Usually this call suceeds with initial buffer size */
991 res
= (*ares_fpGetAdaptersAddresses
) (AF_UNSPEC
, AddrFlags
, NULL
,
993 if ((res
!= ERROR_BUFFER_OVERFLOW
) && (res
!= ERROR_SUCCESS
))
996 while ((res
== ERROR_BUFFER_OVERFLOW
) && (--trying
))
998 if (Bufsz
< ReqBufsz
)
1000 newipaa
= ares_realloc(ipaa
, ReqBufsz
);
1006 res
= (*ares_fpGetAdaptersAddresses
) (AF_UNSPEC
, AddrFlags
, NULL
,
1008 if (res
== ERROR_SUCCESS
)
1011 if (res
!= ERROR_SUCCESS
)
1014 for (ipaaEntry
= ipaa
; ipaaEntry
; ipaaEntry
= ipaaEntry
->Next
)
1016 if(ipaaEntry
->OperStatus
!= IfOperStatusUp
)
1019 for (ipaDNSAddr
= ipaaEntry
->FirstDnsServerAddress
;
1021 ipaDNSAddr
= ipaDNSAddr
->Next
)
1023 namesrvr
.sa
= ipaDNSAddr
->Address
.lpSockaddr
;
1025 if (namesrvr
.sa
->sa_family
== AF_INET
)
1027 if ((namesrvr
.sa4
->sin_addr
.S_un
.S_addr
== INADDR_ANY
) ||
1028 (namesrvr
.sa4
->sin_addr
.S_un
.S_addr
== INADDR_NONE
))
1030 if (! ares_inet_ntop(AF_INET
, &namesrvr
.sa4
->sin_addr
,
1031 txtaddr
, sizeof(txtaddr
)))
1034 else if (namesrvr
.sa
->sa_family
== AF_INET6
)
1036 if (memcmp(&namesrvr
.sa6
->sin6_addr
, &ares_in6addr_any
,
1037 sizeof(namesrvr
.sa6
->sin6_addr
)) == 0)
1039 if (! ares_inet_ntop(AF_INET6
, &namesrvr
.sa6
->sin6_addr
,
1040 txtaddr
, sizeof(txtaddr
)))
1046 commajoin(outptr
, txtaddr
);
1066 * Locates DNS info from Windows employing most suitable methods available at
1067 * run-time no matter which Windows version it is. When located, this returns
1068 * a pointer in *outptr to a newly allocated memory area holding a string with
1069 * a space or comma seperated list of DNS IP addresses, null-terminated.
1071 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1073 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1075 * Implementation supports Windows 95 and newer.
1077 static int get_DNS_Windows(char **outptr
)
1080 Use GetNetworkParams First in case of
1081 multiple adapter is enabled on this machine.
1082 GetAdaptersAddresses will retrive dummy dns servers.
1083 That will slowing DNS lookup.
1085 /* Try using IP helper API GetNetworkParams() */
1086 if (get_DNS_NetworkParams(outptr
))
1089 /* Try using IP helper API GetAdaptersAddresses() */
1090 if (get_DNS_AdaptersAddresses(outptr
))
1093 /* Fall-back to registry information */
1094 return get_DNS_Registry(outptr
);
1098 static int init_by_resolv_conf(ares_channel channel
)
1100 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1101 !defined(CARES_USE_LIBRESOLV)
1104 int status
= -1, nservers
= 0, nsort
= 0;
1105 struct server_state
*servers
= NULL
;
1106 struct apattern
*sortlist
= NULL
;
1110 if (channel
->nservers
> -1) /* don't override ARES_OPT_SERVER */
1111 return ARES_SUCCESS
;
1113 if (get_DNS_Windows(&line
))
1115 status
= config_nameserver(&servers
, &nservers
, line
);
1119 if (status
== ARES_SUCCESS
)
1122 /* Catch the case when all the above checks fail (which happens when there
1123 is no network card or the cable is unplugged) */
1124 status
= ARES_EFILE
;
1126 #elif defined(__riscos__)
1128 /* Under RISC OS, name servers are listed in the
1129 system variable Inet$Resolvers, space separated. */
1131 line
= getenv("Inet$Resolvers");
1134 char *resolvers
= ares_strdup(line
), *pos
, *space
;
1141 space
= strchr(pos
, ' ');
1144 status
= config_nameserver(&servers
, &nservers
, pos
);
1145 if (status
!= ARES_SUCCESS
)
1150 if (status
== ARES_SUCCESS
)
1153 ares_free(resolvers
);
1156 #elif defined(WATT32)
1160 for (i
= 0; def_nameservers
[i
]; i
++)
1163 return ARES_SUCCESS
; /* use localhost DNS server */
1166 servers
= ares_malloc(sizeof(struct server_state
));
1169 memset(servers
, 0, sizeof(struct server_state
));
1171 for (i
= 0; def_nameservers
[i
]; i
++)
1173 servers
[i
].addr
.addrV4
.s_addr
= htonl(def_nameservers
[i
]);
1174 servers
[i
].addr
.family
= AF_INET
;
1175 servers
[i
].addr
.udp_port
= 0;
1176 servers
[i
].addr
.tcp_port
= 0;
1180 #elif defined(ANDROID) || defined(__ANDROID__)
1182 char propname
[PROP_NAME_MAX
];
1183 char propvalue
[PROP_VALUE_MAX
]="";
1185 for (i
= 1; i
<= MAX_DNS_PROPERTIES
; i
++) {
1186 snprintf(propname
, sizeof(propname
), "%s%u", DNS_PROP_NAME_PREFIX
, i
);
1187 if (__system_property_get(propname
, propvalue
) < 1) {
1191 status
= config_nameserver(&servers
, &nservers
, propvalue
);
1192 if (status
!= ARES_SUCCESS
)
1196 #elif defined(CARES_USE_LIBRESOLV)
1197 struct __res_state res
;
1198 memset(&res
, 0, sizeof(res
));
1199 int result
= res_ninit(&res
);
1200 if (result
== 0 && (res
.options
& RES_INIT
)) {
1203 if (channel
->nservers
== -1) {
1204 union res_sockaddr_union addr
[MAXNS
];
1205 int nscount
= res_getservers(&res
, addr
, MAXNS
);
1206 for (int i
= 0; i
< nscount
; ++i
) {
1207 char str
[INET6_ADDRSTRLEN
];
1209 sa_family_t family
= addr
[i
].sin
.sin_family
;
1210 if (family
== AF_INET
) {
1211 ares_inet_ntop(family
, &addr
[i
].sin
.sin_addr
, str
, sizeof(str
));
1212 } else if (family
== AF_INET6
) {
1213 ares_inet_ntop(family
, &addr
[i
].sin6
.sin6_addr
, str
, sizeof(str
));
1218 config_status
= config_nameserver(&servers
, &nservers
, str
);
1219 if (config_status
!= ARES_SUCCESS
) {
1220 status
= config_status
;
1225 if (channel
->ndomains
== -1) {
1227 while ((entries
< MAXDNSRCH
) && res
.dnsrch
[entries
])
1230 channel
->domains
= ares_malloc(entries
* sizeof(char *));
1231 if (!channel
->domains
) {
1232 status
= ARES_ENOMEM
;
1234 channel
->ndomains
= entries
;
1235 for (int i
= 0; i
< channel
->ndomains
; ++i
) {
1236 channel
->domains
[i
] = ares_strdup(res
.dnsrch
[i
]);
1237 if (!channel
->domains
[i
])
1238 status
= ARES_ENOMEM
;
1242 if (channel
->ndots
== -1)
1243 channel
->ndots
= res
.ndots
;
1244 if (channel
->tries
== -1)
1245 channel
->tries
= res
.retry
;
1246 if (channel
->rotate
== -1)
1247 channel
->rotate
= res
.options
& RES_ROTATE
;
1248 if (channel
->timeout
== -1)
1249 channel
->timeout
= res
.retrans
* 1000;
1261 /* Don't read resolv.conf and friends if we don't have to */
1262 if (ARES_CONFIG_CHECK(channel
))
1263 return ARES_SUCCESS
;
1265 /* Only update search domains if they're not already specified */
1266 update_domains
= (channel
->ndomains
== -1);
1268 fp
= fopen(PATH_RESOLV_CONF
, "r");
1270 while ((status
= ares__read_line(fp
, &line
, &linesize
)) == ARES_SUCCESS
)
1272 if ((p
= try_config(line
, "domain", ';')) && update_domains
)
1273 status
= config_domain(channel
, p
);
1274 else if ((p
= try_config(line
, "lookup", ';')) && !channel
->lookups
)
1275 status
= config_lookup(channel
, p
, "bind", NULL
, "file");
1276 else if ((p
= try_config(line
, "search", ';')) && update_domains
)
1277 status
= set_search(channel
, p
);
1278 else if ((p
= try_config(line
, "nameserver", ';')) &&
1279 channel
->nservers
== -1)
1280 status
= config_nameserver(&servers
, &nservers
, p
);
1281 else if ((p
= try_config(line
, "sortlist", ';')) &&
1282 channel
->nsort
== -1)
1283 status
= config_sortlist(&sortlist
, &nsort
, p
);
1284 else if ((p
= try_config(line
, "options", ';')))
1285 status
= set_options(channel
, p
);
1287 status
= ARES_SUCCESS
;
1288 if (status
!= ARES_SUCCESS
)
1301 DEBUGF(fprintf(stderr
, "fopen() failed with error: %d %s\n",
1302 error
, strerror(error
)));
1303 DEBUGF(fprintf(stderr
, "Error opening file: %s\n", PATH_RESOLV_CONF
));
1304 status
= ARES_EFILE
;
1308 if ((status
== ARES_EOF
) && (!channel
->lookups
)) {
1309 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1310 fp
= fopen("/etc/nsswitch.conf", "r");
1312 while ((status
= ares__read_line(fp
, &line
, &linesize
)) ==
1315 if ((p
= try_config(line
, "hosts:", '\0')) && !channel
->lookups
)
1316 (void)config_lookup(channel
, p
, "dns", "resolve", "files");
1327 DEBUGF(fprintf(stderr
, "fopen() failed with error: %d %s\n",
1328 error
, strerror(error
)));
1329 DEBUGF(fprintf(stderr
, "Error opening file: %s\n",
1330 "/etc/nsswitch.conf"));
1333 /* ignore error, maybe we will get luck in next if clause */
1338 if ((status
== ARES_EOF
) && (!channel
->lookups
)) {
1339 /* Linux / GNU libc 2.x and possibly others have host.conf */
1340 fp
= fopen("/etc/host.conf", "r");
1342 while ((status
= ares__read_line(fp
, &line
, &linesize
)) ==
1345 if ((p
= try_config(line
, "order", '\0')) && !channel
->lookups
)
1347 (void)config_lookup(channel
, p
, "bind", NULL
, "hosts");
1358 DEBUGF(fprintf(stderr
, "fopen() failed with error: %d %s\n",
1359 error
, strerror(error
)));
1360 DEBUGF(fprintf(stderr
, "Error opening file: %s\n",
1364 /* ignore error, maybe we will get luck in next if clause */
1369 if ((status
== ARES_EOF
) && (!channel
->lookups
)) {
1370 /* Tru64 uses /etc/svc.conf */
1371 fp
= fopen("/etc/svc.conf", "r");
1373 while ((status
= ares__read_line(fp
, &line
, &linesize
)) ==
1376 if ((p
= try_config(line
, "hosts=", '\0')) && !channel
->lookups
)
1378 (void)config_lookup(channel
, p
, "bind", NULL
, "local");
1389 DEBUGF(fprintf(stderr
, "fopen() failed with error: %d %s\n",
1390 error
, strerror(error
)));
1391 DEBUGF(fprintf(stderr
, "Error opening file: %s\n", "/etc/svc.conf"));
1394 /* ignore error, default value will be chosen for `channel->lookups` */
1405 /* Handle errors. */
1406 if (status
!= ARES_EOF
)
1408 if (servers
!= NULL
)
1410 if (sortlist
!= NULL
)
1411 ares_free(sortlist
);
1415 /* If we got any name server entries, fill them in. */
1418 channel
->servers
= servers
;
1419 channel
->nservers
= nservers
;
1422 /* If we got any sortlist entries, fill them in. */
1425 channel
->sortlist
= sortlist
;
1426 channel
->nsort
= nsort
;
1429 return ARES_SUCCESS
;
1432 static int init_by_defaults(ares_channel channel
)
1434 char *hostname
= NULL
;
1435 int rc
= ARES_SUCCESS
;
1436 #ifdef HAVE_GETHOSTNAME
1440 if (channel
->flags
== -1)
1442 if (channel
->timeout
== -1)
1443 channel
->timeout
= DEFAULT_TIMEOUT
;
1444 if (channel
->tries
== -1)
1445 channel
->tries
= DEFAULT_TRIES
;
1446 if (channel
->ndots
== -1)
1448 if (channel
->rotate
== -1)
1449 channel
->rotate
= 0;
1450 if (channel
->udp_port
== -1)
1451 channel
->udp_port
= htons(NAMESERVER_PORT
);
1452 if (channel
->tcp_port
== -1)
1453 channel
->tcp_port
= htons(NAMESERVER_PORT
);
1455 if (channel
->ednspsz
== -1)
1456 channel
->ednspsz
= EDNSPACKETSZ
;
1458 if (channel
->nservers
== -1) {
1459 /* If nobody specified servers, try a local named. */
1460 channel
->servers
= ares_malloc(sizeof(struct server_state
));
1461 if (!channel
->servers
) {
1465 channel
->servers
[0].addr
.family
= AF_INET
;
1466 channel
->servers
[0].addr
.addrV4
.s_addr
= htonl(INADDR_LOOPBACK
);
1467 channel
->servers
[0].addr
.udp_port
= 0;
1468 channel
->servers
[0].addr
.tcp_port
= 0;
1469 channel
->nservers
= 1;
1472 #if defined(USE_WINSOCK)
1473 #define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1474 #elif defined(ENAMETOOLONG)
1475 #define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1476 (SOCKERRNO == EINVAL))
1478 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1481 if (channel
->ndomains
== -1) {
1482 /* Derive a default domain search list from the kernel hostname,
1483 * or set it to empty if the hostname isn't helpful.
1485 #ifndef HAVE_GETHOSTNAME
1486 channel
->ndomains
= 0; /* default to none */
1488 GETHOSTNAME_TYPE_ARG2 lenv
= 64;
1491 channel
->ndomains
= 0; /* default to none */
1493 hostname
= ares_malloc(len
);
1500 res
= gethostname(hostname
, lenv
);
1506 p
= ares_realloc(hostname
, len
);
1521 dot
= strchr(hostname
, '.');
1523 /* a dot was found */
1524 channel
->domains
= ares_malloc(sizeof(char *));
1525 if (!channel
->domains
) {
1529 channel
->domains
[0] = ares_strdup(dot
+ 1);
1530 if (!channel
->domains
[0]) {
1534 channel
->ndomains
= 1;
1539 if (channel
->nsort
== -1) {
1540 channel
->sortlist
= NULL
;
1544 if (!channel
->lookups
) {
1545 channel
->lookups
= ares_strdup("fb");
1546 if (!channel
->lookups
)
1552 if(channel
->servers
) {
1553 ares_free(channel
->servers
);
1554 channel
->servers
= NULL
;
1557 if(channel
->domains
&& channel
->domains
[0])
1558 ares_free(channel
->domains
[0]);
1559 if(channel
->domains
) {
1560 ares_free(channel
->domains
);
1561 channel
->domains
= NULL
;
1564 if(channel
->lookups
) {
1565 ares_free(channel
->lookups
);
1566 channel
->lookups
= NULL
;
1571 ares_free(hostname
);
1576 #if !defined(WIN32) && !defined(WATT32) && \
1577 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1578 static int config_domain(ares_channel channel
, char *str
)
1582 /* Set a single search domain. */
1584 while (*q
&& !ISSPACE(*q
))
1587 return set_search(channel
, str
);
1590 #if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1591 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1592 /* workaround icc 9.1 optimizer issue */
1593 # define vqualifier volatile
1598 static int config_lookup(ares_channel channel
, const char *str
,
1599 const char *bindch
, const char *altbindch
,
1602 char lookups
[3], *l
;
1603 const char *vqualifier p
;
1605 if (altbindch
== NULL
)
1608 /* Set the lookup order. Only the first letter of each work
1609 * is relevant, and it has to be "b" for DNS or "f" for the
1610 * host file. Ignore everything else.
1616 if ((*p
== *bindch
|| *p
== *altbindch
|| *p
== *filech
) && l
< lookups
+ 2) {
1617 if (*p
== *bindch
|| *p
== *altbindch
) *l
++ = 'b';
1620 while (*p
&& !ISSPACE(*p
) && (*p
!= ','))
1622 while (*p
&& (ISSPACE(*p
) || (*p
== ',')))
1626 channel
->lookups
= ares_strdup(lookups
);
1627 return (channel
->lookups
) ? ARES_SUCCESS
: ARES_ENOMEM
;
1629 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
1632 static int config_nameserver(struct server_state
**servers
, int *nservers
,
1635 struct ares_addr host
;
1636 struct server_state
*newserv
;
1638 /* On Windows, there may be more than one nameserver specified in the same
1639 * registry key, so we parse input as a space or comma seperated list.
1643 /* Skip whitespace and commas. */
1644 while (*p
&& (ISSPACE(*p
) || (*p
== ',')))
1647 /* No more input, done. */
1650 /* Pointer to start of IPv4 or IPv6 address part. */
1653 /* Advance past this address. */
1654 while (*p
&& !ISSPACE(*p
) && (*p
!= ','))
1657 /* Null terminate this address. */
1660 /* Reached end of input, done when this address is processed. */
1663 /* Convert textual address to binary format. */
1664 if (ares_inet_pton(AF_INET
, txtaddr
, &host
.addrV4
) == 1)
1665 host
.family
= AF_INET
;
1666 else if (ares_inet_pton(AF_INET6
, txtaddr
, &host
.addrV6
) == 1)
1667 host
.family
= AF_INET6
;
1671 /* Resize servers state array. */
1672 newserv
= ares_realloc(*servers
, (*nservers
+ 1) *
1673 sizeof(struct server_state
));
1677 /* Store address data. */
1678 newserv
[*nservers
].addr
.family
= host
.family
;
1679 newserv
[*nservers
].addr
.udp_port
= 0;
1680 newserv
[*nservers
].addr
.tcp_port
= 0;
1681 if (host
.family
== AF_INET
)
1682 memcpy(&newserv
[*nservers
].addr
.addrV4
, &host
.addrV4
,
1683 sizeof(host
.addrV4
));
1685 memcpy(&newserv
[*nservers
].addr
.addrV6
, &host
.addrV6
,
1686 sizeof(host
.addrV6
));
1688 /* Update arguments. */
1693 return ARES_SUCCESS
;
1695 #endif /* !WATT32 */
1697 static int config_sortlist(struct apattern
**sortlist
, int *nsort
,
1700 struct apattern pat
;
1703 /* Add sortlist entries. */
1704 while (*str
&& *str
!= ';')
1707 char ipbuf
[16], ipbufpfx
[32];
1708 /* Find just the IP */
1710 while (*q
&& *q
!= '/' && *q
!= ';' && !ISSPACE(*q
))
1712 memcpy(ipbuf
, str
, q
-str
);
1713 ipbuf
[q
-str
] = '\0';
1714 /* Find the prefix */
1717 const char *str2
= q
+1;
1718 while (*q
&& *q
!= ';' && !ISSPACE(*q
))
1720 memcpy(ipbufpfx
, str
, q
-str
);
1721 ipbufpfx
[q
-str
] = '\0';
1726 /* Lets see if it is CIDR */
1727 /* First we'll try IPv6 */
1728 if ((bits
= ares_inet_net_pton(AF_INET6
, ipbufpfx
[0] ? ipbufpfx
: ipbuf
,
1730 sizeof(pat
.addrV6
))) > 0)
1732 pat
.type
= PATTERN_CIDR
;
1733 pat
.mask
.bits
= (unsigned short)bits
;
1734 pat
.family
= AF_INET6
;
1735 if (!sortlist_alloc(sortlist
, nsort
, &pat
)) {
1736 ares_free(*sortlist
);
1741 else if (ipbufpfx
[0] &&
1742 (bits
= ares_inet_net_pton(AF_INET
, ipbufpfx
, &pat
.addrV4
,
1743 sizeof(pat
.addrV4
))) > 0)
1745 pat
.type
= PATTERN_CIDR
;
1746 pat
.mask
.bits
= (unsigned short)bits
;
1747 pat
.family
= AF_INET
;
1748 if (!sortlist_alloc(sortlist
, nsort
, &pat
)) {
1749 ares_free(*sortlist
);
1754 /* See if it is just a regular IP */
1755 else if (ip_addr(ipbuf
, q
-str
, &pat
.addrV4
) == 0)
1759 memcpy(ipbuf
, str
, q
-str
);
1760 ipbuf
[q
-str
] = '\0';
1761 if (ip_addr(ipbuf
, q
-str
, &pat
.mask
.addr4
) != 0)
1766 pat
.family
= AF_INET
;
1767 pat
.type
= PATTERN_MASK
;
1768 if (!sortlist_alloc(sortlist
, nsort
, &pat
)) {
1769 ares_free(*sortlist
);
1776 while (*q
&& *q
!= ';' && !ISSPACE(*q
))
1780 while (ISSPACE(*str
))
1784 return ARES_SUCCESS
;
1787 static int set_search(ares_channel channel
, const char *str
)
1792 if(channel
->ndomains
!= -1) {
1793 /* LCOV_EXCL_START: all callers check ndomains == -1 */
1794 /* if we already have some domains present, free them first */
1795 for(n
=0; n
< channel
->ndomains
; n
++)
1796 ares_free(channel
->domains
[n
]);
1797 ares_free(channel
->domains
);
1798 channel
->domains
= NULL
;
1799 channel
->ndomains
= -1;
1800 } /* LCOV_EXCL_STOP */
1802 /* Count the domains given. */
1807 while (*p
&& !ISSPACE(*p
))
1816 channel
->ndomains
= 0;
1817 return ARES_SUCCESS
;
1820 channel
->domains
= ares_malloc(n
* sizeof(char *));
1821 if (!channel
->domains
)
1824 /* Now copy the domains. */
1829 channel
->ndomains
= n
;
1831 while (*q
&& !ISSPACE(*q
))
1833 channel
->domains
[n
] = ares_malloc(q
- p
+ 1);
1834 if (!channel
->domains
[n
])
1836 memcpy(channel
->domains
[n
], p
, q
- p
);
1837 channel
->domains
[n
][q
- p
] = 0;
1843 channel
->ndomains
= n
;
1845 return ARES_SUCCESS
;
1848 static int set_options(ares_channel channel
, const char *str
)
1850 const char *p
, *q
, *val
;
1856 while (*q
&& !ISSPACE(*q
))
1858 val
= try_option(p
, q
, "ndots:");
1859 if (val
&& channel
->ndots
== -1)
1860 channel
->ndots
= aresx_sltosi(strtol(val
, NULL
, 10));
1861 val
= try_option(p
, q
, "retrans:");
1862 if (val
&& channel
->timeout
== -1)
1863 channel
->timeout
= aresx_sltosi(strtol(val
, NULL
, 10));
1864 val
= try_option(p
, q
, "retry:");
1865 if (val
&& channel
->tries
== -1)
1866 channel
->tries
= aresx_sltosi(strtol(val
, NULL
, 10));
1867 val
= try_option(p
, q
, "rotate");
1868 if (val
&& channel
->rotate
== -1)
1869 channel
->rotate
= 1;
1875 return ARES_SUCCESS
;
1878 static const char *try_option(const char *p
, const char *q
, const char *opt
)
1880 size_t len
= strlen(opt
);
1881 return ((size_t)(q
- p
) >= len
&& !strncmp(p
, opt
, len
)) ? &p
[len
] : NULL
;
1884 #if !defined(WIN32) && !defined(WATT32) && \
1885 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1886 static char *try_config(char *s
, const char *opt
, char scc
)
1893 /* no line or no option */
1894 return NULL
; /* LCOV_EXCL_LINE */
1896 /* Hash '#' character is always used as primary comment char, additionally
1897 a not-NUL secondary comment char will be considered when specified. */
1899 /* trim line comment */
1902 while (*p
&& (*p
!= '#') && (*p
!= scc
))
1905 while (*p
&& (*p
!= '#'))
1909 /* trim trailing whitespace */
1911 while ((q
>= s
) && ISSPACE(*q
))
1915 /* skip leading whitespace */
1917 while (*p
&& ISSPACE(*p
))
1924 if ((len
= strlen(opt
)) == 0)
1926 return NULL
; /* LCOV_EXCL_LINE */
1928 if (strncmp(p
, opt
, len
) != 0)
1929 /* line and option do not match */
1932 /* skip over given option name */
1936 /* no option value */
1937 return NULL
; /* LCOV_EXCL_LINE */
1939 if ((opt
[len
-1] != ':') && (opt
[len
-1] != '=') && !ISSPACE(*p
))
1940 /* whitespace between option name and value is mandatory
1941 for given option names which do not end with ':' or '=' */
1944 /* skip over whitespace */
1945 while (*p
&& ISSPACE(*p
))
1949 /* no option value */
1952 /* return pointer to option value */
1955 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1957 static int ip_addr(const char *ipbuf
, ssize_t len
, struct in_addr
*addr
)
1960 /* Four octets and three periods yields at most 15 characters. */
1964 addr
->s_addr
= inet_addr(ipbuf
);
1965 if (addr
->s_addr
== INADDR_NONE
&& strcmp(ipbuf
, "255.255.255.255") != 0)
1970 static void natural_mask(struct apattern
*pat
)
1972 struct in_addr addr
;
1974 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1977 addr
.s_addr
= ntohl(pat
->addrV4
.s_addr
);
1979 /* This is out of date in the CIDR world, but some people might
1982 if (IN_CLASSA(addr
.s_addr
))
1983 pat
->mask
.addr4
.s_addr
= htonl(IN_CLASSA_NET
);
1984 else if (IN_CLASSB(addr
.s_addr
))
1985 pat
->mask
.addr4
.s_addr
= htonl(IN_CLASSB_NET
);
1987 pat
->mask
.addr4
.s_addr
= htonl(IN_CLASSC_NET
);
1990 static int sortlist_alloc(struct apattern
**sortlist
, int *nsort
,
1991 struct apattern
*pat
)
1993 struct apattern
*newsort
;
1994 newsort
= ares_realloc(*sortlist
, (*nsort
+ 1) * sizeof(struct apattern
));
1997 newsort
[*nsort
] = *pat
;
1998 *sortlist
= newsort
;
2003 /* initialize an rc4 key. If possible a cryptographically secure random key
2004 is generated using a suitable function (for example win32's RtlGenRandom as
2006 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
2007 otherwise the code defaults to cross-platform albeit less secure mechanism
2010 static void randomize_key(unsigned char* key
,int key_data_len
)
2016 if (ares_fpSystemFunction036
)
2018 res
= (*ares_fpSystemFunction036
) (key
, key_data_len
);
2024 FILE *f
= fopen(RANDOM_FILE
, "rb");
2026 counter
= aresx_uztosi(fread(key
, 1, key_data_len
, f
));
2033 for (;counter
<key_data_len
;counter
++)
2034 key
[counter
]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2038 static int init_id_key(rc4_key
* key
,int key_data_len
)
2040 unsigned char index1
;
2041 unsigned char index2
;
2042 unsigned char* state
;
2044 unsigned char *key_data_ptr
= 0;
2046 key_data_ptr
= ares_malloc(key_data_len
);
2049 memset(key_data_ptr
, 0, key_data_len
);
2051 state
= &key
->state
[0];
2052 for(counter
= 0; counter
< 256; counter
++)
2053 /* unnecessary AND but it keeps some compilers happier */
2054 state
[counter
] = (unsigned char)(counter
& 0xff);
2055 randomize_key(key
->state
,key_data_len
);
2060 for(counter
= 0; counter
< 256; counter
++)
2062 index2
= (unsigned char)((key_data_ptr
[index1
] + state
[counter
] +
2064 ARES_SWAP_BYTE(&state
[counter
], &state
[index2
]);
2066 index1
= (unsigned char)((index1
+ 1) % key_data_len
);
2068 ares_free(key_data_ptr
);
2069 return ARES_SUCCESS
;
2072 void ares_set_local_ip4(ares_channel channel
, unsigned int local_ip
)
2074 channel
->local_ip4
= local_ip
;
2077 /* local_ip6 should be 16 bytes in length */
2078 void ares_set_local_ip6(ares_channel channel
,
2079 const unsigned char* local_ip6
)
2081 memcpy(&channel
->local_ip6
, local_ip6
, sizeof(channel
->local_ip6
));
2084 /* local_dev_name should be null terminated. */
2085 void ares_set_local_dev(ares_channel channel
,
2086 const char* local_dev_name
)
2088 strncpy(channel
->local_dev_name
, local_dev_name
,
2089 sizeof(channel
->local_dev_name
));
2090 channel
->local_dev_name
[sizeof(channel
->local_dev_name
) - 1] = 0;
2094 void ares_set_socket_callback(ares_channel channel
,
2095 ares_sock_create_callback cb
,
2098 channel
->sock_create_cb
= cb
;
2099 channel
->sock_create_cb_data
= data
;
2102 void ares_set_socket_configure_callback(ares_channel channel
,
2103 ares_sock_config_callback cb
,
2106 channel
->sock_config_cb
= cb
;
2107 channel
->sock_config_cb_data
= data
;
2110 void ares_set_socket_functions(ares_channel channel
,
2111 const struct ares_socket_functions
* funcs
,
2114 channel
->sock_funcs
= funcs
;
2115 channel
->sock_func_cb_data
= data
;
2118 int ares_set_sortlist(ares_channel channel
, const char *sortstr
)
2121 struct apattern
*sortlist
= NULL
;
2125 return ARES_ENODATA
;
2127 status
= config_sortlist(&sortlist
, &nsort
, sortstr
);
2128 if (status
== ARES_SUCCESS
&& sortlist
) {
2129 if (channel
->sortlist
)
2130 ares_free(channel
->sortlist
);
2131 channel
->sortlist
= sortlist
;
2132 channel
->nsort
= nsort
;
2137 void ares__init_servers_state(ares_channel channel
)
2139 struct server_state
*server
;
2142 for (i
= 0; i
< channel
->nservers
; i
++)
2144 server
= &channel
->servers
[i
];
2145 server
->udp_socket
= ARES_SOCKET_BAD
;
2146 server
->tcp_socket
= ARES_SOCKET_BAD
;
2147 server
->tcp_connection_generation
= ++channel
->tcp_connection_generation
;
2148 server
->tcp_lenbuf_pos
= 0;
2149 server
->tcp_buffer_pos
= 0;
2150 server
->tcp_buffer
= NULL
;
2151 server
->tcp_length
= 0;
2152 server
->qhead
= NULL
;
2153 server
->qtail
= NULL
;
2154 ares__init_list_head(&server
->queries_to_server
);
2155 server
->channel
= channel
;
2156 server
->is_broken
= 0;