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