1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2010, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
7 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
15 * \brief Code to send and fetch directories and router
16 * descriptors via HTTP. Directories use dirserv.c to generate the
17 * results; clients use routers.c to parse them.
20 /* In-points to directory.c:
22 * - directory_post_to_dirservers(), called from
23 * router_upload_dir_desc_to_dirservers() in router.c
24 * upload_service_descriptor() in rendservice.c
25 * - directory_get_from_dirserver(), called from
26 * rend_client_refetch_renddesc() in rendclient.c
27 * run_scheduled_events() in main.c
29 * - connection_dir_process_inbuf(), called from
30 * connection_process_inbuf() in connection.c
31 * - connection_dir_finished_flushing(), called from
32 * connection_finished_flushing() in connection.c
33 * - connection_dir_finished_connecting(), called from
34 * connection_finished_connecting() in connection.c
36 static void directory_send_command(dir_connection_t
*conn
,
37 int purpose
, int direct
, const char *resource
,
38 const char *payload
, size_t payload_len
,
39 int supports_conditional_consensus
,
40 time_t if_modified_since
);
41 static int directory_handle_command(dir_connection_t
*conn
);
42 static int body_is_plausible(const char *body
, size_t body_len
, int purpose
);
43 static int purpose_needs_anonymity(uint8_t dir_purpose
,
44 uint8_t router_purpose
);
45 static char *http_get_header(const char *headers
, const char *which
);
46 static void http_set_address_origin(const char *headers
, connection_t
*conn
);
47 static void connection_dir_download_networkstatus_failed(
48 dir_connection_t
*conn
, int status_code
);
49 static void connection_dir_download_routerdesc_failed(dir_connection_t
*conn
);
50 static void connection_dir_download_cert_failed(
51 dir_connection_t
*conn
, int status_code
);
52 static void dir_networkstatus_download_failed(smartlist_t
*failed
,
54 static void dir_routerdesc_download_failed(smartlist_t
*failed
,
58 int was_descriptor_digests
);
59 static void note_client_request(int purpose
, int compressed
, size_t bytes
);
60 static int client_likes_consensus(networkstatus_t
*v
, const char *want_url
);
62 static void directory_initiate_command_rend(const char *address
,
63 const tor_addr_t
*addr
,
66 int supports_conditional_consensus
,
67 int supports_begindir
,
70 uint8_t router_purpose
,
71 int anonymized_connection
,
75 time_t if_modified_since
,
76 const rend_data_t
*rend_query
);
78 /********* START VARIABLES **********/
80 /** How far in the future do we allow a directory server to tell us it is
81 * before deciding that one of us has the wrong time? */
82 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
84 #define X_ADDRESS_HEADER "X-Your-Address-Is: "
86 /** HTTP cache control: how long do we tell proxies they can cache each
87 * kind of document we serve? */
88 #define FULL_DIR_CACHE_LIFETIME (60*60)
89 #define RUNNINGROUTERS_CACHE_LIFETIME (20*60)
90 #define DIRPORTFRONTPAGE_CACHE_LIFETIME (20*60)
91 #define NETWORKSTATUS_CACHE_LIFETIME (5*60)
92 #define ROUTERDESC_CACHE_LIFETIME (30*60)
93 #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
94 #define ROBOTS_CACHE_LIFETIME (24*60*60)
95 #define MICRODESC_CACHE_LIFETIME (48*60*60)
97 /********* END VARIABLES ************/
99 /** Return true iff the directory purpose <b>dir_purpose</b> (and if it's
100 * fetching descriptors, it's fetching them for <b>router_purpose</b>)
101 * must use an anonymous connection to a directory. */
103 purpose_needs_anonymity(uint8_t dir_purpose
, uint8_t router_purpose
)
105 if (get_options()->AllDirActionsPrivate
)
107 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
&& has_completed_circuit
)
108 return 1; /* if no circuits yet, we may need this info to bootstrap. */
109 if (dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
||
110 dir_purpose
== DIR_PURPOSE_UPLOAD_VOTE
||
111 dir_purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
||
112 dir_purpose
== DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
||
113 dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
114 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
||
115 dir_purpose
== DIR_PURPOSE_FETCH_CONSENSUS
||
116 dir_purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
||
117 dir_purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
118 dir_purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
)
123 /** Return a newly allocated string describing <b>auth</b>. */
125 authority_type_to_string(authority_type_t auth
)
128 smartlist_t
*lst
= smartlist_create();
129 if (auth
& V1_AUTHORITY
)
130 smartlist_add(lst
, (void*)"V1");
131 if (auth
& V2_AUTHORITY
)
132 smartlist_add(lst
, (void*)"V2");
133 if (auth
& V3_AUTHORITY
)
134 smartlist_add(lst
, (void*)"V3");
135 if (auth
& BRIDGE_AUTHORITY
)
136 smartlist_add(lst
, (void*)"Bridge");
137 if (auth
& HIDSERV_AUTHORITY
)
138 smartlist_add(lst
, (void*)"Hidden service");
139 if (smartlist_len(lst
)) {
140 result
= smartlist_join_strings(lst
, ", ", 0, NULL
);
142 result
= tor_strdup("[Not an authority]");
148 /** Return a string describing a given directory connection purpose. */
150 dir_conn_purpose_to_string(int purpose
)
154 case DIR_PURPOSE_FETCH_RENDDESC
:
155 return "hidden-service descriptor fetch";
156 case DIR_PURPOSE_UPLOAD_DIR
:
157 return "server descriptor upload";
158 case DIR_PURPOSE_UPLOAD_RENDDESC
:
159 return "hidden-service descriptor upload";
160 case DIR_PURPOSE_UPLOAD_VOTE
:
161 return "server vote upload";
162 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
163 return "consensus signature upload";
164 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
:
165 return "network-status fetch";
166 case DIR_PURPOSE_FETCH_SERVERDESC
:
167 return "server descriptor fetch";
168 case DIR_PURPOSE_FETCH_EXTRAINFO
:
169 return "extra-info fetch";
170 case DIR_PURPOSE_FETCH_CONSENSUS
:
171 return "consensus network-status fetch";
172 case DIR_PURPOSE_FETCH_CERTIFICATE
:
173 return "authority cert fetch";
174 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
175 return "status vote fetch";
176 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
177 return "consensus signature fetch";
178 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
179 return "hidden-service v2 descriptor fetch";
180 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
181 return "hidden-service v2 descriptor upload";
184 log_warn(LD_BUG
, "Called with unknown purpose %d", purpose
);
188 /** Return true iff <b>identity_digest</b> is the digest of a router we
189 * believe to support extrainfo downloads. (If <b>is_authority</b> we do
190 * additional checking that's only valid for authorities.) */
192 router_supports_extrainfo(const char *identity_digest
, int is_authority
)
194 routerinfo_t
*ri
= router_get_by_digest(identity_digest
);
197 if (ri
->caches_extra_info
)
199 if (is_authority
&& ri
->platform
&&
200 tor_version_as_new_as(ri
->platform
, "Tor 0.2.0.0-alpha-dev (r10070)"))
204 routerstatus_t
*rs
= router_get_consensus_status_by_id(identity_digest
);
205 if (rs
&& rs
->version_supports_extrainfo_upload
)
211 /** Return true iff any trusted directory authority has accepted our
214 * We consider any authority sufficient because waiting for all of
215 * them means it never happens while any authority is down; we don't
216 * go for something more complex in the middle (like \>1/3 or \>1/2 or
217 * \>=1/2) because that doesn't seem necessary yet.
220 directories_have_accepted_server_descriptor(void)
222 smartlist_t
*servers
= router_get_trusted_dir_servers();
223 or_options_t
*options
= get_options();
224 SMARTLIST_FOREACH(servers
, trusted_dir_server_t
*, d
, {
225 if ((d
->type
& options
->_PublishServerDescriptor
) &&
226 d
->has_accepted_serverdesc
) {
233 /** Start a connection to every suitable directory authority, using
234 * connection purpose 'purpose' and uploading the payload 'payload'
235 * (length 'payload_len'). dir_purpose should be one of
236 * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
238 * <b>type</b> specifies what sort of dir authorities (V1, V2,
239 * HIDSERV, BRIDGE) we should upload to.
241 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
242 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
243 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
244 * to all authorities, and the extra-info document to all authorities that
248 directory_post_to_dirservers(uint8_t dir_purpose
, uint8_t router_purpose
,
249 authority_type_t type
,
251 size_t payload_len
, size_t extrainfo_len
)
254 smartlist_t
*dirservers
= router_get_trusted_dir_servers();
256 tor_assert(dirservers
);
257 /* This tries dirservers which we believe to be down, but ultimately, that's
258 * harmless, and we may as well err on the side of getting things uploaded.
260 SMARTLIST_FOREACH_BEGIN(dirservers
, trusted_dir_server_t
*, ds
) {
261 routerstatus_t
*rs
= &(ds
->fake_status
);
262 size_t upload_len
= payload_len
;
265 if ((type
& ds
->type
) == 0)
268 found
= 1; /* at least one authority of this type was listed */
269 if (dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
)
270 ds
->has_accepted_serverdesc
= 0;
272 if (extrainfo_len
&& router_supports_extrainfo(ds
->digest
, 1)) {
273 upload_len
+= extrainfo_len
;
274 log_info(LD_DIR
, "Uploading an extrainfo too (length %d)",
275 (int) extrainfo_len
);
277 tor_addr_from_ipv4h(&ds_addr
, ds
->addr
);
278 post_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
) ||
279 !fascist_firewall_allows_address_dir(&ds_addr
, ds
->dir_port
);
280 directory_initiate_command_routerstatus(rs
, dir_purpose
,
283 NULL
, payload
, upload_len
, 0);
284 } SMARTLIST_FOREACH_END(ds
);
286 char *s
= authority_type_to_string(type
);
287 log_warn(LD_DIR
, "Publishing server descriptor to directory authorities "
288 "of type '%s', but no authorities of that type listed!", s
);
293 /** Start a connection to a random running directory server, using
294 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
295 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
296 * Use <b>pds_flags</b> as arguments to router_pick_directory_server()
297 * or router_pick_trusteddirserver().
300 directory_get_from_dirserver(uint8_t dir_purpose
, uint8_t router_purpose
,
301 const char *resource
, int pds_flags
)
303 routerstatus_t
*rs
= NULL
;
304 or_options_t
*options
= get_options();
305 int prefer_authority
= directory_fetches_from_authorities(options
);
306 int get_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
);
307 authority_type_t type
;
308 time_t if_modified_since
= 0;
310 /* FFFF we could break this switch into its own function, and call
311 * it elsewhere in directory.c. -RD */
312 switch (dir_purpose
) {
313 case DIR_PURPOSE_FETCH_EXTRAINFO
:
314 type
= EXTRAINFO_CACHE
|
315 (router_purpose
== ROUTER_PURPOSE_BRIDGE
? BRIDGE_AUTHORITY
:
318 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
:
321 case DIR_PURPOSE_FETCH_SERVERDESC
:
322 type
= (router_purpose
== ROUTER_PURPOSE_BRIDGE
? BRIDGE_AUTHORITY
:
325 case DIR_PURPOSE_FETCH_RENDDESC
:
326 type
= HIDSERV_AUTHORITY
;
328 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
329 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
332 case DIR_PURPOSE_FETCH_CONSENSUS
:
333 case DIR_PURPOSE_FETCH_CERTIFICATE
:
337 log_warn(LD_BUG
, "Unexpected purpose %d", (int)dir_purpose
);
341 if (dir_purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
342 networkstatus_t
*v
= networkstatus_get_latest_consensus();
344 if_modified_since
= v
->valid_after
+ 180;
347 if (!options
->FetchServerDescriptors
&& type
!= HIDSERV_AUTHORITY
)
351 if (options
->UseBridges
&& type
!= BRIDGE_AUTHORITY
) {
352 /* want to ask a running bridge for which we have a descriptor. */
353 /* XXX022 we assume that all of our bridges can answer any
354 * possible directory question. This won't be true forever. -RD */
355 /* It certainly is not true with conditional consensus downloading,
356 * so, for now, never assume the server supports that. */
357 routerinfo_t
*ri
= choose_random_entry(NULL
);
360 tor_addr_from_ipv4h(&addr
, ri
->addr
);
361 directory_initiate_command(ri
->address
, &addr
,
363 0, /* don't use conditional consensus url */
364 1, ri
->cache_info
.identity_digest
,
367 0, resource
, NULL
, 0, if_modified_since
);
369 log_notice(LD_DIR
, "Ignoring directory request, since no bridge "
370 "nodes are available yet.");
373 if (prefer_authority
|| type
== BRIDGE_AUTHORITY
) {
374 /* only ask authdirservers, and don't ask myself */
375 rs
= router_pick_trusteddirserver(type
, pds_flags
);
376 if (rs
== NULL
&& (pds_flags
& PDS_NO_EXISTING_SERVERDESC_FETCH
)) {
377 /* We don't want to fetch from any authorities that we're currently
378 * fetching server descriptors from, and we got no match. Did we
379 * get no match because all the authorities have connections
380 * fetching server descriptors (in which case we should just
381 * return,) or because all the authorities are down or on fire or
382 * unreachable or something (in which case we should go on with
383 * our fallback code)? */
384 pds_flags
&= ~PDS_NO_EXISTING_SERVERDESC_FETCH
;
385 rs
= router_pick_trusteddirserver(type
, pds_flags
);
387 log_debug(LD_DIR
, "Deferring serverdesc fetch: all authorities "
393 if (!rs
&& type
!= BRIDGE_AUTHORITY
) {
394 /* anybody with a non-zero dirport will do */
395 rs
= router_pick_directory_server(type
, pds_flags
);
397 log_info(LD_DIR
, "No router found for %s; falling back to "
398 "dirserver list.", dir_conn_purpose_to_string(dir_purpose
));
399 rs
= router_pick_trusteddirserver(type
, pds_flags
);
401 get_via_tor
= 1; /* last resort: try routing it via Tor */
405 } else { /* get_via_tor */
406 /* Never use fascistfirewall; we're going via Tor. */
407 if (dir_purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
408 /* only ask hidserv authorities, any of them will do */
409 pds_flags
|= PDS_IGNORE_FASCISTFIREWALL
|PDS_ALLOW_SELF
;
410 rs
= router_pick_trusteddirserver(HIDSERV_AUTHORITY
, pds_flags
);
412 /* anybody with a non-zero dirport will do. Disregard firewalls. */
413 pds_flags
|= PDS_IGNORE_FASCISTFIREWALL
;
414 rs
= router_pick_directory_server(type
, pds_flags
);
415 /* If we have any hope of building an indirect conn, we know some router
416 * descriptors. If (rs==NULL), we can't build circuits anyway, so
417 * there's no point in falling back to the authorities in this case. */
422 directory_initiate_command_routerstatus(rs
, dir_purpose
,
429 "While fetching directory info, "
430 "no running dirservers known. Will try again later. "
431 "(purpose %d)", dir_purpose
);
432 if (!purpose_needs_anonymity(dir_purpose
, router_purpose
)) {
433 /* remember we tried them all and failed. */
434 directory_all_unreachable(time(NULL
));
439 /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
440 * directory authority other than ourself. Only for use by authorities when
441 * searching for missing information while voting. */
443 directory_get_from_all_authorities(uint8_t dir_purpose
,
444 uint8_t router_purpose
,
445 const char *resource
)
447 tor_assert(dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
448 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
);
450 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
451 trusted_dir_server_t
*, ds
,
454 if (router_digest_is_me(ds
->digest
))
456 if (!(ds
->type
& V3_AUTHORITY
))
458 rs
= &ds
->fake_status
;
459 directory_initiate_command_routerstatus(rs
, dir_purpose
, router_purpose
,
460 0, resource
, NULL
, 0, 0);
464 /** Same as directory_initiate_command_routerstatus(), but accepts
465 * rendezvous data to fetch a hidden service descriptor. */
467 directory_initiate_command_routerstatus_rend(routerstatus_t
*status
,
469 uint8_t router_purpose
,
470 int anonymized_connection
,
471 const char *resource
,
474 time_t if_modified_since
,
475 const rend_data_t
*rend_query
)
477 routerinfo_t
*router
;
478 char address_buf
[INET_NTOA_BUF_LEN
+1];
482 router
= router_get_by_digest(status
->identity_digest
);
483 if (!router
&& anonymized_connection
) {
484 log_info(LD_DIR
, "Not sending anonymized request to directory '%s'; we "
485 "don't have its router descriptor.", status
->nickname
);
488 address
= router
->address
;
490 in
.s_addr
= htonl(status
->addr
);
491 tor_inet_ntoa(&in
, address_buf
, sizeof(address_buf
));
492 address
= address_buf
;
494 tor_addr_from_ipv4h(&addr
, status
->addr
);
495 directory_initiate_command_rend(address
, &addr
,
496 status
->or_port
, status
->dir_port
,
497 status
->version_supports_conditional_consensus
,
498 status
->version_supports_begindir
,
499 status
->identity_digest
,
500 dir_purpose
, router_purpose
,
501 anonymized_connection
, resource
,
502 payload
, payload_len
, if_modified_since
,
506 /** Launch a new connection to the directory server <b>status</b> to
507 * upload or download a server or rendezvous
508 * descriptor. <b>dir_purpose</b> determines what
509 * kind of directory connection we're launching, and must be one of
510 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. <b>router_purpose</b>
511 * specifies the descriptor purposes we have in mind (currently only
512 * used for FETCH_DIR).
514 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
515 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
517 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
521 directory_initiate_command_routerstatus(routerstatus_t
*status
,
523 uint8_t router_purpose
,
524 int anonymized_connection
,
525 const char *resource
,
528 time_t if_modified_since
)
530 directory_initiate_command_routerstatus_rend(status
, dir_purpose
,
532 anonymized_connection
, resource
,
533 payload
, payload_len
,
534 if_modified_since
, NULL
);
537 /** Return true iff <b>conn</b> is the client side of a directory connection
538 * we launched to ourself in order to determine the reachability of our
541 directory_conn_is_self_reachability_test(dir_connection_t
*conn
)
543 if (conn
->requested_resource
&&
544 !strcmpstart(conn
->requested_resource
,"authority")) {
545 routerinfo_t
*me
= router_get_my_routerinfo();
547 router_digest_is_me(conn
->identity_digest
) &&
548 tor_addr_eq_ipv4h(&conn
->_base
.addr
, me
->addr
) && /*XXXX prop 118*/
549 me
->dir_port
== conn
->_base
.port
)
555 /** Called when we are unable to complete the client's request to a directory
556 * server due to a network error: Mark the router as down and try again if
560 connection_dir_request_failed(dir_connection_t
*conn
)
562 if (directory_conn_is_self_reachability_test(conn
)) {
563 return; /* this was a test fetch. don't retry. */
565 if (entry_list_is_constrained(get_options()))
566 router_set_status(conn
->identity_digest
, 0); /* don't try him again */
567 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
) {
568 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
569 conn
->_base
.address
);
570 connection_dir_download_networkstatus_failed(conn
, -1);
571 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
572 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
573 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
574 conn
->_base
.address
);
575 connection_dir_download_routerdesc_failed(conn
);
576 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
577 networkstatus_consensus_download_failed(0);
578 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
579 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
580 conn
->_base
.address
);
581 connection_dir_download_cert_failed(conn
, 0);
582 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
583 log_info(LD_DIR
, "Giving up downloading detached signatures from '%s'",
584 conn
->_base
.address
);
585 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
586 log_info(LD_DIR
, "Giving up downloading votes from '%s'",
587 conn
->_base
.address
);
591 /** Called when an attempt to download one or more network status
592 * documents on connection <b>conn</b> failed. Decide whether to
593 * retry the fetch now, later, or never.
596 connection_dir_download_networkstatus_failed(dir_connection_t
*conn
,
599 if (!conn
->requested_resource
) {
600 /* We never reached directory_send_command, which means that we never
601 * opened a network connection. Either we're out of sockets, or the
602 * network is down. Either way, retrying would be pointless. */
605 if (!strcmpstart(conn
->requested_resource
, "all")) {
606 /* We're a non-authoritative directory cache; try again. Ignore status
607 * code, since we don't want to keep trying forever in a tight loop
608 * if all the authorities are shutting us out. */
609 smartlist_t
*trusted_dirs
= router_get_trusted_dir_servers();
610 SMARTLIST_FOREACH(trusted_dirs
, trusted_dir_server_t
*, ds
,
611 download_status_failed(&ds
->v2_ns_dl_status
, 0));
612 directory_get_from_dirserver(conn
->_base
.purpose
, conn
->router_purpose
,
613 "all.z", 0 /* don't retry_if_no_servers */);
614 } else if (!strcmpstart(conn
->requested_resource
, "fp/")) {
615 /* We were trying to download by fingerprint; mark them all as having
616 * failed, and possibly retry them later.*/
617 smartlist_t
*failed
= smartlist_create();
618 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
620 if (smartlist_len(failed
)) {
621 dir_networkstatus_download_failed(failed
, status_code
);
622 SMARTLIST_FOREACH(failed
, char *, cp
, tor_free(cp
));
624 smartlist_free(failed
);
628 /** Called when an attempt to download one or more router descriptors
629 * or extra-info documents on connection <b>conn</b> failed.
632 connection_dir_download_routerdesc_failed(dir_connection_t
*conn
)
634 /* No need to increment the failure count for routerdescs, since
635 * it's not their fault. */
637 /* No need to relaunch descriptor downloads here: we already do it
638 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
639 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
640 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
645 /** Called when an attempt to fetch a certificate fails. */
647 connection_dir_download_cert_failed(dir_connection_t
*conn
, int status
)
650 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
);
652 if (!conn
->requested_resource
)
654 failed
= smartlist_create();
655 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
656 failed
, NULL
, DSR_HEX
);
657 SMARTLIST_FOREACH(failed
, char *, cp
,
659 authority_cert_dl_failed(cp
, status
);
662 smartlist_free(failed
);
664 update_certificate_downloads(time(NULL
));
667 /** Evaluate the situation and decide if we should use an encrypted
668 * "begindir-style" connection for this directory request.
669 * 1) If or_port is 0, or it's a direct conn and or_port is firewalled
670 * or we're a dir mirror, no.
671 * 2) If we prefer to avoid begindir conns, and we're not fetching or
672 * publishing a bridge relay descriptor, no.
676 directory_command_should_use_begindir(or_options_t
*options
,
677 const tor_addr_t
*addr
,
678 int or_port
, uint8_t router_purpose
,
679 int anonymized_connection
)
682 return 0; /* We don't know an ORPort -- no chance. */
683 if (!anonymized_connection
)
684 if (!fascist_firewall_allows_address_or(addr
, or_port
) ||
685 directory_fetches_from_authorities(options
) ||
686 (server_mode(options
) && !options
->Address
))
687 return 0; /* We're firewalled or are acting like a relay -- also no. */
688 if (!options
->TunnelDirConns
&&
689 router_purpose
!= ROUTER_PURPOSE_BRIDGE
)
690 return 0; /* We prefer to avoid using begindir conns. Fine. */
694 /** Helper for directory_initiate_command_routerstatus: send the
695 * command to a server whose address is <b>address</b>, whose IP is
696 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
697 * <b>supports_begindir</b>, and whose identity key digest is
700 directory_initiate_command(const char *address
, const tor_addr_t
*_addr
,
701 uint16_t or_port
, uint16_t dir_port
,
702 int supports_conditional_consensus
,
703 int supports_begindir
, const char *digest
,
704 uint8_t dir_purpose
, uint8_t router_purpose
,
705 int anonymized_connection
, const char *resource
,
706 const char *payload
, size_t payload_len
,
707 time_t if_modified_since
)
709 directory_initiate_command_rend(address
, _addr
, or_port
, dir_port
,
710 supports_conditional_consensus
,
711 supports_begindir
, digest
, dir_purpose
,
712 router_purpose
, anonymized_connection
,
713 resource
, payload
, payload_len
,
714 if_modified_since
, NULL
);
717 /** Same as directory_initiate_command(), but accepts rendezvous data to
718 * fetch a hidden service descriptor. */
720 directory_initiate_command_rend(const char *address
, const tor_addr_t
*_addr
,
721 uint16_t or_port
, uint16_t dir_port
,
722 int supports_conditional_consensus
,
723 int supports_begindir
, const char *digest
,
724 uint8_t dir_purpose
, uint8_t router_purpose
,
725 int anonymized_connection
,
726 const char *resource
,
727 const char *payload
, size_t payload_len
,
728 time_t if_modified_since
,
729 const rend_data_t
*rend_query
)
731 dir_connection_t
*conn
;
732 or_options_t
*options
= get_options();
733 int socket_error
= 0;
734 int use_begindir
= supports_begindir
&&
735 directory_command_should_use_begindir(options
, _addr
,
736 or_port
, router_purpose
, anonymized_connection
);
741 tor_assert(or_port
|| dir_port
);
744 tor_addr_copy(&addr
, _addr
);
746 log_debug(LD_DIR
, "anonymized %d, use_begindir %d.",
747 anonymized_connection
, use_begindir
);
749 log_debug(LD_DIR
, "Initiating %s", dir_conn_purpose_to_string(dir_purpose
));
751 /* ensure that we don't make direct connections when a SOCKS server is
753 if (!anonymized_connection
&& !use_begindir
&& !options
->HttpProxy
&&
754 (options
->Socks4Proxy
|| options
->Socks5Proxy
)) {
755 log_warn(LD_DIR
, "Cannot connect to a directory server through a "
760 conn
= dir_connection_new(AF_INET
);
762 /* set up conn so it's got all the data we need to remember */
763 tor_addr_copy(&conn
->_base
.addr
, &addr
);
764 conn
->_base
.port
= use_begindir
? or_port
: dir_port
;
765 conn
->_base
.address
= tor_strdup(address
);
766 memcpy(conn
->identity_digest
, digest
, DIGEST_LEN
);
768 conn
->_base
.purpose
= dir_purpose
;
769 conn
->router_purpose
= router_purpose
;
771 /* give it an initial state */
772 conn
->_base
.state
= DIR_CONN_STATE_CONNECTING
;
774 /* decide whether we can learn our IP address from this conn */
775 conn
->dirconn_direct
= !anonymized_connection
;
777 /* copy rendezvous data, if any */
779 conn
->rend_data
= rend_data_dup(rend_query
);
781 if (!anonymized_connection
&& !use_begindir
) {
782 /* then we want to connect to dirport directly */
784 if (options
->HttpProxy
) {
785 tor_addr_copy(&addr
, &options
->HttpProxyAddr
);
786 dir_port
= options
->HttpProxyPort
;
789 switch (connection_connect(TO_CONN(conn
), conn
->_base
.address
, &addr
,
790 dir_port
, &socket_error
)) {
792 connection_dir_request_failed(conn
); /* retry if we want */
793 /* XXX we only pass 'conn' above, not 'resource', 'payload',
794 * etc. So in many situations it can't retry! -RD */
795 connection_free(TO_CONN(conn
));
798 /* start flushing conn */
799 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
802 /* queue the command on the outbuf */
803 directory_send_command(conn
, dir_purpose
, 1, resource
,
804 payload
, payload_len
,
805 supports_conditional_consensus
,
807 connection_watch_events(TO_CONN(conn
), READ_EVENT
| WRITE_EVENT
);
808 /* writable indicates finish, readable indicates broken link,
809 error indicates broken link in windowsland. */
811 } else { /* we want to connect via a tor connection */
812 edge_connection_t
*linked_conn
;
814 /* If it's an anonymized connection, remember the fact that we
815 * wanted it for later: maybe we'll want it again soon. */
816 if (anonymized_connection
&& use_begindir
)
817 rep_hist_note_used_internal(time(NULL
), 0, 1);
818 else if (anonymized_connection
&& !use_begindir
)
819 rep_hist_note_used_port(time(NULL
), conn
->_base
.port
);
821 /* make an AP connection
822 * populate it and add it at the right state
826 connection_ap_make_link(conn
->_base
.address
, conn
->_base
.port
,
827 digest
, use_begindir
, conn
->dirconn_direct
);
829 log_warn(LD_NET
,"Making tunnel to dirserver failed.");
830 connection_mark_for_close(TO_CONN(conn
));
833 connection_link_connections(TO_CONN(conn
), TO_CONN(linked_conn
));
835 if (connection_add(TO_CONN(conn
)) < 0) {
836 log_warn(LD_NET
,"Unable to add connection for link to dirserver.");
837 connection_mark_for_close(TO_CONN(conn
));
840 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
841 /* queue the command on the outbuf */
842 directory_send_command(conn
, dir_purpose
, 0, resource
,
843 payload
, payload_len
,
844 supports_conditional_consensus
,
846 connection_watch_events(TO_CONN(conn
), READ_EVENT
|WRITE_EVENT
);
847 connection_start_reading(TO_CONN(linked_conn
));
851 /** Return true iff anything we say on <b>conn</b> is being encrypted before
852 * we send it to the client/server. */
854 connection_dir_is_encrypted(dir_connection_t
*conn
)
856 /* Right now it's sufficient to see if conn is or has been linked, since
857 * the only thing it could be linked to is an edge connection on a
858 * circuit, and the only way it could have been unlinked is at the edge
859 * connection getting closed.
861 return TO_CONN(conn
)->linked
;
864 /** Helper for sorting
866 * sort strings alphabetically
869 _compare_strs(const void **a
, const void **b
)
871 const char *s1
= *a
, *s2
= *b
;
872 return strcmp(s1
, s2
);
875 #define CONDITIONAL_CONSENSUS_FPR_LEN 3
876 #if (CONDITIONAL_CONSENSUS_FPR_LEN > DIGEST_LEN)
877 #error "conditional consensus fingerprint length is larger than digest length"
880 /** Return the URL we should use for a consensus download.
882 * This url depends on whether or not the server we go to
883 * is sufficiently new to support conditional consensus downloading,
884 * i.e. GET .../consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>
887 directory_get_consensus_url(int supports_conditional_consensus
)
892 if (supports_conditional_consensus
) {
893 char *authority_id_list
;
894 smartlist_t
*authority_digests
= smartlist_create();
896 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
897 trusted_dir_server_t
*, ds
,
900 if (!(ds
->type
& V3_AUTHORITY
))
903 hex
= tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN
+1);
904 base16_encode(hex
, 2*CONDITIONAL_CONSENSUS_FPR_LEN
+1,
905 ds
->v3_identity_digest
, CONDITIONAL_CONSENSUS_FPR_LEN
);
906 smartlist_add(authority_digests
, hex
);
908 smartlist_sort(authority_digests
, _compare_strs
);
909 authority_id_list
= smartlist_join_strings(authority_digests
,
912 len
= strlen(authority_id_list
)+64;
913 url
= tor_malloc(len
);
914 tor_snprintf(url
, len
, "/tor/status-vote/current/consensus/%s.z",
917 SMARTLIST_FOREACH(authority_digests
, char *, cp
, tor_free(cp
));
918 smartlist_free(authority_digests
);
919 tor_free(authority_id_list
);
921 url
= tor_strdup("/tor/status-vote/current/consensus.z");
926 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
927 * are as in directory_initiate_command().
930 directory_send_command(dir_connection_t
*conn
,
931 int purpose
, int direct
, const char *resource
,
932 const char *payload
, size_t payload_len
,
933 int supports_conditional_consensus
,
934 time_t if_modified_since
)
936 char proxystring
[256];
937 char proxyauthstring
[256];
938 char hoststring
[128];
939 char imsstring
[RFC1123_TIME_LEN
+32];
942 const char *httpcommand
= NULL
;
946 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
948 tor_free(conn
->requested_resource
);
950 conn
->requested_resource
= tor_strdup(resource
);
952 /* come up with a string for which Host: we want */
953 if (conn
->_base
.port
== 80) {
954 strlcpy(hoststring
, conn
->_base
.address
, sizeof(hoststring
));
956 tor_snprintf(hoststring
, sizeof(hoststring
),"%s:%d",
957 conn
->_base
.address
, conn
->_base
.port
);
960 /* Format if-modified-since */
961 if (!if_modified_since
) {
964 char b
[RFC1123_TIME_LEN
+1];
965 format_rfc1123_time(b
, if_modified_since
);
966 tor_snprintf(imsstring
, sizeof(imsstring
), "\r\nIf-Modified-Since: %s", b
);
969 /* come up with some proxy lines, if we're using one. */
970 if (direct
&& get_options()->HttpProxy
) {
971 char *base64_authenticator
=NULL
;
972 const char *authenticator
= get_options()->HttpProxyAuthenticator
;
974 tor_snprintf(proxystring
, sizeof(proxystring
),"http://%s", hoststring
);
976 base64_authenticator
= alloc_http_authenticator(authenticator
);
977 if (!base64_authenticator
)
978 log_warn(LD_BUG
, "Encoding http authenticator failed");
980 if (base64_authenticator
) {
981 tor_snprintf(proxyauthstring
, sizeof(proxyauthstring
),
982 "\r\nProxy-Authorization: Basic %s",
983 base64_authenticator
);
984 tor_free(base64_authenticator
);
986 proxyauthstring
[0] = 0;
990 proxyauthstring
[0] = 0;
994 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
:
995 tor_assert(resource
);
997 len
= strlen(resource
)+32;
998 url
= tor_malloc(len
);
999 tor_snprintf(url
, len
, "/tor/status/%s", resource
);
1001 case DIR_PURPOSE_FETCH_CONSENSUS
:
1002 tor_assert(!resource
);
1003 tor_assert(!payload
);
1004 httpcommand
= "GET";
1005 url
= directory_get_consensus_url(supports_conditional_consensus
);
1006 log_info(LD_DIR
, "Downloading consensus from %s using %s",
1009 case DIR_PURPOSE_FETCH_CERTIFICATE
:
1010 tor_assert(resource
);
1011 tor_assert(!payload
);
1012 httpcommand
= "GET";
1013 len
= strlen(resource
)+32;
1014 url
= tor_malloc(len
);
1015 tor_snprintf(url
, len
, "/tor/keys/%s", resource
);
1017 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
1018 tor_assert(resource
);
1019 tor_assert(!payload
);
1020 httpcommand
= "GET";
1021 len
= strlen(resource
)+32;
1022 url
= tor_malloc(len
);
1023 tor_snprintf(url
, len
, "/tor/status-vote/next/%s.z", resource
);
1025 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
1026 tor_assert(!resource
);
1027 tor_assert(!payload
);
1028 httpcommand
= "GET";
1029 url
= tor_strdup("/tor/status-vote/next/consensus-signatures.z");
1031 case DIR_PURPOSE_FETCH_SERVERDESC
:
1032 tor_assert(resource
);
1033 httpcommand
= "GET";
1034 len
= strlen(resource
)+32;
1035 url
= tor_malloc(len
);
1036 tor_snprintf(url
, len
, "/tor/server/%s", resource
);
1038 case DIR_PURPOSE_FETCH_EXTRAINFO
:
1039 tor_assert(resource
);
1040 httpcommand
= "GET";
1041 len
= strlen(resource
)+32;
1042 url
= tor_malloc(len
);
1043 tor_snprintf(url
, len
, "/tor/extra/%s", resource
);
1045 case DIR_PURPOSE_UPLOAD_DIR
:
1046 tor_assert(!resource
);
1047 tor_assert(payload
);
1048 httpcommand
= "POST";
1049 url
= tor_strdup("/tor/");
1051 case DIR_PURPOSE_UPLOAD_VOTE
:
1052 tor_assert(!resource
);
1053 tor_assert(payload
);
1054 httpcommand
= "POST";
1055 url
= tor_strdup("/tor/post/vote");
1057 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
1058 tor_assert(!resource
);
1059 tor_assert(payload
);
1060 httpcommand
= "POST";
1061 url
= tor_strdup("/tor/post/consensus-signature");
1063 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
1064 tor_assert(resource
);
1065 tor_assert(strlen(resource
) <= REND_DESC_ID_V2_LEN_BASE32
);
1066 tor_assert(!payload
);
1067 httpcommand
= "GET";
1068 len
= strlen(resource
) + 32;
1069 url
= tor_malloc(len
);
1070 tor_snprintf(url
, len
, "/tor/rendezvous2/%s", resource
);
1072 case DIR_PURPOSE_UPLOAD_RENDDESC
:
1073 tor_assert(!resource
);
1074 tor_assert(payload
);
1075 httpcommand
= "POST";
1076 url
= tor_strdup("/tor/rendezvous/publish");
1078 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
1079 tor_assert(!resource
);
1080 tor_assert(payload
);
1081 httpcommand
= "POST";
1082 url
= tor_strdup("/tor/rendezvous2/publish");
1089 if (strlen(proxystring
) + strlen(url
) >= 4096) {
1091 "Squid does not like URLs longer than 4095 bytes, and this "
1092 "one is %d bytes long: %s%s",
1093 (int)(strlen(proxystring
) + strlen(url
)), proxystring
, url
);
1096 tor_snprintf(request
, sizeof(request
), "%s %s", httpcommand
, proxystring
);
1097 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
1098 connection_write_to_buf(url
, strlen(url
), TO_CONN(conn
));
1101 if (!strcmp(httpcommand
, "GET") && !payload
) {
1102 tor_snprintf(request
, sizeof(request
),
1103 " HTTP/1.0\r\nHost: %s%s%s\r\n\r\n",
1108 tor_snprintf(request
, sizeof(request
),
1109 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s%s\r\n\r\n",
1110 payload
? (unsigned long)payload_len
: 0,
1115 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
1118 /* then send the payload afterwards too */
1119 connection_write_to_buf(payload
, payload_len
, TO_CONN(conn
));
1123 /** Parse an HTTP request string <b>headers</b> of the form
1125 * "\%s [http[s]://]\%s HTTP/1..."
1127 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
1128 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
1129 * so it does. Return 0.
1130 * Otherwise, return -1.
1133 parse_http_url(const char *headers
, char **url
)
1135 char *s
, *start
, *tmp
;
1137 s
= (char *)eat_whitespace_no_nl(headers
);
1139 s
= (char *)find_whitespace(s
); /* get past GET/POST */
1141 s
= (char *)eat_whitespace_no_nl(s
);
1143 start
= s
; /* this is it, assuming it's valid */
1144 s
= (char *)find_whitespace(start
);
1147 /* tolerate the http[s] proxy style of putting the hostname in the url */
1148 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
1152 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
1153 tmp
= strchr(tmp
+3, '/');
1154 if (tmp
&& tmp
< s
) {
1155 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname/' string");
1161 if (s
-start
< 5 || strcmpstart(start
,"/tor/")) { /* need to rewrite it */
1162 *url
= tor_malloc(s
- start
+ 5);
1163 strlcpy(*url
,"/tor", s
-start
+5);
1164 strlcat((*url
)+4, start
, s
-start
+1);
1166 *url
= tor_strndup(start
, s
-start
);
1171 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
1172 * <b>which</b>. The key should be given with a terminating colon and space;
1173 * this function copies everything after, up to but not including the
1174 * following \\r\\n. */
1176 http_get_header(const char *headers
, const char *which
)
1178 const char *cp
= headers
;
1180 if (!strcasecmpstart(cp
, which
)) {
1182 cp
+= strlen(which
);
1183 if ((eos
= strchr(cp
,'\r')))
1184 return tor_strndup(cp
, eos
-cp
);
1186 return tor_strdup(cp
);
1188 cp
= strchr(cp
, '\n');
1195 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
1196 * <b>conn</b>-\>address to describe our best guess of the address that
1197 * originated this HTTP request. */
1199 http_set_address_origin(const char *headers
, connection_t
*conn
)
1203 fwd
= http_get_header(headers
, "Forwarded-For: ");
1205 fwd
= http_get_header(headers
, "X-Forwarded-For: ");
1208 if (!tor_inet_aton(fwd
, &in
) || is_internal_IP(ntohl(in
.s_addr
), 0)) {
1209 log_debug(LD_DIR
, "Ignoring unrecognized or internal IP %s",
1214 tor_free(conn
->address
);
1215 conn
->address
= tor_strdup(fwd
);
1220 /** Parse an HTTP response string <b>headers</b> of the form
1222 * "HTTP/1.\%d \%d\%s\r\n...".
1225 * If it's well-formed, assign the status code to *<b>code</b> and
1226 * return 0. Otherwise, return -1.
1228 * On success: If <b>date</b> is provided, set *date to the Date
1229 * header in the http headers, or 0 if no such header is found. If
1230 * <b>compression</b> is provided, set *<b>compression</b> to the
1231 * compression method given in the Content-Encoding header, or 0 if no
1232 * such header is found, or -1 if the value of the header is not
1233 * recognized. If <b>reason</b> is provided, strdup the reason string
1237 parse_http_response(const char *headers
, int *code
, time_t *date
,
1238 compress_method_t
*compression
, char **reason
)
1241 char datestr
[RFC1123_TIME_LEN
+1];
1242 smartlist_t
*parsed_headers
;
1243 tor_assert(headers
);
1246 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
1248 if (tor_sscanf(headers
, "HTTP/1.%u %u", &n1
, &n2
) < 2 ||
1249 (n1
!= 0 && n1
!= 1) ||
1250 (n2
< 100 || n2
>= 600)) {
1251 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
1256 parsed_headers
= smartlist_create();
1257 smartlist_split_string(parsed_headers
, headers
, "\n",
1258 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
1260 smartlist_t
*status_line_elements
= smartlist_create();
1261 tor_assert(smartlist_len(parsed_headers
));
1262 smartlist_split_string(status_line_elements
,
1263 smartlist_get(parsed_headers
, 0),
1264 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
1265 tor_assert(smartlist_len(status_line_elements
) <= 3);
1266 if (smartlist_len(status_line_elements
) == 3) {
1267 *reason
= smartlist_get(status_line_elements
, 2);
1268 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
1270 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
1271 smartlist_free(status_line_elements
);
1275 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1276 if (!strcmpstart(s
, "Date: ")) {
1277 strlcpy(datestr
, s
+6, sizeof(datestr
));
1278 /* This will do nothing on failure, so we don't need to check
1279 the result. We shouldn't warn, since there are many other valid
1280 date formats besides the one we use. */
1281 parse_rfc1123_time(datestr
, date
);
1286 const char *enc
= NULL
;
1287 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1288 if (!strcmpstart(s
, "Content-Encoding: ")) {
1291 if (!enc
|| !strcmp(enc
, "identity")) {
1292 *compression
= NO_METHOD
;
1293 } else if (!strcmp(enc
, "deflate") || !strcmp(enc
, "x-deflate")) {
1294 *compression
= ZLIB_METHOD
;
1295 } else if (!strcmp(enc
, "gzip") || !strcmp(enc
, "x-gzip")) {
1296 *compression
= GZIP_METHOD
;
1298 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
1300 *compression
= UNKNOWN_METHOD
;
1303 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
1304 smartlist_free(parsed_headers
);
1309 /** Return true iff <b>body</b> doesn't start with a plausible router or
1310 * running-list or directory opening. This is a sign of possible compression.
1313 body_is_plausible(const char *body
, size_t len
, int purpose
)
1317 return 1; /* empty bodies don't need decompression */
1320 if (purpose
!= DIR_PURPOSE_FETCH_RENDDESC
) {
1321 if (!strcmpstart(body
,"router") ||
1322 !strcmpstart(body
,"signed-directory") ||
1323 !strcmpstart(body
,"network-status") ||
1324 !strcmpstart(body
,"running-routers"))
1326 for (i
=0;i
<32;++i
) {
1327 if (!TOR_ISPRINT(body
[i
]) && !TOR_ISSPACE(body
[i
]))
1336 /** Called when we've just fetched a bunch of router descriptors in
1337 * <b>body</b>. The list <b>which</b>, if present, holds digests for
1338 * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1339 * is true, or identity digests otherwise. Parse the descriptors, validate
1340 * them, and annotate them as having purpose <b>purpose</b> and as having been
1341 * downloaded from <b>source</b>.
1343 * Return the number of routers actually added. */
1345 load_downloaded_routers(const char *body
, smartlist_t
*which
,
1346 int descriptor_digests
,
1351 char time_buf
[ISO_TIME_LEN
+1];
1353 int general
= router_purpose
== ROUTER_PURPOSE_GENERAL
;
1354 format_iso_time(time_buf
, time(NULL
));
1357 if (tor_snprintf(buf
, sizeof(buf
),
1358 "@downloaded-at %s\n"
1360 "%s%s%s", time_buf
, escaped(source
),
1361 !general
? "@purpose " : "",
1362 !general
? router_purpose_to_string(router_purpose
) : "",
1363 !general
? "\n" : "")<0)
1366 added
= router_load_routers_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1367 descriptor_digests
, buf
);
1368 control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS
,
1369 count_loading_descriptors_progress());
1373 /** We are a client, and we've finished reading the server's
1374 * response. Parse it and act appropriately.
1376 * If we're still happy with using this directory server in the future, return
1377 * 0. Otherwise return -1; and the caller should consider trying the request
1380 * The caller will take care of marking the connection for close.
1383 connection_dir_client_reached_eof(dir_connection_t
*conn
)
1387 char *reason
= NULL
;
1388 size_t body_len
=0, orig_len
=0;
1390 time_t date_header
=0;
1392 compress_method_t compression
;
1395 int allow_partial
= (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1396 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
1397 int was_compressed
=0;
1398 time_t now
= time(NULL
);
1400 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
1401 &headers
, MAX_HEADERS_SIZE
,
1402 &body
, &body_len
, MAX_DIR_DL_SIZE
,
1404 case -1: /* overflow */
1405 log_warn(LD_PROTOCOL
,
1406 "'fetch' response too large (server '%s:%d'). Closing.",
1407 conn
->_base
.address
, conn
->_base
.port
);
1411 "'fetch' response not all here, but we're at eof. Closing.");
1413 /* case 1, fall through */
1415 orig_len
= body_len
;
1417 if (parse_http_response(headers
, &status_code
, &date_header
,
1418 &compression
, &reason
) < 0) {
1419 log_warn(LD_HTTP
,"Unparseable headers (server '%s:%d'). Closing.",
1420 conn
->_base
.address
, conn
->_base
.port
);
1421 tor_free(body
); tor_free(headers
);
1424 if (!reason
) reason
= tor_strdup("[no reason given]");
1427 "Received response from directory server '%s:%d': %d %s",
1428 conn
->_base
.address
, conn
->_base
.port
, status_code
,
1431 /* now check if it's got any hints for us about our IP address. */
1432 if (conn
->dirconn_direct
) {
1433 char *guess
= http_get_header(headers
, X_ADDRESS_HEADER
);
1435 router_new_address_suggestion(guess
, conn
);
1440 if (date_header
> 0) {
1441 /* The date header was written very soon after we sent our request,
1442 * so compute the skew as the difference between sending the request
1443 * and the date header. (We used to check now-date_header, but that's
1444 * inaccurate if we spend a lot of time downloading.)
1446 delta
= conn
->_base
.timestamp_lastwritten
- date_header
;
1447 if (labs(delta
)>ALLOW_DIRECTORY_TIME_SKEW
) {
1449 int trusted
= router_digest_is_trusted_dir(conn
->identity_digest
);
1450 format_time_interval(dbuf
, sizeof(dbuf
), delta
);
1451 log_fn(trusted
? LOG_WARN
: LOG_INFO
,
1453 "Received directory with skewed time (server '%s:%d'): "
1454 "It seems that our clock is %s by %s, or that theirs is %s. "
1455 "Tor requires an accurate clock to work: please check your time, "
1456 "timezone, and date settings.",
1457 conn
->_base
.address
, conn
->_base
.port
,
1458 delta
>0 ? "ahead" : "behind", dbuf
,
1459 delta
>0 ? "behind" : "ahead");
1460 skewed
= 1; /* don't check the recommended-versions line */
1461 control_event_general_status(trusted
? LOG_WARN
: LOG_NOTICE
,
1462 "CLOCK_SKEW SKEW=%ld SOURCE=DIRSERV:%s:%d",
1463 delta
, conn
->_base
.address
, conn
->_base
.port
);
1465 log_debug(LD_HTTP
, "Time on received directory is within tolerance; "
1466 "we are %ld seconds skewed. (That's okay.)", delta
);
1469 (void) skewed
; /* skewed isn't used yet. */
1471 if (status_code
== 503) {
1472 if (body_len
< 16) {
1474 trusted_dir_server_t
*ds
;
1475 log_info(LD_DIR
,"Received http status code %d (%s) from server "
1476 "'%s:%d'. I'll try again soon.",
1477 status_code
, escaped(reason
), conn
->_base
.address
,
1479 if ((rs
= router_get_consensus_status_by_id(conn
->identity_digest
)))
1480 rs
->last_dir_503_at
= now
;
1481 if ((ds
= router_get_trusteddirserver_by_digest(conn
->identity_digest
)))
1482 ds
->fake_status
.last_dir_503_at
= now
;
1484 tor_free(body
); tor_free(headers
); tor_free(reason
);
1487 /* XXXX022 Remove this once every server with bug 539 is obsolete. */
1488 log_info(LD_DIR
, "Server at '%s:%d' sent us a 503 response, but included "
1489 "a body anyway. We'll pretend it gave us a 200.",
1490 conn
->_base
.address
, conn
->_base
.port
);
1494 plausible
= body_is_plausible(body
, body_len
, conn
->_base
.purpose
);
1495 if (compression
!= NO_METHOD
|| !plausible
) {
1496 char *new_body
= NULL
;
1498 compress_method_t guessed
= detect_compression_method(body
, body_len
);
1499 if (compression
== UNKNOWN_METHOD
|| guessed
!= compression
) {
1500 /* Tell the user if we don't believe what we're told about compression.*/
1501 const char *description1
, *description2
;
1502 if (compression
== ZLIB_METHOD
)
1503 description1
= "as deflated";
1504 else if (compression
== GZIP_METHOD
)
1505 description1
= "as gzipped";
1506 else if (compression
== NO_METHOD
)
1507 description1
= "as uncompressed";
1509 description1
= "with an unknown Content-Encoding";
1510 if (guessed
== ZLIB_METHOD
)
1511 description2
= "deflated";
1512 else if (guessed
== GZIP_METHOD
)
1513 description2
= "gzipped";
1514 else if (!plausible
)
1515 description2
= "confusing binary junk";
1517 description2
= "uncompressed";
1519 log_info(LD_HTTP
, "HTTP body from server '%s:%d' was labeled %s, "
1520 "but it seems to be %s.%s",
1521 conn
->_base
.address
, conn
->_base
.port
, description1
,
1523 (compression
>0 && guessed
>0)?" Trying both.":"");
1525 /* Try declared compression first if we can. */
1526 if (compression
== GZIP_METHOD
|| compression
== ZLIB_METHOD
)
1527 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, compression
,
1528 !allow_partial
, LOG_PROTOCOL_WARN
);
1529 /* Okay, if that didn't work, and we think that it was compressed
1530 * differently, try that. */
1532 (guessed
== GZIP_METHOD
|| guessed
== ZLIB_METHOD
) &&
1533 compression
!= guessed
)
1534 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, guessed
,
1535 !allow_partial
, LOG_PROTOCOL_WARN
);
1536 /* If we're pretty sure that we have a compressed directory, and
1537 * we didn't manage to uncompress it, then warn and bail. */
1538 if (!plausible
&& !new_body
) {
1539 log_fn(LOG_PROTOCOL_WARN
, LD_HTTP
,
1540 "Unable to decompress HTTP body (server '%s:%d').",
1541 conn
->_base
.address
, conn
->_base
.port
);
1542 tor_free(body
); tor_free(headers
); tor_free(reason
);
1553 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
) {
1554 smartlist_t
*which
= NULL
;
1555 v2_networkstatus_source_t source
;
1557 log_info(LD_DIR
,"Received networkstatus objects (size %d) from server "
1558 "'%s:%d'", (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1559 if (status_code
!= 200) {
1561 "Received http status code %d (%s) from server "
1562 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1563 status_code
, escaped(reason
), conn
->_base
.address
,
1564 conn
->_base
.port
, conn
->requested_resource
);
1565 tor_free(body
); tor_free(headers
); tor_free(reason
);
1566 connection_dir_download_networkstatus_failed(conn
, status_code
);
1569 if (conn
->requested_resource
&&
1570 !strcmpstart(conn
->requested_resource
,"fp/")) {
1571 source
= NS_FROM_DIR_BY_FP
;
1572 which
= smartlist_create();
1573 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
1575 } else if (conn
->requested_resource
&&
1576 !strcmpstart(conn
->requested_resource
, "all")) {
1577 source
= NS_FROM_DIR_ALL
;
1578 which
= smartlist_create();
1579 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1580 trusted_dir_server_t
*, ds
,
1582 char *hex
= tor_malloc(HEX_DIGEST_LEN
+1);
1583 base16_encode(hex
, HEX_DIGEST_LEN
+1, ds
->digest
, DIGEST_LEN
);
1584 smartlist_add(which
, hex
);
1587 /* XXXX Can we even end up here? -- weasel*/
1588 source
= NS_FROM_DIR_BY_FP
;
1589 log_warn(LD_BUG
, "We received a networkstatus but we didn't ask "
1590 "for it by fp, nor did we ask for all.");
1594 char *next
= strstr(cp
, "\nnetwork-status-version");
1597 /* learn from it, and then remove it from 'which' */
1598 if (router_set_networkstatus_v2(cp
, now
, source
, which
)<0)
1606 /* launches router downloads as needed */
1607 routers_update_all_from_networkstatus(now
, 2);
1608 directory_info_has_arrived(now
, 0);
1610 if (smartlist_len(which
)) {
1611 dir_networkstatus_download_failed(which
, status_code
);
1613 SMARTLIST_FOREACH(which
, char *, s
, tor_free(s
));
1614 smartlist_free(which
);
1618 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
1620 if (status_code
!= 200) {
1621 int severity
= (status_code
== 304) ? LOG_INFO
: LOG_WARN
;
1622 log(severity
, LD_DIR
,
1623 "Received http status code %d (%s) from server "
1624 "'%s:%d' while fetching consensus directory.",
1625 status_code
, escaped(reason
), conn
->_base
.address
,
1627 tor_free(body
); tor_free(headers
); tor_free(reason
);
1628 networkstatus_consensus_download_failed(status_code
);
1631 log_info(LD_DIR
,"Received consensus directory (size %d) from server "
1632 "'%s:%d'", (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1633 if ((r
=networkstatus_set_current_consensus(body
, "ns", 0))<0) {
1634 log_fn(r
<-1?LOG_WARN
:LOG_INFO
, LD_DIR
,
1635 "Unable to load consensus directory downloaded from "
1636 "server '%s:%d'. I'll try again soon.",
1637 conn
->_base
.address
, conn
->_base
.port
);
1638 tor_free(body
); tor_free(headers
); tor_free(reason
);
1639 networkstatus_consensus_download_failed(0);
1642 /* launches router downloads as needed */
1643 routers_update_all_from_networkstatus(now
, 3);
1644 directory_info_has_arrived(now
, 0);
1645 log_info(LD_DIR
, "Successfully loaded consensus.");
1648 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
1649 if (status_code
!= 200) {
1651 "Received http status code %d (%s) from server "
1652 "'%s:%d' while fetching \"/tor/keys/%s\".",
1653 status_code
, escaped(reason
), conn
->_base
.address
,
1654 conn
->_base
.port
, conn
->requested_resource
);
1655 connection_dir_download_cert_failed(conn
, status_code
);
1656 tor_free(body
); tor_free(headers
); tor_free(reason
);
1659 log_info(LD_DIR
,"Received authority certificates (size %d) from server "
1660 "'%s:%d'", (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1661 if (trusted_dirs_load_certs_from_string(body
, 0, 1)<0) {
1662 log_warn(LD_DIR
, "Unable to parse fetched certificates");
1663 /* if we fetched more than one and only some failed, the successful
1664 * ones got flushed to disk so it's safe to call this on them */
1665 connection_dir_download_cert_failed(conn
, status_code
);
1667 directory_info_has_arrived(now
, 0);
1668 log_info(LD_DIR
, "Successfully loaded certificates from fetch.");
1671 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
1674 log_info(LD_DIR
,"Got votes (size %d) from server %s:%d",
1675 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1676 if (status_code
!= 200) {
1678 "Received http status code %d (%s) from server "
1679 "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".",
1680 status_code
, escaped(reason
), conn
->_base
.address
,
1681 conn
->_base
.port
, conn
->requested_resource
);
1682 tor_free(body
); tor_free(headers
); tor_free(reason
);
1685 dirvote_add_vote(body
, &msg
, &st
);
1687 log_warn(LD_DIR
, "Error adding retrieved vote: %s", msg
);
1689 log_info(LD_DIR
, "Added vote(s) successfully [msg: %s]", msg
);
1692 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
1693 const char *msg
= NULL
;
1694 log_info(LD_DIR
,"Got detached signatures (size %d) from server %s:%d",
1695 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1696 if (status_code
!= 200) {
1698 "Received http status code %d (%s) from server '%s:%d' while fetching "
1699 "\"/tor/status-vote/next/consensus-signatures.z\".",
1700 status_code
, escaped(reason
), conn
->_base
.address
,
1702 tor_free(body
); tor_free(headers
); tor_free(reason
);
1705 if (dirvote_add_signatures(body
, conn
->_base
.address
, &msg
)<0) {
1706 log_warn(LD_DIR
, "Problem adding detached signatures from %s:%d: %s",
1707 conn
->_base
.address
, conn
->_base
.port
, msg
?msg
:"???");
1711 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1712 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
1713 int was_ei
= conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
;
1714 smartlist_t
*which
= NULL
;
1715 int n_asked_for
= 0;
1716 int descriptor_digests
= conn
->requested_resource
&&
1717 !strcmpstart(conn
->requested_resource
,"d/");
1718 log_info(LD_DIR
,"Received %s (size %d) from server '%s:%d'",
1719 was_ei
? "extra server info" : "server info",
1720 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1721 if (conn
->requested_resource
&&
1722 (!strcmpstart(conn
->requested_resource
,"d/") ||
1723 !strcmpstart(conn
->requested_resource
,"fp/"))) {
1724 which
= smartlist_create();
1725 dir_split_resource_into_fingerprints(conn
->requested_resource
+
1726 (descriptor_digests
? 2 : 3),
1728 n_asked_for
= smartlist_len(which
);
1730 if (status_code
!= 200) {
1731 int dir_okay
= status_code
== 404 ||
1732 (status_code
== 400 && !strcmp(reason
, "Servers unavailable."));
1733 /* 404 means that it didn't have them; no big deal.
1734 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1735 log_fn(dir_okay
? LOG_INFO
: LOG_WARN
, LD_DIR
,
1736 "Received http status code %d (%s) from server '%s:%d' "
1737 "while fetching \"/tor/server/%s\". I'll try again soon.",
1738 status_code
, escaped(reason
), conn
->_base
.address
,
1739 conn
->_base
.port
, conn
->requested_resource
);
1741 connection_dir_download_routerdesc_failed(conn
);
1743 dir_routerdesc_download_failed(which
, status_code
,
1744 conn
->router_purpose
,
1745 was_ei
, descriptor_digests
);
1746 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1747 smartlist_free(which
);
1749 tor_free(body
); tor_free(headers
); tor_free(reason
);
1750 return dir_okay
? 0 : -1;
1752 /* Learn the routers, assuming we requested by fingerprint or "all"
1755 * We use "authority" to fetch our own descriptor for
1756 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1757 * the output of "authority" requests unless we are using bridges,
1758 * since otherwise they'll be the response from reachability tests,
1759 * and we don't really want to add that to our routerlist. */
1760 if (which
|| (conn
->requested_resource
&&
1761 (!strcmpstart(conn
->requested_resource
, "all") ||
1762 (!strcmpstart(conn
->requested_resource
, "authority") &&
1763 get_options()->UseBridges
)))) {
1764 /* as we learn from them, we remove them from 'which' */
1766 router_load_extrainfo_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1767 descriptor_digests
);
1769 //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1770 // descriptor_digests, conn->router_purpose);
1771 if (load_downloaded_routers(body
, which
, descriptor_digests
,
1772 conn
->router_purpose
,
1773 conn
->_base
.address
))
1774 directory_info_has_arrived(now
, 0);
1777 if (which
) { /* mark remaining ones as failed */
1778 log_info(LD_DIR
, "Received %d/%d %s requested from %s:%d",
1779 n_asked_for
-smartlist_len(which
), n_asked_for
,
1780 was_ei
? "extra-info documents" : "router descriptors",
1781 conn
->_base
.address
, (int)conn
->_base
.port
);
1782 if (smartlist_len(which
)) {
1783 dir_routerdesc_download_failed(which
, status_code
,
1784 conn
->router_purpose
,
1785 was_ei
, descriptor_digests
);
1787 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1788 smartlist_free(which
);
1790 if (directory_conn_is_self_reachability_test(conn
))
1791 router_dirport_found_reachable();
1794 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_DIR
) {
1795 switch (status_code
) {
1797 trusted_dir_server_t
*ds
=
1798 router_get_trusteddirserver_by_digest(conn
->identity_digest
);
1799 char *rejected_hdr
= http_get_header(headers
,
1800 "X-Descriptor-Not-New: ");
1803 if (!strcmp(rejected_hdr
, "Yes")) {
1804 log_info(LD_GENERAL
,
1805 "Authority '%s' declined our descriptor (not new)",
1807 /* XXXX use this information; be sure to upload next one
1809 /* XXXX021 On further thought, the task above implies that we're
1810 * basing our regenerate-descriptor time on when we uploaded the
1811 * last descriptor, not on the published time of the last
1812 * descriptor. If those are different, that's a bad thing to
1816 tor_free(rejected_hdr
);
1818 log_info(LD_GENERAL
,"eof (status 200) after uploading server "
1819 "descriptor: finished.");
1820 control_event_server_status(
1821 LOG_NOTICE
, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1822 conn
->_base
.address
, conn
->_base
.port
);
1824 ds
->has_accepted_serverdesc
= 1;
1825 if (directories_have_accepted_server_descriptor())
1826 control_event_server_status(LOG_NOTICE
, "GOOD_SERVER_DESCRIPTOR");
1830 log_warn(LD_GENERAL
,"http status 400 (%s) response from "
1831 "dirserver '%s:%d'. Please correct.",
1832 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1833 control_event_server_status(LOG_WARN
,
1834 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1835 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1838 log_warn(LD_GENERAL
,
1839 "http status %d (%s) reason unexpected while uploading "
1840 "descriptor to server '%s:%d').",
1841 status_code
, escaped(reason
), conn
->_base
.address
,
1845 /* return 0 in all cases, since we don't want to mark any
1846 * dirservers down just because they don't like us. */
1849 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_VOTE
) {
1850 switch (status_code
) {
1852 log_notice(LD_DIR
,"Uploaded a vote to dirserver %s:%d",
1853 conn
->_base
.address
, conn
->_base
.port
);
1857 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
1858 "vote to dirserver '%s:%d'. Please correct.",
1859 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1862 log_warn(LD_GENERAL
,
1863 "http status %d (%s) reason unexpected while uploading "
1864 "vote to server '%s:%d').",
1865 status_code
, escaped(reason
), conn
->_base
.address
,
1869 /* return 0 in all cases, since we don't want to mark any
1870 * dirservers down just because they don't like us. */
1873 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
) {
1874 switch (status_code
) {
1876 log_notice(LD_DIR
,"Uploaded signature(s) to dirserver %s:%d",
1877 conn
->_base
.address
, conn
->_base
.port
);
1881 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
1882 "signatures to dirserver '%s:%d'. Please correct.",
1883 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1886 log_warn(LD_GENERAL
,
1887 "http status %d (%s) reason unexpected while uploading "
1888 "signatures to server '%s:%d').",
1889 status_code
, escaped(reason
), conn
->_base
.address
,
1893 /* return 0 in all cases, since we don't want to mark any
1894 * dirservers down just because they don't like us. */
1897 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
1898 tor_assert(conn
->rend_data
);
1899 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1901 (int)body_len
, status_code
, escaped(reason
));
1902 switch (status_code
) {
1904 if (rend_cache_store(body
, body_len
, 0) < -1) {
1905 log_warn(LD_REND
,"Failed to parse rendezvous descriptor.");
1906 /* Any pending rendezvous attempts will notice when
1907 * connection_about_to_close_connection()
1908 * cleans this dir conn up. */
1909 /* We could retry. But since v0 descriptors are going out of
1910 * style, it isn't worth the hassle. We'll do better in v2. */
1912 /* Success, or at least there's a v2 descriptor already
1913 * present. Notify pending connections about this. */
1914 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1915 rend_client_desc_trynow(conn
->rend_data
->onion_address
);
1919 /* Not there. Pending connections will be notified when
1920 * connection_about_to_close_connection() cleans this conn up. */
1924 "http status 400 (%s). Dirserver didn't like our "
1925 "rendezvous query?", escaped(reason
));
1928 log_warn(LD_REND
,"http status %d (%s) response unexpected while "
1929 "fetching hidden service descriptor (server '%s:%d').",
1930 status_code
, escaped(reason
), conn
->_base
.address
,
1936 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC_V2
) {
1937 tor_assert(conn
->rend_data
);
1938 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1940 (int)body_len
, status_code
, escaped(reason
));
1941 switch (status_code
) {
1943 switch (rend_cache_store_v2_desc_as_client(body
, conn
->rend_data
)) {
1945 log_warn(LD_REND
,"Fetching v2 rendezvous descriptor failed. "
1946 "Retrying at another directory.");
1947 /* We'll retry when connection_about_to_close_connection()
1948 * cleans this dir conn up. */
1951 /* We already have a v0 descriptor here. Ignoring this one
1952 * and _not_ performing another request. */
1953 log_info(LD_REND
, "Successfully fetched v2 rendezvous "
1954 "descriptor, but we already have a v0 descriptor.");
1955 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1958 /* success. notify pending connections about this. */
1959 log_info(LD_REND
, "Successfully fetched v2 rendezvous "
1961 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1962 rend_client_desc_trynow(conn
->rend_data
->onion_address
);
1967 /* Not there. We'll retry when
1968 * connection_about_to_close_connection() cleans this conn up. */
1969 log_info(LD_REND
,"Fetching v2 rendezvous descriptor failed: "
1970 "Retrying at another directory.");
1973 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
1974 "http status 400 (%s). Dirserver didn't like our "
1975 "v2 rendezvous query? Retrying at another directory.",
1979 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
1980 "http status %d (%s) response unexpected while "
1981 "fetching v2 hidden service descriptor (server '%s:%d'). "
1982 "Retrying at another directory.",
1983 status_code
, escaped(reason
), conn
->_base
.address
,
1989 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC
||
1990 conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC_V2
) {
1991 log_info(LD_REND
,"Uploaded rendezvous descriptor (status %d "
1993 status_code
, escaped(reason
));
1994 switch (status_code
) {
1997 "Uploading rendezvous descriptor: finished with status "
1998 "200 (%s)", escaped(reason
));
2001 log_warn(LD_REND
,"http status 400 (%s) response from dirserver "
2002 "'%s:%d'. Malformed rendezvous descriptor?",
2003 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
2006 log_warn(LD_REND
,"http status %d (%s) response unexpected (server "
2008 status_code
, escaped(reason
), conn
->_base
.address
,
2013 note_client_request(conn
->_base
.purpose
, was_compressed
, orig_len
);
2014 tor_free(body
); tor_free(headers
); tor_free(reason
);
2018 /** Called when a directory connection reaches EOF. */
2020 connection_dir_reached_eof(dir_connection_t
*conn
)
2023 if (conn
->_base
.state
!= DIR_CONN_STATE_CLIENT_READING
) {
2024 log_info(LD_HTTP
,"conn reached eof, not reading. [state=%d] Closing.",
2026 connection_close_immediate(TO_CONN(conn
)); /* error: give up on flushing */
2027 connection_mark_for_close(TO_CONN(conn
));
2031 retval
= connection_dir_client_reached_eof(conn
);
2032 if (retval
== 0) /* success */
2033 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_FINISHED
;
2034 connection_mark_for_close(TO_CONN(conn
));
2038 /** If any directory object is arriving, and it's over 10MB large, we're
2039 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
2040 * ask for more than 96 router descriptors at a time.)
2042 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
2044 /** Read handler for directory connections. (That's connections <em>to</em>
2045 * directory servers and connections <em>at</em> directory servers.)
2048 connection_dir_process_inbuf(dir_connection_t
*conn
)
2051 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2053 /* Directory clients write, then read data until they receive EOF;
2054 * directory servers read data until they get an HTTP command, then
2055 * write their response (when it's finished flushing, they mark for
2059 /* If we're on the dirserver side, look for a command. */
2060 if (conn
->_base
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
2061 if (directory_handle_command(conn
) < 0) {
2062 connection_mark_for_close(TO_CONN(conn
));
2068 if (buf_datalen(conn
->_base
.inbuf
) > MAX_DIRECTORY_OBJECT_SIZE
) {
2069 log_warn(LD_HTTP
, "Too much data received from directory connection: "
2070 "denial of service attempt, or you need to upgrade?");
2071 connection_mark_for_close(TO_CONN(conn
));
2075 if (!conn
->_base
.inbuf_reached_eof
)
2076 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
2080 /** Create an http response for the client <b>conn</b> out of
2081 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
2084 write_http_status_line(dir_connection_t
*conn
, int status
,
2085 const char *reason_phrase
)
2088 if (tor_snprintf(buf
, sizeof(buf
), "HTTP/1.0 %d %s\r\n\r\n",
2089 status
, reason_phrase
? reason_phrase
: "OK") < 0) {
2090 log_warn(LD_BUG
,"status line too long.");
2093 connection_write_to_buf(buf
, strlen(buf
), TO_CONN(conn
));
2096 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
2097 * with <b>type</b> as the Content-Type.
2099 * If <b>length</b> is nonnegative, it is the Content-Length.
2100 * If <b>encoding</b> is provided, it is the Content-Encoding.
2101 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
2102 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
2104 write_http_response_header_impl(dir_connection_t
*conn
, ssize_t length
,
2105 const char *type
, const char *encoding
,
2106 const char *extra_headers
,
2107 long cache_lifetime
)
2109 char date
[RFC1123_TIME_LEN
+1];
2112 time_t now
= time(NULL
);
2116 format_rfc1123_time(date
, now
);
2118 tor_snprintf(cp
, sizeof(tmp
),
2119 "HTTP/1.0 200 OK\r\nDate: %s\r\n",
2123 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
), "Content-Type: %s\r\n", type
);
2126 if (!is_local_addr(&conn
->_base
.addr
)) {
2127 /* Don't report the source address for a nearby/private connection.
2128 * Otherwise we tend to mis-report in cases where incoming ports are
2129 * being forwarded to a Tor server running behind the firewall. */
2130 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2131 X_ADDRESS_HEADER
"%s\r\n", conn
->_base
.address
);
2135 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2136 "Content-Encoding: %s\r\n", encoding
);
2140 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2141 "Content-Length: %ld\r\n", (long)length
);
2144 if (cache_lifetime
> 0) {
2145 char expbuf
[RFC1123_TIME_LEN
+1];
2146 format_rfc1123_time(expbuf
, now
+ cache_lifetime
);
2147 /* We could say 'Cache-control: max-age=%d' here if we start doing
2149 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2150 "Expires: %s\r\n", expbuf
);
2152 } else if (cache_lifetime
== 0) {
2153 /* We could say 'Cache-control: no-cache' here if we start doing
2155 strlcpy(cp
, "Pragma: no-cache\r\n", sizeof(tmp
)-(cp
-tmp
));
2158 if (extra_headers
) {
2159 strlcpy(cp
, extra_headers
, sizeof(tmp
)-(cp
-tmp
));
2162 if (sizeof(tmp
)-(cp
-tmp
) > 3)
2163 memcpy(cp
, "\r\n", 3);
2166 connection_write_to_buf(tmp
, strlen(tmp
), TO_CONN(conn
));
2169 /** As write_http_response_header_impl, but sets encoding and content-typed
2170 * based on whether the response will be <b>compressed</b> or not. */
2172 write_http_response_header(dir_connection_t
*conn
, ssize_t length
,
2173 int compressed
, long cache_lifetime
)
2175 write_http_response_header_impl(conn
, length
,
2176 compressed
?"application/octet-stream":"text/plain",
2177 compressed
?"deflate":"identity",
2182 #ifdef INSTRUMENT_DOWNLOADS
2183 typedef struct request_t
{
2184 uint64_t bytes
; /**< How many bytes have we transferred? */
2185 uint64_t count
; /**< How many requests have we made? */
2188 /** Map used to keep track of how much data we've up/downloaded in what kind
2189 * of request. Maps from request type to pointer to request_t. */
2190 static strmap_t
*request_map
= NULL
;
2192 /** Record that a client request of <b>purpose</b> was made, and that
2193 * <b>bytes</b> bytes of possibly <b>compressed</b> data were sent/received.
2194 * Used to keep track of how much we've up/downloaded in what kind of
2197 note_client_request(int purpose
, int compressed
, size_t bytes
)
2200 const char *kind
= NULL
;
2202 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS
: kind
= "dl/status"; break;
2203 case DIR_PURPOSE_FETCH_CONSENSUS
: kind
= "dl/consensus"; break;
2204 case DIR_PURPOSE_FETCH_CERTIFICATE
: kind
= "dl/cert"; break;
2205 case DIR_PURPOSE_FETCH_STATUS_VOTE
: kind
= "dl/vote"; break;
2206 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
: kind
= "dl/detached_sig";
2208 case DIR_PURPOSE_FETCH_SERVERDESC
: kind
= "dl/server"; break;
2209 case DIR_PURPOSE_FETCH_EXTRAINFO
: kind
= "dl/extra"; break;
2210 case DIR_PURPOSE_UPLOAD_DIR
: kind
= "dl/ul-dir"; break;
2211 case DIR_PURPOSE_UPLOAD_VOTE
: kind
= "dl/ul-vote"; break;
2212 case DIR_PURPOSE_UPLOAD_SIGNATURES
: kind
= "dl/ul-sig"; break;
2213 case DIR_PURPOSE_FETCH_RENDDESC
: kind
= "dl/rend"; break;
2214 case DIR_PURPOSE_FETCH_RENDDESC_V2
: kind
= "dl/rend2"; break;
2215 case DIR_PURPOSE_UPLOAD_RENDDESC
: kind
= "dl/ul-rend"; break;
2216 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
: kind
= "dl/ul-rend2"; break;
2219 key
= tor_malloc(256);
2220 tor_snprintf(key
, 256, "%s%s", kind
, compressed
?".z":"");
2222 key
= tor_malloc(256);
2223 tor_snprintf(key
, 256, "unknown purpose (%d)%s",
2224 purpose
, compressed
?".z":"");
2226 note_request(key
, bytes
);
2230 /** Helper: initialize the request map to instrument downloads. */
2232 ensure_request_map_initialized(void)
2235 request_map
= strmap_new();
2238 /** Called when we just transmitted or received <b>bytes</b> worth of data
2239 * because of a request of type <b>key</b> (an arbitrary identifier): adds
2240 * <b>bytes</b> to the total associated with key. */
2242 note_request(const char *key
, size_t bytes
)
2245 ensure_request_map_initialized();
2247 r
= strmap_get(request_map
, key
);
2249 r
= tor_malloc_zero(sizeof(request_t
));
2250 strmap_set(request_map
, key
, r
);
2256 /** Return a newly allocated string holding a summary of bytes used per
2259 directory_dump_request_log(void)
2264 strmap_iter_t
*iter
;
2266 ensure_request_map_initialized();
2268 lines
= smartlist_create();
2270 for (iter
= strmap_iter_init(request_map
);
2271 !strmap_iter_done(iter
);
2272 iter
= strmap_iter_next(request_map
, iter
)) {
2276 strmap_iter_get(iter
, &key
, &val
);
2278 tor_snprintf(tmp
, sizeof(tmp
), "%s "U64_FORMAT
" "U64_FORMAT
"\n",
2279 key
, U64_PRINTF_ARG(r
->bytes
), U64_PRINTF_ARG(r
->count
));
2280 smartlist_add(lines
, tor_strdup(tmp
));
2282 smartlist_sort_strings(lines
);
2283 result
= smartlist_join_strings(lines
, "", 0, NULL
);
2284 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
2285 smartlist_free(lines
);
2290 note_client_request(int purpose
, int compressed
, size_t bytes
)
2298 note_request(const char *key
, size_t bytes
)
2305 directory_dump_request_log(void)
2307 return tor_strdup("Not supported.");
2311 /** Decide whether a client would accept the consensus we have.
2313 * Clients can say they only want a consensus if it's signed by more
2314 * than half the authorities in a list. They pass this list in
2315 * the url as "...consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>".
2317 * <b>fpr</b> may be an abbreviated fingerprint, i.e. only a left substring
2318 * of the full authority identity digest. (Only strings of even length,
2319 * i.e. encodings of full bytes, are handled correctly. In the case
2320 * of an odd number of hex digits the last one is silently ignored.)
2322 * Returns 1 if more than half of the requested authorities signed the
2323 * consensus, 0 otherwise.
2326 client_likes_consensus(networkstatus_t
*v
, const char *want_url
)
2328 smartlist_t
*want_authorities
= smartlist_create();
2332 dir_split_resource_into_fingerprints(want_url
, want_authorities
, NULL
, 0);
2333 need_at_least
= smartlist_len(want_authorities
)/2+1;
2334 SMARTLIST_FOREACH_BEGIN(want_authorities
, const char *, d
) {
2335 char want_digest
[DIGEST_LEN
];
2336 size_t want_len
= strlen(d
)/2;
2337 if (want_len
> DIGEST_LEN
)
2338 want_len
= DIGEST_LEN
;
2340 if (base16_decode(want_digest
, DIGEST_LEN
, d
, want_len
*2) < 0) {
2341 log_fn(LOG_PROTOCOL_WARN
, LD_DIR
,
2342 "Failed to decode requested authority digest %s.", d
);
2346 SMARTLIST_FOREACH_BEGIN(v
->voters
, networkstatus_voter_info_t
*, vi
) {
2347 if (smartlist_len(vi
->sigs
) &&
2348 !memcmp(vi
->identity_digest
, want_digest
, want_len
)) {
2352 } SMARTLIST_FOREACH_END(vi
);
2354 /* early exit, if we already have enough */
2355 if (have
>= need_at_least
)
2357 } SMARTLIST_FOREACH_END(d
);
2359 SMARTLIST_FOREACH(want_authorities
, char *, d
, tor_free(d
));
2360 smartlist_free(want_authorities
);
2361 return (have
>= need_at_least
);
2364 /** Helper function: called when a dirserver gets a complete HTTP GET
2365 * request. Look for a request for a directory or for a rendezvous
2366 * service descriptor. On finding one, write a response into
2367 * conn-\>outbuf. If the request is unrecognized, send a 400.
2368 * Always return 0. */
2370 directory_handle_command_get(dir_connection_t
*conn
, const char *headers
,
2371 const char *body
, size_t body_len
)
2374 char *url
, *url_mem
, *header
;
2375 or_options_t
*options
= get_options();
2376 time_t if_modified_since
= 0;
2380 /* We ignore the body of a GET request. */
2384 log_debug(LD_DIRSERV
,"Received GET command.");
2386 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2388 if (parse_http_url(headers
, &url
) < 0) {
2389 write_http_status_line(conn
, 400, "Bad request");
2392 if ((header
= http_get_header(headers
, "If-Modified-Since: "))) {
2394 if (parse_http_time(header
, &tm
) == 0) {
2395 if_modified_since
= tor_timegm(&tm
);
2397 /* The correct behavior on a malformed If-Modified-Since header is to
2398 * act as if no If-Modified-Since header had been given. */
2401 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2404 url_len
= strlen(url
);
2405 compressed
= url_len
> 2 && !strcmp(url
+url_len
-2, ".z");
2407 url
[url_len
-2] = '\0';
2411 if (!strcmp(url
,"/tor/")) {
2412 const char *frontpage
= get_dirportfrontpage();
2415 dlen
= strlen(frontpage
);
2416 /* Let's return a disclaimer page (users shouldn't use V1 anymore,
2417 and caches don't fetch '/', so this is safe). */
2419 /* [We don't check for write_bucket_low here, since we want to serve
2420 * this page no matter what.] */
2421 note_request(url
, dlen
);
2422 write_http_response_header_impl(conn
, dlen
, "text/html", "identity",
2423 NULL
, DIRPORTFRONTPAGE_CACHE_LIFETIME
);
2424 connection_write_to_buf(frontpage
, dlen
, TO_CONN(conn
));
2427 /* if no disclaimer file, fall through and continue */
2430 if (!strcmp(url
,"/tor/") || !strcmp(url
,"/tor/dir")) { /* v1 dir fetch */
2431 cached_dir_t
*d
= dirserv_get_directory();
2434 log_info(LD_DIRSERV
,"Client asked for the mirrored directory, but we "
2435 "don't have a good one yet. Sending 503 Dir not available.");
2436 write_http_status_line(conn
, 503, "Directory unavailable");
2439 if (d
->published
< if_modified_since
) {
2440 write_http_status_line(conn
, 304, "Not modified");
2444 dlen
= compressed
? d
->dir_z_len
: d
->dir_len
;
2446 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
2447 log_debug(LD_DIRSERV
,
2448 "Client asked for the mirrored directory, but we've been "
2449 "writing too many bytes lately. Sending 503 Dir busy.");
2450 write_http_status_line(conn
, 503, "Directory busy, try again later");
2454 note_request(url
, dlen
);
2456 log_debug(LD_DIRSERV
,"Dumping %sdirectory to client.",
2457 compressed
?"compressed ":"");
2458 write_http_response_header(conn
, dlen
, compressed
,
2459 FULL_DIR_CACHE_LIFETIME
);
2460 conn
->cached_dir
= d
;
2461 conn
->cached_dir_offset
= 0;
2463 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2466 /* Prime the connection with some data. */
2467 conn
->dir_spool_src
= DIR_SPOOL_CACHED_DIR
;
2468 connection_dirserv_flushed_some(conn
);
2472 if (!strcmp(url
,"/tor/running-routers")) { /* running-routers fetch */
2473 cached_dir_t
*d
= dirserv_get_runningrouters();
2475 write_http_status_line(conn
, 503, "Directory unavailable");
2478 if (d
->published
< if_modified_since
) {
2479 write_http_status_line(conn
, 304, "Not modified");
2482 dlen
= compressed
? d
->dir_z_len
: d
->dir_len
;
2484 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
2485 log_info(LD_DIRSERV
,
2486 "Client asked for running-routers, but we've been "
2487 "writing too many bytes lately. Sending 503 Dir busy.");
2488 write_http_status_line(conn
, 503, "Directory busy, try again later");
2491 note_request(url
, dlen
);
2492 write_http_response_header(conn
, dlen
, compressed
,
2493 RUNNINGROUTERS_CACHE_LIFETIME
);
2494 connection_write_to_buf(compressed
? d
->dir_z
: d
->dir
, dlen
,
2499 if (!strcmpstart(url
,"/tor/status/")
2500 || !strcmpstart(url
, "/tor/status-vote/current/consensus")) {
2501 /* v2 or v3 network status fetch. */
2502 smartlist_t
*dir_fps
= smartlist_create();
2503 int is_v3
= !strcmpstart(url
, "/tor/status-vote");
2504 geoip_client_action_t act
=
2505 is_v3
? GEOIP_CLIENT_NETWORKSTATUS
: GEOIP_CLIENT_NETWORKSTATUS_V2
;
2506 const char *request_type
= NULL
;
2507 const char *key
= url
+ strlen("/tor/status/");
2508 long lifetime
= NETWORKSTATUS_CACHE_LIFETIME
;
2511 dirserv_get_networkstatus_v2_fingerprints(dir_fps
, key
);
2512 if (!strcmpstart(key
, "fp/"))
2513 request_type
= compressed
?"/tor/status/fp.z":"/tor/status/fp";
2514 else if (!strcmpstart(key
, "authority"))
2515 request_type
= compressed
?"/tor/status/authority.z":
2516 "/tor/status/authority";
2517 else if (!strcmpstart(key
, "all"))
2518 request_type
= compressed
?"/tor/status/all.z":"/tor/status/all";
2520 request_type
= "/tor/status/?";
2522 networkstatus_t
*v
= networkstatus_get_latest_consensus();
2523 time_t now
= time(NULL
);
2524 const char *want_fps
= NULL
;
2525 char *flavor
= NULL
;
2526 #define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
2527 #define CONSENSUS_FLAVORED_PREFIX "/tor/status-vote/current/consensus-"
2528 /* figure out the flavor if any, and who we wanted to sign the thing */
2529 if (!strcmpstart(url
, CONSENSUS_FLAVORED_PREFIX
)) {
2531 f
= url
+ strlen(CONSENSUS_FLAVORED_PREFIX
);
2532 cp
= strchr(f
, '/');
2535 flavor
= tor_strndup(f
, cp
-f
);
2537 flavor
= tor_strdup(f
);
2540 if (!strcmpstart(url
, CONSENSUS_URL_PREFIX
))
2541 want_fps
= url
+strlen(CONSENSUS_URL_PREFIX
);
2544 /* XXXX MICRODESC NM NM should check document of correct flavor */
2545 if (v
&& want_fps
&&
2546 !client_likes_consensus(v
, want_fps
)) {
2547 write_http_status_line(conn
, 404, "Consensus not signed by sufficient "
2548 "number of requested authorities");
2549 smartlist_free(dir_fps
);
2550 geoip_note_ns_response(act
, GEOIP_REJECT_NOT_ENOUGH_SIGS
);
2556 char *fp
= tor_malloc_zero(DIGEST_LEN
);
2558 strlcpy(fp
, flavor
, DIGEST_LEN
);
2560 smartlist_add(dir_fps
, fp
);
2562 request_type
= compressed
?"v3.z":"v3";
2563 lifetime
= (v
&& v
->fresh_until
> now
) ? v
->fresh_until
- now
: 0;
2566 if (!smartlist_len(dir_fps
)) { /* we failed to create/cache cp */
2567 write_http_status_line(conn
, 503, "Network status object unavailable");
2568 smartlist_free(dir_fps
);
2569 geoip_note_ns_response(act
, GEOIP_REJECT_UNAVAILABLE
);
2573 if (!dirserv_remove_old_statuses(dir_fps
, if_modified_since
)) {
2574 write_http_status_line(conn
, 404, "Not found");
2575 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2576 smartlist_free(dir_fps
);
2577 geoip_note_ns_response(act
, GEOIP_REJECT_NOT_FOUND
);
2579 } else if (!smartlist_len(dir_fps
)) {
2580 write_http_status_line(conn
, 304, "Not modified");
2581 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2582 smartlist_free(dir_fps
);
2583 geoip_note_ns_response(act
, GEOIP_REJECT_NOT_MODIFIED
);
2587 dlen
= dirserv_estimate_data_size(dir_fps
, 0, compressed
);
2588 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2589 log_debug(LD_DIRSERV
,
2590 "Client asked for network status lists, but we've been "
2591 "writing too many bytes lately. Sending 503 Dir busy.");
2592 write_http_status_line(conn
, 503, "Directory busy, try again later");
2593 SMARTLIST_FOREACH(dir_fps
, char *, fp
, tor_free(fp
));
2594 smartlist_free(dir_fps
);
2595 geoip_note_ns_response(act
, GEOIP_REJECT_BUSY
);
2601 if (tor_inet_aton((TO_CONN(conn
))->address
, &in
)) {
2602 geoip_note_client_seen(act
, ntohl(in
.s_addr
), time(NULL
));
2603 geoip_note_ns_response(act
, GEOIP_SUCCESS
);
2604 /* Note that a request for a network status has started, so that we
2605 * can measure the download time later on. */
2606 if (TO_CONN(conn
)->dirreq_id
)
2607 geoip_start_dirreq(TO_CONN(conn
)->dirreq_id
, dlen
, act
,
2610 geoip_start_dirreq(TO_CONN(conn
)->global_identifier
, dlen
, act
,
2615 // note_request(request_type,dlen);
2616 (void) request_type
;
2617 write_http_response_header(conn
, -1, compressed
,
2618 smartlist_len(dir_fps
) == 1 ? lifetime
: 0);
2619 conn
->fingerprint_stack
= dir_fps
;
2621 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2623 /* Prime the connection with some data. */
2624 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
2625 connection_dirserv_flushed_some(conn
);
2629 if (!strcmpstart(url
,"/tor/status-vote/current/") ||
2630 !strcmpstart(url
,"/tor/status-vote/next/")) {
2631 /* XXXX If-modified-since is only implemented for the current
2632 * consensus: that's probably fine, since it's the only vote document
2633 * people fetch much. */
2635 ssize_t body_len
= 0;
2636 ssize_t estimated_len
= 0;
2637 smartlist_t
*items
= smartlist_create();
2638 smartlist_t
*dir_items
= smartlist_create();
2639 int lifetime
= 60; /* XXXX022 should actually use vote intervals. */
2640 url
+= strlen("/tor/status-vote/");
2641 current
= !strcmpstart(url
, "current/");
2642 url
= strchr(url
, '/');
2645 if (!strcmp(url
, "consensus")) {
2647 tor_assert(!current
); /* we handle current consensus specially above,
2648 * since it wants to be spooled. */
2649 if ((item
= dirvote_get_pending_consensus(FLAV_NS
)))
2650 smartlist_add(items
, (char*)item
);
2651 } else if (!current
&& !strcmp(url
, "consensus-signatures")) {
2652 /* XXXX the spec says that we should implement
2653 * current/consensus-signatures too. It doesn't seem to be needed,
2656 if ((item
=dirvote_get_pending_detached_signatures()))
2657 smartlist_add(items
, (char*)item
);
2658 } else if (!strcmp(url
, "authority")) {
2659 const cached_dir_t
*d
;
2660 int flags
= DGV_BY_ID
|
2661 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2662 if ((d
=dirvote_get_vote(NULL
, flags
)))
2663 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2665 const cached_dir_t
*d
;
2666 smartlist_t
*fps
= smartlist_create();
2668 if (!strcmpstart(url
, "d/")) {
2670 flags
= DGV_INCLUDE_PENDING
| DGV_INCLUDE_PREVIOUS
;
2673 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2675 dir_split_resource_into_fingerprints(url
, fps
, NULL
,
2676 DSR_HEX
|DSR_SORT_UNIQ
);
2677 SMARTLIST_FOREACH(fps
, char *, fp
, {
2678 if ((d
= dirvote_get_vote(fp
, flags
)))
2679 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2682 smartlist_free(fps
);
2684 if (!smartlist_len(dir_items
) && !smartlist_len(items
)) {
2685 write_http_status_line(conn
, 404, "Not found");
2688 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2689 body_len
+= compressed
? d
->dir_z_len
: d
->dir_len
);
2690 estimated_len
+= body_len
;
2691 SMARTLIST_FOREACH(items
, const char *, item
, {
2692 size_t ln
= strlen(item
);
2694 estimated_len
+= ln
/2;
2696 body_len
+= ln
; estimated_len
+= ln
;
2700 if (global_write_bucket_low(TO_CONN(conn
), estimated_len
, 2)) {
2701 write_http_status_line(conn
, 503, "Directory busy, try again later.");
2704 write_http_response_header(conn
, body_len
? body_len
: -1, compressed
,
2707 if (smartlist_len(items
)) {
2709 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2710 SMARTLIST_FOREACH(items
, const char *, c
,
2711 connection_write_to_buf_zlib(c
, strlen(c
), conn
, 0));
2712 connection_write_to_buf_zlib("", 0, conn
, 1);
2714 SMARTLIST_FOREACH(items
, const char *, c
,
2715 connection_write_to_buf(c
, strlen(c
), TO_CONN(conn
)));
2718 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2719 connection_write_to_buf(compressed
? d
->dir_z
: d
->dir
,
2720 compressed
? d
->dir_z_len
: d
->dir_len
,
2724 smartlist_free(items
);
2725 smartlist_free(dir_items
);
2729 if (!strcmpstart(url
, "/tor/micro/d/")) {
2730 smartlist_t
*fps
= smartlist_create();
2732 dir_split_resource_into_fingerprints(url
+strlen("/tor/micro/d/"),
2734 DSR_DIGEST256
|DSR_BASE64
|DSR_SORT_UNIQ
);
2736 if (!dirserv_have_any_microdesc(fps
)) {
2737 write_http_status_line(conn
, 404, "Not found");
2738 SMARTLIST_FOREACH(fps
, char *, fp
, tor_free(fp
));
2739 smartlist_free(fps
);
2742 dlen
= dirserv_estimate_microdesc_size(fps
, compressed
);
2743 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2744 log_info(LD_DIRSERV
,
2745 "Client asked for server descriptors, but we've been "
2746 "writing too many bytes lately. Sending 503 Dir busy.");
2747 write_http_status_line(conn
, 503, "Directory busy, try again later");
2748 SMARTLIST_FOREACH(fps
, char *, fp
, tor_free(fp
));
2749 smartlist_free(fps
);
2753 write_http_response_header(conn
, -1, compressed
, MICRODESC_CACHE_LIFETIME
);
2754 conn
->dir_spool_src
= DIR_SPOOL_MICRODESC
;
2755 conn
->fingerprint_stack
= fps
;
2758 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2760 connection_dirserv_flushed_some(conn
);
2764 if (!strcmpstart(url
,"/tor/server/") ||
2765 (!options
->BridgeAuthoritativeDir
&&
2766 !options
->BridgeRelay
&& !strcmpstart(url
,"/tor/extra/"))) {
2769 const char *request_type
= NULL
;
2770 int cache_lifetime
= 0;
2771 int is_extra
= !strcmpstart(url
,"/tor/extra/");
2772 url
+= is_extra
? strlen("/tor/extra/") : strlen("/tor/server/");
2773 conn
->fingerprint_stack
= smartlist_create();
2774 res
= dirserv_get_routerdesc_fingerprints(conn
->fingerprint_stack
, url
,
2776 !connection_dir_is_encrypted(conn
),
2779 if (!strcmpstart(url
, "fp/")) {
2780 request_type
= compressed
?"/tor/server/fp.z":"/tor/server/fp";
2781 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2782 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2783 } else if (!strcmpstart(url
, "authority")) {
2784 request_type
= compressed
?"/tor/server/authority.z":
2785 "/tor/server/authority";
2786 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2787 } else if (!strcmpstart(url
, "all")) {
2788 request_type
= compressed
?"/tor/server/all.z":"/tor/server/all";
2789 cache_lifetime
= FULL_DIR_CACHE_LIFETIME
;
2790 } else if (!strcmpstart(url
, "d/")) {
2791 request_type
= compressed
?"/tor/server/d.z":"/tor/server/d";
2792 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2793 cache_lifetime
= ROUTERDESC_BY_DIGEST_CACHE_LIFETIME
;
2795 request_type
= "/tor/server/?";
2797 (void) request_type
; /* usable for note_request. */
2798 if (!strcmpstart(url
, "d/"))
2799 conn
->dir_spool_src
=
2800 is_extra
? DIR_SPOOL_EXTRA_BY_DIGEST
: DIR_SPOOL_SERVER_BY_DIGEST
;
2802 conn
->dir_spool_src
=
2803 is_extra
? DIR_SPOOL_EXTRA_BY_FP
: DIR_SPOOL_SERVER_BY_FP
;
2805 if (!dirserv_have_any_serverdesc(conn
->fingerprint_stack
,
2806 conn
->dir_spool_src
)) {
2812 write_http_status_line(conn
, 404, msg
);
2814 dlen
= dirserv_estimate_data_size(conn
->fingerprint_stack
,
2816 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2817 log_info(LD_DIRSERV
,
2818 "Client asked for server descriptors, but we've been "
2819 "writing too many bytes lately. Sending 503 Dir busy.");
2820 write_http_status_line(conn
, 503, "Directory busy, try again later");
2821 conn
->dir_spool_src
= DIR_SPOOL_NONE
;
2824 write_http_response_header(conn
, -1, compressed
, cache_lifetime
);
2826 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2827 /* Prime the connection with some data. */
2828 connection_dirserv_flushed_some(conn
);
2833 if (!strcmpstart(url
,"/tor/keys/")) {
2834 smartlist_t
*certs
= smartlist_create();
2836 if (!strcmp(url
, "/tor/keys/all")) {
2837 authority_cert_get_all(certs
);
2838 } else if (!strcmp(url
, "/tor/keys/authority")) {
2839 authority_cert_t
*cert
= get_my_v3_authority_cert();
2841 smartlist_add(certs
, cert
);
2842 } else if (!strcmpstart(url
, "/tor/keys/fp/")) {
2843 smartlist_t
*fps
= smartlist_create();
2844 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/fp/"),
2846 DSR_HEX
|DSR_SORT_UNIQ
);
2847 SMARTLIST_FOREACH(fps
, char *, d
, {
2848 authority_cert_t
*c
= authority_cert_get_newest_by_id(d
);
2849 if (c
) smartlist_add(certs
, c
);
2852 smartlist_free(fps
);
2853 } else if (!strcmpstart(url
, "/tor/keys/sk/")) {
2854 smartlist_t
*fps
= smartlist_create();
2855 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/sk/"),
2857 DSR_HEX
|DSR_SORT_UNIQ
);
2858 SMARTLIST_FOREACH(fps
, char *, d
, {
2859 authority_cert_t
*c
= authority_cert_get_by_sk_digest(d
);
2860 if (c
) smartlist_add(certs
, c
);
2863 smartlist_free(fps
);
2864 } else if (!strcmpstart(url
, "/tor/keys/fp-sk/")) {
2865 smartlist_t
*fp_sks
= smartlist_create();
2866 dir_split_resource_into_fingerprint_pairs(url
+strlen("/tor/keys/fp-sk/"),
2868 SMARTLIST_FOREACH(fp_sks
, fp_pair_t
*, pair
, {
2869 authority_cert_t
*c
= authority_cert_get_by_digests(pair
->first
,
2871 if (c
) smartlist_add(certs
, c
);
2874 smartlist_free(fp_sks
);
2876 write_http_status_line(conn
, 400, "Bad request");
2879 if (!smartlist_len(certs
)) {
2880 write_http_status_line(conn
, 404, "Not found");
2883 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2884 if (c
->cache_info
.published_on
< if_modified_since
)
2885 SMARTLIST_DEL_CURRENT(certs
, c
));
2886 if (!smartlist_len(certs
)) {
2887 write_http_status_line(conn
, 304, "Not modified");
2891 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2892 len
+= c
->cache_info
.signed_descriptor_len
);
2894 if (global_write_bucket_low(TO_CONN(conn
), compressed
?len
/2:len
, 2)) {
2895 write_http_status_line(conn
, 503, "Directory busy, try again later.");
2899 write_http_response_header(conn
, compressed
?-1:len
, compressed
, 60*60);
2901 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2902 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2903 connection_write_to_buf_zlib(c
->cache_info
.signed_descriptor_body
,
2904 c
->cache_info
.signed_descriptor_len
,
2906 connection_write_to_buf_zlib("", 0, conn
, 1);
2908 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2909 connection_write_to_buf(c
->cache_info
.signed_descriptor_body
,
2910 c
->cache_info
.signed_descriptor_len
,
2914 smartlist_free(certs
);
2918 if (options
->HidServDirectoryV2
&&
2919 !strcmpstart(url
,"/tor/rendezvous2/")) {
2920 /* Handle v2 rendezvous descriptor fetch request. */
2922 const char *query
= url
+ strlen("/tor/rendezvous2/");
2923 if (strlen(query
) == REND_DESC_ID_V2_LEN_BASE32
) {
2924 log_info(LD_REND
, "Got a v2 rendezvous descriptor request for ID '%s'",
2926 switch (rend_cache_lookup_v2_desc_as_dir(query
, &descp
)) {
2928 write_http_response_header(conn
, strlen(descp
), 0, 0);
2929 connection_write_to_buf(descp
, strlen(descp
), TO_CONN(conn
));
2931 case 0: /* well-formed but not present */
2932 write_http_status_line(conn
, 404, "Not found");
2934 case -1: /* not well-formed */
2935 write_http_status_line(conn
, 400, "Bad request");
2938 } else { /* not well-formed */
2939 write_http_status_line(conn
, 400, "Bad request");
2944 if (options
->HSAuthoritativeDir
&& !strcmpstart(url
,"/tor/rendezvous/")) {
2945 /* rendezvous descriptor fetch */
2948 const char *query
= url
+strlen("/tor/rendezvous/");
2950 log_info(LD_REND
, "Handling rendezvous descriptor get");
2951 switch (rend_cache_lookup_desc(query
, 0, &descp
, &desc_len
)) {
2953 write_http_response_header_impl(conn
, desc_len
,
2954 "application/octet-stream",
2956 note_request("/tor/rendezvous?/", desc_len
);
2957 /* need to send descp separately, because it may include NULs */
2958 connection_write_to_buf(descp
, desc_len
, TO_CONN(conn
));
2960 case 0: /* well-formed but not present */
2961 write_http_status_line(conn
, 404, "Not found");
2963 case -1: /* not well-formed */
2964 write_http_status_line(conn
, 400, "Bad request");
2970 if (options
->BridgeAuthoritativeDir
&&
2971 options
->BridgePassword
&&
2972 connection_dir_is_encrypted(conn
) &&
2973 !strcmp(url
,"/tor/networkstatus-bridges")) {
2975 char *secret
= alloc_http_authenticator(options
->BridgePassword
);
2977 header
= http_get_header(headers
, "Authorization: Basic ");
2979 /* now make sure the password is there and right */
2980 if (!header
|| strcmp(header
, secret
)) {
2981 write_http_status_line(conn
, 404, "Not found");
2989 /* all happy now. send an answer. */
2990 status
= networkstatus_getinfo_by_purpose("bridge", time(NULL
));
2991 dlen
= strlen(status
);
2992 write_http_response_header(conn
, dlen
, 0, 0);
2993 connection_write_to_buf(status
, dlen
, TO_CONN(conn
));
2998 if (!strcmpstart(url
,"/tor/bytes.txt")) {
2999 char *bytes
= directory_dump_request_log();
3000 size_t len
= strlen(bytes
);
3001 write_http_response_header(conn
, len
, 0, 0);
3002 connection_write_to_buf(bytes
, len
, TO_CONN(conn
));
3007 if (!strcmp(url
,"/tor/robots.txt")) { /* /robots.txt will have been
3008 rewritten to /tor/robots.txt */
3009 char robots
[] = "User-agent: *\r\nDisallow: /\r\n";
3010 size_t len
= strlen(robots
);
3011 write_http_response_header(conn
, len
, 0, ROBOTS_CACHE_LIFETIME
);
3012 connection_write_to_buf(robots
, len
, TO_CONN(conn
));
3016 if (!strcmp(url
,"/tor/dbg-stability.txt")) {
3017 const char *stability
;
3019 if (options
->BridgeAuthoritativeDir
||
3020 ! authdir_mode_tests_reachability(options
) ||
3021 ! (stability
= rep_hist_get_router_stability_doc(time(NULL
)))) {
3022 write_http_status_line(conn
, 404, "Not found.");
3026 len
= strlen(stability
);
3027 write_http_response_header(conn
, len
, 0, 0);
3028 connection_write_to_buf(stability
, len
, TO_CONN(conn
));
3032 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
3033 #define ADD_MALLINFO_LINE(x) do { \
3034 tor_snprintf(tmp, sizeof(tmp), "%s %d\n", #x, mi.x); \
3035 smartlist_add(lines, tor_strdup(tmp)); \
3038 if (!strcmp(url
,"/tor/mallinfo.txt") &&
3039 (tor_addr_eq_ipv4h(&conn
->_base
.addr
, 0x7f000001ul
))) {
3046 memset(&mi
, 0, sizeof(mi
));
3048 lines
= smartlist_create();
3050 ADD_MALLINFO_LINE(arena
)
3051 ADD_MALLINFO_LINE(ordblks
)
3052 ADD_MALLINFO_LINE(smblks
)
3053 ADD_MALLINFO_LINE(hblks
)
3054 ADD_MALLINFO_LINE(hblkhd
)
3055 ADD_MALLINFO_LINE(usmblks
)
3056 ADD_MALLINFO_LINE(fsmblks
)
3057 ADD_MALLINFO_LINE(uordblks
)
3058 ADD_MALLINFO_LINE(fordblks
)
3059 ADD_MALLINFO_LINE(keepcost
)
3061 result
= smartlist_join_strings(lines
, "", 0, NULL
);
3062 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
3063 smartlist_free(lines
);
3065 len
= strlen(result
);
3066 write_http_response_header(conn
, len
, 0, 0);
3067 connection_write_to_buf(result
, len
, TO_CONN(conn
));
3073 /* we didn't recognize the url */
3074 write_http_status_line(conn
, 404, "Not found");
3081 /** Helper function: called when a dirserver gets a complete HTTP POST
3082 * request. Look for an uploaded server descriptor or rendezvous
3083 * service descriptor. On finding one, process it and write a
3084 * response into conn-\>outbuf. If the request is unrecognized, send a
3085 * 400. Always return 0. */
3087 directory_handle_command_post(dir_connection_t
*conn
, const char *headers
,
3088 const char *body
, size_t body_len
)
3091 or_options_t
*options
= get_options();
3093 log_debug(LD_DIRSERV
,"Received POST command.");
3095 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
3097 if (parse_http_url(headers
, &url
) < 0) {
3098 write_http_status_line(conn
, 400, "Bad request");
3101 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
3103 /* Handle v2 rendezvous service publish request. */
3104 if (options
->HidServDirectoryV2
&&
3105 !strcmpstart(url
,"/tor/rendezvous2/publish")) {
3106 switch (rend_cache_store_v2_desc_as_dir(body
)) {
3108 log_info(LD_REND
, "Rejected v2 rend descriptor (length %d) from %s "
3109 "since we're not currently a hidden service directory.",
3110 (int)body_len
, conn
->_base
.address
);
3111 write_http_status_line(conn
, 503, "Currently not acting as v2 "
3112 "hidden service directory");
3115 log_warn(LD_REND
, "Rejected v2 rend descriptor (length %d) from %s.",
3116 (int)body_len
, conn
->_base
.address
);
3117 write_http_status_line(conn
, 400,
3118 "Invalid v2 service descriptor rejected");
3121 write_http_status_line(conn
, 200, "Service descriptor (v2) stored");
3122 log_info(LD_REND
, "Handled v2 rendezvous descriptor post: accepted");
3127 if (!authdir_mode(options
)) {
3128 /* we just provide cached directories; we don't want to
3129 * receive anything. */
3130 write_http_status_line(conn
, 400, "Nonauthoritative directory does not "
3131 "accept posted server descriptors");
3135 if (authdir_mode_handles_descs(options
, -1) &&
3136 !strcmp(url
,"/tor/")) { /* server descriptor post */
3137 const char *msg
= "[None]";
3138 uint8_t purpose
= authdir_mode_bridge(options
) ?
3139 ROUTER_PURPOSE_BRIDGE
: ROUTER_PURPOSE_GENERAL
;
3140 was_router_added_t r
= dirserv_add_multiple_descriptors(body
, purpose
,
3141 conn
->_base
.address
, &msg
);
3143 if (WRA_WAS_ADDED(r
))
3144 dirserv_get_directory(); /* rebuild and write to disk */
3146 if (r
== ROUTER_ADDED_NOTIFY_GENERATOR
) {
3147 /* Accepted with a message. */
3148 log_info(LD_DIRSERV
,
3149 "Problematic router descriptor or extra-info from %s "
3151 conn
->_base
.address
, msg
);
3152 write_http_status_line(conn
, 400, msg
);
3153 } else if (r
== ROUTER_ADDED_SUCCESSFULLY
) {
3154 write_http_status_line(conn
, 200, msg
);
3155 } else if (WRA_WAS_OUTDATED(r
)) {
3156 write_http_response_header_impl(conn
, -1, NULL
, NULL
,
3157 "X-Descriptor-Not-New: Yes\r\n", -1);
3159 log_info(LD_DIRSERV
,
3160 "Rejected router descriptor or extra-info from %s "
3162 conn
->_base
.address
, msg
);
3163 write_http_status_line(conn
, 400, msg
);
3168 if (options
->HSAuthoritativeDir
&&
3169 !strcmpstart(url
,"/tor/rendezvous/publish")) {
3170 /* rendezvous descriptor post */
3171 log_info(LD_REND
, "Handling rendezvous descriptor post.");
3172 if (rend_cache_store(body
, body_len
, 1) < 0) {
3173 log_fn(LOG_PROTOCOL_WARN
, LD_DIRSERV
,
3174 "Rejected rend descriptor (length %d) from %s.",
3175 (int)body_len
, conn
->_base
.address
);
3176 write_http_status_line(conn
, 400,
3177 "Invalid v0 service descriptor rejected");
3179 write_http_status_line(conn
, 200, "Service descriptor (v0) stored");
3184 if (authdir_mode_v3(options
) &&
3185 !strcmp(url
,"/tor/post/vote")) { /* v3 networkstatus vote */
3186 const char *msg
= "OK";
3188 if (dirvote_add_vote(body
, &msg
, &status
)) {
3189 write_http_status_line(conn
, status
, "Vote stored");
3192 write_http_status_line(conn
, status
, msg
);
3197 if (authdir_mode_v3(options
) &&
3198 !strcmp(url
,"/tor/post/consensus-signature")) { /* sigs on consensus. */
3199 const char *msg
= NULL
;
3200 if (dirvote_add_signatures(body
, conn
->_base
.address
, &msg
)>=0) {
3201 write_http_status_line(conn
, 200, msg
?msg
:"Signatures stored");
3203 log_warn(LD_DIR
, "Unable to store signatures posted by %s: %s",
3204 conn
->_base
.address
, msg
?msg
:"???");
3205 write_http_status_line(conn
, 400, msg
?msg
:"Unable to store signatures");
3210 /* we didn't recognize the url */
3211 write_http_status_line(conn
, 404, "Not found");
3218 /** Called when a dirserver receives data on a directory connection;
3219 * looks for an HTTP request. If the request is complete, remove it
3220 * from the inbuf, try to process it; otherwise, leave it on the
3221 * buffer. Return a 0 on success, or -1 on error.
3224 directory_handle_command(dir_connection_t
*conn
)
3226 char *headers
=NULL
, *body
=NULL
;
3231 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
3233 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
3234 &headers
, MAX_HEADERS_SIZE
,
3235 &body
, &body_len
, MAX_DIR_UL_SIZE
, 0)) {
3236 case -1: /* overflow */
3237 log_warn(LD_DIRSERV
,
3238 "Request too large from address '%s' to DirPort. Closing.",
3239 safe_str(conn
->_base
.address
));
3242 log_debug(LD_DIRSERV
,"command not all here yet.");
3244 /* case 1, fall through */
3247 http_set_address_origin(headers
, TO_CONN(conn
));
3248 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
3250 if (!strncasecmp(headers
,"GET",3))
3251 r
= directory_handle_command_get(conn
, headers
, body
, body_len
);
3252 else if (!strncasecmp(headers
,"POST",4))
3253 r
= directory_handle_command_post(conn
, headers
, body
, body_len
);
3255 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
3256 "Got headers %s with unknown command. Closing.",
3261 tor_free(headers
); tor_free(body
);
3265 /** Write handler for directory connections; called when all data has
3266 * been flushed. Close the connection or wait for a response as
3270 connection_dir_finished_flushing(dir_connection_t
*conn
)
3273 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
3275 /* Note that we have finished writing the directory response. For direct
3276 * connections this means we're done, for tunneled connections its only
3277 * an intermediate step. */
3278 if (TO_CONN(conn
)->dirreq_id
)
3279 geoip_change_dirreq_state(TO_CONN(conn
)->dirreq_id
, DIRREQ_TUNNELED
,
3280 DIRREQ_FLUSHING_DIR_CONN_FINISHED
);
3282 geoip_change_dirreq_state(TO_CONN(conn
)->global_identifier
,
3284 DIRREQ_FLUSHING_DIR_CONN_FINISHED
);
3285 switch (conn
->_base
.state
) {
3286 case DIR_CONN_STATE_CLIENT_SENDING
:
3287 log_debug(LD_DIR
,"client finished sending command.");
3288 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_READING
;
3289 connection_stop_writing(TO_CONN(conn
));
3291 case DIR_CONN_STATE_SERVER_WRITING
:
3292 log_debug(LD_DIRSERV
,"Finished writing server response. Closing.");
3293 connection_mark_for_close(TO_CONN(conn
));
3296 log_warn(LD_BUG
,"called in unexpected state %d.",
3298 tor_fragile_assert();
3304 /** Connected handler for directory connections: begin sending data to the
3307 connection_dir_finished_connecting(dir_connection_t
*conn
)
3310 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
3311 tor_assert(conn
->_base
.state
== DIR_CONN_STATE_CONNECTING
);
3313 log_debug(LD_HTTP
,"Dir connection to router %s:%u established.",
3314 conn
->_base
.address
,conn
->_base
.port
);
3316 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
; /* start flushing conn */
3320 /** Called when one or more networkstatus fetches have failed (with uppercase
3321 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
3322 * failed once, unless they failed with status code 503. */
3324 dir_networkstatus_download_failed(smartlist_t
*failed
, int status_code
)
3326 if (status_code
== 503)
3328 SMARTLIST_FOREACH(failed
, const char *, fp
,
3330 char digest
[DIGEST_LEN
];
3331 trusted_dir_server_t
*dir
;
3332 if (base16_decode(digest
, DIGEST_LEN
, fp
, strlen(fp
))<0) {
3333 log_warn(LD_BUG
, "Called with bad fingerprint in list: %s",
3337 dir
= router_get_trusteddirserver_by_digest(digest
);
3340 download_status_failed(&dir
->v2_ns_dl_status
, status_code
);
3344 /** Schedule for when servers should download things in general. */
3345 static const int server_dl_schedule
[] = {
3346 0, 0, 0, 60, 60, 60*2, 60*5, 60*15, INT_MAX
3348 /** Schedule for when clients should download things in general. */
3349 static const int client_dl_schedule
[] = {
3350 0, 0, 60, 60*5, 60*10, INT_MAX
3352 /** Schedule for when servers should download consensuses. */
3353 static const int server_consensus_dl_schedule
[] = {
3354 0, 0, 60, 60*5, 60*10, 60*30, 60*30, 60*30, 60*30, 60*30, 60*60, 60*60*2
3356 /** Schedule for when clients should download consensuses. */
3357 static const int client_consensus_dl_schedule
[] = {
3358 0, 0, 60, 60*5, 60*10, 60*30, 60*60, 60*60, 60*60, 60*60*3, 60*60*6, 60*60*12
3360 /** Schedule for when clients should download bridge descriptors. */
3361 static const int bridge_dl_schedule
[] = {
3362 60*60, 15*60, 15*60, 60*60
3365 /** Decide which download schedule we want to use, and then return a
3366 * pointer to it along with a pointer to its length. Helper function for
3367 * download_status_increment_failure() and download_status_reset(). */
3369 find_dl_schedule_and_len(download_status_t
*dls
, int server
,
3370 const int **schedule
, size_t *schedule_len
)
3372 switch (dls
->schedule
) {
3373 case DL_SCHED_GENERIC
:
3375 *schedule
= server_dl_schedule
;
3376 *schedule_len
= sizeof(server_dl_schedule
)/sizeof(int);
3378 *schedule
= client_dl_schedule
;
3379 *schedule_len
= sizeof(client_dl_schedule
)/sizeof(int);
3382 case DL_SCHED_CONSENSUS
:
3384 *schedule
= server_consensus_dl_schedule
;
3385 *schedule_len
= sizeof(server_consensus_dl_schedule
)/sizeof(int);
3387 *schedule
= client_consensus_dl_schedule
;
3388 *schedule_len
= sizeof(client_consensus_dl_schedule
)/sizeof(int);
3391 case DL_SCHED_BRIDGE
:
3392 *schedule
= bridge_dl_schedule
;
3393 *schedule_len
= sizeof(bridge_dl_schedule
)/sizeof(int);
3400 /** Called when an attempt to download <b>dls</b> has failed with HTTP status
3401 * <b>status_code</b>. Increment the failure count (if the code indicates a
3402 * real failure) and set <b>dls</b>-\>next_attempt_at to an appropriate time
3405 download_status_increment_failure(download_status_t
*dls
, int status_code
,
3406 const char *item
, int server
, time_t now
)
3408 const int *schedule
;
3409 size_t schedule_len
;
3412 if (status_code
!= 503 || server
) {
3413 if (dls
->n_download_failures
< IMPOSSIBLE_TO_DOWNLOAD
-1)
3414 ++dls
->n_download_failures
;
3417 find_dl_schedule_and_len(dls
, server
, &schedule
, &schedule_len
);
3419 if (dls
->n_download_failures
< schedule_len
)
3420 increment
= schedule
[dls
->n_download_failures
];
3421 else if (dls
->n_download_failures
== IMPOSSIBLE_TO_DOWNLOAD
)
3422 increment
= INT_MAX
;
3424 increment
= schedule
[schedule_len
-1];
3426 if (increment
< INT_MAX
)
3427 dls
->next_attempt_at
= now
+increment
;
3429 dls
->next_attempt_at
= TIME_MAX
;
3433 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again immediately.",
3434 item
, (int)dls
->n_download_failures
);
3435 else if (dls
->next_attempt_at
< TIME_MAX
)
3436 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again in %d seconds.",
3437 item
, (int)dls
->n_download_failures
,
3438 (int)(dls
->next_attempt_at
-now
));
3440 log_debug(LD_DIR
, "%s failed %d time(s); Giving up for a while.",
3441 item
, (int)dls
->n_download_failures
);
3443 return dls
->next_attempt_at
;
3446 /** Reset <b>dls</b> so that it will be considered downloadable
3447 * immediately, and/or to show that we don't need it anymore.
3449 * (We find the zeroth element of the download schedule, and set
3450 * next_attempt_at to be the appropriate offset from 'now'. In most
3451 * cases this means setting it to 'now', so the item will be immediately
3452 * downloadable; in the case of bridge descriptors, the zeroth element
3453 * is an hour from now.) */
3455 download_status_reset(download_status_t
*dls
)
3457 const int *schedule
;
3458 size_t schedule_len
;
3460 find_dl_schedule_and_len(dls
, get_options()->DirPort
,
3461 &schedule
, &schedule_len
);
3463 dls
->n_download_failures
= 0;
3464 dls
->next_attempt_at
= time(NULL
) + schedule
[0];
3467 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
3468 * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
3469 * either as descriptor digests or as identity digests based on
3470 * <b>was_descriptor_digests</b>).
3473 dir_routerdesc_download_failed(smartlist_t
*failed
, int status_code
,
3475 int was_extrainfo
, int was_descriptor_digests
)
3477 char digest
[DIGEST_LEN
];
3478 time_t now
= time(NULL
);
3479 int server
= directory_fetches_from_authorities(get_options());
3480 if (!was_descriptor_digests
) {
3481 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
) {
3482 tor_assert(!was_extrainfo
); /* not supported yet */
3483 SMARTLIST_FOREACH(failed
, const char *, cp
,
3485 if (base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
))<0) {
3486 log_warn(LD_BUG
, "Malformed fingerprint in list: %s",
3490 retry_bridge_descriptor_fetch_directly(digest
);
3493 return; /* FFFF should implement for other-than-router-purpose someday */
3495 SMARTLIST_FOREACH(failed
, const char *, cp
,
3497 download_status_t
*dls
= NULL
;
3498 if (base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
)) < 0) {
3499 log_warn(LD_BUG
, "Malformed fingerprint in list: %s", escaped(cp
));
3502 if (was_extrainfo
) {
3503 signed_descriptor_t
*sd
=
3504 router_get_by_extrainfo_digest(digest
);
3506 dls
= &sd
->ei_dl_status
;
3508 dls
= router_get_dl_status_by_descriptor_digest(digest
);
3510 if (!dls
|| dls
->n_download_failures
>= MAX_ROUTERDESC_DOWNLOAD_FAILURES
)
3512 download_status_increment_failure(dls
, status_code
, cp
, server
, now
);
3515 /* No need to relaunch descriptor downloads here: we already do it
3516 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
3519 /** Helper. Compare two fp_pair_t objects, and return -1, 0, or 1 as
3522 _compare_pairs(const void **a
, const void **b
)
3524 const fp_pair_t
*fp1
= *a
, *fp2
= *b
;
3526 if ((r
= memcmp(fp1
->first
, fp2
->first
, DIGEST_LEN
)))
3529 return memcmp(fp1
->second
, fp2
->second
, DIGEST_LEN
);
3532 /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
3533 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
3534 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
3535 * fp_pair_t into <b>pairs_out</b>. On failure, return -1. */
3537 dir_split_resource_into_fingerprint_pairs(const char *res
,
3538 smartlist_t
*pairs_out
)
3540 smartlist_t
*pairs_tmp
= smartlist_create();
3541 smartlist_t
*pairs_result
= smartlist_create();
3543 smartlist_split_string(pairs_tmp
, res
, "+", 0, 0);
3544 if (smartlist_len(pairs_tmp
)) {
3545 char *last
= smartlist_get(pairs_tmp
,smartlist_len(pairs_tmp
)-1);
3546 size_t last_len
= strlen(last
);
3547 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
3548 last
[last_len
-2] = '\0';
3551 SMARTLIST_FOREACH_BEGIN(pairs_tmp
, char *, cp
) {
3552 if (strlen(cp
) != HEX_DIGEST_LEN
*2+1) {
3554 "Skipping digest pair %s with non-standard length.", escaped(cp
));
3555 } else if (cp
[HEX_DIGEST_LEN
] != '-') {
3557 "Skipping digest pair %s with missing dash.", escaped(cp
));
3560 if (base16_decode(pair
.first
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
)<0 ||
3561 base16_decode(pair
.second
,
3562 DIGEST_LEN
, cp
+HEX_DIGEST_LEN
+1, HEX_DIGEST_LEN
)<0) {
3563 log_info(LD_DIR
, "Skipping non-decodable digest pair %s", escaped(cp
));
3565 smartlist_add(pairs_result
, tor_memdup(&pair
, sizeof(pair
)));
3569 } SMARTLIST_FOREACH_END(cp
);
3570 smartlist_free(pairs_tmp
);
3573 smartlist_sort(pairs_result
, _compare_pairs
);
3574 smartlist_uniq(pairs_result
, _compare_pairs
, _tor_free
);
3576 smartlist_add_all(pairs_out
, pairs_result
);
3577 smartlist_free(pairs_result
);
3581 /** Given a directory <b>resource</b> request, containing zero
3582 * or more strings separated by plus signs, followed optionally by ".z", store
3583 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
3584 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0.
3586 * If (flags & DSR_HEX), then delete all elements that aren't hex digests, and
3587 * decode the rest. If (flags & DSR_BASE64), then use "-" rather than "+" as
3588 * a separator, delete all the elements that aren't base64-encoded digests,
3589 * and decode the rest. If (flags & DSR_DIGEST256), these digests should be
3590 * 256 bits long; else they should be 160.
3592 * If (flags & DSR_SORT_UNIQ), then sort the list and remove all duplicates.
3595 dir_split_resource_into_fingerprints(const char *resource
,
3596 smartlist_t
*fp_out
, int *compressed_out
,
3599 const int decode_hex
= flags
& DSR_HEX
;
3600 const int decode_base64
= flags
& DSR_BASE64
;
3601 const int digests_are_256
= flags
& DSR_DIGEST256
;
3602 const int sort_uniq
= flags
& DSR_SORT_UNIQ
;
3604 const int digest_len
= digests_are_256
? DIGEST256_LEN
: DIGEST_LEN
;
3605 const int hex_digest_len
= digests_are_256
?
3606 HEX_DIGEST256_LEN
: HEX_DIGEST_LEN
;
3607 const int base64_digest_len
= digests_are_256
?
3608 BASE64_DIGEST256_LEN
: BASE64_DIGEST_LEN
;
3609 smartlist_t
*fp_tmp
= smartlist_create();
3611 tor_assert(!(decode_hex
&& decode_base64
));
3614 smartlist_split_string(fp_tmp
, resource
, decode_base64
?"-":"+", 0, 0);
3616 *compressed_out
= 0;
3617 if (smartlist_len(fp_tmp
)) {
3618 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
3619 size_t last_len
= strlen(last
);
3620 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
3621 last
[last_len
-2] = '\0';
3623 *compressed_out
= 1;
3626 if (decode_hex
|| decode_base64
) {
3627 const size_t encoded_len
= decode_hex
? hex_digest_len
: base64_digest_len
;
3629 char *cp
, *d
= NULL
;
3630 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
3631 cp
= smartlist_get(fp_tmp
, i
);
3632 if (strlen(cp
) != encoded_len
) {
3634 "Skipping digest %s with non-standard length.", escaped(cp
));
3635 smartlist_del_keeporder(fp_tmp
, i
--);
3638 d
= tor_malloc_zero(digest_len
);
3640 (base16_decode(d
, digest_len
, cp
, hex_digest_len
)<0) :
3641 (base64_decode(d
, digest_len
, cp
, base64_digest_len
)<0)) {
3642 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
3643 smartlist_del_keeporder(fp_tmp
, i
--);
3646 smartlist_set(fp_tmp
, i
, d
);
3654 if (decode_hex
|| decode_base64
) {
3655 if (digests_are_256
) {
3656 smartlist_sort_digests256(fp_tmp
);
3657 smartlist_uniq_digests256(fp_tmp
);
3659 smartlist_sort_digests(fp_tmp
);
3660 smartlist_uniq_digests(fp_tmp
);
3663 smartlist_sort_strings(fp_tmp
);
3664 smartlist_uniq_strings(fp_tmp
);
3667 smartlist_add_all(fp_out
, fp_tmp
);
3668 smartlist_free(fp_tmp
);