dirclient.c 116 KB
Newer Older
1
2
/* Copyright (c) 2001-2004, Roger Dingledine.
 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3
 * Copyright (c) 2007-2020, The Tor Project, Inc. */
Roger Dingledine's avatar
Roger Dingledine committed
4
/* See LICENSE for licensing information */
5

6
7
8
9
10
/**
 * @file dirclient.c
 * @brief Download directory information
 **/

11
#define DIRCLIENT_PRIVATE
12

13
#include "core/or/or.h"
14

15
16
#include "app/config/config.h"
#include "core/mainloop/connection.h"
17
#include "core/mainloop/mainloop.h"
18
#include "core/or/connection_edge.h"
19
20
21
#include "core/or/policies.h"
#include "feature/client/bridges.h"
#include "feature/client/entrynodes.h"
22
#include "feature/control/control_events.h"
23
#include "feature/dirauth/authmode.h"
24
#include "feature/dirclient/dirclient.h"
25
26
#include "feature/dirauth/dirvote.h"
#include "feature/dirauth/shared_random.h"
27
#include "feature/dircache/dirserv.h"
28
#include "feature/dirclient/dirclient.h"
29
#include "feature/dirclient/dirclient_modes.h"
30
31
32
#include "feature/dirclient/dlstatus.h"
#include "feature/dircommon/consdiff.h"
#include "feature/dircommon/directory.h"
33
34
35
#include "feature/dircommon/fp_pair.h"
#include "feature/hs/hs_cache.h"
#include "feature/hs/hs_client.h"
36
37
#include "feature/hs/hs_control.h"
#include "feature/nodelist/authcert.h"
38
#include "feature/nodelist/describe.h"
39
#include "feature/nodelist/dirlist.h"
40
41
#include "feature/nodelist/microdesc.h"
#include "feature/nodelist/networkstatus.h"
42
#include "feature/nodelist/node_select.h"
43
#include "feature/nodelist/nodelist.h"
44
#include "feature/nodelist/routerinfo.h"
45
46
#include "feature/nodelist/routerlist.h"
#include "feature/nodelist/routerset.h"
47
#include "feature/relay/relay_find_addr.h"
48
#include "feature/relay/routermode.h"
49
#include "feature/relay/selftest.h"
50
#include "feature/rend/rendcache.h"
51
52
53
#include "feature/rend/rendclient.h"
#include "feature/rend/rendcommon.h"
#include "feature/rend/rendservice.h"
54
#include "feature/stats/predict_ports.h"
55

56
#include "lib/cc/ctassert.h"
57
#include "lib/compress/compress.h"
58
#include "lib/crypt_ops/crypto_format.h"
59
60
61
#include "lib/crypt_ops/crypto_util.h"
#include "lib/encoding/confline.h"
#include "lib/err/backtrace.h"
Sebastian Hahn's avatar
Sebastian Hahn committed
62

63
#include "core/or/entry_connection_st.h"
64
65
#include "feature/dircache/cached_dir_st.h"
#include "feature/dirclient/dir_server_st.h"
66
#include "feature/dircommon/dir_connection_st.h"
67
68
69
#include "feature/nodelist/networkstatus_st.h"
#include "feature/nodelist/node_st.h"
#include "feature/nodelist/routerinfo_st.h"
70
#include "feature/rend/rend_service_descriptor_st.h"
71

72
73
74
75
76
77
/** Maximum size, in bytes, for any directory object that we've downloaded. */
#define MAX_DIR_DL_SIZE ((1<<24)-1) /* 16 MB - 1 */

/** How far in the future do we allow a directory server to tell us it is
 * before deciding that one of us has the wrong time? */
#define ALLOW_DIRECTORY_TIME_SKEW (30*60)
78

79
static int body_is_plausible(const char *body, size_t body_len, int purpose);
80
static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
81
static void connection_dir_bridge_routerdesc_failed(dir_connection_t *conn);
82
83
static void connection_dir_download_cert_failed(
                               dir_connection_t *conn, int status_code);
84
static void connection_dir_retry_bridges(smartlist_t *descs);
85
static void dir_routerdesc_download_failed(smartlist_t *failed,
86
                                           int status_code,
87
                                           int router_purpose,
88
89
                                           int was_extrainfo,
                                           int was_descriptor_digests);
90
static void dir_microdesc_download_failed(smartlist_t *failed,
91
92
                                          int status_code,
                                          const char *dir_id);
93
94
95
static void directory_send_command(dir_connection_t *conn,
                                   const int direct,
                                   const directory_request_t *req);
96
97
98
static void connection_dir_close_consensus_fetches(
                   dir_connection_t *except_this_one, const char *resource);

99
/** Return a string describing a given directory connection purpose. */
100
STATIC const char *
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
dir_conn_purpose_to_string(int purpose)
{
  switch (purpose)
    {
    case DIR_PURPOSE_UPLOAD_DIR:
      return "server descriptor upload";
    case DIR_PURPOSE_UPLOAD_VOTE:
      return "server vote upload";
    case DIR_PURPOSE_UPLOAD_SIGNATURES:
      return "consensus signature upload";
    case DIR_PURPOSE_FETCH_SERVERDESC:
      return "server descriptor fetch";
    case DIR_PURPOSE_FETCH_EXTRAINFO:
      return "extra-info fetch";
    case DIR_PURPOSE_FETCH_CONSENSUS:
      return "consensus network-status fetch";
    case DIR_PURPOSE_FETCH_CERTIFICATE:
      return "authority cert fetch";
    case DIR_PURPOSE_FETCH_STATUS_VOTE:
      return "status vote fetch";
    case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
      return "consensus signature fetch";
123
124
125
126
    case DIR_PURPOSE_FETCH_RENDDESC_V2:
      return "hidden-service v2 descriptor fetch";
    case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
      return "hidden-service v2 descriptor upload";
127
128
129
130
    case DIR_PURPOSE_FETCH_HSDESC:
      return "hidden-service descriptor fetch";
    case DIR_PURPOSE_UPLOAD_HSDESC:
      return "hidden-service descriptor upload";
131
132
    case DIR_PURPOSE_FETCH_MICRODESC:
      return "microdescriptor fetch";
133
134
135
136
137
138
    }

  log_warn(LD_BUG, "Called with unknown purpose %d", purpose);
  return "(unknown)";
}

139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
/** Return the requisite directory information types. */
STATIC dirinfo_type_t
dir_fetch_type(int dir_purpose, int router_purpose, const char *resource)
{
  dirinfo_type_t type;
  switch (dir_purpose) {
    case DIR_PURPOSE_FETCH_EXTRAINFO:
      type = EXTRAINFO_DIRINFO;
      if (router_purpose == ROUTER_PURPOSE_BRIDGE)
        type |= BRIDGE_DIRINFO;
      else
        type |= V3_DIRINFO;
      break;
    case DIR_PURPOSE_FETCH_SERVERDESC:
      if (router_purpose == ROUTER_PURPOSE_BRIDGE)
        type = BRIDGE_DIRINFO;
      else
        type = V3_DIRINFO;
      break;
    case DIR_PURPOSE_FETCH_STATUS_VOTE:
    case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
    case DIR_PURPOSE_FETCH_CERTIFICATE:
      type = V3_DIRINFO;
      break;
    case DIR_PURPOSE_FETCH_CONSENSUS:
      type = V3_DIRINFO;
      if (resource && !strcmp(resource, "microdesc"))
        type |= MICRODESC_DIRINFO;
      break;
    case DIR_PURPOSE_FETCH_MICRODESC:
      type = MICRODESC_DIRINFO;
      break;
    default:
      log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose);
      type = NO_DIRINFO;
      break;
  }
  return type;
}

179
180
181
/** Return true iff <b>identity_digest</b> is the digest of a router which
 * says that it caches extrainfos.  (If <b>is_authority</b> we always
 * believe that to be true.) */
182
183
184
int
router_supports_extrainfo(const char *identity_digest, int is_authority)
{
185
  const node_t *node = node_get_by_id(identity_digest);
186

Nick Mathewson's avatar
Nick Mathewson committed
187
  if (node && node->ri) {
188
    if (node->ri->caches_extra_info)
189
190
191
      return 1;
  }
  if (is_authority) {
192
    return 1;
193
194
195
196
  }
  return 0;
}

197
198
199
200
201
202
203
204
/** Return true iff any trusted directory authority has accepted our
 * server descriptor.
 *
 * We consider any authority sufficient because waiting for all of
 * them means it never happens while any authority is down; we don't
 * go for something more complex in the middle (like \>1/3 or \>1/2 or
 * \>=1/2) because that doesn't seem necessary yet.
 */
205
206
207
int
directories_have_accepted_server_descriptor(void)
{
208
  const smartlist_t *servers = router_get_trusted_dir_servers();
209
  const or_options_t *options = get_options();
210
  SMARTLIST_FOREACH(servers, dir_server_t *, d, {
211
    if ((d->type & options->PublishServerDescriptor_) &&
212
213
        d->has_accepted_serverdesc) {
      return 1;
214
215
    }
  });
216
  return 0;
217
218
}

219
/** Start a connection to every suitable directory authority, using
220
221
 * connection purpose <b>dir_purpose</b> and uploading <b>payload</b>
 * (of length <b>payload_len</b>). The dir_purpose should be one of
222
 * 'DIR_PURPOSE_UPLOAD_{DIR|VOTE|SIGNATURES}'.
223
 *
224
225
226
 * <b>router_purpose</b> describes the type of descriptor we're
 * publishing, if we're publishing a descriptor -- e.g. general or bridge.
 *
227
 * <b>type</b> specifies what sort of dir authorities (V3,
228
 * BRIDGE, etc) we should upload to.
229
 *
230
231
232
233
234
 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
 * bytes of <b>payload</b> hold an extra-info document.  Upload the descriptor
 * to all authorities, and the extra-info document to all authorities that
 * support it.
Roger Dingledine's avatar
Roger Dingledine committed
235
236
 */
void
237
directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
238
                             dirinfo_type_t type,
239
                             const char *payload,
240
                             size_t payload_len, size_t extrainfo_len)
Roger Dingledine's avatar
Roger Dingledine committed
241
{
242
  const or_options_t *options = get_options();
243
  dir_indirection_t indirection;
244
  const smartlist_t *dirservers = router_get_trusted_dir_servers();
245
  int found = 0;
246
247
  const int exclude_self = (dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
                            dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES);
248
  tor_assert(dirservers);
Nick Mathewson's avatar
Nick Mathewson committed
249
250
251
  /* This tries dirservers which we believe to be down, but ultimately, that's
   * harmless, and we may as well err on the side of getting things uploaded.
   */
252
  SMARTLIST_FOREACH_BEGIN(dirservers, dir_server_t *, ds) {
253
      routerstatus_t *rs = &(ds->fake_status);
254
      size_t upload_len = payload_len;
255
256

      if ((type & ds->type) == 0)
257
        continue;
258

259
260
261
262
      if (exclude_self && router_digest_is_me(ds->digest)) {
        /* we don't upload to ourselves, but at least there's now at least
         * one authority of this type that has what we wanted to upload. */
        found = 1;
263
        continue;
264
      }
265

266
      if (options->StrictNodes &&
267
          routerset_contains_routerstatus(options->ExcludeNodes, rs, -1)) {
268
269
270
271
272
273
274
275
        log_warn(LD_DIR, "Wanted to contact authority '%s' for %s, but "
                 "it's in our ExcludedNodes list and StrictNodes is set. "
                 "Skipping.",
                 ds->nickname,
                 dir_conn_purpose_to_string(dir_purpose));
        continue;
      }

276
      found = 1; /* at least one authority of this type was listed */
277
      if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR)
278
        ds->has_accepted_serverdesc = 0;
279

280
      if (extrainfo_len && router_supports_extrainfo(ds->digest, 1)) {
281
        upload_len += extrainfo_len;
282
        log_info(LD_DIR, "Uploading an extrainfo too (length %d)",
283
                 (int) extrainfo_len);
284
      }
285
      if (purpose_needs_anonymity(dir_purpose, router_purpose, NULL)) {
286
        indirection = DIRIND_ANONYMOUS;
287
      } else if (!reachable_addr_allows_dir_server(ds,
288
289
                                                     FIREWALL_DIR_CONNECTION,
                                                     0)) {
290
        if (reachable_addr_allows_dir_server(ds, FIREWALL_OR_CONNECTION, 0))
291
292
293
294
295
296
          indirection = DIRIND_ONEHOP;
        else
          indirection = DIRIND_ANONYMOUS;
      } else {
        indirection = DIRIND_DIRECT_CONN;
      }
297
298
299
300
301
302
303
304

      directory_request_t *req = directory_request_new(dir_purpose);
      directory_request_set_routerstatus(req, rs);
      directory_request_set_router_purpose(req, router_purpose);
      directory_request_set_indirection(req, indirection);
      directory_request_set_payload(req, payload, upload_len);
      directory_initiate_request(req);
      directory_request_free(req);
305
  } SMARTLIST_FOREACH_END(ds);
306
  if (!found) {
307
    char *s = authdir_type_to_string(type);
308
    log_warn(LD_DIR, "Publishing server descriptor to directory authorities "
309
310
             "of type '%s', but no authorities of that type listed!", s);
    tor_free(s);
311
  }
Roger Dingledine's avatar
Roger Dingledine committed
312
313
}

314
315
/** Return true iff, according to the values in <b>options</b>, we should be
 * using directory guards for direct downloads of directory information. */
316
STATIC int
317
318
319
320
321
should_use_directory_guards(const or_options_t *options)
{
  /* Public (non-bridge) servers never use directory guards. */
  if (public_server_mode(options))
    return 0;
Nick Mathewson's avatar
Nick Mathewson committed
322
  /* If guards are disabled, we can't use directory guards.
323
   */
Nick Mathewson's avatar
Nick Mathewson committed
324
  if (!options->UseEntryGuards)
325
326
327
328
    return 0;
  /* If we're configured to fetch directory info aggressively or of a
   * nonstandard type, don't use directory guards. */
  if (options->DownloadExtraInfo || options->FetchDirInfoEarly ||
329
      options->FetchDirInfoExtraEarly || options->FetchUselessDescriptors)
330
331
332
333
    return 0;
  return 1;
}

Roger Dingledine's avatar
Roger Dingledine committed
334
/** Pick an unconstrained directory server from among our guards, the latest
335
336
 * networkstatus, or the fallback dirservers, for use in downloading
 * information of type <b>type</b>, and return its routerstatus. */
337
338
static const routerstatus_t *
directory_pick_generic_dirserver(dirinfo_type_t type, int pds_flags,
339
340
                                 uint8_t dir_purpose,
                                 circuit_guard_state_t **guard_state_out)
341
{
342
  const routerstatus_t *rs = NULL;
343
  const or_options_t *options = get_options();
344

345
346
347
348
  if (options->UseBridges)
    log_warn(LD_BUG, "Called when we have UseBridges set.");

  if (should_use_directory_guards(options)) {
349
    const node_t *node = guards_choose_dirguard(dir_purpose, guard_state_out);
350
351
352
353
354
355
    if (node)
      rs = node->rs;
  } else {
    /* anybody with a non-zero dirport will do */
    rs = router_pick_directory_server(type, pds_flags);
  }
356
357
358
359
360
361
362
363
364
  if (!rs) {
    log_info(LD_DIR, "No router found for %s; falling back to "
             "dirserver list.", dir_conn_purpose_to_string(dir_purpose));
    rs = router_pick_fallback_dirserver(type, pds_flags);
  }

  return rs;
}

365
366
367
/**
 * Set the extra fields in <b>req</b> that are used when requesting a
 * consensus of type <b>resource</b>.
368
369
 *
 * Right now, these fields are if-modified-since and x-or-diff-from-consensus.
Roger Dingledine's avatar
Roger Dingledine committed
370
 */
371
372
373
static void
dir_consensus_request_set_additional_headers(directory_request_t *req,
                                             const char *resource)
Roger Dingledine's avatar
Roger Dingledine committed
374
{
375
  time_t if_modified_since = 0;
376
377
  uint8_t or_diff_from[DIGEST256_LEN];
  int or_diff_from_is_set = 0;
378

379
380
381
382
  /* DEFAULT_IF_MODIFIED_SINCE_DELAY is 1/20 of the default consensus
   * period of 1 hour.
   */
  const int DEFAULT_IF_MODIFIED_SINCE_DELAY = 180;
383
384
385
386
387
  const int32_t DEFAULT_TRY_DIFF_FOR_CONSENSUS_NEWER = 72;
  const int32_t MIN_TRY_DIFF_FOR_CONSENSUS_NEWER = 0;
  const int32_t MAX_TRY_DIFF_FOR_CONSENSUS_NEWER = 8192;
  const char TRY_DIFF_FOR_CONSENSUS_NEWER_NAME[] =
    "try-diff-for-consensus-newer-than";
388

389
390
391
392
  int flav = FLAV_NS;
  if (resource)
    flav = networkstatus_parse_flavor_name(resource);

393
394
395
396
397
398
399
  int32_t max_age_for_diff = 3600 *
    networkstatus_get_param(NULL,
                            TRY_DIFF_FOR_CONSENSUS_NEWER_NAME,
                            DEFAULT_TRY_DIFF_FOR_CONSENSUS_NEWER,
                            MIN_TRY_DIFF_FOR_CONSENSUS_NEWER,
                            MAX_TRY_DIFF_FOR_CONSENSUS_NEWER);

400
401
402
  if (flav != -1) {
    /* IF we have a parsed consensus of this type, we can do an
     * if-modified-time based on it. */
403
    networkstatus_t *v;
404
405
406
407
408
409
410
411
412
    v = networkstatus_get_latest_consensus_by_flavor(flav);
    if (v) {
      /* In networks with particularly short V3AuthVotingIntervals,
       * ask for the consensus if it's been modified since half the
       * V3AuthVotingInterval of the most recent consensus. */
      time_t ims_delay = DEFAULT_IF_MODIFIED_SINCE_DELAY;
      if (v->fresh_until > v->valid_after
          && ims_delay > (v->fresh_until - v->valid_after)/2) {
        ims_delay = (v->fresh_until - v->valid_after)/2;
413
      }
414
      if_modified_since = v->valid_after + ims_delay;
415
416
417
418
      if (v->valid_after >= approx_time() - max_age_for_diff) {
        memcpy(or_diff_from, v->digest_sha3_as_signed, DIGEST256_LEN);
        or_diff_from_is_set = 1;
      }
419
    }
420
421
422
423
424
425
  } else {
    /* Otherwise it might be a consensus we don't parse, but which we
     * do cache.  Look at the cached copy, perhaps. */
    cached_dir_t *cd = dirserv_get_consensus(resource);
    /* We have no method of determining the voting interval from an
     * unparsed consensus, so we use the default. */
426
    if (cd) {
427
      if_modified_since = cd->published + DEFAULT_IF_MODIFIED_SINCE_DELAY;
428
429
430
431
      if (cd->published >= approx_time() - max_age_for_diff) {
        memcpy(or_diff_from, cd->digest_sha3_as_signed, DIGEST256_LEN);
        or_diff_from_is_set = 1;
      }
432
    }
433
  }
434

435
436
437
438
439
440
441
442
  if (if_modified_since > 0)
    directory_request_set_if_modified_since(req, if_modified_since);
  if (or_diff_from_is_set) {
    char hex[HEX_DIGEST256_LEN + 1];
    base16_encode(hex, sizeof(hex),
                  (const char*)or_diff_from, sizeof(or_diff_from));
    directory_request_add_header(req, X_OR_DIFF_FROM_CONSENSUS_HEADER, hex);
  }
443
444
445
446
447
448
449
}
/** Start a connection to a random running directory server, using
 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
 * Use <b>pds_flags</b> as arguments to router_pick_directory_server()
 * or router_pick_trusteddirserver().
 */
450
451
MOCK_IMPL(void,
directory_get_from_dirserver,(
452
453
454
455
456
457
458
459
                            uint8_t dir_purpose,
                            uint8_t router_purpose,
                            const char *resource,
                            int pds_flags,
                            download_want_authority_t want_authority))
{
  const routerstatus_t *rs = NULL;
  const or_options_t *options = get_options();
460
  int prefer_authority = (dirclient_fetches_from_authorities(options)
461
462
463
464
465
466
467
468
                          || want_authority == DL_WANT_AUTHORITY);
  int require_authority = 0;
  int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose,
                                            resource);
  dirinfo_type_t type = dir_fetch_type(dir_purpose, router_purpose, resource);

  if (type == NO_DIRINFO)
    return;
469

470
  if (!options->FetchServerDescriptors)
471
472
    return;

473
  circuit_guard_state_t *guard_state = NULL;
474
  if (!get_via_tor) {
teor's avatar
teor committed
475
    if (options->UseBridges && !(type & BRIDGE_DIRINFO)) {
476
477
      /* We want to ask a running bridge for which we have a descriptor.
       *
478
479
480
       * When we ask choose_random_entry() for a bridge, we specify what
       * sort of dir fetch we'll be doing, so it won't return a bridge
       * that can't answer our question.
481
       */
482
      const node_t *node = guards_choose_dirguard(dir_purpose, &guard_state);
483
484
485
      if (node && node->ri) {
        /* every bridge has a routerinfo. */
        routerinfo_t *ri = node->ri;
486
487
        /* clients always make OR connections to bridges */
        tor_addr_port_t or_ap;
488
        directory_request_t *req = directory_request_new(dir_purpose);
489
        /* we are willing to use a non-preferred address if we need to */
490
        reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0,
491
                                             &or_ap);
492
493
494
495
496
        directory_request_set_or_addr_port(req, &or_ap);
        directory_request_set_directory_id_digest(req,
                                            ri->cache_info.identity_digest);
        directory_request_set_router_purpose(req, router_purpose);
        directory_request_set_resource(req, resource);
497
498
        if (dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS)
          dir_consensus_request_set_additional_headers(req, resource);
499
500
501
        directory_request_set_guard_state(req, guard_state);
        directory_initiate_request(req);
        directory_request_free(req);
502
503
504
505
      } else {
        if (guard_state) {
          entry_guard_cancel(&guard_state);
        }
506
507
        log_notice(LD_DIR, "Ignoring directory request, since no bridge "
                           "nodes are available yet.");
508
509
      }

510
511
      return;
    } else {
teor's avatar
teor committed
512
      if (prefer_authority || (type & BRIDGE_DIRINFO)) {
513
        /* only ask authdirservers, and don't ask myself */
514
        rs = router_pick_trusteddirserver(type, pds_flags);
515
516
        if (rs == NULL && (pds_flags & (PDS_NO_EXISTING_SERVERDESC_FETCH|
                                        PDS_NO_EXISTING_MICRODESC_FETCH))) {
517
518
519
520
521
522
523
          /* We don't want to fetch from any authorities that we're currently
           * fetching server descriptors from, and we got no match.  Did we
           * get no match because all the authorities have connections
           * fetching server descriptors (in which case we should just
           * return,) or because all the authorities are down or on fire or
           * unreachable or something (in which case we should go on with
           * our fallback code)? */
524
525
          pds_flags &= ~(PDS_NO_EXISTING_SERVERDESC_FETCH|
                         PDS_NO_EXISTING_MICRODESC_FETCH);
526
527
528
529
530
531
532
          rs = router_pick_trusteddirserver(type, pds_flags);
          if (rs) {
            log_debug(LD_DIR, "Deferring serverdesc fetch: all authorities "
                      "are in use.");
            return;
          }
        }
533
534
535
536
537
        if (rs == NULL && require_authority) {
          log_info(LD_DIR, "No authorities were available for %s: will try "
                   "later.", dir_conn_purpose_to_string(dir_purpose));
          return;
        }
538
      }
teor's avatar
teor committed
539
      if (!rs && !(type & BRIDGE_DIRINFO)) {
540
        rs = directory_pick_generic_dirserver(type, pds_flags,
541
542
                                              dir_purpose,
                                              &guard_state);
543
        if (!rs)
544
          get_via_tor = 1; /* last resort: try routing it via Tor */
545
      }
546
    }
547
548
549
  }

  if (get_via_tor) {
550
    /* Never use fascistfirewall; we're going via Tor. */
Arlo Breault's avatar
Arlo Breault committed
551
552
    pds_flags |= PDS_IGNORE_FASCISTFIREWALL;
    rs = router_pick_directory_server(type, pds_flags);
553
554
  }

teor's avatar
teor committed
555
556
557
  /* If we have any hope of building an indirect conn, we know some router
   * descriptors.  If (rs==NULL), we can't build circuits anyway, so
   * there's no point in falling back to the authorities in this case. */
558
559
560
  if (rs) {
    const dir_indirection_t indirection =
      get_via_tor ? DIRIND_ANONYMOUS : DIRIND_ONEHOP;
561
562
563
564
565
    directory_request_t *req = directory_request_new(dir_purpose);
    directory_request_set_routerstatus(req, rs);
    directory_request_set_router_purpose(req, router_purpose);
    directory_request_set_indirection(req, indirection);
    directory_request_set_resource(req, resource);
566
567
    if (dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS)
      dir_consensus_request_set_additional_headers(req, resource);
568
569
570
571
    if (guard_state)
      directory_request_set_guard_state(req, guard_state);
    directory_initiate_request(req);
    directory_request_free(req);
572
  } else {
573
    log_notice(LD_DIR,
574
575
               "While fetching directory info, "
               "no running dirservers known. Will try again later. "
576
               "(purpose %d)", dir_purpose);
577
    if (!purpose_needs_anonymity(dir_purpose, router_purpose, resource)) {
578
      /* remember we tried them all and failed. */
579
      directory_all_unreachable(time(NULL));
580
    }
581
  }
Roger Dingledine's avatar
Roger Dingledine committed
582
583
}

584
585
586
587
588
589
590
591
592
593
594
/** As directory_get_from_dirserver, but initiates a request to <i>every</i>
 * directory authority other than ourself.  Only for use by authorities when
 * searching for missing information while voting. */
void
directory_get_from_all_authorities(uint8_t dir_purpose,
                                   uint8_t router_purpose,
                                   const char *resource)
{
  tor_assert(dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
             dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES);

595
  SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
596
                          dir_server_t *, ds) {
597
598
      if (router_digest_is_me(ds->digest))
        continue;
599
      if (!(ds->type & V3_DIRINFO))
600
        continue;
601
602
603
604
605
606
607
      const routerstatus_t *rs = &ds->fake_status;
      directory_request_t *req = directory_request_new(dir_purpose);
      directory_request_set_routerstatus(req, rs);
      directory_request_set_router_purpose(req, router_purpose);
      directory_request_set_resource(req, resource);
      directory_initiate_request(req);
      directory_request_free(req);
608
  } SMARTLIST_FOREACH_END(ds);
609
610
}

611
612
613
614
615
616
617
/** Return true iff <b>ind</b> requires a multihop circuit. */
static int
dirind_is_anon(dir_indirection_t ind)
{
  return ind == DIRIND_ANON_DIRPORT || ind == DIRIND_ANONYMOUS;
}

618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
/* Choose reachable OR and Dir addresses and ports from status, copying them
 * into use_or_ap and use_dir_ap. If indirection is anonymous, then we're
 * connecting via another relay, so choose the primary IPv4 address and ports.
 *
 * status should have at least one reachable address, if we can't choose a
 * reachable address, warn and return -1. Otherwise, return 0.
 */
static int
directory_choose_address_routerstatus(const routerstatus_t *status,
                                      dir_indirection_t indirection,
                                      tor_addr_port_t *use_or_ap,
                                      tor_addr_port_t *use_dir_ap)
{
  tor_assert(status != NULL);
  tor_assert(use_or_ap != NULL);
  tor_assert(use_dir_ap != NULL);

635
  const or_options_t *options = get_options();
636
637
638
639
640
641
642
643
644
  int have_or = 0, have_dir = 0;

  /* We expect status to have at least one reachable address if we're
   * connecting to it directly.
   *
   * Therefore, we can simply use the other address if the one we want isn't
   * allowed by the firewall.
   *
   * (When Tor uploads and downloads a hidden service descriptor, it uses
David Goulet's avatar
David Goulet committed
645
646
   * DIRIND_ANONYMOUS. Even Single Onion Servers (NYI) use DIRIND_ANONYMOUS,
   * to avoid HSDirs denying service by rejecting descriptors.)
647
648
649
650
651
652
653
654
   */

  /* Initialise the OR / Dir addresses */
  tor_addr_make_null(&use_or_ap->addr, AF_UNSPEC);
  use_or_ap->port = 0;
  tor_addr_make_null(&use_dir_ap->addr, AF_UNSPEC);
  use_dir_ap->port = 0;

655
656
  /* ORPort connections */
  if (indirection == DIRIND_ANONYMOUS) {
657
    if (!tor_addr_is_null(&status->ipv4_addr)) {
658
659
      /* Since we're going to build a 3-hop circuit and ask the 2nd relay
       * to extend to this address, always use the primary (IPv4) OR address */
660
661
      tor_addr_copy(&use_or_ap->addr, &status->ipv4_addr);
      use_or_ap->port = status->ipv4_orport;
662
663
664
      have_or = 1;
    }
  } else if (indirection == DIRIND_ONEHOP) {
665
666
667
668
    /* We use an IPv6 address if we have one and we prefer it.
     * Use the preferred address and port if they are reachable, otherwise,
     * use the alternate address and port (if any).
     */
669
    reachable_addr_choose_from_rs(status, FIREWALL_OR_CONNECTION, 0,
670
671
                                       use_or_ap);
    have_or = tor_addr_port_is_valid_ap(use_or_ap, 0);
672
673
  }

674
  /* DirPort connections
675
   * DIRIND_ONEHOP uses ORPort, but may fall back to the DirPort on relays */
676
677
  if (indirection == DIRIND_DIRECT_CONN ||
      indirection == DIRIND_ANON_DIRPORT ||
678
      (indirection == DIRIND_ONEHOP
679
       && !dirclient_must_use_begindir(options))) {
680
    reachable_addr_choose_from_rs(status, FIREWALL_DIR_CONNECTION, 0,
681
682
                                       use_dir_ap);
    have_dir = tor_addr_port_is_valid_ap(use_dir_ap, 0);
683
  }
684

685
686
  /* We rejected all addresses in the relay's status. This means we can't
   * connect to it. */
687
  if (!have_or && !have_dir) {
688
    static int logged_backtrace = 0;
689
    char *ipv6_str = tor_addr_to_str_dup(&status->ipv6_addr);
690
    log_info(LD_BUG, "Rejected all OR and Dir addresses from %s when "
691
692
             "launching an outgoing directory connection to: IPv4 %s OR %d "
             "Dir %d IPv6 %s OR %d Dir %d", routerstatus_describe(status),
693
             fmt_addr(&status->ipv4_addr), status->ipv4_orport,
694
695
696
             status->ipv4_dirport, ipv6_str, status->ipv6_orport,
             status->ipv4_dirport);
    tor_free(ipv6_str);
697
698
699
700
    if (!logged_backtrace) {
      log_backtrace(LOG_INFO, LD_BUG, "Addresses came from");
      logged_backtrace = 1;
    }
701
702
703
704
705
706
    return -1;
  }

  return 0;
}

707
708
709
/** Return true iff <b>conn</b> is the client side of a directory connection
 * we launched to ourself in order to determine the reachability of our
 * dir_port. */
710
711
712
713
714
static int
directory_conn_is_self_reachability_test(dir_connection_t *conn)
{
  if (conn->requested_resource &&
      !strcmpstart(conn->requested_resource,"authority")) {
715
    const routerinfo_t *me = router_get_my_routerinfo();
716
717
    if (me &&
        router_digest_is_me(conn->identity_digest) &&
718
719
        tor_addr_eq(&TO_CONN(conn)->addr, &me->ipv4_addr) &&
        me->ipv4_dirport == conn->base_.port)
720
721
722
723
724
      return 1;
  }
  return 0;
}

725
726
727
/** Called when we are unable to complete the client's request to a directory
 * server due to a network error: Mark the router as down and try again if
 * possible.
728
 */
729
730
void
connection_dir_client_request_failed(dir_connection_t *conn)
731
{
732
733
734
  if (conn->guard_state) {
    /* We haven't seen a success on this guard state, so consider it to have
     * failed. */
735
    entry_guard_failed(&conn->guard_state);
736
  }
737
  if (directory_conn_is_self_reachability_test(conn)) {
738
    return; /* this was a test fetch. don't retry. */
739
  }
740
  if (!entry_list_is_constrained(get_options()))
741
    router_set_status(conn->identity_digest, 0); /* don't try this one again */
742
  if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
743
             conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
744
    log_info(LD_DIR, "Giving up on serverdesc/extrainfo fetch from "
745
746
             "directory server at %s; retrying",
             connection_describe_peer(TO_CONN(conn)));
747
748
    if (conn->router_purpose == ROUTER_PURPOSE_BRIDGE)
      connection_dir_bridge_routerdesc_failed(conn);
749
    connection_dir_download_routerdesc_failed(conn);
750
  } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
751
752
    if (conn->requested_resource)
      networkstatus_consensus_download_failed(0, conn->requested_resource);
753
  } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
754
    log_info(LD_DIR, "Giving up on certificate fetch from directory server "
755
756
             "at %s; retrying",
             connection_describe_peer(TO_CONN(conn)));
757
    connection_dir_download_cert_failed(conn, 0);
758
  } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
759
760
    log_info(LD_DIR, "Giving up downloading detached signatures from %s",
             connection_describe_peer(TO_CONN(conn)));
761
  } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
762
763
    log_info(LD_DIR, "Giving up downloading votes from %s",
             connection_describe_peer(TO_CONN(conn)));
764
  } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC) {
765
    log_info(LD_DIR, "Giving up on downloading microdescriptors from "
766
767
             "directory server at %s; will retry",
             connection_describe_peer(TO_CONN(conn)));
768
    connection_dir_download_routerdesc_failed(conn);
769
770
771
  }
}

772
773
774
775
/** Helper: Attempt to fetch directly the descriptors of each bridge
 * listed in <b>failed</b>.
 */
static void
776
connection_dir_retry_bridges(smartlist_t *descs)
777
778
{
  char digest[DIGEST_LEN];
Robert Hogan's avatar
Robert Hogan committed
779
  SMARTLIST_FOREACH(descs, const char *, cp,
780
  {
781
    if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp)) != DIGEST_LEN) {
782
783
784
785
786
787
788
789
      log_warn(LD_BUG, "Malformed fingerprint in list: %s",
              escaped(cp));
      continue;
    }
    retry_bridge_descriptor_fetch_directly(digest);
  });
}

790
/** Called when an attempt to download one or more router descriptors
791
 * or extra-info documents on connection <b>conn</b> failed.
792
793
 */
static void
794
connection_dir_download_routerdesc_failed(dir_connection_t *conn)
795
{
796
  /* No need to increment the failure count for routerdescs, since
797
   * it's not their fault. */
798

799
  /* No need to relaunch descriptor downloads here: we already do it
800
   * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
801
802
803
  tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
             conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
             conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
804

805
  (void) conn;
806
807
}

808
809
810
811
812
813
814
815
816
817
818
/** Called when an attempt to download a bridge's routerdesc from
 * one of the authorities failed due to a network error. If
 * possible attempt to download descriptors from the bridge directly.
 */
static void
connection_dir_bridge_routerdesc_failed(dir_connection_t *conn)
{
  smartlist_t *which = NULL;

  /* Requests for bridge descriptors are in the form 'fp/', so ignore
     anything else. */
819
  if (!conn->requested_resource || strcmpstart(conn->requested_resource,"fp/"))
820
821
    return;

822
  which = smartlist_new();
Robert Hogan's avatar
Robert Hogan committed
823
824
825
  dir_split_resource_into_fingerprints(conn->requested_resource
                                        + strlen("fp/"),
                                       which, NULL, 0);
826

827
  tor_assert(conn->base_.purpose != DIR_PURPOSE_FETCH_EXTRAINFO);
828
  if (smartlist_len(which)) {
Robert Hogan's avatar
Robert Hogan committed
829
    connection_dir_retry_bridges(which);
830
831
832
833
834
    SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
  }
  smartlist_free(which);
}

835
836
837
838
/** Called when an attempt to fetch a certificate fails. */
static void
connection_dir_download_cert_failed(dir_connection_t *conn, int status)
{
839
840
  const char *fp_pfx = "fp/";
  const char *fpsk_pfx = "fp-sk/";
841
  smartlist_t *failed;
842
  tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
843
844
845

  if (!conn->requested_resource)
    return;
846
  failed = smartlist_new();
847
848
849
850
851
  /*
   * We have two cases download by fingerprint (resource starts
   * with "fp/") or download by fingerprint/signing key pair
   * (resource starts with "fp-sk/").
   */
852
  if (!strcmpstart(conn->requested_resource, fp_pfx)) {
853
    /* Download by fingerprint case */
854
855
    dir_split_resource_into_fingerprints(conn->requested_resource +
                                         strlen(fp_pfx),
856
857
858
859
860
861
                                         failed, NULL, DSR_HEX);
    SMARTLIST_FOREACH_BEGIN(failed, char *, cp) {
      /* Null signing key digest indicates download by fp only */
      authority_cert_dl_failed(cp, NULL, status);
      tor_free(cp);
    } SMARTLIST_FOREACH_END(cp);
862
  } else if (!strcmpstart(conn->requested_resource, fpsk_pfx)) {
863
    /* Download by (fp,sk) pairs */
864
865
    dir_split_resource_into_fingerprint_pairs(conn->requested_resource +
                                              strlen(fpsk_pfx), failed);
866
867
868
869
870
871
872
873
874
875
    SMARTLIST_FOREACH_BEGIN(failed, fp_pair_t *, cp) {
      authority_cert_dl_failed(cp->first, cp->second, status);
      tor_free(cp);
    } SMARTLIST_FOREACH_END(cp);
  } else {
    log_warn(LD_DIR,
             "Don't know what to do with failure for cert fetch %s",
             conn->requested_resource);
  }

876
  smartlist_free(failed);
877
878

  update_certificate_downloads(time(NULL));
879
880
}

Roger Dingledine's avatar
Roger Dingledine committed
881
882
/** Evaluate the situation and decide if we should use an encrypted
 * "begindir-style" connection for this directory request.
883
 * 0) If there is no DirPort, yes.
Roger Dingledine's avatar
Roger Dingledine committed
884
885
886
 * 1) If or_port is 0, or it's a direct conn and or_port is firewalled
 *    or we're a dir mirror, no.
 * 2) If we prefer to avoid begindir conns, and we're not fetching or
Roger Dingledine's avatar
Roger Dingledine committed
887
 *    publishing a bridge relay descriptor, no.
Roger Dingledine's avatar
Roger Dingledine committed
888
 * 3) Else yes.
889
890
 * If returning 0, return in *reason why we can't use begindir.
 * reason must not be NULL.
Roger Dingledine's avatar
Roger Dingledine committed
891
892
 */
static int
893
directory_command_should_use_begindir(const or_options_t *options,
894
                                      const directory_request_t *req,
895
                                      const char **reason)
Roger Dingledine's avatar
Roger Dingledine committed
896
{
897
898
899
900
901
902
903
  const tor_addr_t *or_addr = &req->or_addr_port.addr;
  //const tor_addr_t *dir_addr = &req->dir_addr_port.addr;
  const int or_port = req->or_addr_port.port;
  const int dir_port = req->dir_addr_port.port;

  const dir_indirection_t indirection = req->indirection;

904
905
906
  tor_assert(reason);
  *reason = NULL;

907
908
909
910
911
  /* Reasons why we must use begindir */
  if (!dir_port) {
    *reason = "(using begindir - directory with no DirPort)";
    return 1; /* We don't know a DirPort -- must begindir. */
  }
912
913
914
  /* Reasons why we can't possibly use begindir */
  if (!or_port) {
    *reason = "directory with unknown ORPort";
Roger Dingledine's avatar
Roger Dingledine committed
915
    return 0; /* We don't know an ORPort -- no chance. */
916
917
918
919
  }
  if (indirection == DIRIND_DIRECT_CONN ||
      indirection == DIRIND_ANON_DIRPORT) {
    *reason = "DirPort connection";
920
    return 0;
921
922
923
  }
  if (indirection == DIRIND_ONEHOP) {
    /* We're firewalled and want a direct OR connection */
924
    if (!reachable_addr_allows_addr(or_addr, or_port,
925
926
927
928
929
930
931
                                              FIREWALL_OR_CONNECTION, 0, 0)) {
      *reason = "ORPort not reachable";
      return 0;
    }
  }
  /* Reasons why we want to avoid using begindir */
  if (indirection == DIRIND_ONEHOP) {
932
    if (!dirclient_must_use_begindir(options)) {
933
934
935
936
937
938
939
      *reason = "in relay mode";
      return 0;
    }
  }
  /* DIRIND_ONEHOP on a client, or DIRIND_ANONYMOUS
   */
  *reason = "(using begindir)";
Roger Dingledine's avatar
Roger Dingledine committed
940
941
942
  return 1;
}

943
944
945
946
/**
 * Create and return a new directory_request_t with purpose
 * <b>dir_purpose</b>.
 */
947
948
949
950
951
952
953
directory_request_t *
directory_request_new(uint8_t dir_purpose)
{
  tor_assert(dir_purpose >= DIR_PURPOSE_MIN_);
  tor_assert(dir_purpose <= DIR_PURPOSE_MAX_);
  tor_assert(dir_purpose != DIR_PURPOSE_SERVER);
  tor_assert(dir_purpose != DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2);
954
  tor_assert(dir_purpose != DIR_PURPOSE_HAS_FETCHED_HSDESC);
955
956

  directory_request_t *result = tor_malloc_zero(sizeof(*result));
957
958
959
960
  tor_addr_make_null(&result->or_addr_port.addr, AF_INET);
  result->or_addr_port.port = 0;
  tor_addr_make_null(&result->dir_addr_port.addr, AF_INET);
  result->dir_addr_port.port = 0;
961
962
963
964
965
  result->dir_purpose = dir_purpose;
  result->router_purpose = ROUTER_PURPOSE_GENERAL;
  result->indirection = DIRIND_ONEHOP;
  return result;
}
966
967
968
/**
 * Release all resources held by <b>req</b>.
 */
969
void
970
directory_request_free_(directory_request_t *req)
971
972
973
{
  if (req == NULL)
    return;
974
  config_free_lines(req->additional_headers);
975
976
  tor_free(req);
}
977
978
979
/**
 * Set the address and OR port to use for this directory request.  If there is
 * no OR port, we'll have to connect over the dirport.  (If there are both,
980
 * the indirection setting determines which to use.)
981
 */
982
983
984
985
986
987
void
directory_request_set_or_addr_port(directory_request_t *req,
                                   const tor_addr_port_t *p)
{
  memcpy(&req->or_addr_port, p, sizeof(*p));
}
988
989
990
/**
 * Set the address and dirport to use for this directory request.  If there
 * is no dirport, we'll have to connect over the OR port.  (If there are both,
991
 * the indirection setting determines which to use.)
992
 */
993
994
995
996
997
998
void
directory_request_set_dir_addr_port(directory_request_t *req,
                                    const tor_addr_port_t *p)
{
  memcpy(&req->dir_addr_port, p, sizeof(*p));
}
999
1000
/**
 * Set the RSA identity digest of the directory to use for this directory
For faster browsing, not all history is shown. View entire blame