]> git.proxmox.com Git - ceph.git/blob - ceph/src/c-ares/ares_init.c
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / c-ares / ares_init.c
1
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
67 static int init_by_options(ares_channel channel,
68 const struct ares_options *options,
69 int optmask);
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);
73
74 #ifndef WATT32
75 static int config_nameserver(struct server_state **servers, int *nservers,
76 char *str);
77 #endif
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);
82
83 static int config_sortlist(struct apattern **sortlist, int *nsort,
84 const char *str);
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,
94 const char *filech);
95 static 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
104 int ares_init(ares_channel *channelptr)
105 {
106 return ares_init_options(channelptr, NULL, 0);
107 }
108
109 int ares_init_options(ares_channel *channelptr, struct ares_options *options,
110 int optmask)
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 channel->sock_funcs = NULL;
170 channel->sock_func_cb_data = NULL;
171
172 channel->last_server = 0;
173 channel->last_timeout_processed = (time_t)now.tv_sec;
174
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));
178
179 /* Initialize our lists of queries */
180 ares__init_list_head(&(channel->all_queries));
181 for (i = 0; i < ARES_QID_TABLE_SIZE; i++)
182 {
183 ares__init_list_head(&(channel->queries_by_qid[i]));
184 }
185 for (i = 0; i < ARES_TIMEOUT_TABLE_SIZE; i++)
186 {
187 ares__init_list_head(&(channel->queries_by_timeout[i]));
188 }
189
190 /* Initialize configuration by each of the four sources, from highest
191 * precedence to lowest.
192 */
193
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 */
199 goto done;
200 }
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)));
210 }
211
212 /*
213 * No matter what failed or succeeded, seed defaults to provide
214 * useful behavior for things that we missed.
215 */
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)));
220
221 /* Generate random key */
222
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);
227 else
228 DEBUGF(fprintf(stderr, "Error: init_id_key failed: %s\n",
229 ares_strerror(status)));
230 }
231
232 done:
233 if (status != ARES_SUCCESS)
234 {
235 /* Something failed; clean up memory we may have allocated. */
236 if (channel->servers)
237 ares_free(channel->servers);
238 if (channel->domains)
239 {
240 for (i = 0; i < channel->ndomains; i++)
241 ares_free(channel->domains[i]);
242 ares_free(channel->domains);
243 }
244 if (channel->sortlist)
245 ares_free(channel->sortlist);
246 if(channel->lookups)
247 ares_free(channel->lookups);
248 ares_free(channel);
249 return status;
250 }
251
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;
255
256 ares__init_servers_state(channel);
257
258 *channelptr = channel;
259 return ARES_SUCCESS;
260 }
261
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)
265 {
266 struct ares_options opts;
267 struct ares_addr_port_node *servers;
268 int non_v4_default_port = 0;
269 int i, rc;
270 int optmask;
271
272 *dest = NULL; /* in case of failure return NULL explicitly */
273
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);
277 if(rc)
278 {
279 ares_destroy_options(&opts);
280 return rc;
281 }
282
283 /* Then create the new channel with those options */
284 rc = ares_init_options(dest, &opts, optmask);
285
286 /* destroy the options copy to not leak any memory */
287 ares_destroy_options(&opts);
288
289 if(rc)
290 return rc;
291
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;
299
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));
304
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++)
307 {
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++;
312 break;
313 }
314 }
315 if (non_v4_default_port) {
316 rc = ares_get_servers_ports(src, &servers);
317 if (rc != ARES_SUCCESS) {
318 ares_destroy(*dest);
319 *dest = NULL;
320 return rc;
321 }
322 rc = ares_set_servers_ports(*dest, servers);
323 ares_free_data(servers);
324 if (rc != ARES_SUCCESS) {
325 ares_destroy(*dest);
326 *dest = NULL;
327 return rc;
328 }
329 }
330
331 return ARES_SUCCESS; /* everything went fine */
332 }
333
334 /* Save options from initialized channel */
335 int ares_save_options(ares_channel channel, struct ares_options *options,
336 int *optmask)
337 {
338 int i, j;
339 int ipv4_nservers = 0;
340
341 /* Zero everything out */
342 memset(options, 0, sizeof(struct ares_options));
343
344 if (!ARES_CONFIG_CHECK(channel))
345 return ARES_ENODATA;
346
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);
355
356 /* Copy easy stuff */
357 options->flags = channel->flags;
358
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;
368
369 /* Copy IPv4 servers that use the default port */
370 if (channel->nservers) {
371 for (i = 0; i < channel->nservers; i++)
372 {
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))
376 ipv4_nservers++;
377 }
378 if (ipv4_nservers) {
379 options->servers = ares_malloc(ipv4_nservers * sizeof(struct in_addr));
380 if (!options->servers)
381 return ARES_ENOMEM;
382 for (i = j = 0; i < channel->nservers; i++)
383 {
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));
390 }
391 }
392 }
393 options->nservers = ipv4_nservers;
394
395 /* copy domains */
396 if (channel->ndomains) {
397 options->domains = ares_malloc(channel->ndomains * sizeof(char *));
398 if (!options->domains)
399 return ARES_ENOMEM;
400
401 for (i = 0; i < channel->ndomains; i++)
402 {
403 options->ndomains = i;
404 options->domains[i] = ares_strdup(channel->domains[i]);
405 if (!options->domains[i])
406 return ARES_ENOMEM;
407 }
408 }
409 options->ndomains = channel->ndomains;
410
411 /* copy lookups */
412 if (channel->lookups) {
413 options->lookups = ares_strdup(channel->lookups);
414 if (!options->lookups && channel->lookups)
415 return ARES_ENOMEM;
416 }
417
418 /* copy sortlist */
419 if (channel->nsort) {
420 options->sortlist = ares_malloc(channel->nsort * sizeof(struct apattern));
421 if (!options->sortlist)
422 return ARES_ENOMEM;
423 for (i = 0; i < channel->nsort; i++)
424 options->sortlist[i] = channel->sortlist[i];
425 }
426 options->nsort = channel->nsort;
427
428 return ARES_SUCCESS;
429 }
430
431 static int init_by_options(ares_channel channel,
432 const struct ares_options *options,
433 int optmask)
434 {
435 int i;
436
437 /* Easy stuff. */
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)
449 channel->rotate = 1;
450 if ((optmask & ARES_OPT_NOROTATE) && channel->rotate == -1)
451 channel->rotate = 0;
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)
457 {
458 channel->sock_state_cb = options->sock_state_cb;
459 channel->sock_state_cb_data = options->sock_state_cb_data;
460 }
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;
467
468 if ((optmask & ARES_OPT_EDNSPSZ) && channel->ednspsz == -1)
469 channel->ednspsz = options->ednspsz;
470
471 /* Copy the IPv4 servers, if given. */
472 if ((optmask & ARES_OPT_SERVERS) && channel->nservers == -1)
473 {
474 /* Avoid zero size allocations at any cost */
475 if (options->nservers > 0)
476 {
477 channel->servers =
478 ares_malloc(options->nservers * sizeof(struct server_state));
479 if (!channel->servers)
480 return ARES_ENOMEM;
481 for (i = 0; i < options->nservers; i++)
482 {
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));
489 }
490 }
491 channel->nservers = options->nservers;
492 }
493
494 /* Copy the domains, if given. Keep channel->ndomains consistent so
495 * we can clean up in case of error.
496 */
497 if ((optmask & ARES_OPT_DOMAINS) && channel->ndomains == -1)
498 {
499 /* Avoid zero size allocations at any cost */
500 if (options->ndomains > 0)
501 {
502 channel->domains = ares_malloc(options->ndomains * sizeof(char *));
503 if (!channel->domains)
504 return ARES_ENOMEM;
505 for (i = 0; i < options->ndomains; i++)
506 {
507 channel->ndomains = i;
508 channel->domains[i] = ares_strdup(options->domains[i]);
509 if (!channel->domains[i])
510 return ARES_ENOMEM;
511 }
512 }
513 channel->ndomains = options->ndomains;
514 }
515
516 /* Set lookups, if given. */
517 if ((optmask & ARES_OPT_LOOKUPS) && !channel->lookups)
518 {
519 channel->lookups = ares_strdup(options->lookups);
520 if (!channel->lookups)
521 return ARES_ENOMEM;
522 }
523
524 /* copy sortlist */
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)
529 return ARES_ENOMEM;
530 for (i = 0; i < options->nsort; i++)
531 channel->sortlist[i] = options->sortlist[i];
532 }
533 channel->nsort = options->nsort;
534 }
535
536 channel->optmask = optmask;
537
538 return ARES_SUCCESS;
539 }
540
541 static int init_by_environment(ares_channel channel)
542 {
543 const char *localdomain, *res_options;
544 int status;
545
546 localdomain = getenv("LOCALDOMAIN");
547 if (localdomain && channel->ndomains == -1)
548 {
549 status = set_search(channel, localdomain);
550 if (status != ARES_SUCCESS)
551 return status;
552 }
553
554 res_options = getenv("RES_OPTIONS");
555 if (res_options)
556 {
557 status = set_options(channel, res_options);
558 if (status != ARES_SUCCESS)
559 return status; /* LCOV_EXCL_LINE: set_options() never fails */
560 }
561
562 return ARES_SUCCESS;
563 }
564
565 #ifdef WIN32
566 /*
567 * get_REG_SZ()
568 *
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.
573 *
574 * Returns 0 and nullifies *outptr upon inability to return a string value.
575 *
576 * Returns 1 and sets *outptr when returning a dynamically allocated string.
577 *
578 * Supported on Windows NT 3.5 and newer.
579 */
580 static int get_REG_SZ(HKEY hKey, const char *leafKeyName, char **outptr)
581 {
582 DWORD size = 0;
583 int res;
584
585 *outptr = NULL;
586
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)
590 return 0;
591
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);
595 if (!*outptr)
596 return 0;
597
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))
602 {
603 ares_free(*outptr);
604 *outptr = NULL;
605 return 0;
606 }
607
608 /* Null terminate buffer allways */
609 *(*outptr + size) = '\0';
610
611 return 1;
612 }
613
614 /*
615 * get_REG_SZ_9X()
616 *
617 * Functionally identical to get_REG_SZ()
618 *
619 * Supported on Windows 95, 98 and ME.
620 */
621 static int get_REG_SZ_9X(HKEY hKey, const char *leafKeyName, char **outptr)
622 {
623 DWORD dataType = 0;
624 DWORD size = 0;
625 int res;
626
627 *outptr = NULL;
628
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)
632 return 0;
633
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);
637 if (!*outptr)
638 return 0;
639
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))
644 {
645 ares_free(*outptr);
646 *outptr = NULL;
647 return 0;
648 }
649
650 /* Null terminate buffer allways */
651 *(*outptr + size) = '\0';
652
653 return 1;
654 }
655
656 /*
657 * get_enum_REG_SZ()
658 *
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.
664 *
665 * Returns 0 and nullifies *outptr upon inability to return a string value.
666 *
667 * Returns 1 and sets *outptr when returning a dynamically allocated string.
668 *
669 * Supported on Windows NT 3.5 and newer.
670 */
671 static int get_enum_REG_SZ(HKEY hKeyParent, const char *leafKeyName,
672 char **outptr)
673 {
674 char enumKeyName[256];
675 DWORD enumKeyNameBuffSize;
676 DWORD enumKeyIdx = 0;
677 HKEY hKeyEnum;
678 int gotString;
679 int res;
680
681 *outptr = NULL;
682
683 for(;;)
684 {
685 enumKeyNameBuffSize = sizeof(enumKeyName);
686 res = RegEnumKeyEx(hKeyParent, enumKeyIdx++, enumKeyName,
687 &enumKeyNameBuffSize, 0, NULL, NULL, NULL);
688 if (res != ERROR_SUCCESS)
689 break;
690 res = RegOpenKeyEx(hKeyParent, enumKeyName, 0, KEY_QUERY_VALUE,
691 &hKeyEnum);
692 if (res != ERROR_SUCCESS)
693 continue;
694 gotString = get_REG_SZ(hKeyEnum, leafKeyName, outptr);
695 RegCloseKey(hKeyEnum);
696 if (gotString)
697 break;
698 }
699
700 if (!*outptr)
701 return 0;
702
703 return 1;
704 }
705
706 /*
707 * get_DNS_Registry_9X()
708 *
709 * Functionally identical to get_DNS_Registry()
710 *
711 * Implementation supports Windows 95, 98 and ME.
712 */
713 static int get_DNS_Registry_9X(char **outptr)
714 {
715 HKEY hKey_VxD_MStcp;
716 int gotString;
717 int res;
718
719 *outptr = NULL;
720
721 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_9X, 0, KEY_READ,
722 &hKey_VxD_MStcp);
723 if (res != ERROR_SUCCESS)
724 return 0;
725
726 gotString = get_REG_SZ_9X(hKey_VxD_MStcp, NAMESERVER, outptr);
727 RegCloseKey(hKey_VxD_MStcp);
728
729 if (!gotString || !*outptr)
730 return 0;
731
732 return 1;
733 }
734
735 /*
736 * get_DNS_Registry_NT()
737 *
738 * Functionally identical to get_DNS_Registry()
739 *
740 * Refs: Microsoft Knowledge Base articles KB120642 and KB314053.
741 *
742 * Implementation supports Windows NT 3.5 and newer.
743 */
744 static int get_DNS_Registry_NT(char **outptr)
745 {
746 HKEY hKey_Interfaces = NULL;
747 HKEY hKey_Tcpip_Parameters;
748 int gotString;
749 int res;
750
751 *outptr = NULL;
752
753 res = RegOpenKeyEx(HKEY_LOCAL_MACHINE, WIN_NS_NT_KEY, 0, KEY_READ,
754 &hKey_Tcpip_Parameters);
755 if (res != ERROR_SUCCESS)
756 return 0;
757
758 /*
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.
762 */
763
764 /* Global DNS static parameters */
765 gotString = get_REG_SZ(hKey_Tcpip_Parameters, NAMESERVER, outptr);
766 if (gotString)
767 goto done;
768
769 /* Global DNS DHCP-configured parameters */
770 gotString = get_REG_SZ(hKey_Tcpip_Parameters, DHCPNAMESERVER, outptr);
771 if (gotString)
772 goto done;
773
774 /* Try adapter specific parameters */
775 res = RegOpenKeyEx(hKey_Tcpip_Parameters, "Interfaces", 0,
776 KEY_QUERY_VALUE | KEY_ENUMERATE_SUB_KEYS,
777 &hKey_Interfaces);
778 if (res != ERROR_SUCCESS)
779 {
780 hKey_Interfaces = NULL;
781 goto done;
782 }
783
784 /* Adapter specific DNS static parameters */
785 gotString = get_enum_REG_SZ(hKey_Interfaces, NAMESERVER, outptr);
786 if (gotString)
787 goto done;
788
789 /* Adapter specific DNS DHCP-configured parameters */
790 gotString = get_enum_REG_SZ(hKey_Interfaces, DHCPNAMESERVER, outptr);
791
792 done:
793 if (hKey_Interfaces)
794 RegCloseKey(hKey_Interfaces);
795
796 RegCloseKey(hKey_Tcpip_Parameters);
797
798 if (!gotString || !*outptr)
799 return 0;
800
801 return 1;
802 }
803
804 /*
805 * get_DNS_Registry()
806 *
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.
810 *
811 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
812 *
813 * Returns 1 and sets *outptr when returning a dynamically allocated string.
814 */
815 static int get_DNS_Registry(char **outptr)
816 {
817 win_platform platform;
818 int gotString = 0;
819
820 *outptr = NULL;
821
822 platform = ares__getplatform();
823
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);
828
829 if (!gotString)
830 return 0;
831
832 return 1;
833 }
834
835 /*
836 * commajoin()
837 *
838 * RTF code.
839 */
840 static void commajoin(char **dst, const char *src)
841 {
842 char *tmp;
843
844 if (*dst)
845 {
846 tmp = ares_malloc(strlen(*dst) + strlen(src) + 2);
847 if (!tmp)
848 return;
849 sprintf(tmp, "%s,%s", *dst, src);
850 ares_free(*dst);
851 *dst = tmp;
852 }
853 else
854 {
855 *dst = ares_malloc(strlen(src) + 1);
856 if (!*dst)
857 return;
858 strcpy(*dst, src);
859 }
860 }
861
862 /*
863 * get_DNS_NetworkParams()
864 *
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.
869 *
870 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
871 *
872 * Returns 1 and sets *outptr when returning a dynamically allocated string.
873 *
874 * Implementation supports Windows 98 and newer.
875 *
876 * Note: Ancient PSDK required in order to build a W98 target.
877 */
878 static int get_DNS_NetworkParams(char **outptr)
879 {
880 FIXED_INFO *fi, *newfi;
881 struct ares_addr namesrvr;
882 char *txtaddr;
883 IP_ADDR_STRING *ipAddr;
884 int res;
885 DWORD size = sizeof (*fi);
886
887 *outptr = NULL;
888
889 /* Verify run-time availability of GetNetworkParams() */
890 if (ares_fpGetNetworkParams == ZERO_NULL)
891 return 0;
892
893 fi = ares_malloc(size);
894 if (!fi)
895 return 0;
896
897 res = (*ares_fpGetNetworkParams) (fi, &size);
898 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
899 goto done;
900
901 newfi = ares_realloc(fi, size);
902 if (!newfi)
903 goto done;
904
905 fi = newfi;
906 res = (*ares_fpGetNetworkParams) (fi, &size);
907 if (res != ERROR_SUCCESS)
908 goto done;
909
910 for (ipAddr = &fi->DnsServerList; ipAddr; ipAddr = ipAddr->Next)
911 {
912 txtaddr = &ipAddr->IpAddress.String[0];
913
914 /* Validate converting textual address to binary format. */
915 if (ares_inet_pton(AF_INET, txtaddr, &namesrvr.addrV4) == 1)
916 {
917 if ((namesrvr.addrV4.S_un.S_addr == INADDR_ANY) ||
918 (namesrvr.addrV4.S_un.S_addr == INADDR_NONE))
919 continue;
920 }
921 else if (ares_inet_pton(AF_INET6, txtaddr, &namesrvr.addrV6) == 1)
922 {
923 if (memcmp(&namesrvr.addrV6, &ares_in6addr_any,
924 sizeof(namesrvr.addrV6)) == 0)
925 continue;
926 }
927 else
928 continue;
929
930 commajoin(outptr, txtaddr);
931
932 if (!*outptr)
933 break;
934 }
935
936 done:
937 if (fi)
938 ares_free(fi);
939
940 if (!*outptr)
941 return 0;
942
943 return 1;
944 }
945
946 /*
947 * get_DNS_AdaptersAddresses()
948 *
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.
953 *
954 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
955 *
956 * Returns 1 and sets *outptr when returning a dynamically allocated string.
957 *
958 * Implementation supports Windows XP and newer.
959 */
960 #define IPAA_INITIAL_BUF_SZ 15 * 1024
961 #define IPAA_MAX_TRIES 3
962 static int get_DNS_AdaptersAddresses(char **outptr)
963 {
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;
968 ULONG AddrFlags = 0;
969 int trying = IPAA_MAX_TRIES;
970 int res;
971
972 union {
973 struct sockaddr *sa;
974 struct sockaddr_in *sa4;
975 struct sockaddr_in6 *sa6;
976 } namesrvr;
977
978 char txtaddr[sizeof("ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255")];
979
980 *outptr = NULL;
981
982 /* Verify run-time availability of GetAdaptersAddresses() */
983 if (ares_fpGetAdaptersAddresses == ZERO_NULL)
984 return 0;
985
986 ipaa = ares_malloc(Bufsz);
987 if (!ipaa)
988 return 0;
989
990 /* Usually this call suceeds with initial buffer size */
991 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
992 ipaa, &ReqBufsz);
993 if ((res != ERROR_BUFFER_OVERFLOW) && (res != ERROR_SUCCESS))
994 goto done;
995
996 while ((res == ERROR_BUFFER_OVERFLOW) && (--trying))
997 {
998 if (Bufsz < ReqBufsz)
999 {
1000 newipaa = ares_realloc(ipaa, ReqBufsz);
1001 if (!newipaa)
1002 goto done;
1003 Bufsz = ReqBufsz;
1004 ipaa = newipaa;
1005 }
1006 res = (*ares_fpGetAdaptersAddresses) (AF_UNSPEC, AddrFlags, NULL,
1007 ipaa, &ReqBufsz);
1008 if (res == ERROR_SUCCESS)
1009 break;
1010 }
1011 if (res != ERROR_SUCCESS)
1012 goto done;
1013
1014 for (ipaaEntry = ipaa; ipaaEntry; ipaaEntry = ipaaEntry->Next)
1015 {
1016 if(ipaaEntry->OperStatus != IfOperStatusUp)
1017 continue;
1018
1019 for (ipaDNSAddr = ipaaEntry->FirstDnsServerAddress;
1020 ipaDNSAddr;
1021 ipaDNSAddr = ipaDNSAddr->Next)
1022 {
1023 namesrvr.sa = ipaDNSAddr->Address.lpSockaddr;
1024
1025 if (namesrvr.sa->sa_family == AF_INET)
1026 {
1027 if ((namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_ANY) ||
1028 (namesrvr.sa4->sin_addr.S_un.S_addr == INADDR_NONE))
1029 continue;
1030 if (! ares_inet_ntop(AF_INET, &namesrvr.sa4->sin_addr,
1031 txtaddr, sizeof(txtaddr)))
1032 continue;
1033 }
1034 else if (namesrvr.sa->sa_family == AF_INET6)
1035 {
1036 if (memcmp(&namesrvr.sa6->sin6_addr, &ares_in6addr_any,
1037 sizeof(namesrvr.sa6->sin6_addr)) == 0)
1038 continue;
1039 if (! ares_inet_ntop(AF_INET6, &namesrvr.sa6->sin6_addr,
1040 txtaddr, sizeof(txtaddr)))
1041 continue;
1042 }
1043 else
1044 continue;
1045
1046 commajoin(outptr, txtaddr);
1047
1048 if (!*outptr)
1049 goto done;
1050 }
1051 }
1052
1053 done:
1054 if (ipaa)
1055 ares_free(ipaa);
1056
1057 if (!*outptr)
1058 return 0;
1059
1060 return 1;
1061 }
1062
1063 /*
1064 * get_DNS_Windows()
1065 *
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.
1070 *
1071 * Returns 0 and nullifies *outptr upon inability to return DNSes string.
1072 *
1073 * Returns 1 and sets *outptr when returning a dynamically allocated string.
1074 *
1075 * Implementation supports Windows 95 and newer.
1076 */
1077 static int get_DNS_Windows(char **outptr)
1078 {
1079 /*
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.
1084 */
1085 /* Try using IP helper API GetNetworkParams() */
1086 if (get_DNS_NetworkParams(outptr))
1087 return 1;
1088
1089 /* Try using IP helper API GetAdaptersAddresses() */
1090 if (get_DNS_AdaptersAddresses(outptr))
1091 return 1;
1092
1093 /* Fall-back to registry information */
1094 return get_DNS_Registry(outptr);
1095 }
1096 #endif
1097
1098 static int init_by_resolv_conf(ares_channel channel)
1099 {
1100 #if !defined(ANDROID) && !defined(__ANDROID__) && !defined(WATT32) && \
1101 !defined(CARES_USE_LIBRESOLV)
1102 char *line = NULL;
1103 #endif
1104 int status = -1, nservers = 0, nsort = 0;
1105 struct server_state *servers = NULL;
1106 struct apattern *sortlist = NULL;
1107
1108 #ifdef WIN32
1109
1110 if (channel->nservers > -1) /* don't override ARES_OPT_SERVER */
1111 return ARES_SUCCESS;
1112
1113 if (get_DNS_Windows(&line))
1114 {
1115 status = config_nameserver(&servers, &nservers, line);
1116 ares_free(line);
1117 }
1118
1119 if (status == ARES_SUCCESS)
1120 status = ARES_EOF;
1121 else
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;
1125
1126 #elif defined(__riscos__)
1127
1128 /* Under RISC OS, name servers are listed in the
1129 system variable Inet$Resolvers, space separated. */
1130
1131 line = getenv("Inet$Resolvers");
1132 status = ARES_EOF;
1133 if (line) {
1134 char *resolvers = ares_strdup(line), *pos, *space;
1135
1136 if (!resolvers)
1137 return ARES_ENOMEM;
1138
1139 pos = resolvers;
1140 do {
1141 space = strchr(pos, ' ');
1142 if (space)
1143 *space = '\0';
1144 status = config_nameserver(&servers, &nservers, pos);
1145 if (status != ARES_SUCCESS)
1146 break;
1147 pos = space + 1;
1148 } while (space);
1149
1150 if (status == ARES_SUCCESS)
1151 status = ARES_EOF;
1152
1153 ares_free(resolvers);
1154 }
1155
1156 #elif defined(WATT32)
1157 int i;
1158
1159 sock_init();
1160 for (i = 0; def_nameservers[i]; i++)
1161 ;
1162 if (i == 0)
1163 return ARES_SUCCESS; /* use localhost DNS server */
1164
1165 nservers = i;
1166 servers = ares_malloc(sizeof(struct server_state));
1167 if (!servers)
1168 return ARES_ENOMEM;
1169 memset(servers, 0, sizeof(struct server_state));
1170
1171 for (i = 0; def_nameservers[i]; i++)
1172 {
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;
1177 }
1178 status = ARES_EOF;
1179
1180 #elif defined(ANDROID) || defined(__ANDROID__)
1181 unsigned int i;
1182 char propname[PROP_NAME_MAX];
1183 char propvalue[PROP_VALUE_MAX]="";
1184
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) {
1188 status = ARES_EOF;
1189 break;
1190 }
1191 status = config_nameserver(&servers, &nservers, propvalue);
1192 if (status != ARES_SUCCESS)
1193 break;
1194 status = ARES_EOF;
1195 }
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)) {
1201 status = ARES_EOF;
1202
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];
1208 int config_status;
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));
1214 } else {
1215 continue;
1216 }
1217
1218 config_status = config_nameserver(&servers, &nservers, str);
1219 if (config_status != ARES_SUCCESS) {
1220 status = config_status;
1221 break;
1222 }
1223 }
1224 }
1225 if (channel->ndomains == -1) {
1226 int entries = 0;
1227 while ((entries < MAXDNSRCH) && res.dnsrch[entries])
1228 entries++;
1229
1230 channel->domains = ares_malloc(entries * sizeof(char *));
1231 if (!channel->domains) {
1232 status = ARES_ENOMEM;
1233 } else {
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;
1239 }
1240 }
1241 }
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;
1250
1251 res_ndestroy(&res);
1252 }
1253 #else
1254 {
1255 char *p;
1256 FILE *fp;
1257 size_t linesize;
1258 int error;
1259 int update_domains;
1260
1261 /* Don't read resolv.conf and friends if we don't have to */
1262 if (ARES_CONFIG_CHECK(channel))
1263 return ARES_SUCCESS;
1264
1265 /* Only update search domains if they're not already specified */
1266 update_domains = (channel->ndomains == -1);
1267
1268 fp = fopen(PATH_RESOLV_CONF, "r");
1269 if (fp) {
1270 while ((status = ares__read_line(fp, &line, &linesize)) == ARES_SUCCESS)
1271 {
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);
1286 else
1287 status = ARES_SUCCESS;
1288 if (status != ARES_SUCCESS)
1289 break;
1290 }
1291 fclose(fp);
1292 }
1293 else {
1294 error = ERRNO;
1295 switch(error) {
1296 case ENOENT:
1297 case ESRCH:
1298 status = ARES_EOF;
1299 break;
1300 default:
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;
1305 }
1306 }
1307
1308 if ((status == ARES_EOF) && (!channel->lookups)) {
1309 /* Many systems (Solaris, Linux, BSD's) use nsswitch.conf */
1310 fp = fopen("/etc/nsswitch.conf", "r");
1311 if (fp) {
1312 while ((status = ares__read_line(fp, &line, &linesize)) ==
1313 ARES_SUCCESS)
1314 {
1315 if ((p = try_config(line, "hosts:", '\0')) && !channel->lookups)
1316 (void)config_lookup(channel, p, "dns", "resolve", "files");
1317 }
1318 fclose(fp);
1319 }
1320 else {
1321 error = ERRNO;
1322 switch(error) {
1323 case ENOENT:
1324 case ESRCH:
1325 break;
1326 default:
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"));
1331 }
1332
1333 /* ignore error, maybe we will get luck in next if clause */
1334 status = ARES_EOF;
1335 }
1336 }
1337
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");
1341 if (fp) {
1342 while ((status = ares__read_line(fp, &line, &linesize)) ==
1343 ARES_SUCCESS)
1344 {
1345 if ((p = try_config(line, "order", '\0')) && !channel->lookups)
1346 /* ignore errors */
1347 (void)config_lookup(channel, p, "bind", NULL, "hosts");
1348 }
1349 fclose(fp);
1350 }
1351 else {
1352 error = ERRNO;
1353 switch(error) {
1354 case ENOENT:
1355 case ESRCH:
1356 break;
1357 default:
1358 DEBUGF(fprintf(stderr, "fopen() failed with error: %d %s\n",
1359 error, strerror(error)));
1360 DEBUGF(fprintf(stderr, "Error opening file: %s\n",
1361 "/etc/host.conf"));
1362 }
1363
1364 /* ignore error, maybe we will get luck in next if clause */
1365 status = ARES_EOF;
1366 }
1367 }
1368
1369 if ((status == ARES_EOF) && (!channel->lookups)) {
1370 /* Tru64 uses /etc/svc.conf */
1371 fp = fopen("/etc/svc.conf", "r");
1372 if (fp) {
1373 while ((status = ares__read_line(fp, &line, &linesize)) ==
1374 ARES_SUCCESS)
1375 {
1376 if ((p = try_config(line, "hosts=", '\0')) && !channel->lookups)
1377 /* ignore errors */
1378 (void)config_lookup(channel, p, "bind", NULL, "local");
1379 }
1380 fclose(fp);
1381 }
1382 else {
1383 error = ERRNO;
1384 switch(error) {
1385 case ENOENT:
1386 case ESRCH:
1387 break;
1388 default:
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"));
1392 }
1393
1394 /* ignore error, default value will be chosen for `channel->lookups` */
1395 status = ARES_EOF;
1396 }
1397 }
1398
1399 if(line)
1400 ares_free(line);
1401 }
1402
1403 #endif
1404
1405 /* Handle errors. */
1406 if (status != ARES_EOF)
1407 {
1408 if (servers != NULL)
1409 ares_free(servers);
1410 if (sortlist != NULL)
1411 ares_free(sortlist);
1412 return status;
1413 }
1414
1415 /* If we got any name server entries, fill them in. */
1416 if (servers)
1417 {
1418 channel->servers = servers;
1419 channel->nservers = nservers;
1420 }
1421
1422 /* If we got any sortlist entries, fill them in. */
1423 if (sortlist)
1424 {
1425 channel->sortlist = sortlist;
1426 channel->nsort = nsort;
1427 }
1428
1429 return ARES_SUCCESS;
1430 }
1431
1432 static int init_by_defaults(ares_channel channel)
1433 {
1434 char *hostname = NULL;
1435 int rc = ARES_SUCCESS;
1436 #ifdef HAVE_GETHOSTNAME
1437 char *dot;
1438 #endif
1439
1440 if (channel->flags == -1)
1441 channel->flags = 0;
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)
1447 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);
1454
1455 if (channel->ednspsz == -1)
1456 channel->ednspsz = EDNSPACKETSZ;
1457
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) {
1462 rc = ARES_ENOMEM;
1463 goto error;
1464 }
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;
1470 }
1471
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))
1477 #else
1478 #define toolong(x) (x == -1) && (SOCKERRNO == EINVAL)
1479 #endif
1480
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.
1484 */
1485 #ifndef HAVE_GETHOSTNAME
1486 channel->ndomains = 0; /* default to none */
1487 #else
1488 GETHOSTNAME_TYPE_ARG2 lenv = 64;
1489 size_t len = 64;
1490 int res;
1491 channel->ndomains = 0; /* default to none */
1492
1493 hostname = ares_malloc(len);
1494 if(!hostname) {
1495 rc = ARES_ENOMEM;
1496 goto error;
1497 }
1498
1499 do {
1500 res = gethostname(hostname, lenv);
1501
1502 if(toolong(res)) {
1503 char *p;
1504 len *= 2;
1505 lenv *= 2;
1506 p = ares_realloc(hostname, len);
1507 if(!p) {
1508 rc = ARES_ENOMEM;
1509 goto error;
1510 }
1511 hostname = p;
1512 continue;
1513 }
1514 else if(res) {
1515 rc = ARES_EBADNAME;
1516 goto error;
1517 }
1518
1519 } while (res != 0);
1520
1521 dot = strchr(hostname, '.');
1522 if (dot) {
1523 /* a dot was found */
1524 channel->domains = ares_malloc(sizeof(char *));
1525 if (!channel->domains) {
1526 rc = ARES_ENOMEM;
1527 goto error;
1528 }
1529 channel->domains[0] = ares_strdup(dot + 1);
1530 if (!channel->domains[0]) {
1531 rc = ARES_ENOMEM;
1532 goto error;
1533 }
1534 channel->ndomains = 1;
1535 }
1536 #endif
1537 }
1538
1539 if (channel->nsort == -1) {
1540 channel->sortlist = NULL;
1541 channel->nsort = 0;
1542 }
1543
1544 if (!channel->lookups) {
1545 channel->lookups = ares_strdup("fb");
1546 if (!channel->lookups)
1547 rc = ARES_ENOMEM;
1548 }
1549
1550 error:
1551 if(rc) {
1552 if(channel->servers) {
1553 ares_free(channel->servers);
1554 channel->servers = NULL;
1555 }
1556
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;
1562 }
1563
1564 if(channel->lookups) {
1565 ares_free(channel->lookups);
1566 channel->lookups = NULL;
1567 }
1568 }
1569
1570 if(hostname)
1571 ares_free(hostname);
1572
1573 return rc;
1574 }
1575
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)
1579 {
1580 char *q;
1581
1582 /* Set a single search domain. */
1583 q = str;
1584 while (*q && !ISSPACE(*q))
1585 q++;
1586 *q = '\0';
1587 return set_search(channel, str);
1588 }
1589
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
1594 #else
1595 # define vqualifier
1596 #endif
1597
1598 static int config_lookup(ares_channel channel, const char *str,
1599 const char *bindch, const char *altbindch,
1600 const char *filech)
1601 {
1602 char lookups[3], *l;
1603 const char *vqualifier p;
1604
1605 if (altbindch == NULL)
1606 altbindch = bindch;
1607
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.
1611 */
1612 l = lookups;
1613 p = str;
1614 while (*p)
1615 {
1616 if ((*p == *bindch || *p == *altbindch || *p == *filech) && l < lookups + 2) {
1617 if (*p == *bindch || *p == *altbindch) *l++ = 'b';
1618 else *l++ = 'f';
1619 }
1620 while (*p && !ISSPACE(*p) && (*p != ','))
1621 p++;
1622 while (*p && (ISSPACE(*p) || (*p == ',')))
1623 p++;
1624 }
1625 *l = '\0';
1626 channel->lookups = ares_strdup(lookups);
1627 return (channel->lookups) ? ARES_SUCCESS : ARES_ENOMEM;
1628 }
1629 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ & !CARES_USE_LIBRESOLV */
1630
1631 #ifndef WATT32
1632 static int config_nameserver(struct server_state **servers, int *nservers,
1633 char *str)
1634 {
1635 struct ares_addr host;
1636 struct server_state *newserv;
1637 char *p, *txtaddr;
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.
1640 */
1641 for (p = str; p;)
1642 {
1643 /* Skip whitespace and commas. */
1644 while (*p && (ISSPACE(*p) || (*p == ',')))
1645 p++;
1646 if (!*p)
1647 /* No more input, done. */
1648 break;
1649
1650 /* Pointer to start of IPv4 or IPv6 address part. */
1651 txtaddr = p;
1652
1653 /* Advance past this address. */
1654 while (*p && !ISSPACE(*p) && (*p != ','))
1655 p++;
1656 if (*p)
1657 /* Null terminate this address. */
1658 *p++ = '\0';
1659 else
1660 /* Reached end of input, done when this address is processed. */
1661 p = NULL;
1662
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;
1668 else
1669 continue;
1670
1671 /* Resize servers state array. */
1672 newserv = ares_realloc(*servers, (*nservers + 1) *
1673 sizeof(struct server_state));
1674 if (!newserv)
1675 return ARES_ENOMEM;
1676
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));
1684 else
1685 memcpy(&newserv[*nservers].addr.addrV6, &host.addrV6,
1686 sizeof(host.addrV6));
1687
1688 /* Update arguments. */
1689 *servers = newserv;
1690 *nservers += 1;
1691 }
1692
1693 return ARES_SUCCESS;
1694 }
1695 #endif /* !WATT32 */
1696
1697 static int config_sortlist(struct apattern **sortlist, int *nsort,
1698 const char *str)
1699 {
1700 struct apattern pat;
1701 const char *q;
1702
1703 /* Add sortlist entries. */
1704 while (*str && *str != ';')
1705 {
1706 int bits;
1707 char ipbuf[16], ipbufpfx[32];
1708 /* Find just the IP */
1709 q = str;
1710 while (*q && *q != '/' && *q != ';' && !ISSPACE(*q))
1711 q++;
1712 memcpy(ipbuf, str, q-str);
1713 ipbuf[q-str] = '\0';
1714 /* Find the prefix */
1715 if (*q == '/')
1716 {
1717 const char *str2 = q+1;
1718 while (*q && *q != ';' && !ISSPACE(*q))
1719 q++;
1720 memcpy(ipbufpfx, str, q-str);
1721 ipbufpfx[q-str] = '\0';
1722 str = str2;
1723 }
1724 else
1725 ipbufpfx[0] = '\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,
1729 &pat.addrV6,
1730 sizeof(pat.addrV6))) > 0)
1731 {
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);
1737 *sortlist = NULL;
1738 return ARES_ENOMEM;
1739 }
1740 }
1741 else if (ipbufpfx[0] &&
1742 (bits = ares_inet_net_pton(AF_INET, ipbufpfx, &pat.addrV4,
1743 sizeof(pat.addrV4))) > 0)
1744 {
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);
1750 *sortlist = NULL;
1751 return ARES_ENOMEM;
1752 }
1753 }
1754 /* See if it is just a regular IP */
1755 else if (ip_addr(ipbuf, q-str, &pat.addrV4) == 0)
1756 {
1757 if (ipbufpfx[0])
1758 {
1759 memcpy(ipbuf, str, q-str);
1760 ipbuf[q-str] = '\0';
1761 if (ip_addr(ipbuf, q-str, &pat.mask.addr4) != 0)
1762 natural_mask(&pat);
1763 }
1764 else
1765 natural_mask(&pat);
1766 pat.family = AF_INET;
1767 pat.type = PATTERN_MASK;
1768 if (!sortlist_alloc(sortlist, nsort, &pat)) {
1769 ares_free(*sortlist);
1770 *sortlist = NULL;
1771 return ARES_ENOMEM;
1772 }
1773 }
1774 else
1775 {
1776 while (*q && *q != ';' && !ISSPACE(*q))
1777 q++;
1778 }
1779 str = q;
1780 while (ISSPACE(*str))
1781 str++;
1782 }
1783
1784 return ARES_SUCCESS;
1785 }
1786
1787 static int set_search(ares_channel channel, const char *str)
1788 {
1789 int n;
1790 const char *p, *q;
1791
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 */
1801
1802 /* Count the domains given. */
1803 n = 0;
1804 p = str;
1805 while (*p)
1806 {
1807 while (*p && !ISSPACE(*p))
1808 p++;
1809 while (ISSPACE(*p))
1810 p++;
1811 n++;
1812 }
1813
1814 if (!n)
1815 {
1816 channel->ndomains = 0;
1817 return ARES_SUCCESS;
1818 }
1819
1820 channel->domains = ares_malloc(n * sizeof(char *));
1821 if (!channel->domains)
1822 return ARES_ENOMEM;
1823
1824 /* Now copy the domains. */
1825 n = 0;
1826 p = str;
1827 while (*p)
1828 {
1829 channel->ndomains = n;
1830 q = p;
1831 while (*q && !ISSPACE(*q))
1832 q++;
1833 channel->domains[n] = ares_malloc(q - p + 1);
1834 if (!channel->domains[n])
1835 return ARES_ENOMEM;
1836 memcpy(channel->domains[n], p, q - p);
1837 channel->domains[n][q - p] = 0;
1838 p = q;
1839 while (ISSPACE(*p))
1840 p++;
1841 n++;
1842 }
1843 channel->ndomains = n;
1844
1845 return ARES_SUCCESS;
1846 }
1847
1848 static int set_options(ares_channel channel, const char *str)
1849 {
1850 const char *p, *q, *val;
1851
1852 p = str;
1853 while (*p)
1854 {
1855 q = p;
1856 while (*q && !ISSPACE(*q))
1857 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;
1870 p = q;
1871 while (ISSPACE(*p))
1872 p++;
1873 }
1874
1875 return ARES_SUCCESS;
1876 }
1877
1878 static const char *try_option(const char *p, const char *q, const char *opt)
1879 {
1880 size_t len = strlen(opt);
1881 return ((size_t)(q - p) >= len && !strncmp(p, opt, len)) ? &p[len] : NULL;
1882 }
1883
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)
1887 {
1888 size_t len;
1889 char *p;
1890 char *q;
1891
1892 if (!s || !opt)
1893 /* no line or no option */
1894 return NULL; /* LCOV_EXCL_LINE */
1895
1896 /* Hash '#' character is always used as primary comment char, additionally
1897 a not-NUL secondary comment char will be considered when specified. */
1898
1899 /* trim line comment */
1900 p = s;
1901 if(scc)
1902 while (*p && (*p != '#') && (*p != scc))
1903 p++;
1904 else
1905 while (*p && (*p != '#'))
1906 p++;
1907 *p = '\0';
1908
1909 /* trim trailing whitespace */
1910 q = p - 1;
1911 while ((q >= s) && ISSPACE(*q))
1912 q--;
1913 *++q = '\0';
1914
1915 /* skip leading whitespace */
1916 p = s;
1917 while (*p && ISSPACE(*p))
1918 p++;
1919
1920 if (!*p)
1921 /* empty line */
1922 return NULL;
1923
1924 if ((len = strlen(opt)) == 0)
1925 /* empty option */
1926 return NULL; /* LCOV_EXCL_LINE */
1927
1928 if (strncmp(p, opt, len) != 0)
1929 /* line and option do not match */
1930 return NULL;
1931
1932 /* skip over given option name */
1933 p += len;
1934
1935 if (!*p)
1936 /* no option value */
1937 return NULL; /* LCOV_EXCL_LINE */
1938
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 '=' */
1942 return NULL;
1943
1944 /* skip over whitespace */
1945 while (*p && ISSPACE(*p))
1946 p++;
1947
1948 if (!*p)
1949 /* no option value */
1950 return NULL;
1951
1952 /* return pointer to option value */
1953 return p;
1954 }
1955 #endif /* !WIN32 & !WATT32 & !ANDROID & !__ANDROID__ */
1956
1957 static int ip_addr(const char *ipbuf, ssize_t len, struct in_addr *addr)
1958 {
1959
1960 /* Four octets and three periods yields at most 15 characters. */
1961 if (len > 15)
1962 return -1;
1963
1964 addr->s_addr = inet_addr(ipbuf);
1965 if (addr->s_addr == INADDR_NONE && strcmp(ipbuf, "255.255.255.255") != 0)
1966 return -1;
1967 return 0;
1968 }
1969
1970 static void natural_mask(struct apattern *pat)
1971 {
1972 struct in_addr addr;
1973
1974 /* Store a host-byte-order copy of pat in a struct in_addr. Icky,
1975 * but portable.
1976 */
1977 addr.s_addr = ntohl(pat->addrV4.s_addr);
1978
1979 /* This is out of date in the CIDR world, but some people might
1980 * still rely on it.
1981 */
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);
1986 else
1987 pat->mask.addr4.s_addr = htonl(IN_CLASSC_NET);
1988 }
1989
1990 static int sortlist_alloc(struct apattern **sortlist, int *nsort,
1991 struct apattern *pat)
1992 {
1993 struct apattern *newsort;
1994 newsort = ares_realloc(*sortlist, (*nsort + 1) * sizeof(struct apattern));
1995 if (!newsort)
1996 return 0;
1997 newsort[*nsort] = *pat;
1998 *sortlist = newsort;
1999 (*nsort)++;
2000 return 1;
2001 }
2002
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
2005 described in
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
2008 using rand
2009 */
2010 static void randomize_key(unsigned char* key,int key_data_len)
2011 {
2012 int randomized = 0;
2013 int counter=0;
2014 #ifdef WIN32
2015 BOOLEAN res;
2016 if (ares_fpSystemFunction036)
2017 {
2018 res = (*ares_fpSystemFunction036) (key, key_data_len);
2019 if (res)
2020 randomized = 1;
2021 }
2022 #else /* !WIN32 */
2023 #ifdef RANDOM_FILE
2024 FILE *f = fopen(RANDOM_FILE, "rb");
2025 if(f) {
2026 counter = aresx_uztosi(fread(key, 1, key_data_len, f));
2027 fclose(f);
2028 }
2029 #endif
2030 #endif /* WIN32 */
2031
2032 if (!randomized) {
2033 for (;counter<key_data_len;counter++)
2034 key[counter]=(unsigned char)(rand() % 256); /* LCOV_EXCL_LINE */
2035 }
2036 }
2037
2038 static int init_id_key(rc4_key* key,int key_data_len)
2039 {
2040 unsigned char index1;
2041 unsigned char index2;
2042 unsigned char* state;
2043 short counter;
2044 unsigned char *key_data_ptr = 0;
2045
2046 key_data_ptr = ares_malloc(key_data_len);
2047 if (!key_data_ptr)
2048 return ARES_ENOMEM;
2049 memset(key_data_ptr, 0, key_data_len);
2050
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);
2056 key->x = 0;
2057 key->y = 0;
2058 index1 = 0;
2059 index2 = 0;
2060 for(counter = 0; counter < 256; counter++)
2061 {
2062 index2 = (unsigned char)((key_data_ptr[index1] + state[counter] +
2063 index2) % 256);
2064 ARES_SWAP_BYTE(&state[counter], &state[index2]);
2065
2066 index1 = (unsigned char)((index1 + 1) % key_data_len);
2067 }
2068 ares_free(key_data_ptr);
2069 return ARES_SUCCESS;
2070 }
2071
2072 void ares_set_local_ip4(ares_channel channel, unsigned int local_ip)
2073 {
2074 channel->local_ip4 = local_ip;
2075 }
2076
2077 /* local_ip6 should be 16 bytes in length */
2078 void ares_set_local_ip6(ares_channel channel,
2079 const unsigned char* local_ip6)
2080 {
2081 memcpy(&channel->local_ip6, local_ip6, sizeof(channel->local_ip6));
2082 }
2083
2084 /* local_dev_name should be null terminated. */
2085 void ares_set_local_dev(ares_channel channel,
2086 const char* local_dev_name)
2087 {
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;
2091 }
2092
2093
2094 void ares_set_socket_callback(ares_channel channel,
2095 ares_sock_create_callback cb,
2096 void *data)
2097 {
2098 channel->sock_create_cb = cb;
2099 channel->sock_create_cb_data = data;
2100 }
2101
2102 void ares_set_socket_configure_callback(ares_channel channel,
2103 ares_sock_config_callback cb,
2104 void *data)
2105 {
2106 channel->sock_config_cb = cb;
2107 channel->sock_config_cb_data = data;
2108 }
2109
2110 void ares_set_socket_functions(ares_channel channel,
2111 const struct ares_socket_functions * funcs,
2112 void *data)
2113 {
2114 channel->sock_funcs = funcs;
2115 channel->sock_func_cb_data = data;
2116 }
2117
2118 int ares_set_sortlist(ares_channel channel, const char *sortstr)
2119 {
2120 int nsort = 0;
2121 struct apattern *sortlist = NULL;
2122 int status;
2123
2124 if (!channel)
2125 return ARES_ENODATA;
2126
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;
2133 }
2134 return status;
2135 }
2136
2137 void ares__init_servers_state(ares_channel channel)
2138 {
2139 struct server_state *server;
2140 int i;
2141
2142 for (i = 0; i < channel->nservers; i++)
2143 {
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;
2157 }
2158 }