• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* MIT License
2  *
3  * Copyright (c) 1998 Massachusetts Institute of Technology
4  * Copyright (c) 2010 Daniel Stenberg
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to deal
8  * in the Software without restriction, including without limitation the rights
9  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10  * copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice (including the next
14  * paragraph) shall be included in all copies or substantial portions of the
15  * Software.
16  *
17  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
23  * SOFTWARE.
24  *
25  * SPDX-License-Identifier: MIT
26  */
27 #ifndef __ARES_PRIVATE_H
28 #define __ARES_PRIVATE_H
29 
30 /*
31  * Define WIN32 when build target is Win32 API
32  */
33 
34 #if (defined(_WIN32) || defined(__WIN32__)) && !defined(WIN32)
35 #  define WIN32
36 #endif
37 
38 #ifdef HAVE_NETINET_IN_H
39 #  include <netinet/in.h>
40 #endif
41 
42 #ifdef WATT32
43 #  include <tcp.h>
44 #  include <sys/ioctl.h>
45 #endif
46 
47 #define DEFAULT_TIMEOUT 2000 /* milliseconds */
48 #define DEFAULT_TRIES   3
49 #ifndef INADDR_NONE
50 #  define INADDR_NONE 0xffffffff
51 #endif
52 
53 /* By using a double cast, we can get rid of the bogus warning of
54  * warning: cast from 'const struct sockaddr *' to 'const struct sockaddr_in6 *'
55  * increases required alignment from 1 to 4 [-Wcast-align]
56  */
57 #define CARES_INADDR_CAST(type, var) ((type)((void *)var))
58 
59 #if defined(WIN32) && !defined(WATT32)
60 
61 #  define WIN_NS_9X     "System\\CurrentControlSet\\Services\\VxD\\MSTCP"
62 #  define WIN_NS_NT_KEY "System\\CurrentControlSet\\Services\\Tcpip\\Parameters"
63 #  define WIN_DNSCLIENT "Software\\Policies\\Microsoft\\System\\DNSClient"
64 #  define WIN_NT_DNSCLIENT \
65     "Software\\Policies\\Microsoft\\Windows NT\\DNSClient"
66 #  define NAMESERVER           "NameServer"
67 #  define DHCPNAMESERVER       "DhcpNameServer"
68 #  define DATABASEPATH         "DatabasePath"
69 #  define WIN_PATH_HOSTS       "\\hosts"
70 #  define SEARCHLIST_KEY       "SearchList"
71 #  define PRIMARYDNSSUFFIX_KEY "PrimaryDNSSuffix"
72 #  define INTERFACES_KEY       "Interfaces"
73 #  define DOMAIN_KEY           "Domain"
74 #  define DHCPDOMAIN_KEY       "DhcpDomain"
75 #  define PATH_RESOLV_CONF     ""
76 #elif defined(WATT32)
77 
78 #  define PATH_RESOLV_CONF "/dev/ENV/etc/resolv.conf"
79 W32_FUNC const char *_w32_GetHostsFile(void);
80 
81 #elif defined(NETWARE)
82 
83 #  define PATH_RESOLV_CONF "sys:/etc/resolv.cfg"
84 #  define PATH_HOSTS       "sys:/etc/hosts"
85 
86 #elif defined(__riscos__)
87 
88 #  define PATH_RESOLV_CONF ""
89 #  define PATH_HOSTS       "InetDBase:Hosts"
90 
91 #elif defined(__HAIKU__)
92 
93 #  define PATH_RESOLV_CONF "/system/settings/network/resolv.conf"
94 #  define PATH_HOSTS       "/system/settings/network/hosts"
95 
96 #else
97 
98 #  define PATH_RESOLV_CONF "/etc/resolv.conf"
99 #  ifdef ETC_INET
100 #    define PATH_HOSTS "/etc/inet/hosts"
101 #  else
102 #    define PATH_HOSTS "/etc/hosts"
103 #  endif
104 
105 #endif
106 
107 #include "ares_ipv6.h"
108 
109 struct ares_rand_state;
110 typedef struct ares_rand_state ares_rand_state;
111 
112 #include "ares__llist.h"
113 #include "ares__slist.h"
114 #include "ares__htable_strvp.h"
115 #include "ares__htable_szvp.h"
116 #include "ares__htable_asvp.h"
117 #include "ares__buf.h"
118 #include "ares_dns_private.h"
119 #include "ares__iface_ips.h"
120 #include "ares__threads.h"
121 
122 #ifndef HAVE_GETENV
123 #  include "ares_getenv.h"
124 #  define getenv(ptr) ares_getenv(ptr)
125 #endif
126 
127 #include "ares_str.h"
128 #include "ares_strsplit.h"
129 
130 #ifndef HAVE_STRCASECMP
131 #  include "ares_strcasecmp.h"
132 #  define strcasecmp(p1, p2) ares_strcasecmp(p1, p2)
133 #endif
134 
135 #ifndef HAVE_STRNCASECMP
136 #  include "ares_strcasecmp.h"
137 #  define strncasecmp(p1, p2, n) ares_strncasecmp(p1, p2, n)
138 #endif
139 
140 /********* EDNS defines section ******/
141 #define EDNSPACKETSZ                                          \
142   1232 /* Reasonable UDP payload size, as agreed by operators \
143           https://www.dnsflagday.net/2020/#faq */
144 #define MAXENDSSZ   4096 /* Maximum (local) limit for edns packet size */
145 #define EDNSFIXEDSZ 11   /* Size of EDNS header */
146 
147 /********* EDNS defines section ******/
148 
149 
150 struct query;
151 
152 struct server_state;
153 
154 struct server_connection {
155   struct server_state *server;
156   ares_socket_t        fd;
157   ares_bool_t          is_tcp;
158   /* total number of queries run on this connection since it was established */
159   size_t               total_queries;
160   /* list of outstanding queries to this connection */
161   ares__llist_t       *queries_to_conn;
162 };
163 
164 struct server_state {
165   /* Configuration */
166   size_t                    idx; /* index for server in system configuration */
167   struct ares_addr          addr;
168   unsigned short            udp_port;        /* host byte order */
169   unsigned short            tcp_port;        /* host byte order */
170   char                      ll_iface[64];    /* IPv6 Link Local Interface */
171   unsigned int              ll_scope;        /* IPv6 Link Local Scope */
172 
173   size_t                    consec_failures; /* Consecutive query failure count
174                                               * can be hard errors or timeouts
175                                               */
176   ares__llist_t            *connections;
177   struct server_connection *tcp_conn;
178 
179   /* TCP buffer since multiple responses can come back in one read, or partial
180    * in a read */
181   ares__buf_t              *tcp_parser;
182 
183   /* TCP output queue */
184   ares__buf_t              *tcp_send;
185 
186   /* Link back to owning channel */
187   ares_channel_t           *channel;
188 };
189 
190 /* State to represent a DNS query */
191 struct query {
192   /* Query ID from qbuf, for faster lookup, and current timeout */
193   unsigned short            qid; /* host byte order */
194   struct timeval            timeout;
195   ares_channel_t           *channel;
196 
197   /*
198    * Node object for each list entry the query belongs to in order to
199    * make removal operations O(1).
200    */
201   ares__slist_node_t       *node_queries_by_timeout;
202   ares__llist_node_t       *node_queries_to_conn;
203   ares__llist_node_t       *node_all_queries;
204 
205   /* connection handle query is associated with */
206   struct server_connection *conn;
207 
208   /* Arguments passed to ares_send() */
209   unsigned char            *qbuf;
210   size_t                    qlen;
211 
212   ares_callback             callback;
213   void                     *arg;
214 
215   /* Query status */
216   size_t        try_count; /* Number of times we tried this query already. */
217   ares_bool_t   using_tcp;
218   ares_status_t error_status;
219   size_t        timeouts; /* number of timeouts we saw for this request */
220   ares_bool_t no_retries; /* do not perform any additional retries, this is set
221                            * when a query is to be canceled */
222 };
223 
224 struct apattern {
225   struct ares_addr addr;
226   unsigned char    mask;
227 };
228 
229 struct ares__qcache;
230 typedef struct ares__qcache ares__qcache_t;
231 
232 struct ares_hosts_file;
233 typedef struct ares_hosts_file ares_hosts_file_t;
234 
235 struct ares_channeldata {
236   /* Configuration data */
237   unsigned int          flags;
238   size_t                timeout; /* in milliseconds */
239   size_t                tries;
240   size_t                ndots;
241   size_t                maxtimeout;              /* in milliseconds */
242   ares_bool_t           rotate;
243   unsigned short        udp_port;                /* stored in network order */
244   unsigned short        tcp_port;                /* stored in network order */
245   int                   socket_send_buffer_size; /* setsockopt takes int */
246   int                   socket_receive_buffer_size; /* setsockopt takes int */
247   char                **domains;
248   size_t                ndomains;
249   struct apattern      *sortlist;
250   size_t                nsort;
251   char                 *lookups;
252   size_t                ednspsz;
253   unsigned int          qcache_max_ttl;
254   ares_evsys_t          evsys;
255   unsigned int          optmask;
256 
257   /* For binding to local devices and/or IP addresses.  Leave
258    * them null/zero for no binding.
259    */
260   char                  local_dev_name[32];
261   unsigned int          local_ip4;
262   unsigned char         local_ip6[16];
263 
264   /* Thread safety lock */
265   ares__thread_mutex_t *lock;
266 
267   /* Conditional to wake waiters when queue is empty */
268   ares__thread_cond_t  *cond_empty;
269 
270   /* Server addresses and communications state. Sorted by least consecutive
271    * failures, followed by the configuration order if failures are equal. */
272   ares__slist_t        *servers;
273 
274   /* random state to use when generating new ids and generating retry penalties
275    */
276   ares_rand_state      *rand_state;
277 
278   /* All active queries in a single list */
279   ares__llist_t        *all_queries;
280   /* Queries bucketed by qid, for quickly dispatching DNS responses: */
281   ares__htable_szvp_t  *queries_by_qid;
282 
283   /* Queries bucketed by timeout, for quickly handling timeouts: */
284   ares__slist_t        *queries_by_timeout;
285 
286   /* Map linked list node member for connection to file descriptor.  We use
287    * the node instead of the connection object itself so we can quickly look
288    * up a connection and remove it if necessary (as otherwise we'd have to
289    * scan all connections) */
290   ares__htable_asvp_t  *connnode_by_socket;
291 
292   ares_sock_state_cb    sock_state_cb;
293   void                 *sock_state_cb_data;
294 
295   ares_sock_create_callback           sock_create_cb;
296   void                               *sock_create_cb_data;
297 
298   ares_sock_config_callback           sock_config_cb;
299   void                               *sock_config_cb_data;
300 
301   const struct ares_socket_functions *sock_funcs;
302   void                               *sock_func_cb_data;
303 
304   /* Path for resolv.conf file, configurable via ares_options */
305   char                               *resolvconf_path;
306 
307   /* Path for hosts file, configurable via ares_options */
308   char                               *hosts_path;
309 
310   /* Maximum UDP queries per connection allowed */
311   size_t                              udp_max_queries;
312 
313   /* Cache of local hosts file */
314   ares_hosts_file_t                  *hf;
315 
316   /* Query Cache */
317   ares__qcache_t                     *qcache;
318 };
319 
320 /* Does the domain end in ".onion" or ".onion."? Case-insensitive. */
321 ares_bool_t   ares__is_onion_domain(const char *name);
322 
323 /* Memory management functions */
324 extern void  *(*ares_malloc)(size_t size);
325 extern void  *(*ares_realloc)(void *ptr, size_t size);
326 extern void   (*ares_free)(void *ptr);
327 void         *ares_malloc_zero(size_t size);
328 void         *ares_realloc_zero(void *ptr, size_t orig_size, size_t new_size);
329 
330 /* return true if now is exactly check time or later */
331 ares_bool_t   ares__timedout(const struct timeval *now,
332                              const struct timeval *check);
333 
334 /* Returns one of the normal ares status codes like ARES_SUCCESS */
335 ares_status_t ares__send_query(struct query *query, struct timeval *now);
336 ares_status_t ares__requeue_query(struct query *query, struct timeval *now);
337 
338 /* Identical to ares_query, but returns a normal ares return code like
339  * ARES_SUCCESS, and can be passed the qid by reference which will be
340  * filled in on ARES_SUCCESS */
341 ares_status_t ares_query_qid(ares_channel_t *channel, const char *name,
342                              int dnsclass, int type, ares_callback callback,
343                              void *arg, unsigned short *qid);
344 /* Identical to ares_send() except returns normal ares return codes like
345  * ARES_SUCCESS */
346 ares_status_t ares_send_ex(ares_channel_t *channel, const unsigned char *qbuf,
347                            size_t qlen, ares_callback callback, void *arg,
348                            unsigned short *qid);
349 void          ares__close_connection(struct server_connection *conn);
350 void          ares__close_sockets(struct server_state *server);
351 void          ares__check_cleanup_conn(const ares_channel_t     *channel,
352                                        struct server_connection *conn);
353 ares_status_t ares__read_line(FILE *fp, char **buf, size_t *bufsize);
354 void          ares__free_query(struct query *query);
355 
356 ares_rand_state *ares__init_rand_state(void);
357 void             ares__destroy_rand_state(ares_rand_state *state);
358 void ares__rand_bytes(ares_rand_state *state, unsigned char *buf, size_t len);
359 
360 unsigned short ares__generate_new_id(ares_rand_state *state);
361 struct timeval ares__tvnow(void);
362 void           ares__timeval_remaining(struct timeval       *remaining,
363                                        const struct timeval *now,
364                                        const struct timeval *tout);
365 ares_status_t  ares__expand_name_validated(const unsigned char *encoded,
366                                            const unsigned char *abuf,
367                                            size_t alen, char **s, size_t *enclen,
368                                            ares_bool_t is_hostname);
369 ares_status_t  ares__expand_name_for_response(const unsigned char *encoded,
370                                               const unsigned char *abuf,
371                                               size_t alen, char **s,
372                                               size_t     *enclen,
373                                               ares_bool_t is_hostname);
374 ares_status_t  ares_expand_string_ex(const unsigned char *encoded,
375                                      const unsigned char *abuf, size_t alen,
376                                      unsigned char **s, size_t *enclen);
377 ares_status_t  ares__init_servers_state(ares_channel_t *channel);
378 ares_status_t  ares__init_by_options(ares_channel_t            *channel,
379                                      const struct ares_options *options,
380                                      int                        optmask);
381 ares_status_t  ares__init_by_sysconfig(ares_channel_t *channel);
382 
383 typedef struct {
384   ares__llist_t   *sconfig;
385   struct apattern *sortlist;
386   size_t           nsortlist;
387   char           **domains;
388   size_t           ndomains;
389   char            *lookups;
390   size_t           ndots;
391   size_t           tries;
392   ares_bool_t      rotate;
393   size_t           timeout_ms;
394 } ares_sysconfig_t;
395 
396 ares_status_t ares__init_by_environment(ares_sysconfig_t *sysconfig);
397 
398 ares_status_t ares__init_sysconfig_files(const ares_channel_t *channel,
399                                          ares_sysconfig_t     *sysconfig);
400 ares_status_t ares__parse_sortlist(struct apattern **sortlist, size_t *nsort,
401                                    const char *str);
402 
403 void          ares__destroy_servers_state(ares_channel_t *channel);
404 ares_status_t ares__single_domain(const ares_channel_t *channel,
405                                   const char *name, char **s);
406 ares_status_t ares__cat_domain(const char *name, const char *domain, char **s);
407 ares_status_t ares__sortaddrinfo(ares_channel_t            *channel,
408                                  struct ares_addrinfo_node *ai_node);
409 
410 void          ares__freeaddrinfo_nodes(struct ares_addrinfo_node *ai_node);
411 ares_bool_t   ares__is_localhost(const char *name);
412 
413 struct ares_addrinfo_node    *
414   ares__append_addrinfo_node(struct ares_addrinfo_node **ai_node);
415 void ares__addrinfo_cat_nodes(struct ares_addrinfo_node **head,
416                               struct ares_addrinfo_node  *tail);
417 
418 void ares__freeaddrinfo_cnames(struct ares_addrinfo_cname *ai_cname);
419 
420 struct ares_addrinfo_cname *
421   ares__append_addrinfo_cname(struct ares_addrinfo_cname **ai_cname);
422 
423 ares_status_t ares_append_ai_node(int aftype, unsigned short port,
424                                   unsigned int ttl, const void *adata,
425                                   struct ares_addrinfo_node **nodes);
426 
427 void          ares__addrinfo_cat_cnames(struct ares_addrinfo_cname **head,
428                                         struct ares_addrinfo_cname  *tail);
429 
430 ares_status_t ares__parse_into_addrinfo(const unsigned char *abuf, size_t alen,
431                                         ares_bool_t    cname_only_is_enodata,
432                                         unsigned short port,
433                                         struct ares_addrinfo *ai);
434 
435 ares_status_t ares__addrinfo2hostent(const struct ares_addrinfo *ai, int family,
436                                      struct hostent **host);
437 ares_status_t ares__addrinfo2addrttl(const struct ares_addrinfo *ai, int family,
438                                      size_t                req_naddrttls,
439                                      struct ares_addrttl  *addrttls,
440                                      struct ares_addr6ttl *addr6ttls,
441                                      size_t               *naddrttls);
442 ares_status_t ares__addrinfo_localhost(const char *name, unsigned short port,
443                                        const struct ares_addrinfo_hints *hints,
444                                        struct ares_addrinfo             *ai);
445 ares_status_t ares__open_connection(ares_channel_t      *channel,
446                                     struct server_state *server,
447                                     ares_bool_t          is_tcp);
448 ares_socket_t ares__open_socket(ares_channel_t *channel, int af, int type,
449                                 int protocol);
450 ares_ssize_t  ares__socket_write(ares_channel_t *channel, ares_socket_t s,
451                                  const void *data, size_t len);
452 ares_ssize_t  ares__socket_recvfrom(ares_channel_t *channel, ares_socket_t s,
453                                     void *data, size_t data_len, int flags,
454                                     struct sockaddr *from,
455                                     ares_socklen_t  *from_len);
456 ares_ssize_t  ares__socket_recv(ares_channel_t *channel, ares_socket_t s,
457                                 void *data, size_t data_len);
458 void          ares__close_socket(ares_channel, ares_socket_t);
459 int         ares__connect_socket(ares_channel_t *channel, ares_socket_t sockfd,
460                                  const struct sockaddr *addr, ares_socklen_t addrlen);
461 ares_bool_t ares__is_hostnamech(int ch);
462 void        ares__destroy_server(struct server_state *server);
463 
464 ares_status_t ares__servers_update(ares_channel_t *channel,
465                                    ares__llist_t  *server_list,
466                                    ares_bool_t     user_specified);
467 ares_status_t ares__sconfig_append(ares__llist_t         **sconfig,
468                                    const struct ares_addr *addr,
469                                    unsigned short          udp_port,
470                                    unsigned short          tcp_port,
471                                    const char             *ll_iface);
472 ares_status_t ares__sconfig_append_fromstr(ares__llist_t **sconfig,
473                                            const char     *str,
474                                            ares_bool_t     ignore_invalid);
475 ares_status_t ares_in_addr_to_server_config_llist(const struct in_addr *servers,
476                                                   size_t          nservers,
477                                                   ares__llist_t **llist);
478 
479 struct ares_hosts_entry;
480 typedef struct ares_hosts_entry ares_hosts_entry_t;
481 
482 void                            ares__hosts_file_destroy(ares_hosts_file_t *hf);
483 ares_status_t ares__hosts_search_ipaddr(ares_channel_t *channel,
484                                         ares_bool_t use_env, const char *ipaddr,
485                                         const ares_hosts_entry_t **entry);
486 ares_status_t ares__hosts_search_host(ares_channel_t *channel,
487                                       ares_bool_t use_env, const char *host,
488                                       const ares_hosts_entry_t **entry);
489 ares_status_t ares__hosts_entry_to_hostent(const ares_hosts_entry_t *entry,
490                                            int                       family,
491                                            struct hostent          **hostent);
492 ares_status_t ares__hosts_entry_to_addrinfo(const ares_hosts_entry_t *entry,
493                                             const char *name, int family,
494                                             unsigned short        port,
495                                             ares_bool_t           want_cnames,
496                                             struct ares_addrinfo *ai);
497 ares_bool_t   ares__isprint(int ch);
498 
499 
500 /*! Parse a compressed DNS name as defined in RFC1035 starting at the current
501  *  offset within the buffer.
502  *
503  *  It is assumed that either a const buffer is being used, or before
504  *  the message processing was started that ares__buf_reclaim() was called.
505  *
506  *  \param[in]  buf        Initialized buffer object
507  *  \param[out] name       Pointer passed by reference to be filled in with
508  *                         allocated string of the parsed name that must be
509  *                         ares_free()'d by the caller.
510  *  \param[in] is_hostname if ARES_TRUE, will validate the character set for
511  *                         a valid hostname or will return error.
512  *  \return ARES_SUCCESS on success
513  */
514 ares_status_t ares__dns_name_parse(ares__buf_t *buf, char **name,
515                                    ares_bool_t is_hostname);
516 
517 /*! Write the DNS name to the buffer in the DNS domain-name syntax as a
518  *  series of labels.  The maximum domain name length is 255 characters with
519  *  each label being a maximum of 63 characters.  If the validate_hostname
520  *  flag is set, it will strictly validate the character set.
521  *
522  *  \param[in,out]  buf   Initialized buffer object to write name to
523  *  \param[in,out]  list  Pointer passed by reference to maintain a list of
524  *                        domain name to indexes used for name compression.
525  *                        Pass NULL (not by reference) if name compression isn't
526  *                        desired.  Otherwise the list will be automatically
527  *                        created upon first entry.
528  *  \param[in]      validate_hostname Validate the hostname character set.
529  *  \param[in]      name              Name to write out, it may have escape
530  *                                    sequences.
531  *  \return ARES_SUCCESS on success, most likely ARES_EBADNAME if the name is
532  *          bad.
533  */
534 ares_status_t ares__dns_name_write(ares__buf_t *buf, ares__llist_t **list,
535                                    ares_bool_t validate_hostname,
536                                    const char *name);
537 
538 /*! Check if the queue is empty, if so, wake any waiters.  This is only
539  *  effective if built with threading support.
540  *
541  *  Must be holding a channel lock when calling this function.
542  *
543  *  \param[in]  channel Initialized ares channel object
544  */
545 void          ares_queue_notify_empty(ares_channel_t *channel);
546 
547 
548 #define ARES_SWAP_BYTE(a, b)           \
549   do {                                 \
550     unsigned char swapByte = *(a);     \
551     *(a)                   = *(b);     \
552     *(b)                   = swapByte; \
553   } while (0)
554 
555 #define SOCK_STATE_CALLBACK(c, s, r, w)                           \
556   do {                                                            \
557     if ((c)->sock_state_cb) {                                     \
558       (c)->sock_state_cb((c)->sock_state_cb_data, (s), (r), (w)); \
559     }                                                             \
560   } while (0)
561 
562 #define ARES_CONFIG_CHECK(x)                                             \
563   (x && x->lookups && ares__slist_len(x->servers) > 0 && x->ndots > 0 && \
564    x->timeout > 0 && x->tries > 0)
565 
566 ares_bool_t   ares__subnet_match(const struct ares_addr *addr,
567                                  const struct ares_addr *subnet,
568                                  unsigned char           netmask);
569 ares_bool_t   ares__addr_is_linklocal(const struct ares_addr *addr);
570 
571 size_t        ares__round_up_pow2(size_t n);
572 size_t        ares__log2(size_t n);
573 size_t        ares__pow(size_t x, size_t y);
574 size_t        ares__count_digits(size_t n);
575 size_t        ares__count_hexdigits(size_t n);
576 unsigned char ares__count_bits_u8(unsigned char x);
577 void          ares__qcache_destroy(ares__qcache_t *cache);
578 ares_status_t ares__qcache_create(ares_rand_state *rand_state,
579                                   unsigned int     max_ttl,
580                                   ares__qcache_t **cache_out);
581 void          ares__qcache_flush(ares__qcache_t *cache);
582 ares_status_t ares_qcache_insert(ares_channel_t       *channel,
583                                  const struct timeval *now,
584                                  const struct query   *query,
585                                  ares_dns_record_t    *dnsrec);
586 ares_status_t ares_qcache_fetch(ares_channel_t       *channel,
587                                 const struct timeval *now,
588                                 const unsigned char *qbuf, size_t qlen,
589                                 unsigned char **abuf, size_t *alen);
590 
591 ares_status_t ares__channel_threading_init(ares_channel_t *channel);
592 void          ares__channel_threading_destroy(ares_channel_t *channel);
593 void          ares__channel_lock(ares_channel_t *channel);
594 void          ares__channel_unlock(ares_channel_t *channel);
595 
596 struct ares_event_thread;
597 typedef struct ares_event_thread ares_event_thread_t;
598 
599 void          ares_event_thread_destroy(ares_channel_t *channel);
600 ares_status_t ares_event_thread_init(ares_channel_t *channel);
601 
602 
603 #ifdef _MSC_VER
604 typedef __int64          ares_int64_t;
605 typedef unsigned __int64 ares_uint64_t;
606 #else
607 typedef long long          ares_int64_t;
608 typedef unsigned long long ares_uint64_t;
609 #endif
610 
611 #ifdef _WIN32
612 #  define HOSTENT_ADDRTYPE_TYPE short
613 #  define HOSTENT_LENGTH_TYPE   short
614 #else
615 #  define HOSTENT_ADDRTYPE_TYPE int
616 #  define HOSTENT_LENGTH_TYPE   int
617 #endif
618 
619 #endif /* __ARES_PRIVATE_H */
620