Line data Source code
1 : /* Copyright (c) 2001-2004, Roger Dingledine.
2 : * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 : * Copyright (c) 2007-2021, The Tor Project, Inc. */
4 : /* See LICENSE for licensing information */
5 :
6 : /**
7 : * @file dirclient.c
8 : * @brief Download directory information
9 : **/
10 :
11 : #define DIRCLIENT_PRIVATE
12 :
13 : #include "core/or/or.h"
14 :
15 : #include "app/config/config.h"
16 : #include "core/mainloop/connection.h"
17 : #include "core/mainloop/mainloop.h"
18 : #include "core/or/connection_edge.h"
19 : #include "core/or/policies.h"
20 : #include "feature/client/bridges.h"
21 : #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 : #include "feature/dirauth/dirvote.h"
26 : #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 : #include "feature/dirclient/dlstatus.h"
31 : #include "feature/dircommon/consdiff.h"
32 : #include "feature/dircommon/directory.h"
33 : #include "feature/dircommon/fp_pair.h"
34 : #include "feature/hs/hs_cache.h"
35 : #include "feature/hs/hs_client.h"
36 : #include "feature/hs/hs_control.h"
37 : #include "feature/nodelist/authcert.h"
38 : #include "feature/nodelist/describe.h"
39 : #include "feature/nodelist/dirlist.h"
40 : #include "feature/nodelist/microdesc.h"
41 : #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 : #include "feature/nodelist/routerlist.h"
46 : #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/rendcommon.h"
51 : #include "feature/stats/predict_ports.h"
52 :
53 : #include "lib/cc/ctassert.h"
54 : #include "lib/compress/compress.h"
55 : #include "lib/crypt_ops/crypto_format.h"
56 : #include "lib/crypt_ops/crypto_util.h"
57 : #include "lib/encoding/confline.h"
58 : #include "lib/err/backtrace.h"
59 :
60 : #include "core/or/entry_connection_st.h"
61 : #include "feature/dircache/cached_dir_st.h"
62 : #include "feature/dirclient/dir_server_st.h"
63 : #include "feature/dircommon/dir_connection_st.h"
64 : #include "feature/nodelist/networkstatus_st.h"
65 : #include "feature/nodelist/node_st.h"
66 : #include "feature/nodelist/routerinfo_st.h"
67 :
68 : /** Maximum size, in bytes, for any directory object that we've downloaded. */
69 : #define MAX_DIR_DL_SIZE ((1<<24)-1) /* 16 MB - 1 */
70 :
71 : /** How far in the future do we allow a directory server to tell us it is
72 : * before deciding that one of us has the wrong time? */
73 : #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
74 :
75 : static int body_is_plausible(const char *body, size_t body_len, int purpose);
76 : static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
77 : static void connection_dir_bridge_routerdesc_failed(dir_connection_t *conn);
78 : static void connection_dir_download_cert_failed(
79 : dir_connection_t *conn, int status_code);
80 : static void connection_dir_retry_bridges(smartlist_t *descs);
81 : static void dir_routerdesc_download_failed(smartlist_t *failed,
82 : int status_code,
83 : int router_purpose,
84 : int was_extrainfo,
85 : int was_descriptor_digests);
86 : static void dir_microdesc_download_failed(smartlist_t *failed,
87 : int status_code,
88 : const char *dir_id);
89 : static void directory_send_command(dir_connection_t *conn,
90 : const int direct,
91 : const directory_request_t *req);
92 : static void connection_dir_close_consensus_fetches(
93 : dir_connection_t *except_this_one, const char *resource);
94 :
95 : /** Return a string describing a given directory connection purpose. */
96 : STATIC const char *
97 11 : dir_conn_purpose_to_string(int purpose)
98 : {
99 11 : switch (purpose)
100 : {
101 : case DIR_PURPOSE_UPLOAD_DIR:
102 : return "server descriptor upload";
103 1 : case DIR_PURPOSE_UPLOAD_VOTE:
104 1 : return "server vote upload";
105 1 : case DIR_PURPOSE_UPLOAD_SIGNATURES:
106 1 : return "consensus signature upload";
107 1 : case DIR_PURPOSE_FETCH_SERVERDESC:
108 1 : return "server descriptor fetch";
109 1 : case DIR_PURPOSE_FETCH_EXTRAINFO:
110 1 : return "extra-info fetch";
111 1 : case DIR_PURPOSE_FETCH_CONSENSUS:
112 1 : return "consensus network-status fetch";
113 1 : case DIR_PURPOSE_FETCH_CERTIFICATE:
114 1 : return "authority cert fetch";
115 1 : case DIR_PURPOSE_FETCH_STATUS_VOTE:
116 1 : return "status vote fetch";
117 1 : case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
118 1 : return "consensus signature fetch";
119 0 : case DIR_PURPOSE_FETCH_HSDESC:
120 0 : return "hidden-service descriptor fetch";
121 0 : case DIR_PURPOSE_UPLOAD_HSDESC:
122 0 : return "hidden-service descriptor upload";
123 1 : case DIR_PURPOSE_FETCH_MICRODESC:
124 1 : return "microdescriptor fetch";
125 : }
126 :
127 1 : log_warn(LD_BUG, "Called with unknown purpose %d", purpose);
128 1 : return "(unknown)";
129 : }
130 :
131 : /** Return the requisite directory information types. */
132 : STATIC dirinfo_type_t
133 14 : dir_fetch_type(int dir_purpose, int router_purpose, const char *resource)
134 : {
135 14 : dirinfo_type_t type;
136 14 : switch (dir_purpose) {
137 2 : case DIR_PURPOSE_FETCH_EXTRAINFO:
138 2 : type = EXTRAINFO_DIRINFO;
139 2 : if (router_purpose == ROUTER_PURPOSE_BRIDGE)
140 : type |= BRIDGE_DIRINFO;
141 : else
142 1 : type |= V3_DIRINFO;
143 : break;
144 2 : case DIR_PURPOSE_FETCH_SERVERDESC:
145 2 : if (router_purpose == ROUTER_PURPOSE_BRIDGE)
146 : type = BRIDGE_DIRINFO;
147 : else
148 1 : type = V3_DIRINFO;
149 : break;
150 : case DIR_PURPOSE_FETCH_STATUS_VOTE:
151 : case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
152 : case DIR_PURPOSE_FETCH_CERTIFICATE:
153 : type = V3_DIRINFO;
154 : break;
155 2 : case DIR_PURPOSE_FETCH_CONSENSUS:
156 2 : type = V3_DIRINFO;
157 2 : if (resource && !strcmp(resource, "microdesc"))
158 1 : type |= MICRODESC_DIRINFO;
159 : break;
160 5 : case DIR_PURPOSE_FETCH_MICRODESC:
161 5 : type = MICRODESC_DIRINFO;
162 5 : break;
163 0 : default:
164 0 : log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose);
165 0 : type = NO_DIRINFO;
166 0 : break;
167 : }
168 14 : return type;
169 : }
170 :
171 : /** Return true iff <b>identity_digest</b> is the digest of a router which
172 : * says that it caches extrainfos. (If <b>is_authority</b> we always
173 : * believe that to be true.) */
174 : int
175 0 : router_supports_extrainfo(const char *identity_digest, int is_authority)
176 : {
177 0 : const node_t *node = node_get_by_id(identity_digest);
178 :
179 0 : if (node && node->ri) {
180 0 : if (node->ri->caches_extra_info)
181 : return 1;
182 : }
183 0 : if (is_authority) {
184 0 : return 1;
185 : }
186 : return 0;
187 : }
188 :
189 : /** Return true iff any trusted directory authority has accepted our
190 : * server descriptor.
191 : *
192 : * We consider any authority sufficient because waiting for all of
193 : * them means it never happens while any authority is down; we don't
194 : * go for something more complex in the middle (like \>1/3 or \>1/2 or
195 : * \>=1/2) because that doesn't seem necessary yet.
196 : */
197 : int
198 0 : directories_have_accepted_server_descriptor(void)
199 : {
200 0 : const smartlist_t *servers = router_get_trusted_dir_servers();
201 0 : const or_options_t *options = get_options();
202 0 : SMARTLIST_FOREACH(servers, dir_server_t *, d, {
203 : if ((d->type & options->PublishServerDescriptor_) &&
204 : d->has_accepted_serverdesc) {
205 : return 1;
206 : }
207 : });
208 : return 0;
209 : }
210 :
211 : /** Start a connection to every suitable directory authority, using
212 : * connection purpose <b>dir_purpose</b> and uploading <b>payload</b>
213 : * (of length <b>payload_len</b>). The dir_purpose should be one of
214 : * 'DIR_PURPOSE_UPLOAD_{DIR|VOTE|SIGNATURES}'.
215 : *
216 : * <b>router_purpose</b> describes the type of descriptor we're
217 : * publishing, if we're publishing a descriptor -- e.g. general or bridge.
218 : *
219 : * <b>type</b> specifies what sort of dir authorities (V3,
220 : * BRIDGE, etc) we should upload to.
221 : *
222 : * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
223 : * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
224 : * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
225 : * to all authorities, and the extra-info document to all authorities that
226 : * support it.
227 : */
228 : void
229 0 : directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
230 : dirinfo_type_t type,
231 : const char *payload,
232 : size_t payload_len, size_t extrainfo_len)
233 : {
234 0 : const or_options_t *options = get_options();
235 0 : dir_indirection_t indirection;
236 0 : const smartlist_t *dirservers = router_get_trusted_dir_servers();
237 0 : int found = 0;
238 0 : const int exclude_self = (dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
239 : dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES);
240 0 : tor_assert(dirservers);
241 : /* This tries dirservers which we believe to be down, but ultimately, that's
242 : * harmless, and we may as well err on the side of getting things uploaded.
243 : */
244 0 : SMARTLIST_FOREACH_BEGIN(dirservers, dir_server_t *, ds) {
245 0 : routerstatus_t *rs = &(ds->fake_status);
246 0 : size_t upload_len = payload_len;
247 :
248 0 : if ((type & ds->type) == 0)
249 0 : continue;
250 :
251 0 : if (exclude_self && router_digest_is_me(ds->digest)) {
252 : /* we don't upload to ourselves, but at least there's now at least
253 : * one authority of this type that has what we wanted to upload. */
254 0 : found = 1;
255 0 : continue;
256 : }
257 :
258 0 : if (options->StrictNodes &&
259 0 : routerset_contains_routerstatus(options->ExcludeNodes, rs, -1)) {
260 0 : log_warn(LD_DIR, "Wanted to contact authority '%s' for %s, but "
261 : "it's in our ExcludedNodes list and StrictNodes is set. "
262 : "Skipping.",
263 : ds->nickname,
264 : dir_conn_purpose_to_string(dir_purpose));
265 0 : continue;
266 : }
267 :
268 0 : found = 1; /* at least one authority of this type was listed */
269 0 : if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR)
270 0 : ds->has_accepted_serverdesc = 0;
271 :
272 0 : if (extrainfo_len && router_supports_extrainfo(ds->digest, 1)) {
273 0 : upload_len += extrainfo_len;
274 0 : log_info(LD_DIR, "Uploading an extrainfo too (length %d)",
275 : (int) extrainfo_len);
276 : }
277 0 : if (purpose_needs_anonymity(dir_purpose, router_purpose, NULL)) {
278 : indirection = DIRIND_ANONYMOUS;
279 0 : } else if (!reachable_addr_allows_dir_server(ds,
280 : FIREWALL_DIR_CONNECTION,
281 : 0)) {
282 0 : if (reachable_addr_allows_dir_server(ds, FIREWALL_OR_CONNECTION, 0))
283 : indirection = DIRIND_ONEHOP;
284 : else
285 0 : indirection = DIRIND_ANONYMOUS;
286 : } else {
287 : indirection = DIRIND_DIRECT_CONN;
288 : }
289 :
290 0 : directory_request_t *req = directory_request_new(dir_purpose);
291 0 : directory_request_set_routerstatus(req, rs);
292 0 : directory_request_set_router_purpose(req, router_purpose);
293 0 : directory_request_set_indirection(req, indirection);
294 0 : directory_request_set_payload(req, payload, upload_len);
295 0 : directory_initiate_request(req);
296 0 : directory_request_free(req);
297 0 : } SMARTLIST_FOREACH_END(ds);
298 0 : if (!found) {
299 0 : char *s = authdir_type_to_string(type);
300 0 : log_warn(LD_DIR, "Publishing server descriptor to directory authorities "
301 : "of type '%s', but no authorities of that type listed!", s);
302 0 : tor_free(s);
303 : }
304 0 : }
305 :
306 : /** Return true iff, according to the values in <b>options</b>, we should be
307 : * using directory guards for direct downloads of directory information. */
308 : STATIC int
309 11 : should_use_directory_guards(const or_options_t *options)
310 : {
311 : /* Public (non-bridge) servers never use directory guards. */
312 11 : if (public_server_mode(options))
313 : return 0;
314 : /* If guards are disabled, we can't use directory guards.
315 : */
316 10 : if (!options->UseEntryGuards)
317 : return 0;
318 : /* If we're configured to fetch directory info aggressively or of a
319 : * nonstandard type, don't use directory guards. */
320 9 : if (options->DownloadExtraInfo || options->FetchDirInfoEarly ||
321 7 : options->FetchDirInfoExtraEarly || options->FetchUselessDescriptors)
322 4 : return 0;
323 : return 1;
324 : }
325 :
326 : /** Pick an unconstrained directory server from among our guards, the latest
327 : * networkstatus, or the fallback dirservers, for use in downloading
328 : * information of type <b>type</b>, and return its routerstatus. */
329 : static const routerstatus_t *
330 4 : directory_pick_generic_dirserver(dirinfo_type_t type, int pds_flags,
331 : uint8_t dir_purpose,
332 : circuit_guard_state_t **guard_state_out)
333 : {
334 4 : const routerstatus_t *rs = NULL;
335 4 : const or_options_t *options = get_options();
336 :
337 4 : if (options->UseBridges)
338 0 : log_warn(LD_BUG, "Called when we have UseBridges set.");
339 :
340 4 : if (should_use_directory_guards(options)) {
341 4 : const node_t *node = guards_choose_dirguard(dir_purpose, guard_state_out);
342 4 : if (node)
343 4 : rs = node->rs;
344 : } else {
345 : /* anybody with a non-zero dirport will do */
346 0 : rs = router_pick_directory_server(type, pds_flags);
347 : }
348 4 : if (!rs) {
349 0 : log_info(LD_DIR, "No router found for %s; falling back to "
350 : "dirserver list.", dir_conn_purpose_to_string(dir_purpose));
351 0 : rs = router_pick_fallback_dirserver(type, pds_flags);
352 : }
353 :
354 4 : return rs;
355 : }
356 :
357 : /**
358 : * Set the extra fields in <b>req</b> that are used when requesting a
359 : * consensus of type <b>resource</b>.
360 : *
361 : * Right now, these fields are if-modified-since and x-or-diff-from-consensus.
362 : */
363 : static void
364 0 : dir_consensus_request_set_additional_headers(directory_request_t *req,
365 : const char *resource)
366 : {
367 0 : time_t if_modified_since = 0;
368 0 : uint8_t or_diff_from[DIGEST256_LEN];
369 0 : int or_diff_from_is_set = 0;
370 :
371 : /* DEFAULT_IF_MODIFIED_SINCE_DELAY is 1/20 of the default consensus
372 : * period of 1 hour.
373 : */
374 0 : const int DEFAULT_IF_MODIFIED_SINCE_DELAY = 180;
375 0 : const int32_t DEFAULT_TRY_DIFF_FOR_CONSENSUS_NEWER = 72;
376 0 : const int32_t MIN_TRY_DIFF_FOR_CONSENSUS_NEWER = 0;
377 0 : const int32_t MAX_TRY_DIFF_FOR_CONSENSUS_NEWER = 8192;
378 0 : const char TRY_DIFF_FOR_CONSENSUS_NEWER_NAME[] =
379 : "try-diff-for-consensus-newer-than";
380 :
381 0 : int flav = FLAV_NS;
382 0 : if (resource)
383 0 : flav = networkstatus_parse_flavor_name(resource);
384 :
385 0 : int32_t max_age_for_diff = 3600 *
386 0 : networkstatus_get_param(NULL,
387 : TRY_DIFF_FOR_CONSENSUS_NEWER_NAME,
388 : DEFAULT_TRY_DIFF_FOR_CONSENSUS_NEWER,
389 : MIN_TRY_DIFF_FOR_CONSENSUS_NEWER,
390 : MAX_TRY_DIFF_FOR_CONSENSUS_NEWER);
391 :
392 0 : if (flav != -1) {
393 : /* IF we have a parsed consensus of this type, we can do an
394 : * if-modified-time based on it. */
395 0 : networkstatus_t *v;
396 0 : v = networkstatus_get_latest_consensus_by_flavor(flav);
397 0 : if (v) {
398 : /* In networks with particularly short V3AuthVotingIntervals,
399 : * ask for the consensus if it's been modified since half the
400 : * V3AuthVotingInterval of the most recent consensus. */
401 0 : time_t ims_delay = DEFAULT_IF_MODIFIED_SINCE_DELAY;
402 0 : if (v->fresh_until > v->valid_after
403 0 : && ims_delay > (v->fresh_until - v->valid_after)/2) {
404 0 : ims_delay = (v->fresh_until - v->valid_after)/2;
405 : }
406 0 : if_modified_since = v->valid_after + ims_delay;
407 0 : if (v->valid_after >= approx_time() - max_age_for_diff) {
408 0 : memcpy(or_diff_from, v->digest_sha3_as_signed, DIGEST256_LEN);
409 0 : or_diff_from_is_set = 1;
410 : }
411 : }
412 : } else {
413 : /* Otherwise it might be a consensus we don't parse, but which we
414 : * do cache. Look at the cached copy, perhaps. */
415 0 : cached_dir_t *cd = dirserv_get_consensus(resource);
416 : /* We have no method of determining the voting interval from an
417 : * unparsed consensus, so we use the default. */
418 0 : if (cd) {
419 0 : if_modified_since = cd->published + DEFAULT_IF_MODIFIED_SINCE_DELAY;
420 0 : if (cd->published >= approx_time() - max_age_for_diff) {
421 0 : memcpy(or_diff_from, cd->digest_sha3_as_signed, DIGEST256_LEN);
422 0 : or_diff_from_is_set = 1;
423 : }
424 : }
425 : }
426 :
427 0 : if (if_modified_since > 0)
428 0 : directory_request_set_if_modified_since(req, if_modified_since);
429 0 : if (or_diff_from_is_set) {
430 0 : char hex[HEX_DIGEST256_LEN + 1];
431 0 : base16_encode(hex, sizeof(hex),
432 : (const char*)or_diff_from, sizeof(or_diff_from));
433 0 : directory_request_add_header(req, X_OR_DIFF_FROM_CONSENSUS_HEADER, hex);
434 : }
435 0 : }
436 : /** Start a connection to a random running directory server, using
437 : * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
438 : * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
439 : * Use <b>pds_flags</b> as arguments to router_pick_directory_server()
440 : * or router_pick_trusteddirserver().
441 : */
442 4 : MOCK_IMPL(void,
443 : directory_get_from_dirserver,(
444 : uint8_t dir_purpose,
445 : uint8_t router_purpose,
446 : const char *resource,
447 : int pds_flags,
448 : download_want_authority_t want_authority))
449 : {
450 4 : const routerstatus_t *rs = NULL;
451 4 : const or_options_t *options = get_options();
452 4 : int prefer_authority = (dirclient_fetches_from_authorities(options)
453 4 : || want_authority == DL_WANT_AUTHORITY);
454 4 : int require_authority = 0;
455 4 : int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose,
456 : resource);
457 4 : dirinfo_type_t type = dir_fetch_type(dir_purpose, router_purpose, resource);
458 :
459 4 : if (type == NO_DIRINFO)
460 0 : return;
461 :
462 4 : if (!options->FetchServerDescriptors)
463 : return;
464 :
465 4 : circuit_guard_state_t *guard_state = NULL;
466 4 : if (!get_via_tor) {
467 4 : if (options->UseBridges && !(type & BRIDGE_DIRINFO)) {
468 : /* We want to ask a running bridge for which we have a descriptor.
469 : *
470 : * When we ask choose_random_entry() for a bridge, we specify what
471 : * sort of dir fetch we'll be doing, so it won't return a bridge
472 : * that can't answer our question.
473 : */
474 0 : const node_t *node = guards_choose_dirguard(dir_purpose, &guard_state);
475 0 : if (node && node->ri) {
476 : /* every bridge has a routerinfo. */
477 0 : routerinfo_t *ri = node->ri;
478 : /* clients always make OR connections to bridges */
479 0 : tor_addr_port_t or_ap;
480 0 : directory_request_t *req = directory_request_new(dir_purpose);
481 : /* we are willing to use a non-preferred address if we need to */
482 0 : reachable_addr_choose_from_node(node, FIREWALL_OR_CONNECTION, 0,
483 : &or_ap);
484 0 : directory_request_set_or_addr_port(req, &or_ap);
485 0 : directory_request_set_directory_id_digest(req,
486 0 : ri->cache_info.identity_digest);
487 0 : directory_request_set_router_purpose(req, router_purpose);
488 0 : directory_request_set_resource(req, resource);
489 0 : if (dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS)
490 0 : dir_consensus_request_set_additional_headers(req, resource);
491 0 : directory_request_set_guard_state(req, guard_state);
492 0 : directory_initiate_request(req);
493 0 : directory_request_free(req);
494 : } else {
495 0 : if (guard_state) {
496 0 : entry_guard_cancel(&guard_state);
497 : }
498 0 : log_notice(LD_DIR, "Ignoring directory request, since no bridge "
499 : "nodes are available yet.");
500 : }
501 :
502 0 : return;
503 : } else {
504 4 : if (prefer_authority || (type & BRIDGE_DIRINFO)) {
505 : /* only ask authdirservers, and don't ask myself */
506 0 : rs = router_pick_trusteddirserver(type, pds_flags);
507 0 : if (rs == NULL && (pds_flags & (PDS_NO_EXISTING_SERVERDESC_FETCH|
508 : PDS_NO_EXISTING_MICRODESC_FETCH))) {
509 : /* We don't want to fetch from any authorities that we're currently
510 : * fetching server descriptors from, and we got no match. Did we
511 : * get no match because all the authorities have connections
512 : * fetching server descriptors (in which case we should just
513 : * return,) or because all the authorities are down or on fire or
514 : * unreachable or something (in which case we should go on with
515 : * our fallback code)? */
516 0 : pds_flags &= ~(PDS_NO_EXISTING_SERVERDESC_FETCH|
517 : PDS_NO_EXISTING_MICRODESC_FETCH);
518 0 : rs = router_pick_trusteddirserver(type, pds_flags);
519 0 : if (rs) {
520 0 : log_debug(LD_DIR, "Deferring serverdesc fetch: all authorities "
521 : "are in use.");
522 0 : return;
523 : }
524 : }
525 0 : if (rs == NULL && require_authority) {
526 : log_info(LD_DIR, "No authorities were available for %s: will try "
527 : "later.", dir_conn_purpose_to_string(dir_purpose));
528 : return;
529 : }
530 : }
531 4 : if (!rs && !(type & BRIDGE_DIRINFO)) {
532 4 : rs = directory_pick_generic_dirserver(type, pds_flags,
533 : dir_purpose,
534 : &guard_state);
535 4 : if (!rs)
536 0 : get_via_tor = 1; /* last resort: try routing it via Tor */
537 : }
538 : }
539 : }
540 :
541 4 : if (get_via_tor) {
542 : /* Never use fascistfirewall; we're going via Tor. */
543 0 : pds_flags |= PDS_IGNORE_FASCISTFIREWALL;
544 0 : rs = router_pick_directory_server(type, pds_flags);
545 : }
546 :
547 : /* If we have any hope of building an indirect conn, we know some router
548 : * descriptors. If (rs==NULL), we can't build circuits anyway, so
549 : * there's no point in falling back to the authorities in this case. */
550 4 : if (rs) {
551 4 : const dir_indirection_t indirection =
552 4 : get_via_tor ? DIRIND_ANONYMOUS : DIRIND_ONEHOP;
553 4 : directory_request_t *req = directory_request_new(dir_purpose);
554 4 : directory_request_set_routerstatus(req, rs);
555 4 : directory_request_set_router_purpose(req, router_purpose);
556 4 : directory_request_set_indirection(req, indirection);
557 4 : directory_request_set_resource(req, resource);
558 4 : if (dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS)
559 0 : dir_consensus_request_set_additional_headers(req, resource);
560 4 : if (guard_state)
561 3 : directory_request_set_guard_state(req, guard_state);
562 4 : directory_initiate_request(req);
563 4 : directory_request_free(req);
564 : } else {
565 0 : log_notice(LD_DIR,
566 : "While fetching directory info, "
567 : "no running dirservers known. Will try again later. "
568 : "(purpose %d)", dir_purpose);
569 0 : if (!purpose_needs_anonymity(dir_purpose, router_purpose, resource)) {
570 : /* remember we tried them all and failed. */
571 0 : directory_all_unreachable(time(NULL));
572 : }
573 : }
574 : }
575 :
576 : /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
577 : * directory authority other than ourself. Only for use by authorities when
578 : * searching for missing information while voting. */
579 : void
580 6 : directory_get_from_all_authorities(uint8_t dir_purpose,
581 : uint8_t router_purpose,
582 : const char *resource)
583 : {
584 6 : tor_assert(dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
585 : dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES);
586 :
587 12 : SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
588 : dir_server_t *, ds) {
589 6 : if (router_digest_is_me(ds->digest))
590 2 : continue;
591 4 : if (!(ds->type & V3_DIRINFO))
592 2 : continue;
593 2 : const routerstatus_t *rs = &ds->fake_status;
594 2 : directory_request_t *req = directory_request_new(dir_purpose);
595 2 : directory_request_set_routerstatus(req, rs);
596 2 : directory_request_set_router_purpose(req, router_purpose);
597 2 : directory_request_set_resource(req, resource);
598 2 : directory_initiate_request(req);
599 2 : directory_request_free(req);
600 6 : } SMARTLIST_FOREACH_END(ds);
601 6 : }
602 :
603 : /** Return true iff <b>ind</b> requires a multihop circuit. */
604 : static int
605 0 : dirind_is_anon(dir_indirection_t ind)
606 : {
607 0 : return ind == DIRIND_ANON_DIRPORT || ind == DIRIND_ANONYMOUS;
608 : }
609 :
610 : /* Choose reachable OR and Dir addresses and ports from status, copying them
611 : * into use_or_ap and use_dir_ap. If indirection is anonymous, then we're
612 : * connecting via another relay, so choose the primary IPv4 address and ports.
613 : *
614 : * status should have at least one reachable address, if we can't choose a
615 : * reachable address, warn and return -1. Otherwise, return 0.
616 : */
617 : static int
618 0 : directory_choose_address_routerstatus(const routerstatus_t *status,
619 : dir_indirection_t indirection,
620 : tor_addr_port_t *use_or_ap,
621 : tor_addr_port_t *use_dir_ap)
622 : {
623 0 : tor_assert(status != NULL);
624 0 : tor_assert(use_or_ap != NULL);
625 0 : tor_assert(use_dir_ap != NULL);
626 :
627 0 : const or_options_t *options = get_options();
628 0 : int have_or = 0, have_dir = 0;
629 :
630 : /* We expect status to have at least one reachable address if we're
631 : * connecting to it directly.
632 : *
633 : * Therefore, we can simply use the other address if the one we want isn't
634 : * allowed by the firewall.
635 : *
636 : * (When Tor uploads and downloads a hidden service descriptor, it uses
637 : * DIRIND_ANONYMOUS. Even Single Onion Servers (NYI) use DIRIND_ANONYMOUS,
638 : * to avoid HSDirs denying service by rejecting descriptors.)
639 : */
640 :
641 : /* Initialise the OR / Dir addresses */
642 0 : tor_addr_make_null(&use_or_ap->addr, AF_UNSPEC);
643 0 : use_or_ap->port = 0;
644 0 : tor_addr_make_null(&use_dir_ap->addr, AF_UNSPEC);
645 0 : use_dir_ap->port = 0;
646 :
647 : /* ORPort connections */
648 0 : if (indirection == DIRIND_ANONYMOUS) {
649 0 : if (!tor_addr_is_null(&status->ipv4_addr)) {
650 : /* Since we're going to build a 3-hop circuit and ask the 2nd relay
651 : * to extend to this address, always use the primary (IPv4) OR address */
652 0 : tor_addr_copy(&use_or_ap->addr, &status->ipv4_addr);
653 0 : use_or_ap->port = status->ipv4_orport;
654 0 : have_or = 1;
655 : }
656 0 : } else if (indirection == DIRIND_ONEHOP) {
657 : /* We use an IPv6 address if we have one and we prefer it.
658 : * Use the preferred address and port if they are reachable, otherwise,
659 : * use the alternate address and port (if any).
660 : */
661 0 : reachable_addr_choose_from_rs(status, FIREWALL_OR_CONNECTION, 0,
662 : use_or_ap);
663 0 : have_or = tor_addr_port_is_valid_ap(use_or_ap, 0);
664 : }
665 :
666 : /* DirPort connections
667 : * DIRIND_ONEHOP uses ORPort, but may fall back to the DirPort on relays */
668 0 : if (indirection == DIRIND_DIRECT_CONN ||
669 0 : indirection == DIRIND_ANON_DIRPORT ||
670 : (indirection == DIRIND_ONEHOP
671 0 : && !dirclient_must_use_begindir(options))) {
672 0 : reachable_addr_choose_from_rs(status, FIREWALL_DIR_CONNECTION, 0,
673 : use_dir_ap);
674 0 : have_dir = tor_addr_port_is_valid_ap(use_dir_ap, 0);
675 : }
676 :
677 : /* We rejected all addresses in the relay's status. This means we can't
678 : * connect to it. */
679 0 : if (!have_or && !have_dir) {
680 0 : static int logged_backtrace = 0;
681 0 : char *ipv6_str = tor_addr_to_str_dup(&status->ipv6_addr);
682 0 : log_info(LD_BUG, "Rejected all OR and Dir addresses from %s when "
683 : "launching an outgoing directory connection to: IPv4 %s OR %d "
684 : "Dir %d IPv6 %s OR %d Dir %d", routerstatus_describe(status),
685 : fmt_addr(&status->ipv4_addr), status->ipv4_orport,
686 : status->ipv4_dirport, ipv6_str, status->ipv6_orport,
687 : status->ipv4_dirport);
688 0 : tor_free(ipv6_str);
689 0 : if (!logged_backtrace) {
690 0 : log_backtrace(LOG_INFO, LD_BUG, "Addresses came from");
691 0 : logged_backtrace = 1;
692 : }
693 0 : return -1;
694 : }
695 :
696 : return 0;
697 : }
698 :
699 : /** Called when we are unable to complete the client's request to a directory
700 : * server due to a network error: Mark the router as down and try again if
701 : * possible.
702 : */
703 : void
704 3 : connection_dir_client_request_failed(dir_connection_t *conn)
705 : {
706 3 : if (conn->guard_state) {
707 : /* We haven't seen a success on this guard state, so consider it to have
708 : * failed. */
709 0 : entry_guard_failed(&conn->guard_state);
710 : }
711 3 : if (!entry_list_is_constrained(get_options()))
712 3 : router_set_status(conn->identity_digest, 0); /* don't try this one again */
713 3 : if (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
714 : conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
715 1 : log_info(LD_DIR, "Giving up on serverdesc/extrainfo fetch from "
716 : "directory server at %s; retrying",
717 : connection_describe_peer(TO_CONN(conn)));
718 1 : if (conn->router_purpose == ROUTER_PURPOSE_BRIDGE)
719 0 : connection_dir_bridge_routerdesc_failed(conn);
720 1 : connection_dir_download_routerdesc_failed(conn);
721 2 : } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
722 2 : if (conn->requested_resource)
723 2 : networkstatus_consensus_download_failed(0, conn->requested_resource);
724 : } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
725 0 : log_info(LD_DIR, "Giving up on certificate fetch from directory server "
726 : "at %s; retrying",
727 : connection_describe_peer(TO_CONN(conn)));
728 0 : connection_dir_download_cert_failed(conn, 0);
729 : } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
730 0 : log_info(LD_DIR, "Giving up downloading detached signatures from %s",
731 : connection_describe_peer(TO_CONN(conn)));
732 : } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
733 0 : log_info(LD_DIR, "Giving up downloading votes from %s",
734 : connection_describe_peer(TO_CONN(conn)));
735 : } else if (conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC) {
736 0 : log_info(LD_DIR, "Giving up on downloading microdescriptors from "
737 : "directory server at %s; will retry",
738 : connection_describe_peer(TO_CONN(conn)));
739 0 : connection_dir_download_routerdesc_failed(conn);
740 : }
741 3 : }
742 :
743 : /** Helper: Attempt to fetch directly the descriptors of each bridge
744 : * listed in <b>failed</b>.
745 : */
746 : static void
747 0 : connection_dir_retry_bridges(smartlist_t *descs)
748 : {
749 0 : char digest[DIGEST_LEN];
750 0 : SMARTLIST_FOREACH(descs, const char *, cp,
751 : {
752 : if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp)) != DIGEST_LEN) {
753 : log_warn(LD_BUG, "Malformed fingerprint in list: %s",
754 : escaped(cp));
755 : continue;
756 : }
757 : retry_bridge_descriptor_fetch_directly(digest);
758 : });
759 0 : }
760 :
761 : /** Called when an attempt to download one or more router descriptors
762 : * or extra-info documents on connection <b>conn</b> failed.
763 : */
764 : static void
765 1 : connection_dir_download_routerdesc_failed(dir_connection_t *conn)
766 : {
767 : /* No need to increment the failure count for routerdescs, since
768 : * it's not their fault. */
769 :
770 : /* No need to relaunch descriptor downloads here: we already do it
771 : * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
772 1 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
773 : conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
774 : conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
775 :
776 1 : (void) conn;
777 1 : }
778 :
779 : /** Called when an attempt to download a bridge's routerdesc from
780 : * one of the authorities failed due to a network error. If
781 : * possible attempt to download descriptors from the bridge directly.
782 : */
783 : static void
784 0 : connection_dir_bridge_routerdesc_failed(dir_connection_t *conn)
785 : {
786 0 : smartlist_t *which = NULL;
787 :
788 : /* Requests for bridge descriptors are in the form 'fp/', so ignore
789 : anything else. */
790 0 : if (!conn->requested_resource || strcmpstart(conn->requested_resource,"fp/"))
791 0 : return;
792 :
793 0 : which = smartlist_new();
794 0 : dir_split_resource_into_fingerprints(conn->requested_resource
795 0 : + strlen("fp/"),
796 : which, NULL, 0);
797 :
798 0 : tor_assert(conn->base_.purpose != DIR_PURPOSE_FETCH_EXTRAINFO);
799 0 : if (smartlist_len(which)) {
800 0 : connection_dir_retry_bridges(which);
801 0 : SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
802 : }
803 0 : smartlist_free(which);
804 : }
805 :
806 : /** Called when an attempt to fetch a certificate fails. */
807 : static void
808 0 : connection_dir_download_cert_failed(dir_connection_t *conn, int status)
809 : {
810 0 : const char *fp_pfx = "fp/";
811 0 : const char *fpsk_pfx = "fp-sk/";
812 0 : smartlist_t *failed;
813 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
814 :
815 0 : if (!conn->requested_resource)
816 0 : return;
817 0 : failed = smartlist_new();
818 : /*
819 : * We have two cases download by fingerprint (resource starts
820 : * with "fp/") or download by fingerprint/signing key pair
821 : * (resource starts with "fp-sk/").
822 : */
823 0 : if (!strcmpstart(conn->requested_resource, fp_pfx)) {
824 : /* Download by fingerprint case */
825 0 : dir_split_resource_into_fingerprints(conn->requested_resource +
826 : strlen(fp_pfx),
827 : failed, NULL, DSR_HEX);
828 0 : SMARTLIST_FOREACH_BEGIN(failed, char *, cp) {
829 : /* Null signing key digest indicates download by fp only */
830 0 : authority_cert_dl_failed(cp, NULL, status);
831 0 : tor_free(cp);
832 0 : } SMARTLIST_FOREACH_END(cp);
833 0 : } else if (!strcmpstart(conn->requested_resource, fpsk_pfx)) {
834 : /* Download by (fp,sk) pairs */
835 0 : dir_split_resource_into_fingerprint_pairs(conn->requested_resource +
836 : strlen(fpsk_pfx), failed);
837 0 : SMARTLIST_FOREACH_BEGIN(failed, fp_pair_t *, cp) {
838 0 : authority_cert_dl_failed(cp->first, cp->second, status);
839 0 : tor_free(cp);
840 0 : } SMARTLIST_FOREACH_END(cp);
841 : } else {
842 0 : log_warn(LD_DIR,
843 : "Don't know what to do with failure for cert fetch %s",
844 : conn->requested_resource);
845 : }
846 :
847 0 : smartlist_free(failed);
848 :
849 0 : update_certificate_downloads(time(NULL));
850 : }
851 :
852 : /** Evaluate the situation and decide if we should use an encrypted
853 : * "begindir-style" connection for this directory request.
854 : * 0) If there is no DirPort, yes.
855 : * 1) If or_port is 0, or it's a direct conn and or_port is firewalled
856 : * or we're a dir mirror, no.
857 : * 2) If we prefer to avoid begindir conns, and we're not fetching or
858 : * publishing a bridge relay descriptor, no.
859 : * 3) Else yes.
860 : * If returning 0, return in *reason why we can't use begindir.
861 : * reason must not be NULL.
862 : */
863 : static int
864 0 : directory_command_should_use_begindir(const or_options_t *options,
865 : const directory_request_t *req,
866 : const char **reason)
867 : {
868 0 : const tor_addr_t *or_addr = &req->or_addr_port.addr;
869 : //const tor_addr_t *dir_addr = &req->dir_addr_port.addr;
870 0 : const int or_port = req->or_addr_port.port;
871 0 : const int dir_port = req->dir_addr_port.port;
872 :
873 0 : const dir_indirection_t indirection = req->indirection;
874 :
875 0 : tor_assert(reason);
876 0 : *reason = NULL;
877 :
878 : /* Reasons why we must use begindir */
879 0 : if (!dir_port) {
880 0 : *reason = "(using begindir - directory with no DirPort)";
881 0 : return 1; /* We don't know a DirPort -- must begindir. */
882 : }
883 : /* Reasons why we can't possibly use begindir */
884 0 : if (!or_port) {
885 0 : *reason = "directory with unknown ORPort";
886 0 : return 0; /* We don't know an ORPort -- no chance. */
887 : }
888 0 : if (indirection == DIRIND_DIRECT_CONN ||
889 : indirection == DIRIND_ANON_DIRPORT) {
890 0 : *reason = "DirPort connection";
891 0 : return 0;
892 : }
893 0 : if (indirection == DIRIND_ONEHOP) {
894 : /* We're firewalled and want a direct OR connection */
895 0 : if (!reachable_addr_allows_addr(or_addr, or_port,
896 : FIREWALL_OR_CONNECTION, 0, 0)) {
897 0 : *reason = "ORPort not reachable";
898 0 : return 0;
899 : }
900 : }
901 : /* Reasons why we want to avoid using begindir */
902 0 : if (indirection == DIRIND_ONEHOP) {
903 0 : if (!dirclient_must_use_begindir(options)) {
904 0 : *reason = "in relay mode";
905 0 : return 0;
906 : }
907 : }
908 : /* DIRIND_ONEHOP on a client, or DIRIND_ANONYMOUS
909 : */
910 0 : *reason = "(using begindir)";
911 0 : return 1;
912 : }
913 :
914 : /**
915 : * Create and return a new directory_request_t with purpose
916 : * <b>dir_purpose</b>.
917 : */
918 : directory_request_t *
919 72 : directory_request_new(uint8_t dir_purpose)
920 : {
921 72 : tor_assert(dir_purpose >= DIR_PURPOSE_MIN_);
922 72 : tor_assert(dir_purpose <= DIR_PURPOSE_MAX_);
923 72 : tor_assert(dir_purpose != DIR_PURPOSE_SERVER);
924 72 : tor_assert(dir_purpose != DIR_PURPOSE_HAS_FETCHED_HSDESC);
925 :
926 72 : directory_request_t *result = tor_malloc_zero(sizeof(*result));
927 72 : tor_addr_make_null(&result->or_addr_port.addr, AF_INET);
928 72 : result->or_addr_port.port = 0;
929 72 : tor_addr_make_null(&result->dir_addr_port.addr, AF_INET);
930 72 : result->dir_addr_port.port = 0;
931 72 : result->dir_purpose = dir_purpose;
932 72 : result->router_purpose = ROUTER_PURPOSE_GENERAL;
933 72 : result->indirection = DIRIND_ONEHOP;
934 72 : return result;
935 : }
936 : /**
937 : * Release all resources held by <b>req</b>.
938 : */
939 : void
940 72 : directory_request_free_(directory_request_t *req)
941 : {
942 72 : if (req == NULL)
943 : return;
944 72 : config_free_lines(req->additional_headers);
945 72 : tor_free(req);
946 : }
947 : /**
948 : * Set the address and OR port to use for this directory request. If there is
949 : * no OR port, we'll have to connect over the dirport. (If there are both,
950 : * the indirection setting determines which to use.)
951 : */
952 : void
953 0 : directory_request_set_or_addr_port(directory_request_t *req,
954 : const tor_addr_port_t *p)
955 : {
956 0 : memcpy(&req->or_addr_port, p, sizeof(*p));
957 0 : }
958 : /**
959 : * Set the address and dirport to use for this directory request. If there
960 : * is no dirport, we'll have to connect over the OR port. (If there are both,
961 : * the indirection setting determines which to use.)
962 : */
963 : void
964 0 : directory_request_set_dir_addr_port(directory_request_t *req,
965 : const tor_addr_port_t *p)
966 : {
967 0 : memcpy(&req->dir_addr_port, p, sizeof(*p));
968 0 : }
969 : /**
970 : * Set the RSA identity digest of the directory to use for this directory
971 : * request.
972 : */
973 : void
974 0 : directory_request_set_directory_id_digest(directory_request_t *req,
975 : const char *digest)
976 : {
977 0 : memcpy(req->digest, digest, DIGEST_LEN);
978 0 : }
979 : /**
980 : * Set the router purpose associated with uploaded and downloaded router
981 : * descriptors and extrainfo documents in this directory request. The purpose
982 : * must be one of ROUTER_PURPOSE_GENERAL (the default) or
983 : * ROUTER_PURPOSE_BRIDGE.
984 : */
985 : void
986 6 : directory_request_set_router_purpose(directory_request_t *req,
987 : uint8_t router_purpose)
988 : {
989 6 : tor_assert(router_purpose == ROUTER_PURPOSE_GENERAL ||
990 : router_purpose == ROUTER_PURPOSE_BRIDGE);
991 : // assert that it actually makes sense to set this purpose, given
992 : // the dir_purpose.
993 6 : req->router_purpose = router_purpose;
994 6 : }
995 : /**
996 : * Set the indirection to be used for the directory request. The indirection
997 : * parameter configures whether to connect to a DirPort or ORPort, and whether
998 : * to anonymize the connection. DIRIND_ONEHOP (use ORPort, don't anonymize)
999 : * is the default. See dir_indirection_t for more information.
1000 : */
1001 : void
1002 70 : directory_request_set_indirection(directory_request_t *req,
1003 : dir_indirection_t indirection)
1004 : {
1005 70 : req->indirection = indirection;
1006 70 : }
1007 :
1008 : /**
1009 : * Set a pointer to the resource to request from a directory. Different
1010 : * request types use resources to indicate different components of their URL.
1011 : * Note that only an alias to <b>resource</b> is stored, so the
1012 : * <b>resource</b> must outlive the request.
1013 : */
1014 : void
1015 72 : directory_request_set_resource(directory_request_t *req,
1016 : const char *resource)
1017 : {
1018 72 : req->resource = resource;
1019 72 : }
1020 : /**
1021 : * Set a pointer to the payload to include with this directory request, along
1022 : * with its length. Note that only an alias to <b>payload</b> is stored, so
1023 : * the <b>payload</b> must outlive the request.
1024 : */
1025 : void
1026 66 : directory_request_set_payload(directory_request_t *req,
1027 : const char *payload,
1028 : size_t payload_len)
1029 : {
1030 66 : tor_assert(DIR_PURPOSE_IS_UPLOAD(req->dir_purpose));
1031 :
1032 66 : req->payload = payload;
1033 66 : req->payload_len = payload_len;
1034 66 : }
1035 : /**
1036 : * Set an if-modified-since date to send along with the request. The
1037 : * default is 0 (meaning, send no if-modified-since header).
1038 : */
1039 : void
1040 0 : directory_request_set_if_modified_since(directory_request_t *req,
1041 : time_t if_modified_since)
1042 : {
1043 0 : req->if_modified_since = if_modified_since;
1044 0 : }
1045 :
1046 : /** Include a header of name <b>key</b> with content <b>val</b> in the
1047 : * request. Neither may include newlines or other odd characters. Their
1048 : * ordering is not currently guaranteed.
1049 : *
1050 : * Note that, as elsewhere in this module, header keys include a trailing
1051 : * colon and space.
1052 : */
1053 : void
1054 0 : directory_request_add_header(directory_request_t *req,
1055 : const char *key,
1056 : const char *val)
1057 : {
1058 0 : config_line_prepend(&req->additional_headers, key, val);
1059 0 : }
1060 : /**
1061 : * Set an object containing HS connection identifier to be associated with
1062 : * this request. Note that only an alias to <b>ident</b> is stored, so the
1063 : * <b>ident</b> object must outlive the request.
1064 : */
1065 : void
1066 66 : directory_request_upload_set_hs_ident(directory_request_t *req,
1067 : const hs_ident_dir_conn_t *ident)
1068 : {
1069 66 : if (ident) {
1070 66 : tor_assert(req->dir_purpose == DIR_PURPOSE_UPLOAD_HSDESC);
1071 : }
1072 66 : req->hs_ident = ident;
1073 66 : }
1074 : /**
1075 : * Set an object containing HS connection identifier to be associated with
1076 : * this fetch request. Note that only an alias to <b>ident</b> is stored, so
1077 : * the <b>ident</b> object must outlive the request.
1078 : */
1079 : void
1080 0 : directory_request_fetch_set_hs_ident(directory_request_t *req,
1081 : const hs_ident_dir_conn_t *ident)
1082 : {
1083 0 : if (ident) {
1084 0 : tor_assert(req->dir_purpose == DIR_PURPOSE_FETCH_HSDESC);
1085 : }
1086 0 : req->hs_ident = ident;
1087 0 : }
1088 : /** Set a static circuit_guard_state_t object to affliate with the request in
1089 : * <b>req</b>. This object will receive notification when the attempt to
1090 : * connect to the guard either succeeds or fails. */
1091 : void
1092 3 : directory_request_set_guard_state(directory_request_t *req,
1093 : circuit_guard_state_t *state)
1094 : {
1095 3 : req->guard_state = state;
1096 3 : }
1097 :
1098 : /**
1099 : * Internal: Return true if any information for contacting the directory in
1100 : * <b>req</b> has been set, other than by the routerstatus. */
1101 : static int
1102 0 : directory_request_dir_contact_info_specified(const directory_request_t *req)
1103 : {
1104 : /* We only check for ports here, since we don't use an addr unless the port
1105 : * is set */
1106 0 : return (req->or_addr_port.port ||
1107 0 : req->dir_addr_port.port ||
1108 0 : ! tor_digest_is_zero(req->digest));
1109 : }
1110 :
1111 : /**
1112 : * Set the routerstatus to use for the directory associated with this
1113 : * request. If this option is set, then no other function to set the
1114 : * directory's address or identity should be called.
1115 : */
1116 : void
1117 72 : directory_request_set_routerstatus(directory_request_t *req,
1118 : const routerstatus_t *status)
1119 : {
1120 72 : req->routerstatus = status;
1121 72 : }
1122 :
1123 : /**
1124 : * Helper: update the addresses, ports, and identities in <b>req</b>
1125 : * from the routerstatus object in <b>req</b>. Return 0 on success.
1126 : * On failure, warn and return -1.
1127 : */
1128 : static int
1129 0 : directory_request_set_dir_from_routerstatus(directory_request_t *req)
1130 :
1131 : {
1132 0 : const routerstatus_t *status = req->routerstatus;
1133 0 : if (BUG(status == NULL))
1134 0 : return -1;
1135 0 : const or_options_t *options = get_options();
1136 0 : const node_t *node;
1137 0 : tor_addr_port_t use_or_ap, use_dir_ap;
1138 0 : const int anonymized_connection = dirind_is_anon(req->indirection);
1139 :
1140 0 : tor_assert(status != NULL);
1141 :
1142 0 : node = node_get_by_id(status->identity_digest);
1143 :
1144 : /* XXX The below check is wrong: !node means it's not in the consensus,
1145 : * but we haven't checked if we have a descriptor for it -- and also,
1146 : * we only care about the descriptor if it's a begindir-style anonymized
1147 : * connection. */
1148 0 : if (!node && anonymized_connection) {
1149 0 : log_info(LD_DIR, "Not sending anonymized request to directory '%s'; we "
1150 : "don't have its router descriptor.",
1151 : routerstatus_describe(status));
1152 0 : return -1;
1153 : }
1154 :
1155 0 : if (options->ExcludeNodes && options->StrictNodes &&
1156 0 : routerset_contains_routerstatus(options->ExcludeNodes, status, -1)) {
1157 0 : log_warn(LD_DIR, "Wanted to contact directory mirror %s for %s, but "
1158 : "it's in our ExcludedNodes list and StrictNodes is set. "
1159 : "Skipping. This choice might make your Tor not work.",
1160 : routerstatus_describe(status),
1161 : dir_conn_purpose_to_string(req->dir_purpose));
1162 0 : return -1;
1163 : }
1164 :
1165 : /* At this point, if we are a client making a direct connection to a
1166 : * directory server, we have selected a server that has at least one address
1167 : * allowed by ClientUseIPv4/6 and Reachable{"",OR,Dir}Addresses. This
1168 : * selection uses the preference in ClientPreferIPv6{OR,Dir}Port, if
1169 : * possible. (If UseBridges is set, clients always use IPv6, and prefer it
1170 : * by default.)
1171 : *
1172 : * Now choose an address that we can use to connect to the directory server.
1173 : */
1174 0 : if (directory_choose_address_routerstatus(status,
1175 : req->indirection, &use_or_ap,
1176 : &use_dir_ap) < 0) {
1177 : return -1;
1178 : }
1179 :
1180 : /* One last thing: If we're talking to an authority, we might want to use
1181 : * a special HTTP port for it based on our purpose.
1182 : */
1183 0 : if (req->indirection == DIRIND_DIRECT_CONN && status->is_authority) {
1184 0 : const dir_server_t *ds = router_get_trusteddirserver_by_digest(
1185 : status->identity_digest);
1186 0 : if (ds) {
1187 0 : const tor_addr_port_t *v4 = NULL;
1188 0 : if (authdir_mode_v3(get_options())) {
1189 : // An authority connecting to another authority should always
1190 : // prefer the VOTING usage, if one is specifically configured.
1191 0 : v4 = trusted_dir_server_get_dirport_exact(
1192 : ds, AUTH_USAGE_VOTING, AF_INET);
1193 : }
1194 0 : if (! v4) {
1195 : // Everybody else should prefer a usage dependent on their
1196 : // the dir_purpose.
1197 0 : auth_dirport_usage_t usage =
1198 0 : auth_dirport_usage_for_purpose(req->dir_purpose);
1199 0 : v4 = trusted_dir_server_get_dirport(ds, usage, AF_INET);
1200 : }
1201 0 : tor_assert_nonfatal(v4);
1202 0 : if (v4) {
1203 : // XXXX We could, if we wanted, also select a v6 address. But a v4
1204 : // address must exist here, and we as a relay are required to support
1205 : // ipv4. So we just that.
1206 0 : tor_addr_port_copy(&use_dir_ap, v4);
1207 : }
1208 : }
1209 : }
1210 :
1211 0 : directory_request_set_or_addr_port(req, &use_or_ap);
1212 0 : directory_request_set_dir_addr_port(req, &use_dir_ap);
1213 0 : directory_request_set_directory_id_digest(req, status->identity_digest);
1214 0 : return 0;
1215 : }
1216 :
1217 : /**
1218 : * Launch the provided directory request, configured in <b>request</b>.
1219 : * After this function is called, you can free <b>request</b>.
1220 : */
1221 0 : MOCK_IMPL(void,
1222 : directory_initiate_request,(directory_request_t *request))
1223 : {
1224 0 : tor_assert(request);
1225 0 : if (request->routerstatus) {
1226 0 : tor_assert_nonfatal(
1227 : ! directory_request_dir_contact_info_specified(request));
1228 0 : if (directory_request_set_dir_from_routerstatus(request) < 0) {
1229 0 : return; // or here XXXX
1230 : }
1231 : }
1232 :
1233 0 : const tor_addr_port_t *or_addr_port = &request->or_addr_port;
1234 0 : const tor_addr_port_t *dir_addr_port = &request->dir_addr_port;
1235 0 : const char *digest = request->digest;
1236 0 : const uint8_t dir_purpose = request->dir_purpose;
1237 0 : const uint8_t router_purpose = request->router_purpose;
1238 0 : const dir_indirection_t indirection = request->indirection;
1239 0 : const char *resource = request->resource;
1240 0 : const hs_ident_dir_conn_t *hs_ident = request->hs_ident;
1241 0 : circuit_guard_state_t *guard_state = request->guard_state;
1242 :
1243 0 : tor_assert(or_addr_port->port || dir_addr_port->port);
1244 0 : tor_assert(digest);
1245 :
1246 0 : dir_connection_t *conn;
1247 0 : const or_options_t *options = get_options();
1248 0 : int socket_error = 0;
1249 0 : const char *begindir_reason = NULL;
1250 : /* Should the connection be to a relay's OR port (and inside that we will
1251 : * send our directory request)? */
1252 0 : const int use_begindir =
1253 0 : directory_command_should_use_begindir(options, request, &begindir_reason);
1254 :
1255 : /* Will the connection go via a three-hop Tor circuit? Note that this
1256 : * is separate from whether it will use_begindir. */
1257 0 : const int anonymized_connection = dirind_is_anon(indirection);
1258 :
1259 : /* What is the address we want to make the directory request to? If
1260 : * we're making a begindir request this is the ORPort of the relay
1261 : * we're contacting; if not a begindir request, this is its DirPort.
1262 : * Note that if anonymized_connection is true, we won't be initiating
1263 : * a connection directly to this address. */
1264 0 : tor_addr_t addr;
1265 0 : tor_addr_copy(&addr, &(use_begindir ? or_addr_port : dir_addr_port)->addr);
1266 0 : uint16_t port = (use_begindir ? or_addr_port : dir_addr_port)->port;
1267 :
1268 0 : log_debug(LD_DIR, "anonymized %d, use_begindir %d.",
1269 : anonymized_connection, use_begindir);
1270 :
1271 0 : log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
1272 :
1273 0 : if (purpose_needs_anonymity(dir_purpose, router_purpose, resource)) {
1274 0 : tor_assert(anonymized_connection ||
1275 : hs_service_non_anonymous_mode_enabled(options));
1276 : }
1277 :
1278 : /* use encrypted begindir connections for everything except relays
1279 : * this provides better protection for directory fetches */
1280 0 : if (!use_begindir && dirclient_must_use_begindir(options)) {
1281 0 : log_warn(LD_BUG, "Client could not use begindir connection: %s",
1282 : begindir_reason ? begindir_reason : "(NULL)");
1283 0 : return;
1284 : }
1285 :
1286 : /* ensure that we don't make direct connections when a SOCKS server is
1287 : * configured. */
1288 0 : if (!anonymized_connection && !use_begindir && !options->HTTPProxy &&
1289 0 : (options->Socks4Proxy || options->Socks5Proxy)) {
1290 0 : log_warn(LD_DIR, "Cannot connect to a directory server through a "
1291 : "SOCKS proxy!");
1292 0 : return;
1293 : }
1294 :
1295 : /* Make sure that the destination addr and port we picked is viable. */
1296 0 : if (!port || tor_addr_is_null(&addr)) {
1297 0 : static int logged_backtrace = 0;
1298 0 : log_warn(LD_DIR,
1299 : "Cannot make an outgoing %sconnection without a remote %sPort.",
1300 : use_begindir ? "begindir " : "",
1301 : use_begindir ? "OR" : "Dir");
1302 0 : if (!logged_backtrace) {
1303 0 : log_backtrace(LOG_INFO, LD_BUG, "Address came from");
1304 0 : logged_backtrace = 1;
1305 : }
1306 0 : return;
1307 : }
1308 :
1309 0 : conn = dir_connection_new(tor_addr_family(&addr));
1310 :
1311 : /* set up conn so it's got all the data we need to remember */
1312 0 : tor_addr_copy(&conn->base_.addr, &addr);
1313 0 : conn->base_.port = port;
1314 0 : conn->base_.address = tor_addr_to_str_dup(&addr);
1315 0 : memcpy(conn->identity_digest, digest, DIGEST_LEN);
1316 :
1317 0 : conn->base_.purpose = dir_purpose;
1318 0 : conn->router_purpose = router_purpose;
1319 :
1320 : /* give it an initial state */
1321 0 : conn->base_.state = DIR_CONN_STATE_CONNECTING;
1322 :
1323 : /* decide whether we can learn our IP address from this conn */
1324 : /* XXXX This is a bad name for this field now. */
1325 0 : conn->dirconn_direct = !anonymized_connection;
1326 :
1327 0 : if (hs_ident) {
1328 0 : conn->hs_ident = hs_ident_dir_conn_dup(hs_ident);
1329 : }
1330 :
1331 0 : if (!anonymized_connection && !use_begindir) {
1332 : /* then we want to connect to dirport directly */
1333 :
1334 0 : if (options->HTTPProxy) {
1335 0 : tor_addr_copy(&addr, &options->HTTPProxyAddr);
1336 0 : port = options->HTTPProxyPort;
1337 : }
1338 :
1339 : // In this case we should not have picked a directory guard.
1340 0 : if (BUG(guard_state)) {
1341 0 : entry_guard_cancel(&guard_state);
1342 : }
1343 :
1344 : // XXXX This is the case where we replace.
1345 :
1346 0 : switch (connection_connect(TO_CONN(conn), conn->base_.address, &addr,
1347 : port, &socket_error)) {
1348 0 : case -1:
1349 0 : connection_mark_for_close(TO_CONN(conn));
1350 0 : return;
1351 0 : case 1:
1352 : /* start flushing conn */
1353 0 : conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING;
1354 0 : FALLTHROUGH;
1355 0 : case 0:
1356 : /* queue the command on the outbuf */
1357 0 : directory_send_command(conn, 1, request);
1358 0 : connection_watch_events(TO_CONN(conn), READ_EVENT | WRITE_EVENT);
1359 : /* writable indicates finish, readable indicates broken link,
1360 : error indicates broken link in windowsland. */
1361 : }
1362 : } else {
1363 : /* We will use a Tor circuit (maybe 1-hop, maybe 3-hop, maybe with
1364 : * begindir, maybe not with begindir) */
1365 :
1366 0 : entry_connection_t *linked_conn;
1367 :
1368 : /* Anonymized tunneled connections can never share a circuit.
1369 : * One-hop directory connections can share circuits with each other
1370 : * but nothing else. */
1371 0 : int iso_flags = anonymized_connection ? ISO_STREAM : ISO_SESSIONGRP;
1372 :
1373 : /* If it's an anonymized connection, remember the fact that we
1374 : * wanted it for later: maybe we'll want it again soon. */
1375 0 : if (anonymized_connection && use_begindir)
1376 0 : rep_hist_note_used_internal(time(NULL), 0, 1);
1377 0 : else if (anonymized_connection && !use_begindir)
1378 0 : rep_hist_note_used_port(time(NULL), conn->base_.port);
1379 :
1380 : // In this case we should not have a directory guard; we'll
1381 : // get a regular guard later when we build the circuit.
1382 0 : if (BUG(anonymized_connection && guard_state)) {
1383 0 : entry_guard_cancel(&guard_state);
1384 : }
1385 :
1386 0 : conn->guard_state = guard_state;
1387 :
1388 : /* make an AP connection
1389 : * populate it and add it at the right state
1390 : * hook up both sides
1391 : */
1392 0 : linked_conn =
1393 0 : connection_ap_make_link(TO_CONN(conn),
1394 0 : conn->base_.address, conn->base_.port,
1395 : digest,
1396 : SESSION_GROUP_DIRCONN, iso_flags,
1397 : use_begindir, !anonymized_connection);
1398 0 : if (!linked_conn) {
1399 0 : log_warn(LD_NET,"Making tunnel to dirserver failed.");
1400 0 : connection_mark_for_close(TO_CONN(conn));
1401 0 : return;
1402 : }
1403 :
1404 0 : if (connection_add(TO_CONN(conn)) < 0) {
1405 0 : log_warn(LD_NET,"Unable to add connection for link to dirserver.");
1406 0 : connection_mark_for_close(TO_CONN(conn));
1407 0 : return;
1408 : }
1409 0 : conn->base_.state = DIR_CONN_STATE_CLIENT_SENDING;
1410 : /* queue the command on the outbuf */
1411 0 : directory_send_command(conn, 0, request);
1412 :
1413 0 : connection_watch_events(TO_CONN(conn), READ_EVENT|WRITE_EVENT);
1414 0 : connection_start_reading(ENTRY_TO_CONN(linked_conn));
1415 : }
1416 : }
1417 :
1418 : /** Helper for sorting
1419 : *
1420 : * sort strings alphabetically
1421 : *
1422 : * XXXX we have a smartlist_sort_strings() function, right?
1423 : */
1424 : static int
1425 0 : compare_strs_(const void **a, const void **b)
1426 : {
1427 0 : const char *s1 = *a, *s2 = *b;
1428 0 : return strcmp(s1, s2);
1429 : }
1430 :
1431 : #define CONDITIONAL_CONSENSUS_FPR_LEN 3
1432 : CTASSERT(CONDITIONAL_CONSENSUS_FPR_LEN <= DIGEST_LEN);
1433 :
1434 : /** Return the URL we should use for a consensus download.
1435 : *
1436 : * Use the "conditional consensus downloading" feature described in
1437 : * dir-spec.txt, i.e.
1438 : * GET .../consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>
1439 : *
1440 : * If 'resource' is provided, it is the name of a consensus flavor to request.
1441 : */
1442 : static char *
1443 0 : directory_get_consensus_url(const char *resource)
1444 : {
1445 0 : char *url = NULL;
1446 0 : const char *hyphen, *flavor;
1447 0 : if (resource==NULL || strcmp(resource, "ns")==0) {
1448 : flavor = ""; /* Request ns consensuses as "", so older servers will work*/
1449 : hyphen = "";
1450 : } else {
1451 0 : flavor = resource;
1452 0 : hyphen = "-";
1453 : }
1454 :
1455 : {
1456 0 : char *authority_id_list;
1457 0 : smartlist_t *authority_digests = smartlist_new();
1458 :
1459 0 : SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
1460 : dir_server_t *, ds) {
1461 0 : char *hex;
1462 0 : if (!(ds->type & V3_DIRINFO))
1463 0 : continue;
1464 :
1465 0 : hex = tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN+1);
1466 0 : base16_encode(hex, 2*CONDITIONAL_CONSENSUS_FPR_LEN+1,
1467 0 : ds->v3_identity_digest, CONDITIONAL_CONSENSUS_FPR_LEN);
1468 0 : smartlist_add(authority_digests, hex);
1469 0 : } SMARTLIST_FOREACH_END(ds);
1470 0 : smartlist_sort(authority_digests, compare_strs_);
1471 0 : authority_id_list = smartlist_join_strings(authority_digests,
1472 : "+", 0, NULL);
1473 :
1474 0 : tor_asprintf(&url, "/tor/status-vote/current/consensus%s%s/%s.z",
1475 : hyphen, flavor, authority_id_list);
1476 :
1477 0 : SMARTLIST_FOREACH(authority_digests, char *, cp, tor_free(cp));
1478 0 : smartlist_free(authority_digests);
1479 0 : tor_free(authority_id_list);
1480 : }
1481 0 : return url;
1482 : }
1483 :
1484 : /**
1485 : * Copies the ipv6 from source to destination, subject to buffer size limit
1486 : * size. If decorate is true, makes sure the copied address is decorated.
1487 : */
1488 : static void
1489 0 : copy_ipv6_address(char* destination, const char* source, size_t len,
1490 : int decorate) {
1491 0 : tor_assert(destination);
1492 0 : tor_assert(source);
1493 :
1494 0 : if (decorate && source[0] != '[') {
1495 0 : tor_snprintf(destination, len, "[%s]", source);
1496 : } else {
1497 0 : strlcpy(destination, source, len);
1498 : }
1499 0 : }
1500 :
1501 : /** Queue an appropriate HTTP command for <b>request</b> on
1502 : * <b>conn</b>-\>outbuf. If <b>direct</b> is true, we're making a
1503 : * non-anonymized connection to the dirport.
1504 : */
1505 : static void
1506 0 : directory_send_command(dir_connection_t *conn,
1507 : const int direct,
1508 : const directory_request_t *req)
1509 : {
1510 0 : tor_assert(req);
1511 0 : const int purpose = req->dir_purpose;
1512 0 : const char *resource = req->resource;
1513 0 : const char *payload = req->payload;
1514 0 : const size_t payload_len = req->payload_len;
1515 0 : const time_t if_modified_since = req->if_modified_since;
1516 0 : const int anonymized_connection = dirind_is_anon(req->indirection);
1517 :
1518 0 : char proxystring[256];
1519 0 : char hoststring[128];
1520 : /* NEEDS to be the same size hoststring.
1521 : Will be decorated with brackets around it if it is ipv6. */
1522 0 : char decorated_address[128];
1523 0 : smartlist_t *headers = smartlist_new();
1524 0 : char *url;
1525 0 : char *accept_encoding;
1526 0 : size_t url_len;
1527 0 : char request[8192];
1528 0 : size_t request_len, total_request_len = 0;
1529 0 : const char *httpcommand = NULL;
1530 :
1531 0 : tor_assert(conn);
1532 0 : tor_assert(conn->base_.type == CONN_TYPE_DIR);
1533 :
1534 0 : tor_free(conn->requested_resource);
1535 0 : if (resource)
1536 0 : conn->requested_resource = tor_strdup(resource);
1537 :
1538 : /* decorate the ip address if it is ipv6 */
1539 0 : if (strchr(conn->base_.address, ':')) {
1540 0 : copy_ipv6_address(decorated_address, conn->base_.address,
1541 : sizeof(decorated_address), 1);
1542 : } else {
1543 0 : strlcpy(decorated_address, conn->base_.address, sizeof(decorated_address));
1544 : }
1545 :
1546 : /* come up with a string for which Host: we want */
1547 0 : if (conn->base_.port == 80) {
1548 0 : strlcpy(hoststring, decorated_address, sizeof(hoststring));
1549 : } else {
1550 0 : tor_snprintf(hoststring, sizeof(hoststring), "%s:%d",
1551 : decorated_address, conn->base_.port);
1552 : }
1553 :
1554 : /* Format if-modified-since */
1555 0 : if (if_modified_since) {
1556 0 : char b[RFC1123_TIME_LEN+1];
1557 0 : format_rfc1123_time(b, if_modified_since);
1558 0 : smartlist_add_asprintf(headers, "If-Modified-Since: %s\r\n", b);
1559 : }
1560 :
1561 : /* come up with some proxy lines, if we're using one. */
1562 0 : if (direct && get_options()->HTTPProxy) {
1563 0 : char *base64_authenticator=NULL;
1564 0 : const char *authenticator = get_options()->HTTPProxyAuthenticator;
1565 :
1566 0 : tor_snprintf(proxystring, sizeof(proxystring),"http://%s", hoststring);
1567 0 : if (authenticator) {
1568 0 : base64_authenticator = alloc_http_authenticator(authenticator);
1569 0 : if (!base64_authenticator)
1570 0 : log_warn(LD_BUG, "Encoding http authenticator failed");
1571 : }
1572 0 : if (base64_authenticator) {
1573 0 : smartlist_add_asprintf(headers,
1574 : "Proxy-Authorization: Basic %s\r\n",
1575 : base64_authenticator);
1576 0 : tor_free(base64_authenticator);
1577 : }
1578 : } else {
1579 0 : proxystring[0] = 0;
1580 : }
1581 :
1582 0 : if (! anonymized_connection) {
1583 : /* Add Accept-Encoding. */
1584 0 : accept_encoding = accept_encoding_header();
1585 0 : smartlist_add_asprintf(headers, "Accept-Encoding: %s\r\n",
1586 : accept_encoding);
1587 0 : tor_free(accept_encoding);
1588 : }
1589 :
1590 : /* Add additional headers, if any */
1591 : {
1592 0 : config_line_t *h;
1593 0 : for (h = req->additional_headers; h; h = h->next) {
1594 0 : smartlist_add_asprintf(headers, "%s%s\r\n", h->key, h->value);
1595 : }
1596 : }
1597 :
1598 0 : switch (purpose) {
1599 0 : case DIR_PURPOSE_FETCH_CONSENSUS:
1600 : /* resource is optional. If present, it's a flavor name */
1601 0 : tor_assert(!payload);
1602 0 : httpcommand = "GET";
1603 0 : url = directory_get_consensus_url(resource);
1604 0 : log_info(LD_DIR, "Downloading consensus from %s using %s",
1605 : hoststring, url);
1606 0 : break;
1607 0 : case DIR_PURPOSE_FETCH_CERTIFICATE:
1608 0 : tor_assert(resource);
1609 0 : tor_assert(!payload);
1610 0 : httpcommand = "GET";
1611 0 : tor_asprintf(&url, "/tor/keys/%s", resource);
1612 0 : break;
1613 0 : case DIR_PURPOSE_FETCH_STATUS_VOTE:
1614 0 : tor_assert(resource);
1615 0 : tor_assert(!payload);
1616 0 : httpcommand = "GET";
1617 0 : tor_asprintf(&url, "/tor/status-vote/next/%s.z", resource);
1618 0 : break;
1619 0 : case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
1620 0 : tor_assert(!resource);
1621 0 : tor_assert(!payload);
1622 0 : httpcommand = "GET";
1623 0 : url = tor_strdup("/tor/status-vote/next/consensus-signatures.z");
1624 0 : break;
1625 0 : case DIR_PURPOSE_FETCH_SERVERDESC:
1626 0 : tor_assert(resource);
1627 0 : httpcommand = "GET";
1628 0 : tor_asprintf(&url, "/tor/server/%s", resource);
1629 0 : break;
1630 0 : case DIR_PURPOSE_FETCH_EXTRAINFO:
1631 0 : tor_assert(resource);
1632 0 : httpcommand = "GET";
1633 0 : tor_asprintf(&url, "/tor/extra/%s", resource);
1634 0 : break;
1635 0 : case DIR_PURPOSE_FETCH_MICRODESC:
1636 0 : tor_assert(resource);
1637 0 : httpcommand = "GET";
1638 0 : tor_asprintf(&url, "/tor/micro/%s", resource);
1639 0 : break;
1640 0 : case DIR_PURPOSE_UPLOAD_DIR: {
1641 0 : const char *why = router_get_descriptor_gen_reason();
1642 0 : tor_assert(!resource);
1643 0 : tor_assert(payload);
1644 0 : httpcommand = "POST";
1645 0 : url = tor_strdup("/tor/");
1646 0 : if (!why) {
1647 0 : why = "for no reason at all";
1648 : }
1649 0 : smartlist_add_asprintf(headers, "X-Desc-Gen-Reason: %s\r\n", why);
1650 0 : break;
1651 : }
1652 0 : case DIR_PURPOSE_UPLOAD_VOTE:
1653 0 : tor_assert(!resource);
1654 0 : tor_assert(payload);
1655 0 : httpcommand = "POST";
1656 0 : url = tor_strdup("/tor/post/vote");
1657 0 : break;
1658 0 : case DIR_PURPOSE_UPLOAD_SIGNATURES:
1659 0 : tor_assert(!resource);
1660 0 : tor_assert(payload);
1661 0 : httpcommand = "POST";
1662 0 : url = tor_strdup("/tor/post/consensus-signature");
1663 0 : break;
1664 0 : case DIR_PURPOSE_FETCH_HSDESC:
1665 0 : tor_assert(resource);
1666 0 : tor_assert(strlen(resource) <= ED25519_BASE64_LEN);
1667 0 : tor_assert(!payload);
1668 0 : httpcommand = "GET";
1669 0 : tor_asprintf(&url, "/tor/hs/3/%s", resource);
1670 0 : break;
1671 0 : case DIR_PURPOSE_UPLOAD_HSDESC:
1672 0 : tor_assert(resource);
1673 0 : tor_assert(payload);
1674 0 : httpcommand = "POST";
1675 0 : tor_asprintf(&url, "/tor/hs/%s/publish", resource);
1676 0 : break;
1677 : default:
1678 0 : tor_assert(0);
1679 : return;
1680 : }
1681 :
1682 : /* warn in the non-tunneled case */
1683 0 : if (direct && (strlen(proxystring) + strlen(url) >= 4096)) {
1684 0 : log_warn(LD_BUG,
1685 : "Squid does not like URLs longer than 4095 bytes, and this "
1686 : "one is %d bytes long: %s%s",
1687 : (int)(strlen(proxystring) + strlen(url)), proxystring, url);
1688 : }
1689 :
1690 0 : tor_snprintf(request, sizeof(request), "%s %s", httpcommand, proxystring);
1691 :
1692 0 : request_len = strlen(request);
1693 0 : total_request_len += request_len;
1694 0 : connection_buf_add(request, request_len, TO_CONN(conn));
1695 :
1696 0 : url_len = strlen(url);
1697 0 : total_request_len += url_len;
1698 0 : connection_buf_add(url, url_len, TO_CONN(conn));
1699 0 : tor_free(url);
1700 :
1701 0 : if (!strcmp(httpcommand, "POST") || payload) {
1702 0 : smartlist_add_asprintf(headers, "Content-Length: %lu\r\n",
1703 : payload ? (unsigned long)payload_len : 0);
1704 : }
1705 :
1706 : {
1707 0 : char *header = smartlist_join_strings(headers, "", 0, NULL);
1708 0 : tor_snprintf(request, sizeof(request), " HTTP/1.0\r\nHost: %s\r\n%s\r\n",
1709 : hoststring, header);
1710 0 : tor_free(header);
1711 : }
1712 :
1713 0 : request_len = strlen(request);
1714 0 : total_request_len += request_len;
1715 0 : connection_buf_add(request, request_len, TO_CONN(conn));
1716 :
1717 0 : if (payload) {
1718 : /* then send the payload afterwards too */
1719 0 : connection_buf_add(payload, payload_len, TO_CONN(conn));
1720 0 : total_request_len += payload_len;
1721 : }
1722 :
1723 0 : SMARTLIST_FOREACH(headers, char *, h, tor_free(h));
1724 0 : smartlist_free(headers);
1725 :
1726 0 : log_debug(LD_DIR,
1727 : "Sent request to directory server %s "
1728 : "(purpose: %d, request size: %"TOR_PRIuSZ", "
1729 : "payload size: %"TOR_PRIuSZ")",
1730 : connection_describe_peer(TO_CONN(conn)),
1731 : conn->base_.purpose,
1732 : (total_request_len),
1733 : (payload ? payload_len : 0));
1734 : }
1735 :
1736 : /** Return true iff <b>body</b> doesn't start with a plausible router or
1737 : * network-status or microdescriptor opening. This is a sign of possible
1738 : * compression. */
1739 : static int
1740 0 : body_is_plausible(const char *body, size_t len, int purpose)
1741 : {
1742 0 : int i;
1743 0 : if (len == 0)
1744 : return 1; /* empty bodies don't need decompression */
1745 0 : if (len < 32)
1746 : return 0;
1747 0 : if (purpose == DIR_PURPOSE_FETCH_MICRODESC) {
1748 0 : return (!strcmpstart(body,"onion-key"));
1749 : }
1750 :
1751 0 : if (!strcmpstart(body,"router") ||
1752 0 : !strcmpstart(body,"network-status"))
1753 0 : return 1;
1754 0 : for (i=0;i<32;++i) {
1755 0 : if (!TOR_ISPRINT(body[i]) && !TOR_ISSPACE(body[i]))
1756 : return 0;
1757 : }
1758 :
1759 : return 1;
1760 : }
1761 :
1762 : /** Called when we've just fetched a bunch of router descriptors in
1763 : * <b>body</b>. The list <b>which</b>, if present, holds digests for
1764 : * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1765 : * is true, or identity digests otherwise. Parse the descriptors, validate
1766 : * them, and annotate them as having purpose <b>purpose</b> and as having been
1767 : * downloaded from <b>source</b>.
1768 : *
1769 : * Return the number of routers actually added. */
1770 : static int
1771 0 : load_downloaded_routers(const char *body, smartlist_t *which,
1772 : int descriptor_digests,
1773 : int router_purpose,
1774 : const char *source)
1775 : {
1776 0 : char buf[256];
1777 0 : char time_buf[ISO_TIME_LEN+1];
1778 0 : int added = 0;
1779 0 : int general = router_purpose == ROUTER_PURPOSE_GENERAL;
1780 0 : format_iso_time(time_buf, time(NULL));
1781 0 : tor_assert(source);
1782 :
1783 0 : if (tor_snprintf(buf, sizeof(buf),
1784 : "@downloaded-at %s\n"
1785 : "@source %s\n"
1786 : "%s%s%s", time_buf, escaped(source),
1787 : !general ? "@purpose " : "",
1788 0 : !general ? router_purpose_to_string(router_purpose) : "",
1789 : !general ? "\n" : "")<0)
1790 : return added;
1791 :
1792 0 : added = router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1793 : descriptor_digests, buf);
1794 0 : if (added && general)
1795 0 : control_event_boot_dir(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
1796 : count_loading_descriptors_progress());
1797 : return added;
1798 : }
1799 :
1800 : static int handle_response_fetch_certificate(dir_connection_t *,
1801 : const response_handler_args_t *);
1802 : static int handle_response_fetch_status_vote(dir_connection_t *,
1803 : const response_handler_args_t *);
1804 : static int handle_response_fetch_detached_signatures(dir_connection_t *,
1805 : const response_handler_args_t *);
1806 : static int handle_response_fetch_desc(dir_connection_t *,
1807 : const response_handler_args_t *);
1808 : static int handle_response_upload_dir(dir_connection_t *,
1809 : const response_handler_args_t *);
1810 : static int handle_response_upload_vote(dir_connection_t *,
1811 : const response_handler_args_t *);
1812 : static int handle_response_upload_signatures(dir_connection_t *,
1813 : const response_handler_args_t *);
1814 : static int handle_response_upload_hsdesc(dir_connection_t *,
1815 : const response_handler_args_t *);
1816 :
1817 : static int
1818 0 : dir_client_decompress_response_body(char **bodyp, size_t *bodylenp,
1819 : dir_connection_t *conn,
1820 : compress_method_t compression,
1821 : int anonymized_connection)
1822 : {
1823 0 : int rv = 0;
1824 0 : const char *body = *bodyp;
1825 0 : size_t body_len = *bodylenp;
1826 0 : int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
1827 0 : conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
1828 : conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
1829 :
1830 0 : int plausible = body_is_plausible(body, body_len, conn->base_.purpose);
1831 :
1832 0 : if (plausible && compression == NO_METHOD) {
1833 : return 0;
1834 : }
1835 :
1836 0 : int severity = LOG_DEBUG;
1837 0 : char *new_body = NULL;
1838 0 : size_t new_len = 0;
1839 0 : const char *description1, *description2;
1840 0 : int want_to_try_both = 0;
1841 0 : int tried_both = 0;
1842 0 : compress_method_t guessed = detect_compression_method(body, body_len);
1843 :
1844 0 : description1 = compression_method_get_human_name(compression);
1845 :
1846 0 : if (BUG(description1 == NULL))
1847 0 : description1 = compression_method_get_human_name(UNKNOWN_METHOD);
1848 :
1849 0 : if (guessed == UNKNOWN_METHOD && !plausible)
1850 : description2 = "confusing binary junk";
1851 : else
1852 0 : description2 = compression_method_get_human_name(guessed);
1853 :
1854 : /* Tell the user if we don't believe what we're told about compression.*/
1855 0 : want_to_try_both = (compression == UNKNOWN_METHOD ||
1856 0 : guessed != compression);
1857 0 : if (want_to_try_both) {
1858 0 : severity = LOG_PROTOCOL_WARN;
1859 : }
1860 :
1861 0 : tor_log(severity, LD_HTTP,
1862 : "HTTP body from %s was labeled as %s, "
1863 : "%s it seems to be %s.%s",
1864 0 : connection_describe(TO_CONN(conn)),
1865 : description1,
1866 : guessed != compression?"but":"and",
1867 : description2,
1868 0 : (compression>0 && guessed>0 && want_to_try_both)?
1869 : " Trying both.":"");
1870 :
1871 : /* Try declared compression first if we can.
1872 : * tor_compress_supports_method() also returns true for NO_METHOD.
1873 : * Ensure that the server is not sending us data compressed using a
1874 : * compression method that is not allowed for anonymous connections. */
1875 0 : if (anonymized_connection &&
1876 0 : ! allowed_anonymous_connection_compression_method(compression)) {
1877 0 : warn_disallowed_anonymous_compression_method(compression);
1878 0 : rv = -1;
1879 0 : goto done;
1880 : }
1881 :
1882 0 : if (tor_compress_supports_method(compression)) {
1883 0 : tor_uncompress(&new_body, &new_len, body, body_len, compression,
1884 : !allow_partial, LOG_PROTOCOL_WARN);
1885 0 : if (new_body) {
1886 : /* We succeeded with the declared compression method. Great! */
1887 0 : rv = 0;
1888 0 : goto done;
1889 : }
1890 : }
1891 :
1892 : /* Okay, if that didn't work, and we think that it was compressed
1893 : * differently, try that. */
1894 0 : if (anonymized_connection &&
1895 0 : ! allowed_anonymous_connection_compression_method(guessed)) {
1896 0 : warn_disallowed_anonymous_compression_method(guessed);
1897 0 : rv = -1;
1898 0 : goto done;
1899 : }
1900 :
1901 0 : if (tor_compress_supports_method(guessed) &&
1902 : compression != guessed) {
1903 0 : tor_uncompress(&new_body, &new_len, body, body_len, guessed,
1904 : !allow_partial, LOG_INFO);
1905 0 : tried_both = 1;
1906 : }
1907 : /* If we're pretty sure that we have a compressed directory, and
1908 : * we didn't manage to uncompress it, then warn and bail. */
1909 0 : if (!plausible && !new_body) {
1910 0 : log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
1911 : "Unable to decompress HTTP body (tried %s%s%s, on %s).",
1912 : description1,
1913 : tried_both?" and ":"",
1914 : tried_both?description2:"",
1915 : connection_describe(TO_CONN(conn)));
1916 0 : rv = -1;
1917 0 : goto done;
1918 : }
1919 :
1920 0 : done:
1921 0 : if (new_body) {
1922 0 : if (rv == 0) {
1923 : /* success! */
1924 0 : tor_free(*bodyp);
1925 0 : *bodyp = new_body;
1926 0 : *bodylenp = new_len;
1927 : } else {
1928 0 : tor_free(new_body);
1929 : }
1930 : }
1931 :
1932 : return rv;
1933 : }
1934 :
1935 : /**
1936 : * Total number of bytes downloaded of each directory purpose, when
1937 : * bootstrapped, and when not bootstrapped.
1938 : *
1939 : * (For example, the number of bytes downloaded of purpose p while
1940 : * not fully bootstrapped is total_dl[p][false].)
1941 : **/
1942 : static uint64_t total_dl[DIR_PURPOSE_MAX_][2];
1943 :
1944 : /**
1945 : * Heartbeat: dump a summary of how many bytes of which purpose we've
1946 : * downloaded, when bootstrapping and when not bootstrapping.
1947 : **/
1948 : void
1949 5 : dirclient_dump_total_dls(void)
1950 : {
1951 5 : const or_options_t *options = get_options();
1952 15 : for (int bootstrapped = 0; bootstrapped < 2; ++bootstrapped) {
1953 10 : smartlist_t *lines = smartlist_new();
1954 230 : for (int i=0; i < DIR_PURPOSE_MAX_; ++i) {
1955 220 : uint64_t n = total_dl[i][bootstrapped];
1956 220 : if (n == 0)
1957 220 : continue;
1958 0 : if (options->SafeLogging_ != SAFELOG_SCRUB_NONE &&
1959 0 : purpose_needs_anonymity(i, ROUTER_PURPOSE_GENERAL, NULL))
1960 0 : continue;
1961 0 : smartlist_add_asprintf(lines, "%"PRIu64" (%s)",
1962 : n, dir_conn_purpose_to_string(i));
1963 : }
1964 :
1965 10 : if (smartlist_len(lines) > 0) {
1966 0 : char *log_line = smartlist_join_strings(lines, "; ", 0, NULL);
1967 0 : log_notice(LD_NET, "While %sbootstrapping, fetched this many bytes: %s",
1968 : bootstrapped?"not ":"", log_line);
1969 0 : tor_free(log_line);
1970 :
1971 0 : SMARTLIST_FOREACH(lines, char *, s, tor_free(s));
1972 : }
1973 10 : smartlist_free(lines);
1974 : }
1975 5 : }
1976 :
1977 : /** We are a client, and we've finished reading the server's
1978 : * response. Parse it and act appropriately.
1979 : *
1980 : * If we're still happy with using this directory server in the future, return
1981 : * 0. Otherwise return -1; and the caller should consider trying the request
1982 : * again.
1983 : *
1984 : * The caller will take care of marking the connection for close.
1985 : */
1986 : static int
1987 0 : connection_dir_client_reached_eof(dir_connection_t *conn)
1988 : {
1989 0 : char *body = NULL;
1990 0 : char *headers = NULL;
1991 0 : char *reason = NULL;
1992 0 : size_t body_len = 0;
1993 0 : int status_code;
1994 0 : time_t date_header = 0;
1995 0 : long apparent_skew;
1996 0 : compress_method_t compression;
1997 0 : int skewed = 0;
1998 0 : int rv;
1999 0 : int allow_partial = (conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
2000 0 : conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO ||
2001 : conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
2002 0 : size_t received_bytes;
2003 0 : const int anonymized_connection =
2004 0 : purpose_needs_anonymity(conn->base_.purpose,
2005 0 : conn->router_purpose,
2006 0 : conn->requested_resource);
2007 :
2008 0 : received_bytes = connection_get_inbuf_len(TO_CONN(conn));
2009 :
2010 0 : log_debug(LD_DIR, "Downloaded %"TOR_PRIuSZ" bytes on connection of purpose "
2011 : "%s; bootstrap %d%%",
2012 : received_bytes,
2013 : dir_conn_purpose_to_string(conn->base_.purpose),
2014 : control_get_bootstrap_percent());
2015 : {
2016 0 : bool bootstrapped = control_get_bootstrap_percent() == 100;
2017 0 : total_dl[conn->base_.purpose][bootstrapped] += received_bytes;
2018 : }
2019 :
2020 0 : switch (connection_fetch_from_buf_http(TO_CONN(conn),
2021 : &headers, MAX_HEADERS_SIZE,
2022 : &body, &body_len, MAX_DIR_DL_SIZE,
2023 : allow_partial)) {
2024 0 : case -1: /* overflow */
2025 0 : log_warn(LD_PROTOCOL,
2026 : "'fetch' response too large (%s). Closing.",
2027 : connection_describe(TO_CONN(conn)));
2028 0 : return -1;
2029 0 : case 0:
2030 0 : log_info(LD_HTTP,
2031 : "'fetch' response not all here, but we're at eof. Closing.");
2032 0 : return -1;
2033 : /* case 1, fall through */
2034 : }
2035 :
2036 0 : if (parse_http_response(headers, &status_code, &date_header,
2037 : &compression, &reason) < 0) {
2038 0 : log_warn(LD_HTTP,"Unparseable headers (%s). Closing.",
2039 : connection_describe(TO_CONN(conn)));
2040 0 : rv = -1;
2041 0 : goto done;
2042 : }
2043 0 : if (!reason) reason = tor_strdup("[no reason given]");
2044 :
2045 0 : tor_log(LOG_DEBUG, LD_DIR,
2046 : "Received response on %s: %d %s "
2047 : "(purpose: %d, response size: %"TOR_PRIuSZ
2048 : #ifdef MEASUREMENTS_21206
2049 : ", data cells received: %d, data cells sent: %d"
2050 : #endif
2051 : ", compression: %d)",
2052 : connection_describe(TO_CONN(conn)),
2053 : status_code,
2054 0 : escaped(reason), conn->base_.purpose,
2055 : (received_bytes),
2056 : #ifdef MEASUREMENTS_21206
2057 : conn->data_cells_received, conn->data_cells_sent,
2058 : #endif
2059 : compression);
2060 :
2061 0 : if (conn->guard_state) {
2062 : /* we count the connection as successful once we can read from it. We do
2063 : * not, however, delay use of the circuit here, since it's just for a
2064 : * one-hop directory request. */
2065 : /* XXXXprop271 note that this will not do the right thing for other
2066 : * waiting circuits that would be triggered by this circuit becoming
2067 : * complete/usable. But that's ok, I think.
2068 : */
2069 0 : entry_guard_succeeded(&conn->guard_state);
2070 0 : circuit_guard_state_free(conn->guard_state);
2071 0 : conn->guard_state = NULL;
2072 : }
2073 :
2074 : /* now check if it's got any hints for us about our IP address. */
2075 0 : if (conn->dirconn_direct) {
2076 0 : char *guess = http_get_header(headers, X_ADDRESS_HEADER);
2077 0 : if (guess) {
2078 0 : tor_addr_t addr;
2079 0 : if (tor_addr_parse(&addr, guess) < 0) {
2080 0 : log_debug(LD_DIR, "Malformed X-Your-Address-Is header %s. Ignoring.",
2081 : escaped(guess));
2082 : } else {
2083 0 : relay_address_new_suggestion(&addr, &TO_CONN(conn)->addr, NULL);
2084 : }
2085 0 : tor_free(guess);
2086 : }
2087 : }
2088 :
2089 0 : if (date_header > 0) {
2090 : /* The date header was written very soon after we sent our request,
2091 : * so compute the skew as the difference between sending the request
2092 : * and the date header. (We used to check now-date_header, but that's
2093 : * inaccurate if we spend a lot of time downloading.)
2094 : */
2095 0 : apparent_skew = conn->base_.timestamp_last_write_allowed - date_header;
2096 0 : if (labs(apparent_skew)>ALLOW_DIRECTORY_TIME_SKEW) {
2097 0 : int trusted = router_digest_is_trusted_dir(conn->identity_digest);
2098 0 : clock_skew_warning(TO_CONN(conn), apparent_skew, trusted, LD_HTTP,
2099 : "directory", "DIRSERV");
2100 0 : skewed = 1; /* don't check the recommended-versions line */
2101 : } else {
2102 0 : log_debug(LD_HTTP, "Time on received directory is within tolerance; "
2103 : "we are %ld seconds skewed. (That's okay.)", apparent_skew);
2104 : }
2105 : }
2106 0 : (void) skewed; /* skewed isn't used yet. */
2107 :
2108 0 : if (status_code == 503) {
2109 0 : routerstatus_t *rs;
2110 0 : dir_server_t *ds;
2111 0 : const char *id_digest = conn->identity_digest;
2112 0 : log_info(LD_DIR,"Received http status code %d (%s) from server "
2113 : "%s. I'll try again soon.",
2114 : status_code, escaped(reason),
2115 : connection_describe_peer(TO_CONN(conn)));
2116 0 : time_t now = approx_time();
2117 0 : if ((rs = router_get_mutable_consensus_status_by_id(id_digest)))
2118 0 : rs->last_dir_503_at = now;
2119 0 : if ((ds = router_get_fallback_dirserver_by_digest(id_digest)))
2120 0 : ds->fake_status.last_dir_503_at = now;
2121 :
2122 0 : rv = -1;
2123 0 : goto done;
2124 : }
2125 :
2126 0 : if (dir_client_decompress_response_body(&body, &body_len,
2127 : conn, compression, anonymized_connection) < 0) {
2128 0 : rv = -1;
2129 0 : goto done;
2130 : }
2131 :
2132 0 : response_handler_args_t args;
2133 0 : memset(&args, 0, sizeof(args));
2134 0 : args.status_code = status_code;
2135 0 : args.reason = reason;
2136 0 : args.body = body;
2137 0 : args.body_len = body_len;
2138 0 : args.headers = headers;
2139 :
2140 0 : switch (conn->base_.purpose) {
2141 0 : case DIR_PURPOSE_FETCH_CONSENSUS:
2142 0 : rv = handle_response_fetch_consensus(conn, &args);
2143 0 : break;
2144 0 : case DIR_PURPOSE_FETCH_CERTIFICATE:
2145 0 : rv = handle_response_fetch_certificate(conn, &args);
2146 0 : break;
2147 0 : case DIR_PURPOSE_FETCH_STATUS_VOTE:
2148 0 : rv = handle_response_fetch_status_vote(conn, &args);
2149 0 : break;
2150 0 : case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
2151 0 : rv = handle_response_fetch_detached_signatures(conn, &args);
2152 0 : break;
2153 0 : case DIR_PURPOSE_FETCH_SERVERDESC:
2154 : case DIR_PURPOSE_FETCH_EXTRAINFO:
2155 0 : rv = handle_response_fetch_desc(conn, &args);
2156 0 : break;
2157 0 : case DIR_PURPOSE_FETCH_MICRODESC:
2158 0 : rv = handle_response_fetch_microdesc(conn, &args);
2159 0 : break;
2160 0 : case DIR_PURPOSE_UPLOAD_DIR:
2161 0 : rv = handle_response_upload_dir(conn, &args);
2162 0 : break;
2163 0 : case DIR_PURPOSE_UPLOAD_SIGNATURES:
2164 0 : rv = handle_response_upload_signatures(conn, &args);
2165 0 : break;
2166 0 : case DIR_PURPOSE_UPLOAD_VOTE:
2167 0 : rv = handle_response_upload_vote(conn, &args);
2168 0 : break;
2169 0 : case DIR_PURPOSE_UPLOAD_HSDESC:
2170 0 : rv = handle_response_upload_hsdesc(conn, &args);
2171 0 : break;
2172 0 : case DIR_PURPOSE_FETCH_HSDESC:
2173 0 : rv = handle_response_fetch_hsdesc_v3(conn, &args);
2174 0 : break;
2175 0 : default:
2176 0 : tor_assert_nonfatal_unreached();
2177 0 : rv = -1;
2178 0 : break;
2179 : }
2180 :
2181 0 : done:
2182 0 : tor_free(body);
2183 0 : tor_free(headers);
2184 0 : tor_free(reason);
2185 0 : return rv;
2186 : }
2187 :
2188 : /**
2189 : * Handler function: processes a response to a request for a networkstatus
2190 : * consensus document by checking the consensus, storing it, and marking
2191 : * router requests as reachable.
2192 : **/
2193 : STATIC int
2194 1 : handle_response_fetch_consensus(dir_connection_t *conn,
2195 : const response_handler_args_t *args)
2196 : {
2197 1 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_CONSENSUS);
2198 1 : const int status_code = args->status_code;
2199 1 : const char *body = args->body;
2200 1 : const size_t body_len = args->body_len;
2201 1 : const char *reason = args->reason;
2202 1 : const time_t now = approx_time();
2203 :
2204 1 : const char *consensus;
2205 1 : char *new_consensus = NULL;
2206 1 : const char *sourcename;
2207 :
2208 1 : int r;
2209 1 : const char *flavname = conn->requested_resource;
2210 1 : if (status_code != 200) {
2211 0 : int severity = (status_code == 304) ? LOG_INFO : LOG_WARN;
2212 0 : tor_log(severity, LD_DIR,
2213 : "Received http status code %d (%s) from server "
2214 : "%s while fetching consensus directory.",
2215 : status_code, escaped(reason),
2216 0 : connection_describe_peer(TO_CONN(conn)));
2217 0 : networkstatus_consensus_download_failed(status_code, flavname);
2218 0 : return -1;
2219 : }
2220 :
2221 1 : if (looks_like_a_consensus_diff(body, body_len)) {
2222 : /* First find our previous consensus. Maybe it's in ram, maybe not. */
2223 0 : cached_dir_t *cd = dirserv_get_consensus(flavname);
2224 0 : const char *consensus_body = NULL;
2225 0 : size_t consensus_body_len;
2226 0 : tor_mmap_t *mapped_consensus = NULL;
2227 0 : if (cd) {
2228 0 : consensus_body = cd->dir;
2229 0 : consensus_body_len = cd->dir_len;
2230 : } else {
2231 0 : mapped_consensus = networkstatus_map_cached_consensus(flavname);
2232 0 : if (mapped_consensus) {
2233 0 : consensus_body = mapped_consensus->data;
2234 0 : consensus_body_len = mapped_consensus->size;
2235 : }
2236 : }
2237 0 : if (!consensus_body) {
2238 0 : log_warn(LD_DIR, "Received a consensus diff, but we can't find "
2239 : "any %s-flavored consensus in our current cache.",flavname);
2240 0 : tor_munmap_file(mapped_consensus);
2241 0 : networkstatus_consensus_download_failed(0, flavname);
2242 : // XXXX if this happens too much, see below
2243 0 : return -1;
2244 : }
2245 :
2246 0 : new_consensus = consensus_diff_apply(consensus_body, consensus_body_len,
2247 : body, body_len);
2248 0 : tor_munmap_file(mapped_consensus);
2249 0 : if (new_consensus == NULL) {
2250 0 : log_warn(LD_DIR, "Could not apply consensus diff received from server "
2251 : "%s", connection_describe_peer(TO_CONN(conn)));
2252 : // XXXX If this happens too many times, we should maybe not use
2253 : // XXXX this directory for diffs any more?
2254 0 : networkstatus_consensus_download_failed(0, flavname);
2255 0 : return -1;
2256 : }
2257 0 : log_info(LD_DIR, "Applied consensus diff (size %d) from server "
2258 : "%s, resulting in a new consensus document (size %d).",
2259 : (int)body_len, connection_describe_peer(TO_CONN(conn)),
2260 : (int)strlen(new_consensus));
2261 0 : consensus = new_consensus;
2262 0 : sourcename = "generated based on a diff";
2263 : } else {
2264 1 : log_info(LD_DIR,"Received consensus directory (body size %d) from server "
2265 : "%s", (int)body_len, connection_describe_peer(TO_CONN(conn)));
2266 1 : consensus = body;
2267 1 : sourcename = "downloaded";
2268 : }
2269 :
2270 1 : if ((r=networkstatus_set_current_consensus(consensus,
2271 : strlen(consensus),
2272 : flavname, 0,
2273 1 : conn->identity_digest))<0) {
2274 0 : log_fn(r<-1?LOG_WARN:LOG_INFO, LD_DIR,
2275 : "Unable to load %s consensus directory %s from "
2276 : "server %s. I'll try again soon.",
2277 : flavname, sourcename,
2278 : connection_describe_peer(TO_CONN(conn)));
2279 0 : networkstatus_consensus_download_failed(0, flavname);
2280 0 : tor_free(new_consensus);
2281 0 : return -1;
2282 : }
2283 :
2284 : /* If we launched other fetches for this consensus, cancel them. */
2285 1 : connection_dir_close_consensus_fetches(conn, flavname);
2286 :
2287 : /* update the list of routers and directory guards */
2288 1 : routers_update_all_from_networkstatus(now, 3);
2289 1 : update_microdescs_from_networkstatus(now);
2290 1 : directory_info_has_arrived(now, 0, 0);
2291 :
2292 1 : if (authdir_mode_v3(get_options())) {
2293 0 : sr_act_post_consensus(
2294 0 : networkstatus_get_latest_consensus_by_flavor(FLAV_NS));
2295 : }
2296 1 : log_info(LD_DIR, "Successfully loaded consensus.");
2297 :
2298 1 : tor_free(new_consensus);
2299 1 : return 0;
2300 : }
2301 :
2302 : /**
2303 : * Handler function: processes a response to a request for one or more
2304 : * authority certificates
2305 : **/
2306 : static int
2307 0 : handle_response_fetch_certificate(dir_connection_t *conn,
2308 : const response_handler_args_t *args)
2309 : {
2310 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
2311 0 : const int status_code = args->status_code;
2312 0 : const char *reason = args->reason;
2313 0 : const char *body = args->body;
2314 0 : const size_t body_len = args->body_len;
2315 :
2316 0 : if (status_code != 200) {
2317 0 : log_warn(LD_DIR,
2318 : "Received http status code %d (%s) from server "
2319 : "%s while fetching \"/tor/keys/%s\".",
2320 : status_code, escaped(reason),
2321 : connection_describe_peer(TO_CONN(conn)),
2322 : conn->requested_resource);
2323 0 : connection_dir_download_cert_failed(conn, status_code);
2324 0 : return -1;
2325 : }
2326 0 : log_info(LD_DIR,"Received authority certificates (body size %d) from "
2327 : "server %s",
2328 : (int)body_len, connection_describe_peer(TO_CONN(conn)));
2329 :
2330 : /*
2331 : * Tell trusted_dirs_load_certs_from_string() whether it was by fp
2332 : * or fp-sk pair.
2333 : */
2334 0 : int src_code = -1;
2335 0 : if (!strcmpstart(conn->requested_resource, "fp/")) {
2336 : src_code = TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST;
2337 0 : } else if (!strcmpstart(conn->requested_resource, "fp-sk/")) {
2338 : src_code = TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST;
2339 : }
2340 :
2341 0 : if (src_code != -1) {
2342 0 : if (trusted_dirs_load_certs_from_string(body, src_code, 1,
2343 0 : conn->identity_digest)<0) {
2344 0 : log_warn(LD_DIR, "Unable to parse fetched certificates");
2345 : /* if we fetched more than one and only some failed, the successful
2346 : * ones got flushed to disk so it's safe to call this on them */
2347 0 : connection_dir_download_cert_failed(conn, status_code);
2348 : } else {
2349 0 : time_t now = approx_time();
2350 0 : directory_info_has_arrived(now, 0, 0);
2351 0 : log_info(LD_DIR, "Successfully loaded certificates from fetch.");
2352 : }
2353 : } else {
2354 0 : log_warn(LD_DIR,
2355 : "Couldn't figure out what to do with fetched certificates for "
2356 : "unknown resource %s",
2357 : conn->requested_resource);
2358 0 : connection_dir_download_cert_failed(conn, status_code);
2359 : }
2360 : return 0;
2361 : }
2362 :
2363 : /**
2364 : * Handler function: processes a response to a request for an authority's
2365 : * current networkstatus vote.
2366 : **/
2367 : static int
2368 0 : handle_response_fetch_status_vote(dir_connection_t *conn,
2369 : const response_handler_args_t *args)
2370 : {
2371 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE);
2372 0 : const int status_code = args->status_code;
2373 0 : const char *reason = args->reason;
2374 0 : const char *body = args->body;
2375 0 : const size_t body_len = args->body_len;
2376 :
2377 0 : const char *msg;
2378 0 : int st;
2379 0 : log_notice(LD_DIR,"Got votes (body size %d) from server %s",
2380 : (int)body_len, connection_describe_peer(TO_CONN(conn)));
2381 0 : if (status_code != 200) {
2382 0 : log_warn(LD_DIR,
2383 : "Received http status code %d (%s) from server "
2384 : "%s while fetching \"/tor/status-vote/next/%s.z\".",
2385 : status_code, escaped(reason),
2386 : connection_describe_peer(TO_CONN(conn)),
2387 : conn->requested_resource);
2388 0 : return -1;
2389 : }
2390 0 : dirvote_add_vote(body, 0, TO_CONN(conn)->address, &msg, &st);
2391 0 : if (st > 299) {
2392 0 : log_warn(LD_DIR, "Error adding retrieved vote: %s", msg);
2393 : } else {
2394 0 : log_info(LD_DIR, "Added vote(s) successfully [msg: %s]", msg);
2395 : }
2396 :
2397 : return 0;
2398 : }
2399 :
2400 : /**
2401 : * Handler function: processes a response to a request for the signatures
2402 : * that an authority knows about on a given consensus.
2403 : **/
2404 : static int
2405 0 : handle_response_fetch_detached_signatures(dir_connection_t *conn,
2406 : const response_handler_args_t *args)
2407 : {
2408 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES);
2409 0 : const int status_code = args->status_code;
2410 0 : const char *reason = args->reason;
2411 0 : const char *body = args->body;
2412 0 : const size_t body_len = args->body_len;
2413 :
2414 0 : const char *msg = NULL;
2415 0 : log_info(LD_DIR,"Got detached signatures (body size %d) from server %s",
2416 : (int)body_len,
2417 : connection_describe_peer(TO_CONN(conn)));
2418 0 : if (status_code != 200) {
2419 0 : log_warn(LD_DIR,
2420 : "Received http status code %d (%s) from server %s while fetching "
2421 : "\"/tor/status-vote/next/consensus-signatures.z\".",
2422 : status_code, escaped(reason),
2423 : connection_describe_peer(TO_CONN(conn)));
2424 0 : return -1;
2425 : }
2426 0 : if (dirvote_add_signatures(body, conn->base_.address, &msg)<0) {
2427 0 : log_warn(LD_DIR, "Problem adding detached signatures from %s: %s",
2428 : connection_describe_peer(TO_CONN(conn)),
2429 : msg?msg:"???");
2430 : }
2431 :
2432 : return 0;
2433 : }
2434 :
2435 : /**
2436 : * Handler function: processes a response to a request for a group of server
2437 : * descriptors or an extrainfo documents.
2438 : **/
2439 : static int
2440 0 : handle_response_fetch_desc(dir_connection_t *conn,
2441 : const response_handler_args_t *args)
2442 : {
2443 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
2444 : conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO);
2445 0 : const int status_code = args->status_code;
2446 0 : const char *reason = args->reason;
2447 0 : const char *body = args->body;
2448 0 : const size_t body_len = args->body_len;
2449 :
2450 0 : int was_ei = conn->base_.purpose == DIR_PURPOSE_FETCH_EXTRAINFO;
2451 0 : smartlist_t *which = NULL;
2452 0 : int n_asked_for = 0;
2453 0 : int descriptor_digests = conn->requested_resource &&
2454 0 : !strcmpstart(conn->requested_resource,"d/");
2455 0 : log_info(LD_DIR,"Received %s (body size %d) from server %s",
2456 : was_ei ? "extra server info" : "server info",
2457 : (int)body_len, connection_describe_peer(TO_CONN(conn)));
2458 0 : if (conn->requested_resource &&
2459 0 : (!strcmpstart(conn->requested_resource,"d/") ||
2460 0 : !strcmpstart(conn->requested_resource,"fp/"))) {
2461 0 : which = smartlist_new();
2462 0 : dir_split_resource_into_fingerprints(conn->requested_resource +
2463 0 : (descriptor_digests ? 2 : 3),
2464 : which, NULL, 0);
2465 0 : n_asked_for = smartlist_len(which);
2466 : }
2467 0 : if (status_code != 200) {
2468 0 : int dir_okay = status_code == 404 ||
2469 0 : (status_code == 400 && !strcmp(reason, "Servers unavailable.")) ||
2470 : status_code == 301;
2471 : /* 404 means that it didn't have them; no big deal.
2472 : * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead.
2473 : * 301 is considered as an error since Tor does not follow redirects,
2474 : * which means we failed to reach the server we wanted. */
2475 0 : log_fn(dir_okay ? LOG_INFO : LOG_WARN, LD_DIR,
2476 : "Received http status code %d (%s) from server %s "
2477 : "while fetching \"/tor/server/%s\". I'll try again soon.",
2478 : status_code, escaped(reason),
2479 : connection_describe_peer(TO_CONN(conn)),
2480 : conn->requested_resource);
2481 0 : if (!which) {
2482 0 : connection_dir_download_routerdesc_failed(conn);
2483 : } else {
2484 0 : dir_routerdesc_download_failed(which, status_code,
2485 0 : conn->router_purpose,
2486 : was_ei, descriptor_digests);
2487 0 : SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
2488 0 : smartlist_free(which);
2489 : }
2490 0 : return dir_okay ? 0 : -1;
2491 : }
2492 : /* Learn the routers, assuming we requested by fingerprint or "all"
2493 : * or "authority".
2494 : *
2495 : * We use "authority" to fetch our own descriptor for
2496 : * testing, and to fetch bridge descriptors for bootstrapping. Ignore
2497 : * the output of "authority" requests unless we are using bridges,
2498 : * since otherwise they'll be the response from reachability tests,
2499 : * and we don't really want to add that to our routerlist. */
2500 0 : if (which || (conn->requested_resource &&
2501 0 : (!strcmpstart(conn->requested_resource, "all") ||
2502 0 : (!strcmpstart(conn->requested_resource, "authority") &&
2503 0 : get_options()->UseBridges)))) {
2504 : /* as we learn from them, we remove them from 'which' */
2505 0 : if (was_ei) {
2506 0 : router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which,
2507 : descriptor_digests);
2508 : } else {
2509 : //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
2510 : // descriptor_digests, conn->router_purpose);
2511 0 : if (load_downloaded_routers(body, which, descriptor_digests,
2512 0 : conn->router_purpose,
2513 0 : conn->base_.address)) {
2514 0 : time_t now = approx_time();
2515 0 : directory_info_has_arrived(now, 0, 1);
2516 : }
2517 : }
2518 : }
2519 0 : if (which) { /* mark remaining ones as failed */
2520 0 : log_info(LD_DIR, "Received %d/%d %s requested from %s",
2521 : n_asked_for-smartlist_len(which), n_asked_for,
2522 : was_ei ? "extra-info documents" : "router descriptors",
2523 : connection_describe_peer(TO_CONN(conn)));
2524 0 : if (smartlist_len(which)) {
2525 0 : dir_routerdesc_download_failed(which, status_code,
2526 0 : conn->router_purpose,
2527 : was_ei, descriptor_digests);
2528 : }
2529 0 : SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
2530 0 : smartlist_free(which);
2531 : }
2532 :
2533 : return 0;
2534 : }
2535 :
2536 : /**
2537 : * Handler function: processes a response to a request for a group of
2538 : * microdescriptors
2539 : **/
2540 : STATIC int
2541 9 : handle_response_fetch_microdesc(dir_connection_t *conn,
2542 : const response_handler_args_t *args)
2543 : {
2544 9 : tor_assert(conn->base_.purpose == DIR_PURPOSE_FETCH_MICRODESC);
2545 9 : const int status_code = args->status_code;
2546 9 : const char *reason = args->reason;
2547 9 : const char *body = args->body;
2548 9 : const size_t body_len = args->body_len;
2549 :
2550 9 : smartlist_t *which = NULL;
2551 9 : log_info(LD_DIR,"Received answer to microdescriptor request (status %d, "
2552 : "body size %d) from server %s",
2553 : status_code, (int)body_len,
2554 : connection_describe_peer(TO_CONN(conn)));
2555 9 : tor_assert(conn->requested_resource &&
2556 : !strcmpstart(conn->requested_resource, "d/"));
2557 9 : tor_assert_nonfatal(!fast_mem_is_zero(conn->identity_digest, DIGEST_LEN));
2558 9 : which = smartlist_new();
2559 9 : dir_split_resource_into_fingerprints(conn->requested_resource+2,
2560 : which, NULL,
2561 : DSR_DIGEST256|DSR_BASE64);
2562 9 : if (status_code != 200) {
2563 9 : log_info(LD_DIR, "Received status code %d (%s) from server "
2564 : "%s while fetching \"/tor/micro/%s\". I'll try again "
2565 : "soon.",
2566 : status_code, escaped(reason),
2567 : connection_describe_peer(TO_CONN(conn)),
2568 : conn->requested_resource);
2569 9 : dir_microdesc_download_failed(which, status_code, conn->identity_digest);
2570 9 : SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
2571 9 : smartlist_free(which);
2572 9 : return 0;
2573 : } else {
2574 0 : smartlist_t *mds;
2575 0 : time_t now = approx_time();
2576 0 : mds = microdescs_add_to_cache(get_microdesc_cache(),
2577 : body, body+body_len, SAVED_NOWHERE, 0,
2578 : now, which);
2579 0 : if (smartlist_len(which)) {
2580 : /* Mark remaining ones as failed. */
2581 0 : dir_microdesc_download_failed(which, status_code, conn->identity_digest);
2582 : }
2583 0 : if (mds && smartlist_len(mds)) {
2584 0 : control_event_boot_dir(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
2585 : count_loading_descriptors_progress());
2586 0 : directory_info_has_arrived(now, 0, 1);
2587 : }
2588 0 : SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
2589 0 : smartlist_free(which);
2590 0 : smartlist_free(mds);
2591 : }
2592 :
2593 0 : return 0;
2594 : }
2595 :
2596 : /**
2597 : * Handler function: processes a response to a POST request to upload our
2598 : * router descriptor.
2599 : **/
2600 : static int
2601 0 : handle_response_upload_dir(dir_connection_t *conn,
2602 : const response_handler_args_t *args)
2603 : {
2604 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_UPLOAD_DIR);
2605 0 : const int status_code = args->status_code;
2606 0 : const char *reason = args->reason;
2607 0 : const char *headers = args->headers;
2608 :
2609 0 : switch (status_code) {
2610 0 : case 200: {
2611 0 : dir_server_t *ds =
2612 0 : router_get_trusteddirserver_by_digest(conn->identity_digest);
2613 0 : char *rejected_hdr = http_get_header(headers,
2614 : "X-Descriptor-Not-New: ");
2615 0 : if (rejected_hdr) {
2616 0 : if (!strcmp(rejected_hdr, "Yes")) {
2617 0 : log_info(LD_GENERAL,
2618 : "Authority '%s' declined our descriptor (not new)",
2619 : ds->nickname);
2620 : /* XXXX use this information; be sure to upload next one
2621 : * sooner. -NM */
2622 : /* XXXX++ On further thought, the task above implies that we're
2623 : * basing our regenerate-descriptor time on when we uploaded the
2624 : * last descriptor, not on the published time of the last
2625 : * descriptor. If those are different, that's a bad thing to
2626 : * do. -NM */
2627 : }
2628 0 : tor_free(rejected_hdr);
2629 : }
2630 0 : log_info(LD_GENERAL,"eof (status 200) after uploading server "
2631 : "descriptor: finished.");
2632 0 : control_event_server_status(
2633 : LOG_NOTICE, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
2634 0 : conn->base_.address, conn->base_.port);
2635 :
2636 0 : ds->has_accepted_serverdesc = 1;
2637 0 : if (directories_have_accepted_server_descriptor())
2638 0 : control_event_server_status(LOG_NOTICE, "GOOD_SERVER_DESCRIPTOR");
2639 : }
2640 : break;
2641 0 : case 400:
2642 0 : log_warn(LD_GENERAL,"http status 400 (%s) response from "
2643 : "dirserver %s. Please correct.",
2644 : escaped(reason), connection_describe_peer(TO_CONN(conn)));
2645 0 : control_event_server_status(LOG_WARN,
2646 : "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
2647 0 : conn->base_.address, conn->base_.port, escaped(reason));
2648 0 : break;
2649 0 : default:
2650 0 : log_warn(LD_GENERAL,
2651 : "HTTP status %d (%s) was unexpected while uploading "
2652 : "descriptor to server %s'. Possibly the server is "
2653 : "misconfigured?",
2654 : status_code, escaped(reason),
2655 : connection_describe_peer(TO_CONN(conn)));
2656 0 : break;
2657 : }
2658 : /* return 0 in all cases, since we don't want to mark any
2659 : * dirservers down just because they don't like us. */
2660 :
2661 0 : return 0;
2662 : }
2663 :
2664 : /**
2665 : * Handler function: processes a response to POST request to upload our
2666 : * own networkstatus vote.
2667 : **/
2668 : static int
2669 0 : handle_response_upload_vote(dir_connection_t *conn,
2670 : const response_handler_args_t *args)
2671 : {
2672 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_UPLOAD_VOTE);
2673 0 : const int status_code = args->status_code;
2674 0 : const char *reason = args->reason;
2675 :
2676 0 : switch (status_code) {
2677 0 : case 200: {
2678 0 : log_notice(LD_DIR,"Uploaded my vote to dirserver %s",
2679 : connection_describe_peer(TO_CONN(conn)));
2680 : }
2681 0 : break;
2682 0 : case 400:
2683 0 : log_warn(LD_DIR,"http status 400 (%s) response after uploading "
2684 : "vote to dirserver %s. Please correct.",
2685 : escaped(reason), connection_describe_peer(TO_CONN(conn)));
2686 0 : break;
2687 0 : default:
2688 0 : log_warn(LD_GENERAL,
2689 : "HTTP status %d (%s) was unexpected while uploading "
2690 : "vote to server %s.",
2691 : status_code, escaped(reason),
2692 : connection_describe_peer(TO_CONN(conn)));
2693 0 : break;
2694 : }
2695 : /* return 0 in all cases, since we don't want to mark any
2696 : * dirservers down just because they don't like us. */
2697 0 : return 0;
2698 : }
2699 :
2700 : /**
2701 : * Handler function: processes a response to POST request to upload our
2702 : * view of the signatures on the current consensus.
2703 : **/
2704 : static int
2705 0 : handle_response_upload_signatures(dir_connection_t *conn,
2706 : const response_handler_args_t *args)
2707 : {
2708 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_UPLOAD_SIGNATURES);
2709 0 : const int status_code = args->status_code;
2710 0 : const char *reason = args->reason;
2711 :
2712 0 : switch (status_code) {
2713 0 : case 200: {
2714 0 : log_notice(LD_DIR,"Uploaded signature(s) to dirserver %s",
2715 : connection_describe_peer(TO_CONN(conn)));
2716 : }
2717 0 : break;
2718 0 : case 400:
2719 0 : log_warn(LD_DIR,"http status 400 (%s) response after uploading "
2720 : "signatures to dirserver %s. Please correct.",
2721 : escaped(reason), connection_describe_peer(TO_CONN(conn)));
2722 0 : break;
2723 0 : default:
2724 0 : log_warn(LD_GENERAL,
2725 : "HTTP status %d (%s) was unexpected while uploading "
2726 : "signatures to server %s.",
2727 : status_code, escaped(reason),
2728 : connection_describe_peer(TO_CONN(conn)));
2729 0 : break;
2730 : }
2731 : /* return 0 in all cases, since we don't want to mark any
2732 : * dirservers down just because they don't like us. */
2733 :
2734 0 : return 0;
2735 : }
2736 :
2737 : /**
2738 : * Handler function: processes a response to a request for a v3 hidden service
2739 : * descriptor.
2740 : **/
2741 : STATIC int
2742 1 : handle_response_fetch_hsdesc_v3(dir_connection_t *conn,
2743 : const response_handler_args_t *args)
2744 : {
2745 1 : const int status_code = args->status_code;
2746 1 : const char *reason = args->reason;
2747 1 : const char *body = args->body;
2748 1 : const size_t body_len = args->body_len;
2749 :
2750 1 : tor_assert(conn->hs_ident);
2751 :
2752 1 : log_info(LD_REND,"Received v3 hsdesc (body size %d, status %d (%s))",
2753 : (int)body_len, status_code, escaped(reason));
2754 :
2755 1 : hs_client_dir_fetch_done(conn, reason, body, status_code);
2756 1 : return 0;
2757 : }
2758 :
2759 : /**
2760 : * Handler function: processes a response to a POST request to upload an
2761 : * hidden service descriptor.
2762 : **/
2763 : static int
2764 0 : handle_response_upload_hsdesc(dir_connection_t *conn,
2765 : const response_handler_args_t *args)
2766 : {
2767 0 : const int status_code = args->status_code;
2768 0 : const char *reason = args->reason;
2769 :
2770 0 : tor_assert(conn);
2771 0 : tor_assert(conn->base_.purpose == DIR_PURPOSE_UPLOAD_HSDESC);
2772 :
2773 0 : log_info(LD_REND, "Uploaded hidden service descriptor (status %d "
2774 : "(%s))",
2775 : status_code, escaped(reason));
2776 : /* For this directory response, it MUST have an hidden service identifier on
2777 : * this connection. */
2778 0 : tor_assert(conn->hs_ident);
2779 0 : switch (status_code) {
2780 0 : case 200:
2781 0 : log_info(LD_REND, "Uploading hidden service descriptor: "
2782 : "finished with status 200 (%s)", escaped(reason));
2783 0 : hs_control_desc_event_uploaded(conn->hs_ident, conn->identity_digest);
2784 0 : break;
2785 0 : case 400:
2786 0 : log_fn(LOG_PROTOCOL_WARN, LD_REND,
2787 : "Uploading hidden service descriptor: http "
2788 : "status 400 (%s) response from dirserver "
2789 : "%s. Malformed hidden service descriptor?",
2790 : escaped(reason), connection_describe_peer(TO_CONN(conn)));
2791 0 : hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest,
2792 : "UPLOAD_REJECTED");
2793 0 : break;
2794 0 : default:
2795 0 : log_warn(LD_REND, "Uploading hidden service descriptor: http "
2796 : "status %d (%s) response unexpected (server "
2797 : "%s').",
2798 : status_code, escaped(reason),
2799 : connection_describe_peer(TO_CONN(conn)));
2800 0 : hs_control_desc_event_failed(conn->hs_ident, conn->identity_digest,
2801 : "UNEXPECTED");
2802 0 : break;
2803 : }
2804 :
2805 0 : return 0;
2806 : }
2807 :
2808 : /** Called when a directory connection reaches EOF. */
2809 : int
2810 0 : connection_dir_reached_eof(dir_connection_t *conn)
2811 : {
2812 0 : int retval;
2813 0 : if (conn->base_.state != DIR_CONN_STATE_CLIENT_READING) {
2814 0 : log_info(LD_HTTP,"conn reached eof, not reading. [state=%d] Closing.",
2815 : conn->base_.state);
2816 0 : connection_close_immediate(TO_CONN(conn)); /* error: give up on flushing */
2817 0 : connection_mark_for_close(TO_CONN(conn));
2818 0 : return -1;
2819 : }
2820 :
2821 0 : retval = connection_dir_client_reached_eof(conn);
2822 0 : if (retval == 0) /* success */
2823 0 : conn->base_.state = DIR_CONN_STATE_CLIENT_FINISHED;
2824 0 : connection_mark_for_close(TO_CONN(conn));
2825 0 : return retval;
2826 : }
2827 : /** We are closing a dir connection: If <b>dir_conn</b> is a dir connection
2828 : * that tried to fetch an HS descriptor, check if it successfully fetched it,
2829 : * or if we need to try again. */
2830 : void
2831 8 : connection_dir_client_refetch_hsdesc_if_needed(dir_connection_t *dir_conn)
2832 : {
2833 8 : connection_t *conn = TO_CONN(dir_conn);
2834 :
2835 : /* Check for v3 rend desc fetch */
2836 8 : if (conn->purpose == DIR_PURPOSE_FETCH_HSDESC &&
2837 0 : dir_conn->hs_ident &&
2838 0 : !ed25519_public_key_is_zero(&dir_conn->hs_ident->identity_pk)) {
2839 0 : hs_client_refetch_hsdesc(&dir_conn->hs_ident->identity_pk);
2840 : }
2841 8 : }
2842 :
2843 : /** Array of compression methods to use (if supported) for requesting
2844 : * compressed data, ordered from best to worst. */
2845 : static compress_method_t client_meth_pref[] = {
2846 : LZMA_METHOD,
2847 : ZSTD_METHOD,
2848 : ZLIB_METHOD,
2849 : GZIP_METHOD,
2850 : NO_METHOD
2851 : };
2852 :
2853 : /** Array of allowed compression methods to use (if supported) when receiving a
2854 : * response from a request that was required to be anonymous. */
2855 : static compress_method_t client_meth_allowed_anonymous_compression[] = {
2856 : ZLIB_METHOD,
2857 : GZIP_METHOD,
2858 : NO_METHOD
2859 : };
2860 :
2861 : /** Return a newly allocated string containing a comma separated list of
2862 : * supported encodings. */
2863 : STATIC char *
2864 0 : accept_encoding_header(void)
2865 : {
2866 0 : smartlist_t *methods = smartlist_new();
2867 0 : char *header = NULL;
2868 0 : compress_method_t method;
2869 0 : unsigned i;
2870 :
2871 0 : for (i = 0; i < ARRAY_LENGTH(client_meth_pref); ++i) {
2872 0 : method = client_meth_pref[i];
2873 0 : if (tor_compress_supports_method(method))
2874 0 : smartlist_add(methods, (char *)compression_method_get_name(method));
2875 : }
2876 :
2877 0 : header = smartlist_join_strings(methods, ", ", 0, NULL);
2878 0 : smartlist_free(methods);
2879 :
2880 0 : return header;
2881 : }
2882 :
2883 : /** Check if the given compression method is allowed for a connection that is
2884 : * supposed to be anonymous. Returns 1 if the compression method is allowed,
2885 : * otherwise 0. */
2886 : STATIC int
2887 0 : allowed_anonymous_connection_compression_method(compress_method_t method)
2888 : {
2889 0 : unsigned u;
2890 :
2891 0 : for (u = 0; u < ARRAY_LENGTH(client_meth_allowed_anonymous_compression);
2892 0 : ++u) {
2893 0 : compress_method_t allowed_method =
2894 : client_meth_allowed_anonymous_compression[u];
2895 :
2896 0 : if (! tor_compress_supports_method(allowed_method))
2897 0 : continue;
2898 :
2899 0 : if (method == allowed_method)
2900 : return 1;
2901 : }
2902 :
2903 : return 0;
2904 : }
2905 :
2906 : /** Log a warning when a remote server has sent us a document using a
2907 : * compression method that is not allowed for anonymous directory requests. */
2908 : STATIC void
2909 0 : warn_disallowed_anonymous_compression_method(compress_method_t method)
2910 : {
2911 0 : log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
2912 : "Received a %s HTTP response, which is not "
2913 : "allowed for anonymous directory requests.",
2914 : compression_method_get_human_name(method));
2915 0 : }
2916 :
2917 : /* We just got a new consensus! If there are other in-progress requests
2918 : * for this consensus flavor (for example because we launched several in
2919 : * parallel), cancel them.
2920 : *
2921 : * We do this check here (not just in
2922 : * connection_ap_handshake_attach_circuit()) to handle the edge case where
2923 : * a consensus fetch begins and ends before some other one tries to attach to
2924 : * a circuit, in which case the other one won't know that we're all happy now.
2925 : *
2926 : * Don't mark the conn that just gave us the consensus -- otherwise we
2927 : * would end up double-marking it when it cleans itself up.
2928 : */
2929 : static void
2930 1 : connection_dir_close_consensus_fetches(dir_connection_t *except_this_one,
2931 : const char *resource)
2932 : {
2933 2 : smartlist_t *conns_to_close =
2934 1 : connection_dir_list_by_purpose_and_resource(DIR_PURPOSE_FETCH_CONSENSUS,
2935 : resource);
2936 1 : SMARTLIST_FOREACH_BEGIN(conns_to_close, dir_connection_t *, d) {
2937 0 : if (d == except_this_one)
2938 0 : continue;
2939 0 : log_info(LD_DIR, "Closing consensus fetch (to %s) since one "
2940 : "has just arrived.", connection_describe_peer(TO_CONN(d)));
2941 0 : connection_mark_for_close(TO_CONN(d));
2942 0 : } SMARTLIST_FOREACH_END(d);
2943 1 : smartlist_free(conns_to_close);
2944 1 : }
2945 : /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
2946 : * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
2947 : * either as descriptor digests or as identity digests based on
2948 : * <b>was_descriptor_digests</b>).
2949 : */
2950 : static void
2951 0 : dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
2952 : int router_purpose,
2953 : int was_extrainfo, int was_descriptor_digests)
2954 : {
2955 0 : char digest[DIGEST_LEN];
2956 0 : time_t now = time(NULL);
2957 0 : int server = dirclient_fetches_from_authorities(get_options());
2958 0 : if (!was_descriptor_digests) {
2959 0 : if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
2960 0 : tor_assert(!was_extrainfo);
2961 0 : connection_dir_retry_bridges(failed);
2962 : }
2963 0 : return; /* FFFF should implement for other-than-router-purpose someday */
2964 : }
2965 0 : SMARTLIST_FOREACH_BEGIN(failed, const char *, cp) {
2966 0 : download_status_t *dls = NULL;
2967 0 : if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp)) != DIGEST_LEN) {
2968 0 : log_warn(LD_BUG, "Malformed fingerprint in list: %s", escaped(cp));
2969 0 : continue;
2970 : }
2971 0 : if (was_extrainfo) {
2972 0 : signed_descriptor_t *sd =
2973 0 : router_get_by_extrainfo_digest(digest);
2974 0 : if (sd)
2975 0 : dls = &sd->ei_dl_status;
2976 : } else {
2977 0 : dls = router_get_dl_status_by_descriptor_digest(digest);
2978 : }
2979 0 : if (!dls)
2980 0 : continue;
2981 0 : download_status_increment_failure(dls, status_code, cp, server, now);
2982 0 : } SMARTLIST_FOREACH_END(cp);
2983 :
2984 : /* No need to relaunch descriptor downloads here: we already do it
2985 : * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
2986 : }
2987 :
2988 : /** Called when a connection to download microdescriptors from relay with
2989 : * <b>dir_id</b> has failed in whole or in part. <b>failed</b> is a list
2990 : * of every microdesc digest we didn't get. <b>status_code</b> is the http
2991 : * status code we received. Reschedule the microdesc downloads as
2992 : * appropriate. */
2993 : static void
2994 9 : dir_microdesc_download_failed(smartlist_t *failed,
2995 : int status_code, const char *dir_id)
2996 : {
2997 9 : networkstatus_t *consensus
2998 9 : = networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC);
2999 9 : routerstatus_t *rs;
3000 9 : download_status_t *dls;
3001 9 : time_t now = time(NULL);
3002 9 : int server = dirclient_fetches_from_authorities(get_options());
3003 :
3004 9 : if (! consensus)
3005 : return;
3006 :
3007 : /* We failed to fetch a microdescriptor from 'dir_id', note it down
3008 : * so that we don't try the same relay next time... */
3009 9 : microdesc_note_outdated_dirserver(dir_id);
3010 :
3011 9 : SMARTLIST_FOREACH_BEGIN(failed, const char *, d) {
3012 0 : rs = router_get_mutable_consensus_status_by_descriptor_digest(consensus,d);
3013 0 : if (!rs)
3014 0 : continue;
3015 0 : dls = &rs->dl_status;
3016 :
3017 : { /* Increment the failure count for this md fetch */
3018 0 : char buf[BASE64_DIGEST256_LEN+1];
3019 0 : digest256_to_base64(buf, d);
3020 0 : log_info(LD_DIR, "Failed to download md %s from %s",
3021 : buf, hex_str(dir_id, DIGEST_LEN));
3022 0 : download_status_increment_failure(dls, status_code, buf,
3023 : server, now);
3024 : }
3025 0 : } SMARTLIST_FOREACH_END(d);
3026 : }
|