dns.c 71.8 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
64
65
66
67
68
69
  ((evdns_resolve_ipv4((addr), (options), (cb), (ptr))!=0)    \
   ? NULL : ((void*)1))
#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))
70
71
72
73
74
75
76
77

#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

78
79
#endif

Roger Dingledine's avatar
Roger Dingledine committed
80
/** Longest hostname we're willing to resolve. */
81
82
#define MAX_ADDRESSLEN 256

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

Roger Dingledine's avatar
Roger Dingledine committed
87
/** Possible outcomes from hostname lookup: permanent failure,
88
 * transient (retryable) failure, and success. */
89
90
91
92
#define DNS_RESOLVE_FAILED_TRANSIENT 1
#define DNS_RESOLVE_FAILED_PERMANENT 2
#define DNS_RESOLVE_SUCCEEDED 3

93
94
95
/** Our evdns_base; this structure handles all our name lookups. */
static struct evdns_base *the_evdns_base = NULL;

96
97
/** Have we currently configured nameservers with eventdns? */
static int nameservers_configured = 0;
98
99
/** Did our most recent attempt to configure nameservers with eventdns fail? */
static int nameserver_config_failed = 0;
100
101
102
103
104
105
/** 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;
106

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

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

117
118
119
/* 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
120
 * will become "DONE" and we'll possibly add a CACHED
121
122
123
 * 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. */
124
#define CACHE_STATE_PENDING 0
125
126
127
/** 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. */
128
#define CACHE_STATE_DONE 1
129
130
/** We are caching an answer for this address. This should have no pending
 * connections, and should appear in the hash table. */
131
132
133
134
135
136
#define CACHE_STATE_CACHED 2

/* DOCDOC */
#define RES_STATUS_INFLIGHT 1
#define RES_STATUS_DONE_OK 2
#define RES_STATUS_DONE_ERR 3
137

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

  union {
    uint32_t addr_ipv4; /**< IPv4 addr for <b>address</b>. */
    int err_ipv4;
  } result_ipv4;
151
  union {
152
153
154
155
156
157
158
159
160
161
162
163
164
    struct in6_addr addr_ipv6;
    int err_ipv6;
  } result_ipv6;
  union {
    char *hostname;
    int err_hostname;
  } result_ptr;
  unsigned int res_status_ipv4 : 2;
  unsigned int res_status_ipv6 : 2;
  unsigned int res_status_hostname : 2;

  uint8_t state; /**< Is this cached entry pending/done/informative? */
  //uint8_t is_reverse; /**< Is this a reverse (addr-to-hostname) lookup? */
165
  time_t expire; /**< Remove items from cache after this time. */
166
167
168
  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? */
169
  /** Connections that want to know when we get an answer for this resolve. */
170
  pending_connection_t *pending_connections;
171
172
  /** Position of this element in the heap*/
  int minheap_idx;
173
} cached_resolve_t;
174

175
static void purge_expired_resolves(time_t now);
176
177
178
179
static void dns_found_answer(const char *address, uint8_t query_type,
                             int dns_answer,
                             const tor_addr_t *addr,
                             const char *hostname,
180
                             uint32_t ttl);
181
static void send_resolved_cell(edge_connection_t *conn, uint8_t answer_type);
182
static int launch_resolve(cached_resolve_t *resolve);
183
static void add_wildcarded_test_address(const char *address);
184
static int configure_nameservers(int force);
185
static int answer_is_wildcarded(const char *ip);
186
static int dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
187
188
                            or_circuit_t *oncirc, char **resolved_to_hostname,
                            int *made_connection_pending_out);
189
190
191
192
193
194
195
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);

196
#ifdef DEBUG_DNS_CACHE
197
198
static void assert_cache_ok_(void);
#define assert_cache_ok() assert_cache_ok_()
199
#else
200
#define assert_cache_ok() STMT_NIL
201
#endif
202
static void assert_resolve_ok(cached_resolve_t *resolve);
203

204
205
/** Hash table of cached_resolve objects. */
static HT_HEAD(cache_map, cached_resolve_t) cache_root;
206

207
208
209
210
211
/*DOCDOC*/
static uint64_t n_ipv6_requests_made = 0;
static uint64_t n_ipv6_timeouts = 0;
static int dns_is_broken_for_ipv6 = 0;

Roger Dingledine's avatar
Roger Dingledine committed
212
/** Function to compare hashed resolves on their addresses; used to
213
 * implement hash tables. */
214
215
static INLINE int
cached_resolves_eq(cached_resolve_t *a, cached_resolve_t *b)
216
{
217
  /* make this smarter one day? */
218
  assert_resolve_ok(a); // Not b; b may be just a search.
219
220
221
  return !strncmp(a->address, b->address, MAX_ADDRESSLEN);
}

222
/** Hash function for cached_resolve objects */
223
224
225
226
static INLINE unsigned int
cached_resolve_hash(cached_resolve_t *a)
{
  return ht_string_hash(a->address);
227
228
}

229
HT_PROTOTYPE(cache_map, cached_resolve_t, node, cached_resolve_hash,
230
             cached_resolves_eq)
231
HT_GENERATE(cache_map, cached_resolve_t, node, cached_resolve_hash,
232
            cached_resolves_eq, 0.6, malloc, realloc, free)
233

234
/** Initialize the DNS cache. */
235
static void
236
init_cache_map(void)
237
{
238
  HT_INIT(cache_map, &cache_root);
239
240
}

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

282
283
/** Helper: passed to eventdns.c as a callback so it can generate random
 * numbers for transaction IDs and 0x20-hack coding. */
284
static void
285
dns_randfn_(char *b, size_t n)
286
{
287
  crypto_rand(b,n);
288
289
}

Roger Dingledine's avatar
Roger Dingledine committed
290
/** Initialize the DNS subsystem; called by the OR process. */
291
int
292
293
dns_init(void)
{
294
  init_cache_map();
295
  evdns_set_random_bytes_fn(dns_randfn_);
296
297
298
299
  if (server_mode(get_options())) {
    int r = configure_nameservers(1);
    return r;
  }
300
  return 0;
301
}
302

303
304
305
/** Called when DNS-related options change (or may have changed).  Returns -1
 * on failure, 0 on success. */
int
306
307
dns_reset(void)
{
308
  const or_options_t *options = get_options();
309
  if (! server_mode(options)) {
310
311
312
313
314
315
316
317

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

318
319
    evdns_base_clear_nameservers_and_suspend(the_evdns_base);
    evdns_base_search_clear(the_evdns_base);
320
321
322
323
    nameservers_configured = 0;
    tor_free(resolv_conf_fname);
    resolv_conf_mtime = 0;
  } else {
324
    if (configure_nameservers(0) < 0) {
325
      return -1;
326
    }
327
  }
328
  return 0;
329
330
}

Nick Mathewson's avatar
Nick Mathewson committed
331
332
/** Return true iff the most recent attempt to initialize the DNS subsystem
 * failed. */
333
334
335
336
337
338
int
has_dns_init_failed(void)
{
  return nameserver_config_failed;
}

339
340
/** Helper: Given a TTL from a DNS response, determine what TTL to give the
 * OP that asked us to resolve it. */
341
342
343
344
345
346
347
348
349
350
351
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;
}

352
353
/** Helper: Given a TTL from a DNS response, determine how long to hold it in
 * our cache. */
354
355
356
357
358
359
360
361
362
363
364
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;
}

365
/** Helper: free storage held by an entry in the DNS cache. */
366
static void
367
free_cached_resolve_(cached_resolve_t *r)
368
{
369
370
  if (!r)
    return;
Nick Mathewson's avatar
Nick Mathewson committed
371
  while (r->pending_connections) {
372
    pending_connection_t *victim = r->pending_connections;
373
374
375
    r->pending_connections = victim->next;
    tor_free(victim);
  }
376
377
  if (r->res_status_hostname == RES_STATUS_DONE_OK)
    tor_free(r->result_ptr.hostname);
378
  r->magic = 0xFF00FF00;
379
380
381
  tor_free(r);
}

382
383
384
/** 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. */
385
static int
386
compare_cached_resolves_by_expiry_(const void *_a, const void *_b)
387
{
388
  const cached_resolve_t *a = _a, *b = _b;
389
390
391
392
393
394
  if (a->expire < b->expire)
    return -1;
  else if (a->expire == b->expire)
    return 0;
  else
    return 1;
395
396
}

397
398
/** Priority queue of cached_resolve_t objects to let us know when they
 * will expire. */
399
400
static smartlist_t *cached_resolve_pqueue = NULL;

401
402
403
404
405
406
407
408
409
410
411
412
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
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;
    }
  }
}

/*DOCDOC*/
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);
}

460
461
/** Set an expiry time for a cached_resolve_t, and add it to the expiry
 * priority queue */
462
463
464
465
static void
set_expiry(cached_resolve_t *resolve, time_t expires)
{
  tor_assert(resolve && resolve->expire == 0);
466
  if (!cached_resolve_pqueue)
467
    cached_resolve_pqueue = smartlist_new();
468
469
  resolve->expire = expires;
  smartlist_pqueue_add(cached_resolve_pqueue,
470
                       compare_cached_resolves_by_expiry_,
471
                       STRUCT_OFFSET(cached_resolve_t, minheap_idx),
472
473
474
                       resolve);
}

475
/** Free all storage held in the DNS cache and related structures. */
476
477
478
void
dns_free_all(void)
{
479
  cached_resolve_t **ptr, **next, *item;
480
  assert_cache_ok();
481
482
483
  if (cached_resolve_pqueue) {
    SMARTLIST_FOREACH(cached_resolve_pqueue, cached_resolve_t *, res,
      {
484
        if (res->state == CACHE_STATE_DONE)
485
          free_cached_resolve_(res);
486
487
      });
  }
488
  for (ptr = HT_START(cache_map, &cache_root); ptr != NULL; ptr = next) {
489
    item = *ptr;
490
    next = HT_NEXT_RMV(cache_map, &cache_root, ptr);
491
    free_cached_resolve_(item);
492
  }
493
  HT_CLEAR(cache_map, &cache_root);
494
  smartlist_free(cached_resolve_pqueue);
495
  cached_resolve_pqueue = NULL;
496
  tor_free(resolv_conf_fname);
497
498
}

499
500
/** Remove every cached_resolve whose <b>expire</b> time is before or
 * equal to <b>now</b> from the cache. */
501
static void
502
purge_expired_resolves(time_t now)
503
{
Nick Mathewson's avatar
Nick Mathewson committed
504
  cached_resolve_t *resolve, *removed;
505
  pending_connection_t *pend;
506
  edge_connection_t *pendconn;
507

Nick Mathewson's avatar
Nick Mathewson committed
508
  assert_cache_ok();
509
510
511
512
513
514
515
516
  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,
517
                         compare_cached_resolves_by_expiry_,
518
                         STRUCT_OFFSET(cached_resolve_t, minheap_idx));
519

520
    if (resolve->state == CACHE_STATE_PENDING) {
521
      log_debug(LD_EXIT,
522
523
                "Expiring a dns resolve %s that's still pending. Forgot to "
                "cull it? DNS resolve didn't tell us about the timeout?",
524
                escaped_safe_str(resolve->address));
525
    } else if (resolve->state == CACHE_STATE_CACHED) {
526
527
528
529
530
531
532
533
      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);
534
    }
535

536
    if (resolve->pending_connections) {
537
      log_debug(LD_EXIT,
538
                "Closing pending connections on timed-out DNS resolve!");
539
540
541
542
      while (resolve->pending_connections) {
        pend = resolve->pending_connections;
        resolve->pending_connections = pend->next;
        /* Connections should only be pending if they have no socket. */
543
        tor_assert(!SOCKET_OK(pend->conn->base_.s));
544
        pendconn = pend->conn;
545
        if (!pendconn->base_.marked_for_close) {
546
547
548
549
          connection_edge_end(pendconn, END_STREAM_REASON_TIMEOUT);
          circuit_detach_stream(circuit_get_by_edge_conn(pendconn), pendconn);
          connection_free(TO_CONN(pendconn));
        }
550
551
        tor_free(pend);
      }
552
    }
553

554
    if (resolve->state == CACHE_STATE_CACHED ||
555
556
557
558
559
        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).",
560
                resolve->address, (void*)resolve,
561
                removed ? removed->address : "NULL", (void*)removed);
562
563
564
      }
      tor_assert(removed == resolve);
    } else {
565
      /* This should be in state DONE. Make sure it's not in the cache. */
566
567
      cached_resolve_t *tmp = HT_FIND(cache_map, &cache_root, resolve);
      tor_assert(tmp != resolve);
568
    }
569
570
    if (resolve->res_status_hostname == RES_STATUS_DONE_OK)
      tor_free(resolve->result_ptr.hostname);
571
572
    resolve->magic = 0xF0BBF0BB;
    tor_free(resolve);
573
  }
574

Nick Mathewson's avatar
Nick Mathewson committed
575
  assert_cache_ok();
576
577
}

578
579
580
581
/* 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

582
583
/** Send a response to the RESOLVE request of a connection.
 * <b>answer_type</b> must be one of
584
 * RESOLVED_TYPE_(IPV4|IPV6|ERROR|ERROR_TRANSIENT|AUTO).
585
586
 *
 * If <b>circ</b> is provided, and we have a cached answer, send the
587
588
 * answer back along circ; otherwise, send the answer back along
 * <b>conn</b>'s attached circuit.
589
 */
590
static void
591
send_resolved_cell(edge_connection_t *conn, uint8_t answer_type)
592
593
{
  char buf[RELAY_PAYLOAD_SIZE];
594
  size_t buflen;
595
  uint32_t ttl;
596

597
598
599
600
601
602
603
604
605
606
  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;
  }

607
  buf[0] = answer_type;
608
  ttl = dns_clip_ttl(conn->address_ttl);
609
610
611
612
613

  switch (answer_type)
    {
    case RESOLVED_TYPE_IPV4:
      buf[1] = 4;
614
      set_uint32(buf+2, tor_addr_to_ipv4n(&conn->base_.addr));
615
      set_uint32(buf+6, htonl(ttl));
616
      buflen = 10;
617
      break;
618
619
620
621
622
623
624
625
626
    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;
627
628
    case RESOLVED_TYPE_ERROR_TRANSIENT:
    case RESOLVED_TYPE_ERROR:
629
630
      {
        const char *errmsg = "Error resolving hostname";
631
        size_t msglen = strlen(errmsg);
632

633
634
        buf[1] = msglen;
        strlcpy(buf+2, errmsg, sizeof(buf)-2);
635
        set_uint32(buf+2+msglen, htonl(ttl));
636
637
638
        buflen = 6+msglen;
        break;
      }
639
640
    default:
      tor_assert(0);
641
      return;
642
    }
643
  // log_notice(LD_EXIT, "Sending a regular RESOLVED reply: ");
Roger Dingledine's avatar
Roger Dingledine committed
644

645
  connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
646
647
}

648
649
650
/** 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.
651
652
653
 *
 * If <b>circ</b> is provided, and we have a cached answer, send the
 * answer back along circ; otherwise, send the answer back along
654
 * <b>conn</b>'s attached circuit.
655
656
 */
static void
657
send_resolved_hostname_cell(edge_connection_t *conn, const char *hostname)
658
659
660
661
662
{
  char buf[RELAY_PAYLOAD_SIZE];
  size_t buflen;
  uint32_t ttl;
  size_t namelen = strlen(hostname);
663
  tor_assert(hostname);
664
665
666
667
668
669
670
671
672
673

  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;

674
  // log_notice(LD_EXIT, "Sending a reply RESOLVED reply: %s", hostname);
675
  connection_edge_send_command(conn, RELAY_COMMAND_RESOLVED, buf, buflen);
676
  // log_notice(LD_EXIT, "Sent");
677
678
}

Roger Dingledine's avatar
Roger Dingledine committed
679
/** See if we have a cache entry for <b>exitconn</b>-\>address. If so,
Nick Mathewson's avatar
Nick Mathewson committed
680
 * if resolve valid, put it into <b>exitconn</b>-\>addr and return 1.
Roger Dingledine's avatar
Roger Dingledine committed
681
 * If resolve failed, free exitconn and return -1.
682
 *
683
684
685
686
687
 * (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.)
 *
688
 * If we have a cached answer, send the answer back along <b>exitconn</b>'s
689
 * circuit.
690
 *
691
692
693
694
695
 * 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.
696
697
698
699
700
701
 *
 * 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.
702
 */
703
int
704
dns_resolve(edge_connection_t *exitconn)
705
706
707
{
  or_circuit_t *oncirc = TO_OR_CIRCUIT(exitconn->on_circuit);
  int is_resolve, r;
708
  int made_connection_pending = 0;
709
  char *hostname = NULL;
710
  is_resolve = exitconn->base_.purpose == EXIT_PURPOSE_RESOLVE;
711

712
713
  r = dns_resolve_impl(exitconn, is_resolve, oncirc, &hostname,
                       &made_connection_pending);
714

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

749
      exitconn->on_circuit = NULL;
750

751
      dns_cancel_pending_resolve(exitconn->base_.address);
752

753
      if (!made_connection_pending && !exitconn->base_.marked_for_close) {
754
755
756
        /* 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. */
757
        connection_free(TO_CONN(exitconn));
758
      }
759
760
761
762
763
764
765
766
767
768
769
770
771
772
      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
773
774
775
 * 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.
776
777
778
779
 *
 * 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.
780
781
782
 */
static int
dns_resolve_impl(edge_connection_t *exitconn, int is_resolve,
783
784
                 or_circuit_t *oncirc, char **hostname_out,
                 int *made_connection_pending_out)
785
{
786
787
788
  cached_resolve_t *resolve;
  cached_resolve_t search;
  pending_connection_t *pending_connection;
789
  int is_reverse = 0;
790
  const routerinfo_t *me;
791
  tor_addr_t addr;
792
  time_t now = time(NULL);
793
  int r;
794
  assert_connection_ok(TO_CONN(exitconn), 0);
795
  tor_assert(!SOCKET_OK(exitconn->base_.s));
796
  assert_cache_ok();
797
  tor_assert(oncirc);
798
  *made_connection_pending_out = 0;
799

800
  /* first check if exitconn->base_.address is an IP. If so, we already
801
   * know the answer. */
802
  if (tor_addr_parse(&addr, exitconn->base_.address) >= 0) {
803
804
    if (tor_addr_family(&addr) == AF_INET ||
        tor_addr_family(&addr) == AF_INET6) {
805
      tor_addr_copy(&exitconn->base_.addr, &addr);
806
807
808
      exitconn->address_ttl = DEFAULT_DNS_TTL;
      return 1;
    } else {
809
      /* XXXX unspec? Bogus? */
810
811
      return -1;
    }
812
  }
813

814
815
816
817
818
  /* 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;
  }
819
  if (address_is_invalid_destination(exitconn->base_.address, 0)) {
820
821
    log(LOG_PROTOCOL_WARN, LD_EXIT,
        "Rejecting invalid destination address %s",
822
        escaped_safe_str(exitconn->base_.address));
823
824
    return -1;
  }
825
826

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

830
831
  /* lower-case exitconn->base_.address, so it's in canonical form */
  tor_strlower(exitconn->base_.address);
832

833
834
  /* 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
835
   * connection.
836
   */
837
  if ((r = tor_addr_parse_PTR_name(&addr, exitconn->base_.address,
838
                                              AF_UNSPEC, 0)) != 0) {
839
    if (r == 1) {
840
      is_reverse = 1;
841
842
      if (tor_addr_is_internal(&addr, 0)) /* internal address? */
        return -1;
843
    }
844
845
846
847

    if (!is_reverse || !is_resolve) {
      if (!is_reverse)
        log_info(LD_EXIT, "Bad .in-addr.arpa address \"%s\"; sending error.",
848
                 escaped_safe_str(exitconn->base_.address));
849
850
851
852
      else if (!is_resolve)
        log_info(LD_EXIT,
                 "Attempt to connect to a .in-addr.arpa address \"%s\"; "
                 "sending error.",
853
                 escaped_safe_str(exitconn->base_.address));
854
855
856

      return -1;
    }
857
    //log_notice(LD_EXIT, "Looks like an address %s",
858
    //exitconn->base_.address);
859
  }
860
  exitconn->is_reverse_dns_lookup = is_reverse;
861

862
  /* now check the hash table to see if 'address' is already there. */
863
  strlcpy(search.address, exitconn->base_.address, sizeof(search.address));
864
  resolve = HT_FIND(cache_map, &cache_root, &search);
865
  if (resolve && resolve->expire > now) { /* already there */
866
    switch (resolve->state) {
867
868
      case CACHE_STATE_PENDING:
        /* add us to the pending list */
869
        pending_connection = tor_malloc_zero(
870
                                      sizeof(pending_connection_t));
871
        pending_connection->conn = exitconn;
Roger Dingledine's avatar
   
Roger Dingledine committed
872
873
        pending_connection->next = resolve->pending_connections;
        resolve->pending_connections = pending_connection;
874
        *made_connection_pending_out = 1;
875
        log_debug(LD_EXIT,"Connection (fd %d) waiting for pending DNS "
876
877
                  "resolve of %s", exitconn->base_.s,
                  escaped_safe_str(exitconn->base_.address));
Roger Dingledine's avatar
   
Roger Dingledine committed
878
        return 0;
879
880
      case CACHE_STATE_CACHED:
        log_debug(LD_EXIT,"Connection (fd %d) found cachedresult for %s",
881
                  exitconn->base_.s,
882
                  escaped_safe_str(resolve->address));
883
884
885

        return set_exitconn_info_from_resolve(exitconn, resolve, hostname_out);

886
887
888
      case CACHE_STATE_DONE:
        log_err(LD_BUG, "Found a 'DONE' dns resolve still in the cache.");
        tor_fragile_assert();
889
    }
Roger Dingledine's avatar
Roger Dingledine committed
890
    tor_assert(0);
Roger Dingledine's avatar
Roger Dingledine committed
891
  }
892
  tor_assert(!resolve);
Roger Dingledine's avatar
Roger Dingledine committed
893
  /* not there, need to add it */
894
  resolve = tor_malloc_zero(sizeof(cached_resolve_t));
895
  resolve->magic = CACHED_RESOLVE_MAGIC;
Roger Dingledine's avatar
Roger Dingledine committed
896
  resolve->state = CACHE_STATE_PENDING;
897
  resolve->minheap_idx = -1;
898
  strlcpy(resolve->address, exitconn->base_.address, sizeof(resolve->address));
Roger Dingledine's avatar
Roger Dingledine committed
899

900
  /* add this connection to the pending list */
901
  pending_connection = tor_malloc_zero(sizeof(pending_connection_t));
Roger Dingledine's avatar
Roger Dingledine committed
902
903
  pending_connection->conn = exitconn;
  resolve->pending_connections = pending_connection;
904
  *made_connection_pending_out = 1;
Roger Dingledine's avatar
Roger Dingledine committed
905

906
  /* Add this resolve to the cache and priority queue. */
907
  HT_INSERT(cache_map, &cache_root, resolve);
908
  set_expiry(resolve, now + RESOLVE_MAX_TIMEOUT);
909

910
  log_debug(LD_EXIT,"Launching %s.",
911
            escaped_safe_str(exitconn->base_.address));
912
  assert_cache_ok();
913

914
915
916
917
918
919
920
921
922
923
924