blob: 6482f8e2555b572700abc033f16836cafb63b462 [file] [log] [blame]
lh9ed821d2023-04-07 01:36:19 -07001
2/* Copyright 1998 by the Massachusetts Institute of Technology.
3 * Copyright (C) 2007-2013 by Daniel Stenberg
4 *
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.
16 */
17
18#include "ares_setup.h"
19
20#ifdef HAVE_SYS_PARAM_H
21#include <sys/param.h>
22#endif
23
24#ifdef HAVE_NETINET_IN_H
25#include <netinet/in.h>
26#endif
27
28#ifdef HAVE_NETDB_H
29#include <netdb.h>
30#endif
31
32#ifdef HAVE_ARPA_INET_H
33#include <arpa/inet.h>
34#endif
35
36#ifdef HAVE_ARPA_NAMESER_H
37# include <arpa/nameser.h>
38#else
39# include "nameser.h"
40#endif
41#ifdef HAVE_ARPA_NAMESER_COMPAT_H
42# include <arpa/nameser_compat.h>
43#endif
44
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
50#endif
51
52#if defined(CARES_USE_LIBRESOLV)
53#include <resolv.h>
54#endif
55
56#include "ares.h"
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"
62
63#ifdef WATT32
64#undef WIN32 /* Redefined in MingW/MSVC headers */
65#endif
66
67static int init_by_options(ares_channel channel,
68 const struct ares_options *options,
69 int optmask);
70static int init_by_environment(ares_channel channel);
71static int init_by_resolv_conf(ares_channel channel);
72static int init_by_defaults(ares_channel channel);
73
74#ifndef WATT32
75static int config_nameserver(struct server_state **servers, int *nservers,
76 char *str);
77#endif
78static int set_search(ares_channel channel, const char *str);
79static int set_options(ares_channel channel, const char *str);
80static const char *try_option(const char *p, const char *q, const char *opt);
81static int init_id_key(rc4_key* key,int key_data_len);
82
83static int config_sortlist(struct apattern **sortlist, int *nsort,
84 const char *str);
85static int sortlist_alloc(struct apattern **sortlist, int *nsort,
86 struct apattern *pat);
87static int ip_addr(const char *s, ssize_t len, struct in_addr *addr);
88static void natural_mask(struct apattern *pat);
89#if !defined(WIN32) && !defined(WATT32) && \
90 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
91static int config_domain(ares_channel channel, char *str);
92static int config_lookup(ares_channel channel, const char *str,
93 const char *bindch, const char *altbindch,
94 const char *filech);
95static char *try_config(char *s, const char *opt, char scc);
96#endif
97
98#define ARES_CONFIG_CHECK(x) (x->lookups && x->nsort > -1 && \
99 x->nservers > -1 && \
100 x->ndomains > -1 && \
101 x->ndots > -1 && x->timeout > -1 && \
102 x->tries > -1)
103
104int ares_init(ares_channel *channelptr)
105{
106 return ares_init_options(channelptr, NULL, 0, NULL);
107}
108
109int ares_init_options(ares_channel *channelptr, struct ares_options *options,
110 int optmask, char * dev)
111{
112 ares_channel channel;
113 int i;
114 int status = ARES_SUCCESS;
115 struct timeval now;
116
117#ifdef CURLDEBUG
118 const char *env = getenv("CARES_MEMDEBUG");
119
120 if (env)
121 curl_memdebug(env);
122 env = getenv("CARES_MEMLIMIT");
123 if (env) {
124 char *endptr;
125 long num = strtol(env, &endptr, 10);
126 if((endptr != env) && (endptr == env + strlen(env)) && (num > 0))
127 curl_memlimit(num);
128 }
129#endif
130
131 if (ares_library_initialized() != ARES_SUCCESS)
132 return ARES_ENOTINITIALIZED; /* LCOV_EXCL_LINE: n/a on non-WinSock */
133
134 channel = ares_malloc(sizeof(struct ares_channeldata));
135 if (!channel) {
136 *channelptr = NULL;
137 return ARES_ENOMEM;
138 }
139
140 now = ares__tvnow();
141
142 /* Set everything to distinguished values so we know they haven't
143 * been set yet.
144 */
145 channel->flags = -1;
146 channel->timeout = -1;
147 channel->tries = -1;
148 channel->ndots = -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;
157 channel->nsort = -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
170 channel->last_server = 0;
171 channel->last_timeout_processed = (time_t)now.tv_sec;
172
173 memset(&channel->local_dev_name, 0, sizeof(channel->local_dev_name));
174 channel->local_ip4 = 0;
175 memset(&channel->local_ip6, 0, sizeof(channel->local_ip6));
176
177
178 ares_set_local_dev(channel, dev);
179 fprintf(stderr, "channel_dev is %s\n", channel->local_dev_name);
180 if(dev)
181 ares_free(dev);
182
183 /* Initialize our lists of queries */
184 ares__init_list_head(&(channel->all_queries));
185 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
186 {
187 ares__init_list_head(&(channel->queries_by_qid[i]));
188 }
189 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
190 {
191 ares__init_list_head(&(channel->queries_by_timeout[i]));
192 }
193
194 /* Initialize configuration by each of the four sources, from highest
195 * precedence to lowest.
196 */
197
198 status = init_by_options(channel, options, optmask);
199 if (status != ARES_SUCCESS) {
200 DEBUGF(fprintf(stderr, "Error: init_by_options failed: %s\n",
201 ares_strerror(status)));
202 /* If we fail to apply user-specified options, fail the whole init process */
203 goto done;
204 }
205 status = init_by_environment(channel);
206 if (status != ARES_SUCCESS)
207 DEBUGF(fprintf(stderr, "Error: init_by_environment failed: %s\n",
208 ares_strerror(status)));
209 if (status == ARES_SUCCESS) {
210 status = init_by_resolv_conf(channel);
211 if (status != ARES_SUCCESS)
212 DEBUGF(fprintf(stderr, "Error: init_by_resolv_conf failed: %s\n",
213 ares_strerror(status)));
214 }
215
216 /*
217 * No matter what failed or succeeded, seed defaults to provide
218 * useful behavior for things that we missed.
219 */
220 status = init_by_defaults(channel);
221 if (status != ARES_SUCCESS)
222 DEBUGF(fprintf(stderr, "Error: init_by_defaults failed: %s\n",
223 ares_strerror(status)));
224
225 /* Generate random key */
226
227 if (status == ARES_SUCCESS) {
228 status = init_id_key(&channel->id_key, ARES_ID_KEY_LEN);
229 if (status == ARES_SUCCESS)
230 channel->next_id = ares__generate_new_id(&channel->id_key);
231 else
232 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
233 ares_strerror(status)));
234 }
235
236done:
237 if (status != ARES_SUCCESS)
238 {
239 /* Something failed; clean up memory we may have allocated. */
240 if (channel->servers)
241 ares_free(channel->servers);
242 if (channel->domains)
243 {
244 for (i = 0; i < channel->ndomains; i++)
245 ares_free(channel->domains[i]);
246 ares_free(channel->domains);
247 }
248 if (channel->sortlist)
249 ares_free(channel->sortlist);
250 if(channel->lookups)
251 ares_free(channel->lookups);
252 ares_free(channel);
253 return status;
254 }
255
256 /* Trim to one server if ARES_FLAG_PRIMARY is set. */
257 if ((channel->flags & ARES_FLAG_PRIMARY) && channel->nservers > 1)
258 channel->nservers = 1;
259
260 ares__init_servers_state(channel);
261
262 *channelptr = channel;
263 return ARES_SUCCESS;
264}
265
266/* ares_dup() duplicates a channel handle with all its options and returns a
267 new channel handle */
268int ares_dup(ares_channel *dest, ares_channel src)
269{
270 struct ares_options opts;
271 struct ares_addr_port_node *servers;
272 int non_v4_default_port = 0;
273 int i, rc;
274 int optmask;
275
276 *dest = NULL; /* in case of failure return NULL explicitly */
277
278 /* First get the options supported by the old ares_save_options() function,
279 which is most of them */
280 rc = ares_save_options(src, &opts, &optmask);
281 if(rc)
282 {
283 ares_destroy_options(&opts);
284 return rc;
285 }
286
287 /* Then create the new channel with those options */
288 rc = ares_init_options(dest, &opts, optmask, NULL);
289
290 /* destroy the options copy to not leak any memory */
291 ares_destroy_options(&opts);
292
293 if(rc)
294 return rc;
295
296 /* Now clone the options that ares_save_options() doesn't support. */
297 (*dest)->sock_create_cb = src->sock_create_cb;
298 (*dest)->sock_create_cb_data = src->sock_create_cb_data;
299 (*dest)->sock_config_cb = src->sock_config_cb;
300 (*dest)->sock_config_cb_data = src->sock_config_cb_data;
301
302 strncpy((*dest)->local_dev_name, src->local_dev_name,
303 sizeof(src->local_dev_name));
304 (*dest)->local_ip4 = src->local_ip4;
305 memcpy((*dest)->local_ip6, src->local_ip6, sizeof(src->local_ip6));
306
307 /* Full name server cloning required if there is a non-IPv4, or non-default port, nameserver */
308 for (i = 0; i < src->nservers; i++)
309 {
310 if ((src->servers[i].addr.family != AF_INET) ||
311 (src->servers[i].addr.udp_port != 0) ||
312 (src->servers[i].addr.tcp_port != 0)) {
313 non_v4_default_port++;
314 break;
315 }
316 }
317 if (non_v4_default_port) {
318 rc = ares_get_servers_ports(src, &servers);
319 if (rc != ARES_SUCCESS) {
320 ares_destroy(*dest);
321 *dest = NULL;
322 return rc;
323 }
324 rc = ares_set_servers_ports(*dest, servers);
325 ares_free_data(servers);
326 if (rc != ARES_SUCCESS) {
327 ares_destroy(*dest);
328 *dest = NULL;
329 return rc;
330 }
331 }
332
333 return ARES_SUCCESS; /* everything went fine */
334}
335
336/* Save options from initialized channel */
337int ares_save_options(ares_channel channel, struct ares_options *options,
338 int *optmask)
339{
340 int i, j;
341 int ipv4_nservers = 0;
342
343 /* Zero everything out */
344 memset(options, 0, sizeof(struct ares_options));
345
346 if (!ARES_CONFIG_CHECK(channel))
347 return ARES_ENODATA;
348
349 /* Traditionally the optmask wasn't saved in the channel struct so it was
350 recreated here. ROTATE is the first option that has no struct field of
351 its own in the public config struct */
352 (*optmask) = (ARES_OPT_FLAGS|ARES_OPT_TRIES|ARES_OPT_NDOTS|
353 ARES_OPT_UDP_PORT|ARES_OPT_TCP_PORT|ARES_OPT_SOCK_STATE_CB|
354 ARES_OPT_SERVERS|ARES_OPT_DOMAINS|ARES_OPT_LOOKUPS|
355 ARES_OPT_SORTLIST|ARES_OPT_TIMEOUTMS);
356 (*optmask) |= (channel->rotate ? ARES_OPT_ROTATE : ARES_OPT_NOROTATE);
357
358 /* Copy easy stuff */
359 options->flags = channel->flags;
360
361 /* We return full millisecond resolution but that's only because we don't
362 set the ARES_OPT_TIMEOUT anymore, only the new ARES_OPT_TIMEOUTMS */
363 options->timeout = channel->timeout;
364 options->tries = channel->tries;
365 options->ndots = channel->ndots;
366 options->udp_port = ntohs(aresx_sitous(channel->udp_port));
367 options->tcp_port = ntohs(aresx_sitous(channel->tcp_port));
368 options->sock_state_cb = channel->sock_state_cb;
369 options->sock_state_cb_data = channel->sock_state_cb_data;
370
371 /* Copy IPv4 servers that use the default port */
372 if (channel->nservers) {
373 for (i = 0; i < channel->nservers; i++)
374 {
375 if ((channel->servers[i].addr.family == AF_INET) &&
376 (channel->servers[i].addr.udp_port == 0) &&
377 (channel->servers[i].addr.tcp_port == 0))
378 ipv4_nservers++;
379 }
380 if (ipv4_nservers) {
381 options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
382 if (!options->servers)
383 return ARES_ENOMEM;
384 for (i = j = 0; i < channel->nservers; i++)
385 {
386 if ((channel->servers[i].addr.family == AF_INET) &&
387 (channel->servers[i].addr.udp_port == 0) &&
388 (channel->servers[i].addr.tcp_port == 0))
389 memcpy(&options->servers[j++],
390 &channel->servers[i].addr.addrV4,
391 sizeof(channel->servers[i].addr.addrV4));
392 }
393 }
394 }
395 options->nservers = ipv4_nservers;
396
397 /* copy domains */
398 if (channel->ndomains) {
399 options->domains = ares_malloc(channel->ndomains * sizeof(char *));
400 if (!options->domains)
401 return ARES_ENOMEM;
402
403 for (i = 0; i < channel->ndomains; i++)
404 {
405 options->ndomains = i;
406 options->domains[i] = ares_strdup(channel->domains[i]);
407 if (!options->domains[i])
408 return ARES_ENOMEM;
409 }
410 }
411 options->ndomains = channel->ndomains;
412
413 /* copy lookups */
414 if (channel->lookups) {
415 options->lookups = ares_strdup(channel->lookups);
416 if (!options->lookups && channel->lookups)
417 return ARES_ENOMEM;
418 }
419
420 /* copy sortlist */
421 if (channel->nsort) {
422 options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
423 if (!options->sortlist)
424 return ARES_ENOMEM;
425 for (i = 0; i < channel->nsort; i++)
426 options->sortlist[i] = channel->sortlist[i];
427 }
428 options->nsort = channel->nsort;
429
430 return ARES_SUCCESS;
431}
432
433static int init_by_options(ares_channel channel,
434 const struct ares_options *options,
435 int optmask)
436{
437 int i;
438
439 /* Easy stuff. */
440 if ((optmask & ARES_OPT_FLAGS) && channel->flags == -1)
441 channel->flags = options->flags;
442 if ((optmask & ARES_OPT_TIMEOUTMS) && channel->timeout == -1)
443 channel->timeout = options->timeout;
444 else if ((optmask & ARES_OPT_TIMEOUT) && channel->timeout == -1)
445 channel->timeout = options->timeout * 1000;
446 if ((optmask & ARES_OPT_TRIES) && channel->tries == -1)
447 channel->tries = options->tries;
448 if ((optmask & ARES_OPT_NDOTS) && channel->ndots == -1)
449 channel->ndots = options->ndots;
450 if ((optmask & ARES_OPT_ROTATE) && channel->rotate == -1)
451 channel->rotate = 1;
452 if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
453 channel->rotate = 0;
454 if ((optmask & ARES_OPT_UDP_PORT) && channel->udp_port == -1)
455 channel->udp_port = htons(options->udp_port);
456 if ((optmask & ARES_OPT_TCP_PORT) && channel->tcp_port == -1)
457 channel->tcp_port = htons(options->tcp_port);
458 if ((optmask & ARES_OPT_SOCK_STATE_CB) && channel->sock_state_cb == NULL)
459 {
460 channel->sock_state_cb = options->sock_state_cb;
461 channel->sock_state_cb_data = options->sock_state_cb_data;
462 }
463 if ((optmask & ARES_OPT_SOCK_SNDBUF)
464 && channel->socket_send_buffer_size == -1)
465 channel->socket_send_buffer_size = options->socket_send_buffer_size;
466 if ((optmask & ARES_OPT_SOCK_RCVBUF)
467 && channel->socket_receive_buffer_size == -1)
468 channel->socket_receive_buffer_size = options->socket_receive_buffer_size;
469
470 if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
471 channel->ednspsz = options->ednspsz;
472
473 /* Copy the IPv4 servers, if given. */
474 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
475 {
476 /* Avoid zero size allocations at any cost */
477 if (options->nservers > 0)
478 {
479 channel->servers =
480 ares_malloc(options->nservers * sizeof(struct server_state));
481 if (!channel->servers)
482 return ARES_ENOMEM;
483 for (i = 0; i < options->nservers; i++)
484 {
485 channel->servers[i].addr.family = AF_INET;
486 channel->servers[i].addr.udp_port = 0;
487 channel->servers[i].addr.tcp_port = 0;
488 memcpy(&channel->servers[i].addr.addrV4,
489 &options->servers[i],
490 sizeof(channel->servers[i].addr.addrV4));
491 }
492 }
493 channel->nservers = options->nservers;
494 }
495
496 /* Copy the domains, if given. Keep channel->ndomains consistent so
497 * we can clean up in case of error.
498 */
499 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
500 {
501 /* Avoid zero size allocations at any cost */
502 if (options->ndomains > 0)
503 {
504 channel->domains = ares_malloc(options->ndomains * sizeof(char *));
505 if (!channel->domains)
506 return ARES_ENOMEM;
507 for (i = 0; i < options->ndomains; i++)
508 {
509 channel->ndomains = i;
510 channel->domains[i] = ares_strdup(options->domains[i]);
511 if (!channel->domains[i])
512 return ARES_ENOMEM;
513 }
514 }
515 channel->ndomains = options->ndomains;
516 }
517
518 /* Set lookups, if given. */
519 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
520 {
521 channel->lookups = ares_strdup(options->lookups);
522 if (!channel->lookups)
523 return ARES_ENOMEM;
524 }
525
526 /* copy sortlist */
527 if ((optmask & ARES_OPT_SORTLIST) && (channel->nsort == -1)) {
528 if (options->nsort > 0) {
529 channel->sortlist = ares_malloc(options->nsort * sizeof(struct apattern));
530 if (!channel->sortlist)
531 return ARES_ENOMEM;
532 for (i = 0; i < options->nsort; i++)
533 channel->sortlist[i] = options->sortlist[i];
534 }
535 channel->nsort = options->nsort;
536 }
537
538 channel->optmask = optmask;
539
540 return ARES_SUCCESS;
541}
542
543static int init_by_environment(ares_channel channel)
544{
545 const char *localdomain, *res_options;
546 int status;
547
548 localdomain = getenv("LOCALDOMAIN");
549 if (localdomain && channel->ndomains == -1)
550 {
551 status = set_search(channel, localdomain);
552 if (status != ARES_SUCCESS)
553 return status;
554 }
555
556 res_options = getenv("RES_OPTIONS");
557 if (res_options)
558 {
559 status = set_options(channel, res_options);
560 if (status != ARES_SUCCESS)
561 return status; /* LCOV_EXCL_LINE: set_options() never fails */
562 }
563
564 return ARES_SUCCESS;
565}
566
567#ifdef WIN32
568/*
569 * get_REG_SZ()
570 *
571 * Given a 'hKey' handle to an open registry key and a 'leafKeyName' pointer
572 * to the name of the registry leaf key to be queried, fetch it's string
573 * value and return a pointer in *outptr to a newly allocated memory area
574 * holding it as a null-terminated string.
575 *
576 * Returns 0 and nullifies *outptr upon inability to return a string value.
577 *
578 * Returns 1 and sets *outptr when returning a dynamically allocated string.
579 *
580 * Supported on Windows NT 3.5 and newer.
581 */
582static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
583{
584 DWORD size = 0;
585 int res;
586
587 *outptr = NULL;
588
589 /* Find out size of string stored in registry */
590 res = RegQueryValueEx(hKey, leafKeyName, 0, NULL, NULL, &size);
591 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
592 return 0;
593
594 /* Allocate buffer of indicated size plus one given that string
595 might have been stored without null termination */
596 *outptr = ares_malloc(size+1);
597 if (!*outptr)
598 return 0;
599
600 /* Get the value for real */
601 res = RegQueryValueEx(hKey, leafKeyName, 0, NULL,
602 (unsigned char *)*outptr, &size);
603 if ((res != ERROR_SUCCESS) || (size == 1))
604 {
605 ares_free(*outptr);
606 *outptr = NULL;
607 return 0;
608 }
609
610 /* Null terminate buffer allways */
611 *(*outptr + size) = '\0';
612
613 return 1;
614}
615
616/*
617 * get_REG_SZ_9X()
618 *
619 * Functionally identical to get_REG_SZ()
620 *
621 * Supported on Windows 95, 98 and ME.
622 */
623static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
624{
625 DWORD dataType = 0;
626 DWORD size = 0;
627 int res;
628
629 *outptr = NULL;
630
631 /* Find out size of string stored in registry */
632 res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType, NULL, &size);
633 if ((res != ERROR_SUCCESS && res != ERROR_MORE_DATA) || !size)
634 return 0;
635
636 /* Allocate buffer of indicated size plus one given that string
637 might have been stored without null termination */
638 *outptr = ares_malloc(size+1);
639 if (!*outptr)
640 return 0;
641
642 /* Get the value for real */
643 res = RegQueryValueEx(hKey, leafKeyName, 0, &dataType,
644 (unsigned char *)*outptr, &size);
645 if ((res != ERROR_SUCCESS) || (size == 1))
646 {
647 ares_free(*outptr);
648 *outptr = NULL;
649 return 0;
650 }
651
652 /* Null terminate buffer allways */
653 *(*outptr + size) = '\0';
654
655 return 1;
656}
657
658/*
659 * get_enum_REG_SZ()
660 *
661 * Given a 'hKeyParent' handle to an open registry key and a 'leafKeyName'
662 * pointer to the name of the registry leaf key to be queried, parent key
663 * is enumerated searching in child keys for given leaf key name and its
664 * associated string value. When located, this returns a pointer in *outptr
665 * to a newly allocated memory area holding it as a null-terminated string.
666 *
667 * Returns 0 and nullifies *outptr upon inability to return a string value.
668 *
669 * Returns 1 and sets *outptr when returning a dynamically allocated string.
670 *
671 * Supported on Windows NT 3.5 and newer.
672 */
673static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
674 char **outptr)
675{
676 char enumKeyName[256];
677 DWORD enumKeyNameBuffSize;
678 DWORD enumKeyIdx = 0;
679 HKEY hKeyEnum;
680 int gotString;
681 int res;
682
683 *outptr = NULL;
684
685 for(;;)
686 {
687 enumKeyNameBuffSize = sizeof(enumKeyName);
688 res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName,
689 &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
690 if (res != ERROR_SUCCESS)
691 break;
692 res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
693 &hKeyEnum);
694 if (res != ERROR_SUCCESS)
695 continue;
696 gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
697 RegCloseKey(hKeyEnum);
698 if (gotString)
699 break;
700 }
701
702 if (!*outptr)
703 return 0;
704
705 return 1;
706}
707
708/*
709 * get_DNS_Registry_9X()
710 *
711 * Functionally identical to get_DNS_Registry()
712 *
713 * Implementation supports Windows 95, 98 and ME.
714 */
715static int get_DNS_Registry_9X(char **outptr)
716{
717 HKEY hKey_VxD_MStcp;
718 int gotString;
719 int res;
720
721 *outptr = NULL;
722
723 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
724 &hKey_VxD_MStcp);
725 if (res != ERROR_SUCCESS)
726 return 0;
727
728 gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
729 RegCloseKey(hKey_VxD_MStcp);
730
731 if (!gotString || !*outptr)
732 return 0;
733
734 return 1;
735}
736
737/*
738 * get_DNS_Registry_NT()
739 *
740 * Functionally identical to get_DNS_Registry()
741 *
742 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
743 *
744 * Implementation supports Windows NT 3.5 and newer.
745 */
746static int get_DNS_Registry_NT(char **outptr)
747{
748 HKEY hKey_Interfaces = NULL;
749 HKEY hKey_Tcpip_Parameters;
750 int gotString;
751 int res;
752
753 *outptr = NULL;
754
755 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
756 &hKey_Tcpip_Parameters);
757 if (res != ERROR_SUCCESS)
758 return 0;
759
760 /*
761 ** Global DNS settings override adapter specific parameters when both
762 ** are set. Additionally static DNS settings override DHCP-configured
763 ** parameters when both are set.
764 */
765
766 /* Global DNS static parameters */
767 gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
768 if (gotString)
769 goto done;
770
771 /* Global DNS DHCP-configured parameters */
772 gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
773 if (gotString)
774 goto done;
775
776 /* Try adapter specific parameters */
777 res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0,
778 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
779 &hKey_Interfaces);
780 if (res != ERROR_SUCCESS)
781 {
782 hKey_Interfaces = NULL;
783 goto done;
784 }
785
786 /* Adapter specific DNS static parameters */
787 gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
788 if (gotString)
789 goto done;
790
791 /* Adapter specific DNS DHCP-configured parameters */
792 gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
793
794done:
795 if (hKey_Interfaces)
796 RegCloseKey(hKey_Interfaces);
797
798 RegCloseKey(hKey_Tcpip_Parameters);
799
800 if (!gotString || !*outptr)
801 return 0;
802
803 return 1;
804}
805
806/*
807 * get_DNS_Registry()
808 *
809 * Locates DNS info in the registry. When located, this returns a pointer
810 * in *outptr to a newly allocated memory area holding a null-terminated
811 * string with a space or comma seperated list of DNS IP addresses.
812 *
813 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
814 *
815 * Returns 1 and sets *outptr when returning a dynamically allocated string.
816 */
817static int get_DNS_Registry(char **outptr)
818{
819 win_platform platform;
820 int gotString = 0;
821
822 *outptr = NULL;
823
824 platform = ares__getplatform();
825
826 if (platform == WIN_NT)
827 gotString = get_DNS_Registry_NT(outptr);
828 else if (platform == WIN_9X)
829 gotString = get_DNS_Registry_9X(outptr);
830
831 if (!gotString)
832 return 0;
833
834 return 1;
835}
836
837/*
838 * commajoin()
839 *
840 * RTF code.
841 */
842static void commajoin(char **dst, const char *src)
843{
844 char *tmp;
845
846 if (*dst)
847 {
848 tmp = ares_malloc(strlen(*dst) + strlen(src) + 2);
849 if (!tmp)
850 return;
851 sprintf(tmp, "%s,%s", *dst, src);
852 ares_free(*dst);
853 *dst = tmp;
854 }
855 else
856 {
857 *dst = ares_malloc(strlen(src) + 1);
858 if (!*dst)
859 return;
860 strcpy(*dst, src);
861 }
862}
863
864/*
865 * get_DNS_NetworkParams()
866 *
867 * Locates DNS info using GetNetworkParams() function from the Internet
868 * Protocol Helper (IP Helper) API. When located, this returns a pointer
869 * in *outptr to a newly allocated memory area holding a null-terminated
870 * string with a space or comma seperated list of DNS IP addresses.
871 *
872 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
873 *
874 * Returns 1 and sets *outptr when returning a dynamically allocated string.
875 *
876 * Implementation supports Windows 98 and newer.
877 *
878 * Note: Ancient PSDK required in order to build a W98 target.
879 */
880static int get_DNS_NetworkParams(char **outptr)
881{
882 FIXED_INFO *fi, *newfi;
883 struct ares_addr namesrvr;
884 char *txtaddr;
885 IP_ADDR_STRING *ipAddr;
886 int res;
887 DWORD size = sizeof (*fi);
888
889 *outptr = NULL;
890
891 /* Verify run-time availability of GetNetworkParams() */
892 if (ares_fpGetNetworkParams == ZERO_NULL)
893 return 0;
894
895 fi = ares_malloc(size);
896 if (!fi)
897 return 0;
898
899 res = (*ares_fpGetNetworkParams) (fi, &size);
900 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
901 goto done;
902
903 newfi = ares_realloc(fi, size);
904 if (!newfi)
905 goto done;
906
907 fi = newfi;
908 res = (*ares_fpGetNetworkParams) (fi, &size);
909 if (res != ERROR_SUCCESS)
910 goto done;
911
912 for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
913 {
914 txtaddr = &ipAddr->IpAddress.String[0];
915
916 /* Validate converting textual address to binary format. */
917 if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
918 {
919 if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
920 (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
921 continue;
922 }
923 else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
924 {
925 if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
926 sizeof(namesrvr.addrV6)) == 0)
927 continue;
928 }
929 else
930 continue;
931
932 commajoin(outptr, txtaddr);
933
934 if (!*outptr)
935 break;
936 }
937
938done:
939 if (fi)
940 ares_free(fi);
941
942 if (!*outptr)
943 return 0;
944
945 return 1;
946}
947
948/*
949 * get_DNS_AdaptersAddresses()
950 *
951 * Locates DNS info using GetAdaptersAddresses() function from the Internet
952 * Protocol Helper (IP Helper) API. When located, this returns a pointer
953 * in *outptr to a newly allocated memory area holding a null-terminated
954 * string with a space or comma seperated list of DNS IP addresses.
955 *
956 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
957 *
958 * Returns 1 and sets *outptr when returning a dynamically allocated string.
959 *
960 * Implementation supports Windows XP and newer.
961 */
962#define IPAA_INITIAL_BUF_SZ 15 * 1024
963#define IPAA_MAX_TRIES 3
964static int get_DNS_AdaptersAddresses(char **outptr)
965{
966 IP_ADAPTER_DNS_SERVER_ADDRESS *ipaDNSAddr;
967 IP_ADAPTER_ADDRESSES *ipaa, *newipaa, *ipaaEntry;
968 ULONG ReqBufsz = IPAA_INITIAL_BUF_SZ;
969 ULONG Bufsz = IPAA_INITIAL_BUF_SZ;
970 ULONG AddrFlags = 0;
971 int trying = IPAA_MAX_TRIES;
972 int res;
973
974 union {
975 struct sockaddr *sa;
976 struct sockaddr_in *sa4;
977 struct sockaddr_in6 *sa6;
978 } namesrvr;
979
980 char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
981
982 *outptr = NULL;
983
984 /* Verify run-time availability of GetAdaptersAddresses() */
985 if (ares_fpGetAdaptersAddresses == ZERO_NULL)
986 return 0;
987
988 ipaa = ares_malloc(Bufsz);
989 if (!ipaa)
990 return 0;
991
992 /* Usually this call suceeds with initial buffer size */
993 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
994 ipaa, &ReqBufsz);
995 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
996 goto done;
997
998 while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
999 {
1000 if (Bufsz < ReqBufsz)
1001 {
1002 newipaa = ares_realloc(ipaa, ReqBufsz);
1003 if (!newipaa)
1004 goto done;
1005 Bufsz = ReqBufsz;
1006 ipaa = newipaa;
1007 }
1008 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1009 ipaa, &ReqBufsz);
1010 if (res == ERROR_SUCCESS)
1011 break;
1012 }
1013 if (res != ERROR_SUCCESS)
1014 goto done;
1015
1016 for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1017 {
1018 if(ipaaEntry->OperStatus != IfOperStatusUp)
1019 continue;
1020
1021 for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1022 ipaDNSAddr;
1023 ipaDNSAddr = ipaDNSAddr->Next)
1024 {
1025 namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1026
1027 if (namesrvr.sa->sa_family == AF_INET)
1028 {
1029 if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1030 (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
1031 continue;
1032 if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1033 txtaddr, sizeof(txtaddr)))
1034 continue;
1035 }
1036 else if (namesrvr.sa->sa_family == AF_INET6)
1037 {
1038 if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1039 sizeof(namesrvr.sa6->sin6_addr)) == 0)
1040 continue;
1041 if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1042 txtaddr, sizeof(txtaddr)))
1043 continue;
1044 }
1045 else
1046 continue;
1047
1048 commajoin(outptr, txtaddr);
1049
1050 if (!*outptr)
1051 goto done;
1052 }
1053 }
1054
1055done:
1056 if (ipaa)
1057 ares_free(ipaa);
1058
1059 if (!*outptr)
1060 return 0;
1061
1062 return 1;
1063}
1064
1065/*
1066 * get_DNS_Windows()
1067 *
1068 * Locates DNS info from Windows employing most suitable methods available at
1069 * run-time no matter which Windows version it is. When located, this returns
1070 * a pointer in *outptr to a newly allocated memory area holding a string with
1071 * a space or comma seperated list of DNS IP addresses, null-terminated.
1072 *
1073 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1074 *
1075 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1076 *
1077 * Implementation supports Windows 95 and newer.
1078 */
1079static int get_DNS_Windows(char **outptr)
1080{
1081 /*
1082 Use GetNetworkParams First in case of
1083 multiple adapter is enabled on this machine.
1084 GetAdaptersAddresses will retrive dummy dns servers.
1085 That will slowing DNS lookup.
1086 */
1087 /* Try using IP helper API GetNetworkParams() */
1088 if (get_DNS_NetworkParams(outptr))
1089 return 1;
1090
1091 /* Try using IP helper API GetAdaptersAddresses() */
1092 if (get_DNS_AdaptersAddresses(outptr))
1093 return 1;
1094
1095 /* Fall-back to registry information */
1096 return get_DNS_Registry(outptr);
1097}
1098#endif
1099
1100static int init_by_resolv_conf(ares_channel channel)
1101{
1102#if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1103 !defined(CARES_USE_LIBRESOLV)
1104 char *line = NULL;
1105#endif
1106 int status = -1, nservers = 0, nsort = 0;
1107 struct server_state *servers = NULL;
1108 struct apattern *sortlist = NULL;
1109
1110#ifdef WIN32
1111
1112 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1113 return ARES_SUCCESS;
1114
1115 if (get_DNS_Windows(&line))
1116 {
1117 status = config_nameserver(&servers, &nservers, line);
1118 ares_free(line);
1119 }
1120
1121 if (status == ARES_SUCCESS)
1122 status = ARES_EOF;
1123 else
1124 /* Catch the case when all the above checks fail (which happens when there
1125 is no network card or the cable is unplugged) */
1126 status = ARES_EFILE;
1127
1128#elif defined(__riscos__)
1129
1130 /* Under RISC OS, name servers are listed in the
1131 system variable Inet$Resolvers, space separated. */
1132
1133 line = getenv("Inet$Resolvers");
1134 status = ARES_EOF;
1135 if (line) {
1136 char *resolvers = ares_strdup(line), *pos, *space;
1137
1138 if (!resolvers)
1139 return ARES_ENOMEM;
1140
1141 pos = resolvers;
1142 do {
1143 space = strchr(pos, ' ');
1144 if (space)
1145 *space = '\0';
1146 status = config_nameserver(&servers, &nservers, pos);
1147 if (status != ARES_SUCCESS)
1148 break;
1149 pos = space + 1;
1150 } while (space);
1151
1152 if (status == ARES_SUCCESS)
1153 status = ARES_EOF;
1154
1155 ares_free(resolvers);
1156 }
1157
1158#elif defined(WATT32)
1159 int i;
1160
1161 sock_init();
1162 for (i = 0; def_nameservers[i]; i++)
1163 ;
1164 if (i == 0)
1165 return ARES_SUCCESS; /* use localhost DNS server */
1166
1167 nservers = i;
1168 servers = ares_malloc(sizeof(struct server_state));
1169 if (!servers)
1170 return ARES_ENOMEM;
1171 memset(servers, 0, sizeof(struct server_state));
1172
1173 for (i = 0; def_nameservers[i]; i++)
1174 {
1175 servers[i].addr.addrV4.s_addr = htonl(def_nameservers[i]);
1176 servers[i].addr.family = AF_INET;
1177 servers[i].addr.udp_port = 0;
1178 servers[i].addr.tcp_port = 0;
1179 }
1180 status = ARES_EOF;
1181
1182#elif defined(ANDROID) || defined(__ANDROID__)
1183 unsigned int i;
1184 char propname[PROP_NAME_MAX];
1185 char propvalue[PROP_VALUE_MAX]="";
1186
1187 for (i = 1; i <= MAX_DNS_PROPERTIES; i++) {
1188 snprintf(propname, sizeof(propname), "%s%u", DNS_PROP_NAME_PREFIX, i);
1189 if (__system_property_get(propname, propvalue) < 1) {
1190 status = ARES_EOF;
1191 break;
1192 }
1193 status = config_nameserver(&servers, &nservers, propvalue);
1194 if (status != ARES_SUCCESS)
1195 break;
1196 status = ARES_EOF;
1197 }
1198#elif defined(CARES_USE_LIBRESOLV)
1199 struct __res_state res;
1200 memset(&res, 0, sizeof(res));
1201 int result = res_ninit(&res);
1202 if (result == 0 && (res.options & RES_INIT)) {
1203 status = ARES_EOF;
1204
1205 if (channel->nservers == -1) {
1206 union res_sockaddr_union addr[MAXNS];
1207 int nscount = res_getservers(&res, addr, MAXNS);
1208 for (int i = 0; i < nscount; ++i) {
1209 char str[INET6_ADDRSTRLEN];
1210 int config_status;
1211 sa_family_t family = addr[i].sin.sin_family;
1212 if (family == AF_INET) {
1213 ares_inet_ntop(family, &addr[i].sin.sin_addr, str, sizeof(str));
1214 } else if (family == AF_INET6) {
1215 ares_inet_ntop(family, &addr[i].sin6.sin6_addr, str, sizeof(str));
1216 } else {
1217 continue;
1218 }
1219
1220 config_status = config_nameserver(&servers, &nservers, str);
1221 if (config_status != ARES_SUCCESS) {
1222 status = config_status;
1223 break;
1224 }
1225 }
1226 }
1227 if (channel->ndomains == -1) {
1228 int entries = 0;
1229 while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1230 entries++;
1231
1232 channel->domains = ares_malloc(entries * sizeof(char *));
1233 if (!channel->domains) {
1234 status = ARES_ENOMEM;
1235 } else {
1236 channel->ndomains = entries;
1237 for (int i = 0; i < channel->ndomains; ++i) {
1238 channel->domains[i] = ares_strdup(res.dnsrch[i]);
1239 if (!channel->domains[i])
1240 status = ARES_ENOMEM;
1241 }
1242 }
1243 }
1244 if (channel->ndots == -1)
1245 channel->ndots = res.ndots;
1246 if (channel->tries == -1)
1247 channel->tries = res.retry;
1248 if (channel->rotate == -1)
1249 channel->rotate = res.options & RES_ROTATE;
1250 if (channel->timeout == -1)
1251 channel->timeout = res.retrans * 1000;
1252
1253 res_ndestroy(&res);
1254 }
1255#else
1256 {
1257 char *p;
1258 FILE *fp;
1259 size_t linesize;
1260 int error;
1261 int update_domains;
1262
1263 /* Don't read resolv.conf and friends if we don't have to */
1264 if (ARES_CONFIG_CHECK(channel))
1265 return ARES_SUCCESS;
1266
1267 /* Only update search domains if they're not already specified */
1268 update_domains = (channel->ndomains == -1);
1269
1270 fp = fopen(PATH_RESOLV_CONF, "r");
1271 if (fp) {
1272 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1273 {
1274 if ((p = try_config(line, "domain", ';')) && update_domains)
1275 status = config_domain(channel, p);
1276 else if ((p = try_config(line, "lookup", ';')) && !channel->lookups)
1277 status = config_lookup(channel, p, "bind", NULL, "file");
1278 else if ((p = try_config(line, "search", ';')) && update_domains)
1279 status = set_search(channel, p);
1280 else if ((p = try_config(line, "nameserver", ';')) &&
1281 channel->nservers == -1)
1282 status = config_nameserver(&servers, &nservers, p);
1283 else if ((p = try_config(line, "sortlist", ';')) &&
1284 channel->nsort == -1)
1285 status = config_sortlist(&sortlist, &nsort, p);
1286 else if ((p = try_config(line, "options", ';')))
1287 status = set_options(channel, p);
1288 else
1289 status = ARES_SUCCESS;
1290 if (status != ARES_SUCCESS)
1291 break;
1292 }
1293 fclose(fp);
1294 }
1295 else {
1296 error = ERRNO;
1297 switch(error) {
1298 case ENOENT:
1299 case ESRCH:
1300 status = ARES_EOF;
1301 break;
1302 default:
1303 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1304 error, strerror(error)));
1305 DEBUGF(fprintf(stderr, "Error opening file: %s\n", PATH_RESOLV_CONF));
1306 status = ARES_EFILE;
1307 }
1308 }
1309
1310 if ((status == ARES_EOF) && (!channel->lookups)) {
1311 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1312 fp = fopen("/etc/nsswitch.conf", "r");
1313 if (fp) {
1314 while ((status = ares__read_line(fp, &line, &linesize)) ==
1315 ARES_SUCCESS)
1316 {
1317 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1318 (void)config_lookup(channel, p, "dns", "resolve", "files");
1319 }
1320 fclose(fp);
1321 }
1322 else {
1323 error = ERRNO;
1324 switch(error) {
1325 case ENOENT:
1326 case ESRCH:
1327 break;
1328 default:
1329 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1330 error, strerror(error)));
1331 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1332 "/etc/nsswitch.conf"));
1333 }
1334
1335 /* ignore error, maybe we will get luck in next if clause */
1336 status = ARES_EOF;
1337 }
1338 }
1339
1340 if ((status == ARES_EOF) && (!channel->lookups)) {
1341 /* Linux / GNU libc 2.x and possibly others have host.conf */
1342 fp = fopen("/etc/host.conf", "r");
1343 if (fp) {
1344 while ((status = ares__read_line(fp, &line, &linesize)) ==
1345 ARES_SUCCESS)
1346 {
1347 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1348 /* ignore errors */
1349 (void)config_lookup(channel, p, "bind", NULL, "hosts");
1350 }
1351 fclose(fp);
1352 }
1353 else {
1354 error = ERRNO;
1355 switch(error) {
1356 case ENOENT:
1357 case ESRCH:
1358 break;
1359 default:
1360 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1361 error, strerror(error)));
1362 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1363 "/etc/host.conf"));
1364 }
1365
1366 /* ignore error, maybe we will get luck in next if clause */
1367 status = ARES_EOF;
1368 }
1369 }
1370
1371 if ((status == ARES_EOF) && (!channel->lookups)) {
1372 /* Tru64 uses /etc/svc.conf */
1373 fp = fopen("/etc/svc.conf", "r");
1374 if (fp) {
1375 while ((status = ares__read_line(fp, &line, &linesize)) ==
1376 ARES_SUCCESS)
1377 {
1378 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1379 /* ignore errors */
1380 (void)config_lookup(channel, p, "bind", NULL, "local");
1381 }
1382 fclose(fp);
1383 }
1384 else {
1385 error = ERRNO;
1386 switch(error) {
1387 case ENOENT:
1388 case ESRCH:
1389 break;
1390 default:
1391 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1392 error, strerror(error)));
1393 DEBUGF(fprintf(stderr, "Error opening file: %s\n", "/etc/svc.conf"));
1394 }
1395
1396 /* ignore error, default value will be chosen for `channel->lookups` */
1397 status = ARES_EOF;
1398 }
1399 }
1400
1401 if(line)
1402 ares_free(line);
1403 }
1404
1405#endif
1406
1407 /* Handle errors. */
1408 if (status != ARES_EOF)
1409 {
1410 if (servers != NULL)
1411 ares_free(servers);
1412 if (sortlist != NULL)
1413 ares_free(sortlist);
1414 return status;
1415 }
1416
1417 /* If we got any name server entries, fill them in. */
1418 if (servers)
1419 {
1420 channel->servers = servers;
1421 channel->nservers = nservers;
1422 }
1423
1424 /* If we got any sortlist entries, fill them in. */
1425 if (sortlist)
1426 {
1427 channel->sortlist = sortlist;
1428 channel->nsort = nsort;
1429 }
1430
1431 return ARES_SUCCESS;
1432}
1433
1434static int init_by_defaults(ares_channel channel)
1435{
1436 char *hostname = NULL;
1437 int rc = ARES_SUCCESS;
1438#ifdef HAVE_GETHOSTNAME
1439 char *dot;
1440#endif
1441
1442 if (channel->flags == -1)
1443 channel->flags = 0;
1444 if (channel->timeout == -1)
1445 channel->timeout = DEFAULT_TIMEOUT;
1446 if (channel->tries == -1)
1447 channel->tries = DEFAULT_TRIES;
1448 if (channel->ndots == -1)
1449 channel->ndots = 1;
1450 if (channel->rotate == -1)
1451 channel->rotate = 0;
1452 if (channel->udp_port == -1)
1453 channel->udp_port = htons(NAMESERVER_PORT);
1454 if (channel->tcp_port == -1)
1455 channel->tcp_port = htons(NAMESERVER_PORT);
1456
1457 if (channel->ednspsz == -1)
1458 channel->ednspsz = EDNSPACKETSZ;
1459
1460 if (channel->nservers == -1) {
1461 /* If nobody specified servers, try a local named. */
1462 channel->servers = ares_malloc(sizeof(struct server_state));
1463 if (!channel->servers) {
1464 rc = ARES_ENOMEM;
1465 goto error;
1466 }
1467 channel->servers[0].addr.family = AF_INET;
1468 channel->servers[0].addr.addrV4.s_addr = htonl(INADDR_LOOPBACK);
1469 channel->servers[0].addr.udp_port = 0;
1470 channel->servers[0].addr.tcp_port = 0;
1471 channel->nservers = 1;
1472 }
1473
1474#if defined(USE_WINSOCK)
1475#define toolong(x) (x == -1) && (SOCKERRNO == WSAEFAULT)
1476#elif defined(ENAMETOOLONG)
1477#define toolong(x) (x == -1) && ((SOCKERRNO == ENAMETOOLONG) || \
1478 (SOCKERRNO == EINVAL))
1479#else
1480#define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1481#endif
1482
1483 if (channel->ndomains == -1) {
1484 /* Derive a default domain search list from the kernel hostname,
1485 * or set it to empty if the hostname isn't helpful.
1486 */
1487#ifndef HAVE_GETHOSTNAME
1488 channel->ndomains = 0; /* default to none */
1489#else
1490 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1491 size_t len = 64;
1492 int res;
1493 channel->ndomains = 0; /* default to none */
1494
1495 hostname = ares_malloc(len);
1496 if(!hostname) {
1497 rc = ARES_ENOMEM;
1498 goto error;
1499 }
1500
1501 do {
1502 res = gethostname(hostname, lenv);
1503
1504 if(toolong(res)) {
1505 char *p;
1506 len *= 2;
1507 lenv *= 2;
1508 p = ares_realloc(hostname, len);
1509 if(!p) {
1510 rc = ARES_ENOMEM;
1511 goto error;
1512 }
1513 hostname = p;
1514 continue;
1515 }
1516 else if(res) {
1517 rc = ARES_EBADNAME;
1518 goto error;
1519 }
1520
1521 } while (res != 0);
1522
1523 dot = strchr(hostname, '.');
1524 if (dot) {
1525 /* a dot was found */
1526 channel->domains = ares_malloc(sizeof(char *));
1527 if (!channel->domains) {
1528 rc = ARES_ENOMEM;
1529 goto error;
1530 }
1531 channel->domains[0] = ares_strdup(dot + 1);
1532 if (!channel->domains[0]) {
1533 rc = ARES_ENOMEM;
1534 goto error;
1535 }
1536 channel->ndomains = 1;
1537 }
1538#endif
1539 }
1540
1541 if (channel->nsort == -1) {
1542 channel->sortlist = NULL;
1543 channel->nsort = 0;
1544 }
1545
1546 if (!channel->lookups) {
1547 channel->lookups = ares_strdup("fb");
1548 if (!channel->lookups)
1549 rc = ARES_ENOMEM;
1550 }
1551
1552 error:
1553 if(rc) {
1554 if(channel->servers) {
1555 ares_free(channel->servers);
1556 channel->servers = NULL;
1557 }
1558
1559 if(channel->domains && channel->domains[0])
1560 ares_free(channel->domains[0]);
1561 if(channel->domains) {
1562 ares_free(channel->domains);
1563 channel->domains = NULL;
1564 }
1565
1566 if(channel->lookups) {
1567 ares_free(channel->lookups);
1568 channel->lookups = NULL;
1569 }
1570 }
1571
1572 if(hostname)
1573 ares_free(hostname);
1574
1575 return rc;
1576}
1577
1578#if !defined(WIN32) && !defined(WATT32) && \
1579 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1580static int config_domain(ares_channel channel, char *str)
1581{
1582 char *q;
1583
1584 /* Set a single search domain. */
1585 q = str;
1586 while (*q && !ISSPACE(*q))
1587 q++;
1588 *q = '\0';
1589 return set_search(channel, str);
1590}
1591
1592#if defined(__INTEL_COMPILER) && (__INTEL_COMPILER == 910) && \
1593 defined(__OPTIMIZE__) && defined(__unix__) && defined(__i386__)
1594 /* workaround icc 9.1 optimizer issue */
1595# define vqualifier volatile
1596#else
1597# define vqualifier
1598#endif
1599
1600static int config_lookup(ares_channel channel, const char *str,
1601 const char *bindch, const char *altbindch,
1602 const char *filech)
1603{
1604 char lookups[3], *l;
1605 const char *vqualifier p;
1606
1607 if (altbindch == NULL)
1608 altbindch = bindch;
1609
1610 /* Set the lookup order. Only the first letter of each work
1611 * is relevant, and it has to be "b" for DNS or "f" for the
1612 * host file. Ignore everything else.
1613 */
1614 l = lookups;
1615 p = str;
1616 while (*p)
1617 {
1618 if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
1619 if (*p == *bindch || *p == *altbindch) *l++ = 'b';
1620 else *l++ = 'f';
1621 }
1622 while (*p && !ISSPACE(*p) && (*p != ','))
1623 p++;
1624 while (*p && (ISSPACE(*p) || (*p == ',')))
1625 p++;
1626 }
1627 *l = '\0';
1628 channel->lookups = ares_strdup(lookups);
1629 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1630}
1631#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
1632
1633#ifndef WATT32
1634static int config_nameserver(struct server_state **servers, int *nservers,
1635 char *str)
1636{
1637 struct ares_addr host;
1638 struct server_state *newserv;
1639 char *p, *txtaddr;
1640 /* On Windows, there may be more than one nameserver specified in the same
1641 * registry key, so we parse input as a space or comma seperated list.
1642 */
1643 for (p = str; p;)
1644 {
1645 /* Skip whitespace and commas. */
1646 while (*p && (ISSPACE(*p) || (*p == ',')))
1647 p++;
1648 if (!*p)
1649 /* No more input, done. */
1650 break;
1651
1652 /* Pointer to start of IPv4 or IPv6 address part. */
1653 txtaddr = p;
1654
1655 /* Advance past this address. */
1656 while (*p && !ISSPACE(*p) && (*p != ','))
1657 p++;
1658 if (*p)
1659 /* Null terminate this address. */
1660 *p++ = '\0';
1661 else
1662 /* Reached end of input, done when this address is processed. */
1663 p = NULL;
1664
1665 /* Convert textual address to binary format. */
1666 if (ares_inet_pton(AF_INET, txtaddr, &host.addrV4) == 1)
1667 host.family = AF_INET;
1668 else if (ares_inet_pton(AF_INET6, txtaddr, &host.addrV6) == 1)
1669 host.family = AF_INET6;
1670 else
1671 continue;
1672
1673 /* Resize servers state array. */
1674 newserv = ares_realloc(*servers, (*nservers + 1) *
1675 sizeof(struct server_state));
1676 if (!newserv)
1677 return ARES_ENOMEM;
1678
1679 /* Store address data. */
1680 newserv[*nservers].addr.family = host.family;
1681 newserv[*nservers].addr.udp_port = 0;
1682 newserv[*nservers].addr.tcp_port = 0;
1683 if (host.family == AF_INET)
1684 memcpy(&newserv[*nservers].addr.addrV4, &host.addrV4,
1685 sizeof(host.addrV4));
1686 else
1687 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1688 sizeof(host.addrV6));
1689
1690 /* Update arguments. */
1691 *servers = newserv;
1692 *nservers += 1;
1693 }
1694
1695 return ARES_SUCCESS;
1696}
1697#endif /* !WATT32 */
1698
1699static int config_sortlist(struct apattern **sortlist, int *nsort,
1700 const char *str)
1701{
1702 struct apattern pat;
1703 const char *q;
1704
1705 /* Add sortlist entries. */
1706 while (*str && *str != ';')
1707 {
1708 int bits;
1709 char ipbuf[16], ipbufpfx[32];
1710 /* Find just the IP */
1711 q = str;
1712 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1713 q++;
1714 memcpy(ipbuf, str, q-str);
1715 ipbuf[q-str] = '\0';
1716 /* Find the prefix */
1717 if (*q == '/')
1718 {
1719 const char *str2 = q+1;
1720 while (*q && *q != ';' && !ISSPACE(*q))
1721 q++;
1722 memcpy(ipbufpfx, str, q-str);
1723 ipbufpfx[q-str] = '\0';
1724 str = str2;
1725 }
1726 else
1727 ipbufpfx[0] = '\0';
1728 /* Lets see if it is CIDR */
1729 /* First we'll try IPv6 */
1730 if ((bits = ares_inet_net_pton(AF_INET6, ipbufpfx[0] ? ipbufpfx : ipbuf,
1731 &pat.addrV6,
1732 sizeof(pat.addrV6))) > 0)
1733 {
1734 pat.type = PATTERN_CIDR;
1735 pat.mask.bits = (unsigned short)bits;
1736 pat.family = AF_INET6;
1737 if (!sortlist_alloc(sortlist, nsort, &pat)) {
1738 ares_free(*sortlist);
1739 *sortlist = NULL;
1740 return ARES_ENOMEM;
1741 }
1742 }
1743 else if (ipbufpfx[0] &&
1744 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1745 sizeof(pat.addrV4))) > 0)
1746 {
1747 pat.type = PATTERN_CIDR;
1748 pat.mask.bits = (unsigned short)bits;
1749 pat.family = AF_INET;
1750 if (!sortlist_alloc(sortlist, nsort, &pat)) {
1751 ares_free(*sortlist);
1752 *sortlist = NULL;
1753 return ARES_ENOMEM;
1754 }
1755 }
1756 /* See if it is just a regular IP */
1757 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1758 {
1759 if (ipbufpfx[0])
1760 {
1761 memcpy(ipbuf, str, q-str);
1762 ipbuf[q-str] = '\0';
1763 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1764 natural_mask(&pat);
1765 }
1766 else
1767 natural_mask(&pat);
1768 pat.family = AF_INET;
1769 pat.type = PATTERN_MASK;
1770 if (!sortlist_alloc(sortlist, nsort, &pat)) {
1771 ares_free(*sortlist);
1772 *sortlist = NULL;
1773 return ARES_ENOMEM;
1774 }
1775 }
1776 else
1777 {
1778 while (*q && *q != ';' && !ISSPACE(*q))
1779 q++;
1780 }
1781 str = q;
1782 while (ISSPACE(*str))
1783 str++;
1784 }
1785
1786 return ARES_SUCCESS;
1787}
1788
1789static int set_search(ares_channel channel, const char *str)
1790{
1791 int n;
1792 const char *p, *q;
1793
1794 if(channel->ndomains != -1) {
1795 /* LCOV_EXCL_START: all callers check ndomains == -1 */
1796 /* if we already have some domains present, free them first */
1797 for(n=0; n < channel->ndomains; n++)
1798 ares_free(channel->domains[n]);
1799 ares_free(channel->domains);
1800 channel->domains = NULL;
1801 channel->ndomains = -1;
1802 } /* LCOV_EXCL_STOP */
1803
1804 /* Count the domains given. */
1805 n = 0;
1806 p = str;
1807 while (*p)
1808 {
1809 while (*p && !ISSPACE(*p))
1810 p++;
1811 while (ISSPACE(*p))
1812 p++;
1813 n++;
1814 }
1815
1816 if (!n)
1817 {
1818 channel->ndomains = 0;
1819 return ARES_SUCCESS;
1820 }
1821
1822 channel->domains = ares_malloc(n * sizeof(char *));
1823 if (!channel->domains)
1824 return ARES_ENOMEM;
1825
1826 /* Now copy the domains. */
1827 n = 0;
1828 p = str;
1829 while (*p)
1830 {
1831 channel->ndomains = n;
1832 q = p;
1833 while (*q && !ISSPACE(*q))
1834 q++;
1835 channel->domains[n] = ares_malloc(q - p + 1);
1836 if (!channel->domains[n])
1837 return ARES_ENOMEM;
1838 memcpy(channel->domains[n], p, q - p);
1839 channel->domains[n][q - p] = 0;
1840 p = q;
1841 while (ISSPACE(*p))
1842 p++;
1843 n++;
1844 }
1845 channel->ndomains = n;
1846
1847 return ARES_SUCCESS;
1848}
1849
1850static int set_options(ares_channel channel, const char *str)
1851{
1852 const char *p, *q, *val;
1853
1854 p = str;
1855 while (*p)
1856 {
1857 q = p;
1858 while (*q && !ISSPACE(*q))
1859 q++;
1860 val = try_option(p, q, "ndots:");
1861 if (val && channel->ndots == -1)
1862 channel->ndots = aresx_sltosi(strtol(val, NULL, 10));
1863 val = try_option(p, q, "retrans:");
1864 if (val && channel->timeout == -1)
1865 channel->timeout = aresx_sltosi(strtol(val, NULL, 10));
1866 val = try_option(p, q, "retry:");
1867 if (val && channel->tries == -1)
1868 channel->tries = aresx_sltosi(strtol(val, NULL, 10));
1869 val = try_option(p, q, "rotate");
1870 if (val && channel->rotate == -1)
1871 channel->rotate = 1;
1872 p = q;
1873 while (ISSPACE(*p))
1874 p++;
1875 }
1876
1877 return ARES_SUCCESS;
1878}
1879
1880static const char *try_option(const char *p, const char *q, const char *opt)
1881{
1882 size_t len = strlen(opt);
1883 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1884}
1885
1886#if !defined(WIN32) && !defined(WATT32) && \
1887 !defined(ANDROID) && !defined(__ANDROID__) && !defined(CARES_USE_LIBRESOLV)
1888static char *try_config(char *s, const char *opt, char scc)
1889{
1890 size_t len;
1891 char *p;
1892 char *q;
1893
1894 if (!s || !opt)
1895 /* no line or no option */
1896 return NULL; /* LCOV_EXCL_LINE */
1897
1898 /* Hash '#' character is always used as primary comment char, additionally
1899 a not-NUL secondary comment char will be considered when specified. */
1900
1901 /* trim line comment */
1902 p = s;
1903 if(scc)
1904 while (*p && (*p != '#') && (*p != scc))
1905 p++;
1906 else
1907 while (*p && (*p != '#'))
1908 p++;
1909 *p = '\0';
1910
1911 /* trim trailing whitespace */
1912 q = p - 1;
1913 while ((q >= s) && ISSPACE(*q))
1914 q--;
1915 *++q = '\0';
1916
1917 /* skip leading whitespace */
1918 p = s;
1919 while (*p && ISSPACE(*p))
1920 p++;
1921
1922 if (!*p)
1923 /* empty line */
1924 return NULL;
1925
1926 if ((len = strlen(opt)) == 0)
1927 /* empty option */
1928 return NULL; /* LCOV_EXCL_LINE */
1929
1930 if (strncmp(p, opt, len) != 0)
1931 /* line and option do not match */
1932 return NULL;
1933
1934 /* skip over given option name */
1935 p += len;
1936
1937 if (!*p)
1938 /* no option value */
1939 return NULL; /* LCOV_EXCL_LINE */
1940
1941 if ((opt[len-1] != ':') && (opt[len-1] != '=') && !ISSPACE(*p))
1942 /* whitespace between option name and value is mandatory
1943 for given option names which do not end with ':' or '=' */
1944 return NULL;
1945
1946 /* skip over whitespace */
1947 while (*p && ISSPACE(*p))
1948 p++;
1949
1950 if (!*p)
1951 /* no option value */
1952 return NULL;
1953
1954 /* return pointer to option value */
1955 return p;
1956}
1957#endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1958
1959static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1960{
1961
1962 /* Four octets and three periods yields at most 15 characters. */
1963 if (len > 15)
1964 return -1;
1965
1966 addr->s_addr = inet_addr(ipbuf);
1967 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1968 return -1;
1969 return 0;
1970}
1971
1972static void natural_mask(struct apattern *pat)
1973{
1974 struct in_addr addr;
1975
1976 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1977 * but portable.
1978 */
1979 addr.s_addr = ntohl(pat->addrV4.s_addr);
1980
1981 /* This is out of date in the CIDR world, but some people might
1982 * still rely on it.
1983 */
1984 if (IN_CLASSA(addr.s_addr))
1985 pat->mask.addr4.s_addr = htonl(IN_CLASSA_NET);
1986 else if (IN_CLASSB(addr.s_addr))
1987 pat->mask.addr4.s_addr = htonl(IN_CLASSB_NET);
1988 else
1989 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1990}
1991
1992static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1993 struct apattern *pat)
1994{
1995 struct apattern *newsort;
1996 newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1997 if (!newsort)
1998 return 0;
1999 newsort[*nsort] = *pat;
2000 *sortlist = newsort;
2001 (*nsort)++;
2002 return 1;
2003}
2004
2005/* initialize an rc4 key. If possible a cryptographically secure random key
2006 is generated using a suitable function (for example win32's RtlGenRandom as
2007 described in
2008 http://blogs.msdn.com/michael_howard/archive/2005/01/14/353379.aspx
2009 otherwise the code defaults to cross-platform albeit less secure mechanism
2010 using rand
2011*/
2012static void randomize_key(unsigned char* key,int key_data_len)
2013{
2014 int randomized = 0;
2015 int counter=0;
2016#ifdef WIN32
2017 BOOLEAN res;
2018 if (ares_fpSystemFunction036)
2019 {
2020 res = (*ares_fpSystemFunction036) (key, key_data_len);
2021 if (res)
2022 randomized = 1;
2023 }
2024#else /* !WIN32 */
2025#ifdef RANDOM_FILE
2026 FILE *f = fopen(RANDOM_FILE, "rb");
2027 if(f) {
2028 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2029 fclose(f);
2030 }
2031#endif
2032#endif /* WIN32 */
2033
2034 if (!randomized) {
2035 for (;counter<key_data_len;counter++)
2036 key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2037 }
2038}
2039
2040static int init_id_key(rc4_key* key,int key_data_len)
2041{
2042 unsigned char index1;
2043 unsigned char index2;
2044 unsigned char* state;
2045 short counter;
2046 unsigned char *key_data_ptr = 0;
2047
2048 key_data_ptr = ares_malloc(key_data_len);
2049 if (!key_data_ptr)
2050 return ARES_ENOMEM;
2051 memset(key_data_ptr, 0, key_data_len);
2052
2053 state = &key->state[0];
2054 for(counter = 0; counter < 256; counter++)
2055 /* unnecessary AND but it keeps some compilers happier */
2056 state[counter] = (unsigned char)(counter & 0xff);
2057 randomize_key(key->state,key_data_len);
2058 key->x = 0;
2059 key->y = 0;
2060 index1 = 0;
2061 index2 = 0;
2062 for(counter = 0; counter < 256; counter++)
2063 {
2064 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2065 index2) % 256);
2066 ARES_SWAP_BYTE(&state[counter], &state[index2]);
2067
2068 index1 = (unsigned char)((index1 + 1) % key_data_len);
2069 }
2070 ares_free(key_data_ptr);
2071 return ARES_SUCCESS;
2072}
2073
2074void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2075{
2076 channel->local_ip4 = local_ip;
2077}
2078
2079/* local_ip6 should be 16 bytes in length */
2080void ares_set_local_ip6(ares_channel channel,
2081 const unsigned char* local_ip6)
2082{
2083 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2084}
2085
2086/* local_dev_name should be null terminated. */
2087void ares_set_local_dev(ares_channel channel,
2088 const char* local_dev_name)
2089{
2090 strncpy(channel->local_dev_name, local_dev_name,
2091 sizeof(channel->local_dev_name));
2092 channel->local_dev_name[sizeof(channel->local_dev_name) - 1] = 0;
2093}
2094
2095
2096void ares_set_socket_callback(ares_channel channel,
2097 ares_sock_create_callback cb,
2098 void *data)
2099{
2100 channel->sock_create_cb = cb;
2101 channel->sock_create_cb_data = data;
2102}
2103
2104void ares_set_socket_configure_callback(ares_channel channel,
2105 ares_sock_config_callback cb,
2106 void *data)
2107{
2108 channel->sock_config_cb = cb;
2109 channel->sock_config_cb_data = data;
2110}
2111
2112int ares_set_sortlist(ares_channel channel, const char *sortstr)
2113{
2114 int nsort = 0;
2115 struct apattern *sortlist = NULL;
2116 int status;
2117
2118 if (!channel)
2119 return ARES_ENODATA;
2120
2121 status = config_sortlist(&sortlist, &nsort, sortstr);
2122 if (status == ARES_SUCCESS && sortlist) {
2123 if (channel->sortlist)
2124 ares_free(channel->sortlist);
2125 channel->sortlist = sortlist;
2126 channel->nsort = nsort;
2127 }
2128 return status;
2129}
2130
2131void ares__init_servers_state(ares_channel channel)
2132{
2133 struct server_state *server;
2134 int i;
2135
2136 for (i = 0; i < channel->nservers; i++)
2137 {
2138 server = &channel->servers[i];
2139 server->udp_socket = ARES_SOCKET_BAD;
2140 server->tcp_socket = ARES_SOCKET_BAD;
2141 server->tcp_connection_generation = ++channel->tcp_connection_generation;
2142 server->tcp_lenbuf_pos = 0;
2143 server->tcp_buffer_pos = 0;
2144 server->tcp_buffer = NULL;
2145 server->tcp_length = 0;
2146 server->qhead = NULL;
2147 server->qtail = NULL;
2148 ares__init_list_head(&server->queries_to_server);
2149 server->channel = channel;
2150 server->is_broken = 0;
2151 }
2152}