dns.c 74.3 KB
Newer Older
1
2
/* Copyright (c) 2003-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3
 * Copyright (c) 2007-2013, The Tor Project, Inc. */
4
5
/* See LICENSE for licensing information */

Roger Dingledine's avatar
Roger Dingledine committed
6
7
/**
 * \file dns.c
8
 * \brief Implements a local cache for DNS results for Tor servers.
Roger Dingledine's avatar
Roger Dingledine committed
9
 * This is implemented as a wrapper around Adam Langley's eventdns.c code.
10
11
 * (We can't just use gethostbyname() and friends because we really need to
 * be nonblocking.)
Roger Dingledine's avatar
Roger Dingledine committed
12
 **/
13

14
#include "or.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
15
#include "circuitlist.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
16
#include "circuituse.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
17
#include "config.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
18
#include "connection.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
19
#include "connection_edge.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
20
#include "control.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
21
#include "dns.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
22
#include "main.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
23
#include "policies.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
24
#include "relay.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
25
#include "router.h"
26
#include "ht.h"
27
#ifdef HAVE_EVENT2_DNS_H
28
#include <event2/event.h>
29
30
#include <event2/dns.h>
#else
31
#include <event.h>
32
#include "eventdns.h"
33
34
35
36
#ifndef HAVE_EVDNS_SET_DEFAULT_OUTGOING_BIND_ADDRESS
#define HAVE_EVDNS_SET_DEFAULT_OUTGOING_BIND_ADDRESS
#endif
#endif
37

38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
#ifndef HAVE_EVENT2_DNS_H
struct evdns_base;
struct evdns_request;
#define evdns_base_new(x,y) tor_malloc(1)
#define evdns_base_clear_nameservers_and_suspend(base) \
  evdns_clear_nameservers_and_suspend()
#define evdns_base_search_clear(base) evdns_search_clear()
#define evdns_base_set_default_outgoing_bind_address(base, a, len)  \
  evdns_set_default_outgoing_bind_address((a),(len))
#define evdns_base_resolv_conf_parse(base, options, fname) \
  evdns_resolv_conf_parse((options), (fname))
#define evdns_base_count_nameservers(base)      \
  evdns_count_nameservers()
#define evdns_base_resume(base)                 \
  evdns_resume()
#define evdns_base_config_windows_nameservers(base)     \
  evdns_config_windows_nameservers()
55
56
#define evdns_base_set_option_(base, opt, val) \
  evdns_set_option((opt),(val),DNS_OPTIONS_ALL)
57
/* Note: our internal eventdns.c, plus Libevent 1.4, used a 1 return to
58
 * signify failure to launch a resolve. Libevent 2.0 uses a -1 return to
59
 * signify a failure on a resolve, though if we're on Libevent 2.0, we should
60
 * have event2/dns.h and never hit these macros.  Regardless, 0 is success. */
61
#define evdns_base_resolve_ipv4(base, addr, options, cb, ptr) \
62
63
  ((evdns_resolve_ipv4((addr), (options), (cb), (ptr))!=0)    \
   ? NULL : ((void*)1))
64
65
66
#define evdns_base_resolve_ipv6(base, addr, options, cb, ptr) \
  ((evdns_resolve_ipv6((addr), (options), (cb), (ptr))!=0)    \
   ? NULL : ((void*)1))
67
68
69
70
71
72
#define evdns_base_resolve_reverse(base, addr, options, cb, ptr)        \
  ((evdns_resolve_reverse((addr), (options), (cb), (ptr))!=0)           \
   ? NULL : ((void*)1))
#define evdns_base_resolve_reverse_ipv6(base, addr, options, cb, ptr)   \
  ((evdns_resolve_reverse_ipv6((addr), (options), (cb), (ptr))!=0)      \
   ? NULL : ((void*)1))
73
74
75
76
77
78
79
80

#elif defined(LIBEVENT_VERSION_NUMBER) && LIBEVENT_VERSION_NUMBER < 0x02000303
#define evdns_base_set_option_(base, opt, val) \
  evdns_base_set_option((base), (opt),(val),DNS_OPTIONS_ALL)

#else
#define evdns_base_set_option_ evdns_base_set_option

81
82
#endif

Roger Dingledine's avatar
Roger Dingledine committed
83
/** Longest hostname we're willing to resolve. */
84
85
#define MAX_ADDRESSLEN 256

86
87
/** How long will we wait for an answer from the resolver before we decide
 * that the resolver is wedged? */
88
89
#define RESOLVE_MAX_TIMEOUT 300

90
91
92
/** Our evdns_base; this structure handles all our name lookups. */
static struct evdns_base *the_evdns_base = NULL;

93
94
/** Have we currently configured nameservers with eventdns? */
static int nameservers_configured = 0;
95
96
/** Did our most recent attempt to configure nameservers with eventdns fail? */
static int nameserver_config_failed = 0;
97
98
99
100
101
102
/** What was the resolv_conf fname we last used when configuring the
 * nameservers? Used to check whether we need to reconfigure. */
static char *resolv_conf_fname = NULL;
/** What was the mtime on the resolv.conf file we last used when configuring
 * the nameservers?  Used to check whether we need to reconfigure. */
static time_t resolv_conf_mtime = 0;
103

Roger Dingledine's avatar
Roger Dingledine committed
104
/** Linked list of connections waiting for a DNS answer. */
105
typedef struct pending_connection_t {
106
  edge_connection_t *conn;
107
  struct pending_connection_t *next;
108
} pending_connection_t;
109

110
111
/** Value of 'magic' field for cached_resolve_t.  Used to try to catch bad
 * pointers and memory stomping. */
112
113
#define CACHED_RESOLVE_MAGIC 0x1234F00D

114
115
116
/* Possible states for a cached resolve_t */
/** We are waiting for the resolver system to tell us an answer here.
 * When we get one, or when we time out, the state of this cached_resolve_t
117
 * will become "DONE" and we'll possibly add a CACHED
118
119
120
 * entry. This cached_resolve_t will be in the hash table so that we will
 * know not to launch more requests for this addr, but rather to add more
 * connections to the pending list for the addr. */
121
#define CACHE_STATE_PENDING 0
122
123
124
/** This used to be a pending cached_resolve_t, and we got an answer for it.
 * Now we're waiting for this cached_resolve_t to expire.  This should
 * have no pending connections, and should not appear in the hash table. */
125
#define CACHE_STATE_DONE 1
126
127
/** We are caching an answer for this address. This should have no pending
 * connections, and should appear in the hash table. */
128
129
#define CACHE_STATE_CACHED 2

130
131
132
133
/** @name status values for a single DNS request.
 *
 * @{ */
/** The DNS request is in progress. */
134
#define RES_STATUS_INFLIGHT 1
135
/** The DNS request finished and gave an answer */
136
#define RES_STATUS_DONE_OK 2
137
/** The DNS request finished and gave an error */
138
#define RES_STATUS_DONE_ERR 3
139
/**@}*/
140

Roger Dingledine's avatar
Roger Dingledine committed
141
/** A DNS request: possibly completed, possibly pending; cached_resolve
142
 * structs are stored at the OR side in a hash table, and as a linked
143
144
 * list from oldest to newest.
 */
145
typedef struct cached_resolve_t {
146
  HT_ENTRY(cached_resolve_t) node;
147
  uint32_t magic;  /**< Must be CACHED_RESOLVE_MAGIC */
148
  char address[MAX_ADDRESSLEN]; /**< The hostname to be resolved. */
149
150

  union {
151
152
    uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful.
                         * (In host order.) */
153
154
    int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */
  } result_ipv4; /**< Outcome of IPv4 lookup */
155
  union {
156
157
158
159
    struct in6_addr addr_ipv6; /**< IPv6 addr for <b>address</b>, if
                                * successful */
    int err_ipv6; /**< One of DNS_ERR_*, if IPv6 lookup failed. */
  } result_ipv6; /**< Outcome of IPv6 lookup, if any */
160
  union {
161
162
    char *hostname; /** A hostname, if PTR lookup happened successfully*/
    int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */
163
  } result_ptr;
164
165
166
167
168
169
  /** @name Status fields
   *
   * These take one of the RES_STATUS_* values, depending on the state
   * of the corresponding lookup.
   *
   * @{ */
170
171
172
  unsigned int res_status_ipv4 : 2;
  unsigned int res_status_ipv6 : 2;
  unsigned int res_status_hostname : 2;
173
  /**@}*/
174
  uint8_t state; /**< Is this cached entry pending/done/informative? */
175

176
  time_t expire; /**< Remove items from cache after this time. */
177
178
179
  uint32_t ttl_ipv4; /**< What TTL did the nameserver tell us? */
  uint32_t ttl_ipv6; /**< What TTL did the nameserver tell us? */
  uint32_t ttl_hostname; /**< What TTL did the nameserver tell us? */
180
  /** Connections that want to know when we get an answer for this resolve. */
181
  pending_connection_t *pending_connections;
182
183
  /** Position of this element in the heap*/
  int minheap_idx;
184
} cached_resolve_t;
185

186
static void purge_expired_resolves(time_t now);
187
188
189
190
static void dns_found_answer(const char *address, uint8_t query_type,
                             int dns_answer,
                             const tor_addr_t *addr,
                             const char *hostname,
191
                             uint32_t ttl);
192
193
static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type,
                               const cached_resolve_t *resolve);
194
static int launch_resolve(cached_resolve_t *resolve);
195
static void add_wildcarded_test_address(const char *address);
196
static int configure_nameservers(int force);
197
static int answer_is_wildcarded(const char *ip);
198
static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
199
                            or_circuit_t *oncirc, char **resolved_to_hostname,
200
201
                            int *made_connection_pending_out,
                            cached_resolve_t **resolve_out);
202
203
204
205
206
207
208
static int set_exitconn_info_from_resolve(edge_connection_t *exitconn,
                                          const cached_resolve_t *resolve,
                                          char **hostname_out);
static int evdns_err_is_transient(int err);
static void inform_pending_connections(cached_resolve_t *resolve);
static void make_pending_resolve_cached(cached_resolve_t *cached);

209
#ifdef DEBUG_DNS_CACHE
210
211
static void assert_cache_ok_(void);
#define assert_cache_ok() assert_cache_ok_()
212
#else
213
#define assert_cache_ok() STMT_NIL
214
#endif
215
static void assert_resolve_ok(cached_resolve_t *resolve);
216

217
218
/** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root;
219

220
/** Global: how many IPv6 requests have we made in all? */
221
static uint64_t n_ipv6_requests_made = 0;
222
/** Global: how many IPv6 requests have timed out? */
223
static uint64_t n_ipv6_timeouts = 0;
224
/** Global: Do we think that IPv6 DNS is broken? */
225
226
static int dns_is_broken_for_ipv6 = 0;

Roger Dingledine's avatar
Roger Dingledine committed
227
/** Function to compare hashed resolves on their addresses; used to
228
 * implement hash tables. */
229
230
static INLINE int
cached_resolves_eq(cached_resolve_t *a, cached_resolve_t *b)
231
{
232
  /* make this smarter one day? */
233
  assert_resolve_ok(a); // Not b; b may be just a search.
234
235
236
  return !strncmp(a->address, b->address, MAX_ADDRESSLEN);
}

237
/** Hash function for cached_resolve objects */
238
239
240
241
static INLINE unsigned int
cached_resolve_hash(cached_resolve_t *a)
{
  return ht_string_hash(a->address);
242
243
}

244
HT_PROTOTYPE(cache_map, cached_resolve_t, node, cached_resolve_hash,
245
             cached_resolves_eq)
246
HT_GENERATE(cache_map, cached_resolve_t, node, cached_resolve_hash,
247
            cached_resolves_eq, 0.6, malloc, realloc, free)
248

249
/** Initialize the DNS cache. */
250
static void
251
init_cache_map(void)
252
{
253
  HT_INIT(cache_map, &cache_root);
254
255
}

256
/** Helper: called by eventdns when eventdns wants to log something. */
257
static void
258
evdns_log_cb(int warn, const char *msg)
259
{
260
  const char *cp;
261
262
  static int all_down = 0;
  int severity = warn ? LOG_WARN : LOG_INFO;
263
264
265
266
  if (!strcmpstart(msg, "Resolve requested for") &&
      get_options()->SafeLogging) {
    log(LOG_INFO, LD_EXIT, "eventdns: Resolve requested.");
    return;
267
268
  } else if (!strcmpstart(msg, "Search: ")) {
    return;
269
  }
270
271
  if (!strcmpstart(msg, "Nameserver ") && (cp=strstr(msg, " has failed: "))) {
    char *ns = tor_strndup(msg+11, cp-(msg+11));
272
    const char *err = strchr(cp, ':')+2;
273
    tor_assert(err);
274
275
276
    /* Don't warn about a single failed nameserver; we'll warn with 'all
     * nameservers have failed' if we're completely out of nameservers;
     * otherwise, the situation is tolerable. */
277
    severity = LOG_INFO;
278
    control_event_server_status(LOG_NOTICE,
279
280
281
282
283
284
                                "NAMESERVER_STATUS NS=%s STATUS=DOWN ERR=%s",
                                ns, escaped(err));
    tor_free(ns);
  } else if (!strcmpstart(msg, "Nameserver ") &&
             (cp=strstr(msg, " is back up"))) {
    char *ns = tor_strndup(msg+11, cp-(msg+11));
285
    severity = (all_down && warn) ? LOG_NOTICE : LOG_INFO;
286
    all_down = 0;
287
288
289
290
291
    control_event_server_status(LOG_NOTICE,
                                "NAMESERVER_STATUS NS=%s STATUS=UP", ns);
    tor_free(ns);
  } else if (!strcmp(msg, "All nameservers have failed")) {
    control_event_server_status(LOG_WARN, "NAMESERVER_ALL_DOWN");
292
    all_down = 1;
293
  }
294
  log(severity, LD_EXIT, "eventdns: %s", msg);
295
296
}

297
298
/** Helper: passed to eventdns.c as a callback so it can generate random
 * numbers for transaction IDs and 0x20-hack coding. */
299
static void
300
dns_randfn_(char *b, size_t n)
301
{
302
  crypto_rand(b,n);
303
304
}

Roger Dingledine's avatar
Roger Dingledine committed
305
/** Initialize the DNS subsystem; called by the OR process. */
306
int
307
308
dns_init(void)
{
309
  init_cache_map();
310
  evdns_set_random_bytes_fn(dns_randfn_);
311
312
313
314
  if (server_mode(get_options())) {
    int r = configure_nameservers(1);
    return r;
  }
315
  return 0;
316
}
317

318
319
320
/** Called when DNS-related options change (or may have changed).  Returns -1
 * on failure, 0 on success. */
int
321
322
dns_reset(void)
{
323
  const or_options_t *options = get_options();
324
  if (! server_mode(options)) {
325
326
327
328
329
330
331
332

    if (!the_evdns_base) {
      if (!(the_evdns_base = evdns_base_new(tor_libevent_get_base(), 0))) {
        log_err(LD_BUG, "Couldn't create an evdns_base");
        return -1;
      }
    }

333
334
    evdns_base_clear_nameservers_and_suspend(the_evdns_base);
    evdns_base_search_clear(the_evdns_base);
335
336
337
338
    nameservers_configured = 0;
    tor_free(resolv_conf_fname);
    resolv_conf_mtime = 0;
  } else {
339
    if (configure_nameservers(0) < 0) {
340
      return -1;
341
    }
342
  }
343
  return 0;
344
345
}

Nick Mathewson's avatar
Nick Mathewson committed
346
347
/** Return true iff the most recent attempt to initialize the DNS subsystem
 * failed. */
348
349
350
351
352
353
int
has_dns_init_failed(void)
{
  return nameserver_config_failed;
}

354
355
/** Helper: Given a TTL from a DNS response, determine what TTL to give the
 * OP that asked us to resolve it. */
356
357
358
359
360
361
362
363
364
365
366
uint32_t
dns_clip_ttl(uint32_t ttl)
{
  if (ttl < MIN_DNS_TTL)
    return MIN_DNS_TTL;
  else if (ttl > MAX_DNS_TTL)
    return MAX_DNS_TTL;
  else
    return ttl;
}

367
368
/** Helper: Given a TTL from a DNS response, determine how long to hold it in
 * our cache. */
369
370
371
372
373
374
375
376
377
378
379
static uint32_t
dns_get_expiry_ttl(uint32_t ttl)
{
  if (ttl < MIN_DNS_TTL)
    return MIN_DNS_TTL;
  else if (ttl > MAX_DNS_ENTRY_AGE)
    return MAX_DNS_ENTRY_AGE;
  else
    return ttl;
}

380
/** Helper: free storage held by an entry in the DNS cache. */
381
static void
382
free_cached_resolve_(cached_resolve_t *r)
383
{
384
385
  if (!r)
    return;
Nick Mathewson's avatar
Nick Mathewson committed
386
  while (r->pending_connections) {
387
    pending_connection_t *victim = r->pending_connections;
388
389
390
    r->pending_connections = victim->next;
    tor_free(victim);
  }
391
392
  if (r->res_status_hostname == RES_STATUS_DONE_OK)
    tor_free(r->result_ptr.hostname);
393
  r->magic = 0xFF00FF00;
394
395
396
  tor_free(r);
}

397
398
399
/** Compare two cached_resolve_t pointers by expiry time, and return
 * less-than-zero, zero, or greater-than-zero as appropriate. Used for
 * the priority queue implementation. */
400
static int
401
compare_cached_resolves_by_expiry_(const void *_a, const void *_b)
402
{
403
  const cached_resolve_t *a = _a, *b = _b;
404
405
406
407
408
409
  if (a->expire < b->expire)
    return -1;
  else if (a->expire == b->expire)
    return 0;
  else
    return 1;
410
411
}

412
413
/** Priority queue of cached_resolve_t objects to let us know when they
 * will expire. */
414
415
static smartlist_t *cached_resolve_pqueue = NULL;

416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
static void
cached_resolve_add_answer(cached_resolve_t *resolve,
                          int query_type,
                          int dns_result,
                          const tor_addr_t *answer_addr,
                          const char *answer_hostname,
                          uint32_t ttl)
{
  if (query_type == DNS_PTR) {
    if (resolve->res_status_hostname != RES_STATUS_INFLIGHT)
      return;

    if (dns_result == DNS_ERR_NONE && answer_hostname) {
      resolve->result_ptr.hostname = tor_strdup(answer_hostname);
      resolve->res_status_hostname = RES_STATUS_DONE_OK;
    } else {
      resolve->result_ptr.err_hostname = dns_result;
      resolve->res_status_hostname = RES_STATUS_DONE_ERR;
    }
    resolve->ttl_hostname = ttl;
  } else if (query_type == DNS_IPv4_A) {
    if (resolve->res_status_ipv4 != RES_STATUS_INFLIGHT)
      return;

    if (dns_result == DNS_ERR_NONE && answer_addr) {
      tor_assert(tor_addr_family(answer_addr) == AF_INET);
      resolve->result_ipv4.addr_ipv4 = tor_addr_to_ipv4h(answer_addr);
      resolve->res_status_ipv4 = RES_STATUS_DONE_OK;
    } else {
      resolve->result_ipv4.err_ipv4 = dns_result;
      resolve->res_status_ipv4 = RES_STATUS_DONE_ERR;
    }

  } else if (query_type == DNS_IPv6_AAAA) {
    if (resolve->res_status_ipv6 != RES_STATUS_INFLIGHT)
      return;

    if (dns_result == DNS_ERR_NONE && answer_addr) {
      tor_assert(tor_addr_family(answer_addr) == AF_INET6);
      memcpy(&resolve->result_ipv6.addr_ipv6,
             tor_addr_to_in6(answer_addr),
             sizeof(struct in6_addr));
      resolve->res_status_ipv6 = RES_STATUS_DONE_OK;
    } else {
      resolve->result_ipv6.err_ipv6 = dns_result;
      resolve->res_status_ipv6 = RES_STATUS_DONE_ERR;
    }
  }
}

466
/** Return true iff there are no in-flight requests for <b>resolve</b>. */
467
468
469
470
471
472
473
474
static int
cached_resolve_have_all_answers(const cached_resolve_t *resolve)
{
  return (resolve->res_status_ipv4 != RES_STATUS_INFLIGHT &&
          resolve->res_status_ipv6 != RES_STATUS_INFLIGHT &&
          resolve->res_status_hostname != RES_STATUS_INFLIGHT);
}

475
476
/** Set an expiry time for a cached_resolve_t, and add it to the expiry
 * priority queue */
477
478
479
480
static void
set_expiry(cached_resolve_t *resolve, time_t expires)
{
  tor_assert(resolve && resolve->expire == 0);
481
  if (!cached_resolve_pqueue)
482
    cached_resolve_pqueue = smartlist_new();
483
484
  resolve->expire = expires;
  smartlist_pqueue_add(cached_resolve_pqueue,
485
                       compare_cached_resolves_by_expiry_,
486
                       STRUCT_OFFSET(cached_resolve_t, minheap_idx),
487
488
489
                       resolve);
}

490
/** Free all storage held in the DNS cache and related structures. */
491
492
493
void
dns_free_all(void)
{
494
  cached_resolve_t **ptr, **next, *item;
495
  assert_cache_ok();
496
497
498
  if (cached_resolve_pqueue) {
    SMARTLIST_FOREACH(cached_resolve_pqueue, cached_resolve_t *, res,
      {
499
        if (res->state == CACHE_STATE_DONE)
500
          free_cached_resolve_(res);
501
502
      });
  }
503
  for (ptr = HT_START(cache_map, &cache_root); ptr != NULL; ptr = next) {
504
    item = *ptr;
505
    next = HT_NEXT_RMV(cache_map, &cache_root, ptr);
506
    free_cached_resolve_(item);
507
  }
508
  HT_CLEAR(cache_map, &cache_root);
509
  smartlist_free(cached_resolve_pqueue);
510
  cached_resolve_pqueue = NULL;
511
  tor_free(resolv_conf_fname);
512
513
}

514
515
/** Remove every cached_resolve whose <b>expire</b> time is before or
 * equal to <b>now</b> from the cache. */
516
static void
517
purge_expired_resolves(time_t now)
518
{
Nick Mathewson's avatar
Nick Mathewson committed
519
  cached_resolve_t *resolve, *removed;
520
  pending_connection_t *pend;
521
  edge_connection_t *pendconn;
522

Nick Mathewson's avatar
Nick Mathewson committed
523
  assert_cache_ok();
524
525
526
527
528
529
530
531
  if (!cached_resolve_pqueue)
    return;

  while (smartlist_len(cached_resolve_pqueue)) {
    resolve = smartlist_get(cached_resolve_pqueue, 0);
    if (resolve->expire > now)
      break;
    smartlist_pqueue_pop(cached_resolve_pqueue,
532
                         compare_cached_resolves_by_expiry_,
533
                         STRUCT_OFFSET(cached_resolve_t, minheap_idx));
534

535
    if (resolve->state == CACHE_STATE_PENDING) {
536
      log_debug(LD_EXIT,
537
538
                "Expiring a dns resolve %s that's still pending. Forgot to "
                "cull it? DNS resolve didn't tell us about the timeout?",
539
                escaped_safe_str(resolve->address));
540
    } else if (resolve->state == CACHE_STATE_CACHED) {
541
542
543
544
545
546
547
548
      log_debug(LD_EXIT,
                "Forgetting old cached resolve (address %s, expires %lu)",
                escaped_safe_str(resolve->address),
                (unsigned long)resolve->expire);
      tor_assert(!resolve->pending_connections);
    } else {
      tor_assert(resolve->state == CACHE_STATE_DONE);
      tor_assert(!resolve->pending_connections);
549
    }
550

551
    if (resolve->pending_connections) {
552
      log_debug(LD_EXIT,
553
                "Closing pending connections on timed-out DNS resolve!");
554
555
556
557
      while (resolve->pending_connections) {
        pend = resolve->pending_connections;
        resolve->pending_connections = pend->next;
        /* Connections should only be pending if they have no socket. */
558
        tor_assert(!SOCKET_OK(pend->conn->base_.s));
559
        pendconn = pend->conn;
560
        if (!pendconn->base_.marked_for_close) {
561
562
563
564
          connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT);
          circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
          connection_free(TO_CONN(pendconn));
        }
565
566
        tor_free(pend);
      }
567
    }
568

569
    if (resolve->state == CACHE_STATE_CACHED ||
570
571
572
573
574
        resolve->state == CACHE_STATE_PENDING) {
      removed = HT_REMOVE(cache_map, &cache_root, resolve);
      if (removed != resolve) {
        log_err(LD_BUG, "The expired resolve we purged didn't match any in"
                " the cache. Tried to purge %s (%p); instead got %s (%p).",
575
                resolve->address, (void*)resolve,
576
                removed ? removed->address : "NULL", (void*)removed);
577
578
579
      }
      tor_assert(removed == resolve);
    } else {
580
      /* This should be in state DONE. Make sure it's not in the cache. */
581
582
      cached_resolve_t *tmp = HT_FIND(cache_map, &cache_root, resolve);
      tor_assert(tmp != resolve);
583
    }
584
585
    if (resolve->res_status_hostname == RES_STATUS_DONE_OK)
      tor_free(resolve->result_ptr.hostname);
586
587
    resolve->magic = 0xF0BBF0BB;
    tor_free(resolve);
588
  }
589

Nick Mathewson's avatar
Nick Mathewson committed
590
  assert_cache_ok();
591
592
}

593
594
595
596
/* argument for send_resolved_cell only, meaning "let the answer type be ipv4
 * or ipv6 depending on the connection's address". */
#define RESOLVED_TYPE_AUTO 0xff

597
598
/** Send a response to the RESOLVE request of a connection.
 * <b>answer_type</b> must be one of
599
 * RESOLVED_TYPE_(AUTO|ERROR|ERROR_TRANSIENT|).
600
601
 *
 * If <b>circ</b> is provided, and we have a cached answer, send the
602
603
 * answer back along circ; otherwise, send the answer back along
 * <b>conn</b>'s attached circuit.
604
 */
605
static void
606
607
send_resolved_cell(edge_connection_t *conn, uint8_t answer_type,
                   const cached_resolve_t *resolved)
608
{
609
610
  char buf[RELAY_PAYLOAD_SIZE], *cp = buf;
  size_t buflen = 0;
611
  uint32_t ttl;
612
613

  buf[0] = answer_type;
614
  ttl = dns_clip_ttl(conn->address_ttl);
615
616
617

  switch (answer_type)
    {
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
    case RESOLVED_TYPE_AUTO:
      if (resolved && resolved->res_status_ipv4 == RES_STATUS_DONE_OK) {
        cp[0] = RESOLVED_TYPE_IPV4;
        cp[1] = 4;
        set_uint32(cp+2, htonl(resolved->result_ipv4.addr_ipv4));
        set_uint32(cp+6, htonl(ttl));
        cp += 10;
      }
      if (resolved && resolved->res_status_ipv6 == RES_STATUS_DONE_OK) {
        const uint8_t *bytes = resolved->result_ipv6.addr_ipv6.s6_addr;
        cp[0] = RESOLVED_TYPE_IPV6;
        cp[1] = 16;
        memcpy(cp+2, bytes, 16);
        set_uint32(cp+18, htonl(ttl));
        cp += 22;
      }
      if (cp != buf) {
        buflen = cp - buf;
        break;
      } else {
        answer_type = RESOLVED_TYPE_ERROR;
        /* fall through. */
640
      }
641
642
    case RESOLVED_TYPE_ERROR_TRANSIENT:
    case RESOLVED_TYPE_ERROR:
643
644
      {
        const char *errmsg = "Error resolving hostname";
645
        size_t msglen = strlen(errmsg);
646

647
        buf[0] = answer_type;
648
649
        buf[1] = msglen;
        strlcpy(buf+2, errmsg, sizeof(buf)-2);
650
        set_uint32(buf+2+msglen, htonl(ttl));
651
652
653
        buflen = 6+msglen;
        break;
      }
654
655
    default:
      tor_assert(0);
656
      return;
657
    }
658
  // log_notice(LD_EXIT, "Sending a regular RESOLVED reply: ");
Roger Dingledine's avatar
Roger Dingledine committed
659

660
  connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
661
662
}

663
664
665
/** Send a response to the RESOLVE request of a connection for an in-addr.arpa
 * address on connection <b>conn</b> which yielded the result <b>hostname</b>.
 * The answer type will be RESOLVED_HOSTNAME.
666
667
668
 *
 * If <b>circ</b> is provided, and we have a cached answer, send the
 * answer back along circ; otherwise, send the answer back along
669
 * <b>conn</b>'s attached circuit.
670
671
 */
static void
672
send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname)
673
674
675
676
677
{
  char buf[RELAY_PAYLOAD_SIZE];
  size_t buflen;
  uint32_t ttl;
  size_t namelen = strlen(hostname);
678
  tor_assert(hostname);
679
680
681
682
683
684
685
686
687
688

  tor_assert(namelen < 256);
  ttl = dns_clip_ttl(conn->address_ttl);

  buf[0] = RESOLVED_TYPE_HOSTNAME;
  buf[1] = (uint8_t)namelen;
  memcpy(buf+2, hostname, namelen);
  set_uint32(buf+2+namelen, htonl(ttl));
  buflen = 2+namelen+4;

689
  // log_notice(LD_EXIT, "Sending a reply RESOLVED reply: %s", hostname);
690
  connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
691
  // log_notice(LD_EXIT, "Sent");
692
693
}

Roger Dingledine's avatar
Roger Dingledine committed
694
/** See if we have a cache entry for <b>exitconn</b>-\>address. If so,
Nick Mathewson's avatar
Nick Mathewson committed
695
 * if resolve valid, put it into <b>exitconn</b>-\>addr and return 1.
Roger Dingledine's avatar
Roger Dingledine committed
696
 * If resolve failed, free exitconn and return -1.
697
 *
698
699
700
701
702
 * (For EXIT_PURPOSE_RESOLVE connections, send back a RESOLVED error cell
 * on returning -1.  For EXIT_PURPOSE_CONNECT connections, there's no
 * need to send back an END cell, since connection_exit_begin_conn will
 * do that for us.)
 *
703
 * If we have a cached answer, send the answer back along <b>exitconn</b>'s
704
 * circuit.
705
 *
706
707
708
709
710
 * Else, if seen before and pending, add conn to the pending list,
 * and return 0.
 *
 * Else, if not seen before, add conn to pending list, hand to
 * dns farm, and return 0.
711
712
713
714
715
716
 *
 * Exitconn's on_circuit field must be set, but exitconn should not
 * yet be linked onto the n_streams/resolving_streams list of that circuit.
 * On success, link the connection to n_streams if it's an exit connection.
 * On "pending", link the connection to resolving streams.  Otherwise,
 * clear its on_circuit field.
717
 */
718
int
719
dns_resolve(edge_connection_t *exitconn)
720
721
722
{
  or_circuit_t *oncirc = TO_OR_CIRCUIT(exitconn->on_circuit);
  int is_resolve, r;
723
  int made_connection_pending = 0;
724
  char *hostname = NULL;
725
  cached_resolve_t *resolve = NULL;
726
  is_resolve = exitconn->base_.purpose == EXIT_PURPOSE_RESOLVE;
727

728
  r = dns_resolve_impl(exitconn, is_resolve, oncirc, &hostname,
729
                       &made_connection_pending, &resolve);
730

731
732
  switch (r) {
    case 1:
733
734
      /* We got an answer without a lookup -- either the answer was
       * cached, or it was obvious (like an IP address). */
735
      if (is_resolve) {
736
        /* Send the answer back right now, and detach. */
737
738
739
        if (hostname)
          send_resolved_hostname_cell(exitconn, hostname);
        else
740
          send_resolved_cell(exitconn, RESOLVED_TYPE_AUTO, resolve);
741
        exitconn->on_circuit = NULL;
742
      } else {
743
744
        /* Add to the n_streams list; the calling function will send back a
         * connected cell. */
745
746
747
748
749
        exitconn->next_stream = oncirc->n_streams;
        oncirc->n_streams = exitconn;
      }
      break;
    case 0:
750
751
      /* The request is pending: add the connection into the linked list of
       * resolving_streams on this circuit. */
752
      exitconn->base_.state = EXIT_CONN_STATE_RESOLVING;
753
754
755
756
757
      exitconn->next_stream = oncirc->resolving_streams;
      oncirc->resolving_streams = exitconn;
      break;
    case -2:
    case -1:
758
      /* The request failed before it could start: cancel this connection,
759
       * and stop everybody waiting for the same connection. */
760
761
      if (is_resolve) {
        send_resolved_cell(exitconn,
762
763
             (r == -1) ? RESOLVED_TYPE_ERROR : RESOLVED_TYPE_ERROR_TRANSIENT,
             NULL);
764
      }
765

766
      exitconn->on_circuit = NULL;
767

768
      dns_cancel_pending_resolve(exitconn->base_.address);
769

770
      if (!made_connection_pending && !exitconn->base_.marked_for_close) {
771
772
773
        /* If we made the connection pending, then we freed it already in
         * dns_cancel_pending_resolve().  If we marked it for close, it'll
         * get freed from the main loop.  Otherwise, can free it now. */
774
        connection_free(TO_CONN(exitconn));
775
      }
776
777
778
779
780
781
782
783
784
785
786
787
788
789
      break;
    default:
      tor_assert(0);
  }

  tor_free(hostname);
  return r;
}

/** Helper function for dns_resolve: same functionality, but does not handle:
 *     - marking connections on error and clearing their on_circuit
 *     - linking connections to n_streams/resolving_streams,
 *     - sending resolved cells if we have an answer/error right away,
 *
Roger Dingledine's avatar
Roger Dingledine committed
790
791
792
 * Return -2 on a transient error. If it's a reverse resolve and it's
 * successful, sets *<b>hostname_out</b> to a newly allocated string
 * holding the cached reverse DNS value.
793
794
795
796
 *
 * Set *<b>made_connection_pending_out</b> to true if we have placed
 * <b>exitconn</b> on the list of pending connections for some resolve; set it
 * to false otherwise.
797
798
 *
 * Set *<b>resolve_out</b> to a cached resolve, if we found one.
799
800
801
 */
static int
dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
802
                 or_circuit_t *oncirc, char **hostname_out,
803
804
                 int *made_connection_pending_out,
                 cached_resolve_t **resolve_out)
805
{
806
807
808
  cached_resolve_t *resolve;
  cached_resolve_t search;
  pending_connection_t *pending_connection;
809
  int is_reverse = 0;
810
  tor_addr_t addr;
811
  time_t now = time(NULL);
812
  int r;
813
  assert_connection_ok(TO_CONN(exitconn), 0);
814
  tor_assert(!SOCKET_OK(exitconn->base_.s));
815
  assert_cache_ok();
816
  tor_assert(oncirc);
817
  *made_connection_pending_out = 0;
818

819
  /* first check if exitconn->base_.address is an IP. If so, we already
820
   * know the answer. */
821
  if (tor_addr_parse(&addr, exitconn->base_.address) >= 0) {
822
823
    if (tor_addr_family(&addr) == AF_INET ||
        tor_addr_family(&addr) == AF_INET6) {
824
      tor_addr_copy(&exitconn->base_.addr, &addr);
825
826
827
      exitconn->address_ttl = DEFAULT_DNS_TTL;
      return 1;
    } else {
828
      /* XXXX unspec? Bogus? */
829
830
      return -1;
    }
831
  }
832

833
  /* If we're a non-exit, don't even do DNS lookups. */
834
  if (router_my_exit_policy_is_reject_star())
835
    return -1;
836

837
  if (address_is_invalid_destination(exitconn->base_.address, 0)) {
838
839
    log(LOG_PROTOCOL_WARN, LD_EXIT,
        "Rejecting invalid destination address %s",
840
        escaped_safe_str(exitconn->base_.address));
841
842
    return -1;
  }
843
844

  /* then take this opportunity to see if there are any expired
845
   * resolves in the hash table. */
846
  purge_expired_resolves(now);
847

848
849
  /* lower-case exitconn->base_.address, so it's in canonical form */
  tor_strlower(exitconn->base_.address);
850

851
852
  /* Check whether this is a reverse lookup.  If it's malformed, or it's a
   * .in-addr.arpa address but this isn't a resolve request, kill the
853
   * connection.
854
   */
855
  if ((r = tor_addr_parse_PTR_name(&addr, exitconn->base_.address,
856
                                              AF_UNSPEC, 0)) != 0) {
857
    if (r == 1) {
858
      is_reverse = 1;
859
860
      if (tor_addr_is_internal(&addr, 0)) /* internal address? */
        return -1;
861
    }
862
863
864
865

    if (!is_reverse || !is_resolve) {
      if (!is_reverse)
        log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.",
866
                 escaped_safe_str(exitconn->base_.address));
867
868
869
870
      else if (!is_resolve)
        log_info(LD_EXIT,
                 "Attempt to connect to a .in-addr.arpa address \"%s\"; "
                 "sending error.",
871
                 escaped_safe_str(exitconn->base_.address));
872
873
874

      return -1;
    }
875
    //log_notice(LD_EXIT, "Looks like an address %s",
876
    //exitconn->base_.address);
877
  }
878
  exitconn->is_reverse_dns_lookup = is_reverse;
879

880
  /* now check the hash table to see if 'address' is already there. */
881
  strlcpy(search.address, exitconn->base_.address, sizeof(search.address));
882
  resolve = HT_FIND(cache_map, &cache_root, &search);
883
  if (resolve && resolve->expire > now) { /* already there */
884
    switch (resolve->state) {
885
886
      case CACHE_STATE_PENDING:
        /* add us to the pending list */
887
        pending_connection = tor_malloc_zero(
888
                                      sizeof(pending_connection_t));
889
        pending_connection->conn = exitconn;
Roger Dingledine's avatar
   
Roger Dingledine committed
890
891
        pending_connection->next = resolve->pending_connections;
        resolve->pending_connections = pending_connection;
892
        *made_connection_pending_out = 1;
893
894
        log_debug(LD_EXIT,"Connection (fd "TOR_SOCKET_T_FORMAT") waiting "
                  "for pending DNS resolve of %s", exitconn->base_.s,
895
                  escaped_safe_str(exitconn->base_.address));
Roger Dingledine's avatar
   
Roger Dingledine committed
896
        return 0;
897
      case CACHE_STATE_CACHED:
898
899
        log_debug(LD_EXIT,"Connection (fd "TOR_SOCKET_T_FORMAT") found "
                  "cached answer for %s",
900
                  exitconn->base_.s,
901
                  escaped_safe_str(resolve->address));
902

903
904
        *resolve_out = resolve;

905
        return set_exitconn_info_from_resolve(exitconn, resolve, hostname_out);
906