tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

dns.c (81536B)


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