1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2015, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
8 #include "circuitbuild.h"
10 #include "connection.h"
11 #include "connection_edge.h"
13 #include "directory.h"
16 #include "entrynodes.h"
19 #include "microdesc.h"
20 #include "networkstatus.h"
24 #include "rendclient.h"
25 #include "rendcommon.h"
26 #include "rendservice.h"
29 #include "routerlist.h"
30 #include "routerparse.h"
31 #include "routerset.h"
33 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
41 * \brief Code to send and fetch directories and router
42 * descriptors via HTTP. Directories use dirserv.c to generate the
43 * results; clients use routers.c to parse them.
46 /* In-points to directory.c:
48 * - directory_post_to_dirservers(), called from
49 * router_upload_dir_desc_to_dirservers() in router.c
50 * upload_service_descriptor() in rendservice.c
51 * - directory_get_from_dirserver(), called from
52 * rend_client_refetch_renddesc() in rendclient.c
53 * run_scheduled_events() in main.c
55 * - connection_dir_process_inbuf(), called from
56 * connection_process_inbuf() in connection.c
57 * - connection_dir_finished_flushing(), called from
58 * connection_finished_flushing() in connection.c
59 * - connection_dir_finished_connecting(), called from
60 * connection_finished_connecting() in connection.c
62 static void directory_send_command(dir_connection_t
*conn
,
63 int purpose
, int direct
, const char *resource
,
64 const char *payload
, size_t payload_len
,
65 time_t if_modified_since
);
66 static int directory_handle_command(dir_connection_t
*conn
);
67 static int body_is_plausible(const char *body
, size_t body_len
, int purpose
);
68 static char *http_get_header(const char *headers
, const char *which
);
69 static void http_set_address_origin(const char *headers
, connection_t
*conn
);
70 static void connection_dir_download_routerdesc_failed(dir_connection_t
*conn
);
71 static void connection_dir_bridge_routerdesc_failed(dir_connection_t
*conn
);
72 static void connection_dir_download_cert_failed(
73 dir_connection_t
*conn
, int status_code
);
74 static void connection_dir_retry_bridges(smartlist_t
*descs
);
75 static void dir_routerdesc_download_failed(smartlist_t
*failed
,
79 int was_descriptor_digests
);
80 static void dir_microdesc_download_failed(smartlist_t
*failed
,
82 static void note_client_request(int purpose
, int compressed
, size_t bytes
);
83 static int client_likes_consensus(networkstatus_t
*v
, const char *want_url
);
85 static void directory_initiate_command_rend(const tor_addr_t
*addr
,
90 uint8_t router_purpose
,
91 dir_indirection_t indirection
,
95 time_t if_modified_since
,
96 const rend_data_t
*rend_query
);
98 /********* START VARIABLES **********/
100 /** How far in the future do we allow a directory server to tell us it is
101 * before deciding that one of us has the wrong time? */
102 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
104 #define X_ADDRESS_HEADER "X-Your-Address-Is: "
106 /** HTTP cache control: how long do we tell proxies they can cache each
107 * kind of document we serve? */
108 #define FULL_DIR_CACHE_LIFETIME (60*60)
109 #define RUNNINGROUTERS_CACHE_LIFETIME (20*60)
110 #define DIRPORTFRONTPAGE_CACHE_LIFETIME (20*60)
111 #define NETWORKSTATUS_CACHE_LIFETIME (5*60)
112 #define ROUTERDESC_CACHE_LIFETIME (30*60)
113 #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
114 #define ROBOTS_CACHE_LIFETIME (24*60*60)
115 #define MICRODESC_CACHE_LIFETIME (48*60*60)
117 /********* END VARIABLES ************/
119 /** Return true iff the directory purpose <b>dir_purpose</b> (and if it's
120 * fetching descriptors, it's fetching them for <b>router_purpose</b>)
121 * must use an anonymous connection to a directory. */
123 purpose_needs_anonymity(uint8_t dir_purpose
, uint8_t router_purpose
)
125 if (get_options()->AllDirActionsPrivate
)
127 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
)
128 return 1; /* if no circuits yet, this might break bootstrapping, but it's
129 * needed to be safe. */
130 if (dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
||
131 dir_purpose
== DIR_PURPOSE_UPLOAD_VOTE
||
132 dir_purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
||
133 dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
134 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
||
135 dir_purpose
== DIR_PURPOSE_FETCH_CONSENSUS
||
136 dir_purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
||
137 dir_purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
138 dir_purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
||
139 dir_purpose
== DIR_PURPOSE_FETCH_MICRODESC
)
144 /** Return a newly allocated string describing <b>auth</b>. Only describes
145 * authority features. */
147 authdir_type_to_string(dirinfo_type_t auth
)
150 smartlist_t
*lst
= smartlist_new();
151 if (auth
& V3_DIRINFO
)
152 smartlist_add(lst
, (void*)"V3");
153 if (auth
& BRIDGE_DIRINFO
)
154 smartlist_add(lst
, (void*)"Bridge");
155 if (smartlist_len(lst
)) {
156 result
= smartlist_join_strings(lst
, ", ", 0, NULL
);
158 result
= tor_strdup("[Not an authority]");
164 /** Return a string describing a given directory connection purpose. */
166 dir_conn_purpose_to_string(int purpose
)
170 case DIR_PURPOSE_UPLOAD_DIR
:
171 return "server descriptor upload";
172 case DIR_PURPOSE_UPLOAD_VOTE
:
173 return "server vote upload";
174 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
175 return "consensus signature upload";
176 case DIR_PURPOSE_FETCH_SERVERDESC
:
177 return "server descriptor fetch";
178 case DIR_PURPOSE_FETCH_EXTRAINFO
:
179 return "extra-info fetch";
180 case DIR_PURPOSE_FETCH_CONSENSUS
:
181 return "consensus network-status fetch";
182 case DIR_PURPOSE_FETCH_CERTIFICATE
:
183 return "authority cert fetch";
184 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
185 return "status vote fetch";
186 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
187 return "consensus signature fetch";
188 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
189 return "hidden-service v2 descriptor fetch";
190 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
191 return "hidden-service v2 descriptor upload";
192 case DIR_PURPOSE_FETCH_MICRODESC
:
193 return "microdescriptor fetch";
196 log_warn(LD_BUG
, "Called with unknown purpose %d", purpose
);
200 /** Return the requisite directory information types. */
201 STATIC dirinfo_type_t
202 dir_fetch_type(int dir_purpose
, int router_purpose
, const char *resource
)
205 switch (dir_purpose
) {
206 case DIR_PURPOSE_FETCH_EXTRAINFO
:
207 type
= EXTRAINFO_DIRINFO
;
208 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
)
209 type
|= BRIDGE_DIRINFO
;
213 case DIR_PURPOSE_FETCH_SERVERDESC
:
214 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
)
215 type
= BRIDGE_DIRINFO
;
219 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
220 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
221 case DIR_PURPOSE_FETCH_CERTIFICATE
:
224 case DIR_PURPOSE_FETCH_CONSENSUS
:
226 if (resource
&& !strcmp(resource
, "microdesc"))
227 type
|= MICRODESC_DIRINFO
;
229 case DIR_PURPOSE_FETCH_MICRODESC
:
230 type
= MICRODESC_DIRINFO
;
233 log_warn(LD_BUG
, "Unexpected purpose %d", (int)dir_purpose
);
240 /** Return true iff <b>identity_digest</b> is the digest of a router which
241 * says that it caches extrainfos. (If <b>is_authority</b> we always
242 * believe that to be true.) */
244 router_supports_extrainfo(const char *identity_digest
, int is_authority
)
246 const node_t
*node
= node_get_by_id(identity_digest
);
248 if (node
&& node
->ri
) {
249 if (node
->ri
->caches_extra_info
)
258 /** Return true iff any trusted directory authority has accepted our
261 * We consider any authority sufficient because waiting for all of
262 * them means it never happens while any authority is down; we don't
263 * go for something more complex in the middle (like \>1/3 or \>1/2 or
264 * \>=1/2) because that doesn't seem necessary yet.
267 directories_have_accepted_server_descriptor(void)
269 const smartlist_t
*servers
= router_get_trusted_dir_servers();
270 const or_options_t
*options
= get_options();
271 SMARTLIST_FOREACH(servers
, dir_server_t
*, d
, {
272 if ((d
->type
& options
->PublishServerDescriptor_
) &&
273 d
->has_accepted_serverdesc
) {
280 /** Start a connection to every suitable directory authority, using
281 * connection purpose <b>dir_purpose</b> and uploading <b>payload</b>
282 * (of length <b>payload_len</b>). The dir_purpose should be one of
283 * 'DIR_PURPOSE_UPLOAD_{DIR|VOTE|SIGNATURES}'.
285 * <b>router_purpose</b> describes the type of descriptor we're
286 * publishing, if we're publishing a descriptor -- e.g. general or bridge.
288 * <b>type</b> specifies what sort of dir authorities (V3,
289 * BRIDGE, etc) we should upload to.
291 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
292 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
293 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
294 * to all authorities, and the extra-info document to all authorities that
298 directory_post_to_dirservers(uint8_t dir_purpose
, uint8_t router_purpose
,
301 size_t payload_len
, size_t extrainfo_len
)
303 const or_options_t
*options
= get_options();
304 dir_indirection_t indirection
;
305 const smartlist_t
*dirservers
= router_get_trusted_dir_servers();
307 const int exclude_self
= (dir_purpose
== DIR_PURPOSE_UPLOAD_VOTE
||
308 dir_purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
);
309 tor_assert(dirservers
);
310 /* This tries dirservers which we believe to be down, but ultimately, that's
311 * harmless, and we may as well err on the side of getting things uploaded.
313 SMARTLIST_FOREACH_BEGIN(dirservers
, dir_server_t
*, ds
) {
314 routerstatus_t
*rs
= &(ds
->fake_status
);
315 size_t upload_len
= payload_len
;
318 if ((type
& ds
->type
) == 0)
321 if (exclude_self
&& router_digest_is_me(ds
->digest
)) {
322 /* we don't upload to ourselves, but at least there's now at least
323 * one authority of this type that has what we wanted to upload. */
328 if (options
->StrictNodes
&&
329 routerset_contains_routerstatus(options
->ExcludeNodes
, rs
, -1)) {
330 log_warn(LD_DIR
, "Wanted to contact authority '%s' for %s, but "
331 "it's in our ExcludedNodes list and StrictNodes is set. "
334 dir_conn_purpose_to_string(dir_purpose
));
338 found
= 1; /* at least one authority of this type was listed */
339 if (dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
)
340 ds
->has_accepted_serverdesc
= 0;
342 if (extrainfo_len
&& router_supports_extrainfo(ds
->digest
, 1)) {
343 upload_len
+= extrainfo_len
;
344 log_info(LD_DIR
, "Uploading an extrainfo too (length %d)",
345 (int) extrainfo_len
);
347 tor_addr_from_ipv4h(&ds_addr
, ds
->addr
);
348 if (purpose_needs_anonymity(dir_purpose
, router_purpose
)) {
349 indirection
= DIRIND_ANONYMOUS
;
350 } else if (!fascist_firewall_allows_address_dir(&ds_addr
,ds
->dir_port
)) {
351 if (fascist_firewall_allows_address_or(&ds_addr
,ds
->or_port
))
352 indirection
= DIRIND_ONEHOP
;
354 indirection
= DIRIND_ANONYMOUS
;
356 indirection
= DIRIND_DIRECT_CONN
;
358 directory_initiate_command_routerstatus(rs
, dir_purpose
,
361 NULL
, payload
, upload_len
, 0);
362 } SMARTLIST_FOREACH_END(ds
);
364 char *s
= authdir_type_to_string(type
);
365 log_warn(LD_DIR
, "Publishing server descriptor to directory authorities "
366 "of type '%s', but no authorities of that type listed!", s
);
371 /** Return true iff, according to the values in <b>options</b>, we should be
372 * using directory guards for direct downloads of directory information. */
374 should_use_directory_guards(const or_options_t
*options
)
376 /* Public (non-bridge) servers never use directory guards. */
377 if (public_server_mode(options
))
379 /* If guards are disabled, or directory guards are disabled, we can't
380 * use directory guards.
382 if (!options
->UseEntryGuards
|| !options
->UseEntryGuardsAsDirGuards
)
384 /* If we're configured to fetch directory info aggressively or of a
385 * nonstandard type, don't use directory guards. */
386 if (options
->DownloadExtraInfo
|| options
->FetchDirInfoEarly
||
387 options
->FetchDirInfoExtraEarly
|| options
->FetchUselessDescriptors
)
392 /** Pick an unconstrained directory server from among our guards, the latest
393 * networkstatus, or the fallback dirservers, for use in downloading
394 * information of type <b>type</b>, and return its routerstatus. */
395 static const routerstatus_t
*
396 directory_pick_generic_dirserver(dirinfo_type_t type
, int pds_flags
,
399 const routerstatus_t
*rs
= NULL
;
400 const or_options_t
*options
= get_options();
402 if (options
->UseBridges
)
403 log_warn(LD_BUG
, "Called when we have UseBridges set.");
405 if (should_use_directory_guards(options
)) {
406 const node_t
*node
= choose_random_dirguard(type
);
410 /* anybody with a non-zero dirport will do */
411 rs
= router_pick_directory_server(type
, pds_flags
);
414 log_info(LD_DIR
, "No router found for %s; falling back to "
415 "dirserver list.", dir_conn_purpose_to_string(dir_purpose
));
416 rs
= router_pick_fallback_dirserver(type
, pds_flags
);
422 /** Start a connection to a random running directory server, using
423 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
424 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
425 * Use <b>pds_flags</b> as arguments to router_pick_directory_server()
426 * or router_pick_trusteddirserver().
428 MOCK_IMPL(void, directory_get_from_dirserver
, (
430 uint8_t router_purpose
,
431 const char *resource
,
433 download_want_authority_t want_authority
))
435 const routerstatus_t
*rs
= NULL
;
436 const or_options_t
*options
= get_options();
437 int prefer_authority
= (directory_fetches_from_authorities(options
)
438 || want_authority
== DL_WANT_AUTHORITY
);
439 int require_authority
= 0;
440 int get_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
);
441 dirinfo_type_t type
= dir_fetch_type(dir_purpose
, router_purpose
, resource
);
442 time_t if_modified_since
= 0;
444 if (type
== NO_DIRINFO
)
447 if (dir_purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
451 flav
= networkstatus_parse_flavor_name(resource
);
453 /* DEFAULT_IF_MODIFIED_SINCE_DELAY is 1/20 of the default consensus
456 #define DEFAULT_IF_MODIFIED_SINCE_DELAY (180)
458 /* IF we have a parsed consensus of this type, we can do an
459 * if-modified-time based on it. */
460 v
= networkstatus_get_latest_consensus_by_flavor(flav
);
462 /* In networks with particularly short V3AuthVotingIntervals,
463 * ask for the consensus if it's been modified since half the
464 * V3AuthVotingInterval of the most recent consensus. */
465 time_t ims_delay
= DEFAULT_IF_MODIFIED_SINCE_DELAY
;
466 if (v
->fresh_until
> v
->valid_after
467 && ims_delay
> (v
->fresh_until
- v
->valid_after
)/2) {
468 ims_delay
= (v
->fresh_until
- v
->valid_after
)/2;
470 if_modified_since
= v
->valid_after
+ ims_delay
;
473 /* Otherwise it might be a consensus we don't parse, but which we
474 * do cache. Look at the cached copy, perhaps. */
475 cached_dir_t
*cd
= dirserv_get_consensus(resource
);
476 /* We have no method of determining the voting interval from an
477 * unparsed consensus, so we use the default. */
479 if_modified_since
= cd
->published
+ DEFAULT_IF_MODIFIED_SINCE_DELAY
;
483 if (!options
->FetchServerDescriptors
)
487 if (options
->UseBridges
&& !(type
& BRIDGE_DIRINFO
)) {
488 /* We want to ask a running bridge for which we have a descriptor.
490 * When we ask choose_random_entry() for a bridge, we specify what
491 * sort of dir fetch we'll be doing, so it won't return a bridge
492 * that can't answer our question.
494 /* XXX024 Not all bridges handle conditional consensus downloading,
495 * so, for now, never assume the server supports that. -PP */
496 const node_t
*node
= choose_random_dirguard(type
);
497 if (node
&& node
->ri
) {
498 /* every bridge has a routerinfo. */
500 routerinfo_t
*ri
= node
->ri
;
501 node_get_addr(node
, &addr
);
502 directory_initiate_command(&addr
,
503 ri
->or_port
, 0/*no dirport*/,
504 ri
->cache_info
.identity_digest
,
508 resource
, NULL
, 0, if_modified_since
);
510 log_notice(LD_DIR
, "Ignoring directory request, since no bridge "
511 "nodes are available yet.");
514 if (prefer_authority
|| (type
& BRIDGE_DIRINFO
)) {
515 /* only ask authdirservers, and don't ask myself */
516 rs
= router_pick_trusteddirserver(type
, pds_flags
);
517 if (rs
== NULL
&& (pds_flags
& (PDS_NO_EXISTING_SERVERDESC_FETCH
|
518 PDS_NO_EXISTING_MICRODESC_FETCH
))) {
519 /* We don't want to fetch from any authorities that we're currently
520 * fetching server descriptors from, and we got no match. Did we
521 * get no match because all the authorities have connections
522 * fetching server descriptors (in which case we should just
523 * return,) or because all the authorities are down or on fire or
524 * unreachable or something (in which case we should go on with
525 * our fallback code)? */
526 pds_flags
&= ~(PDS_NO_EXISTING_SERVERDESC_FETCH
|
527 PDS_NO_EXISTING_MICRODESC_FETCH
);
528 rs
= router_pick_trusteddirserver(type
, pds_flags
);
530 log_debug(LD_DIR
, "Deferring serverdesc fetch: all authorities "
535 if (rs
== NULL
&& require_authority
) {
536 log_info(LD_DIR
, "No authorities were available for %s: will try "
537 "later.", dir_conn_purpose_to_string(dir_purpose
));
541 if (!rs
&& !(type
& BRIDGE_DIRINFO
)) {
543 rs
= directory_pick_generic_dirserver(type
, pds_flags
,
546 get_via_tor
= 1; /* last resort: try routing it via Tor */
552 /* Never use fascistfirewall; we're going via Tor. */
553 pds_flags
|= PDS_IGNORE_FASCISTFIREWALL
;
554 rs
= router_pick_directory_server(type
, pds_flags
);
557 /* If we have any hope of building an indirect conn, we know some router
558 * descriptors. If (rs==NULL), we can't build circuits anyway, so
559 * there's no point in falling back to the authorities in this case. */
561 const dir_indirection_t indirection
=
562 get_via_tor
? DIRIND_ANONYMOUS
: DIRIND_ONEHOP
;
563 directory_initiate_command_routerstatus(rs
, dir_purpose
,
570 "While fetching directory info, "
571 "no running dirservers known. Will try again later. "
572 "(purpose %d)", dir_purpose
);
573 if (!purpose_needs_anonymity(dir_purpose
, router_purpose
)) {
574 /* remember we tried them all and failed. */
575 directory_all_unreachable(time(NULL
));
580 /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
581 * directory authority other than ourself. Only for use by authorities when
582 * searching for missing information while voting. */
584 directory_get_from_all_authorities(uint8_t dir_purpose
,
585 uint8_t router_purpose
,
586 const char *resource
)
588 tor_assert(dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
589 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
);
591 SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
592 dir_server_t
*, ds
) {
594 if (router_digest_is_me(ds
->digest
))
596 if (!(ds
->type
& V3_DIRINFO
))
598 rs
= &ds
->fake_status
;
599 directory_initiate_command_routerstatus(rs
, dir_purpose
, router_purpose
,
600 DIRIND_ONEHOP
, resource
, NULL
,
602 } SMARTLIST_FOREACH_END(ds
);
605 /** Return true iff <b>ind</b> requires a multihop circuit. */
607 dirind_is_anon(dir_indirection_t ind
)
609 return ind
== DIRIND_ANON_DIRPORT
|| ind
== DIRIND_ANONYMOUS
;
612 /** Same as directory_initiate_command_routerstatus(), but accepts
613 * rendezvous data to fetch a hidden service descriptor. */
615 directory_initiate_command_routerstatus_rend(const routerstatus_t
*status
,
617 uint8_t router_purpose
,
618 dir_indirection_t indirection
,
619 const char *resource
,
622 time_t if_modified_since
,
623 const rend_data_t
*rend_query
)
625 const or_options_t
*options
= get_options();
628 const int anonymized_connection
= dirind_is_anon(indirection
);
629 node
= node_get_by_id(status
->identity_digest
);
631 if (!node
&& anonymized_connection
) {
632 log_info(LD_DIR
, "Not sending anonymized request to directory '%s'; we "
633 "don't have its router descriptor.",
634 routerstatus_describe(status
));
637 tor_addr_from_ipv4h(&addr
, status
->addr
);
639 if (options
->ExcludeNodes
&& options
->StrictNodes
&&
640 routerset_contains_routerstatus(options
->ExcludeNodes
, status
, -1)) {
641 log_warn(LD_DIR
, "Wanted to contact directory mirror %s for %s, but "
642 "it's in our ExcludedNodes list and StrictNodes is set. "
643 "Skipping. This choice might make your Tor not work.",
644 routerstatus_describe(status
),
645 dir_conn_purpose_to_string(dir_purpose
));
649 directory_initiate_command_rend(&addr
,
650 status
->or_port
, status
->dir_port
,
651 status
->identity_digest
,
652 dir_purpose
, router_purpose
,
653 indirection
, resource
,
654 payload
, payload_len
, if_modified_since
,
658 /** Launch a new connection to the directory server <b>status</b> to
659 * upload or download a server or rendezvous
660 * descriptor. <b>dir_purpose</b> determines what
661 * kind of directory connection we're launching, and must be one of
662 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC_V2}. <b>router_purpose</b>
663 * specifies the descriptor purposes we have in mind (currently only
664 * used for FETCH_DIR).
666 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
667 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
669 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
673 directory_initiate_command_routerstatus(const routerstatus_t
*status
,
675 uint8_t router_purpose
,
676 dir_indirection_t indirection
,
677 const char *resource
,
680 time_t if_modified_since
)
682 directory_initiate_command_routerstatus_rend(status
, dir_purpose
,
684 indirection
, resource
,
685 payload
, payload_len
,
686 if_modified_since
, NULL
);
689 /** Return true iff <b>conn</b> is the client side of a directory connection
690 * we launched to ourself in order to determine the reachability of our
693 directory_conn_is_self_reachability_test(dir_connection_t
*conn
)
695 if (conn
->requested_resource
&&
696 !strcmpstart(conn
->requested_resource
,"authority")) {
697 const routerinfo_t
*me
= router_get_my_routerinfo();
699 router_digest_is_me(conn
->identity_digest
) &&
700 tor_addr_eq_ipv4h(&conn
->base_
.addr
, me
->addr
) && /*XXXX prop 118*/
701 me
->dir_port
== conn
->base_
.port
)
707 /** Called when we are unable to complete the client's request to a directory
708 * server due to a network error: Mark the router as down and try again if
712 connection_dir_request_failed(dir_connection_t
*conn
)
714 if (directory_conn_is_self_reachability_test(conn
)) {
715 return; /* this was a test fetch. don't retry. */
717 if (!entry_list_is_constrained(get_options()))
718 router_set_status(conn
->identity_digest
, 0); /* don't try him again */
719 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
720 conn
->base_
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
721 log_info(LD_DIR
, "Giving up on serverdesc/extrainfo fetch from "
722 "directory server at '%s'; retrying",
723 conn
->base_
.address
);
724 if (conn
->router_purpose
== ROUTER_PURPOSE_BRIDGE
)
725 connection_dir_bridge_routerdesc_failed(conn
);
726 connection_dir_download_routerdesc_failed(conn
);
727 } else if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
728 if (conn
->requested_resource
)
729 networkstatus_consensus_download_failed(0, conn
->requested_resource
);
730 } else if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
731 log_info(LD_DIR
, "Giving up on certificate fetch from directory server "
733 conn
->base_
.address
);
734 connection_dir_download_cert_failed(conn
, 0);
735 } else if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
736 log_info(LD_DIR
, "Giving up downloading detached signatures from '%s'",
737 conn
->base_
.address
);
738 } else if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
739 log_info(LD_DIR
, "Giving up downloading votes from '%s'",
740 conn
->base_
.address
);
741 } else if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_MICRODESC
) {
742 log_info(LD_DIR
, "Giving up on downloading microdescriptors from "
743 "directory server at '%s'; will retry", conn
->base_
.address
);
744 connection_dir_download_routerdesc_failed(conn
);
748 /** Helper: Attempt to fetch directly the descriptors of each bridge
749 * listed in <b>failed</b>.
752 connection_dir_retry_bridges(smartlist_t
*descs
)
754 char digest
[DIGEST_LEN
];
755 SMARTLIST_FOREACH(descs
, const char *, cp
,
757 if (base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
))<0) {
758 log_warn(LD_BUG
, "Malformed fingerprint in list: %s",
762 retry_bridge_descriptor_fetch_directly(digest
);
766 /** Called when an attempt to download one or more router descriptors
767 * or extra-info documents on connection <b>conn</b> failed.
770 connection_dir_download_routerdesc_failed(dir_connection_t
*conn
)
772 /* No need to increment the failure count for routerdescs, since
773 * it's not their fault. */
775 /* No need to relaunch descriptor downloads here: we already do it
776 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
777 tor_assert(conn
->base_
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
778 conn
->base_
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
||
779 conn
->base_
.purpose
== DIR_PURPOSE_FETCH_MICRODESC
);
784 /** Called when an attempt to download a bridge's routerdesc from
785 * one of the authorities failed due to a network error. If
786 * possible attempt to download descriptors from the bridge directly.
789 connection_dir_bridge_routerdesc_failed(dir_connection_t
*conn
)
791 smartlist_t
*which
= NULL
;
793 /* Requests for bridge descriptors are in the form 'fp/', so ignore
795 if (!conn
->requested_resource
|| strcmpstart(conn
->requested_resource
,"fp/"))
798 which
= smartlist_new();
799 dir_split_resource_into_fingerprints(conn
->requested_resource
803 tor_assert(conn
->base_
.purpose
!= DIR_PURPOSE_FETCH_EXTRAINFO
);
804 if (smartlist_len(which
)) {
805 connection_dir_retry_bridges(which
);
806 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
808 smartlist_free(which
);
811 /** Called when an attempt to fetch a certificate fails. */
813 connection_dir_download_cert_failed(dir_connection_t
*conn
, int status
)
815 const char *fp_pfx
= "fp/";
816 const char *fpsk_pfx
= "fp-sk/";
818 tor_assert(conn
->base_
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
);
820 if (!conn
->requested_resource
)
822 failed
= smartlist_new();
824 * We have two cases download by fingerprint (resource starts
825 * with "fp/") or download by fingerprint/signing key pair
826 * (resource starts with "fp-sk/").
828 if (!strcmpstart(conn
->requested_resource
, fp_pfx
)) {
829 /* Download by fingerprint case */
830 dir_split_resource_into_fingerprints(conn
->requested_resource
+
832 failed
, NULL
, DSR_HEX
);
833 SMARTLIST_FOREACH_BEGIN(failed
, char *, cp
) {
834 /* Null signing key digest indicates download by fp only */
835 authority_cert_dl_failed(cp
, NULL
, status
);
837 } SMARTLIST_FOREACH_END(cp
);
838 } else if (!strcmpstart(conn
->requested_resource
, fpsk_pfx
)) {
839 /* Download by (fp,sk) pairs */
840 dir_split_resource_into_fingerprint_pairs(conn
->requested_resource
+
841 strlen(fpsk_pfx
), failed
);
842 SMARTLIST_FOREACH_BEGIN(failed
, fp_pair_t
*, cp
) {
843 authority_cert_dl_failed(cp
->first
, cp
->second
, status
);
845 } SMARTLIST_FOREACH_END(cp
);
848 "Don't know what to do with failure for cert fetch %s",
849 conn
->requested_resource
);
852 smartlist_free(failed
);
854 update_certificate_downloads(time(NULL
));
857 /** Evaluate the situation and decide if we should use an encrypted
858 * "begindir-style" connection for this directory request.
859 * 1) If or_port is 0, or it's a direct conn and or_port is firewalled
860 * or we're a dir mirror, no.
861 * 2) If we prefer to avoid begindir conns, and we're not fetching or
862 * publishing a bridge relay descriptor, no.
866 directory_command_should_use_begindir(const or_options_t
*options
,
867 const tor_addr_t
*addr
,
868 int or_port
, uint8_t router_purpose
,
869 dir_indirection_t indirection
)
871 (void) router_purpose
;
873 return 0; /* We don't know an ORPort -- no chance. */
874 if (indirection
== DIRIND_DIRECT_CONN
|| indirection
== DIRIND_ANON_DIRPORT
)
876 if (indirection
== DIRIND_ONEHOP
)
877 if (!fascist_firewall_allows_address_or(addr
, or_port
) ||
878 directory_fetches_from_authorities(options
))
879 return 0; /* We're firewalled or are acting like a relay -- also no. */
883 /** Helper for directory_initiate_command_routerstatus: send the
884 * command to a server whose address is <b>address</b>, whose IP is
885 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
886 * <b>supports_begindir</b>, and whose identity key digest is
889 directory_initiate_command(const tor_addr_t
*_addr
,
890 uint16_t or_port
, uint16_t dir_port
,
892 uint8_t dir_purpose
, uint8_t router_purpose
,
893 dir_indirection_t indirection
, const char *resource
,
894 const char *payload
, size_t payload_len
,
895 time_t if_modified_since
)
897 directory_initiate_command_rend(_addr
, or_port
, dir_port
,
899 router_purpose
, indirection
,
900 resource
, payload
, payload_len
,
901 if_modified_since
, NULL
);
904 /** Return non-zero iff a directory connection with purpose
905 * <b>dir_purpose</b> reveals sensitive information about a Tor
906 * instance's client activities. (Such connections must be performed
907 * through normal three-hop Tor circuits.) */
909 is_sensitive_dir_purpose(uint8_t dir_purpose
)
911 return ((dir_purpose
== DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2
) ||
912 (dir_purpose
== DIR_PURPOSE_UPLOAD_RENDDESC_V2
) ||
913 (dir_purpose
== DIR_PURPOSE_FETCH_RENDDESC_V2
));
916 /** Same as directory_initiate_command(), but accepts rendezvous data to
917 * fetch a hidden service descriptor. */
919 directory_initiate_command_rend(const tor_addr_t
*_addr
,
920 uint16_t or_port
, uint16_t dir_port
,
922 uint8_t dir_purpose
, uint8_t router_purpose
,
923 dir_indirection_t indirection
,
924 const char *resource
,
925 const char *payload
, size_t payload_len
,
926 time_t if_modified_since
,
927 const rend_data_t
*rend_query
)
929 dir_connection_t
*conn
;
930 const or_options_t
*options
= get_options();
931 int socket_error
= 0;
932 int use_begindir
= directory_command_should_use_begindir(options
, _addr
,
933 or_port
, router_purpose
, indirection
);
934 const int anonymized_connection
= dirind_is_anon(indirection
);
938 tor_assert(or_port
|| dir_port
);
941 tor_addr_copy(&addr
, _addr
);
943 log_debug(LD_DIR
, "anonymized %d, use_begindir %d.",
944 anonymized_connection
, use_begindir
);
946 log_debug(LD_DIR
, "Initiating %s", dir_conn_purpose_to_string(dir_purpose
));
948 #ifndef NON_ANONYMOUS_MODE_ENABLED
949 tor_assert(!(is_sensitive_dir_purpose(dir_purpose
) &&
950 !anonymized_connection
));
952 (void)is_sensitive_dir_purpose
;
955 /* ensure that we don't make direct connections when a SOCKS server is
957 if (!anonymized_connection
&& !use_begindir
&& !options
->HTTPProxy
&&
958 (options
->Socks4Proxy
|| options
->Socks5Proxy
)) {
959 log_warn(LD_DIR
, "Cannot connect to a directory server through a "
964 conn
= dir_connection_new(tor_addr_family(&addr
));
966 /* set up conn so it's got all the data we need to remember */
967 tor_addr_copy(&conn
->base_
.addr
, &addr
);
968 conn
->base_
.port
= use_begindir
? or_port
: dir_port
;
969 conn
->base_
.address
= tor_dup_addr(&addr
);
970 memcpy(conn
->identity_digest
, digest
, DIGEST_LEN
);
972 conn
->base_
.purpose
= dir_purpose
;
973 conn
->router_purpose
= router_purpose
;
975 /* give it an initial state */
976 conn
->base_
.state
= DIR_CONN_STATE_CONNECTING
;
978 /* decide whether we can learn our IP address from this conn */
979 /* XXXX This is a bad name for this field now. */
980 conn
->dirconn_direct
= !anonymized_connection
;
982 /* copy rendezvous data, if any */
984 conn
->rend_data
= rend_data_dup(rend_query
);
986 if (!anonymized_connection
&& !use_begindir
) {
987 /* then we want to connect to dirport directly */
989 if (options
->HTTPProxy
) {
990 tor_addr_copy(&addr
, &options
->HTTPProxyAddr
);
991 dir_port
= options
->HTTPProxyPort
;
994 switch (connection_connect(TO_CONN(conn
), conn
->base_
.address
, &addr
,
995 dir_port
, &socket_error
)) {
997 connection_mark_for_close(TO_CONN(conn
));
1000 /* start flushing conn */
1001 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
1004 /* queue the command on the outbuf */
1005 directory_send_command(conn
, dir_purpose
, 1, resource
,
1006 payload
, payload_len
,
1008 connection_watch_events(TO_CONN(conn
), READ_EVENT
| WRITE_EVENT
);
1009 /* writable indicates finish, readable indicates broken link,
1010 error indicates broken link in windowsland. */
1012 } else { /* we want to connect via a tor connection */
1013 entry_connection_t
*linked_conn
;
1014 /* Anonymized tunneled connections can never share a circuit.
1015 * One-hop directory connections can share circuits with each other
1016 * but nothing else. */
1017 int iso_flags
= anonymized_connection
? ISO_STREAM
: ISO_SESSIONGRP
;
1019 /* If it's an anonymized connection, remember the fact that we
1020 * wanted it for later: maybe we'll want it again soon. */
1021 if (anonymized_connection
&& use_begindir
)
1022 rep_hist_note_used_internal(time(NULL
), 0, 1);
1023 else if (anonymized_connection
&& !use_begindir
)
1024 rep_hist_note_used_port(time(NULL
), conn
->base_
.port
);
1026 /* make an AP connection
1027 * populate it and add it at the right state
1028 * hook up both sides
1031 connection_ap_make_link(TO_CONN(conn
),
1032 conn
->base_
.address
, conn
->base_
.port
,
1034 SESSION_GROUP_DIRCONN
, iso_flags
,
1035 use_begindir
, conn
->dirconn_direct
);
1037 log_warn(LD_NET
,"Making tunnel to dirserver failed.");
1038 connection_mark_for_close(TO_CONN(conn
));
1042 if (connection_add(TO_CONN(conn
)) < 0) {
1043 log_warn(LD_NET
,"Unable to add connection for link to dirserver.");
1044 connection_mark_for_close(TO_CONN(conn
));
1047 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
1048 /* queue the command on the outbuf */
1049 directory_send_command(conn
, dir_purpose
, 0, resource
,
1050 payload
, payload_len
,
1053 connection_watch_events(TO_CONN(conn
), READ_EVENT
|WRITE_EVENT
);
1054 IF_HAS_BUFFEREVENT(ENTRY_TO_CONN(linked_conn
), {
1055 connection_watch_events(ENTRY_TO_CONN(linked_conn
),
1056 READ_EVENT
|WRITE_EVENT
);
1057 }) ELSE_IF_NO_BUFFEREVENT
1058 connection_start_reading(ENTRY_TO_CONN(linked_conn
));
1062 /** Return true iff anything we say on <b>conn</b> is being encrypted before
1063 * we send it to the client/server. */
1065 connection_dir_is_encrypted(dir_connection_t
*conn
)
1067 /* Right now it's sufficient to see if conn is or has been linked, since
1068 * the only thing it could be linked to is an edge connection on a
1069 * circuit, and the only way it could have been unlinked is at the edge
1070 * connection getting closed.
1072 return TO_CONN(conn
)->linked
;
1075 /** Helper for sorting
1077 * sort strings alphabetically
1080 compare_strs_(const void **a
, const void **b
)
1082 const char *s1
= *a
, *s2
= *b
;
1083 return strcmp(s1
, s2
);
1086 #define CONDITIONAL_CONSENSUS_FPR_LEN 3
1087 #if (CONDITIONAL_CONSENSUS_FPR_LEN > DIGEST_LEN)
1088 #error "conditional consensus fingerprint length is larger than digest length"
1091 /** Return the URL we should use for a consensus download.
1093 * This url depends on whether or not the server we go to
1094 * is sufficiently new to support conditional consensus downloading,
1095 * i.e. GET .../consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>
1097 * If 'resource' is provided, it is the name of a consensus flavor to request.
1100 directory_get_consensus_url(const char *resource
)
1103 const char *hyphen
, *flavor
;
1104 if (resource
==NULL
|| strcmp(resource
, "ns")==0) {
1105 flavor
= ""; /* Request ns consensuses as "", so older servers will work*/
1113 char *authority_id_list
;
1114 smartlist_t
*authority_digests
= smartlist_new();
1116 SMARTLIST_FOREACH_BEGIN(router_get_trusted_dir_servers(),
1117 dir_server_t
*, ds
) {
1119 if (!(ds
->type
& V3_DIRINFO
))
1122 hex
= tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN
+1);
1123 base16_encode(hex
, 2*CONDITIONAL_CONSENSUS_FPR_LEN
+1,
1124 ds
->v3_identity_digest
, CONDITIONAL_CONSENSUS_FPR_LEN
);
1125 smartlist_add(authority_digests
, hex
);
1126 } SMARTLIST_FOREACH_END(ds
);
1127 smartlist_sort(authority_digests
, compare_strs_
);
1128 authority_id_list
= smartlist_join_strings(authority_digests
,
1131 tor_asprintf(&url
, "/tor/status-vote/current/consensus%s%s/%s.z",
1132 hyphen
, flavor
, authority_id_list
);
1134 SMARTLIST_FOREACH(authority_digests
, char *, cp
, tor_free(cp
));
1135 smartlist_free(authority_digests
);
1136 tor_free(authority_id_list
);
1141 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
1142 * are as in directory_initiate_command().
1145 directory_send_command(dir_connection_t
*conn
,
1146 int purpose
, int direct
, const char *resource
,
1147 const char *payload
, size_t payload_len
,
1148 time_t if_modified_since
)
1150 char proxystring
[256];
1151 char hoststring
[128];
1152 smartlist_t
*headers
= smartlist_new();
1155 const char *httpcommand
= NULL
;
1158 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
1160 tor_free(conn
->requested_resource
);
1162 conn
->requested_resource
= tor_strdup(resource
);
1164 /* come up with a string for which Host: we want */
1165 if (conn
->base_
.port
== 80) {
1166 strlcpy(hoststring
, conn
->base_
.address
, sizeof(hoststring
));
1168 tor_snprintf(hoststring
, sizeof(hoststring
),"%s:%d",
1169 conn
->base_
.address
, conn
->base_
.port
);
1172 /* Format if-modified-since */
1173 if (if_modified_since
) {
1174 char b
[RFC1123_TIME_LEN
+1];
1175 format_rfc1123_time(b
, if_modified_since
);
1176 smartlist_add_asprintf(headers
, "If-Modified-Since: %s\r\n", b
);
1179 /* come up with some proxy lines, if we're using one. */
1180 if (direct
&& get_options()->HTTPProxy
) {
1181 char *base64_authenticator
=NULL
;
1182 const char *authenticator
= get_options()->HTTPProxyAuthenticator
;
1184 tor_snprintf(proxystring
, sizeof(proxystring
),"http://%s", hoststring
);
1185 if (authenticator
) {
1186 base64_authenticator
= alloc_http_authenticator(authenticator
);
1187 if (!base64_authenticator
)
1188 log_warn(LD_BUG
, "Encoding http authenticator failed");
1190 if (base64_authenticator
) {
1191 smartlist_add_asprintf(headers
,
1192 "Proxy-Authorization: Basic %s\r\n",
1193 base64_authenticator
);
1194 tor_free(base64_authenticator
);
1201 case DIR_PURPOSE_FETCH_CONSENSUS
:
1202 /* resource is optional. If present, it's a flavor name */
1203 tor_assert(!payload
);
1204 httpcommand
= "GET";
1205 url
= directory_get_consensus_url(resource
);
1206 log_info(LD_DIR
, "Downloading consensus from %s using %s",
1209 case DIR_PURPOSE_FETCH_CERTIFICATE
:
1210 tor_assert(resource
);
1211 tor_assert(!payload
);
1212 httpcommand
= "GET";
1213 tor_asprintf(&url
, "/tor/keys/%s", resource
);
1215 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
1216 tor_assert(resource
);
1217 tor_assert(!payload
);
1218 httpcommand
= "GET";
1219 tor_asprintf(&url
, "/tor/status-vote/next/%s.z", resource
);
1221 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
1222 tor_assert(!resource
);
1223 tor_assert(!payload
);
1224 httpcommand
= "GET";
1225 url
= tor_strdup("/tor/status-vote/next/consensus-signatures.z");
1227 case DIR_PURPOSE_FETCH_SERVERDESC
:
1228 tor_assert(resource
);
1229 httpcommand
= "GET";
1230 tor_asprintf(&url
, "/tor/server/%s", resource
);
1232 case DIR_PURPOSE_FETCH_EXTRAINFO
:
1233 tor_assert(resource
);
1234 httpcommand
= "GET";
1235 tor_asprintf(&url
, "/tor/extra/%s", resource
);
1237 case DIR_PURPOSE_FETCH_MICRODESC
:
1238 tor_assert(resource
);
1239 httpcommand
= "GET";
1240 tor_asprintf(&url
, "/tor/micro/%s", resource
);
1242 case DIR_PURPOSE_UPLOAD_DIR
: {
1243 const char *why
= router_get_descriptor_gen_reason();
1244 tor_assert(!resource
);
1245 tor_assert(payload
);
1246 httpcommand
= "POST";
1247 url
= tor_strdup("/tor/");
1249 smartlist_add_asprintf(headers
, "X-Desc-Gen-Reason: %s\r\n", why
);
1253 case DIR_PURPOSE_UPLOAD_VOTE
:
1254 tor_assert(!resource
);
1255 tor_assert(payload
);
1256 httpcommand
= "POST";
1257 url
= tor_strdup("/tor/post/vote");
1259 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
1260 tor_assert(!resource
);
1261 tor_assert(payload
);
1262 httpcommand
= "POST";
1263 url
= tor_strdup("/tor/post/consensus-signature");
1265 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
1266 tor_assert(resource
);
1267 tor_assert(strlen(resource
) <= REND_DESC_ID_V2_LEN_BASE32
);
1268 tor_assert(!payload
);
1269 httpcommand
= "GET";
1270 tor_asprintf(&url
, "/tor/rendezvous2/%s", resource
);
1272 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
1273 tor_assert(!resource
);
1274 tor_assert(payload
);
1275 httpcommand
= "POST";
1276 url
= tor_strdup("/tor/rendezvous2/publish");
1283 /* warn in the non-tunneled case */
1284 if (direct
&& (strlen(proxystring
) + strlen(url
) >= 4096)) {
1286 "Squid does not like URLs longer than 4095 bytes, and this "
1287 "one is %d bytes long: %s%s",
1288 (int)(strlen(proxystring
) + strlen(url
)), proxystring
, url
);
1291 tor_snprintf(request
, sizeof(request
), "%s %s", httpcommand
, proxystring
);
1292 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
1293 connection_write_to_buf(url
, strlen(url
), TO_CONN(conn
));
1296 if (!strcmp(httpcommand
, "POST") || payload
) {
1297 smartlist_add_asprintf(headers
, "Content-Length: %lu\r\n",
1298 payload
? (unsigned long)payload_len
: 0);
1302 char *header
= smartlist_join_strings(headers
, "", 0, NULL
);
1303 tor_snprintf(request
, sizeof(request
), " HTTP/1.0\r\nHost: %s\r\n%s\r\n",
1304 hoststring
, header
);
1308 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
1311 /* then send the payload afterwards too */
1312 connection_write_to_buf(payload
, payload_len
, TO_CONN(conn
));
1315 SMARTLIST_FOREACH(headers
, char *, h
, tor_free(h
));
1316 smartlist_free(headers
);
1319 /** Parse an HTTP request string <b>headers</b> of the form
1321 * "\%s [http[s]://]\%s HTTP/1..."
1323 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
1324 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
1325 * so it does. Return 0.
1326 * Otherwise, return -1.
1329 parse_http_url(const char *headers
, char **url
)
1331 char *s
, *start
, *tmp
;
1333 s
= (char *)eat_whitespace_no_nl(headers
);
1335 s
= (char *)find_whitespace(s
); /* get past GET/POST */
1337 s
= (char *)eat_whitespace_no_nl(s
);
1339 start
= s
; /* this is it, assuming it's valid */
1340 s
= (char *)find_whitespace(start
);
1343 /* tolerate the http[s] proxy style of putting the hostname in the url */
1344 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
1348 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
1349 tmp
= strchr(tmp
+3, '/');
1350 if (tmp
&& tmp
< s
) {
1351 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname/' string");
1357 /* Check if the header is well formed (next sequence
1358 * should be HTTP/1.X\r\n). Assumes we're supporting 1.0? */
1362 char *e
= (char *)eat_whitespace_no_nl(s
);
1363 if (2 != tor_sscanf(e
, "HTTP/1.%u%c", &minor_ver
, &ch
)) {
1370 if (s
-start
< 5 || strcmpstart(start
,"/tor/")) { /* need to rewrite it */
1371 *url
= tor_malloc(s
- start
+ 5);
1372 strlcpy(*url
,"/tor", s
-start
+5);
1373 strlcat((*url
)+4, start
, s
-start
+1);
1375 *url
= tor_strndup(start
, s
-start
);
1380 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
1381 * <b>which</b>. The key should be given with a terminating colon and space;
1382 * this function copies everything after, up to but not including the
1383 * following \\r\\n. */
1385 http_get_header(const char *headers
, const char *which
)
1387 const char *cp
= headers
;
1389 if (!strcasecmpstart(cp
, which
)) {
1391 cp
+= strlen(which
);
1392 if ((eos
= strchr(cp
,'\r')))
1393 return tor_strndup(cp
, eos
-cp
);
1395 return tor_strdup(cp
);
1397 cp
= strchr(cp
, '\n');
1404 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
1405 * <b>conn</b>-\>address to describe our best guess of the address that
1406 * originated this HTTP request. */
1408 http_set_address_origin(const char *headers
, connection_t
*conn
)
1412 fwd
= http_get_header(headers
, "Forwarded-For: ");
1414 fwd
= http_get_header(headers
, "X-Forwarded-For: ");
1417 if (tor_addr_parse(&toraddr
,fwd
) == -1 ||
1418 tor_addr_is_internal(&toraddr
,0)) {
1419 log_debug(LD_DIR
, "Ignoring local/internal IP %s", escaped(fwd
));
1424 tor_free(conn
->address
);
1425 conn
->address
= tor_strdup(fwd
);
1430 /** Parse an HTTP response string <b>headers</b> of the form
1432 * "HTTP/1.\%d \%d\%s\r\n...".
1435 * If it's well-formed, assign the status code to *<b>code</b> and
1436 * return 0. Otherwise, return -1.
1438 * On success: If <b>date</b> is provided, set *date to the Date
1439 * header in the http headers, or 0 if no such header is found. If
1440 * <b>compression</b> is provided, set *<b>compression</b> to the
1441 * compression method given in the Content-Encoding header, or 0 if no
1442 * such header is found, or -1 if the value of the header is not
1443 * recognized. If <b>reason</b> is provided, strdup the reason string
1447 parse_http_response(const char *headers
, int *code
, time_t *date
,
1448 compress_method_t
*compression
, char **reason
)
1451 char datestr
[RFC1123_TIME_LEN
+1];
1452 smartlist_t
*parsed_headers
;
1453 tor_assert(headers
);
1456 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
1458 if (tor_sscanf(headers
, "HTTP/1.%u %u", &n1
, &n2
) < 2 ||
1459 (n1
!= 0 && n1
!= 1) ||
1460 (n2
< 100 || n2
>= 600)) {
1461 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
1466 parsed_headers
= smartlist_new();
1467 smartlist_split_string(parsed_headers
, headers
, "\n",
1468 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
1470 smartlist_t
*status_line_elements
= smartlist_new();
1471 tor_assert(smartlist_len(parsed_headers
));
1472 smartlist_split_string(status_line_elements
,
1473 smartlist_get(parsed_headers
, 0),
1474 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
1475 tor_assert(smartlist_len(status_line_elements
) <= 3);
1476 if (smartlist_len(status_line_elements
) == 3) {
1477 *reason
= smartlist_get(status_line_elements
, 2);
1478 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
1480 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
1481 smartlist_free(status_line_elements
);
1485 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1486 if (!strcmpstart(s
, "Date: ")) {
1487 strlcpy(datestr
, s
+6, sizeof(datestr
));
1488 /* This will do nothing on failure, so we don't need to check
1489 the result. We shouldn't warn, since there are many other valid
1490 date formats besides the one we use. */
1491 parse_rfc1123_time(datestr
, date
);
1496 const char *enc
= NULL
;
1497 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1498 if (!strcmpstart(s
, "Content-Encoding: ")) {
1501 if (!enc
|| !strcmp(enc
, "identity")) {
1502 *compression
= NO_METHOD
;
1503 } else if (!strcmp(enc
, "deflate") || !strcmp(enc
, "x-deflate")) {
1504 *compression
= ZLIB_METHOD
;
1505 } else if (!strcmp(enc
, "gzip") || !strcmp(enc
, "x-gzip")) {
1506 *compression
= GZIP_METHOD
;
1508 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
1510 *compression
= UNKNOWN_METHOD
;
1513 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
1514 smartlist_free(parsed_headers
);
1519 /** Return true iff <b>body</b> doesn't start with a plausible router or
1520 * network-status or microdescriptor opening. This is a sign of possible
1523 body_is_plausible(const char *body
, size_t len
, int purpose
)
1527 return 1; /* empty bodies don't need decompression */
1530 if (purpose
== DIR_PURPOSE_FETCH_MICRODESC
) {
1531 return (!strcmpstart(body
,"onion-key"));
1534 if (!strcmpstart(body
,"router") ||
1535 !strcmpstart(body
,"network-status"))
1537 for (i
=0;i
<32;++i
) {
1538 if (!TOR_ISPRINT(body
[i
]) && !TOR_ISSPACE(body
[i
]))
1545 /** Called when we've just fetched a bunch of router descriptors in
1546 * <b>body</b>. The list <b>which</b>, if present, holds digests for
1547 * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1548 * is true, or identity digests otherwise. Parse the descriptors, validate
1549 * them, and annotate them as having purpose <b>purpose</b> and as having been
1550 * downloaded from <b>source</b>.
1552 * Return the number of routers actually added. */
1554 load_downloaded_routers(const char *body
, smartlist_t
*which
,
1555 int descriptor_digests
,
1560 char time_buf
[ISO_TIME_LEN
+1];
1562 int general
= router_purpose
== ROUTER_PURPOSE_GENERAL
;
1563 format_iso_time(time_buf
, time(NULL
));
1566 if (tor_snprintf(buf
, sizeof(buf
),
1567 "@downloaded-at %s\n"
1569 "%s%s%s", time_buf
, escaped(source
),
1570 !general
? "@purpose " : "",
1571 !general
? router_purpose_to_string(router_purpose
) : "",
1572 !general
? "\n" : "")<0)
1575 added
= router_load_routers_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1576 descriptor_digests
, buf
);
1578 control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS
,
1579 count_loading_descriptors_progress());
1583 /** We are a client, and we've finished reading the server's
1584 * response. Parse it and act appropriately.
1586 * If we're still happy with using this directory server in the future, return
1587 * 0. Otherwise return -1; and the caller should consider trying the request
1590 * The caller will take care of marking the connection for close.
1593 connection_dir_client_reached_eof(dir_connection_t
*conn
)
1597 char *reason
= NULL
;
1598 size_t body_len
= 0, orig_len
= 0;
1600 time_t date_header
= 0;
1602 compress_method_t compression
;
1605 int allow_partial
= (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1606 conn
->base_
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
||
1607 conn
->base_
.purpose
== DIR_PURPOSE_FETCH_MICRODESC
);
1608 int was_compressed
= 0;
1609 time_t now
= time(NULL
);
1612 switch (connection_fetch_from_buf_http(TO_CONN(conn
),
1613 &headers
, MAX_HEADERS_SIZE
,
1614 &body
, &body_len
, MAX_DIR_DL_SIZE
,
1616 case -1: /* overflow */
1617 log_warn(LD_PROTOCOL
,
1618 "'fetch' response too large (server '%s:%d'). Closing.",
1619 conn
->base_
.address
, conn
->base_
.port
);
1623 "'fetch' response not all here, but we're at eof. Closing.");
1625 /* case 1, fall through */
1627 orig_len
= body_len
;
1629 if (parse_http_response(headers
, &status_code
, &date_header
,
1630 &compression
, &reason
) < 0) {
1631 log_warn(LD_HTTP
,"Unparseable headers (server '%s:%d'). Closing.",
1632 conn
->base_
.address
, conn
->base_
.port
);
1633 tor_free(body
); tor_free(headers
);
1636 if (!reason
) reason
= tor_strdup("[no reason given]");
1639 "Received response from directory server '%s:%d': %d %s "
1641 conn
->base_
.address
, conn
->base_
.port
, status_code
,
1643 conn
->base_
.purpose
);
1645 /* now check if it's got any hints for us about our IP address. */
1646 if (conn
->dirconn_direct
) {
1647 char *guess
= http_get_header(headers
, X_ADDRESS_HEADER
);
1649 router_new_address_suggestion(guess
, conn
);
1654 if (date_header
> 0) {
1655 /* The date header was written very soon after we sent our request,
1656 * so compute the skew as the difference between sending the request
1657 * and the date header. (We used to check now-date_header, but that's
1658 * inaccurate if we spend a lot of time downloading.)
1660 apparent_skew
= conn
->base_
.timestamp_lastwritten
- date_header
;
1661 if (labs(apparent_skew
)>ALLOW_DIRECTORY_TIME_SKEW
) {
1662 int trusted
= router_digest_is_trusted_dir(conn
->identity_digest
);
1663 clock_skew_warning(TO_CONN(conn
), apparent_skew
, trusted
, LD_HTTP
,
1664 "directory", "DIRSERV");
1665 skewed
= 1; /* don't check the recommended-versions line */
1667 log_debug(LD_HTTP
, "Time on received directory is within tolerance; "
1668 "we are %ld seconds skewed. (That's okay.)", apparent_skew
);
1671 (void) skewed
; /* skewed isn't used yet. */
1673 if (status_code
== 503) {
1676 const char *id_digest
= conn
->identity_digest
;
1677 log_info(LD_DIR
,"Received http status code %d (%s) from server "
1678 "'%s:%d'. I'll try again soon.",
1679 status_code
, escaped(reason
), conn
->base_
.address
,
1681 if ((rs
= router_get_mutable_consensus_status_by_id(id_digest
)))
1682 rs
->last_dir_503_at
= now
;
1683 if ((ds
= router_get_fallback_dirserver_by_digest(id_digest
)))
1684 ds
->fake_status
.last_dir_503_at
= now
;
1686 tor_free(body
); tor_free(headers
); tor_free(reason
);
1690 plausible
= body_is_plausible(body
, body_len
, conn
->base_
.purpose
);
1691 if (compression
!= NO_METHOD
|| !plausible
) {
1692 char *new_body
= NULL
;
1694 compress_method_t guessed
= detect_compression_method(body
, body_len
);
1695 if (compression
== UNKNOWN_METHOD
|| guessed
!= compression
) {
1696 /* Tell the user if we don't believe what we're told about compression.*/
1697 const char *description1
, *description2
;
1698 if (compression
== ZLIB_METHOD
)
1699 description1
= "as deflated";
1700 else if (compression
== GZIP_METHOD
)
1701 description1
= "as gzipped";
1702 else if (compression
== NO_METHOD
)
1703 description1
= "as uncompressed";
1705 description1
= "with an unknown Content-Encoding";
1706 if (guessed
== ZLIB_METHOD
)
1707 description2
= "deflated";
1708 else if (guessed
== GZIP_METHOD
)
1709 description2
= "gzipped";
1710 else if (!plausible
)
1711 description2
= "confusing binary junk";
1713 description2
= "uncompressed";
1715 log_info(LD_HTTP
, "HTTP body from server '%s:%d' was labeled %s, "
1716 "but it seems to be %s.%s",
1717 conn
->base_
.address
, conn
->base_
.port
, description1
,
1719 (compression
>0 && guessed
>0)?" Trying both.":"");
1721 /* Try declared compression first if we can. */
1722 if (compression
== GZIP_METHOD
|| compression
== ZLIB_METHOD
)
1723 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, compression
,
1724 !allow_partial
, LOG_PROTOCOL_WARN
);
1725 /* Okay, if that didn't work, and we think that it was compressed
1726 * differently, try that. */
1728 (guessed
== GZIP_METHOD
|| guessed
== ZLIB_METHOD
) &&
1729 compression
!= guessed
)
1730 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, guessed
,
1731 !allow_partial
, LOG_PROTOCOL_WARN
);
1732 /* If we're pretty sure that we have a compressed directory, and
1733 * we didn't manage to uncompress it, then warn and bail. */
1734 if (!plausible
&& !new_body
) {
1735 log_fn(LOG_PROTOCOL_WARN
, LD_HTTP
,
1736 "Unable to decompress HTTP body (server '%s:%d').",
1737 conn
->base_
.address
, conn
->base_
.port
);
1738 tor_free(body
); tor_free(headers
); tor_free(reason
);
1749 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
1751 const char *flavname
= conn
->requested_resource
;
1752 if (status_code
!= 200) {
1753 int severity
= (status_code
== 304) ? LOG_INFO
: LOG_WARN
;
1754 tor_log(severity
, LD_DIR
,
1755 "Received http status code %d (%s) from server "
1756 "'%s:%d' while fetching consensus directory.",
1757 status_code
, escaped(reason
), conn
->base_
.address
,
1759 tor_free(body
); tor_free(headers
); tor_free(reason
);
1760 networkstatus_consensus_download_failed(status_code
, flavname
);
1763 log_info(LD_DIR
,"Received consensus directory (size %d) from server "
1764 "'%s:%d'", (int)body_len
, conn
->base_
.address
, conn
->base_
.port
);
1765 if ((r
=networkstatus_set_current_consensus(body
, flavname
, 0))<0) {
1766 log_fn(r
<-1?LOG_WARN
:LOG_INFO
, LD_DIR
,
1767 "Unable to load %s consensus directory downloaded from "
1768 "server '%s:%d'. I'll try again soon.",
1769 flavname
, conn
->base_
.address
, conn
->base_
.port
);
1770 tor_free(body
); tor_free(headers
); tor_free(reason
);
1771 networkstatus_consensus_download_failed(0, flavname
);
1774 /* launches router downloads as needed */
1775 routers_update_all_from_networkstatus(now
, 3);
1776 update_microdescs_from_networkstatus(now
);
1777 update_microdesc_downloads(now
);
1778 directory_info_has_arrived(now
, 0);
1779 log_info(LD_DIR
, "Successfully loaded consensus.");
1782 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
1783 if (status_code
!= 200) {
1785 "Received http status code %d (%s) from server "
1786 "'%s:%d' while fetching \"/tor/keys/%s\".",
1787 status_code
, escaped(reason
), conn
->base_
.address
,
1788 conn
->base_
.port
, conn
->requested_resource
);
1789 connection_dir_download_cert_failed(conn
, status_code
);
1790 tor_free(body
); tor_free(headers
); tor_free(reason
);
1793 log_info(LD_DIR
,"Received authority certificates (size %d) from server "
1794 "'%s:%d'", (int)body_len
, conn
->base_
.address
, conn
->base_
.port
);
1797 * Tell trusted_dirs_load_certs_from_string() whether it was by fp
1801 if (!strcmpstart(conn
->requested_resource
, "fp/")) {
1802 src_code
= TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_DIGEST
;
1803 } else if (!strcmpstart(conn
->requested_resource
, "fp-sk/")) {
1804 src_code
= TRUSTED_DIRS_CERTS_SRC_DL_BY_ID_SK_DIGEST
;
1807 if (src_code
!= -1) {
1808 if (trusted_dirs_load_certs_from_string(body
, src_code
, 1)<0) {
1809 log_warn(LD_DIR
, "Unable to parse fetched certificates");
1810 /* if we fetched more than one and only some failed, the successful
1811 * ones got flushed to disk so it's safe to call this on them */
1812 connection_dir_download_cert_failed(conn
, status_code
);
1814 directory_info_has_arrived(now
, 0);
1815 log_info(LD_DIR
, "Successfully loaded certificates from fetch.");
1819 "Couldn't figure out what to do with fetched certificates for "
1820 "unknown resource %s",
1821 conn
->requested_resource
);
1822 connection_dir_download_cert_failed(conn
, status_code
);
1825 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
1828 log_info(LD_DIR
,"Got votes (size %d) from server %s:%d",
1829 (int)body_len
, conn
->base_
.address
, conn
->base_
.port
);
1830 if (status_code
!= 200) {
1832 "Received http status code %d (%s) from server "
1833 "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".",
1834 status_code
, escaped(reason
), conn
->base_
.address
,
1835 conn
->base_
.port
, conn
->requested_resource
);
1836 tor_free(body
); tor_free(headers
); tor_free(reason
);
1839 dirvote_add_vote(body
, &msg
, &st
);
1841 log_warn(LD_DIR
, "Error adding retrieved vote: %s", msg
);
1843 log_info(LD_DIR
, "Added vote(s) successfully [msg: %s]", msg
);
1846 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
1847 const char *msg
= NULL
;
1848 log_info(LD_DIR
,"Got detached signatures (size %d) from server %s:%d",
1849 (int)body_len
, conn
->base_
.address
, conn
->base_
.port
);
1850 if (status_code
!= 200) {
1852 "Received http status code %d (%s) from server '%s:%d' while fetching "
1853 "\"/tor/status-vote/next/consensus-signatures.z\".",
1854 status_code
, escaped(reason
), conn
->base_
.address
,
1856 tor_free(body
); tor_free(headers
); tor_free(reason
);
1859 if (dirvote_add_signatures(body
, conn
->base_
.address
, &msg
)<0) {
1860 log_warn(LD_DIR
, "Problem adding detached signatures from %s:%d: %s",
1861 conn
->base_
.address
, conn
->base_
.port
, msg
?msg
:"???");
1865 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1866 conn
->base_
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
1867 int was_ei
= conn
->base_
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
;
1868 smartlist_t
*which
= NULL
;
1869 int n_asked_for
= 0;
1870 int descriptor_digests
= conn
->requested_resource
&&
1871 !strcmpstart(conn
->requested_resource
,"d/");
1872 log_info(LD_DIR
,"Received %s (size %d) from server '%s:%d'",
1873 was_ei
? "extra server info" : "server info",
1874 (int)body_len
, conn
->base_
.address
, conn
->base_
.port
);
1875 if (conn
->requested_resource
&&
1876 (!strcmpstart(conn
->requested_resource
,"d/") ||
1877 !strcmpstart(conn
->requested_resource
,"fp/"))) {
1878 which
= smartlist_new();
1879 dir_split_resource_into_fingerprints(conn
->requested_resource
+
1880 (descriptor_digests
? 2 : 3),
1882 n_asked_for
= smartlist_len(which
);
1884 if (status_code
!= 200) {
1885 int dir_okay
= status_code
== 404 ||
1886 (status_code
== 400 && !strcmp(reason
, "Servers unavailable."));
1887 /* 404 means that it didn't have them; no big deal.
1888 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1889 log_fn(dir_okay
? LOG_INFO
: LOG_WARN
, LD_DIR
,
1890 "Received http status code %d (%s) from server '%s:%d' "
1891 "while fetching \"/tor/server/%s\". I'll try again soon.",
1892 status_code
, escaped(reason
), conn
->base_
.address
,
1893 conn
->base_
.port
, conn
->requested_resource
);
1895 connection_dir_download_routerdesc_failed(conn
);
1897 dir_routerdesc_download_failed(which
, status_code
,
1898 conn
->router_purpose
,
1899 was_ei
, descriptor_digests
);
1900 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1901 smartlist_free(which
);
1903 tor_free(body
); tor_free(headers
); tor_free(reason
);
1904 return dir_okay
? 0 : -1;
1906 /* Learn the routers, assuming we requested by fingerprint or "all"
1909 * We use "authority" to fetch our own descriptor for
1910 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1911 * the output of "authority" requests unless we are using bridges,
1912 * since otherwise they'll be the response from reachability tests,
1913 * and we don't really want to add that to our routerlist. */
1914 if (which
|| (conn
->requested_resource
&&
1915 (!strcmpstart(conn
->requested_resource
, "all") ||
1916 (!strcmpstart(conn
->requested_resource
, "authority") &&
1917 get_options()->UseBridges
)))) {
1918 /* as we learn from them, we remove them from 'which' */
1920 router_load_extrainfo_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1921 descriptor_digests
);
1923 //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1924 // descriptor_digests, conn->router_purpose);
1925 if (load_downloaded_routers(body
, which
, descriptor_digests
,
1926 conn
->router_purpose
,
1927 conn
->base_
.address
))
1928 directory_info_has_arrived(now
, 0);
1931 if (which
) { /* mark remaining ones as failed */
1932 log_info(LD_DIR
, "Received %d/%d %s requested from %s:%d",
1933 n_asked_for
-smartlist_len(which
), n_asked_for
,
1934 was_ei
? "extra-info documents" : "router descriptors",
1935 conn
->base_
.address
, (int)conn
->base_
.port
);
1936 if (smartlist_len(which
)) {
1937 dir_routerdesc_download_failed(which
, status_code
,
1938 conn
->router_purpose
,
1939 was_ei
, descriptor_digests
);
1941 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1942 smartlist_free(which
);
1944 if (directory_conn_is_self_reachability_test(conn
))
1945 router_dirport_found_reachable();
1947 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_MICRODESC
) {
1948 smartlist_t
*which
= NULL
;
1949 log_info(LD_DIR
,"Received answer to microdescriptor request (status %d, "
1950 "size %d) from server '%s:%d'",
1951 status_code
, (int)body_len
, conn
->base_
.address
,
1953 tor_assert(conn
->requested_resource
&&
1954 !strcmpstart(conn
->requested_resource
, "d/"));
1955 which
= smartlist_new();
1956 dir_split_resource_into_fingerprints(conn
->requested_resource
+2,
1958 DSR_DIGEST256
|DSR_BASE64
);
1959 if (status_code
!= 200) {
1960 log_info(LD_DIR
, "Received status code %d (%s) from server "
1961 "'%s:%d' while fetching \"/tor/micro/%s\". I'll try again "
1963 status_code
, escaped(reason
), conn
->base_
.address
,
1964 (int)conn
->base_
.port
, conn
->requested_resource
);
1965 dir_microdesc_download_failed(which
, status_code
);
1966 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1967 smartlist_free(which
);
1968 tor_free(body
); tor_free(headers
); tor_free(reason
);
1972 mds
= microdescs_add_to_cache(get_microdesc_cache(),
1973 body
, body
+body_len
, SAVED_NOWHERE
, 0,
1975 if (smartlist_len(which
)) {
1976 /* Mark remaining ones as failed. */
1977 dir_microdesc_download_failed(which
, status_code
);
1979 control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS
,
1980 count_loading_descriptors_progress());
1981 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1982 smartlist_free(which
);
1983 smartlist_free(mds
);
1987 if (conn
->base_
.purpose
== DIR_PURPOSE_UPLOAD_DIR
) {
1988 switch (status_code
) {
1991 router_get_trusteddirserver_by_digest(conn
->identity_digest
);
1992 char *rejected_hdr
= http_get_header(headers
,
1993 "X-Descriptor-Not-New: ");
1995 if (!strcmp(rejected_hdr
, "Yes")) {
1996 log_info(LD_GENERAL
,
1997 "Authority '%s' declined our descriptor (not new)",
1999 /* XXXX use this information; be sure to upload next one
2001 /* XXXX023 On further thought, the task above implies that we're
2002 * basing our regenerate-descriptor time on when we uploaded the
2003 * last descriptor, not on the published time of the last
2004 * descriptor. If those are different, that's a bad thing to
2007 tor_free(rejected_hdr
);
2009 log_info(LD_GENERAL
,"eof (status 200) after uploading server "
2010 "descriptor: finished.");
2011 control_event_server_status(
2012 LOG_NOTICE
, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
2013 conn
->base_
.address
, conn
->base_
.port
);
2015 ds
->has_accepted_serverdesc
= 1;
2016 if (directories_have_accepted_server_descriptor())
2017 control_event_server_status(LOG_NOTICE
, "GOOD_SERVER_DESCRIPTOR");
2021 log_warn(LD_GENERAL
,"http status 400 (%s) response from "
2022 "dirserver '%s:%d'. Please correct.",
2023 escaped(reason
), conn
->base_
.address
, conn
->base_
.port
);
2024 control_event_server_status(LOG_WARN
,
2025 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
2026 conn
->base_
.address
, conn
->base_
.port
, escaped(reason
));
2029 log_warn(LD_GENERAL
,
2030 "http status %d (%s) reason unexpected while uploading "
2031 "descriptor to server '%s:%d').",
2032 status_code
, escaped(reason
), conn
->base_
.address
,
2036 /* return 0 in all cases, since we don't want to mark any
2037 * dirservers down just because they don't like us. */
2040 if (conn
->base_
.purpose
== DIR_PURPOSE_UPLOAD_VOTE
) {
2041 switch (status_code
) {
2043 log_notice(LD_DIR
,"Uploaded a vote to dirserver %s:%d",
2044 conn
->base_
.address
, conn
->base_
.port
);
2048 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
2049 "vote to dirserver '%s:%d'. Please correct.",
2050 escaped(reason
), conn
->base_
.address
, conn
->base_
.port
);
2053 log_warn(LD_GENERAL
,
2054 "http status %d (%s) reason unexpected while uploading "
2055 "vote to server '%s:%d').",
2056 status_code
, escaped(reason
), conn
->base_
.address
,
2060 /* return 0 in all cases, since we don't want to mark any
2061 * dirservers down just because they don't like us. */
2064 if (conn
->base_
.purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
) {
2065 switch (status_code
) {
2067 log_notice(LD_DIR
,"Uploaded signature(s) to dirserver %s:%d",
2068 conn
->base_
.address
, conn
->base_
.port
);
2072 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
2073 "signatures to dirserver '%s:%d'. Please correct.",
2074 escaped(reason
), conn
->base_
.address
, conn
->base_
.port
);
2077 log_warn(LD_GENERAL
,
2078 "http status %d (%s) reason unexpected while uploading "
2079 "signatures to server '%s:%d').",
2080 status_code
, escaped(reason
), conn
->base_
.address
,
2084 /* return 0 in all cases, since we don't want to mark any
2085 * dirservers down just because they don't like us. */
2088 if (conn
->base_
.purpose
== DIR_PURPOSE_FETCH_RENDDESC_V2
) {
2089 #define SEND_HS_DESC_FAILED_EVENT(reason) ( \
2090 control_event_hs_descriptor_failed(conn->rend_data, \
2091 conn->identity_digest, \
2093 #define SEND_HS_DESC_FAILED_CONTENT() ( \
2094 control_event_hs_descriptor_content(conn->rend_data->onion_address, \
2095 conn->requested_resource, \
2096 conn->identity_digest, \
2098 tor_assert(conn
->rend_data
);
2099 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
2101 (int)body_len
, status_code
, escaped(reason
));
2102 switch (status_code
) {
2105 rend_cache_entry_t
*entry
= NULL
;
2107 switch (rend_cache_store_v2_desc_as_client(body
,
2108 conn
->requested_resource
, conn
->rend_data
,
2111 case RCS_NOTDIR
: /* Impossible */
2112 log_warn(LD_REND
,"Fetching v2 rendezvous descriptor failed. "
2113 "Retrying at another directory.");
2114 /* We'll retry when connection_about_to_close_connection()
2115 * cleans this dir conn up. */
2116 SEND_HS_DESC_FAILED_EVENT("BAD_DESC");
2117 SEND_HS_DESC_FAILED_CONTENT();
2122 char service_id
[REND_SERVICE_ID_LEN_BASE32
+ 1];
2123 /* Should never be NULL here for an OKAY returned code. */
2125 rend_get_service_id(entry
->parsed
->pk
, service_id
);
2127 /* success. notify pending connections about this. */
2128 log_info(LD_REND
, "Successfully fetched v2 rendezvous "
2130 control_event_hs_descriptor_received(service_id
,
2132 conn
->identity_digest
);
2133 control_event_hs_descriptor_content(service_id
,
2134 conn
->requested_resource
,
2135 conn
->identity_digest
,
2137 conn
->base_
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2
;
2138 rend_client_desc_trynow(service_id
);
2139 memwipe(service_id
, 0, sizeof(service_id
));
2146 /* Not there. We'll retry when
2147 * connection_about_to_close_connection() cleans this conn up. */
2148 log_info(LD_REND
,"Fetching v2 rendezvous descriptor failed: "
2149 "Retrying at another directory.");
2150 SEND_HS_DESC_FAILED_EVENT("NOT_FOUND");
2151 SEND_HS_DESC_FAILED_CONTENT();
2154 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
2155 "http status 400 (%s). Dirserver didn't like our "
2156 "v2 rendezvous query? Retrying at another directory.",
2158 SEND_HS_DESC_FAILED_EVENT("QUERY_REJECTED");
2159 SEND_HS_DESC_FAILED_CONTENT();
2162 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
2163 "http status %d (%s) response unexpected while "
2164 "fetching v2 hidden service descriptor (server '%s:%d'). "
2165 "Retrying at another directory.",
2166 status_code
, escaped(reason
), conn
->base_
.address
,
2168 SEND_HS_DESC_FAILED_EVENT("UNEXPECTED");
2169 SEND_HS_DESC_FAILED_CONTENT();
2174 if (conn
->base_
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC_V2
) {
2175 #define SEND_HS_DESC_UPLOAD_FAILED_EVENT(reason) ( \
2176 control_event_hs_descriptor_upload_failed(conn->identity_digest, \
2178 log_info(LD_REND
,"Uploaded rendezvous descriptor (status %d "
2180 status_code
, escaped(reason
));
2181 switch (status_code
) {
2184 "Uploading rendezvous descriptor: finished with status "
2185 "200 (%s)", escaped(reason
));
2186 control_event_hs_descriptor_uploaded(conn
->identity_digest
);
2187 rend_service_desc_has_uploaded(conn
->rend_data
);
2190 log_warn(LD_REND
,"http status 400 (%s) response from dirserver "
2191 "'%s:%d'. Malformed rendezvous descriptor?",
2192 escaped(reason
), conn
->base_
.address
, conn
->base_
.port
);
2193 SEND_HS_DESC_UPLOAD_FAILED_EVENT("UPLOAD_REJECTED");
2196 log_warn(LD_REND
,"http status %d (%s) response unexpected (server "
2198 status_code
, escaped(reason
), conn
->base_
.address
,
2200 SEND_HS_DESC_UPLOAD_FAILED_EVENT("UNEXPECTED");
2204 note_client_request(conn
->base_
.purpose
, was_compressed
, orig_len
);
2205 tor_free(body
); tor_free(headers
); tor_free(reason
);
2209 /** Called when a directory connection reaches EOF. */
2211 connection_dir_reached_eof(dir_connection_t
*conn
)
2214 if (conn
->base_
.state
!= DIR_CONN_STATE_CLIENT_READING
) {
2215 log_info(LD_HTTP
,"conn reached eof, not reading. [state=%d] Closing.",
2217 connection_close_immediate(TO_CONN(conn
)); /* error: give up on flushing */
2218 connection_mark_for_close(TO_CONN(conn
));
2222 retval
= connection_dir_client_reached_eof(conn
);
2223 if (retval
== 0) /* success */
2224 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_FINISHED
;
2225 connection_mark_for_close(TO_CONN(conn
));
2229 /** If any directory object is arriving, and it's over 10MB large, we're
2230 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
2231 * ask for more than 96 router descriptors at a time.)
2233 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
2235 #define MAX_VOTE_DL_SIZE (MAX_DIRECTORY_OBJECT_SIZE * 5)
2237 /** Read handler for directory connections. (That's connections <em>to</em>
2238 * directory servers and connections <em>at</em> directory servers.)
2241 connection_dir_process_inbuf(dir_connection_t
*conn
)
2245 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
2247 /* Directory clients write, then read data until they receive EOF;
2248 * directory servers read data until they get an HTTP command, then
2249 * write their response (when it's finished flushing, they mark for
2253 /* If we're on the dirserver side, look for a command. */
2254 if (conn
->base_
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
2255 if (directory_handle_command(conn
) < 0) {
2256 connection_mark_for_close(TO_CONN(conn
));
2263 (TO_CONN(conn
)->purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) ?
2264 MAX_VOTE_DL_SIZE
: MAX_DIRECTORY_OBJECT_SIZE
;
2266 if (connection_get_inbuf_len(TO_CONN(conn
)) > max_size
) {
2268 "Too much data received from directory connection (%s): "
2269 "denial of service attempt, or you need to upgrade?",
2270 conn
->base_
.address
);
2271 connection_mark_for_close(TO_CONN(conn
));
2275 if (!conn
->base_
.inbuf_reached_eof
)
2276 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
2280 /** Called when we're about to finally unlink and free a directory connection:
2281 * perform necessary accounting and cleanup */
2283 connection_dir_about_to_close(dir_connection_t
*dir_conn
)
2285 connection_t
*conn
= TO_CONN(dir_conn
);
2287 if (conn
->state
< DIR_CONN_STATE_CLIENT_FINISHED
) {
2288 /* It's a directory connection and connecting or fetching
2289 * failed: forget about this router, and maybe try again. */
2290 connection_dir_request_failed(dir_conn
);
2292 /* If we were trying to fetch a v2 rend desc and did not succeed,
2293 * retry as needed. (If a fetch is successful, the connection state
2294 * is changed to DIR_PURPOSE_HAS_FETCHED_RENDDESC_V2 to mark that
2295 * refetching is unnecessary.) */
2296 if (conn
->purpose
== DIR_PURPOSE_FETCH_RENDDESC_V2
&&
2297 dir_conn
->rend_data
&&
2298 strlen(dir_conn
->rend_data
->onion_address
) == REND_SERVICE_ID_LEN_BASE32
)
2299 rend_client_refetch_v2_renddesc(dir_conn
->rend_data
);
2302 /** Create an http response for the client <b>conn</b> out of
2303 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
2306 write_http_status_line(dir_connection_t
*conn
, int status
,
2307 const char *reason_phrase
)
2310 if (tor_snprintf(buf
, sizeof(buf
), "HTTP/1.0 %d %s\r\n\r\n",
2311 status
, reason_phrase
? reason_phrase
: "OK") < 0) {
2312 log_warn(LD_BUG
,"status line too long.");
2315 log_debug(LD_DIRSERV
,"Wrote status 'HTTP/1.0 %d %s'", status
, reason_phrase
);
2316 connection_write_to_buf(buf
, strlen(buf
), TO_CONN(conn
));
2319 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
2320 * with <b>type</b> as the Content-Type.
2322 * If <b>length</b> is nonnegative, it is the Content-Length.
2323 * If <b>encoding</b> is provided, it is the Content-Encoding.
2324 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
2325 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
2327 write_http_response_header_impl(dir_connection_t
*conn
, ssize_t length
,
2328 const char *type
, const char *encoding
,
2329 const char *extra_headers
,
2330 long cache_lifetime
)
2332 char date
[RFC1123_TIME_LEN
+1];
2335 time_t now
= time(NULL
);
2339 format_rfc1123_time(date
, now
);
2341 tor_snprintf(cp
, sizeof(tmp
),
2342 "HTTP/1.0 200 OK\r\nDate: %s\r\n",
2346 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
), "Content-Type: %s\r\n", type
);
2349 if (!is_local_addr(&conn
->base_
.addr
)) {
2350 /* Don't report the source address for a nearby/private connection.
2351 * Otherwise we tend to mis-report in cases where incoming ports are
2352 * being forwarded to a Tor server running behind the firewall. */
2353 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2354 X_ADDRESS_HEADER
"%s\r\n", conn
->base_
.address
);
2358 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2359 "Content-Encoding: %s\r\n", encoding
);
2363 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2364 "Content-Length: %ld\r\n", (long)length
);
2367 if (cache_lifetime
> 0) {
2368 char expbuf
[RFC1123_TIME_LEN
+1];
2369 format_rfc1123_time(expbuf
, (time_t)(now
+ cache_lifetime
));
2370 /* We could say 'Cache-control: max-age=%d' here if we start doing
2372 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2373 "Expires: %s\r\n", expbuf
);
2375 } else if (cache_lifetime
== 0) {
2376 /* We could say 'Cache-control: no-cache' here if we start doing
2378 strlcpy(cp
, "Pragma: no-cache\r\n", sizeof(tmp
)-(cp
-tmp
));
2381 if (extra_headers
) {
2382 strlcpy(cp
, extra_headers
, sizeof(tmp
)-(cp
-tmp
));
2385 if (sizeof(tmp
)-(cp
-tmp
) > 3)
2386 memcpy(cp
, "\r\n", 3);
2389 connection_write_to_buf(tmp
, strlen(tmp
), TO_CONN(conn
));
2392 /** As write_http_response_header_impl, but sets encoding and content-typed
2393 * based on whether the response will be <b>compressed</b> or not. */
2395 write_http_response_header(dir_connection_t
*conn
, ssize_t length
,
2396 int compressed
, long cache_lifetime
)
2398 write_http_response_header_impl(conn
, length
,
2399 compressed
?"application/octet-stream":"text/plain",
2400 compressed
?"deflate":"identity",
2405 #if defined(INSTRUMENT_DOWNLOADS) || defined(RUNNING_DOXYGEN)
2407 typedef struct request_t
{
2408 uint64_t bytes
; /**< How many bytes have we transferred? */
2409 uint64_t count
; /**< How many requests have we made? */
2412 /** Map used to keep track of how much data we've up/downloaded in what kind
2413 * of request. Maps from request type to pointer to request_t. */
2414 static strmap_t
*request_map
= NULL
;
2416 /** Record that a client request of <b>purpose</b> was made, and that
2417 * <b>bytes</b> bytes of possibly <b>compressed</b> data were sent/received.
2418 * Used to keep track of how much we've up/downloaded in what kind of
2421 note_client_request(int purpose
, int compressed
, size_t bytes
)
2424 const char *kind
= NULL
;
2426 case DIR_PURPOSE_FETCH_CONSENSUS
: kind
= "dl/consensus"; break;
2427 case DIR_PURPOSE_FETCH_CERTIFICATE
: kind
= "dl/cert"; break;
2428 case DIR_PURPOSE_FETCH_STATUS_VOTE
: kind
= "dl/vote"; break;
2429 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
: kind
= "dl/detached_sig";
2431 case DIR_PURPOSE_FETCH_SERVERDESC
: kind
= "dl/server"; break;
2432 case DIR_PURPOSE_FETCH_EXTRAINFO
: kind
= "dl/extra"; break;
2433 case DIR_PURPOSE_UPLOAD_DIR
: kind
= "dl/ul-dir"; break;
2434 case DIR_PURPOSE_UPLOAD_VOTE
: kind
= "dl/ul-vote"; break;
2435 case DIR_PURPOSE_UPLOAD_SIGNATURES
: kind
= "dl/ul-sig"; break;
2436 case DIR_PURPOSE_FETCH_RENDDESC_V2
: kind
= "dl/rend2"; break;
2437 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
: kind
= "dl/ul-rend2"; break;
2440 tor_asprintf(&key
, "%s%s", kind
, compressed
?".z":"");
2442 tor_asprintf(&key
, "unknown purpose (%d)%s",
2443 purpose
, compressed
?".z":"");
2445 note_request(key
, bytes
);
2449 /** Helper: initialize the request map to instrument downloads. */
2451 ensure_request_map_initialized(void)
2454 request_map
= strmap_new();
2457 /** Called when we just transmitted or received <b>bytes</b> worth of data
2458 * because of a request of type <b>key</b> (an arbitrary identifier): adds
2459 * <b>bytes</b> to the total associated with key. */
2461 note_request(const char *key
, size_t bytes
)
2464 ensure_request_map_initialized();
2466 r
= strmap_get(request_map
, key
);
2468 r
= tor_malloc_zero(sizeof(request_t
));
2469 strmap_set(request_map
, key
, r
);
2475 /** Return a newly allocated string holding a summary of bytes used per
2478 directory_dump_request_log(void)
2482 strmap_iter_t
*iter
;
2484 ensure_request_map_initialized();
2486 lines
= smartlist_new();
2488 for (iter
= strmap_iter_init(request_map
);
2489 !strmap_iter_done(iter
);
2490 iter
= strmap_iter_next(request_map
, iter
)) {
2494 strmap_iter_get(iter
, &key
, &val
);
2496 smartlist_add_asprintf(lines
, "%s "U64_FORMAT
" "U64_FORMAT
"\n",
2497 key
, U64_PRINTF_ARG(r
->bytes
), U64_PRINTF_ARG(r
->count
));
2499 smartlist_sort_strings(lines
);
2500 result
= smartlist_join_strings(lines
, "", 0, NULL
);
2501 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
2502 smartlist_free(lines
);
2507 note_client_request(int purpose
, int compressed
, size_t bytes
)
2515 note_request(const char *key
, size_t bytes
)
2522 directory_dump_request_log(void)
2524 return tor_strdup("Not supported.");
2528 /** Decide whether a client would accept the consensus we have.
2530 * Clients can say they only want a consensus if it's signed by more
2531 * than half the authorities in a list. They pass this list in
2532 * the url as "...consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>".
2534 * <b>fpr</b> may be an abbreviated fingerprint, i.e. only a left substring
2535 * of the full authority identity digest. (Only strings of even length,
2536 * i.e. encodings of full bytes, are handled correctly. In the case
2537 * of an odd number of hex digits the last one is silently ignored.)
2539 * Returns 1 if more than half of the requested authorities signed the
2540 * consensus, 0 otherwise.
2543 client_likes_consensus(networkstatus_t
*v
, const char *want_url
)
2545 smartlist_t
*want_authorities
= smartlist_new();
2549 dir_split_resource_into_fingerprints(want_url
, want_authorities
, NULL
, 0);
2550 need_at_least
= smartlist_len(want_authorities
)/2+1;
2551 SMARTLIST_FOREACH_BEGIN(want_authorities
, const char *, d
) {
2552 char want_digest
[DIGEST_LEN
];
2553 size_t want_len
= strlen(d
)/2;
2554 if (want_len
> DIGEST_LEN
)
2555 want_len
= DIGEST_LEN
;
2557 if (base16_decode(want_digest
, DIGEST_LEN
, d
, want_len
*2) < 0) {
2558 log_fn(LOG_PROTOCOL_WARN
, LD_DIR
,
2559 "Failed to decode requested authority digest %s.", escaped(d
));
2563 SMARTLIST_FOREACH_BEGIN(v
->voters
, networkstatus_voter_info_t
*, vi
) {
2564 if (smartlist_len(vi
->sigs
) &&
2565 tor_memeq(vi
->identity_digest
, want_digest
, want_len
)) {
2569 } SMARTLIST_FOREACH_END(vi
);
2571 /* early exit, if we already have enough */
2572 if (have
>= need_at_least
)
2574 } SMARTLIST_FOREACH_END(d
);
2576 SMARTLIST_FOREACH(want_authorities
, char *, d
, tor_free(d
));
2577 smartlist_free(want_authorities
);
2578 return (have
>= need_at_least
);
2581 /** Return the compression level we should use for sending a compressed
2582 * response of size <b>n_bytes</b>. */
2583 static zlib_compression_level_t
2584 choose_compression_level(ssize_t n_bytes
)
2586 if (! have_been_under_memory_pressure()) {
2587 return HIGH_COMPRESSION
; /* we have plenty of RAM. */
2588 } else if (n_bytes
< 0) {
2589 return HIGH_COMPRESSION
; /* unknown; might be big. */
2590 } else if (n_bytes
< 1024) {
2591 return LOW_COMPRESSION
;
2592 } else if (n_bytes
< 2048) {
2593 return MEDIUM_COMPRESSION
;
2595 return HIGH_COMPRESSION
;
2599 /** Helper function: called when a dirserver gets a complete HTTP GET
2600 * request. Look for a request for a directory or for a rendezvous
2601 * service descriptor. On finding one, write a response into
2602 * conn-\>outbuf. If the request is unrecognized, send a 400.
2603 * Always return 0. */
2605 directory_handle_command_get(dir_connection_t
*conn
, const char *headers
,
2606 const char *req_body
, size_t req_body_len
)
2609 char *url
, *url_mem
, *header
;
2610 const or_options_t
*options
= get_options();
2611 time_t if_modified_since
= 0;
2615 /* We ignore the body of a GET request. */
2619 log_debug(LD_DIRSERV
,"Received GET command.");
2621 conn
->base_
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2623 if (parse_http_url(headers
, &url
) < 0) {
2624 write_http_status_line(conn
, 400, "Bad request");
2627 if ((header
= http_get_header(headers
, "If-Modified-Since: "))) {
2629 if (parse_http_time(header
, &tm
) == 0) {
2630 if (tor_timegm(&tm
, &if_modified_since
)<0) {
2631 if_modified_since
= 0;
2633 log_debug(LD_DIRSERV
, "If-Modified-Since is '%s'.", escaped(header
));
2636 /* The correct behavior on a malformed If-Modified-Since header is to
2637 * act as if no If-Modified-Since header had been given. */
2640 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", escaped(url
));
2643 url_len
= strlen(url
);
2644 compressed
= url_len
> 2 && !strcmp(url
+url_len
-2, ".z");
2646 url
[url_len
-2] = '\0';
2650 if (!strcmp(url
,"/tor/")) {
2651 const char *frontpage
= get_dirportfrontpage();
2654 dlen
= strlen(frontpage
);
2655 /* Let's return a disclaimer page (users shouldn't use V1 anymore,
2656 and caches don't fetch '/', so this is safe). */
2658 /* [We don't check for write_bucket_low here, since we want to serve
2659 * this page no matter what.] */
2660 note_request(url
, dlen
);
2661 write_http_response_header_impl(conn
, dlen
, "text/html", "identity",
2662 NULL
, DIRPORTFRONTPAGE_CACHE_LIFETIME
);
2663 connection_write_to_buf(frontpage
, dlen
, TO_CONN(conn
));
2666 /* if no disclaimer file, fall through and continue */
2669 if (!strcmpstart(url
, "/tor/status-vote/current/consensus")) {
2670 /* v3 network status fetch. */
2671 smartlist_t
*dir_fps
= smartlist_new();
2672 const char *request_type
= NULL
;
2673 long lifetime
= NETWORKSTATUS_CACHE_LIFETIME
;
2677 time_t now
= time(NULL
);
2678 const char *want_fps
= NULL
;
2679 char *flavor
= NULL
;
2681 #define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
2682 #define CONSENSUS_FLAVORED_PREFIX "/tor/status-vote/current/consensus-"
2683 /* figure out the flavor if any, and who we wanted to sign the thing */
2684 if (!strcmpstart(url
, CONSENSUS_FLAVORED_PREFIX
)) {
2686 f
= url
+ strlen(CONSENSUS_FLAVORED_PREFIX
);
2687 cp
= strchr(f
, '/');
2690 flavor
= tor_strndup(f
, cp
-f
);
2692 flavor
= tor_strdup(f
);
2694 flav
= networkstatus_parse_flavor_name(flavor
);
2698 if (!strcmpstart(url
, CONSENSUS_URL_PREFIX
))
2699 want_fps
= url
+strlen(CONSENSUS_URL_PREFIX
);
2702 v
= networkstatus_get_latest_consensus_by_flavor(flav
);
2704 if (v
&& want_fps
&&
2705 !client_likes_consensus(v
, want_fps
)) {
2706 write_http_status_line(conn
, 404, "Consensus not signed by sufficient "
2707 "number of requested authorities");
2708 smartlist_free(dir_fps
);
2709 geoip_note_ns_response(GEOIP_REJECT_NOT_ENOUGH_SIGS
);
2715 char *fp
= tor_malloc_zero(DIGEST_LEN
);
2717 strlcpy(fp
, flavor
, DIGEST_LEN
);
2719 smartlist_add(dir_fps
, fp
);
2721 request_type
= compressed
?"v3.z":"v3";
2722 lifetime
= (v
&& v
->fresh_until
> now
) ? v
->fresh_until
- now
: 0;
2725 if (!smartlist_len(dir_fps
)) { /* we failed to create/cache cp */
2726 write_http_status_line(conn
, 503, "Network status object unavailable");
2727 smartlist_free(dir_fps
);
2728 geoip_note_ns_response(GEOIP_REJECT_UNAVAILABLE
);
2732 if (!dirserv_remove_old_statuses(dir_fps
, if_modified_since
)) {
2733 write_http_status_line(conn
, 404, "Not found");
2734 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2735 smartlist_free(dir_fps
);
2736 geoip_note_ns_response(GEOIP_REJECT_NOT_FOUND
);
2738 } else if (!smartlist_len(dir_fps
)) {
2739 write_http_status_line(conn
, 304, "Not modified");
2740 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2741 smartlist_free(dir_fps
);
2742 geoip_note_ns_response(GEOIP_REJECT_NOT_MODIFIED
);
2746 dlen
= dirserv_estimate_data_size(dir_fps
, 0, compressed
);
2747 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2748 log_debug(LD_DIRSERV
,
2749 "Client asked for network status lists, but we've been "
2750 "writing too many bytes lately. Sending 503 Dir busy.");
2751 write_http_status_line(conn
, 503, "Directory busy, try again later");
2752 SMARTLIST_FOREACH(dir_fps
, char *, fp
, tor_free(fp
));
2753 smartlist_free(dir_fps
);
2755 geoip_note_ns_response(GEOIP_REJECT_BUSY
);
2762 if (tor_inet_aton((TO_CONN(conn
))->address
, &in
)) {
2763 tor_addr_from_ipv4h(&addr
, ntohl(in
.s_addr
));
2764 geoip_note_client_seen(GEOIP_CLIENT_NETWORKSTATUS
,
2767 geoip_note_ns_response(GEOIP_SUCCESS
);
2768 /* Note that a request for a network status has started, so that we
2769 * can measure the download time later on. */
2770 if (conn
->dirreq_id
)
2771 geoip_start_dirreq(conn
->dirreq_id
, dlen
, DIRREQ_TUNNELED
);
2773 geoip_start_dirreq(TO_CONN(conn
)->global_identifier
, dlen
,
2778 // note_request(request_type,dlen);
2779 (void) request_type
;
2780 write_http_response_header(conn
, -1, compressed
,
2781 smartlist_len(dir_fps
) == 1 ? lifetime
: 0);
2782 conn
->fingerprint_stack
= dir_fps
;
2784 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
, HIGH_COMPRESSION
);
2786 /* Prime the connection with some data. */
2787 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
2788 connection_dirserv_flushed_some(conn
);
2792 if (!strcmpstart(url
,"/tor/status-vote/current/") ||
2793 !strcmpstart(url
,"/tor/status-vote/next/")) {
2794 /* XXXX If-modified-since is only implemented for the current
2795 * consensus: that's probably fine, since it's the only vote document
2796 * people fetch much. */
2798 ssize_t body_len
= 0;
2799 ssize_t estimated_len
= 0;
2800 smartlist_t
*items
= smartlist_new();
2801 smartlist_t
*dir_items
= smartlist_new();
2802 int lifetime
= 60; /* XXXX023 should actually use vote intervals. */
2803 url
+= strlen("/tor/status-vote/");
2804 current
= !strcmpstart(url
, "current/");
2805 url
= strchr(url
, '/');
2808 if (!strcmp(url
, "consensus")) {
2810 tor_assert(!current
); /* we handle current consensus specially above,
2811 * since it wants to be spooled. */
2812 if ((item
= dirvote_get_pending_consensus(FLAV_NS
)))
2813 smartlist_add(items
, (char*)item
);
2814 } else if (!current
&& !strcmp(url
, "consensus-signatures")) {
2815 /* XXXX the spec says that we should implement
2816 * current/consensus-signatures too. It doesn't seem to be needed,
2819 if ((item
=dirvote_get_pending_detached_signatures()))
2820 smartlist_add(items
, (char*)item
);
2821 } else if (!strcmp(url
, "authority")) {
2822 const cached_dir_t
*d
;
2823 int flags
= DGV_BY_ID
|
2824 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2825 if ((d
=dirvote_get_vote(NULL
, flags
)))
2826 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2828 const cached_dir_t
*d
;
2829 smartlist_t
*fps
= smartlist_new();
2831 if (!strcmpstart(url
, "d/")) {
2833 flags
= DGV_INCLUDE_PENDING
| DGV_INCLUDE_PREVIOUS
;
2836 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2838 dir_split_resource_into_fingerprints(url
, fps
, NULL
,
2839 DSR_HEX
|DSR_SORT_UNIQ
);
2840 SMARTLIST_FOREACH(fps
, char *, fp
, {
2841 if ((d
= dirvote_get_vote(fp
, flags
)))
2842 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2845 smartlist_free(fps
);
2847 if (!smartlist_len(dir_items
) && !smartlist_len(items
)) {
2848 write_http_status_line(conn
, 404, "Not found");
2851 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2852 body_len
+= compressed
? d
->dir_z_len
: d
->dir_len
);
2853 estimated_len
+= body_len
;
2854 SMARTLIST_FOREACH(items
, const char *, item
, {
2855 size_t ln
= strlen(item
);
2857 estimated_len
+= ln
/2;
2859 body_len
+= ln
; estimated_len
+= ln
;
2863 if (global_write_bucket_low(TO_CONN(conn
), estimated_len
, 2)) {
2864 write_http_status_line(conn
, 503, "Directory busy, try again later");
2867 write_http_response_header(conn
, body_len
? body_len
: -1, compressed
,
2870 if (smartlist_len(items
)) {
2872 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
,
2873 choose_compression_level(estimated_len
));
2874 SMARTLIST_FOREACH(items
, const char *, c
,
2875 connection_write_to_buf_zlib(c
, strlen(c
), conn
, 0));
2876 connection_write_to_buf_zlib("", 0, conn
, 1);
2878 SMARTLIST_FOREACH(items
, const char *, c
,
2879 connection_write_to_buf(c
, strlen(c
), TO_CONN(conn
)));
2882 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2883 connection_write_to_buf(compressed
? d
->dir_z
: d
->dir
,
2884 compressed
? d
->dir_z_len
: d
->dir_len
,
2888 smartlist_free(items
);
2889 smartlist_free(dir_items
);
2893 if (!strcmpstart(url
, "/tor/micro/d/")) {
2894 smartlist_t
*fps
= smartlist_new();
2896 dir_split_resource_into_fingerprints(url
+strlen("/tor/micro/d/"),
2898 DSR_DIGEST256
|DSR_BASE64
|DSR_SORT_UNIQ
);
2900 if (!dirserv_have_any_microdesc(fps
)) {
2901 write_http_status_line(conn
, 404, "Not found");
2902 SMARTLIST_FOREACH(fps
, char *, fp
, tor_free(fp
));
2903 smartlist_free(fps
);
2906 dlen
= dirserv_estimate_microdesc_size(fps
, compressed
);
2907 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2908 log_info(LD_DIRSERV
,
2909 "Client asked for server descriptors, but we've been "
2910 "writing too many bytes lately. Sending 503 Dir busy.");
2911 write_http_status_line(conn
, 503, "Directory busy, try again later");
2912 SMARTLIST_FOREACH(fps
, char *, fp
, tor_free(fp
));
2913 smartlist_free(fps
);
2917 write_http_response_header(conn
, -1, compressed
, MICRODESC_CACHE_LIFETIME
);
2918 conn
->dir_spool_src
= DIR_SPOOL_MICRODESC
;
2919 conn
->fingerprint_stack
= fps
;
2922 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
,
2923 choose_compression_level(dlen
));
2925 connection_dirserv_flushed_some(conn
);
2929 if (!strcmpstart(url
,"/tor/server/") ||
2930 (!options
->BridgeAuthoritativeDir
&&
2931 !options
->BridgeRelay
&& !strcmpstart(url
,"/tor/extra/"))) {
2934 const char *request_type
= NULL
;
2935 int cache_lifetime
= 0;
2936 int is_extra
= !strcmpstart(url
,"/tor/extra/");
2937 url
+= is_extra
? strlen("/tor/extra/") : strlen("/tor/server/");
2938 conn
->fingerprint_stack
= smartlist_new();
2939 res
= dirserv_get_routerdesc_fingerprints(conn
->fingerprint_stack
, url
,
2941 !connection_dir_is_encrypted(conn
),
2944 if (!strcmpstart(url
, "fp/")) {
2945 request_type
= compressed
?"/tor/server/fp.z":"/tor/server/fp";
2946 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2947 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2948 } else if (!strcmpstart(url
, "authority")) {
2949 request_type
= compressed
?"/tor/server/authority.z":
2950 "/tor/server/authority";
2951 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2952 } else if (!strcmpstart(url
, "all")) {
2953 request_type
= compressed
?"/tor/server/all.z":"/tor/server/all";
2954 cache_lifetime
= FULL_DIR_CACHE_LIFETIME
;
2955 } else if (!strcmpstart(url
, "d/")) {
2956 request_type
= compressed
?"/tor/server/d.z":"/tor/server/d";
2957 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2958 cache_lifetime
= ROUTERDESC_BY_DIGEST_CACHE_LIFETIME
;
2960 request_type
= "/tor/server/?";
2962 (void) request_type
; /* usable for note_request. */
2963 if (!strcmpstart(url
, "d/"))
2964 conn
->dir_spool_src
=
2965 is_extra
? DIR_SPOOL_EXTRA_BY_DIGEST
: DIR_SPOOL_SERVER_BY_DIGEST
;
2967 conn
->dir_spool_src
=
2968 is_extra
? DIR_SPOOL_EXTRA_BY_FP
: DIR_SPOOL_SERVER_BY_FP
;
2970 if (!dirserv_have_any_serverdesc(conn
->fingerprint_stack
,
2971 conn
->dir_spool_src
)) {
2977 write_http_status_line(conn
, 404, msg
);
2979 dlen
= dirserv_estimate_data_size(conn
->fingerprint_stack
,
2981 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2982 log_info(LD_DIRSERV
,
2983 "Client asked for server descriptors, but we've been "
2984 "writing too many bytes lately. Sending 503 Dir busy.");
2985 write_http_status_line(conn
, 503, "Directory busy, try again later");
2986 conn
->dir_spool_src
= DIR_SPOOL_NONE
;
2989 write_http_response_header(conn
, -1, compressed
, cache_lifetime
);
2991 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
,
2992 choose_compression_level(dlen
));
2993 /* Prime the connection with some data. */
2994 connection_dirserv_flushed_some(conn
);
2999 if (!strcmpstart(url
,"/tor/keys/")) {
3000 smartlist_t
*certs
= smartlist_new();
3002 if (!strcmp(url
, "/tor/keys/all")) {
3003 authority_cert_get_all(certs
);
3004 } else if (!strcmp(url
, "/tor/keys/authority")) {
3005 authority_cert_t
*cert
= get_my_v3_authority_cert();
3007 smartlist_add(certs
, cert
);
3008 } else if (!strcmpstart(url
, "/tor/keys/fp/")) {
3009 smartlist_t
*fps
= smartlist_new();
3010 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/fp/"),
3012 DSR_HEX
|DSR_SORT_UNIQ
);
3013 SMARTLIST_FOREACH(fps
, char *, d
, {
3014 authority_cert_t
*c
= authority_cert_get_newest_by_id(d
);
3015 if (c
) smartlist_add(certs
, c
);
3018 smartlist_free(fps
);
3019 } else if (!strcmpstart(url
, "/tor/keys/sk/")) {
3020 smartlist_t
*fps
= smartlist_new();
3021 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/sk/"),
3023 DSR_HEX
|DSR_SORT_UNIQ
);
3024 SMARTLIST_FOREACH(fps
, char *, d
, {
3025 authority_cert_t
*c
= authority_cert_get_by_sk_digest(d
);
3026 if (c
) smartlist_add(certs
, c
);
3029 smartlist_free(fps
);
3030 } else if (!strcmpstart(url
, "/tor/keys/fp-sk/")) {
3031 smartlist_t
*fp_sks
= smartlist_new();
3032 dir_split_resource_into_fingerprint_pairs(url
+strlen("/tor/keys/fp-sk/"),
3034 SMARTLIST_FOREACH(fp_sks
, fp_pair_t
*, pair
, {
3035 authority_cert_t
*c
= authority_cert_get_by_digests(pair
->first
,
3037 if (c
) smartlist_add(certs
, c
);
3040 smartlist_free(fp_sks
);
3042 write_http_status_line(conn
, 400, "Bad request");
3045 if (!smartlist_len(certs
)) {
3046 write_http_status_line(conn
, 404, "Not found");
3049 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
3050 if (c
->cache_info
.published_on
< if_modified_since
)
3051 SMARTLIST_DEL_CURRENT(certs
, c
));
3052 if (!smartlist_len(certs
)) {
3053 write_http_status_line(conn
, 304, "Not modified");
3057 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
3058 len
+= c
->cache_info
.signed_descriptor_len
);
3060 if (global_write_bucket_low(TO_CONN(conn
), compressed
?len
/2:len
, 2)) {
3061 write_http_status_line(conn
, 503, "Directory busy, try again later");
3065 write_http_response_header(conn
, compressed
?-1:len
, compressed
, 60*60);
3067 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
,
3068 choose_compression_level(len
));
3069 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
3070 connection_write_to_buf_zlib(c
->cache_info
.signed_descriptor_body
,
3071 c
->cache_info
.signed_descriptor_len
,
3073 connection_write_to_buf_zlib("", 0, conn
, 1);
3075 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
3076 connection_write_to_buf(c
->cache_info
.signed_descriptor_body
,
3077 c
->cache_info
.signed_descriptor_len
,
3081 smartlist_free(certs
);
3085 if (connection_dir_is_encrypted(conn
) &&
3086 !strcmpstart(url
,"/tor/rendezvous2/")) {
3087 /* Handle v2 rendezvous descriptor fetch request. */
3089 const char *query
= url
+ strlen("/tor/rendezvous2/");
3090 if (rend_valid_descriptor_id(query
)) {
3091 log_info(LD_REND
, "Got a v2 rendezvous descriptor request for ID '%s'",
3092 safe_str(escaped(query
)));
3093 switch (rend_cache_lookup_v2_desc_as_dir(query
, &descp
)) {
3095 write_http_response_header(conn
, strlen(descp
), 0, 0);
3096 connection_write_to_buf(descp
, strlen(descp
), TO_CONN(conn
));
3098 case 0: /* well-formed but not present */
3099 write_http_status_line(conn
, 404, "Not found");
3101 case -1: /* not well-formed */
3102 write_http_status_line(conn
, 400, "Bad request");
3105 } else { /* not well-formed */
3106 write_http_status_line(conn
, 400, "Bad request");
3111 if (options
->BridgeAuthoritativeDir
&&
3112 options
->BridgePassword_AuthDigest_
&&
3113 connection_dir_is_encrypted(conn
) &&
3114 !strcmp(url
,"/tor/networkstatus-bridges")) {
3116 char digest
[DIGEST256_LEN
];
3118 header
= http_get_header(headers
, "Authorization: Basic ");
3120 crypto_digest256(digest
, header
, strlen(header
), DIGEST_SHA256
);
3122 /* now make sure the password is there and right */
3125 options
->BridgePassword_AuthDigest_
, DIGEST256_LEN
)) {
3126 write_http_status_line(conn
, 404, "Not found");
3132 /* all happy now. send an answer. */
3133 status
= networkstatus_getinfo_by_purpose("bridge", time(NULL
));
3134 dlen
= strlen(status
);
3135 write_http_response_header(conn
, dlen
, 0, 0);
3136 connection_write_to_buf(status
, dlen
, TO_CONN(conn
));
3141 if (!strcmpstart(url
,"/tor/bytes.txt")) {
3142 char *bytes
= directory_dump_request_log();
3143 size_t len
= strlen(bytes
);
3144 write_http_response_header(conn
, len
, 0, 0);
3145 connection_write_to_buf(bytes
, len
, TO_CONN(conn
));
3150 if (!strcmp(url
,"/tor/robots.txt")) { /* /robots.txt will have been
3151 rewritten to /tor/robots.txt */
3152 char robots
[] = "User-agent: *\r\nDisallow: /\r\n";
3153 size_t len
= strlen(robots
);
3154 write_http_response_header(conn
, len
, 0, ROBOTS_CACHE_LIFETIME
);
3155 connection_write_to_buf(robots
, len
, TO_CONN(conn
));
3159 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
3160 #define ADD_MALLINFO_LINE(x) do { \
3161 smartlist_add_asprintf(lines, "%s %d\n", #x, mi.x); \
3164 if (!strcmp(url
,"/tor/mallinfo.txt") &&
3165 (tor_addr_eq_ipv4h(&conn
->base_
.addr
, 0x7f000001ul
))) {
3171 memset(&mi
, 0, sizeof(mi
));
3173 lines
= smartlist_new();
3175 ADD_MALLINFO_LINE(arena
)
3176 ADD_MALLINFO_LINE(ordblks
)
3177 ADD_MALLINFO_LINE(smblks
)
3178 ADD_MALLINFO_LINE(hblks
)
3179 ADD_MALLINFO_LINE(hblkhd
)
3180 ADD_MALLINFO_LINE(usmblks
)
3181 ADD_MALLINFO_LINE(fsmblks
)
3182 ADD_MALLINFO_LINE(uordblks
)
3183 ADD_MALLINFO_LINE(fordblks
)
3184 ADD_MALLINFO_LINE(keepcost
)
3186 result
= smartlist_join_strings(lines
, "", 0, NULL
);
3187 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
3188 smartlist_free(lines
);
3190 len
= strlen(result
);
3191 write_http_response_header(conn
, len
, 0, 0);
3192 connection_write_to_buf(result
, len
, TO_CONN(conn
));
3198 /* we didn't recognize the url */
3199 write_http_status_line(conn
, 404, "Not found");
3206 /** Helper function: called when a dirserver gets a complete HTTP POST
3207 * request. Look for an uploaded server descriptor or rendezvous
3208 * service descriptor. On finding one, process it and write a
3209 * response into conn-\>outbuf. If the request is unrecognized, send a
3210 * 400. Always return 0. */
3212 directory_handle_command_post(dir_connection_t
*conn
, const char *headers
,
3213 const char *body
, size_t body_len
)
3216 const or_options_t
*options
= get_options();
3218 log_debug(LD_DIRSERV
,"Received POST command.");
3220 conn
->base_
.state
= DIR_CONN_STATE_SERVER_WRITING
;
3222 if (parse_http_url(headers
, &url
) < 0) {
3223 write_http_status_line(conn
, 400, "Bad request");
3226 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", escaped(url
));
3228 /* Handle v2 rendezvous service publish request. */
3229 if (connection_dir_is_encrypted(conn
) &&
3230 !strcmpstart(url
,"/tor/rendezvous2/publish")) {
3231 switch (rend_cache_store_v2_desc_as_dir(body
)) {
3233 log_info(LD_REND
, "Rejected v2 rend descriptor (length %d) from %s "
3234 "since we're not currently a hidden service directory.",
3235 (int)body_len
, conn
->base_
.address
);
3236 write_http_status_line(conn
, 503, "Currently not acting as v2 "
3237 "hidden service directory");
3240 log_warn(LD_REND
, "Rejected v2 rend descriptor (length %d) from %s.",
3241 (int)body_len
, conn
->base_
.address
);
3242 write_http_status_line(conn
, 400,
3243 "Invalid v2 service descriptor rejected");
3247 write_http_status_line(conn
, 200, "Service descriptor (v2) stored");
3248 log_info(LD_REND
, "Handled v2 rendezvous descriptor post: accepted");
3253 if (!authdir_mode(options
)) {
3254 /* we just provide cached directories; we don't want to
3255 * receive anything. */
3256 write_http_status_line(conn
, 400, "Nonauthoritative directory does not "
3257 "accept posted server descriptors");
3261 if (authdir_mode_handles_descs(options
, -1) &&
3262 !strcmp(url
,"/tor/")) { /* server descriptor post */
3263 const char *msg
= "[None]";
3264 uint8_t purpose
= authdir_mode_bridge(options
) ?
3265 ROUTER_PURPOSE_BRIDGE
: ROUTER_PURPOSE_GENERAL
;
3266 was_router_added_t r
= dirserv_add_multiple_descriptors(body
, purpose
,
3267 conn
->base_
.address
, &msg
);
3270 if (r
== ROUTER_ADDED_NOTIFY_GENERATOR
) {
3271 /* Accepted with a message. */
3272 log_info(LD_DIRSERV
,
3273 "Problematic router descriptor or extra-info from %s "
3275 conn
->base_
.address
, msg
);
3276 write_http_status_line(conn
, 400, msg
);
3277 } else if (r
== ROUTER_ADDED_SUCCESSFULLY
) {
3278 write_http_status_line(conn
, 200, msg
);
3279 } else if (WRA_WAS_OUTDATED(r
)) {
3280 write_http_response_header_impl(conn
, -1, NULL
, NULL
,
3281 "X-Descriptor-Not-New: Yes\r\n", -1);
3283 log_info(LD_DIRSERV
,
3284 "Rejected router descriptor or extra-info from %s "
3286 conn
->base_
.address
, msg
);
3287 write_http_status_line(conn
, 400, msg
);
3292 if (authdir_mode_v3(options
) &&
3293 !strcmp(url
,"/tor/post/vote")) { /* v3 networkstatus vote */
3294 const char *msg
= "OK";
3296 if (dirvote_add_vote(body
, &msg
, &status
)) {
3297 write_http_status_line(conn
, status
, "Vote stored");
3300 log_warn(LD_DIRSERV
, "Rejected vote from %s (\"%s\").",
3301 conn
->base_
.address
, msg
);
3302 write_http_status_line(conn
, status
, msg
);
3307 if (authdir_mode_v3(options
) &&
3308 !strcmp(url
,"/tor/post/consensus-signature")) { /* sigs on consensus. */
3309 const char *msg
= NULL
;
3310 if (dirvote_add_signatures(body
, conn
->base_
.address
, &msg
)>=0) {
3311 write_http_status_line(conn
, 200, msg
?msg
:"Signatures stored");
3313 log_warn(LD_DIR
, "Unable to store signatures posted by %s: %s",
3314 conn
->base_
.address
, msg
?msg
:"???");
3315 write_http_status_line(conn
, 400, msg
?msg
:"Unable to store signatures");
3320 /* we didn't recognize the url */
3321 write_http_status_line(conn
, 404, "Not found");
3328 /** Called when a dirserver receives data on a directory connection;
3329 * looks for an HTTP request. If the request is complete, remove it
3330 * from the inbuf, try to process it; otherwise, leave it on the
3331 * buffer. Return a 0 on success, or -1 on error.
3334 directory_handle_command(dir_connection_t
*conn
)
3336 char *headers
=NULL
, *body
=NULL
;
3341 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
3343 switch (connection_fetch_from_buf_http(TO_CONN(conn
),
3344 &headers
, MAX_HEADERS_SIZE
,
3345 &body
, &body_len
, MAX_DIR_UL_SIZE
, 0)) {
3346 case -1: /* overflow */
3347 log_warn(LD_DIRSERV
,
3348 "Request too large from address '%s' to DirPort. Closing.",
3349 safe_str(conn
->base_
.address
));
3352 log_debug(LD_DIRSERV
,"command not all here yet.");
3354 /* case 1, fall through */
3357 http_set_address_origin(headers
, TO_CONN(conn
));
3358 // we should escape headers here as well,
3359 // but we can't call escaped() twice, as it uses the same buffer
3360 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, escaped(body));
3362 if (!strncasecmp(headers
,"GET",3))
3363 r
= directory_handle_command_get(conn
, headers
, body
, body_len
);
3364 else if (!strncasecmp(headers
,"POST",4))
3365 r
= directory_handle_command_post(conn
, headers
, body
, body_len
);
3367 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
3368 "Got headers %s with unknown command. Closing.",
3373 tor_free(headers
); tor_free(body
);
3377 /** Write handler for directory connections; called when all data has
3378 * been flushed. Close the connection or wait for a response as
3382 connection_dir_finished_flushing(dir_connection_t
*conn
)
3385 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
3387 /* Note that we have finished writing the directory response. For direct
3388 * connections this means we're done; for tunneled connections it's only
3389 * an intermediate step. */
3390 if (conn
->dirreq_id
)
3391 geoip_change_dirreq_state(conn
->dirreq_id
, DIRREQ_TUNNELED
,
3392 DIRREQ_FLUSHING_DIR_CONN_FINISHED
);
3394 geoip_change_dirreq_state(TO_CONN(conn
)->global_identifier
,
3396 DIRREQ_FLUSHING_DIR_CONN_FINISHED
);
3397 switch (conn
->base_
.state
) {
3398 case DIR_CONN_STATE_CONNECTING
:
3399 case DIR_CONN_STATE_CLIENT_SENDING
:
3400 log_debug(LD_DIR
,"client finished sending command.");
3401 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_READING
;
3403 case DIR_CONN_STATE_SERVER_WRITING
:
3404 if (conn
->dir_spool_src
!= DIR_SPOOL_NONE
) {
3405 #ifdef USE_BUFFEREVENTS
3406 /* This can happen with paired bufferevents, since a paired connection
3407 * can flush immediately when you write to it, making the subsequent
3408 * check in connection_handle_write_cb() decide that the connection
3410 log_debug(LD_DIRSERV
, "Emptied a dirserv buffer, but still spooling.");
3412 log_warn(LD_BUG
, "Emptied a dirserv buffer, but it's still spooling!");
3413 connection_mark_for_close(TO_CONN(conn
));
3416 log_debug(LD_DIRSERV
, "Finished writing server response. Closing.");
3417 connection_mark_for_close(TO_CONN(conn
));
3421 log_warn(LD_BUG
,"called in unexpected state %d.",
3423 tor_fragile_assert();
3429 /** Connected handler for directory connections: begin sending data to the
3432 connection_dir_finished_connecting(dir_connection_t
*conn
)
3435 tor_assert(conn
->base_
.type
== CONN_TYPE_DIR
);
3436 tor_assert(conn
->base_
.state
== DIR_CONN_STATE_CONNECTING
);
3438 log_debug(LD_HTTP
,"Dir connection to router %s:%u established.",
3439 conn
->base_
.address
,conn
->base_
.port
);
3441 conn
->base_
.state
= DIR_CONN_STATE_CLIENT_SENDING
; /* start flushing conn */
3445 /** Decide which download schedule we want to use based on descriptor type
3446 * in <b>dls</b> and whether we are acting as directory <b>server</b>, and
3447 * then return a list of int pointers defining download delays in seconds.
3448 * Helper function for download_status_increment_failure() and
3449 * download_status_reset(). */
3450 static const smartlist_t
*
3451 find_dl_schedule_and_len(download_status_t
*dls
, int server
)
3453 switch (dls
->schedule
) {
3454 case DL_SCHED_GENERIC
:
3456 return get_options()->TestingServerDownloadSchedule
;
3458 return get_options()->TestingClientDownloadSchedule
;
3459 case DL_SCHED_CONSENSUS
:
3461 return get_options()->TestingServerConsensusDownloadSchedule
;
3463 return get_options()->TestingClientConsensusDownloadSchedule
;
3464 case DL_SCHED_BRIDGE
:
3465 return get_options()->TestingBridgeDownloadSchedule
;
3470 /* Impossible, but gcc will fail with -Werror without a `return`. */
3474 /** Called when an attempt to download <b>dls</b> has failed with HTTP status
3475 * <b>status_code</b>. Increment the failure count (if the code indicates a
3476 * real failure) and set <b>dls</b>-\>next_attempt_at to an appropriate time
3479 download_status_increment_failure(download_status_t
*dls
, int status_code
,
3480 const char *item
, int server
, time_t now
)
3482 const smartlist_t
*schedule
;
3485 if (status_code
!= 503 || server
) {
3486 if (dls
->n_download_failures
< IMPOSSIBLE_TO_DOWNLOAD
-1)
3487 ++dls
->n_download_failures
;
3490 schedule
= find_dl_schedule_and_len(dls
, server
);
3492 if (dls
->n_download_failures
< smartlist_len(schedule
))
3493 increment
= *(int *)smartlist_get(schedule
, dls
->n_download_failures
);
3494 else if (dls
->n_download_failures
== IMPOSSIBLE_TO_DOWNLOAD
)
3495 increment
= INT_MAX
;
3497 increment
= *(int *)smartlist_get(schedule
, smartlist_len(schedule
) - 1);
3499 if (increment
< INT_MAX
)
3500 dls
->next_attempt_at
= now
+increment
;
3502 dls
->next_attempt_at
= TIME_MAX
;
3506 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again immediately.",
3507 item
, (int)dls
->n_download_failures
);
3508 else if (dls
->next_attempt_at
< TIME_MAX
)
3509 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again in %d seconds.",
3510 item
, (int)dls
->n_download_failures
,
3511 (int)(dls
->next_attempt_at
-now
));
3513 log_debug(LD_DIR
, "%s failed %d time(s); Giving up for a while.",
3514 item
, (int)dls
->n_download_failures
);
3516 return dls
->next_attempt_at
;
3519 /** Reset <b>dls</b> so that it will be considered downloadable
3520 * immediately, and/or to show that we don't need it anymore.
3522 * (We find the zeroth element of the download schedule, and set
3523 * next_attempt_at to be the appropriate offset from 'now'. In most
3524 * cases this means setting it to 'now', so the item will be immediately
3525 * downloadable; in the case of bridge descriptors, the zeroth element
3526 * is an hour from now.) */
3528 download_status_reset(download_status_t
*dls
)
3530 if (dls
->n_download_failures
== IMPOSSIBLE_TO_DOWNLOAD
)
3531 return; /* Don't reset this. */
3533 const smartlist_t
*schedule
= find_dl_schedule_and_len(
3534 dls
, get_options()->DirPort_set
);
3536 dls
->n_download_failures
= 0;
3537 dls
->next_attempt_at
= time(NULL
) + *(int *)smartlist_get(schedule
, 0);
3540 /** Return the number of failures on <b>dls</b> since the last success (if
3543 download_status_get_n_failures(const download_status_t
*dls
)
3545 return dls
->n_download_failures
;
3548 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
3549 * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
3550 * either as descriptor digests or as identity digests based on
3551 * <b>was_descriptor_digests</b>).
3554 dir_routerdesc_download_failed(smartlist_t
*failed
, int status_code
,
3556 int was_extrainfo
, int was_descriptor_digests
)
3558 char digest
[DIGEST_LEN
];
3559 time_t now
= time(NULL
);
3560 int server
= directory_fetches_from_authorities(get_options());
3561 if (!was_descriptor_digests
) {
3562 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
) {
3563 tor_assert(!was_extrainfo
);
3564 connection_dir_retry_bridges(failed
);
3566 return; /* FFFF should implement for other-than-router-purpose someday */
3568 SMARTLIST_FOREACH_BEGIN(failed
, const char *, cp
) {
3569 download_status_t
*dls
= NULL
;
3570 if (base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
)) < 0) {
3571 log_warn(LD_BUG
, "Malformed fingerprint in list: %s", escaped(cp
));
3574 if (was_extrainfo
) {
3575 signed_descriptor_t
*sd
=
3576 router_get_by_extrainfo_digest(digest
);
3578 dls
= &sd
->ei_dl_status
;
3580 dls
= router_get_dl_status_by_descriptor_digest(digest
);
3582 if (!dls
|| dls
->n_download_failures
>=
3583 get_options()->TestingDescriptorMaxDownloadTries
)
3585 download_status_increment_failure(dls
, status_code
, cp
, server
, now
);
3586 } SMARTLIST_FOREACH_END(cp
);
3588 /* No need to relaunch descriptor downloads here: we already do it
3589 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
3592 /** Called when a connection to download microdescriptors has failed in whole
3593 * or in part. <b>failed</b> is a list of every microdesc digest we didn't
3594 * get. <b>status_code</b> is the http status code we received. Reschedule the
3595 * microdesc downloads as appropriate. */
3597 dir_microdesc_download_failed(smartlist_t
*failed
,
3600 networkstatus_t
*consensus
3601 = networkstatus_get_latest_consensus_by_flavor(FLAV_MICRODESC
);
3603 download_status_t
*dls
;
3604 time_t now
= time(NULL
);
3605 int server
= directory_fetches_from_authorities(get_options());
3609 SMARTLIST_FOREACH_BEGIN(failed
, const char *, d
) {
3610 rs
= router_get_mutable_consensus_status_by_descriptor_digest(consensus
,d
);
3613 dls
= &rs
->dl_status
;
3614 if (dls
->n_download_failures
>=
3615 get_options()->TestingMicrodescMaxDownloadTries
)
3618 char buf
[BASE64_DIGEST256_LEN
+1];
3619 digest256_to_base64(buf
, d
);
3620 download_status_increment_failure(dls
, status_code
, buf
,
3623 } SMARTLIST_FOREACH_END(d
);
3626 /** Helper. Compare two fp_pair_t objects, and return negative, 0, or
3627 * positive as appropriate. */
3629 compare_pairs_(const void **a
, const void **b
)
3631 const fp_pair_t
*fp1
= *a
, *fp2
= *b
;
3633 if ((r
= fast_memcmp(fp1
->first
, fp2
->first
, DIGEST_LEN
)))
3636 return fast_memcmp(fp1
->second
, fp2
->second
, DIGEST_LEN
);
3639 /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
3640 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
3641 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
3642 * fp_pair_t into <b>pairs_out</b>. On failure, return -1. */
3644 dir_split_resource_into_fingerprint_pairs(const char *res
,
3645 smartlist_t
*pairs_out
)
3647 smartlist_t
*pairs_tmp
= smartlist_new();
3648 smartlist_t
*pairs_result
= smartlist_new();
3650 smartlist_split_string(pairs_tmp
, res
, "+", 0, 0);
3651 if (smartlist_len(pairs_tmp
)) {
3652 char *last
= smartlist_get(pairs_tmp
,smartlist_len(pairs_tmp
)-1);
3653 size_t last_len
= strlen(last
);
3654 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
3655 last
[last_len
-2] = '\0';
3658 SMARTLIST_FOREACH_BEGIN(pairs_tmp
, char *, cp
) {
3659 if (strlen(cp
) != HEX_DIGEST_LEN
*2+1) {
3661 "Skipping digest pair %s with non-standard length.", escaped(cp
));
3662 } else if (cp
[HEX_DIGEST_LEN
] != '-') {
3664 "Skipping digest pair %s with missing dash.", escaped(cp
));
3667 if (base16_decode(pair
.first
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
)<0 ||
3668 base16_decode(pair
.second
,
3669 DIGEST_LEN
, cp
+HEX_DIGEST_LEN
+1, HEX_DIGEST_LEN
)<0) {
3670 log_info(LD_DIR
, "Skipping non-decodable digest pair %s", escaped(cp
));
3672 smartlist_add(pairs_result
, tor_memdup(&pair
, sizeof(pair
)));
3676 } SMARTLIST_FOREACH_END(cp
);
3677 smartlist_free(pairs_tmp
);
3680 smartlist_sort(pairs_result
, compare_pairs_
);
3681 smartlist_uniq(pairs_result
, compare_pairs_
, tor_free_
);
3683 smartlist_add_all(pairs_out
, pairs_result
);
3684 smartlist_free(pairs_result
);
3688 /** Given a directory <b>resource</b> request, containing zero
3689 * or more strings separated by plus signs, followed optionally by ".z", store
3690 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
3691 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.
3693 * If (flags & DSR_HEX), then delete all elements that aren't hex digests, and
3694 * decode the rest. If (flags & DSR_BASE64), then use "-" rather than "+" as
3695 * a separator, delete all the elements that aren't base64-encoded digests,
3696 * and decode the rest. If (flags & DSR_DIGEST256), these digests should be
3697 * 256 bits long; else they should be 160.
3699 * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
3702 dir_split_resource_into_fingerprints(const char *resource
,
3703 smartlist_t
*fp_out
, int *compressed_out
,
3706 const int decode_hex
= flags
& DSR_HEX
;
3707 const int decode_base64
= flags
& DSR_BASE64
;
3708 const int digests_are_256
= flags
& DSR_DIGEST256
;
3709 const int sort_uniq
= flags
& DSR_SORT_UNIQ
;
3711 const int digest_len
= digests_are_256
? DIGEST256_LEN
: DIGEST_LEN
;
3712 const int hex_digest_len
= digests_are_256
?
3713 HEX_DIGEST256_LEN
: HEX_DIGEST_LEN
;
3714 const int base64_digest_len
= digests_are_256
?
3715 BASE64_DIGEST256_LEN
: BASE64_DIGEST_LEN
;
3716 smartlist_t
*fp_tmp
= smartlist_new();
3718 tor_assert(!(decode_hex
&& decode_base64
));
3721 smartlist_split_string(fp_tmp
, resource
, decode_base64
?"-":"+", 0, 0);
3723 *compressed_out
= 0;
3724 if (smartlist_len(fp_tmp
)) {
3725 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
3726 size_t last_len
= strlen(last
);
3727 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
3728 last
[last_len
-2] = '\0';
3730 *compressed_out
= 1;
3733 if (decode_hex
|| decode_base64
) {
3734 const size_t encoded_len
= decode_hex
? hex_digest_len
: base64_digest_len
;
3736 char *cp
, *d
= NULL
;
3737 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
3738 cp
= smartlist_get(fp_tmp
, i
);
3739 if (strlen(cp
) != encoded_len
) {
3741 "Skipping digest %s with non-standard length.", escaped(cp
));
3742 smartlist_del_keeporder(fp_tmp
, i
--);
3745 d
= tor_malloc_zero(digest_len
);
3747 (base16_decode(d
, digest_len
, cp
, hex_digest_len
)<0) :
3748 (base64_decode(d
, digest_len
, cp
, base64_digest_len
)<0)) {
3749 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
3750 smartlist_del_keeporder(fp_tmp
, i
--);
3753 smartlist_set(fp_tmp
, i
, d
);
3761 if (decode_hex
|| decode_base64
) {
3762 if (digests_are_256
) {
3763 smartlist_sort_digests256(fp_tmp
);
3764 smartlist_uniq_digests256(fp_tmp
);
3766 smartlist_sort_digests(fp_tmp
);
3767 smartlist_uniq_digests(fp_tmp
);
3770 smartlist_sort_strings(fp_tmp
);
3771 smartlist_uniq_strings(fp_tmp
);
3774 smartlist_add_all(fp_out
, fp_tmp
);
3775 smartlist_free(fp_tmp
);