LCOV - code coverage report
Current view: top level - feature/relay - dns.c (source / functions) Hit Total Coverage
Test: lcov.info Lines: 236 940 25.1 %
Date: 2021-11-24 03:28:48 Functions: 27 61 44.3 %

          Line data    Source code
       1             : /* Copyright (c) 2003-2004, Roger Dingledine.
       2             :  * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
       3             :  * Copyright (c) 2007-2021, The Tor Project, Inc. */
       4             : /* See LICENSE for licensing information */
       5             : 
       6             : /**
       7             :  * \file dns.c
       8             :  * \brief Implements a local cache for DNS results for Tor servers.
       9             :  * This is implemented as a wrapper around Adam Langley's eventdns.c code.
      10             :  * (We can't just use gethostbyname() and friends because we really need to
      11             :  * be nonblocking.)
      12             :  *
      13             :  * There are three main cases when a Tor relay uses dns.c to launch a DNS
      14             :  * request:
      15             :  *   <ol>
      16             :  *    <li>To check whether the DNS server is working more or less correctly.
      17             :  *      This happens via dns_launch_correctness_checks().  The answer is
      18             :  *      reported in the return value from later calls to
      19             :  *      dns_seems_to_be_broken().
      20             :  *    <li>When a client has asked the relay, in a RELAY_BEGIN cell, to connect
      21             :  *      to a given server by hostname.  This happens via dns_resolve().
      22             :  *    <li>When a client has asked the relay, in a RELAY_RESOLVE cell, to look
      23             :  *      up a given server's IP address(es) by hostname. This also happens via
      24             :  *      dns_resolve().
      25             :  *   </ol>
      26             :  *
      27             :  * Each of these gets handled a little differently.
      28             :  *
      29             :  * To check for correctness, we look up some hostname we expect to exist and
      30             :  * have real entries, some hostnames which we expect to definitely not exist,
      31             :  * and some hostnames that we expect to probably not exist.  If too many of
      32             :  * the hostnames that shouldn't exist do exist, that's a DNS hijacking
      33             :  * attempt.  If too many of the hostnames that should exist have the same
      34             :  * addresses as the ones that shouldn't exist, that's a very bad DNS hijacking
      35             :  * attempt, or a very naughty captive portal.  And if the hostnames that
      36             :  * should exist simply don't exist, we probably have a broken nameserver.
      37             :  *
      38             :  * To handle client requests, we first check our cache for answers. If there
      39             :  * isn't something up-to-date, we've got to launch A or AAAA requests as
      40             :  * appropriate.  How we handle responses to those in particular is a bit
      41             :  * complex; see dns_lookup() and set_exitconn_info_from_resolve().
      42             :  *
      43             :  * When a lookup is finally complete, the inform_pending_connections()
      44             :  * function will tell all of the streams that have been waiting for the
      45             :  * resolve, by calling connection_exit_connect() if the client sent a
      46             :  * RELAY_BEGIN cell, and by calling send_resolved_cell() or
      47             :  * send_hostname_cell() if the client sent a RELAY_RESOLVE cell.
      48             :  **/
      49             : 
      50             : #define DNS_PRIVATE
      51             : 
      52             : #include "core/or/or.h"
      53             : #include "app/config/config.h"
      54             : #include "core/mainloop/connection.h"
      55             : #include "core/mainloop/mainloop.h"
      56             : #include "core/mainloop/netstatus.h"
      57             : #include "core/or/circuitlist.h"
      58             : #include "core/or/circuituse.h"
      59             : #include "core/or/connection_edge.h"
      60             : #include "core/or/policies.h"
      61             : #include "core/or/relay.h"
      62             : #include "feature/control/control_events.h"
      63             : #include "feature/relay/dns.h"
      64             : #include "feature/relay/router.h"
      65             : #include "feature/relay/routermode.h"
      66             : #include "feature/stats/rephist.h"
      67             : #include "lib/crypt_ops/crypto_rand.h"
      68             : #include "lib/evloop/compat_libevent.h"
      69             : #include "lib/sandbox/sandbox.h"
      70             : 
      71             : #include "core/or/edge_connection_st.h"
      72             : #include "core/or/or_circuit_st.h"
      73             : 
      74             : #include "ht.h"
      75             : 
      76             : #ifdef HAVE_SYS_STAT_H
      77             : #include <sys/stat.h>
      78             : #endif
      79             : 
      80             : #include <event2/event.h>
      81             : #include <event2/dns.h>
      82             : 
      83             : /** How long will we wait for an answer from the resolver before we decide
      84             :  * that the resolver is wedged? */
      85             : #define RESOLVE_MAX_TIMEOUT 300
      86             : 
      87             : /** Our evdns_base; this structure handles all our name lookups. */
      88             : static struct evdns_base *the_evdns_base = NULL;
      89             : 
      90             : /** Have we currently configured nameservers with eventdns? */
      91             : static int nameservers_configured = 0;
      92             : /** Did our most recent attempt to configure nameservers with eventdns fail? */
      93             : static int nameserver_config_failed = 0;
      94             : /** What was the resolv_conf fname we last used when configuring the
      95             :  * nameservers? Used to check whether we need to reconfigure. */
      96             : static char *resolv_conf_fname = NULL;
      97             : /** What was the mtime on the resolv.conf file we last used when configuring
      98             :  * the nameservers?  Used to check whether we need to reconfigure. */
      99             : static time_t resolv_conf_mtime = 0;
     100             : 
     101             : static void purge_expired_resolves(time_t now);
     102             : static void dns_found_answer(const char *address, uint8_t query_type,
     103             :                              int dns_answer,
     104             :                              const tor_addr_t *addr,
     105             :                              const char *hostname,
     106             :                              uint32_t ttl);
     107             : static void add_wildcarded_test_address(const char *address);
     108             : static int configure_nameservers(int force);
     109             : static int answer_is_wildcarded(const char *ip);
     110             : static int evdns_err_is_transient(int err);
     111             : static void inform_pending_connections(cached_resolve_t *resolve);
     112             : static void make_pending_resolve_cached(cached_resolve_t *cached);
     113             : 
     114             : #ifdef DEBUG_DNS_CACHE
     115             : static void assert_cache_ok_(void);
     116             : #define assert_cache_ok() assert_cache_ok_()
     117             : #else
     118             : #define assert_cache_ok() STMT_NIL
     119             : #endif /* defined(DEBUG_DNS_CACHE) */
     120             : static void assert_resolve_ok(cached_resolve_t *resolve);
     121             : 
     122             : /** Hash table of cached_resolve objects. */
     123             : static HT_HEAD(cache_map, cached_resolve_t) cache_root;
     124             : 
     125             : /** Global: how many IPv6 requests have we made in all? */
     126             : static uint64_t n_ipv6_requests_made = 0;
     127             : /** Global: how many IPv6 requests have timed out? */
     128             : static uint64_t n_ipv6_timeouts = 0;
     129             : /** Global: Do we think that IPv6 DNS is broken? */
     130             : static int dns_is_broken_for_ipv6 = 0;
     131             : 
     132             : /** Function to compare hashed resolves on their addresses; used to
     133             :  * implement hash tables. */
     134             : static inline int
     135           3 : cached_resolves_eq(cached_resolve_t *a, cached_resolve_t *b)
     136             : {
     137             :   /* make this smarter one day? */
     138           3 :   assert_resolve_ok(a); // Not b; b may be just a search.
     139           3 :   return !strncmp(a->address, b->address, MAX_ADDRESSLEN);
     140             : }
     141             : 
     142             : /** Hash function for cached_resolve objects */
     143             : static inline unsigned int
     144           7 : cached_resolve_hash(cached_resolve_t *a)
     145             : {
     146           7 :   return (unsigned) siphash24g((const uint8_t*)a->address, strlen(a->address));
     147             : }
     148             : 
     149         486 : HT_PROTOTYPE(cache_map, cached_resolve_t, node, cached_resolve_hash,
     150             :              cached_resolves_eq);
     151         238 : HT_GENERATE2(cache_map, cached_resolve_t, node, cached_resolve_hash,
     152             :              cached_resolves_eq, 0.6, tor_reallocarray_, tor_free_);
     153             : 
     154             : /** Initialize the DNS cache. */
     155             : static void
     156           5 : init_cache_map(void)
     157             : {
     158           5 :   HT_INIT(cache_map, &cache_root);
     159           5 : }
     160             : 
     161             : /** Helper: called by eventdns when eventdns wants to log something. */
     162             : static void
     163          10 : evdns_log_cb(int warn, const char *msg)
     164             : {
     165          10 :   const char *cp;
     166          10 :   static int all_down = 0;
     167          10 :   int severity = warn ? LOG_WARN : LOG_INFO;
     168          10 :   if (!strcmpstart(msg, "Resolve requested for") &&
     169           0 :       get_options()->SafeLogging) {
     170           0 :     log_info(LD_EXIT, "eventdns: Resolve requested.");
     171           0 :     return;
     172          10 :   } else if (!strcmpstart(msg, "Search: ")) {
     173             :     return;
     174             :   }
     175          10 :   if (!strcmpstart(msg, "Nameserver ") && (cp=strstr(msg, " has failed: "))) {
     176           0 :     char *ns = tor_strndup(msg+11, cp-(msg+11));
     177           0 :     const char *colon = strchr(cp, ':');
     178           0 :     tor_assert(colon);
     179           0 :     const char *err = colon+2;
     180             :     /* Don't warn about a single failed nameserver; we'll warn with 'all
     181             :      * nameservers have failed' if we're completely out of nameservers;
     182             :      * otherwise, the situation is tolerable. */
     183           0 :     severity = LOG_INFO;
     184           0 :     control_event_server_status(LOG_NOTICE,
     185             :                                 "NAMESERVER_STATUS NS=%s STATUS=DOWN ERR=%s",
     186             :                                 ns, escaped(err));
     187           0 :     tor_free(ns);
     188          10 :   } else if (!strcmpstart(msg, "Nameserver ") &&
     189           0 :              (cp=strstr(msg, " is back up"))) {
     190           0 :     char *ns = tor_strndup(msg+11, cp-(msg+11));
     191           0 :     severity = (all_down && warn) ? LOG_NOTICE : LOG_INFO;
     192           0 :     all_down = 0;
     193           0 :     control_event_server_status(LOG_NOTICE,
     194             :                                 "NAMESERVER_STATUS NS=%s STATUS=UP", ns);
     195           0 :     tor_free(ns);
     196          10 :   } else if (!strcmp(msg, "All nameservers have failed")) {
     197           0 :     control_event_server_status(LOG_WARN, "NAMESERVER_ALL_DOWN");
     198           0 :     all_down = 1;
     199          10 :   } else if (!strcmpstart(msg, "Address mismatch on received DNS")) {
     200           0 :     static ratelim_t mismatch_limit = RATELIM_INIT(3600);
     201           0 :     const char *src = strstr(msg, " Apparent source");
     202           0 :     if (!src || get_options()->SafeLogging) {
     203             :       src = "";
     204             :     }
     205           0 :     log_fn_ratelim(&mismatch_limit, severity, LD_EXIT,
     206             :                    "eventdns: Received a DNS packet from "
     207             :                    "an IP address to which we did not send a request. This "
     208             :                    "could be a DNS spoofing attempt, or some kind of "
     209             :                    "misconfiguration.%s", src);
     210           0 :     return;
     211             :   }
     212          10 :   tor_log(severity, LD_EXIT, "eventdns: %s", msg);
     213             : }
     214             : 
     215             : /** Initialize the DNS subsystem; called by the OR process. */
     216             : int
     217           5 : dns_init(void)
     218             : {
     219           5 :   init_cache_map();
     220           5 :   if (server_mode(get_options())) {
     221           2 :     int r = configure_nameservers(1);
     222           2 :     return r;
     223             :   }
     224             :   return 0;
     225             : }
     226             : 
     227             : /** Called when DNS-related options change (or may have changed).  Returns -1
     228             :  * on failure, 0 on success. */
     229             : int
     230           0 : dns_reset(void)
     231             : {
     232           0 :   const or_options_t *options = get_options();
     233           0 :   if (! server_mode(options)) {
     234             : 
     235           0 :     if (!the_evdns_base) {
     236           0 :       if (!(the_evdns_base = evdns_base_new(tor_libevent_get_base(), 0))) {
     237           0 :         log_err(LD_BUG, "Couldn't create an evdns_base");
     238           0 :         return -1;
     239             :       }
     240             :     }
     241             : 
     242           0 :     evdns_base_clear_nameservers_and_suspend(the_evdns_base);
     243           0 :     evdns_base_search_clear(the_evdns_base);
     244           0 :     nameservers_configured = 0;
     245           0 :     tor_free(resolv_conf_fname);
     246           0 :     resolv_conf_mtime = 0;
     247             :   } else {
     248           0 :     if (configure_nameservers(0) < 0) {
     249           0 :       return -1;
     250             :     }
     251             :   }
     252             :   return 0;
     253             : }
     254             : 
     255             : /** Return true iff the most recent attempt to initialize the DNS subsystem
     256             :  * failed. */
     257             : int
     258           0 : has_dns_init_failed(void)
     259             : {
     260           0 :   return nameserver_config_failed;
     261             : }
     262             : 
     263             : /** Helper: free storage held by an entry in the DNS cache. */
     264             : static void
     265           0 : free_cached_resolve_(cached_resolve_t *r)
     266             : {
     267           0 :   if (!r)
     268             :     return;
     269           0 :   while (r->pending_connections) {
     270           0 :     pending_connection_t *victim = r->pending_connections;
     271           0 :     r->pending_connections = victim->next;
     272           0 :     tor_free(victim);
     273             :   }
     274           0 :   if (r->res_status_hostname == RES_STATUS_DONE_OK)
     275           0 :     tor_free(r->result_ptr.hostname);
     276           0 :   r->magic = 0xFF00FF00;
     277           0 :   tor_free(r);
     278             : }
     279             : 
     280             : /** Compare two cached_resolve_t pointers by expiry time, and return
     281             :  * less-than-zero, zero, or greater-than-zero as appropriate. Used for
     282             :  * the priority queue implementation. */
     283             : static int
     284           0 : compare_cached_resolves_by_expiry_(const void *_a, const void *_b)
     285             : {
     286           0 :   const cached_resolve_t *a = _a, *b = _b;
     287           0 :   if (a->expire < b->expire)
     288             :     return -1;
     289           0 :   else if (a->expire == b->expire)
     290             :     return 0;
     291             :   else
     292           0 :     return 1;
     293             : }
     294             : 
     295             : /** Priority queue of cached_resolve_t objects to let us know when they
     296             :  * will expire. */
     297             : static smartlist_t *cached_resolve_pqueue = NULL;
     298             : 
     299             : static void
     300           0 : cached_resolve_add_answer(cached_resolve_t *resolve,
     301             :                           int query_type,
     302             :                           int dns_result,
     303             :                           const tor_addr_t *answer_addr,
     304             :                           const char *answer_hostname,
     305             :                           uint32_t ttl)
     306             : {
     307           0 :   if (query_type == DNS_PTR) {
     308           0 :     if (resolve->res_status_hostname != RES_STATUS_INFLIGHT)
     309             :       return;
     310             : 
     311           0 :     if (dns_result == DNS_ERR_NONE && answer_hostname) {
     312           0 :       resolve->result_ptr.hostname = tor_strdup(answer_hostname);
     313           0 :       resolve->res_status_hostname = RES_STATUS_DONE_OK;
     314             :     } else {
     315           0 :       resolve->result_ptr.err_hostname = dns_result;
     316           0 :       resolve->res_status_hostname = RES_STATUS_DONE_ERR;
     317             :     }
     318           0 :     resolve->ttl_hostname = ttl;
     319           0 :   } else if (query_type == DNS_IPv4_A) {
     320           0 :     if (resolve->res_status_ipv4 != RES_STATUS_INFLIGHT)
     321             :       return;
     322             : 
     323           0 :     if (dns_result == DNS_ERR_NONE && answer_addr &&
     324           0 :         tor_addr_family(answer_addr) == AF_INET) {
     325           0 :       resolve->result_ipv4.addr_ipv4 = tor_addr_to_ipv4h(answer_addr);
     326           0 :       resolve->res_status_ipv4 = RES_STATUS_DONE_OK;
     327             :     } else {
     328           0 :       resolve->result_ipv4.err_ipv4 = dns_result;
     329           0 :       resolve->res_status_ipv4 = RES_STATUS_DONE_ERR;
     330             :     }
     331           0 :     resolve->ttl_ipv4 = ttl;
     332           0 :   } else if (query_type == DNS_IPv6_AAAA) {
     333           0 :     if (resolve->res_status_ipv6 != RES_STATUS_INFLIGHT)
     334             :       return;
     335             : 
     336           0 :     if (dns_result == DNS_ERR_NONE && answer_addr &&
     337           0 :         tor_addr_family(answer_addr) == AF_INET6) {
     338           0 :       memcpy(&resolve->result_ipv6.addr_ipv6,
     339           0 :              tor_addr_to_in6(answer_addr),
     340             :              sizeof(struct in6_addr));
     341           0 :       resolve->res_status_ipv6 = RES_STATUS_DONE_OK;
     342             :     } else {
     343           0 :       resolve->result_ipv6.err_ipv6 = dns_result;
     344           0 :       resolve->res_status_ipv6 = RES_STATUS_DONE_ERR;
     345             :     }
     346           0 :     resolve->ttl_ipv6 = ttl;
     347             :   }
     348             : }
     349             : 
     350             : /** Return true iff there are no in-flight requests for <b>resolve</b>. */
     351             : static int
     352           0 : cached_resolve_have_all_answers(const cached_resolve_t *resolve)
     353             : {
     354           0 :   return (resolve->res_status_ipv4 != RES_STATUS_INFLIGHT &&
     355           0 :           resolve->res_status_ipv6 != RES_STATUS_INFLIGHT &&
     356           0 :           resolve->res_status_hostname != RES_STATUS_INFLIGHT);
     357             : }
     358             : 
     359             : /** Set an expiry time for a cached_resolve_t, and add it to the expiry
     360             :  * priority queue */
     361             : static void
     362           1 : set_expiry(cached_resolve_t *resolve, time_t expires)
     363             : {
     364           1 :   tor_assert(resolve && resolve->expire == 0);
     365           1 :   if (!cached_resolve_pqueue)
     366           1 :     cached_resolve_pqueue = smartlist_new();
     367           1 :   resolve->expire = expires;
     368           1 :   smartlist_pqueue_add(cached_resolve_pqueue,
     369             :                        compare_cached_resolves_by_expiry_,
     370             :                        offsetof(cached_resolve_t, minheap_idx),
     371             :                        resolve);
     372           1 : }
     373             : 
     374             : /** Free all storage held in the DNS cache and related structures. */
     375             : void
     376         235 : dns_free_all(void)
     377             : {
     378         235 :   cached_resolve_t **ptr, **next, *item;
     379         235 :   assert_cache_ok();
     380         235 :   if (cached_resolve_pqueue) {
     381           0 :     SMARTLIST_FOREACH(cached_resolve_pqueue, cached_resolve_t *, res,
     382             :       {
     383             :         if (res->state == CACHE_STATE_DONE)
     384             :           free_cached_resolve_(res);
     385             :       });
     386             :   }
     387         235 :   for (ptr = HT_START(cache_map, &cache_root); ptr != NULL; ptr = next) {
     388           0 :     item = *ptr;
     389           0 :     next = HT_NEXT_RMV(cache_map, &cache_root, ptr);
     390           0 :     free_cached_resolve_(item);
     391             :   }
     392         235 :   HT_CLEAR(cache_map, &cache_root);
     393         235 :   smartlist_free(cached_resolve_pqueue);
     394         235 :   cached_resolve_pqueue = NULL;
     395         235 :   tor_free(resolv_conf_fname);
     396         235 : }
     397             : 
     398             : /** Remove every cached_resolve whose <b>expire</b> time is before or
     399             :  * equal to <b>now</b> from the cache. */
     400             : static void
     401           5 : purge_expired_resolves(time_t now)
     402             : {
     403           5 :   cached_resolve_t *resolve, *removed;
     404           5 :   pending_connection_t *pend;
     405           5 :   edge_connection_t *pendconn;
     406             : 
     407           5 :   assert_cache_ok();
     408           5 :   if (!cached_resolve_pqueue)
     409           5 :     return;
     410             : 
     411           0 :   while (smartlist_len(cached_resolve_pqueue)) {
     412           0 :     resolve = smartlist_get(cached_resolve_pqueue, 0);
     413           0 :     if (resolve->expire > now)
     414             :       break;
     415           0 :     smartlist_pqueue_pop(cached_resolve_pqueue,
     416             :                          compare_cached_resolves_by_expiry_,
     417             :                          offsetof(cached_resolve_t, minheap_idx));
     418             : 
     419           0 :     if (resolve->state == CACHE_STATE_PENDING) {
     420           0 :       log_debug(LD_EXIT,
     421             :                 "Expiring a dns resolve %s that's still pending. Forgot to "
     422             :                 "cull it? DNS resolve didn't tell us about the timeout?",
     423             :                 escaped_safe_str(resolve->address));
     424           0 :     } else if (resolve->state == CACHE_STATE_CACHED) {
     425           0 :       log_debug(LD_EXIT,
     426             :                 "Forgetting old cached resolve (address %s, expires %lu)",
     427             :                 escaped_safe_str(resolve->address),
     428             :                 (unsigned long)resolve->expire);
     429           0 :       tor_assert(!resolve->pending_connections);
     430             :     } else {
     431           0 :       tor_assert(resolve->state == CACHE_STATE_DONE);
     432           0 :       tor_assert(!resolve->pending_connections);
     433             :     }
     434             : 
     435           0 :     if (resolve->pending_connections) {
     436           0 :       log_debug(LD_EXIT,
     437             :                 "Closing pending connections on timed-out DNS resolve!");
     438           0 :       while (resolve->pending_connections) {
     439           0 :         pend = resolve->pending_connections;
     440           0 :         resolve->pending_connections = pend->next;
     441             :         /* Connections should only be pending if they have no socket. */
     442           0 :         tor_assert(!SOCKET_OK(pend->conn->base_.s));
     443           0 :         pendconn = pend->conn;
     444             :         /* Prevent double-remove */
     445           0 :         pendconn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
     446           0 :         if (!pendconn->base_.marked_for_close) {
     447           0 :           connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT);
     448           0 :           circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
     449           0 :           connection_free_(TO_CONN(pendconn));
     450             :         }
     451           0 :         tor_free(pend);
     452             :       }
     453             :     }
     454             : 
     455           0 :     if (resolve->state == CACHE_STATE_CACHED ||
     456             :         resolve->state == CACHE_STATE_PENDING) {
     457           0 :       removed = HT_REMOVE(cache_map, &cache_root, resolve);
     458           0 :       if (removed != resolve) {
     459           0 :         log_err(LD_BUG, "The expired resolve we purged didn't match any in"
     460             :                 " the cache. Tried to purge %s (%p); instead got %s (%p).",
     461             :                 resolve->address, (void*)resolve,
     462             :                 removed ? removed->address : "NULL", (void*)removed);
     463             :       }
     464           0 :       tor_assert(removed == resolve);
     465             :     } else {
     466             :       /* This should be in state DONE. Make sure it's not in the cache. */
     467           0 :       cached_resolve_t *tmp = HT_FIND(cache_map, &cache_root, resolve);
     468           0 :       tor_assert(tmp != resolve);
     469             :     }
     470           0 :     if (resolve->res_status_hostname == RES_STATUS_DONE_OK)
     471           0 :       tor_free(resolve->result_ptr.hostname);
     472           0 :     resolve->magic = 0xF0BBF0BB;
     473           0 :     tor_free(resolve);
     474             :   }
     475             : 
     476             :   assert_cache_ok();
     477             : }
     478             : 
     479             : /* argument for send_resolved_cell only, meaning "let the answer type be ipv4
     480             :  * or ipv6 depending on the connection's address". */
     481             : #define RESOLVED_TYPE_AUTO 0xff
     482             : 
     483             : /** Send a response to the RESOLVE request of a connection.
     484             :  * <b>answer_type</b> must be one of
     485             :  * RESOLVED_TYPE_(AUTO|ERROR|ERROR_TRANSIENT|).
     486             :  *
     487             :  * If <b>circ</b> is provided, and we have a cached answer, send the
     488             :  * answer back along circ; otherwise, send the answer back along
     489             :  * <b>conn</b>'s attached circuit.
     490             :  */
     491           0 : MOCK_IMPL(STATIC void,
     492             : send_resolved_cell,(edge_connection_t *conn, uint8_t answer_type,
     493             :                     const cached_resolve_t *resolved))
     494             : {
     495           0 :   char buf[RELAY_PAYLOAD_SIZE], *cp = buf;
     496           0 :   size_t buflen = 0;
     497           0 :   uint32_t ttl;
     498             : 
     499           0 :   buf[0] = answer_type;
     500           0 :   ttl = clip_dns_ttl(conn->address_ttl);
     501             : 
     502           0 :   switch (answer_type)
     503             :     {
     504           0 :     case RESOLVED_TYPE_AUTO:
     505           0 :       if (resolved && resolved->res_status_ipv4 == RES_STATUS_DONE_OK) {
     506           0 :         cp[0] = RESOLVED_TYPE_IPV4;
     507           0 :         cp[1] = 4;
     508           0 :         set_uint32(cp+2, htonl(resolved->result_ipv4.addr_ipv4));
     509           0 :         set_uint32(cp+6, htonl(ttl));
     510           0 :         cp += 10;
     511             :       }
     512           0 :       if (resolved && resolved->res_status_ipv6 == RES_STATUS_DONE_OK) {
     513           0 :         const uint8_t *bytes = resolved->result_ipv6.addr_ipv6.s6_addr;
     514           0 :         cp[0] = RESOLVED_TYPE_IPV6;
     515           0 :         cp[1] = 16;
     516           0 :         memcpy(cp+2, bytes, 16);
     517           0 :         set_uint32(cp+18, htonl(ttl));
     518           0 :         cp += 22;
     519             :       }
     520           0 :       if (cp != buf) {
     521           0 :         buflen = cp - buf;
     522           0 :         break;
     523             :       } else {
     524             :         answer_type = RESOLVED_TYPE_ERROR;
     525             :         /* We let this fall through and treat it as an error. */
     526             :       }
     527           0 :       FALLTHROUGH;
     528           0 :     case RESOLVED_TYPE_ERROR_TRANSIENT:
     529             :     case RESOLVED_TYPE_ERROR:
     530             :       {
     531           0 :         const char *errmsg = "Error resolving hostname";
     532           0 :         size_t msglen = strlen(errmsg);
     533             : 
     534           0 :         buf[0] = answer_type;
     535           0 :         buf[1] = msglen;
     536           0 :         strlcpy(buf+2, errmsg, sizeof(buf)-2);
     537           0 :         set_uint32(buf+2+msglen, htonl(ttl));
     538           0 :         buflen = 6+msglen;
     539           0 :         break;
     540             :       }
     541             :     default:
     542           0 :       tor_assert(0);
     543             :       return;
     544             :     }
     545             :   // log_notice(LD_EXIT, "Sending a regular RESOLVED reply: ");
     546             : 
     547           0 :   connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
     548             : }
     549             : 
     550             : /** Send a response to the RESOLVE request of a connection for an in-addr.arpa
     551             :  * address on connection <b>conn</b> which yielded the result <b>hostname</b>.
     552             :  * The answer type will be RESOLVED_HOSTNAME.
     553             :  *
     554             :  * If <b>circ</b> is provided, and we have a cached answer, send the
     555             :  * answer back along circ; otherwise, send the answer back along
     556             :  * <b>conn</b>'s attached circuit.
     557             :  */
     558           0 : MOCK_IMPL(STATIC void,
     559             : send_resolved_hostname_cell,(edge_connection_t *conn,
     560             :                              const char *hostname))
     561             : {
     562           0 :   char buf[RELAY_PAYLOAD_SIZE];
     563           0 :   size_t buflen;
     564           0 :   uint32_t ttl;
     565             : 
     566           0 :   if (BUG(!hostname))
     567           0 :     return;
     568             : 
     569           0 :   size_t namelen = strlen(hostname);
     570             : 
     571           0 :   tor_assert(namelen < 256);
     572           0 :   ttl = clip_dns_ttl(conn->address_ttl);
     573             : 
     574           0 :   buf[0] = RESOLVED_TYPE_HOSTNAME;
     575           0 :   buf[1] = (uint8_t)namelen;
     576           0 :   memcpy(buf+2, hostname, namelen);
     577           0 :   set_uint32(buf+2+namelen, htonl(ttl));
     578           0 :   buflen = 2+namelen+4;
     579             : 
     580             :   // log_notice(LD_EXIT, "Sending a reply RESOLVED reply: %s", hostname);
     581           0 :   connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
     582             :   // log_notice(LD_EXIT, "Sent");
     583             : }
     584             : 
     585             : /** See if we have a cache entry for <b>exitconn</b>-\>address. If so,
     586             :  * if resolve valid, put it into <b>exitconn</b>-\>addr and return 1.
     587             :  * If resolve failed, free exitconn and return -1.
     588             :  *
     589             :  * (For EXIT_PURPOSE_RESOLVE connections, send back a RESOLVED error cell
     590             :  * on returning -1.  For EXIT_PURPOSE_CONNECT connections, there's no
     591             :  * need to send back an END cell, since connection_exit_begin_conn will
     592             :  * do that for us.)
     593             :  *
     594             :  * If we have a cached answer, send the answer back along <b>exitconn</b>'s
     595             :  * circuit.
     596             :  *
     597             :  * Else, if seen before and pending, add conn to the pending list,
     598             :  * and return 0.
     599             :  *
     600             :  * Else, if not seen before, add conn to pending list, hand to
     601             :  * dns farm, and return 0.
     602             :  *
     603             :  * Exitconn's on_circuit field must be set, but exitconn should not
     604             :  * yet be linked onto the n_streams/resolving_streams list of that circuit.
     605             :  * On success, link the connection to n_streams if it's an exit connection.
     606             :  * On "pending", link the connection to resolving streams.  Otherwise,
     607             :  * clear its on_circuit field.
     608             :  */
     609             : int
     610           5 : dns_resolve(edge_connection_t *exitconn)
     611             : {
     612           5 :   or_circuit_t *oncirc = TO_OR_CIRCUIT(exitconn->on_circuit);
     613           5 :   int is_resolve, r;
     614           5 :   int made_connection_pending = 0;
     615           5 :   char *hostname = NULL;
     616           5 :   cached_resolve_t *resolve = NULL;
     617           5 :   is_resolve = exitconn->base_.purpose == EXIT_PURPOSE_RESOLVE;
     618             : 
     619           5 :   r = dns_resolve_impl(exitconn, is_resolve, oncirc, &hostname,
     620             :                        &made_connection_pending, &resolve);
     621             : 
     622           5 :   switch (r) {
     623           3 :     case 1:
     624             :       /* We got an answer without a lookup -- either the answer was
     625             :        * cached, or it was obvious (like an IP address). */
     626           3 :       if (is_resolve) {
     627             :         /* Send the answer back right now, and detach. */
     628           2 :         if (hostname)
     629           1 :           send_resolved_hostname_cell(exitconn, hostname);
     630             :         else
     631           1 :           send_resolved_cell(exitconn, RESOLVED_TYPE_AUTO, resolve);
     632           2 :         exitconn->on_circuit = NULL;
     633             :       } else {
     634             :         /* Add to the n_streams list; the calling function will send back a
     635             :          * connected cell. */
     636           1 :         exitconn->next_stream = oncirc->n_streams;
     637           1 :         oncirc->n_streams = exitconn;
     638             :       }
     639             :       break;
     640           1 :     case 0:
     641             :       /* The request is pending: add the connection into the linked list of
     642             :        * resolving_streams on this circuit. */
     643           1 :       exitconn->base_.state = EXIT_CONN_STATE_RESOLVING;
     644           1 :       exitconn->next_stream = oncirc->resolving_streams;
     645           1 :       oncirc->resolving_streams = exitconn;
     646           1 :       break;
     647           1 :     case -2:
     648             :     case -1:
     649             :       /* The request failed before it could start: cancel this connection,
     650             :        * and stop everybody waiting for the same connection. */
     651           1 :       if (is_resolve) {
     652           1 :         send_resolved_cell(exitconn,
     653             :              (r == -1) ? RESOLVED_TYPE_ERROR : RESOLVED_TYPE_ERROR_TRANSIENT,
     654             :              NULL);
     655             :       }
     656             : 
     657           1 :       exitconn->on_circuit = NULL;
     658             : 
     659           1 :       dns_cancel_pending_resolve(exitconn->base_.address);
     660             : 
     661           1 :       if (!made_connection_pending && !exitconn->base_.marked_for_close) {
     662             :         /* If we made the connection pending, then we freed it already in
     663             :          * dns_cancel_pending_resolve().  If we marked it for close, it'll
     664             :          * get freed from the main loop.  Otherwise, can free it now. */
     665           1 :         connection_free_(TO_CONN(exitconn));
     666             :       }
     667             :       break;
     668             :     default:
     669           0 :       tor_assert(0);
     670             :   }
     671             : 
     672           5 :   tor_free(hostname);
     673           5 :   return r;
     674             : }
     675             : 
     676             : /** Helper function for dns_resolve: same functionality, but does not handle:
     677             :  *     - marking connections on error and clearing their on_circuit
     678             :  *     - linking connections to n_streams/resolving_streams,
     679             :  *     - sending resolved cells if we have an answer/error right away,
     680             :  *
     681             :  * Return -2 on a transient error. If it's a reverse resolve and it's
     682             :  * successful, sets *<b>hostname_out</b> to a newly allocated string
     683             :  * holding the cached reverse DNS value.
     684             :  *
     685             :  * Set *<b>made_connection_pending_out</b> to true if we have placed
     686             :  * <b>exitconn</b> on the list of pending connections for some resolve; set it
     687             :  * to false otherwise.
     688             :  *
     689             :  * Set *<b>resolve_out</b> to a cached resolve, if we found one.
     690             :  */
     691           8 : MOCK_IMPL(STATIC int,
     692             : dns_resolve_impl,(edge_connection_t *exitconn, int is_resolve,
     693             :                  or_circuit_t *oncirc, char **hostname_out,
     694             :                  int *made_connection_pending_out,
     695             :                  cached_resolve_t **resolve_out))
     696             : {
     697           8 :   cached_resolve_t *resolve;
     698           8 :   cached_resolve_t search;
     699           8 :   pending_connection_t *pending_connection;
     700           8 :   int is_reverse = 0;
     701           8 :   tor_addr_t addr;
     702           8 :   time_t now = time(NULL);
     703           8 :   int r;
     704           8 :   assert_connection_ok(TO_CONN(exitconn), 0);
     705           8 :   tor_assert(!SOCKET_OK(exitconn->base_.s));
     706           8 :   assert_cache_ok();
     707           8 :   tor_assert(oncirc);
     708           8 :   *made_connection_pending_out = 0;
     709             : 
     710             :   /* first check if exitconn->base_.address is an IP. If so, we already
     711             :    * know the answer. */
     712           8 :   if (tor_addr_parse(&addr, exitconn->base_.address) >= 0) {
     713           1 :     if (tor_addr_family(&addr) == AF_INET ||
     714             :         tor_addr_family(&addr) == AF_INET6) {
     715           1 :       tor_addr_copy(&exitconn->base_.addr, &addr);
     716           1 :       exitconn->address_ttl = DEFAULT_DNS_TTL;
     717           1 :       return 1;
     718             :     } else {
     719             :       /* XXXX unspec? Bogus? */
     720             :       return -1;
     721             :     }
     722             :   }
     723             : 
     724             :   /* If we're a non-exit, don't even do DNS lookups. */
     725           7 :   if (router_my_exit_policy_is_reject_star())
     726             :     return -1;
     727             : 
     728           6 :   if (address_is_invalid_destination(exitconn->base_.address, 0)) {
     729           1 :     tor_log(LOG_PROTOCOL_WARN, LD_EXIT,
     730             :         "Rejecting invalid destination address %s",
     731           1 :         escaped_safe_str(exitconn->base_.address));
     732           1 :     return -1;
     733             :   }
     734             : 
     735             :   /* then take this opportunity to see if there are any expired
     736             :    * resolves in the hash table. */
     737           5 :   purge_expired_resolves(now);
     738             : 
     739             :   /* lower-case exitconn->base_.address, so it's in canonical form */
     740           5 :   tor_strlower(exitconn->base_.address);
     741             : 
     742             :   /* Check whether this is a reverse lookup.  If it's malformed, or it's a
     743             :    * .in-addr.arpa address but this isn't a resolve request, kill the
     744             :    * connection.
     745             :    */
     746           5 :   if ((r = tor_addr_parse_PTR_name(&addr, exitconn->base_.address,
     747             :                                               AF_UNSPEC, 0)) != 0) {
     748           2 :     if (r == 1) {
     749           1 :       is_reverse = 1;
     750           1 :       if (tor_addr_is_internal(&addr, 0)) /* internal address? */
     751             :         return -1;
     752             :     }
     753             : 
     754           1 :     if (!is_reverse || !is_resolve) {
     755           1 :       if (!is_reverse)
     756           1 :         log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.",
     757             :                  escaped_safe_str(exitconn->base_.address));
     758           0 :       else if (!is_resolve)
     759           0 :         log_info(LD_EXIT,
     760             :                  "Attempt to connect to a .in-addr.arpa address \"%s\"; "
     761             :                  "sending error.",
     762             :                  escaped_safe_str(exitconn->base_.address));
     763             : 
     764           1 :       return -1;
     765             :     }
     766             :     //log_notice(LD_EXIT, "Looks like an address %s",
     767             :     //exitconn->base_.address);
     768             :   }
     769           3 :   exitconn->is_reverse_dns_lookup = is_reverse;
     770             : 
     771             :   /* now check the hash table to see if 'address' is already there. */
     772           3 :   strlcpy(search.address, exitconn->base_.address, sizeof(search.address));
     773           3 :   resolve = HT_FIND(cache_map, &cache_root, &search);
     774           3 :   if (resolve && resolve->expire > now) { /* already there */
     775           2 :     switch (resolve->state) {
     776           1 :       case CACHE_STATE_PENDING:
     777             :         /* add us to the pending list */
     778           1 :         pending_connection = tor_malloc_zero(
     779             :                                       sizeof(pending_connection_t));
     780           1 :         pending_connection->conn = exitconn;
     781           1 :         pending_connection->next = resolve->pending_connections;
     782           1 :         resolve->pending_connections = pending_connection;
     783           1 :         *made_connection_pending_out = 1;
     784           1 :         log_debug(LD_EXIT,"Connection (fd "TOR_SOCKET_T_FORMAT") waiting "
     785             :                   "for pending DNS resolve of %s", exitconn->base_.s,
     786             :                   escaped_safe_str(exitconn->base_.address));
     787           1 :         return 0;
     788             :       case CACHE_STATE_CACHED:
     789           1 :         log_debug(LD_EXIT,"Connection (fd "TOR_SOCKET_T_FORMAT") found "
     790             :                   "cached answer for %s",
     791             :                   exitconn->base_.s,
     792             :                   escaped_safe_str(resolve->address));
     793             : 
     794           1 :         *resolve_out = resolve;
     795             : 
     796           1 :         return set_exitconn_info_from_resolve(exitconn, resolve, hostname_out);
     797           0 :       case CACHE_STATE_DONE:
     798           0 :         log_err(LD_BUG, "Found a 'DONE' dns resolve still in the cache.");
     799           0 :         tor_fragile_assert();
     800             :     }
     801           0 :     tor_assert(0);
     802             :   }
     803           1 :   tor_assert(!resolve);
     804             :   /* not there, need to add it */
     805           1 :   resolve = tor_malloc_zero(sizeof(cached_resolve_t));
     806           1 :   resolve->magic = CACHED_RESOLVE_MAGIC;
     807           1 :   resolve->state = CACHE_STATE_PENDING;
     808           1 :   resolve->minheap_idx = -1;
     809           1 :   strlcpy(resolve->address, exitconn->base_.address, sizeof(resolve->address));
     810             : 
     811             :   /* add this connection to the pending list */
     812           1 :   pending_connection = tor_malloc_zero(sizeof(pending_connection_t));
     813           1 :   pending_connection->conn = exitconn;
     814           1 :   resolve->pending_connections = pending_connection;
     815           1 :   *made_connection_pending_out = 1;
     816             : 
     817             :   /* Add this resolve to the cache and priority queue. */
     818           1 :   HT_INSERT(cache_map, &cache_root, resolve);
     819           1 :   set_expiry(resolve, now + RESOLVE_MAX_TIMEOUT);
     820             : 
     821           1 :   log_debug(LD_EXIT,"Launching %s.",
     822             :             escaped_safe_str(exitconn->base_.address));
     823           1 :   assert_cache_ok();
     824             : 
     825           1 :   return launch_resolve(resolve);
     826             : }
     827             : 
     828             : /** Given an exit connection <b>exitconn</b>, and a cached_resolve_t
     829             :  * <b>resolve</b> whose DNS lookups have all either succeeded or failed,
     830             :  * update the appropriate fields (address_ttl and addr) of <b>exitconn</b>.
     831             :  *
     832             :  * The logic can be complicated here, since we might have launched both
     833             :  * an A lookup and an AAAA lookup, and since either of those might have
     834             :  * succeeded or failed, and since we want to answer a RESOLVE cell with
     835             :  * a full answer but answer a BEGIN cell with whatever answer the client
     836             :  * would accept <i>and</i> we could still connect to.
     837             :  *
     838             :  * If this is a reverse lookup, set *<b>hostname_out</b> to a newly allocated
     839             :  * copy of the name resulting hostname.
     840             :  *
     841             :  * Return -2 on a transient error, -1 on a permenent error, and 1 on
     842             :  * a successful lookup.
     843             :  */
     844           0 : MOCK_IMPL(STATIC int,
     845             : set_exitconn_info_from_resolve,(edge_connection_t *exitconn,
     846             :                                 const cached_resolve_t *resolve,
     847             :                                 char **hostname_out))
     848             : {
     849           0 :   int ipv4_ok, ipv6_ok, answer_with_ipv4, r;
     850           0 :   uint32_t begincell_flags;
     851           0 :   const int is_resolve = exitconn->base_.purpose == EXIT_PURPOSE_RESOLVE;
     852           0 :   tor_assert(exitconn);
     853           0 :   tor_assert(resolve);
     854             : 
     855           0 :   if (exitconn->is_reverse_dns_lookup) {
     856           0 :     exitconn->address_ttl = resolve->ttl_hostname;
     857           0 :     if (resolve->res_status_hostname == RES_STATUS_DONE_OK) {
     858           0 :       *hostname_out = tor_strdup(resolve->result_ptr.hostname);
     859           0 :       return 1;
     860             :     } else {
     861             :       return -1;
     862             :     }
     863             :   }
     864             : 
     865             :   /* If we're here then the connection wants one or either of ipv4, ipv6, and
     866             :    * we can give it one or both. */
     867           0 :   if (is_resolve) {
     868             :     begincell_flags = BEGIN_FLAG_IPV6_OK;
     869             :   } else {
     870           0 :     begincell_flags = exitconn->begincell_flags;
     871             :   }
     872             : 
     873           0 :   ipv4_ok = (resolve->res_status_ipv4 == RES_STATUS_DONE_OK) &&
     874           0 :     ! (begincell_flags & BEGIN_FLAG_IPV4_NOT_OK);
     875           0 :   ipv6_ok = (resolve->res_status_ipv6 == RES_STATUS_DONE_OK) &&
     876           0 :     (begincell_flags & BEGIN_FLAG_IPV6_OK) &&
     877           0 :     get_options()->IPv6Exit;
     878             : 
     879             :   /* Now decide which one to actually give. */
     880           0 :   if (ipv4_ok && ipv6_ok && is_resolve) {
     881             :     answer_with_ipv4 = 1;
     882           0 :   } else if (ipv4_ok && ipv6_ok) {
     883             :     /* If we have both, see if our exit policy has an opinion. */
     884           0 :     const uint16_t port = exitconn->base_.port;
     885           0 :     int ipv4_allowed, ipv6_allowed;
     886           0 :     tor_addr_t a4, a6;
     887           0 :     tor_addr_from_ipv4h(&a4, resolve->result_ipv4.addr_ipv4);
     888           0 :     tor_addr_from_in6(&a6, &resolve->result_ipv6.addr_ipv6);
     889           0 :     ipv4_allowed = !router_compare_to_my_exit_policy(&a4, port);
     890           0 :     ipv6_allowed = !router_compare_to_my_exit_policy(&a6, port);
     891           0 :     if (ipv4_allowed && !ipv6_allowed) {
     892             :       answer_with_ipv4 = 1;
     893           0 :     } else if (ipv6_allowed && !ipv4_allowed) {
     894             :       answer_with_ipv4 = 0;
     895             :     } else {
     896             :       /* Our exit policy would permit both.  Answer with whichever the user
     897             :        * prefers */
     898           0 :       answer_with_ipv4 = !(begincell_flags &
     899             :                            BEGIN_FLAG_IPV6_PREFERRED);
     900             :     }
     901             :   } else {
     902             :     /* Otherwise if one is okay, send it back. */
     903           0 :     if (ipv4_ok) {
     904             :       answer_with_ipv4 = 1;
     905           0 :     } else if (ipv6_ok) {
     906             :       answer_with_ipv4 = 0;
     907             :     } else {
     908             :       /* Neither one was okay. Choose based on user preference. */
     909           0 :       answer_with_ipv4 = !(begincell_flags &
     910             :                            BEGIN_FLAG_IPV6_PREFERRED);
     911             :     }
     912             :   }
     913             : 
     914             :   /* Finally, we write the answer back. */
     915           0 :   r = 1;
     916           0 :   if (answer_with_ipv4) {
     917           0 :     if (resolve->res_status_ipv4 == RES_STATUS_DONE_OK) {
     918           0 :       tor_addr_from_ipv4h(&exitconn->base_.addr,
     919             :                           resolve->result_ipv4.addr_ipv4);
     920             :     } else {
     921           0 :       r = evdns_err_is_transient(resolve->result_ipv4.err_ipv4) ? -2 : -1;
     922             :     }
     923             : 
     924           0 :     exitconn->address_ttl = resolve->ttl_ipv4;
     925             :   } else {
     926           0 :     if (resolve->res_status_ipv6 == RES_STATUS_DONE_OK) {
     927           0 :       tor_addr_from_in6(&exitconn->base_.addr,
     928             :                         &resolve->result_ipv6.addr_ipv6);
     929             :     } else {
     930           0 :       r = evdns_err_is_transient(resolve->result_ipv6.err_ipv6) ? -2 : -1;
     931             :     }
     932             : 
     933           0 :     exitconn->address_ttl = resolve->ttl_ipv6;
     934             :   }
     935             : 
     936             :   return r;
     937             : }
     938             : 
     939             : /** Log an error and abort if conn is waiting for a DNS resolve.
     940             :  */
     941             : void
     942           0 : assert_connection_edge_not_dns_pending(edge_connection_t *conn)
     943             : {
     944           0 :   pending_connection_t *pend;
     945           0 :   cached_resolve_t search;
     946             : 
     947             : #if 1
     948           0 :   cached_resolve_t *resolve;
     949           0 :   strlcpy(search.address, conn->base_.address, sizeof(search.address));
     950           0 :   resolve = HT_FIND(cache_map, &cache_root, &search);
     951           0 :   if (!resolve)
     952           0 :     return;
     953           0 :   for (pend = resolve->pending_connections; pend; pend = pend->next) {
     954           0 :     tor_assert(pend->conn != conn);
     955             :   }
     956             : #else /* !(1) */
     957             :   cached_resolve_t **resolve;
     958             :   HT_FOREACH(resolve, cache_map, &cache_root) {
     959             :     for (pend = (*resolve)->pending_connections; pend; pend = pend->next) {
     960             :       tor_assert(pend->conn != conn);
     961             :     }
     962             :   }
     963             : #endif /* 1 */
     964             : }
     965             : 
     966             : /** Remove <b>conn</b> from the list of connections waiting for conn-\>address.
     967             :  */
     968             : void
     969           0 : connection_dns_remove(edge_connection_t *conn)
     970             : {
     971           0 :   pending_connection_t *pend, *victim;
     972           0 :   cached_resolve_t search;
     973           0 :   cached_resolve_t *resolve;
     974             : 
     975           0 :   tor_assert(conn->base_.type == CONN_TYPE_EXIT);
     976           0 :   tor_assert(conn->base_.state == EXIT_CONN_STATE_RESOLVING);
     977             : 
     978           0 :   strlcpy(search.address, conn->base_.address, sizeof(search.address));
     979             : 
     980           0 :   resolve = HT_FIND(cache_map, &cache_root, &search);
     981           0 :   if (!resolve) {
     982           0 :     log_notice(LD_BUG, "Address %s is not pending. Dropping.",
     983             :                escaped_safe_str(conn->base_.address));
     984           0 :     return;
     985             :   }
     986             : 
     987           0 :   tor_assert(resolve->pending_connections);
     988           0 :   assert_connection_ok(TO_CONN(conn),0);
     989             : 
     990           0 :   pend = resolve->pending_connections;
     991             : 
     992           0 :   if (pend->conn == conn) {
     993           0 :     resolve->pending_connections = pend->next;
     994           0 :     tor_free(pend);
     995           0 :     log_debug(LD_EXIT, "First connection (fd "TOR_SOCKET_T_FORMAT") no "
     996             :               "longer waiting for resolve of %s",
     997             :               conn->base_.s,
     998             :               escaped_safe_str(conn->base_.address));
     999           0 :     return;
    1000             :   } else {
    1001           0 :     for ( ; pend->next; pend = pend->next) {
    1002           0 :       if (pend->next->conn == conn) {
    1003           0 :         victim = pend->next;
    1004           0 :         pend->next = victim->next;
    1005           0 :         tor_free(victim);
    1006           0 :         log_debug(LD_EXIT,
    1007             :                   "Connection (fd "TOR_SOCKET_T_FORMAT") no longer waiting "
    1008             :                   "for resolve of %s",
    1009             :                   conn->base_.s, escaped_safe_str(conn->base_.address));
    1010           0 :         return; /* more are pending */
    1011             :       }
    1012             :     }
    1013           0 :     log_warn(LD_BUG, "Connection (fd "TOR_SOCKET_T_FORMAT") was not waiting "
    1014             :              "for a resolve of %s, but we tried to remove it.",
    1015             :              conn->base_.s, escaped_safe_str(conn->base_.address));
    1016             :   }
    1017             : }
    1018             : 
    1019             : /** Mark all connections waiting for <b>address</b> for close.  Then cancel
    1020             :  * the resolve for <b>address</b> itself, and remove any cached results for
    1021             :  * <b>address</b> from the cache.
    1022             :  */
    1023           0 : MOCK_IMPL(STATIC void,
    1024             : dns_cancel_pending_resolve,(const char *address))
    1025             : {
    1026           0 :   pending_connection_t *pend;
    1027           0 :   cached_resolve_t search;
    1028           0 :   cached_resolve_t *resolve, *tmp;
    1029           0 :   edge_connection_t *pendconn;
    1030           0 :   circuit_t *circ;
    1031             : 
    1032           0 :   strlcpy(search.address, address, sizeof(search.address));
    1033             : 
    1034           0 :   resolve = HT_FIND(cache_map, &cache_root, &search);
    1035           0 :   if (!resolve)
    1036           0 :     return;
    1037             : 
    1038           0 :   if (resolve->state != CACHE_STATE_PENDING) {
    1039             :     /* We can get into this state if we never actually created the pending
    1040             :      * resolve, due to finding an earlier cached error or something.  Just
    1041             :      * ignore it. */
    1042           0 :     if (resolve->pending_connections) {
    1043           0 :       log_warn(LD_BUG,
    1044             :                "Address %s is not pending but has pending connections!",
    1045             :                escaped_safe_str(address));
    1046           0 :       tor_fragile_assert();
    1047             :     }
    1048           0 :     return;
    1049             :   }
    1050             : 
    1051           0 :   if (!resolve->pending_connections) {
    1052           0 :     log_warn(LD_BUG,
    1053             :              "Address %s is pending but has no pending connections!",
    1054             :              escaped_safe_str(address));
    1055           0 :     tor_fragile_assert();
    1056           0 :     return;
    1057             :   }
    1058           0 :   tor_assert(resolve->pending_connections);
    1059             : 
    1060             :   /* mark all pending connections to fail */
    1061           0 :   log_debug(LD_EXIT,
    1062             :              "Failing all connections waiting on DNS resolve of %s",
    1063             :              escaped_safe_str(address));
    1064           0 :   while (resolve->pending_connections) {
    1065           0 :     pend = resolve->pending_connections;
    1066           0 :     pend->conn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
    1067           0 :     pendconn = pend->conn;
    1068           0 :     assert_connection_ok(TO_CONN(pendconn), 0);
    1069           0 :     tor_assert(!SOCKET_OK(pendconn->base_.s));
    1070           0 :     if (!pendconn->base_.marked_for_close) {
    1071           0 :       connection_edge_end(pendconn, END_STREAM_REASON_RESOLVEFAILED);
    1072             :     }
    1073           0 :     circ = circuit_get_by_edge_conn(pendconn);
    1074           0 :     if (circ)
    1075           0 :       circuit_detach_stream(circ, pendconn);
    1076           0 :     if (!pendconn->base_.marked_for_close)
    1077           0 :       connection_free_(TO_CONN(pendconn));
    1078           0 :     resolve->pending_connections = pend->next;
    1079           0 :     tor_free(pend);
    1080             :   }
    1081             : 
    1082           0 :   tmp = HT_REMOVE(cache_map, &cache_root, resolve);
    1083           0 :   if (tmp != resolve) {
    1084           0 :     log_err(LD_BUG, "The cancelled resolve we purged didn't match any in"
    1085             :             " the cache. Tried to purge %s (%p); instead got %s (%p).",
    1086             :             resolve->address, (void*)resolve,
    1087             :             tmp ? tmp->address : "NULL", (void*)tmp);
    1088             :   }
    1089           0 :   tor_assert(tmp == resolve);
    1090             : 
    1091           0 :   resolve->state = CACHE_STATE_DONE;
    1092             : }
    1093             : 
    1094             : /** Return true iff <b>address</b> is one of the addresses we use to verify
    1095             :  * that well-known sites aren't being hijacked by our DNS servers. */
    1096             : static inline int
    1097           0 : is_test_address(const char *address)
    1098             : {
    1099           0 :   const or_options_t *options = get_options();
    1100           0 :   return options->ServerDNSTestAddresses &&
    1101           0 :     smartlist_contains_string_case(options->ServerDNSTestAddresses, address);
    1102             : }
    1103             : 
    1104             : /** Called on the OR side when the eventdns library tells us the outcome of a
    1105             :  * single DNS resolve: remember the answer, and tell all pending connections
    1106             :  * about the result of the lookup if the lookup is now done.  (<b>address</b>
    1107             :  * is a NUL-terminated string containing the address to look up;
    1108             :  * <b>query_type</b> is one of DNS_{IPv4_A,IPv6_AAAA,PTR}; <b>dns_answer</b>
    1109             :  * is DNS_OK or one of DNS_ERR_*, <b>addr</b> is an IPv4 or IPv6 address if we
    1110             :  * got one; <b>hostname</b> is a hostname fora PTR request if we got one, and
    1111             :  * <b>ttl</b> is the time-to-live of this answer, in seconds.)
    1112             :  */
    1113             : static void
    1114           0 : dns_found_answer(const char *address, uint8_t query_type,
    1115             :                  int dns_answer,
    1116             :                  const tor_addr_t *addr,
    1117             :                  const char *hostname, uint32_t ttl)
    1118             : {
    1119           0 :   cached_resolve_t search;
    1120           0 :   cached_resolve_t *resolve;
    1121             : 
    1122           0 :   assert_cache_ok();
    1123             : 
    1124           0 :   strlcpy(search.address, address, sizeof(search.address));
    1125             : 
    1126           0 :   resolve = HT_FIND(cache_map, &cache_root, &search);
    1127           0 :   if (!resolve) {
    1128           0 :     int is_test_addr = is_test_address(address);
    1129           0 :     if (!is_test_addr)
    1130           0 :       log_info(LD_EXIT,"Resolved unasked address %s; ignoring.",
    1131             :                escaped_safe_str(address));
    1132           0 :     return;
    1133             :   }
    1134           0 :   assert_resolve_ok(resolve);
    1135             : 
    1136           0 :   if (resolve->state != CACHE_STATE_PENDING) {
    1137             :     /* XXXX Maybe update addr? or check addr for consistency? Or let
    1138             :      * VALID replace FAILED? */
    1139           0 :     int is_test_addr = is_test_address(address);
    1140           0 :     if (!is_test_addr)
    1141           0 :       log_notice(LD_EXIT,
    1142             :                  "Resolved %s which was already resolved; ignoring",
    1143             :                  escaped_safe_str(address));
    1144           0 :     tor_assert(resolve->pending_connections == NULL);
    1145             :     return;
    1146             :   }
    1147             : 
    1148           0 :   cached_resolve_add_answer(resolve, query_type, dns_answer,
    1149             :                             addr, hostname, ttl);
    1150             : 
    1151           0 :   if (cached_resolve_have_all_answers(resolve)) {
    1152           0 :     inform_pending_connections(resolve);
    1153             : 
    1154           0 :     make_pending_resolve_cached(resolve);
    1155             :   }
    1156             : }
    1157             : 
    1158             : /** Given a pending cached_resolve_t that we just finished resolving,
    1159             :  * inform every connection that was waiting for the outcome of that
    1160             :  * resolution.
    1161             :  *
    1162             :  * Do this by sending a RELAY_RESOLVED cell (if the pending stream had sent us
    1163             :  * RELAY_RESOLVE cell), or by launching an exit connection (if the pending
    1164             :  * stream had send us a RELAY_BEGIN cell).
    1165             :  */
    1166             : static void
    1167           0 : inform_pending_connections(cached_resolve_t *resolve)
    1168             : {
    1169           0 :   pending_connection_t *pend;
    1170           0 :   edge_connection_t *pendconn;
    1171           0 :   int r;
    1172             : 
    1173           0 :   while (resolve->pending_connections) {
    1174           0 :     char *hostname = NULL;
    1175           0 :     pend = resolve->pending_connections;
    1176           0 :     pendconn = pend->conn; /* don't pass complex things to the
    1177             :                               connection_mark_for_close macro */
    1178           0 :     assert_connection_ok(TO_CONN(pendconn),time(NULL));
    1179             : 
    1180           0 :     if (pendconn->base_.marked_for_close) {
    1181             :       /* prevent double-remove. */
    1182           0 :       pendconn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
    1183           0 :       resolve->pending_connections = pend->next;
    1184           0 :       tor_free(pend);
    1185           0 :       continue;
    1186             :     }
    1187             : 
    1188           0 :     r = set_exitconn_info_from_resolve(pendconn,
    1189             :                                        resolve,
    1190             :                                        &hostname);
    1191             : 
    1192           0 :     if (r < 0) {
    1193             :       /* prevent double-remove. */
    1194           0 :       pendconn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
    1195           0 :       if (pendconn->base_.purpose == EXIT_PURPOSE_CONNECT) {
    1196           0 :         connection_edge_end(pendconn, END_STREAM_REASON_RESOLVEFAILED);
    1197             :         /* This detach must happen after we send the end cell. */
    1198           0 :         circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
    1199             :       } else {
    1200           0 :         send_resolved_cell(pendconn, r == -1 ?
    1201             :                          RESOLVED_TYPE_ERROR : RESOLVED_TYPE_ERROR_TRANSIENT,
    1202             :                          NULL);
    1203             :         /* This detach must happen after we send the resolved cell. */
    1204           0 :         circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
    1205             :       }
    1206           0 :       connection_free_(TO_CONN(pendconn));
    1207             :     } else {
    1208           0 :       circuit_t *circ;
    1209           0 :       if (pendconn->base_.purpose == EXIT_PURPOSE_CONNECT) {
    1210             :         /* prevent double-remove. */
    1211           0 :         pend->conn->base_.state = EXIT_CONN_STATE_CONNECTING;
    1212             : 
    1213           0 :         circ = circuit_get_by_edge_conn(pend->conn);
    1214           0 :         tor_assert(circ);
    1215           0 :         tor_assert(!CIRCUIT_IS_ORIGIN(circ));
    1216             :         /* unlink pend->conn from resolving_streams, */
    1217           0 :         circuit_detach_stream(circ, pend->conn);
    1218             :         /* and link it to n_streams */
    1219           0 :         pend->conn->next_stream = TO_OR_CIRCUIT(circ)->n_streams;
    1220           0 :         pend->conn->on_circuit = circ;
    1221           0 :         TO_OR_CIRCUIT(circ)->n_streams = pend->conn;
    1222             : 
    1223           0 :         connection_exit_connect(pend->conn);
    1224             :       } else {
    1225             :         /* prevent double-remove.  This isn't really an accurate state,
    1226             :          * but it does the right thing. */
    1227           0 :         pendconn->base_.state = EXIT_CONN_STATE_RESOLVEFAILED;
    1228           0 :         if (pendconn->is_reverse_dns_lookup)
    1229           0 :           send_resolved_hostname_cell(pendconn, hostname);
    1230             :         else
    1231           0 :           send_resolved_cell(pendconn, RESOLVED_TYPE_AUTO, resolve);
    1232           0 :         circ = circuit_get_by_edge_conn(pendconn);
    1233           0 :         tor_assert(circ);
    1234           0 :         circuit_detach_stream(circ, pendconn);
    1235           0 :         connection_free_(TO_CONN(pendconn));
    1236             :       }
    1237             :     }
    1238           0 :     resolve->pending_connections = pend->next;
    1239           0 :     tor_free(pend);
    1240           0 :     tor_free(hostname);
    1241             :   }
    1242           0 : }
    1243             : 
    1244             : /** Remove a pending cached_resolve_t from the hashtable, and add a
    1245             :  * corresponding cached cached_resolve_t.
    1246             :  *
    1247             :  * This function is only necessary because of the perversity of our
    1248             :  * cache timeout code; see inline comment for ideas on eliminating it.
    1249             :  **/
    1250             : static void
    1251           0 : make_pending_resolve_cached(cached_resolve_t *resolve)
    1252             : {
    1253           0 :   cached_resolve_t *removed;
    1254             : 
    1255           0 :   resolve->state = CACHE_STATE_DONE;
    1256           0 :   removed = HT_REMOVE(cache_map, &cache_root, resolve);
    1257           0 :   if (removed != resolve) {
    1258           0 :     log_err(LD_BUG, "The pending resolve we found wasn't removable from"
    1259             :             " the cache. Tried to purge %s (%p); instead got %s (%p).",
    1260             :             resolve->address, (void*)resolve,
    1261             :             removed ? removed->address : "NULL", (void*)removed);
    1262             :   }
    1263           0 :   assert_resolve_ok(resolve);
    1264           0 :   assert_cache_ok();
    1265             :   /* The resolve will eventually just hit the time-out in the expiry queue and
    1266             :   * expire. See fd0bafb0dedc7e2 for a brief explanation of how this got that
    1267             :   * way.  XXXXX we could do better!*/
    1268             : 
    1269             :   {
    1270           0 :     cached_resolve_t *new_resolve = tor_memdup(resolve,
    1271             :                                                sizeof(cached_resolve_t));
    1272           0 :     uint32_t ttl = UINT32_MAX;
    1273           0 :     new_resolve->expire = 0; /* So that set_expiry won't croak. */
    1274           0 :     if (resolve->res_status_hostname == RES_STATUS_DONE_OK)
    1275           0 :       new_resolve->result_ptr.hostname =
    1276           0 :         tor_strdup(resolve->result_ptr.hostname);
    1277             : 
    1278           0 :     new_resolve->state = CACHE_STATE_CACHED;
    1279             : 
    1280           0 :     assert_resolve_ok(new_resolve);
    1281           0 :     HT_INSERT(cache_map, &cache_root, new_resolve);
    1282             : 
    1283           0 :     if ((resolve->res_status_ipv4 == RES_STATUS_DONE_OK ||
    1284           0 :          resolve->res_status_ipv4 == RES_STATUS_DONE_ERR) &&
    1285           0 :         resolve->ttl_ipv4 < ttl)
    1286           0 :       ttl = resolve->ttl_ipv4;
    1287             : 
    1288           0 :     if ((resolve->res_status_ipv6 == RES_STATUS_DONE_OK ||
    1289             :          resolve->res_status_ipv6 == RES_STATUS_DONE_ERR) &&
    1290           0 :         resolve->ttl_ipv6 < ttl)
    1291             :       ttl = resolve->ttl_ipv6;
    1292             : 
    1293           0 :     if ((resolve->res_status_hostname == RES_STATUS_DONE_OK ||
    1294             :          resolve->res_status_hostname == RES_STATUS_DONE_ERR) &&
    1295           0 :         resolve->ttl_hostname < ttl)
    1296             :       ttl = resolve->ttl_hostname;
    1297             : 
    1298           0 :     set_expiry(new_resolve, time(NULL) + clip_dns_ttl(ttl));
    1299             :   }
    1300             : 
    1301           0 :   assert_cache_ok();
    1302           0 : }
    1303             : 
    1304             : /** Eventdns helper: return true iff the eventdns result <b>err</b> is
    1305             :  * a transient failure. */
    1306             : static int
    1307           0 : evdns_err_is_transient(int err)
    1308             : {
    1309           0 :   switch (err)
    1310             :   {
    1311             :     case DNS_ERR_SERVERFAILED:
    1312             :     case DNS_ERR_TRUNCATED:
    1313             :     case DNS_ERR_TIMEOUT:
    1314             :       return 1;
    1315           0 :     default:
    1316           0 :       return 0;
    1317             :   }
    1318             : }
    1319             : 
    1320             : /**
    1321             :  * Return number of configured nameservers in <b>the_evdns_base</b>.
    1322             :  */
    1323             : size_t
    1324           2 : number_of_configured_nameservers(void)
    1325             : {
    1326           2 :   return evdns_base_count_nameservers(the_evdns_base);
    1327             : }
    1328             : 
    1329             : #ifdef HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR
    1330             : /**
    1331             :  * Return address of configured nameserver in <b>the_evdns_base</b>
    1332             :  * at index <b>idx</b>.
    1333             :  */
    1334             : tor_addr_t *
    1335           2 : configured_nameserver_address(const size_t idx)
    1336             : {
    1337           2 :  struct sockaddr_storage sa;
    1338           2 :  ev_socklen_t sa_len = sizeof(sa);
    1339             : 
    1340           2 :  if (evdns_base_get_nameserver_addr(the_evdns_base, (int)idx,
    1341             :                                     (struct sockaddr *)&sa,
    1342             :                                     sa_len) > 0) {
    1343           2 :    tor_addr_t *tor_addr = tor_malloc(sizeof(tor_addr_t));
    1344           2 :    if (tor_addr_from_sockaddr(tor_addr,
    1345             :                               (const struct sockaddr *)&sa,
    1346             :                               NULL) == 0) {
    1347           2 :      return tor_addr;
    1348             :    }
    1349           0 :    tor_free(tor_addr);
    1350             :  }
    1351             : 
    1352             :  return NULL;
    1353             : }
    1354             : #endif /* defined(HAVE_EVDNS_BASE_GET_NAMESERVER_ADDR) */
    1355             : 
    1356             : /** Configure eventdns nameservers if force is true, or if the configuration
    1357             :  * has changed since the last time we called this function, or if we failed on
    1358             :  * our last attempt.  On Unix, this reads from /etc/resolv.conf or
    1359             :  * options->ServerDNSResolvConfFile; on Windows, this reads from
    1360             :  * options->ServerDNSResolvConfFile or the registry.  Return 0 on success or
    1361             :  * -1 on failure. */
    1362             : static int
    1363           2 : configure_nameservers(int force)
    1364             : {
    1365           2 :   const or_options_t *options;
    1366           2 :   const char *conf_fname;
    1367           2 :   struct stat st;
    1368           2 :   int r, flags;
    1369           2 :   options = get_options();
    1370           2 :   conf_fname = options->ServerDNSResolvConfFile;
    1371             : #ifndef _WIN32
    1372           2 :   if (!conf_fname)
    1373           0 :     conf_fname = "/etc/resolv.conf";
    1374             : #endif
    1375           2 :   flags = DNS_OPTIONS_ALL;
    1376             : 
    1377           2 :   if (!the_evdns_base) {
    1378           1 :     if (!(the_evdns_base = evdns_base_new(tor_libevent_get_base(), 0))) {
    1379           0 :       log_err(LD_BUG, "Couldn't create an evdns_base");
    1380           0 :       return -1;
    1381             :     }
    1382             :   }
    1383             : 
    1384           2 :   evdns_set_log_fn(evdns_log_cb);
    1385           2 :   if (conf_fname) {
    1386           2 :     log_debug(LD_FS, "stat()ing %s", conf_fname);
    1387           2 :     int missing_resolv_conf = 0;
    1388           2 :     int stat_res = stat(sandbox_intern_string(conf_fname), &st);
    1389             : 
    1390           2 :     if (stat_res) {
    1391           1 :       log_warn(LD_EXIT, "Unable to stat resolver configuration in '%s': %s",
    1392             :                conf_fname, strerror(errno));
    1393           1 :       missing_resolv_conf = 1;
    1394           1 :     } else if (!force && resolv_conf_fname &&
    1395           0 :                !strcmp(conf_fname,resolv_conf_fname)
    1396           0 :         && st.st_mtime == resolv_conf_mtime) {
    1397           0 :       log_info(LD_EXIT, "No change to '%s'", conf_fname);
    1398           0 :       return 0;
    1399             :     }
    1400             : 
    1401           2 :     if (stat_res == 0 && st.st_size == 0)
    1402           1 :       missing_resolv_conf = 1;
    1403             : 
    1404           2 :     if (nameservers_configured) {
    1405           1 :       evdns_base_search_clear(the_evdns_base);
    1406           1 :       evdns_base_clear_nameservers_and_suspend(the_evdns_base);
    1407             :     }
    1408             : #if defined(DNS_OPTION_HOSTSFILE) && defined(USE_LIBSECCOMP)
    1409           2 :     if (flags & DNS_OPTION_HOSTSFILE) {
    1410           2 :       flags ^= DNS_OPTION_HOSTSFILE;
    1411           2 :       log_debug(LD_FS, "Loading /etc/hosts");
    1412           2 :       evdns_base_load_hosts(the_evdns_base,
    1413             :           sandbox_intern_string("/etc/hosts"));
    1414             :     }
    1415             : #endif /* defined(DNS_OPTION_HOSTSFILE) && defined(USE_LIBSECCOMP) */
    1416             : 
    1417           2 :     if (!missing_resolv_conf) {
    1418           0 :       log_info(LD_EXIT, "Parsing resolver configuration in '%s'", conf_fname);
    1419           0 :       if ((r = evdns_base_resolv_conf_parse(the_evdns_base, flags,
    1420             :           sandbox_intern_string(conf_fname)))) {
    1421           0 :         log_warn(LD_EXIT, "Unable to parse '%s', or no nameservers "
    1422             :                           "in '%s' (%d)", conf_fname, conf_fname, r);
    1423             : 
    1424           0 :         if (r != 6) // "r = 6" means "no DNS servers were in resolv.conf" -
    1425           0 :           goto err; // in which case we expect libevent to add 127.0.0.1 as
    1426             :                     // fallback.
    1427             :       }
    1428           0 :       if (evdns_base_count_nameservers(the_evdns_base) == 0) {
    1429           0 :         log_warn(LD_EXIT, "Unable to find any nameservers in '%s'.",
    1430             :                  conf_fname);
    1431             :       }
    1432             : 
    1433           0 :       tor_free(resolv_conf_fname);
    1434           0 :       resolv_conf_fname = tor_strdup(conf_fname);
    1435           0 :       resolv_conf_mtime = st.st_mtime;
    1436             :     } else {
    1437           2 :       log_warn(LD_EXIT, "Could not read your DNS config from '%s' - "
    1438             :                         "please investigate your DNS configuration. "
    1439             :                         "This is possibly a problem. Meanwhile, falling"
    1440             :                         " back to local DNS at 127.0.0.1.", conf_fname);
    1441           2 :       evdns_base_nameserver_ip_add(the_evdns_base, "127.0.0.1");
    1442             :     }
    1443             : 
    1444           2 :     if (nameservers_configured)
    1445           1 :       evdns_base_resume(the_evdns_base);
    1446             :   }
    1447             : #ifdef _WIN32
    1448             :   else {
    1449             :     if (nameservers_configured) {
    1450             :       evdns_base_search_clear(the_evdns_base);
    1451             :       evdns_base_clear_nameservers_and_suspend(the_evdns_base);
    1452             :     }
    1453             :     if (evdns_base_config_windows_nameservers(the_evdns_base))  {
    1454             :       log_warn(LD_EXIT,"Could not config nameservers.");
    1455             :       goto err;
    1456             :     }
    1457             :     if (evdns_base_count_nameservers(the_evdns_base) == 0) {
    1458             :       log_warn(LD_EXIT, "Unable to find any platform nameservers in "
    1459             :                "your Windows configuration.");
    1460             :       goto err;
    1461             :     }
    1462             :     if (nameservers_configured)
    1463             :       evdns_base_resume(the_evdns_base);
    1464             :     tor_free(resolv_conf_fname);
    1465             :     resolv_conf_mtime = 0;
    1466             :   }
    1467             : #endif /* defined(_WIN32) */
    1468             : 
    1469             : #define SET(k,v)  evdns_base_set_option(the_evdns_base, (k), (v))
    1470             : 
    1471             :   // If we only have one nameserver, it does not make sense to back off
    1472             :   // from it for a timeout. Unfortunately, the value for max-timeouts is
    1473             :   // currently clamped by libevent to 255, but it does not hurt to set
    1474             :   // it higher in case libevent gets a patch for this.  Higher-than-
    1475             :   // default maximum of 3 with multiple nameservers to avoid spuriously
    1476             :   // marking one down on bursts of timeouts resulting from scans/attacks
    1477             :   // against non-responding authoritative DNS servers.
    1478           2 :   if (evdns_base_count_nameservers(the_evdns_base) == 1) {
    1479           2 :     SET("max-timeouts:", "1000000");
    1480             :   } else {
    1481           0 :     SET("max-timeouts:", "10");
    1482             :   }
    1483             : 
    1484             :   // Elongate the queue of maximum inflight dns requests, so if a bunch
    1485             :   // remain pending at the resolver (happens commonly with Unbound) we won't
    1486             :   // stall every other DNS request. This potentially means some wasted
    1487             :   // CPU as there's a walk over a linear queue involved, but this is a
    1488             :   // much better tradeoff compared to just failing DNS requests because
    1489             :   // of a full queue.
    1490           2 :   SET("max-inflight:", "8192");
    1491             : 
    1492             :   // Two retries at 5 and 10 seconds for bind9/named which relies on
    1493             :   // clients to handle retries.  Second retry for retried circuits with
    1494             :   // extended 15 second timeout.  Superfluous with local-system Unbound
    1495             :   // instance--has its own elaborate retry scheme.
    1496           2 :   SET("timeout:", "5");
    1497           2 :   SET("attempts:","3");
    1498             : 
    1499           2 :   if (options->ServerDNSRandomizeCase)
    1500           0 :     SET("randomize-case:", "1");
    1501             :   else
    1502           2 :     SET("randomize-case:", "0");
    1503             : 
    1504             : #undef SET
    1505             : 
    1506           2 :   dns_servers_relaunch_checks();
    1507             : 
    1508           2 :   nameservers_configured = 1;
    1509           2 :   if (nameserver_config_failed) {
    1510           0 :     nameserver_config_failed = 0;
    1511             :     /* XXX the three calls to republish the descriptor might be producing
    1512             :      * descriptors that are only cosmetically different, especially on
    1513             :      * non-exit relays! -RD */
    1514           0 :     mark_my_descriptor_dirty("dns resolvers back");
    1515             :   }
    1516             :   return 0;
    1517           0 :  err:
    1518           0 :   nameservers_configured = 0;
    1519           0 :   if (! nameserver_config_failed) {
    1520           0 :     nameserver_config_failed = 1;
    1521           0 :     mark_my_descriptor_dirty("dns resolvers failed");
    1522             :   }
    1523             :   return -1;
    1524             : }
    1525             : 
    1526             : /** For eventdns: Called when we get an answer for a request we launched.
    1527             :  * See eventdns.h for arguments; 'arg' holds the address we tried to resolve.
    1528             :  */
    1529             : static void
    1530           0 : evdns_callback(int result, char type, int count, int ttl, void *addresses,
    1531             :                void *arg)
    1532             : {
    1533           0 :   char *arg_ = arg;
    1534           0 :   uint8_t orig_query_type = arg_[0];
    1535           0 :   char *string_address = arg_ + 1;
    1536           0 :   tor_addr_t addr;
    1537           0 :   const char *hostname = NULL;
    1538           0 :   int was_wildcarded = 0;
    1539             : 
    1540           0 :   tor_addr_make_unspec(&addr);
    1541             : 
    1542             :   /* Note down any DNS errors to the statistics module */
    1543           0 :   if (result == DNS_ERR_TIMEOUT) {
    1544             :     /* libevent timed out while resolving a name. However, because libevent
    1545             :      * handles retries and timeouts internally, this means that all attempts of
    1546             :      * libevent timed out. If we wanted to get more granular information about
    1547             :      * individual libevent attempts, we would have to implement our own DNS
    1548             :      * timeout/retry logic */
    1549           0 :     rep_hist_note_overload(OVERLOAD_GENERAL);
    1550             :   }
    1551             : 
    1552             :   /* Keep track of whether IPv6 is working */
    1553           0 :   if (type == DNS_IPv6_AAAA) {
    1554           0 :     if (result == DNS_ERR_TIMEOUT) {
    1555           0 :       ++n_ipv6_timeouts;
    1556             :     }
    1557             : 
    1558           0 :     if (n_ipv6_timeouts > 10 &&
    1559           0 :         n_ipv6_timeouts > n_ipv6_requests_made / 2) {
    1560           0 :       if (! dns_is_broken_for_ipv6) {
    1561           0 :         log_notice(LD_EXIT, "More than half of our IPv6 requests seem to "
    1562             :                    "have timed out. I'm going to assume I can't get AAAA "
    1563             :                    "responses.");
    1564           0 :         dns_is_broken_for_ipv6 = 1;
    1565             :       }
    1566             :     }
    1567             :   }
    1568             : 
    1569           0 :   if (result == DNS_ERR_NONE) {
    1570           0 :     if (type == DNS_IPv4_A && count) {
    1571           0 :       char answer_buf[INET_NTOA_BUF_LEN+1];
    1572           0 :       char *escaped_address;
    1573           0 :       uint32_t *addrs = addresses;
    1574           0 :       tor_addr_from_ipv4n(&addr, addrs[0]);
    1575             : 
    1576           0 :       tor_addr_to_str(answer_buf, &addr, sizeof(answer_buf), 0);
    1577           0 :       escaped_address = esc_for_log(string_address);
    1578             : 
    1579           0 :       if (answer_is_wildcarded(answer_buf)) {
    1580           0 :         log_debug(LD_EXIT, "eventdns said that %s resolves to ISP-hijacked "
    1581             :                   "address %s; treating as a failure.",
    1582             :                   safe_str(escaped_address),
    1583             :                   escaped_safe_str(answer_buf));
    1584           0 :         was_wildcarded = 1;
    1585           0 :         tor_addr_make_unspec(&addr);
    1586           0 :         result = DNS_ERR_NOTEXIST;
    1587             :       } else {
    1588           0 :         log_debug(LD_EXIT, "eventdns said that %s resolves to %s",
    1589             :                   safe_str(escaped_address),
    1590             :                   escaped_safe_str(answer_buf));
    1591             :       }
    1592           0 :       tor_free(escaped_address);
    1593           0 :     } else if (type == DNS_IPv6_AAAA && count) {
    1594           0 :       char answer_buf[TOR_ADDR_BUF_LEN];
    1595           0 :       char *escaped_address;
    1596           0 :       const char *ip_str;
    1597           0 :       struct in6_addr *addrs = addresses;
    1598           0 :       tor_addr_from_in6(&addr, &addrs[0]);
    1599           0 :       ip_str = tor_inet_ntop(AF_INET6, &addrs[0], answer_buf,
    1600             :                              sizeof(answer_buf));
    1601           0 :       escaped_address = esc_for_log(string_address);
    1602             : 
    1603           0 :       if (BUG(ip_str == NULL)) {
    1604           0 :         log_warn(LD_EXIT, "tor_inet_ntop() failed!");
    1605           0 :         result = DNS_ERR_NOTEXIST;
    1606           0 :       } else if (answer_is_wildcarded(answer_buf)) {
    1607           0 :         log_debug(LD_EXIT, "eventdns said that %s resolves to ISP-hijacked "
    1608             :                   "address %s; treating as a failure.",
    1609             :                   safe_str(escaped_address),
    1610             :                   escaped_safe_str(answer_buf));
    1611           0 :         was_wildcarded = 1;
    1612           0 :         tor_addr_make_unspec(&addr);
    1613           0 :         result = DNS_ERR_NOTEXIST;
    1614             :       } else {
    1615           0 :         log_debug(LD_EXIT, "eventdns said that %s resolves to %s",
    1616             :                   safe_str(escaped_address),
    1617             :                   escaped_safe_str(answer_buf));
    1618             :       }
    1619           0 :       tor_free(escaped_address);
    1620           0 :     } else if (type == DNS_PTR && count) {
    1621           0 :       char *escaped_address;
    1622           0 :       hostname = ((char**)addresses)[0];
    1623           0 :       escaped_address = esc_for_log(string_address);
    1624           0 :       log_debug(LD_EXIT, "eventdns said that %s resolves to %s",
    1625             :                 safe_str(escaped_address),
    1626             :                 escaped_safe_str(hostname));
    1627           0 :       tor_free(escaped_address);
    1628           0 :     } else if (count) {
    1629           0 :       log_info(LD_EXIT, "eventdns returned only unrecognized answer types "
    1630             :                " for %s.",
    1631             :                escaped_safe_str(string_address));
    1632             :     } else {
    1633           0 :       log_info(LD_EXIT, "eventdns returned no addresses or error for %s.",
    1634             :                escaped_safe_str(string_address));
    1635             :     }
    1636             :   }
    1637           0 :   if (was_wildcarded) {
    1638           0 :     if (is_test_address(string_address)) {
    1639             :       /* Ick.  We're getting redirected on known-good addresses.  Our DNS
    1640             :        * server must really hate us.  */
    1641           0 :       add_wildcarded_test_address(string_address);
    1642             :     }
    1643             :   }
    1644             : 
    1645           0 :   if (orig_query_type && type && orig_query_type != type) {
    1646           0 :     log_warn(LD_BUG, "Weird; orig_query_type == %d but type == %d",
    1647             :              (int)orig_query_type, (int)type);
    1648             :   }
    1649           0 :   if (result != DNS_ERR_SHUTDOWN)
    1650           0 :     dns_found_answer(string_address, orig_query_type,
    1651             :                      result, &addr, hostname, ttl);
    1652             : 
    1653             :   /* The result can be changed within this function thus why we note the result
    1654             :    * at the end. */
    1655           0 :   rep_hist_note_dns_error(type, result);
    1656             : 
    1657           0 :   tor_free(arg_);
    1658           0 : }
    1659             : 
    1660             : /** Start a single DNS resolve for <b>address</b> (if <b>query_type</b> is
    1661             :  * DNS_IPv4_A or DNS_IPv6_AAAA) <b>ptr_address</b> (if <b>query_type</b> is
    1662             :  * DNS_PTR). Return 0 if we launched the request, -1 otherwise. */
    1663             : static int
    1664           0 : launch_one_resolve(const char *address, uint8_t query_type,
    1665             :                    const tor_addr_t *ptr_address)
    1666             : {
    1667           0 :   const int options = get_options()->ServerDNSSearchDomains ? 0
    1668           0 :     : DNS_QUERY_NO_SEARCH;
    1669           0 :   const size_t addr_len = strlen(address);
    1670           0 :   struct evdns_request *req = 0;
    1671           0 :   char *addr = tor_malloc(addr_len + 2);
    1672           0 :   addr[0] = (char) query_type;
    1673           0 :   memcpy(addr+1, address, addr_len + 1);
    1674             : 
    1675             :   /* Note the query for our statistics. */
    1676           0 :   rep_hist_note_dns_request(query_type);
    1677             : 
    1678           0 :   switch (query_type) {
    1679           0 :   case DNS_IPv4_A:
    1680           0 :     req = evdns_base_resolve_ipv4(the_evdns_base,
    1681             :                                   address, options, evdns_callback, addr);
    1682           0 :     break;
    1683           0 :   case DNS_IPv6_AAAA:
    1684           0 :     req = evdns_base_resolve_ipv6(the_evdns_base,
    1685             :                                   address, options, evdns_callback, addr);
    1686           0 :     ++n_ipv6_requests_made;
    1687           0 :     break;
    1688           0 :   case DNS_PTR:
    1689           0 :     if (tor_addr_family(ptr_address) == AF_INET)
    1690           0 :       req = evdns_base_resolve_reverse(the_evdns_base,
    1691             :                                        tor_addr_to_in(ptr_address),
    1692             :                                        DNS_QUERY_NO_SEARCH,
    1693             :                                        evdns_callback, addr);
    1694           0 :     else if (tor_addr_family(ptr_address) == AF_INET6)
    1695           0 :       req = evdns_base_resolve_reverse_ipv6(the_evdns_base,
    1696             :                                             tor_addr_to_in6(ptr_address),
    1697             :                                             DNS_QUERY_NO_SEARCH,
    1698             :                                             evdns_callback, addr);
    1699             :     else
    1700           0 :       log_warn(LD_BUG, "Called with PTR query and unexpected address family");
    1701             :     break;
    1702           0 :   default:
    1703           0 :     log_warn(LD_BUG, "Called with unexpected query type %d", (int)query_type);
    1704           0 :     break;
    1705             :   }
    1706             : 
    1707           0 :   if (req) {
    1708             :     return 0;
    1709             :   } else {
    1710           0 :     tor_free(addr);
    1711           0 :     return -1;
    1712             :   }
    1713             : }
    1714             : 
    1715             : /** For eventdns: start resolving as necessary to find the target for
    1716             :  * <b>exitconn</b>.  Returns -1 on error, -2 on transient error,
    1717             :  * 0 on "resolve launched." */
    1718           0 : MOCK_IMPL(STATIC int,
    1719             : launch_resolve,(cached_resolve_t *resolve))
    1720             : {
    1721           0 :   tor_addr_t a;
    1722           0 :   int r;
    1723             : 
    1724           0 :   if (net_is_disabled())
    1725             :     return -1;
    1726             : 
    1727             :   /* What? Nameservers not configured?  Sounds like a bug. */
    1728           0 :   if (!nameservers_configured) {
    1729           0 :     log_warn(LD_EXIT, "(Harmless.) Nameservers not configured, but resolve "
    1730             :              "launched.  Configuring.");
    1731           0 :     if (configure_nameservers(1) < 0) {
    1732             :       return -1;
    1733             :     }
    1734             :   }
    1735             : 
    1736           0 :   r = tor_addr_parse_PTR_name(
    1737           0 :                             &a, resolve->address, AF_UNSPEC, 0);
    1738             : 
    1739           0 :   tor_assert(the_evdns_base);
    1740           0 :   if (r == 0) {
    1741           0 :     log_info(LD_EXIT, "Launching eventdns request for %s",
    1742             :              escaped_safe_str(resolve->address));
    1743           0 :     resolve->res_status_ipv4 = RES_STATUS_INFLIGHT;
    1744           0 :     if (get_options()->IPv6Exit)
    1745           0 :       resolve->res_status_ipv6 = RES_STATUS_INFLIGHT;
    1746             : 
    1747           0 :     if (launch_one_resolve(resolve->address, DNS_IPv4_A, NULL) < 0) {
    1748           0 :       resolve->res_status_ipv4 = 0;
    1749           0 :       r = -1;
    1750             :     }
    1751             : 
    1752           0 :     if (r==0 && get_options()->IPv6Exit) {
    1753             :       /* We ask for an IPv6 address for *everything*. */
    1754           0 :       if (launch_one_resolve(resolve->address, DNS_IPv6_AAAA, NULL) < 0) {
    1755           0 :         resolve->res_status_ipv6 = 0;
    1756           0 :         r = -1;
    1757             :       }
    1758             :     }
    1759           0 :   } else if (r == 1) {
    1760           0 :     r = 0;
    1761           0 :     log_info(LD_EXIT, "Launching eventdns reverse request for %s",
    1762             :              escaped_safe_str(resolve->address));
    1763           0 :     resolve->res_status_hostname = RES_STATUS_INFLIGHT;
    1764           0 :     if (launch_one_resolve(resolve->address, DNS_PTR, &a) < 0) {
    1765           0 :       resolve->res_status_hostname = 0;
    1766           0 :       r = -1;
    1767             :     }
    1768           0 :   } else if (r == -1) {
    1769           0 :     log_warn(LD_BUG, "Somehow a malformed in-addr.arpa address reached here.");
    1770             :   }
    1771             : 
    1772           0 :   if (r < 0) {
    1773           0 :     log_fn(LOG_PROTOCOL_WARN, LD_EXIT, "eventdns rejected address %s.",
    1774             :            escaped_safe_str(resolve->address));
    1775             :   }
    1776             :   return r;
    1777             : }
    1778             : 
    1779             : /** How many requests for bogus addresses have we launched so far? */
    1780             : static int n_wildcard_requests = 0;
    1781             : 
    1782             : /** Map from dotted-quad IP address in response to an int holding how many
    1783             :  * times we've seen it for a randomly generated (hopefully bogus) address.  It
    1784             :  * would be easier to use definitely-invalid addresses (as specified by
    1785             :  * RFC2606), but see comment in dns_launch_wildcard_checks(). */
    1786             : static strmap_t *dns_wildcard_response_count = NULL;
    1787             : 
    1788             : /** If present, a list of dotted-quad IP addresses that we are pretty sure our
    1789             :  * nameserver wants to return in response to requests for nonexistent domains.
    1790             :  */
    1791             : static smartlist_t *dns_wildcard_list = NULL;
    1792             : /** True iff we've logged about a single address getting wildcarded.
    1793             :  * Subsequent warnings will be less severe.  */
    1794             : static int dns_wildcard_one_notice_given = 0;
    1795             : /** True iff we've warned that our DNS server is wildcarding too many failures.
    1796             :  */
    1797             : static int dns_wildcard_notice_given = 0;
    1798             : 
    1799             : /** List of supposedly good addresses that are getting wildcarded to the
    1800             :  * same addresses as nonexistent addresses. */
    1801             : static smartlist_t *dns_wildcarded_test_address_list = NULL;
    1802             : /** True iff we've warned about a test address getting wildcarded */
    1803             : static int dns_wildcarded_test_address_notice_given = 0;
    1804             : /** True iff all addresses seem to be getting wildcarded. */
    1805             : static int dns_is_completely_invalid = 0;
    1806             : 
    1807             : /** Called when we see <b>id</b> (a dotted quad or IPv6 address) in response
    1808             :  * to a request for a hopefully bogus address. */
    1809             : static void
    1810           0 : wildcard_increment_answer(const char *id)
    1811             : {
    1812           0 :   int *ip;
    1813           0 :   if (!dns_wildcard_response_count)
    1814           0 :     dns_wildcard_response_count = strmap_new();
    1815             : 
    1816           0 :   ip = strmap_get(dns_wildcard_response_count, id); // may be null (0)
    1817           0 :   if (!ip) {
    1818           0 :     ip = tor_malloc_zero(sizeof(int));
    1819           0 :     strmap_set(dns_wildcard_response_count, id, ip);
    1820             :   }
    1821           0 :   ++*ip;
    1822             : 
    1823           0 :   if (*ip > 5 && n_wildcard_requests > 10) {
    1824           0 :     if (!dns_wildcard_list) dns_wildcard_list = smartlist_new();
    1825           0 :     if (!smartlist_contains_string(dns_wildcard_list, id)) {
    1826           0 :     tor_log(dns_wildcard_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
    1827             :         "Your DNS provider has given \"%s\" as an answer for %d different "
    1828             :         "invalid addresses. Apparently they are hijacking DNS failures. "
    1829             :         "I'll try to correct for this by treating future occurrences of "
    1830             :         "\"%s\" as 'not found'.", id, *ip, id);
    1831           0 :       smartlist_add_strdup(dns_wildcard_list, id);
    1832             :     }
    1833           0 :     if (!dns_wildcard_notice_given)
    1834           0 :       control_event_server_status(LOG_NOTICE, "DNS_HIJACKED");
    1835           0 :     dns_wildcard_notice_given = 1;
    1836             :   }
    1837           0 : }
    1838             : 
    1839             : /** Note that a single test address (one believed to be good) seems to be
    1840             :  * getting redirected to the same IP as failures are. */
    1841             : static void
    1842           0 : add_wildcarded_test_address(const char *address)
    1843             : {
    1844           0 :   int n, n_test_addrs;
    1845           0 :   if (!dns_wildcarded_test_address_list)
    1846           0 :     dns_wildcarded_test_address_list = smartlist_new();
    1847             : 
    1848           0 :   if (smartlist_contains_string_case(dns_wildcarded_test_address_list,
    1849             :                                      address))
    1850             :     return;
    1851             : 
    1852           0 :   n_test_addrs = get_options()->ServerDNSTestAddresses ?
    1853           0 :     smartlist_len(get_options()->ServerDNSTestAddresses) : 0;
    1854             : 
    1855           0 :   smartlist_add_strdup(dns_wildcarded_test_address_list, address);
    1856           0 :   n = smartlist_len(dns_wildcarded_test_address_list);
    1857           0 :   if (n > n_test_addrs/2) {
    1858           0 :     tor_log(dns_wildcarded_test_address_notice_given ? LOG_INFO : LOG_NOTICE,
    1859             :         LD_EXIT, "Your DNS provider tried to redirect \"%s\" to a junk "
    1860             :         "address.  It has done this with %d test addresses so far.  I'm "
    1861             :         "going to stop being an exit node for now, since our DNS seems so "
    1862             :         "broken.", address, n);
    1863           0 :     if (!dns_is_completely_invalid) {
    1864           0 :       dns_is_completely_invalid = 1;
    1865           0 :       mark_my_descriptor_dirty("dns hijacking confirmed");
    1866             :     }
    1867           0 :     if (!dns_wildcarded_test_address_notice_given)
    1868           0 :       control_event_server_status(LOG_WARN, "DNS_USELESS");
    1869           0 :     dns_wildcarded_test_address_notice_given = 1;
    1870             :   }
    1871             : }
    1872             : 
    1873             : /** Callback function when we get an answer (possibly failing) for a request
    1874             :  * for a (hopefully) nonexistent domain. */
    1875             : static void
    1876           0 : evdns_wildcard_check_callback(int result, char type, int count, int ttl,
    1877             :                               void *addresses, void *arg)
    1878             : {
    1879           0 :   (void)ttl;
    1880           0 :   const char *ip_str;
    1881           0 :   ++n_wildcard_requests;
    1882           0 :   if (result == DNS_ERR_NONE && count) {
    1883           0 :     char *string_address = arg;
    1884           0 :     int i;
    1885           0 :     if (type == DNS_IPv4_A) {
    1886             :       const uint32_t *addrs = addresses;
    1887           0 :       for (i = 0; i < count; ++i) {
    1888           0 :         char answer_buf[INET_NTOA_BUF_LEN+1];
    1889           0 :         struct in_addr in;
    1890           0 :         int ntoa_res;
    1891           0 :         in.s_addr = addrs[i];
    1892           0 :         ntoa_res = tor_inet_ntoa(&in, answer_buf, sizeof(answer_buf));
    1893           0 :         tor_assert_nonfatal(ntoa_res >= 0);
    1894           0 :         if (ntoa_res > 0)
    1895           0 :           wildcard_increment_answer(answer_buf);
    1896             :       }
    1897           0 :     } else if (type == DNS_IPv6_AAAA) {
    1898             :       const struct in6_addr *addrs = addresses;
    1899           0 :       for (i = 0; i < count; ++i) {
    1900           0 :         char answer_buf[TOR_ADDR_BUF_LEN+1];
    1901           0 :         ip_str = tor_inet_ntop(AF_INET6, &addrs[i], answer_buf,
    1902             :                                sizeof(answer_buf));
    1903           0 :         tor_assert_nonfatal(ip_str);
    1904           0 :         if (ip_str)
    1905           0 :           wildcard_increment_answer(answer_buf);
    1906             :       }
    1907             :     }
    1908             : 
    1909           0 :     tor_log(dns_wildcard_one_notice_given ? LOG_INFO : LOG_NOTICE, LD_EXIT,
    1910             :         "Your DNS provider gave an answer for \"%s\", which "
    1911             :         "is not supposed to exist. Apparently they are hijacking "
    1912             :         "DNS failures. Trying to correct for this. We've noticed %d "
    1913             :         "possibly bad address%s so far.",
    1914             :         string_address, strmap_size(dns_wildcard_response_count),
    1915           0 :         (strmap_size(dns_wildcard_response_count) == 1) ? "" : "es");
    1916           0 :     dns_wildcard_one_notice_given = 1;
    1917             :   }
    1918           0 :   tor_free(arg);
    1919           0 : }
    1920             : 
    1921             : /** Launch a single request for a nonexistent hostname consisting of between
    1922             :  * <b>min_len</b> and <b>max_len</b> random (plausible) characters followed by
    1923             :  * <b>suffix</b> */
    1924             : static void
    1925           0 : launch_wildcard_check(int min_len, int max_len, int is_ipv6,
    1926             :                       const char *suffix)
    1927             : {
    1928           0 :   char *addr;
    1929           0 :   struct evdns_request *req;
    1930             : 
    1931           0 :   addr = crypto_random_hostname(min_len, max_len, "", suffix);
    1932           0 :   log_info(LD_EXIT, "Testing whether our DNS server is hijacking nonexistent "
    1933             :            "domains with request for bogus hostname \"%s\"", addr);
    1934             : 
    1935           0 :   tor_assert(the_evdns_base);
    1936           0 :   if (is_ipv6)
    1937           0 :     req = evdns_base_resolve_ipv6(
    1938             :                          the_evdns_base,
    1939             :                          /* This "addr" tells us which address to resolve */
    1940             :                          addr,
    1941             :                          DNS_QUERY_NO_SEARCH, evdns_wildcard_check_callback,
    1942             :                          /* This "addr" is an argument to the callback*/ addr);
    1943             :   else
    1944           0 :     req = evdns_base_resolve_ipv4(
    1945             :                          the_evdns_base,
    1946             :                          /* This "addr" tells us which address to resolve */
    1947             :                          addr,
    1948             :                          DNS_QUERY_NO_SEARCH, evdns_wildcard_check_callback,
    1949             :                          /* This "addr" is an argument to the callback*/ addr);
    1950           0 :   if (!req) {
    1951             :     /* There is no evdns request in progress; stop addr from getting leaked */
    1952           0 :     tor_free(addr);
    1953             :   }
    1954           0 : }
    1955             : 
    1956             : /** Launch attempts to resolve a bunch of known-good addresses (configured in
    1957             :  * ServerDNSTestAddresses).  [Callback for a libevent timer] */
    1958             : static void
    1959           0 : launch_test_addresses(evutil_socket_t fd, short event, void *args)
    1960             : {
    1961           0 :   const or_options_t *options = get_options();
    1962           0 :   (void)fd;
    1963           0 :   (void)event;
    1964           0 :   (void)args;
    1965             : 
    1966           0 :   if (net_is_disabled())
    1967             :     return;
    1968             : 
    1969           0 :   log_info(LD_EXIT, "Launching checks to see whether our nameservers like to "
    1970             :            "hijack *everything*.");
    1971             :   /* This situation is worse than the failure-hijacking situation.  When this
    1972             :    * happens, we're no good for DNS requests at all, and we shouldn't really
    1973             :    * be an exit server.*/
    1974           0 :   if (options->ServerDNSTestAddresses) {
    1975             : 
    1976           0 :     tor_assert(the_evdns_base);
    1977           0 :     SMARTLIST_FOREACH_BEGIN(options->ServerDNSTestAddresses,
    1978             :                             const char *, address) {
    1979           0 :       if (launch_one_resolve(address, DNS_IPv4_A, NULL) < 0) {
    1980           0 :         log_info(LD_EXIT, "eventdns rejected test address %s",
    1981             :                  escaped_safe_str(address));
    1982             :       }
    1983             : 
    1984           0 :       if (launch_one_resolve(address, DNS_IPv6_AAAA, NULL) < 0) {
    1985           0 :         log_info(LD_EXIT, "eventdns rejected test address %s",
    1986             :                  escaped_safe_str(address));
    1987             :       }
    1988           0 :     } SMARTLIST_FOREACH_END(address);
    1989             :   }
    1990             : }
    1991             : 
    1992             : #define N_WILDCARD_CHECKS 2
    1993             : 
    1994             : /** Launch DNS requests for a few nonexistent hostnames and a few well-known
    1995             :  * hostnames, and see if we can catch our nameserver trying to hijack them and
    1996             :  * map them to a stupid "I couldn't find ggoogle.com but maybe you'd like to
    1997             :  * buy these lovely encyclopedias" page. */
    1998             : static void
    1999           0 : dns_launch_wildcard_checks(void)
    2000             : {
    2001           0 :   int i, ipv6;
    2002           0 :   log_info(LD_EXIT, "Launching checks to see whether our nameservers like "
    2003             :            "to hijack DNS failures.");
    2004           0 :   for (ipv6 = 0; ipv6 <= 1; ++ipv6) {
    2005           0 :     for (i = 0; i < N_WILDCARD_CHECKS; ++i) {
    2006             :       /* RFC2606 reserves these.  Sadly, some DNS hijackers, in a silly
    2007             :        * attempt to 'comply' with rfc2606, refrain from giving A records for
    2008             :        * these.  This is the standards-compliance equivalent of making sure
    2009             :        * that your crackhouse's elevator inspection certificate is up to date.
    2010             :        */
    2011           0 :       launch_wildcard_check(2, 16, ipv6, ".invalid");
    2012           0 :       launch_wildcard_check(2, 16, ipv6, ".test");
    2013             : 
    2014             :       /* These will break specs if there are ever any number of
    2015             :        * 8+-character top-level domains. */
    2016           0 :       launch_wildcard_check(8, 16, ipv6, "");
    2017             : 
    2018             :       /* Try some random .com/org/net domains. This will work fine so long as
    2019             :        * not too many resolve to the same place. */
    2020           0 :       launch_wildcard_check(8, 16, ipv6, ".com");
    2021           0 :       launch_wildcard_check(8, 16, ipv6, ".org");
    2022           0 :       launch_wildcard_check(8, 16, ipv6, ".net");
    2023             :     }
    2024             :   }
    2025           0 : }
    2026             : 
    2027             : /** If appropriate, start testing whether our DNS servers tend to lie to
    2028             :  * us. */
    2029             : void
    2030           0 : dns_launch_correctness_checks(void)
    2031             : {
    2032           0 :   static struct event *launch_event = NULL;
    2033           0 :   struct timeval timeout;
    2034           0 :   if (!get_options()->ServerDNSDetectHijacking)
    2035           0 :     return;
    2036           0 :   dns_launch_wildcard_checks();
    2037             : 
    2038             :   /* Wait a while before launching requests for test addresses, so we can
    2039             :    * get the results from checking for wildcarding. */
    2040           0 :   if (!launch_event)
    2041           0 :     launch_event = tor_evtimer_new(tor_libevent_get_base(),
    2042             :                                    launch_test_addresses, NULL);
    2043           0 :   timeout.tv_sec = 30;
    2044           0 :   timeout.tv_usec = 0;
    2045           0 :   if (evtimer_add(launch_event, &timeout) < 0) {
    2046           0 :     log_warn(LD_BUG, "Couldn't add timer for checking for dns hijacking");
    2047             :   }
    2048             : }
    2049             : 
    2050             : /** Return true iff our DNS servers lie to us too much to be trusted. */
    2051             : int
    2052           0 : dns_seems_to_be_broken(void)
    2053             : {
    2054           0 :   return dns_is_completely_invalid;
    2055             : }
    2056             : 
    2057             : /** Return true iff we think that IPv6 hostname lookup is broken */
    2058             : int
    2059           0 : dns_seems_to_be_broken_for_ipv6(void)
    2060             : {
    2061           0 :   return dns_is_broken_for_ipv6;
    2062             : }
    2063             : 
    2064             : /** Forget what we've previously learned about our DNS servers' correctness. */
    2065             : void
    2066           2 : dns_reset_correctness_checks(void)
    2067             : {
    2068           2 :   strmap_free(dns_wildcard_response_count, tor_free_);
    2069           2 :   dns_wildcard_response_count = NULL;
    2070             : 
    2071           2 :   n_wildcard_requests = 0;
    2072             : 
    2073           2 :   n_ipv6_requests_made = n_ipv6_timeouts = 0;
    2074             : 
    2075           2 :   if (dns_wildcard_list) {
    2076           0 :     SMARTLIST_FOREACH(dns_wildcard_list, char *, cp, tor_free(cp));
    2077           0 :     smartlist_clear(dns_wildcard_list);
    2078             :   }
    2079           2 :   if (dns_wildcarded_test_address_list) {
    2080           0 :     SMARTLIST_FOREACH(dns_wildcarded_test_address_list, char *, cp,
    2081             :                       tor_free(cp));
    2082           0 :     smartlist_clear(dns_wildcarded_test_address_list);
    2083             :   }
    2084           2 :   dns_wildcard_one_notice_given = dns_wildcard_notice_given =
    2085           2 :     dns_wildcarded_test_address_notice_given = dns_is_completely_invalid =
    2086           2 :     dns_is_broken_for_ipv6 = 0;
    2087           2 : }
    2088             : 
    2089             : /** Return true iff we have noticed that the dotted-quad <b>ip</b> has been
    2090             :  * returned in response to requests for nonexistent hostnames. */
    2091             : static int
    2092           0 : answer_is_wildcarded(const char *ip)
    2093             : {
    2094           0 :   return dns_wildcard_list && smartlist_contains_string(dns_wildcard_list, ip);
    2095             : }
    2096             : 
    2097             : /** Exit with an assertion if <b>resolve</b> is corrupt. */
    2098             : static void
    2099           3 : assert_resolve_ok(cached_resolve_t *resolve)
    2100             : {
    2101           3 :   tor_assert(resolve);
    2102           3 :   tor_assert(resolve->magic == CACHED_RESOLVE_MAGIC);
    2103           3 :   tor_assert(strlen(resolve->address) < MAX_ADDRESSLEN);
    2104           3 :   tor_assert(tor_strisnonupper(resolve->address));
    2105           3 :   if (resolve->state != CACHE_STATE_PENDING) {
    2106           1 :     tor_assert(!resolve->pending_connections);
    2107             :   }
    2108           3 :   if (resolve->state == CACHE_STATE_PENDING ||
    2109             :       resolve->state == CACHE_STATE_DONE) {
    2110             : #if 0
    2111             :     tor_assert(!resolve->ttl);
    2112             :     if (resolve->is_reverse)
    2113             :       tor_assert(!resolve->hostname);
    2114             :     else
    2115             :       tor_assert(!resolve->result_ipv4.addr_ipv4);
    2116             : #endif /* 0 */
    2117             :     /*XXXXX ADD MORE */
    2118           3 :   }
    2119           3 : }
    2120             : 
    2121             : /** Return the number of DNS cache entries as an int */
    2122             : static int
    2123          20 : dns_cache_entry_count(void)
    2124             : {
    2125          20 :    return HT_SIZE(&cache_root);
    2126             : }
    2127             : 
    2128             : /* Return the total size in bytes of the DNS cache. */
    2129             : size_t
    2130          16 : dns_cache_total_allocation(void)
    2131             : {
    2132          16 :   return sizeof(struct cached_resolve_t) * dns_cache_entry_count() +
    2133          16 :          HT_MEM_USAGE(&cache_root);
    2134             : }
    2135             : 
    2136             : /** Log memory information about our internal DNS cache at level 'severity'. */
    2137             : void
    2138           0 : dump_dns_mem_usage(int severity)
    2139             : {
    2140             :   /* This should never be larger than INT_MAX. */
    2141           0 :   int hash_count = dns_cache_entry_count();
    2142           0 :   size_t hash_mem = dns_cache_total_allocation();
    2143             : 
    2144             :   /* Print out the count and estimated size of our &cache_root.  It undercounts
    2145             :      hostnames in cached reverse resolves.
    2146             :    */
    2147           0 :   tor_log(severity, LD_MM, "Our DNS cache has %d entries.", hash_count);
    2148           0 :   tor_log(severity, LD_MM, "Our DNS cache size is approximately %u bytes.",
    2149             :       (unsigned)hash_mem);
    2150           0 : }
    2151             : 
    2152             : /* Do a round of OOM cleanup on all DNS entries. Return the amount of removed
    2153             :  * bytes. It is possible that the returned value is lower than min_remove_bytes
    2154             :  * if the caches get emptied out so the caller should be aware of this. */
    2155             : size_t
    2156           4 : dns_cache_handle_oom(time_t now, size_t min_remove_bytes)
    2157             : {
    2158           4 :   time_t time_inc = 0;
    2159           4 :   size_t total_bytes_removed = 0;
    2160           4 :   size_t current_size = dns_cache_total_allocation();
    2161             : 
    2162           4 :   do {
    2163             :     /* If no DNS entries left, break loop. */
    2164           4 :     if (!dns_cache_entry_count())
    2165             :       break;
    2166             : 
    2167             :     /* Get cutoff interval and remove entries. */
    2168           0 :     time_t cutoff = now + time_inc;
    2169           0 :     purge_expired_resolves(cutoff);
    2170             : 
    2171             :     /* Update amount of bytes removed and array size. */
    2172           0 :     size_t bytes_removed = current_size - dns_cache_total_allocation();
    2173           0 :     current_size -= bytes_removed;
    2174           0 :     total_bytes_removed += bytes_removed;
    2175             : 
    2176             :     /* Increase time_inc by a reasonable fraction. */
    2177           0 :     time_inc += (MAX_DNS_TTL / 4);
    2178           0 :   } while (total_bytes_removed < min_remove_bytes);
    2179             : 
    2180           4 :   return total_bytes_removed;
    2181             : }
    2182             : 
    2183             : #ifdef DEBUG_DNS_CACHE
    2184             : /** Exit with an assertion if the DNS cache is corrupt. */
    2185             : static void
    2186             : assert_cache_ok_(void)
    2187             : {
    2188             :   cached_resolve_t **resolve;
    2189             :   int bad_rep = HT_REP_IS_BAD_(cache_map, &cache_root);
    2190             :   if (bad_rep) {
    2191             :     log_err(LD_BUG, "Bad rep type %d on dns cache hash table", bad_rep);
    2192             :     tor_assert(!bad_rep);
    2193             :   }
    2194             : 
    2195             :   HT_FOREACH(resolve, cache_map, &cache_root) {
    2196             :     assert_resolve_ok(*resolve);
    2197             :     tor_assert((*resolve)->state != CACHE_STATE_DONE);
    2198             :   }
    2199             :   if (!cached_resolve_pqueue)
    2200             :     return;
    2201             : 
    2202             :   smartlist_pqueue_assert_ok(cached_resolve_pqueue,
    2203             :                              compare_cached_resolves_by_expiry_,
    2204             :                              offsetof(cached_resolve_t, minheap_idx));
    2205             : 
    2206             :   SMARTLIST_FOREACH(cached_resolve_pqueue, cached_resolve_t *, res,
    2207             :     {
    2208             :       if (res->state == CACHE_STATE_DONE) {
    2209             :         cached_resolve_t *found = HT_FIND(cache_map, &cache_root, res);
    2210             :         tor_assert(!found || found != res);
    2211             :       } else {
    2212             :         cached_resolve_t *found = HT_FIND(cache_map, &cache_root, res);
    2213             :         tor_assert(found);
    2214             :       }
    2215             :     });
    2216             : }
    2217             : 
    2218             : #endif /* defined(DEBUG_DNS_CACHE) */
    2219             : 
    2220             : cached_resolve_t *
    2221           1 : dns_get_cache_entry(cached_resolve_t *query)
    2222             : {
    2223           1 :   return HT_FIND(cache_map, &cache_root, query);
    2224             : }
    2225             : 
    2226             : void
    2227           2 : dns_insert_cache_entry(cached_resolve_t *new_entry)
    2228             : {
    2229           2 :   HT_INSERT(cache_map, &cache_root, new_entry);
    2230           2 : }

Generated by: LCOV version 1.14