dns.c 73.5 KB
Newer Older
1
2
/* Copyright (c) 2003-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3
 * Copyright (c) 2007-2012, 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
153
    uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>, if successful */
    int err_ipv4; /**< One of DNS_ERR_*, if IPv4 lookup failed. */
  } result_ipv4; /**< Outcome of IPv4 lookup */
154
  union {
155
156
157
158
    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 */
159
  union {
160
161
    char *hostname; /** A hostname, if PTR lookup happened successfully*/
    int err_hostname; /** One of DNS_ERR_*, if PTR lookup failed. */
162
  } result_ptr;
163
164
165
166
167
168
  /** @name Status fields
   *
   * These take one of the RES_STATUS_* values, depending on the state
   * of the corresponding lookup.
   *
   * @{ */
169
170
171
  unsigned int res_status_ipv4 : 2;
  unsigned int res_status_ipv6 : 2;
  unsigned int res_status_hostname : 2;
172
  /**@}*/
173
  uint8_t state; /**< Is this cached entry pending/done/informative? */
174

175
  time_t expire; /**< Remove items from cache after this time. */
176
177
178
  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? */
179
  /** Connections that want to know when we get an answer for this resolve. */
180
  pending_connection_t *pending_connections;
181
182
  /** Position of this element in the heap*/
  int minheap_idx;
183
} cached_resolve_t;
184

185
static void purge_expired_resolves(time_t now);
186
187
188
189
static void dns_found_answer(const char *address, uint8_t query_type,
                             int dns_answer,
                             const tor_addr_t *addr,
                             const char *hostname,
190
                             uint32_t ttl);
191
static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type);
192
static int launch_resolve(cached_resolve_t *resolve);
193
static void add_wildcarded_test_address(const char *address);
194
static int configure_nameservers(int force);
195
static int answer_is_wildcarded(const char *ip);
196
static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
197
198
                            or_circuit_t *oncirc, char **resolved_to_hostname,
                            int *made_connection_pending_out);
199
200
201
202
203
204
205
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);

206
#ifdef DEBUG_DNS_CACHE
207
208
static void assert_cache_ok_(void);
#define assert_cache_ok() assert_cache_ok_()
209
#else
210
#define assert_cache_ok() STMT_NIL
211
#endif
212
static void assert_resolve_ok(cached_resolve_t *resolve);
213

214
215
/** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root;
216

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

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

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

241
HT_PROTOTYPE(cache_map, cached_resolve_t, node, cached_resolve_hash,
242
             cached_resolves_eq)
243
HT_GENERATE(cache_map, cached_resolve_t, node, cached_resolve_hash,
244
            cached_resolves_eq, 0.6, malloc, realloc, free)
245

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

253
/** Helper: called by eventdns when eventdns wants to log something. */
254
static void
255
evdns_log_cb(int warn, const char *msg)
256
{
257
  const char *cp;
258
259
  static int all_down = 0;
  int severity = warn ? LOG_WARN : LOG_INFO;
260
261
262
263
  if (!strcmpstart(msg, "Resolve requested for") &&
      get_options()->SafeLogging) {
    log(LOG_INFO, LD_EXIT, "eventdns: Resolve requested.");
    return;
264
265
  } else if (!strcmpstart(msg, "Search: ")) {
    return;
266
  }
267
268
  if (!strcmpstart(msg, "Nameserver ") && (cp=strstr(msg, " has failed: "))) {
    char *ns = tor_strndup(msg+11, cp-(msg+11));
269
    const char *err = strchr(cp, ':')+2;
270
    tor_assert(err);
271
272
273
    /* 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. */
274
    severity = LOG_INFO;
275
    control_event_server_status(LOG_NOTICE,
276
277
278
279
280
281
                                "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));
282
    severity = (all_down && warn) ? LOG_NOTICE : LOG_INFO;
283
    all_down = 0;
284
285
286
287
288
    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");
289
    all_down = 1;
290
  }
291
  log(severity, LD_EXIT, "eventdns: %s", msg);
292
293
}

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

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

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

    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;
      }
    }

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

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

351
352
/** Helper: Given a TTL from a DNS response, determine what TTL to give the
 * OP that asked us to resolve it. */
353
354
355
356
357
358
359
360
361
362
363
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;
}

364
365
/** Helper: Given a TTL from a DNS response, determine how long to hold it in
 * our cache. */
366
367
368
369
370
371
372
373
374
375
376
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;
}

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

394
395
396
/** 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. */
397
static int
398
compare_cached_resolves_by_expiry_(const void *_a, const void *_b)
399
{
400
  const cached_resolve_t *a = _a, *b = _b;
401
402
403
404
405
406
  if (a->expire < b->expire)
    return -1;
  else if (a->expire == b->expire)
    return 0;
  else
    return 1;
407
408
}

409
410
/** Priority queue of cached_resolve_t objects to let us know when they
 * will expire. */
411
412
static smartlist_t *cached_resolve_pqueue = NULL;

413
414
415
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
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;
    }
  }
}

463
/** Return true iff there are no in-flight requests for <b>resolve</b>. */
464
465
466
467
468
469
470
471
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);
}

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

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

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

Nick Mathewson's avatar
Nick Mathewson committed
520
  assert_cache_ok();
521
522
523
524
525
526
527
528
  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,
529
                         compare_cached_resolves_by_expiry_,
530
                         STRUCT_OFFSET(cached_resolve_t, minheap_idx));
531

532
    if (resolve->state == CACHE_STATE_PENDING) {
533
      log_debug(LD_EXIT,
534
535
                "Expiring a dns resolve %s that's still pending. Forgot to "
                "cull it? DNS resolve didn't tell us about the timeout?",
536
                escaped_safe_str(resolve->address));
537
    } else if (resolve->state == CACHE_STATE_CACHED) {
538
539
540
541
542
543
544
545
      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);
546
    }
547

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

566
    if (resolve->state == CACHE_STATE_CACHED ||
567
568
569
570
571
        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).",
572
                resolve->address, (void*)resolve,
573
                removed ? removed->address : "NULL", (void*)removed);
574
575
576
      }
      tor_assert(removed == resolve);
    } else {
577
      /* This should be in state DONE. Make sure it's not in the cache. */
578
579
      cached_resolve_t *tmp = HT_FIND(cache_map, &cache_root, resolve);
      tor_assert(tmp != resolve);
580
    }
581
582
    if (resolve->res_status_hostname == RES_STATUS_DONE_OK)
      tor_free(resolve->result_ptr.hostname);
583
584
    resolve->magic = 0xF0BBF0BB;
    tor_free(resolve);
585
  }
586

Nick Mathewson's avatar
Nick Mathewson committed
587
  assert_cache_ok();
588
589
}

590
591
592
593
/* 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

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

609
610
611
612
613
614
615
616
617
618
  if (answer_type == RESOLVED_TYPE_AUTO) {
    sa_family_t family = tor_addr_family(&conn->base_.addr);
    if (family == AF_INET)
      answer_type = RESOLVED_TYPE_IPV4;
    else if (family == AF_INET6)
      answer_type = RESOLVED_TYPE_IPV6;
    else
      answer_type = RESOLVED_TYPE_ERROR_TRANSIENT;
  }

619
  buf[0] = answer_type;
620
  ttl = dns_clip_ttl(conn->address_ttl);
621
622
623
624
625

  switch (answer_type)
    {
    case RESOLVED_TYPE_IPV4:
      buf[1] = 4;
626
      set_uint32(buf+2, tor_addr_to_ipv4n(&conn->base_.addr));
627
      set_uint32(buf+6, htonl(ttl));
628
      buflen = 10;
629
      break;
630
631
632
633
634
635
636
637
638
    case RESOLVED_TYPE_IPV6:
      {
        const uint8_t *bytes = tor_addr_to_in6_addr8(&conn->base_.addr);
        buf[1] = 16;
        memcpy(buf+2, bytes, 16);
        set_uint32(buf+18, htonl(ttl));
        buflen = 22;
      }
      break;
639
640
    case RESOLVED_TYPE_ERROR_TRANSIENT:
    case RESOLVED_TYPE_ERROR:
641
642
      {
        const char *errmsg = "Error resolving hostname";
643
        size_t msglen = strlen(errmsg);
644

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

657
  connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
658
659
}

660
661
662
/** 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.
663
664
665
 *
 * If <b>circ</b> is provided, and we have a cached answer, send the
 * answer back along circ; otherwise, send the answer back along
666
 * <b>conn</b>'s attached circuit.
667
668
 */
static void
669
send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname)
670
671
672
673
674
{
  char buf[RELAY_PAYLOAD_SIZE];
  size_t buflen;
  uint32_t ttl;
  size_t namelen = strlen(hostname);
675
  tor_assert(hostname);
676
677
678
679
680
681
682
683
684
685

  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;

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

Roger Dingledine's avatar
Roger Dingledine committed
691
/** See if we have a cache entry for <b>exitconn</b>-\>address. If so,
Nick Mathewson's avatar
Nick Mathewson committed
692
 * if resolve valid, put it into <b>exitconn</b>-\>addr and return 1.
Roger Dingledine's avatar
Roger Dingledine committed
693
 * If resolve failed, free exitconn and return -1.
694
 *
695
696
697
698
699
 * (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.)
 *
700
 * If we have a cached answer, send the answer back along <b>exitconn</b>'s
701
 * circuit.
702
 *
703
704
705
706
707
 * 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.
708
709
710
711
712
713
 *
 * 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.
714
 */
715
int
716
dns_resolve(edge_connection_t *exitconn)
717
718
719
{
  or_circuit_t *oncirc = TO_OR_CIRCUIT(exitconn->on_circuit);
  int is_resolve, r;
720
  int made_connection_pending = 0;
721
  char *hostname = NULL;
722
  is_resolve = exitconn->base_.purpose == EXIT_PURPOSE_RESOLVE;
723

724
725
  r = dns_resolve_impl(exitconn, is_resolve, oncirc, &hostname,
                       &made_connection_pending);
726

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

761
      exitconn->on_circuit = NULL;
762

763
      dns_cancel_pending_resolve(exitconn->base_.address);
764

765
      if (!made_connection_pending && !exitconn->base_.marked_for_close) {
766
767
768
        /* 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. */
769
        connection_free(TO_CONN(exitconn));
770
      }
771
772
773
774
775
776
777
778
779
780
781
782
783
784
      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
785
786
787
 * 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.
788
789
790
791
 *
 * 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.
792
793
794
 */
static int
dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
795
796
                 or_circuit_t *oncirc, char **hostname_out,
                 int *made_connection_pending_out)
797
{
798
799
800
  cached_resolve_t *resolve;
  cached_resolve_t search;
  pending_connection_t *pending_connection;
801
  int is_reverse = 0;
802
  const routerinfo_t *me;
803
  tor_addr_t addr;
804
  time_t now = time(NULL);
805
  int r;
806
  assert_connection_ok(TO_CONN(exitconn), 0);
807
  tor_assert(!SOCKET_OK(exitconn->base_.s));
808
  assert_cache_ok();
809
  tor_assert(oncirc);
810
  *made_connection_pending_out = 0;
811

812
  /* first check if exitconn->base_.address is an IP. If so, we already
813
   * know the answer. */
814
  if (tor_addr_parse(&addr, exitconn->base_.address) >= 0) {
815
816
    if (tor_addr_family(&addr) == AF_INET ||
        tor_addr_family(&addr) == AF_INET6) {
817
      tor_addr_copy(&exitconn->base_.addr, &addr);
818
819
820
      exitconn->address_ttl = DEFAULT_DNS_TTL;
      return 1;
    } else {
821
      /* XXXX unspec? Bogus? */
822
823
      return -1;
    }
824
  }
825

826
827
828
829
830
  /* If we're a non-exit, don't even do DNS lookups. */
  if (!(me = router_get_my_routerinfo()) ||
      policy_is_reject_star(me->exit_policy)) {
    return -1;
  }
831
  if (address_is_invalid_destination(exitconn->base_.address, 0)) {
832
833
    log(LOG_PROTOCOL_WARN, LD_EXIT,
        "Rejecting invalid destination address %s",
834
        escaped_safe_str(exitconn->base_.address));
835
836
    return -1;
  }
837
838

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

842
843
  /* lower-case exitconn->base_.address, so it's in canonical form */
  tor_strlower(exitconn->base_.address);
844

845
846
  /* 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
847
   * connection.
848
   */
849
  if ((r = tor_addr_parse_PTR_name(&addr, exitconn->base_.address,
850
                                              AF_UNSPEC, 0)) != 0) {
851
    if (r == 1) {
852
      is_reverse = 1;
853
854
      if (tor_addr_is_internal(&addr, 0)) /* internal address? */
        return -1;
855
    }
856
857
858
859

    if (!is_reverse || !is_resolve) {
      if (!is_reverse)
        log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.",
860
                 escaped_safe_str(exitconn->base_.address));
861
862
863
864
      else if (!is_resolve)
        log_info(LD_EXIT,
                 "Attempt to connect to a .in-addr.arpa address \"%s\"; "
                 "sending error.",
865
                 escaped_safe_str(exitconn->base_.address));
866
867
868

      return -1;
    }
869
    //log_notice(LD_EXIT, "Looks like an address %s",
870
    //exitconn->base_.address);
871
  }
872
  exitconn->is_reverse_dns_lookup = is_reverse;
873

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

        return set_exitconn_info_from_resolve(exitconn, resolve, hostname_out);

898
899
900
      case CACHE_STATE_DONE:
        log_err(LD_BUG, "Found a 'DONE' dns resolve still in the cache.");
        tor_fragile_assert();
901
    }
Roger Dingledine's avatar
Roger Dingledine committed
902
    tor_assert(0);
Roger Dingledine's avatar
Roger Dingledine committed
903
  }
904
  tor_assert(!resolve);
Roger Dingledine's avatar
Roger Dingledine committed
905
  /* not there, need to add it */
906
  resolve = tor_malloc_zero(sizeof(cached_resolve_t));
907
  resolve->magic = CACHED_RESOLVE_MAGIC;
Roger Dingledine's avatar
Roger Dingledine committed
908
  resolve->state = CACHE_STATE_PENDING;