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