1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2007 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
5 const char directory_c_id
[] =
9 #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 time_t if_modified_since
);
40 static int directory_handle_command(dir_connection_t
*conn
);
41 static int body_is_plausible(const char *body
, size_t body_len
, int purpose
);
42 static int purpose_needs_anonymity(uint8_t dir_purpose
,
43 uint8_t router_purpose
);
44 static char *http_get_header(const char *headers
, const char *which
);
45 static void http_set_address_origin(const char *headers
, connection_t
*conn
);
46 static void connection_dir_download_networkstatus_failed(
47 dir_connection_t
*conn
, int status_code
);
48 static void connection_dir_download_routerdesc_failed(dir_connection_t
*conn
);
49 static void connection_dir_download_cert_failed(
50 dir_connection_t
*conn
, int status_code
);
51 static void dir_networkstatus_download_failed(smartlist_t
*failed
,
53 static void dir_routerdesc_download_failed(smartlist_t
*failed
,
57 int was_descriptor_digests
);
58 static void note_request(const char *key
, size_t bytes
);
60 /********* START VARIABLES **********/
62 /** How far in the future do we allow a directory server to tell us it is
63 * before deciding that one of us has the wrong time? */
64 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
66 #define X_ADDRESS_HEADER "X-Your-Address-Is: "
68 /** HTTP cache control: how long do we tell proxies they can cache each
69 * kind of document we serve? */
70 #define FULL_DIR_CACHE_LIFETIME (60*60)
71 #define RUNNINGROUTERS_CACHE_LIFETIME (20*60)
72 #define NETWORKSTATUS_CACHE_LIFETIME (5*60)
73 #define ROUTERDESC_CACHE_LIFETIME (30*60)
74 #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
75 #define ROBOTS_CACHE_LIFETIME (24*60*60)
77 /********* END VARIABLES ************/
79 /** Return true iff the directory purpose 'purpose' must use an
80 * anonymous connection to a directory. */
82 purpose_needs_anonymity(uint8_t dir_purpose
, uint8_t router_purpose
)
84 if (get_options()->AllDirActionsPrivate
)
86 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
&& has_completed_circuit
)
87 return 1; /* if no circuits yet, we may need this info to bootstrap. */
88 if (dir_purpose
== DIR_PURPOSE_FETCH_DIR
||
89 dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
||
90 dir_purpose
== DIR_PURPOSE_UPLOAD_VOTE
||
91 dir_purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
||
92 dir_purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
||
93 dir_purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
||
94 dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
95 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
||
96 dir_purpose
== DIR_PURPOSE_FETCH_CONSENSUS
||
97 dir_purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
||
98 dir_purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
99 dir_purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
)
104 /** Return a newly allocated string describing <b>auth</b>. */
106 authority_type_to_string(authority_type_t auth
)
109 smartlist_t
*lst
= smartlist_create();
110 if (auth
& V1_AUTHORITY
)
111 smartlist_add(lst
, (void*)"V1");
112 if (auth
& V2_AUTHORITY
)
113 smartlist_add(lst
, (void*)"V2");
114 if (auth
& BRIDGE_AUTHORITY
)
115 smartlist_add(lst
, (void*)"Bridge");
116 if (auth
& HIDSERV_AUTHORITY
)
117 smartlist_add(lst
, (void*)"Hidden service");
118 if (smartlist_len(lst
)) {
119 result
= smartlist_join_strings(lst
, ", ", 0, NULL
);
121 result
= tor_strdup("[Not an authority]");
127 /** Return a string describing a given directory connection purpose. */
129 dir_conn_purpose_to_string(int purpose
)
133 case DIR_PURPOSE_FETCH_DIR
:
134 return "v1 directory fetch";
135 case DIR_PURPOSE_FETCH_RENDDESC
:
136 return "hidden-service descriptor fetch";
137 case DIR_PURPOSE_UPLOAD_DIR
:
138 return "server descriptor upload";
139 case DIR_PURPOSE_UPLOAD_RENDDESC
:
140 return "hidden-service descriptor upload";
141 case DIR_PURPOSE_UPLOAD_VOTE
:
142 return "server vote upload";
143 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
144 return "consensus signature upload";
145 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
146 return "running-routers fetch";
147 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
148 return "network-status fetch";
149 case DIR_PURPOSE_FETCH_SERVERDESC
:
150 return "server descriptor fetch";
151 case DIR_PURPOSE_FETCH_EXTRAINFO
:
152 return "extra-info fetch";
153 case DIR_PURPOSE_FETCH_CONSENSUS
:
154 return "consensus network-status fetch";
155 case DIR_PURPOSE_FETCH_CERTIFICATE
:
156 return "authority cert fetch";
157 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
158 return "status vote fetch";
159 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
160 return "consensus signature fetch";
161 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
162 return "hidden-service v2 descriptor fetch";
163 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
164 return "hidden-service v2 descriptor upload";
167 log_warn(LD_BUG
, "Called with unknown purpose %d", purpose
);
171 /** Return true iff <b>identity_digest</b> is the digest of a router we
172 * believe to support extrainfo downloads. (If <b>is_authority</b> we do
173 * additional checking that's only valid for authorities.) */
175 router_supports_extrainfo(const char *identity_digest
, int is_authority
)
177 routerinfo_t
*ri
= router_get_by_digest(identity_digest
);
180 if (ri
->caches_extra_info
)
182 if (is_authority
&& ri
->platform
&&
183 tor_version_as_new_as(ri
->platform
, "Tor 0.2.0.0-alpha-dev (r10070)"))
187 routerstatus_t
*rs
= router_get_consensus_status_by_id(identity_digest
);
188 if (rs
&& rs
->version_supports_extrainfo_upload
)
194 /** Return true iff all trusted directory servers have accepted our
195 * server descriptor. */
197 directories_have_accepted_server_descriptor(void)
199 smartlist_t
*servers
= router_get_trusted_dir_servers();
200 or_options_t
*options
= get_options();
201 /* XXX020 If any authority of the needed type is down, this
202 * function will never return true. Perhaps we need to be
203 * tolerant of down servers? Or even better, should we change
204 * this so one successful upload is enough? -RD */
205 SMARTLIST_FOREACH(servers
, trusted_dir_server_t
*, d
, {
206 if ((d
->type
& options
->_PublishServerDescriptor
) &&
207 !d
->has_accepted_serverdesc
) {
214 /** Start a connection to every suitable directory authority, using
215 * connection purpose 'purpose' and uploading the payload 'payload'
216 * (length 'payload_len'). The purpose should be one of
217 * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
219 * <b>type</b> specifies what sort of dir authorities (V1, V2,
220 * HIDSERV, BRIDGE) we should upload to.
222 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
223 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
224 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
225 * to all authorities, and the extra-info document to all authorities that
229 directory_post_to_dirservers(uint8_t dir_purpose
, uint8_t router_purpose
,
230 authority_type_t type
,
232 size_t payload_len
, size_t extrainfo_len
)
235 smartlist_t
*dirservers
= router_get_trusted_dir_servers();
237 tor_assert(dirservers
);
238 /* This tries dirservers which we believe to be down, but ultimately, that's
239 * harmless, and we may as well err on the side of getting things uploaded.
241 SMARTLIST_FOREACH(dirservers
, trusted_dir_server_t
*, ds
,
243 routerstatus_t
*rs
= &(ds
->fake_status
);
244 size_t upload_len
= payload_len
;
246 if ((type
& ds
->type
) == 0)
249 found
= 1; /* at least one authority of this type was listed */
250 if (dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
)
251 ds
->has_accepted_serverdesc
= 0;
253 if (extrainfo_len
&& router_supports_extrainfo(ds
->digest
, 1)) {
254 upload_len
+= extrainfo_len
;
255 log_info(LD_DIR
, "Uploading an extrainfo (length %d)",
256 (int) extrainfo_len
);
258 post_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
) ||
259 !fascist_firewall_allows_address_dir(ds
->addr
, ds
->dir_port
);
260 directory_initiate_command_routerstatus(rs
, dir_purpose
,
263 NULL
, payload
, upload_len
, 0);
266 char *s
= authority_type_to_string(type
);
267 log_warn(LD_DIR
, "Publishing server descriptor to directory authorities "
268 "of type '%s', but no authorities of that type listed!", s
);
273 /** Start a connection to a random running directory server, using
274 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
275 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
276 * If <b>retry_if_no_servers</b>, then if all the possible servers seem
277 * down, mark them up and try again.
280 directory_get_from_dirserver(uint8_t dir_purpose
, uint8_t router_purpose
,
281 const char *resource
, int retry_if_no_servers
)
283 routerstatus_t
*rs
= NULL
;
284 or_options_t
*options
= get_options();
285 int prefer_authority
= server_mode(options
) && dirserver_mode(options
);
286 int get_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
);
287 authority_type_t type
;
288 int flags
= retry_if_no_servers
? PDS_RETRY_IF_NO_SERVERS
: 0;
289 time_t if_modified_since
= 0;
291 /* FFFF we could break this switch into its own function, and call
292 * it elsewhere in directory.c. -RD */
293 switch (dir_purpose
) {
294 case DIR_PURPOSE_FETCH_EXTRAINFO
:
295 type
= EXTRAINFO_CACHE
|
296 (router_purpose
== ROUTER_PURPOSE_BRIDGE
? BRIDGE_AUTHORITY
:
299 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
300 case DIR_PURPOSE_FETCH_SERVERDESC
:
301 type
= (router_purpose
== ROUTER_PURPOSE_BRIDGE
? BRIDGE_AUTHORITY
:
304 case DIR_PURPOSE_FETCH_DIR
:
305 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
308 case DIR_PURPOSE_FETCH_RENDDESC
:
309 type
= HIDSERV_AUTHORITY
;
311 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
312 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
315 case DIR_PURPOSE_FETCH_CONSENSUS
:
316 case DIR_PURPOSE_FETCH_CERTIFICATE
:
320 log_warn(LD_BUG
, "Unexpected purpose %d", (int)dir_purpose
);
324 if (DIR_PURPOSE_FETCH_CONSENSUS
) {
325 networkstatus_vote_t
*v
= networkstatus_get_latest_consensus();
327 if_modified_since
= v
->valid_after
+ 180;
330 if (!options
->FetchServerDescriptors
&& type
!= HIDSERV_AUTHORITY
)
334 if (options
->UseBridges
&& type
!= BRIDGE_AUTHORITY
) {
335 /* want to ask a running bridge for which we have a descriptor. */
336 /* XXX020 we assume that all of our bridges can answer any
337 * possible directory question. This won't be true forever. -RD */
338 routerinfo_t
*ri
= choose_random_entry(NULL
);
340 directory_initiate_command(ri
->address
, ri
->addr
,
342 1, ri
->cache_info
.identity_digest
,
345 0, resource
, NULL
, 0, if_modified_since
);
347 log_notice(LD_DIR
, "Ignoring directory request, since no bridge "
348 "nodes are available yet.");
351 if (prefer_authority
|| type
== BRIDGE_AUTHORITY
) {
352 /* only ask authdirservers, and don't ask myself */
353 rs
= router_pick_trusteddirserver(type
, flags
);
355 if (!rs
&& type
!= BRIDGE_AUTHORITY
) {
356 /* anybody with a non-zero dirport will do */
357 rs
= router_pick_directory_server(type
, flags
);
359 log_info(LD_DIR
, "No router found for %s; falling back to "
360 "dirserver list.", dir_conn_purpose_to_string(dir_purpose
));
361 rs
= router_pick_trusteddirserver(type
, flags
);
363 get_via_tor
= 1; /* last resort: try routing it via Tor */
367 } else { /* get_via_tor */
368 /* Never use fascistfirewall; we're going via Tor. */
369 if (dir_purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
370 /* only ask hidserv authorities, any of them will do */
371 flags
|= PDS_IGNORE_FASCISTFIREWALL
|PDS_ALLOW_SELF
;
372 rs
= router_pick_trusteddirserver(HIDSERV_AUTHORITY
, flags
);
374 /* anybody with a non-zero dirport will do. Disregard firewalls. */
375 flags
|= PDS_IGNORE_FASCISTFIREWALL
;
376 rs
= router_pick_directory_server(type
, flags
);
377 /* If we have any hope of building an indirect conn, we know some router
378 * descriptors. If (rs==NULL), we can't build circuits anyway, so
379 * there's no point in falling back to the authorities in this case. */
384 directory_initiate_command_routerstatus(rs
, dir_purpose
,
391 "While fetching directory info, "
392 "no running dirservers known. Will try again later. "
393 "(purpose %d)", dir_purpose
);
394 if (!purpose_needs_anonymity(dir_purpose
, router_purpose
)) {
395 /* remember we tried them all and failed. */
396 directory_all_unreachable(time(NULL
));
401 /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
402 * directory authority other than ourself. Only for use by authorities when
403 * searching for missing information while voting. */
405 directory_get_from_all_authorities(uint8_t dir_purpose
,
406 uint8_t router_purpose
,
407 const char *resource
)
409 tor_assert(dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
410 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
);
412 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
413 trusted_dir_server_t
*, ds
,
416 if (router_digest_is_me(ds
->digest
))
418 if (!(ds
->type
& V3_AUTHORITY
))
420 rs
= &ds
->fake_status
;
421 directory_initiate_command_routerstatus(rs
, dir_purpose
, router_purpose
,
422 0, resource
, NULL
, 0, 0);
426 /** Launch a new connection to the directory server <b>status</b> to
427 * upload or download a server or rendezvous
428 * descriptor. <b>dir_purpose</b> determines what
429 * kind of directory connection we're launching, and must be one of
430 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. <b>router_purpose</b>
431 * specifies the descriptor purposes we have in mind (currently only
432 * used for FETCH_DIR).
434 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
435 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
437 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
441 directory_initiate_command_routerstatus(routerstatus_t
*status
,
443 uint8_t router_purpose
,
444 int anonymized_connection
,
445 const char *resource
,
448 time_t if_modified_since
)
450 routerinfo_t
*router
;
451 char address_buf
[INET_NTOA_BUF_LEN
+1];
454 if ((router
= router_get_by_digest(status
->identity_digest
))) {
455 address
= router
->address
;
457 in
.s_addr
= htonl(status
->addr
);
458 tor_inet_ntoa(&in
, address_buf
, sizeof(address_buf
));
459 address
= address_buf
;
461 directory_initiate_command(address
, status
->addr
,
462 status
->or_port
, status
->dir_port
,
463 status
->version_supports_begindir
,
464 status
->identity_digest
,
465 dir_purpose
, router_purpose
,
466 anonymized_connection
, resource
,
467 payload
, payload_len
, if_modified_since
);
470 /** Return true iff <b>conn</b> is the client side of a directory connection
471 * we launched to ourself in order to determine the reachability of our
474 directory_conn_is_self_reachability_test(dir_connection_t
*conn
)
476 if (conn
->requested_resource
&&
477 !strcmpstart(conn
->requested_resource
,"authority")) {
478 routerinfo_t
*me
= router_get_my_routerinfo();
480 router_digest_is_me(conn
->identity_digest
) &&
481 me
->addr
== conn
->_base
.addr
&&
482 me
->dir_port
== conn
->_base
.port
)
488 /** Called when we are unable to complete the client's request to a directory
489 * server due to a network error: Mark the router as down and try again if
493 connection_dir_request_failed(dir_connection_t
*conn
)
495 if (directory_conn_is_self_reachability_test(conn
)) {
496 routerinfo_t
*me
= router_get_my_routerinfo();
498 control_event_server_status(LOG_WARN
,
499 "REACHABILITY_FAILED DIRADDRESS=%s:%d",
500 me
->address
, me
->dir_port
);
501 return; /* this was a test fetch. don't retry. */
503 router_set_status(conn
->identity_digest
, 0); /* don't try him again */
504 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
||
505 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
506 log_info(LD_DIR
, "Giving up on directory server at '%s:%d'; retrying",
507 conn
->_base
.address
, conn
->_base
.port
);
508 directory_get_from_dirserver(conn
->_base
.purpose
, conn
->router_purpose
,
509 NULL
, 0 /* don't retry_if_no_servers */);
510 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
511 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
512 conn
->_base
.address
);
513 connection_dir_download_networkstatus_failed(conn
, -1);
514 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
515 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
516 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
517 conn
->_base
.address
);
518 connection_dir_download_routerdesc_failed(conn
);
519 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
520 networkstatus_consensus_download_failed(0);
521 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
522 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
523 conn
->_base
.address
);
524 connection_dir_download_cert_failed(conn
, 0);
525 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
526 log_info(LD_DIR
, "Giving up downloading detached signatures from '%s'",
527 conn
->_base
.address
);
528 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
529 log_info(LD_DIR
, "Giving up downloading votes from '%s'",
530 conn
->_base
.address
);
534 /** Called when an attempt to download one or more network status
535 * documents on connection <b>conn</b> failed. Decide whether to
536 * retry the fetch now, later, or never.
539 connection_dir_download_networkstatus_failed(dir_connection_t
*conn
,
542 if (!conn
->requested_resource
) {
543 /* We never reached directory_send_command, which means that we never
544 * opened a network connection. Either we're out of sockets, or the
545 * network is down. Either way, retrying would be pointless. */
548 if (!strcmpstart(conn
->requested_resource
, "all")) {
549 /* We're a non-authoritative directory cache; try again. Ignore status
550 * code, since we don't want to keep trying forever in a tight loop
551 * if all the authorities are shutting us out. */
552 smartlist_t
*trusted_dirs
= router_get_trusted_dir_servers();
553 SMARTLIST_FOREACH(trusted_dirs
, trusted_dir_server_t
*, ds
,
554 download_status_failed(&ds
->v2_ns_dl_status
, 0));
555 directory_get_from_dirserver(conn
->_base
.purpose
, conn
->router_purpose
,
556 "all.z", 0 /* don't retry_if_no_servers */);
557 } else if (!strcmpstart(conn
->requested_resource
, "fp/")) {
558 /* We were trying to download by fingerprint; mark them all as having
559 * failed, and possibly retry them later.*/
560 smartlist_t
*failed
= smartlist_create();
561 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
563 if (smartlist_len(failed
)) {
564 dir_networkstatus_download_failed(failed
, status_code
);
565 SMARTLIST_FOREACH(failed
, char *, cp
, tor_free(cp
));
567 smartlist_free(failed
);
571 /** Called when an attempt to download one or more router descriptors
572 * or extra-info documents on connection <b>conn</b> failed.
575 connection_dir_download_routerdesc_failed(dir_connection_t
*conn
)
577 /* No need to increment the failure count for routerdescs, since
578 * it's not their fault. */
580 /* No need to relaunch descriptor downloads here: we already do it
581 * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
582 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
583 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
588 /** Called when an attempt to fetch a certificate fails. */
590 connection_dir_download_cert_failed(dir_connection_t
*conn
, int status
)
593 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
);
595 if (!conn
->requested_resource
)
597 failed
= smartlist_create();
598 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
600 SMARTLIST_FOREACH(failed
, char *, cp
,
602 trusted_dir_server_t
*dir
= trusteddirserver_get_by_v3_auth_digest(cp
);
604 download_status_failed(&dir
->cert_dl_status
, status
);
607 smartlist_free(failed
);
609 update_certificate_downloads(time(NULL
));
612 /** Helper for directory_initiate_command_routerstatus: send the
613 * command to a server whose address is <b>address</b>, whose IP is
614 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
615 * <b>supports_begindir</b>, and whose identity key digest is
618 directory_initiate_command(const char *address
, uint32_t addr
,
619 uint16_t or_port
, uint16_t dir_port
,
620 int supports_begindir
, const char *digest
,
621 uint8_t dir_purpose
, uint8_t router_purpose
,
622 int anonymized_connection
, const char *resource
,
623 const char *payload
, size_t payload_len
,
624 time_t if_modified_since
)
626 dir_connection_t
*conn
;
627 or_options_t
*options
= get_options();
628 int use_begindir
= supports_begindir
&& or_port
&&
629 (options
->TunnelDirConns
||
630 router_purpose
== ROUTER_PURPOSE_BRIDGE
) &&
631 (anonymized_connection
||
632 fascist_firewall_allows_address_or(addr
, or_port
));
636 tor_assert(or_port
|| dir_port
);
639 log_debug(LD_DIR
, "anonymized %d, use_begindir %d.",
640 anonymized_connection
, use_begindir
);
642 log_debug(LD_DIR
, "Initiating %s", dir_conn_purpose_to_string(dir_purpose
));
644 conn
= TO_DIR_CONN(connection_new(CONN_TYPE_DIR
, AF_INET
));
646 /* set up conn so it's got all the data we need to remember */
647 conn
->_base
.addr
= addr
;
648 conn
->_base
.port
= use_begindir
? or_port
: dir_port
;
649 conn
->_base
.address
= tor_strdup(address
);
650 memcpy(conn
->identity_digest
, digest
, DIGEST_LEN
);
652 conn
->_base
.purpose
= dir_purpose
;
653 conn
->router_purpose
= router_purpose
;
655 /* give it an initial state */
656 conn
->_base
.state
= DIR_CONN_STATE_CONNECTING
;
658 /* decide whether we can learn our IP address from this conn */
659 conn
->dirconn_direct
= !anonymized_connection
;
661 if (!anonymized_connection
&& !use_begindir
) {
662 /* then we want to connect to dirport directly */
664 if (options
->HttpProxy
) {
665 addr
= options
->HttpProxyAddr
;
666 dir_port
= options
->HttpProxyPort
;
669 switch (connection_connect(TO_CONN(conn
), conn
->_base
.address
, addr
,
672 connection_dir_request_failed(conn
); /* retry if we want */
673 /* XXX we only pass 'conn' above, not 'resource', 'payload',
674 * etc. So in many situations it can't retry! -RD */
675 connection_free(TO_CONN(conn
));
678 /* start flushing conn */
679 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
682 /* queue the command on the outbuf */
683 directory_send_command(conn
, dir_purpose
, 1, resource
,
684 payload
, payload_len
, if_modified_since
);
685 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
686 /* writable indicates finish, readable indicates broken link,
687 error indicates broken link in windowsland. */
689 } else { /* we want to connect via a tor connection */
690 edge_connection_t
*linked_conn
;
691 /* make an AP connection
692 * populate it and add it at the right state
696 connection_ap_make_link(conn
->_base
.address
, conn
->_base
.port
,
697 digest
, use_begindir
, conn
->dirconn_direct
);
699 log_warn(LD_NET
,"Making tunnel to dirserver failed.");
700 connection_mark_for_close(TO_CONN(conn
));
703 connection_link_connections(TO_CONN(conn
), TO_CONN(linked_conn
));
705 if (connection_add(TO_CONN(conn
)) < 0) {
706 log_warn(LD_NET
,"Unable to add connection for link to dirserver.");
707 connection_mark_for_close(TO_CONN(conn
));
710 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
711 /* queue the command on the outbuf */
712 directory_send_command(conn
, dir_purpose
, 0, resource
,
713 payload
, payload_len
, if_modified_since
);
714 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
715 connection_start_reading(TO_CONN(linked_conn
));
719 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
720 * are as in directory_initiate_command.
723 directory_send_command(dir_connection_t
*conn
,
724 int purpose
, int direct
, const char *resource
,
725 const char *payload
, size_t payload_len
,
726 time_t if_modified_since
)
728 char proxystring
[256];
729 char proxyauthstring
[256];
730 char hoststring
[128];
731 char imsstring
[RFC1123_TIME_LEN
+32];
734 const char *httpcommand
= NULL
;
738 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
740 tor_free(conn
->requested_resource
);
742 conn
->requested_resource
= tor_strdup(resource
);
744 /* come up with a string for which Host: we want */
745 if (conn
->_base
.port
== 80) {
746 strlcpy(hoststring
, conn
->_base
.address
, sizeof(hoststring
));
748 tor_snprintf(hoststring
, sizeof(hoststring
),"%s:%d",
749 conn
->_base
.address
, conn
->_base
.port
);
752 /* Format if-modified-since */
753 if (!if_modified_since
) {
756 char b
[RFC1123_TIME_LEN
+1];
757 format_rfc1123_time(b
, if_modified_since
);
758 tor_snprintf(imsstring
, sizeof(imsstring
), "\r\nIf-Modified-Since: %s", b
);
761 /* come up with some proxy lines, if we're using one. */
762 if (direct
&& get_options()->HttpProxy
) {
763 char *base64_authenticator
=NULL
;
764 const char *authenticator
= get_options()->HttpProxyAuthenticator
;
766 tor_snprintf(proxystring
, sizeof(proxystring
),"http://%s", hoststring
);
768 base64_authenticator
= alloc_http_authenticator(authenticator
);
769 if (!base64_authenticator
)
770 log_warn(LD_BUG
, "Encoding http authenticator failed");
772 if (base64_authenticator
) {
773 tor_snprintf(proxyauthstring
, sizeof(proxyauthstring
),
774 "\r\nProxy-Authorization: Basic %s",
775 base64_authenticator
);
776 tor_free(base64_authenticator
);
778 proxyauthstring
[0] = 0;
782 proxyauthstring
[0] = 0;
786 case DIR_PURPOSE_FETCH_DIR
:
787 tor_assert(!resource
);
788 tor_assert(!payload
);
790 url
= tor_strdup("/tor/dir.z");
792 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
793 tor_assert(!resource
);
794 tor_assert(!payload
);
796 url
= tor_strdup("/tor/running-routers");
798 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
800 len
= strlen(resource
)+32;
801 url
= tor_malloc(len
);
802 tor_snprintf(url
, len
, "/tor/status/%s", resource
);
804 case DIR_PURPOSE_FETCH_CONSENSUS
:
805 tor_assert(!resource
);
806 tor_assert(!payload
);
808 url
= tor_strdup("/tor/status-vote/current/consensus.z");
810 case DIR_PURPOSE_FETCH_CERTIFICATE
:
811 tor_assert(resource
);
812 tor_assert(!payload
);
814 len
= strlen(resource
)+32;
815 url
= tor_malloc(len
);
816 tor_snprintf(url
, len
, "/tor/keys/%s", resource
);
818 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
819 tor_assert(resource
);
820 tor_assert(!payload
);
822 len
= strlen(resource
)+32;
823 url
= tor_malloc(len
);
824 tor_snprintf(url
, len
, "/tor/status-vote/next/%s.z", resource
);
826 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
827 tor_assert(!resource
);
828 tor_assert(!payload
);
830 url
= tor_strdup("/tor/status-vote/next/consensus-signatures.z");
832 case DIR_PURPOSE_FETCH_SERVERDESC
:
834 len
= strlen(resource
)+32;
835 url
= tor_malloc(len
);
836 tor_snprintf(url
, len
, "/tor/server/%s", resource
);
838 case DIR_PURPOSE_FETCH_EXTRAINFO
:
840 len
= strlen(resource
)+32;
841 url
= tor_malloc(len
);
842 tor_snprintf(url
, len
, "/tor/extra/%s", resource
);
844 case DIR_PURPOSE_UPLOAD_DIR
:
845 tor_assert(!resource
);
847 httpcommand
= "POST";
848 url
= tor_strdup("/tor/");
850 case DIR_PURPOSE_UPLOAD_VOTE
:
851 tor_assert(!resource
);
853 httpcommand
= "POST";
854 url
= tor_strdup("/tor/post/vote");
856 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
857 tor_assert(!resource
);
859 httpcommand
= "POST";
860 url
= tor_strdup("/tor/post/consensus-signature");
862 case DIR_PURPOSE_FETCH_RENDDESC
:
863 tor_assert(resource
);
864 tor_assert(!payload
);
866 /* this must be true or we wouldn't be doing the lookup */
867 tor_assert(strlen(resource
) <= REND_SERVICE_ID_LEN
);
868 /* This breaks the function abstraction. */
869 strlcpy(conn
->rend_query
, resource
, sizeof(conn
->rend_query
));
872 /* Request the most recent versioned descriptor. */
873 // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
874 // but that never got testing, and it wasn't a good design.)
875 len
= strlen(resource
)+32;
876 url
= tor_malloc(len
);
877 tor_snprintf(url
, len
, "/tor/rendezvous/%s", resource
);
879 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
880 tor_assert(resource
);
881 tor_assert(!payload
);
882 tor_assert(strlen(resource
) <= REND_DESC_ID_V2_LEN_BASE32
);
884 len
= strlen(resource
) + 32;
885 url
= tor_malloc(len
);
886 tor_snprintf(url
, len
, "/tor/rendezvous2/%s", resource
);
888 case DIR_PURPOSE_UPLOAD_RENDDESC
:
889 tor_assert(!resource
);
891 httpcommand
= "POST";
892 url
= tor_strdup("/tor/rendezvous/publish");
894 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
895 tor_assert(!resource
);
897 httpcommand
= "POST";
898 url
= tor_strdup("/tor/rendezvous2/publish");
905 if (strlen(proxystring
) + strlen(url
) >= 4096) {
907 "Squid does not like URLs longer than 4095 bytes, and this "
908 "one is %d bytes long: %s%s",
909 (int)(strlen(proxystring
) + strlen(url
)), proxystring
, url
);
912 tor_snprintf(request
, sizeof(request
), "%s %s", httpcommand
, proxystring
);
913 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
914 connection_write_to_buf(url
, strlen(url
), TO_CONN(conn
));
917 if (!strcmp(httpcommand
, "GET") && !payload
) {
918 tor_snprintf(request
, sizeof(request
),
919 " HTTP/1.0\r\nHost: %s%s%s\r\n\r\n",
924 tor_snprintf(request
, sizeof(request
),
925 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s%s\r\n\r\n",
926 payload
? (unsigned long)payload_len
: 0,
931 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
934 /* then send the payload afterwards too */
935 connection_write_to_buf(payload
, payload_len
, TO_CONN(conn
));
939 /** Parse an HTTP request string <b>headers</b> of the form
941 * "\%s [http[s]://]\%s HTTP/1..."
943 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
944 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
945 * so it does. Return 0.
946 * Otherwise, return -1.
949 parse_http_url(const char *headers
, char **url
)
951 char *s
, *start
, *tmp
;
953 s
= (char *)eat_whitespace_no_nl(headers
);
955 s
= (char *)find_whitespace(s
); /* get past GET/POST */
957 s
= (char *)eat_whitespace_no_nl(s
);
959 start
= s
; /* this is it, assuming it's valid */
960 s
= (char *)find_whitespace(start
);
963 /* tolerate the http[s] proxy style of putting the hostname in the url */
964 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
968 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
969 tmp
= strchr(tmp
+3, '/');
970 if (tmp
&& tmp
< s
) {
971 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname' string");
977 if (s
-start
< 5 || strcmpstart(start
,"/tor/")) { /* need to rewrite it */
978 *url
= tor_malloc(s
- start
+ 5);
979 strlcpy(*url
,"/tor", s
-start
+5);
980 strlcat((*url
)+4, start
, s
-start
+1);
982 *url
= tor_strndup(start
, s
-start
);
987 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
988 * <b>which</b>. The key should be given with a terminating colon and space;
989 * this function copies everything after, up to but not including the
990 * following \\r\\n. */
992 http_get_header(const char *headers
, const char *which
)
994 const char *cp
= headers
;
996 if (!strcmpstart(cp
, which
)) {
999 if ((eos
= strchr(cp
,'\r')))
1000 return tor_strndup(cp
, eos
-cp
);
1002 return tor_strdup(cp
);
1004 cp
= strchr(cp
, '\n');
1011 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
1012 * <b>conn</b>-\>address to describe our best guess of the address that
1013 * originated this HTTP request. */
1015 http_set_address_origin(const char *headers
, connection_t
*conn
)
1019 fwd
= http_get_header(headers
, "Forwarded-For: ");
1021 fwd
= http_get_header(headers
, "X-Forwarded-For: ");
1024 if (!tor_inet_aton(fwd
, &in
) || is_internal_IP(ntohl(in
.s_addr
), 0)) {
1025 log_debug(LD_DIR
, "Ignoring unrecognized or internal IP %s",
1030 tor_free(conn
->address
);
1031 conn
->address
= tor_strdup(fwd
);
1036 /** Parse an HTTP response string <b>headers</b> of the form
1038 * "HTTP/1.\%d \%d\%s\r\n...".
1041 * If it's well-formed, assign the status code to *<b>code</b> and
1042 * return 0. Otherwise, return -1.
1044 * On success: If <b>date</b> is provided, set *date to the Date
1045 * header in the http headers, or 0 if no such header is found. If
1046 * <b>compression</b> is provided, set *<b>compression</b> to the
1047 * compression method given in the Content-Encoding header, or 0 if no
1048 * such header is found, or -1 if the value of the header is not
1049 * recognized. If <b>reason</b> is provided, strdup the reason string
1053 parse_http_response(const char *headers
, int *code
, time_t *date
,
1054 compress_method_t
*compression
, char **reason
)
1057 char datestr
[RFC1123_TIME_LEN
+1];
1058 smartlist_t
*parsed_headers
;
1059 tor_assert(headers
);
1062 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
1064 if (sscanf(headers
, "HTTP/1.%d %d", &n1
, &n2
) < 2 ||
1065 (n1
!= 0 && n1
!= 1) ||
1066 (n2
< 100 || n2
>= 600)) {
1067 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
1072 parsed_headers
= smartlist_create();
1073 smartlist_split_string(parsed_headers
, headers
, "\n",
1074 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
1076 smartlist_t
*status_line_elements
= smartlist_create();
1077 tor_assert(smartlist_len(parsed_headers
));
1078 smartlist_split_string(status_line_elements
,
1079 smartlist_get(parsed_headers
, 0),
1080 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
1081 tor_assert(smartlist_len(status_line_elements
) <= 3);
1082 if (smartlist_len(status_line_elements
) == 3) {
1083 *reason
= smartlist_get(status_line_elements
, 2);
1084 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
1086 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
1087 smartlist_free(status_line_elements
);
1091 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1092 if (!strcmpstart(s
, "Date: ")) {
1093 strlcpy(datestr
, s
+6, sizeof(datestr
));
1094 /* This will do nothing on failure, so we don't need to check
1095 the result. We shouldn't warn, since there are many other valid
1096 date formats besides the one we use. */
1097 parse_rfc1123_time(datestr
, date
);
1102 const char *enc
= NULL
;
1103 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1104 if (!strcmpstart(s
, "Content-Encoding: ")) {
1107 if (!enc
|| !strcmp(enc
, "identity")) {
1108 *compression
= NO_METHOD
;
1109 } else if (!strcmp(enc
, "deflate") || !strcmp(enc
, "x-deflate")) {
1110 *compression
= ZLIB_METHOD
;
1111 } else if (!strcmp(enc
, "gzip") || !strcmp(enc
, "x-gzip")) {
1112 *compression
= GZIP_METHOD
;
1114 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
1116 *compression
= UNKNOWN_METHOD
;
1119 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
1120 smartlist_free(parsed_headers
);
1125 /** Return true iff <b>body</b> doesn't start with a plausible router or
1126 * running-list or directory opening. This is a sign of possible compression.
1129 body_is_plausible(const char *body
, size_t len
, int purpose
)
1133 return 1; /* empty bodies don't need decompression */
1136 if (purpose
!= DIR_PURPOSE_FETCH_RENDDESC
) {
1137 if (!strcmpstart(body
,"router") ||
1138 !strcmpstart(body
,"signed-directory") ||
1139 !strcmpstart(body
,"network-status") ||
1140 !strcmpstart(body
,"running-routers"))
1142 for (i
=0;i
<32;++i
) {
1143 if (!TOR_ISPRINT(body
[i
]) && !TOR_ISSPACE(body
[i
]))
1152 /** Called when we've just fetched a bunch of router descriptors in
1153 * <b>body</b>. The list <b>which</b>, if present, holds digests for
1154 * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1155 * is true, or identity digests otherwise. Parse the descriptors, validate
1156 * them, and annotate them as having purpose <b>purpose</b> and as having been
1157 * downloaded from <b>source</b>. */
1159 load_downloaded_routers(const char *body
, smartlist_t
*which
,
1160 int descriptor_digests
,
1165 char time_buf
[ISO_TIME_LEN
+1];
1166 int general
= router_purpose
== ROUTER_PURPOSE_GENERAL
;
1167 format_iso_time(time_buf
, time(NULL
));
1170 if (tor_snprintf(buf
, sizeof(buf
),
1171 "@downloaded-at %s\n"
1173 "%s%s%s", time_buf
, escaped(source
),
1174 !general
? "@purpose " : "",
1175 !general
? router_purpose_to_string(router_purpose
) : "",
1176 !general
? "\n" : "")<0)
1179 router_load_routers_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1180 descriptor_digests
, buf
);
1183 /** We are a client, and we've finished reading the server's
1184 * response. Parse and it and act appropriately.
1186 * If we're still happy with using this directory server in the future, return
1187 * 0. Otherwise return -1; and the caller should consider trying the request
1190 * The caller will take care of marking the connection for close.
1193 connection_dir_client_reached_eof(dir_connection_t
*conn
)
1197 char *reason
= NULL
;
1198 size_t body_len
=0, orig_len
=0;
1200 time_t date_header
=0;
1202 compress_method_t compression
;
1205 int allow_partial
= (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1206 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
1207 int was_compressed
=0;
1208 time_t now
= time(NULL
);
1210 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
1211 &headers
, MAX_HEADERS_SIZE
,
1212 &body
, &body_len
, MAX_DIR_DL_SIZE
,
1214 case -1: /* overflow */
1215 log_warn(LD_PROTOCOL
,
1216 "'fetch' response too large (server '%s:%d'). Closing.",
1217 conn
->_base
.address
, conn
->_base
.port
);
1221 "'fetch' response not all here, but we're at eof. Closing.");
1223 /* case 1, fall through */
1225 orig_len
= body_len
;
1227 if (parse_http_response(headers
, &status_code
, &date_header
,
1228 &compression
, &reason
) < 0) {
1229 log_warn(LD_HTTP
,"Unparseable headers (server '%s:%d'). Closing.",
1230 conn
->_base
.address
, conn
->_base
.port
);
1231 tor_free(body
); tor_free(headers
);
1234 if (!reason
) reason
= tor_strdup("[no reason given]");
1237 "Received response from directory server '%s:%d': %d %s",
1238 conn
->_base
.address
, conn
->_base
.port
, status_code
,
1241 /* now check if it's got any hints for us about our IP address. */
1242 if (conn
->dirconn_direct
) {
1243 char *guess
= http_get_header(headers
, X_ADDRESS_HEADER
);
1245 router_new_address_suggestion(guess
);
1250 if (date_header
> 0) {
1251 /* The date header was written very soon after we sent our request,
1252 * so compute the skew as the difference between sending the request
1253 * and the date header. (We used to check now-date_header, but that's
1254 * inaccurate if we spend a lot of time downloading.)
1256 delta
= conn
->_base
.timestamp_lastwritten
- date_header
;
1257 if (abs(delta
)>ALLOW_DIRECTORY_TIME_SKEW
) {
1259 int trusted
= router_digest_is_trusted_dir(conn
->identity_digest
);
1260 format_time_interval(dbuf
, sizeof(dbuf
), delta
);
1261 log_fn(trusted
? LOG_WARN
: LOG_INFO
,
1263 "Received directory with skewed time (server '%s:%d'): "
1264 "It seems that our clock is %s by %s, or that theirs is %s. "
1265 "Tor requires an accurate clock to work: please check your time "
1266 "and date settings.",
1267 conn
->_base
.address
, conn
->_base
.port
,
1268 delta
>0 ? "ahead" : "behind", dbuf
,
1269 delta
>0 ? "behind" : "ahead");
1270 skewed
= 1; /* don't check the recommended-versions line */
1271 control_event_general_status(trusted
? LOG_WARN
: LOG_NOTICE
,
1272 "CLOCK_SKEW SKEW=%d SOURCE=DIRSERV:%s:%d",
1273 delta
, conn
->_base
.address
, conn
->_base
.port
);
1275 log_debug(LD_HTTP
, "Time on received directory is within tolerance; "
1276 "we are %d seconds skewed. (That's okay.)", delta
);
1279 (void) skewed
; /* skewed isn't used yet. */
1281 if (status_code
== 503) {
1283 trusted_dir_server_t
*ds
;
1284 log_info(LD_DIR
,"Received http status code %d (%s) from server "
1285 "'%s:%d'. I'll try again soon.",
1286 status_code
, escaped(reason
), conn
->_base
.address
,
1288 if ((rs
= router_get_consensus_status_by_id(conn
->identity_digest
)))
1289 rs
->last_dir_503_at
= now
;
1290 if ((ds
= router_get_trusteddirserver_by_digest(conn
->identity_digest
)))
1291 ds
->fake_status
.last_dir_503_at
= now
;
1293 tor_free(body
); tor_free(headers
); tor_free(reason
);
1297 plausible
= body_is_plausible(body
, body_len
, conn
->_base
.purpose
);
1298 if (compression
!= NO_METHOD
|| !plausible
) {
1299 char *new_body
= NULL
;
1301 compress_method_t guessed
= detect_compression_method(body
, body_len
);
1302 if (compression
== UNKNOWN_METHOD
|| guessed
!= compression
) {
1303 /* Tell the user if we don't believe what we're told about compression.*/
1304 const char *description1
, *description2
;
1305 if (compression
== ZLIB_METHOD
)
1306 description1
= "as deflated";
1307 else if (compression
== GZIP_METHOD
)
1308 description1
= "as gzipped";
1309 else if (compression
== NO_METHOD
)
1310 description1
= "as uncompressed";
1312 description1
= "with an unknown Content-Encoding";
1313 if (guessed
== ZLIB_METHOD
)
1314 description2
= "deflated";
1315 else if (guessed
== GZIP_METHOD
)
1316 description2
= "gzipped";
1317 else if (!plausible
)
1318 description2
= "confusing binary junk";
1320 description2
= "uncompressed";
1322 log_info(LD_HTTP
, "HTTP body from server '%s:%d' was labeled %s, "
1323 "but it seems to be %s.%s",
1324 conn
->_base
.address
, conn
->_base
.port
, description1
,
1326 (compression
>0 && guessed
>0)?" Trying both.":"");
1328 /* Try declared compression first if we can. */
1329 if (compression
== GZIP_METHOD
|| compression
== ZLIB_METHOD
)
1330 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, compression
,
1331 !allow_partial
, LOG_PROTOCOL_WARN
);
1332 /* Okay, if that didn't work, and we think that it was compressed
1333 * differently, try that. */
1335 (guessed
== GZIP_METHOD
|| guessed
== ZLIB_METHOD
) &&
1336 compression
!= guessed
)
1337 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, guessed
,
1338 !allow_partial
, LOG_PROTOCOL_WARN
);
1339 /* If we're pretty sure that we have a compressed directory, and
1340 * we didn't manage to uncompress it, then warn and bail. */
1341 if (!plausible
&& !new_body
) {
1342 log_fn(LOG_PROTOCOL_WARN
, LD_HTTP
,
1343 "Unable to decompress HTTP body (server '%s:%d').",
1344 conn
->_base
.address
, conn
->_base
.port
);
1345 tor_free(body
); tor_free(headers
); tor_free(reason
);
1356 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
) {
1357 /* fetch/process the directory to cache it. */
1358 log_info(LD_DIR
,"Received directory (size %d) from server '%s:%d'",
1359 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1360 if (status_code
!= 200) {
1361 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1362 "'%s:%d' while fetching directory. I'll try again soon.",
1363 status_code
, escaped(reason
), conn
->_base
.address
,
1365 tor_free(body
); tor_free(headers
); tor_free(reason
);
1368 if (router_parse_directory(body
) < 0) {
1369 log_notice(LD_DIR
,"I failed to parse the directory I fetched from "
1370 "'%s:%d'. Ignoring.", conn
->_base
.address
, conn
->_base
.port
);
1372 note_request(was_compressed
?"dl/dir.z":"dl/dir", orig_len
);
1375 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
1376 /* just update our list of running routers, if this list is new info */
1377 log_info(LD_DIR
,"Received running-routers list (size %d)", (int)body_len
);
1378 if (status_code
!= 200) {
1379 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1380 "'%s:%d' while fetching running-routers. I'll try again soon.",
1381 status_code
, escaped(reason
), conn
->_base
.address
,
1383 tor_free(body
); tor_free(headers
); tor_free(reason
);
1386 if (router_parse_runningrouters(body
)<0) {
1388 "Bad running-routers from server '%s:%d'. I'll try again soon.",
1389 conn
->_base
.address
, conn
->_base
.port
);
1390 tor_free(body
); tor_free(headers
); tor_free(reason
);
1393 note_request(was_compressed
?"dl/running-routers.z":
1394 "dl/running-routers", orig_len
);
1397 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
1398 smartlist_t
*which
= NULL
;
1399 networkstatus_source_t source
;
1401 log_info(LD_DIR
,"Received networkstatus objects (size %d) from server "
1402 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1403 if (status_code
!= 200) {
1405 "Received http status code %d (%s) from server "
1406 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1407 status_code
, escaped(reason
), conn
->_base
.address
,
1408 conn
->_base
.port
, conn
->requested_resource
);
1409 tor_free(body
); tor_free(headers
); tor_free(reason
);
1410 connection_dir_download_networkstatus_failed(conn
, status_code
);
1413 note_request(was_compressed
?"dl/status.z":"dl/status", orig_len
);
1414 if (conn
->requested_resource
&&
1415 !strcmpstart(conn
->requested_resource
,"fp/")) {
1416 source
= NS_FROM_DIR_BY_FP
;
1417 which
= smartlist_create();
1418 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
1420 } else if (conn
->requested_resource
&&
1421 !strcmpstart(conn
->requested_resource
, "all")) {
1422 source
= NS_FROM_DIR_ALL
;
1423 which
= smartlist_create();
1424 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1425 trusted_dir_server_t
*, ds
,
1427 char *hex
= tor_malloc(HEX_DIGEST_LEN
+1);
1428 base16_encode(hex
, HEX_DIGEST_LEN
+1, ds
->digest
, DIGEST_LEN
);
1429 smartlist_add(which
, hex
);
1432 /* XXXX Can we even end up here? -- weasel*/
1433 source
= NS_FROM_DIR_BY_FP
;
1434 log_warn(LD_BUG
, "We received a networkstatus but we didn't ask "
1435 "for it by fp, nor did we ask for all.");
1439 char *next
= strstr(cp
, "\nnetwork-status-version");
1442 /* learn from it, and then remove it from 'which' */
1443 if (router_set_networkstatus_v2(cp
, now
, source
, which
)<0)
1451 routers_update_all_from_networkstatus(now
); /*launches router downloads*/
1452 directory_info_has_arrived(now
, 0);
1454 if (smartlist_len(which
)) {
1455 dir_networkstatus_download_failed(which
, status_code
);
1457 SMARTLIST_FOREACH(which
, char *, s
, tor_free(s
));
1458 smartlist_free(which
);
1462 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
1464 if (status_code
!= 200) {
1465 int severity
= (status_code
== 304) ? LOG_INFO
: LOG_WARN
;
1466 log(severity
, LD_DIR
,
1467 "Received http status code %d (%s) from server "
1468 "'%s:%d' while fetching consensus directory.",
1469 status_code
, escaped(reason
), conn
->_base
.address
,
1471 tor_free(body
); tor_free(headers
); tor_free(reason
);
1472 networkstatus_consensus_download_failed(status_code
);
1475 log_info(LD_DIR
,"Received consensus directory (size %d) from server "
1476 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1477 if ((r
=networkstatus_set_current_consensus(body
, 0, 0))<0) {
1478 log_fn(r
<-1?LOG_WARN
:LOG_INFO
, LD_DIR
,
1479 "Unable to load consensus directory downloaded from "
1480 "server '%s:%d'", conn
->_base
.address
, conn
->_base
.port
);
1481 tor_free(body
); tor_free(headers
); tor_free(reason
);
1482 networkstatus_consensus_download_failed(0);
1485 routers_update_all_from_networkstatus(now
); /*launches router downloads*/
1486 directory_info_has_arrived(now
, 0);
1487 log_info(LD_DIR
, "Successfully loaded consensus.");
1490 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
1491 if (status_code
!= 200) {
1493 "Received http status code %d (%s) from server "
1494 "'%s:%d' while fetching \"/tor/keys/%s\".",
1495 status_code
, escaped(reason
), conn
->_base
.address
,
1496 conn
->_base
.port
, conn
->requested_resource
);
1497 connection_dir_download_cert_failed(conn
, status_code
);
1498 tor_free(body
); tor_free(headers
); tor_free(reason
);
1501 log_info(LD_DIR
,"Received authority certificates (size %d) from server "
1502 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1503 if (trusted_dirs_load_certs_from_string(body
, 0)<0) {
1504 log_warn(LD_DIR
, "Unable to parse fetched certificates");
1505 connection_dir_download_cert_failed(conn
, status_code
);
1507 directory_info_has_arrived(now
, 0);
1508 log_info(LD_DIR
, "Successfully loaded certificates from fetch.");
1511 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
1514 log_info(LD_DIR
,"Got votes (size %d) from server %s:%d",
1515 (int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1516 if (status_code
!= 200) {
1518 "Received http status code %d (%s) from server "
1519 "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".",
1520 status_code
, escaped(reason
), conn
->_base
.address
,
1521 conn
->_base
.port
, conn
->requested_resource
);
1522 tor_free(body
); tor_free(headers
); tor_free(reason
);
1525 dirvote_add_vote(body
, &msg
, &st
);
1527 log_warn(LD_DIR
, "Error adding retrieved vote: %s", msg
);
1529 log_info(LD_DIR
, "Added vote(s) successfully [msg: %s]", msg
);
1532 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
1533 const char *msg
= NULL
;
1534 log_info(LD_DIR
,"Got detached signatures (size %d) from server %s:%d",
1535 (int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1536 if (status_code
!= 200) {
1538 "Received http status code %d (%s) from server "
1539 "'%s:%d' while fetching \"/tor/status-vote/consensus-signatures.z\".",
1540 status_code
, escaped(reason
), conn
->_base
.address
,
1542 tor_free(body
); tor_free(headers
); tor_free(reason
);
1545 if (dirvote_add_signatures(body
, &msg
)<0) {
1546 log_warn(LD_DIR
, "Problem adding detached signatures from %s:%d: %s",
1547 conn
->_base
.address
, conn
->_base
.port
, msg
?msg
:"???");
1551 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1552 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
1553 int was_ei
= conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
;
1554 smartlist_t
*which
= NULL
;
1555 int n_asked_for
= 0;
1556 int descriptor_digests
= conn
->requested_resource
&&
1557 !strcmpstart(conn
->requested_resource
,"d/");
1558 log_info(LD_DIR
,"Received %s (size %d) from server '%s:%d'",
1559 was_ei
? "extra server info" : "server info",
1560 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1562 note_request(was_compressed
?"dl/extra.z":"dl/extra", orig_len
);
1564 note_request(was_compressed
?"dl/server.z":"dl/server", orig_len
);
1565 if (conn
->requested_resource
&&
1566 (!strcmpstart(conn
->requested_resource
,"d/") ||
1567 !strcmpstart(conn
->requested_resource
,"fp/"))) {
1568 which
= smartlist_create();
1569 dir_split_resource_into_fingerprints(conn
->requested_resource
+
1570 (descriptor_digests
? 2 : 3),
1572 n_asked_for
= smartlist_len(which
);
1574 if (status_code
!= 200) {
1575 int dir_okay
= status_code
== 404 ||
1576 (status_code
== 400 && !strcmp(reason
, "Servers unavailable."));
1577 /* 404 means that it didn't have them; no big deal.
1578 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1579 log_fn(dir_okay
? LOG_INFO
: LOG_WARN
, LD_DIR
,
1580 "Received http status code %d (%s) from server '%s:%d' "
1581 "while fetching \"/tor/server/%s\". I'll try again soon.",
1582 status_code
, escaped(reason
), conn
->_base
.address
,
1583 conn
->_base
.port
, conn
->requested_resource
);
1585 connection_dir_download_routerdesc_failed(conn
);
1587 dir_routerdesc_download_failed(which
, status_code
,
1588 conn
->router_purpose
,
1589 was_ei
, descriptor_digests
);
1590 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1591 smartlist_free(which
);
1593 tor_free(body
); tor_free(headers
); tor_free(reason
);
1594 return dir_okay
? 0 : -1;
1596 /* Learn the routers, assuming we requested by fingerprint or "all"
1599 * We use "authority" to fetch our own descriptor for
1600 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1601 * the output of "authority" requests unless we are using bridges,
1602 * since otherwise they'll be the response from reachability tests,
1603 * and we don't really want to add that to our routerlist. */
1604 if (which
|| (conn
->requested_resource
&&
1605 (!strcmpstart(conn
->requested_resource
, "all") ||
1606 (!strcmpstart(conn
->requested_resource
, "authority") &&
1607 get_options()->UseBridges
)))) {
1608 /* as we learn from them, we remove them from 'which' */
1610 router_load_extrainfo_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1611 descriptor_digests
);
1613 //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1614 // descriptor_digests, conn->router_purpose);
1615 load_downloaded_routers(body
, which
, descriptor_digests
,
1616 conn
->router_purpose
,
1617 conn
->_base
.address
);
1618 directory_info_has_arrived(now
, 0);
1621 if (which
) { /* mark remaining ones as failed */
1622 log_info(LD_DIR
, "Received %d/%d %s requested from %s:%d",
1623 n_asked_for
-smartlist_len(which
), n_asked_for
,
1624 was_ei
? "extra-info documents" : "router descriptors",
1625 conn
->_base
.address
, (int)conn
->_base
.port
);
1626 if (smartlist_len(which
)) {
1627 dir_routerdesc_download_failed(which
, status_code
,
1628 conn
->router_purpose
,
1629 was_ei
, descriptor_digests
);
1631 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1632 smartlist_free(which
);
1634 if (directory_conn_is_self_reachability_test(conn
))
1635 router_dirport_found_reachable();
1638 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_DIR
) {
1639 switch (status_code
) {
1641 trusted_dir_server_t
*ds
=
1642 router_get_trusteddirserver_by_digest(conn
->identity_digest
);
1643 char *rejected_hdr
= http_get_header(headers
,
1644 "X-Descriptor-Not-New: ");
1647 if (!strcmp(rejected_hdr
, "Yes")) {
1648 /* XXXX020 use this information; be sure to upload next one
1652 tor_free(rejected_hdr
);
1654 log_info(LD_GENERAL
,"eof (status 200) after uploading server "
1655 "descriptor: finished.");
1656 control_event_server_status(
1657 LOG_NOTICE
, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1658 conn
->_base
.address
, conn
->_base
.port
);
1660 ds
->has_accepted_serverdesc
= 1;
1661 if (directories_have_accepted_server_descriptor())
1662 control_event_server_status(LOG_NOTICE
, "GOOD_SERVER_DESCRIPTOR");
1666 log_warn(LD_GENERAL
,"http status 400 (%s) response from "
1667 "dirserver '%s:%d'. Please correct.",
1668 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1669 control_event_server_status(LOG_WARN
,
1670 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1671 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1674 log_warn(LD_GENERAL
,
1675 "http status %d (%s) reason unexpected while uploading "
1676 "descriptor to server '%s:%d').",
1677 status_code
, escaped(reason
), conn
->_base
.address
,
1681 /* return 0 in all cases, since we don't want to mark any
1682 * dirservers down just because they don't like us. */
1685 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_VOTE
) {
1686 switch (status_code
) {
1688 log_notice(LD_DIR
,"Uploaded a vote to dirserver %s:%d",
1689 conn
->_base
.address
, conn
->_base
.port
);
1693 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
1694 "vote to dirserver '%s:%d'. Please correct.",
1695 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1698 log_warn(LD_GENERAL
,
1699 "http status %d (%s) reason unexpected while uploading "
1700 "vote to server '%s:%d').",
1701 status_code
, escaped(reason
), conn
->_base
.address
,
1705 /* return 0 in all cases, since we don't want to mark any
1706 * dirservers down just because they don't like us. */
1709 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
) {
1710 switch (status_code
) {
1712 log_notice(LD_DIR
,"Uploaded signature(s) to dirserver %s:%d",
1713 conn
->_base
.address
, conn
->_base
.port
);
1717 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
1718 "signatures to dirserver '%s:%d'. Please correct.",
1719 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1722 log_warn(LD_GENERAL
,
1723 "http status %d (%s) reason unexpected while uploading "
1724 "signatures to server '%s:%d').",
1725 status_code
, escaped(reason
), conn
->_base
.address
,
1729 /* return 0 in all cases, since we don't want to mark any
1730 * dirservers down just because they don't like us. */
1733 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
1734 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1736 (int)body_len
, status_code
, escaped(reason
));
1737 switch (status_code
) {
1739 if (rend_cache_store(body
, body_len
, 0) < 0) {
1740 log_warn(LD_REND
,"Failed to fetch rendezvous descriptor.");
1741 /* alice's ap_stream will notice when connection_mark_for_close
1743 /*XXXX020 maybe retry quickly; timeout takes a while. */
1745 /* success. notify pending connections about this. */
1746 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1747 rend_client_desc_here(conn
->rend_query
);
1751 /* not there. pending connections will be notified when
1752 * connection_mark_for_close cleans it up. */
1753 /*XXXX020 maybe retry quickly; timeout takes a while. */
1757 "http status 400 (%s). Dirserver didn't like our "
1758 "rendezvous query?", escaped(reason
));
1761 log_warn(LD_REND
,"http status %d (%s) response unexpected while "
1762 "fetching hidden service descriptor (server '%s:%d').",
1763 status_code
, escaped(reason
), conn
->_base
.address
,
1769 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC_V2
) {
1770 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1772 (int)body_len
, status_code
, escaped(reason
));
1773 switch (status_code
) {
1775 if (rend_cache_store_v2_desc_as_client(body
, NULL
) < 0) {
1776 log_warn(LD_REND
,"Fetching v2 rendezvous descriptor failed.");
1777 /* alice's ap_stream will notice when connection_mark_for_close
1780 /* success. notify pending connections about this. */
1781 log_info(LD_REND
, "Successfully fetched rendezvous descriptor.");
1782 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1783 rend_client_desc_here(conn
->rend_query
);
1787 /* not there. pending connections will be notified when
1788 * connection_mark_for_close cleans it up. */
1791 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
1792 "http status 400 (%s). Dirserver didn't like our "
1793 "v2 rendezvous query?", escaped(reason
));
1796 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
1797 "http status %d (%s) response unexpected while "
1798 "fetching v2 hidden service descriptor (server '%s:%d').",
1799 status_code
, escaped(reason
), conn
->_base
.address
,
1805 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC
||
1806 conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC_V2
) {
1807 log_info(LD_REND
,"Uploaded rendezvous descriptor (status %d "
1809 status_code
, escaped(reason
));
1810 switch (status_code
) {
1813 "Uploading rendezvous descriptor: finished with status "
1814 "200 (%s)", escaped(reason
));
1817 log_warn(LD_REND
,"http status 400 (%s) response from dirserver "
1818 "'%s:%d'. Malformed rendezvous descriptor?",
1819 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1822 log_warn(LD_REND
,"http status %d (%s) response unexpected (server "
1824 status_code
, escaped(reason
), conn
->_base
.address
,
1829 tor_free(body
); tor_free(headers
); tor_free(reason
);
1833 /** Called when a directory connection reaches EOF */
1835 connection_dir_reached_eof(dir_connection_t
*conn
)
1838 if (conn
->_base
.state
!= DIR_CONN_STATE_CLIENT_READING
) {
1839 log_info(LD_HTTP
,"conn reached eof, not reading. [state=%d] Closing.",
1841 connection_close_immediate(TO_CONN(conn
)); /* error: give up on flushing */
1842 connection_mark_for_close(TO_CONN(conn
));
1846 retval
= connection_dir_client_reached_eof(conn
);
1847 if (retval
== 0) /* success */
1848 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_FINISHED
;
1849 connection_mark_for_close(TO_CONN(conn
));
1853 /** If any directory object is arriving, and it's over 10MB large, we're
1854 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
1855 * ask for more than 96 router descriptors at a time.)
1857 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
1859 /** Read handler for directory connections. (That's connections <em>to</em>
1860 * directory servers and connections <em>at</em> directory servers.)
1863 connection_dir_process_inbuf(dir_connection_t
*conn
)
1866 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
1868 /* Directory clients write, then read data until they receive EOF;
1869 * directory servers read data until they get an HTTP command, then
1870 * write their response (when it's finished flushing, they mark for
1874 /* If we're on the dirserver side, look for a command. */
1875 if (conn
->_base
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
1876 if (directory_handle_command(conn
) < 0) {
1877 connection_mark_for_close(TO_CONN(conn
));
1883 if (buf_datalen(conn
->_base
.inbuf
) > MAX_DIRECTORY_OBJECT_SIZE
) {
1884 log_warn(LD_HTTP
, "Too much data received from directory connection: "
1885 "denial of service attempt, or you need to upgrade?");
1886 connection_mark_for_close(TO_CONN(conn
));
1890 if (!conn
->_base
.inbuf_reached_eof
)
1891 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
1895 /** Create an http response for the client <b>conn</b> out of
1896 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
1899 write_http_status_line(dir_connection_t
*conn
, int status
,
1900 const char *reason_phrase
)
1903 if (tor_snprintf(buf
, sizeof(buf
), "HTTP/1.0 %d %s\r\n\r\n",
1904 status
, reason_phrase
? reason_phrase
: "OK") < 0) {
1905 log_warn(LD_BUG
,"status line too long.");
1908 connection_write_to_buf(buf
, strlen(buf
), TO_CONN(conn
));
1911 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
1912 * with <b>type</b> as the Content-Type.
1914 * If <b>length</b> is nonnegative, it is the Content-Length.
1915 * If <b>encoding</b> is provided, it is the Content-Encoding.
1916 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
1917 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
1919 write_http_response_header_impl(dir_connection_t
*conn
, ssize_t length
,
1920 const char *type
, const char *encoding
,
1921 const char *extra_headers
,
1924 char date
[RFC1123_TIME_LEN
+1];
1927 time_t now
= time(NULL
);
1931 format_rfc1123_time(date
, now
);
1933 tor_snprintf(cp
, sizeof(tmp
),
1934 "HTTP/1.0 200 OK\r\nDate: %s\r\n",
1938 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
), "Content-Type: %s\r\n", type
);
1941 if (!is_internal_IP(conn
->_base
.addr
, 0)) {
1942 /* Don't report the source address for a localhost/private connection. */
1943 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1944 X_ADDRESS_HEADER
"%s\r\n", conn
->_base
.address
);
1948 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1949 "Content-Encoding: %s\r\n", encoding
);
1953 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1954 "Content-Length: %ld\r\n", (long)length
);
1957 if (cache_lifetime
> 0) {
1958 char expbuf
[RFC1123_TIME_LEN
+1];
1959 format_rfc1123_time(expbuf
, now
+ cache_lifetime
);
1960 /* We could say 'Cache-control: max-age=%d' here if we start doing
1962 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1963 "Expires: %s\r\n", expbuf
);
1965 } else if (cache_lifetime
== 0) {
1966 /* We could say 'Cache-control: no-cache' here if we start doing
1968 strlcpy(cp
, "Pragma: no-cache\r\n", sizeof(tmp
)-(cp
-tmp
));
1972 strlcpy(cp
, extra_headers
, sizeof(tmp
)-(cp
-tmp
));
1973 if (sizeof(tmp
)-(cp
-tmp
) > 3)
1974 memcpy(cp
, "\r\n", 3);
1977 connection_write_to_buf(tmp
, strlen(tmp
), TO_CONN(conn
));
1980 /** As write_http_response_header_impl, but sets encoding and content-typed
1981 * based on whether the response will be <b>deflated</b> or not. */
1983 write_http_response_header(dir_connection_t
*conn
, ssize_t length
,
1984 int deflated
, int cache_lifetime
)
1986 write_http_response_header_impl(conn
, length
,
1987 deflated
?"application/octet-stream":"text/plain",
1988 deflated
?"deflate":"identity",
1993 /** Helper function: return 1 if there are any dir conns of purpose
1994 * <b>purpose</b> that are going elsewhere than our own ORPort/Dirport.
1998 already_fetching_directory(int purpose
)
2000 smartlist_t
*conns
= get_connection_array();
2001 SMARTLIST_FOREACH(conns
, connection_t
*, conn
,
2003 if (conn
->type
== CONN_TYPE_DIR
&&
2004 conn
->purpose
== purpose
&&
2005 !conn
->marked_for_close
&&
2006 !router_digest_is_me(TO_DIR_CONN(conn
)->identity_digest
))
2012 #ifdef INSTRUMENT_DOWNLOADS
2013 /** Map used to keep track of how much data we've up/downloaded in what kind
2014 * of request. Maps from request type to pointer to uint64_t. */
2015 static strmap_t
*request_bytes_map
= NULL
;
2017 /** Called when we just transmitted or received <b>bytes</b> worth of data
2018 * because of a request of type <b>key</b> (an arbitrary identifier): adds
2019 * <b>bytes</b> to the total associated with key. */
2021 note_request(const char *key
, size_t bytes
)
2024 if (!request_bytes_map
)
2025 request_bytes_map
= strmap_new();
2027 n
= strmap_get(request_bytes_map
, key
);
2029 n
= tor_malloc_zero(sizeof(uint64_t));
2030 strmap_set(request_bytes_map
, key
, n
);
2035 /** Return a newly allocated string holding a summary of bytes used per
2038 directory_dump_request_log(void)
2043 strmap_iter_t
*iter
;
2045 if (!request_bytes_map
)
2046 request_bytes_map
= strmap_new();
2048 lines
= smartlist_create();
2050 for (iter
= strmap_iter_init(request_bytes_map
);
2051 !strmap_iter_done(iter
);
2052 iter
= strmap_iter_next(request_bytes_map
, iter
)) {
2056 strmap_iter_get(iter
, &key
, &val
);
2058 tor_snprintf(tmp
, sizeof(tmp
), "%s "U64_FORMAT
"\n",
2059 key
, U64_PRINTF_ARG(*n
));
2060 smartlist_add(lines
, tor_strdup(tmp
));
2062 smartlist_sort_strings(lines
);
2063 result
= smartlist_join_strings(lines
, "", 0, NULL
);
2064 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
2065 smartlist_free(lines
);
2070 note_request(const char *key
, size_t bytes
)
2077 directory_dump_request_log(void)
2079 return tor_strdup("Not supported.");
2083 /** Helper function: called when a dirserver gets a complete HTTP GET
2084 * request. Look for a request for a directory or for a rendezvous
2085 * service descriptor. On finding one, write a response into
2086 * conn-\>outbuf. If the request is unrecognized, send a 400.
2087 * Always return 0. */
2089 directory_handle_command_get(dir_connection_t
*conn
, const char *headers
,
2090 const char *body
, size_t body_len
)
2093 char *url
, *url_mem
, *header
;
2094 or_options_t
*options
= get_options();
2095 time_t if_modified_since
= 0;
2099 /* We ignore the body of a GET request. */
2103 log_debug(LD_DIRSERV
,"Received GET command.");
2105 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2107 if (parse_http_url(headers
, &url
) < 0) {
2108 write_http_status_line(conn
, 400, "Bad request");
2111 if ((header
= http_get_header(headers
, "If-Modified-Since: "))) {
2113 if (parse_http_time(header
, &tm
) == 0) {
2114 if_modified_since
= tor_timegm(&tm
);
2116 /* The correct behavior on a malformed If-Modified-Since header is to
2117 * act as if no If-Modified-Since header had been given. */
2120 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2123 url_len
= strlen(url
);
2124 deflated
= url_len
> 2 && !strcmp(url
+url_len
-2, ".z");
2126 url
[url_len
-2] = '\0';
2130 if (!strcmp(url
,"/tor/") || !strcmp(url
,"/tor/dir")) { /* dir fetch */
2131 cached_dir_t
*d
= dirserv_get_directory();
2134 log_notice(LD_DIRSERV
,"Client asked for the mirrored directory, but we "
2135 "don't have a good one yet. Sending 503 Dir not available.");
2136 write_http_status_line(conn
, 503, "Directory unavailable");
2137 /* try to get a new one now */
2138 if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR
) &&
2139 !should_delay_dir_fetches(options
))
2140 directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR
,
2141 ROUTER_PURPOSE_GENERAL
, NULL
, 1);
2144 if (d
->published
< if_modified_since
) {
2145 write_http_status_line(conn
, 304, "Not modified");
2149 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
2151 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
2152 log_info(LD_DIRSERV
,
2153 "Client asked for the mirrored directory, but we've been "
2154 "writing too many bytes lately. Sending 503 Dir busy.");
2155 write_http_status_line(conn
, 503, "Directory busy, try again later");
2159 note_request(url
, dlen
);
2161 log_debug(LD_DIRSERV
,"Dumping %sdirectory to client.",
2162 deflated
?"deflated ":"");
2163 write_http_response_header(conn
, dlen
, deflated
,
2164 FULL_DIR_CACHE_LIFETIME
);
2165 conn
->cached_dir
= d
;
2166 conn
->cached_dir_offset
= 0;
2168 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2171 /* Prime the connection with some data. */
2172 conn
->dir_spool_src
= DIR_SPOOL_CACHED_DIR
;
2173 connection_dirserv_flushed_some(conn
);
2177 if (!strcmp(url
,"/tor/running-routers")) { /* running-routers fetch */
2178 cached_dir_t
*d
= dirserv_get_runningrouters();
2180 write_http_status_line(conn
, 503, "Directory unavailable");
2181 /* try to get a new one now */
2182 if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST
) &&
2183 !should_delay_dir_fetches(options
))
2184 directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST
,
2185 ROUTER_PURPOSE_GENERAL
, NULL
, 1);
2188 if (d
->published
< if_modified_since
) {
2189 write_http_status_line(conn
, 304, "Not modified");
2192 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
2194 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
2195 log_info(LD_DIRSERV
,
2196 "Client asked for running-routers, but we've been "
2197 "writing too many bytes lately. Sending 503 Dir busy.");
2198 write_http_status_line(conn
, 503, "Directory busy, try again later");
2201 note_request(url
, dlen
);
2202 write_http_response_header(conn
, dlen
, deflated
,
2203 RUNNINGROUTERS_CACHE_LIFETIME
);
2204 connection_write_to_buf(deflated
? d
->dir_z
: d
->dir
, dlen
, TO_CONN(conn
));
2208 if (!strcmpstart(url
,"/tor/status/")
2209 || !strcmp(url
, "/tor/status-vote/current/consensus")) {
2210 /* v2 or v3 network status fetch. */
2211 smartlist_t
*dir_fps
= smartlist_create();
2212 int is_v3
= !strcmpstart(url
, "/tor/status-vote");
2213 const char *request_type
= NULL
;
2214 const char *key
= url
+ strlen("/tor/status/");
2215 int lifetime
= NETWORKSTATUS_CACHE_LIFETIME
;
2217 dirserv_get_networkstatus_v2_fingerprints(dir_fps
, key
);
2218 if (!strcmpstart(key
, "fp/"))
2219 request_type
= deflated
?"/tor/status/fp.z":"/tor/status/fp";
2220 else if (!strcmpstart(key
, "authority"))
2221 request_type
= deflated
?"/tor/status/authority.z":
2222 "/tor/status/authority";
2223 else if (!strcmpstart(key
, "all"))
2224 request_type
= deflated
?"/tor/status/all.z":"/tor/status/all";
2226 request_type
= "/tor/status/?";
2228 networkstatus_vote_t
*v
= networkstatus_get_latest_consensus();
2229 time_t now
= time(NULL
);
2230 smartlist_add(dir_fps
, tor_memdup("\0\0\0\0\0\0\0\0\0\0"
2231 "\0\0\0\0\0\0\0\0\0\0", 20));
2232 request_type
= deflated
?"v3.z":"v3";
2233 lifetime
= (v
&& v
->fresh_until
> now
) ? v
->fresh_until
- now
: 0;
2236 if (!smartlist_len(dir_fps
)) { /* we failed to create/cache cp */
2237 write_http_status_line(conn
, 503, "Network status object unavailable");
2238 smartlist_free(dir_fps
);
2242 if (!dirserv_remove_old_statuses(dir_fps
, if_modified_since
)) {
2243 write_http_status_line(conn
, 404, "Not found");
2244 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2245 smartlist_free(dir_fps
);
2247 } else if (!smartlist_len(dir_fps
)) {
2248 write_http_status_line(conn
, 304, "Not modified");
2249 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2250 smartlist_free(dir_fps
);
2254 dlen
= dirserv_estimate_data_size(dir_fps
, 0, deflated
);
2255 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2256 log_info(LD_DIRSERV
,
2257 "Client asked for network status lists, but we've been "
2258 "writing too many bytes lately. Sending 503 Dir busy.");
2259 write_http_status_line(conn
, 503, "Directory busy, try again later");
2260 SMARTLIST_FOREACH(dir_fps
, char *, fp
, tor_free(fp
));
2261 smartlist_free(dir_fps
);
2265 // note_request(request_type,dlen);
2266 (void) request_type
;
2267 write_http_response_header(conn
, -1, deflated
,
2268 smartlist_len(dir_fps
) == 1 ? lifetime
: 0);
2269 conn
->fingerprint_stack
= dir_fps
;
2271 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2273 /* Prime the connection with some data. */
2274 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
2275 connection_dirserv_flushed_some(conn
);
2279 if (!strcmpstart(url
,"/tor/status-vote/current/") ||
2280 !strcmpstart(url
,"/tor/status-vote/next/")) {
2281 /* XXXX If-modified-since is only the implemented for the current
2282 * consensus: that's probably fine, since it's the only vote document
2283 * people fetch much.*/
2285 ssize_t body_len
= 0;
2286 ssize_t estimated_len
= 0;
2287 smartlist_t
*items
= smartlist_create();
2288 smartlist_t
*dir_items
= smartlist_create();
2289 int lifetime
= 60; /* XXXX020 should actually use vote intervals. */
2290 url
+= strlen("/tor/status-vote/");
2291 current
= !strcmpstart(url
, "current/");
2292 url
= strchr(url
, '/');
2295 if (!strcmp(url
, "consensus")) {
2297 tor_assert(!current
); /* we handle current consensus specially above,
2298 * since it wants to be spooled. */
2299 if ((item
= dirvote_get_pending_consensus()))
2300 smartlist_add(items
, (char*)item
);
2301 } else if (!current
&& !strcmp(url
, "consensus-signatures")) {
2302 /* XXXX020 the spec says that we should implement
2303 * currrent/consensus-signatures too. Why? */
2305 if ((item
=dirvote_get_pending_detached_signatures()))
2306 smartlist_add(items
, (char*)item
);
2307 } else if (!strcmp(url
, "authority")) {
2308 const cached_dir_t
*d
;
2309 int flags
= DGV_BY_ID
|
2310 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2311 if ((d
=dirvote_get_vote(NULL
, flags
)))
2312 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2314 const cached_dir_t
*d
;
2315 smartlist_t
*fps
= smartlist_create();
2317 if (!strcmpstart(url
, "d/")) {
2319 flags
= DGV_INCLUDE_PENDING
| DGV_INCLUDE_PREVIOUS
;
2322 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2324 dir_split_resource_into_fingerprints(url
, fps
, NULL
, 1, 1);
2325 SMARTLIST_FOREACH(fps
, char *, fp
, {
2326 if ((d
= dirvote_get_vote(fp
, flags
)))
2327 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2330 smartlist_free(fps
);
2332 if (!smartlist_len(dir_items
) && !smartlist_len(items
)) {
2333 write_http_status_line(conn
, 404, "Not found");
2336 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2337 body_len
+= deflated
? d
->dir_z_len
: d
->dir_len
);
2338 estimated_len
+= body_len
;
2339 SMARTLIST_FOREACH(items
, const char *, item
, {
2340 size_t ln
= strlen(item
);
2342 body_len
+= ln
; estimated_len
+= ln
;
2344 estimated_len
+= ln
/2;
2348 if (global_write_bucket_low(TO_CONN(conn
), estimated_len
, 1)) {
2349 write_http_status_line(conn
, 503, "Directory busy, try again later.");
2352 write_http_response_header(conn
, body_len
? body_len
: -1, deflated
,
2355 if (smartlist_len(items
)) {
2357 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2358 SMARTLIST_FOREACH(items
, const char *, c
,
2359 connection_write_to_buf_zlib(c
, strlen(c
), conn
, 0));
2360 connection_write_to_buf_zlib("", 0, conn
, 1);
2362 SMARTLIST_FOREACH(items
, const char *, c
,
2363 connection_write_to_buf(c
, strlen(c
), TO_CONN(conn
)));
2366 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2367 connection_write_to_buf(deflated
? d
->dir_z
: d
->dir
,
2368 deflated
? d
->dir_z_len
: d
->dir_len
,
2372 smartlist_free(items
);
2373 smartlist_free(dir_items
);
2377 if (!strcmpstart(url
,"/tor/server/") ||
2378 !strcmpstart(url
,"/tor/extra/")) {
2381 const char *request_type
= NULL
;
2382 int cache_lifetime
= 0;
2383 int is_extra
= !strcmpstart(url
,"/tor/extra/");
2384 url
+= is_extra
? strlen("/tor/extra/") : strlen("/tor/server/");
2385 conn
->fingerprint_stack
= smartlist_create();
2386 res
= dirserv_get_routerdesc_fingerprints(conn
->fingerprint_stack
, url
,
2389 if (!strcmpstart(url
, "fp/")) {
2390 request_type
= deflated
?"/tor/server/fp.z":"/tor/server/fp";
2391 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2392 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2393 } else if (!strcmpstart(url
, "authority")) {
2394 request_type
= deflated
?"/tor/server/authority.z":
2395 "/tor/server/authority";
2396 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2397 } else if (!strcmpstart(url
, "all")) {
2398 request_type
= deflated
?"/tor/server/all.z":"/tor/server/all";
2399 cache_lifetime
= FULL_DIR_CACHE_LIFETIME
;
2400 } else if (!strcmpstart(url
, "d/")) {
2401 request_type
= deflated
?"/tor/server/d.z":"/tor/server/d";
2402 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2403 cache_lifetime
= ROUTERDESC_BY_DIGEST_CACHE_LIFETIME
;
2405 request_type
= "/tor/server/?";
2407 (void) request_type
; /* usable for note_request. */
2408 if (!strcmpstart(url
, "d/"))
2409 conn
->dir_spool_src
=
2410 is_extra
? DIR_SPOOL_EXTRA_BY_DIGEST
: DIR_SPOOL_SERVER_BY_DIGEST
;
2412 conn
->dir_spool_src
=
2413 is_extra
? DIR_SPOOL_EXTRA_BY_FP
: DIR_SPOOL_SERVER_BY_FP
;
2415 if (!dirserv_have_any_serverdesc(conn
->fingerprint_stack
,
2416 conn
->dir_spool_src
)) {
2422 write_http_status_line(conn
, 404, msg
);
2424 dlen
= dirserv_estimate_data_size(conn
->fingerprint_stack
,
2426 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2427 log_info(LD_DIRSERV
,
2428 "Client asked for server descriptors, but we've been "
2429 "writing too many bytes lately. Sending 503 Dir busy.");
2430 write_http_status_line(conn
, 503, "Directory busy, try again later");
2433 write_http_response_header(conn
, -1, deflated
, cache_lifetime
);
2435 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2436 /* Prime the connection with some data. */
2437 connection_dirserv_flushed_some(conn
);
2442 if (!strcmpstart(url
,"/tor/keys/")) {
2443 smartlist_t
*certs
= smartlist_create();
2445 if (!strcmp(url
, "/tor/keys/all")) {
2446 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
2447 trusted_dir_server_t
*, ds
,
2451 SMARTLIST_FOREACH(ds
->v3_certs
, authority_cert_t
*, cert
,
2452 smartlist_add(certs
, cert
));
2454 } else if (!strcmp(url
, "/tor/keys/authority")) {
2455 authority_cert_t
*cert
= get_my_v3_authority_cert();
2457 smartlist_add(certs
, cert
);
2458 } else if (!strcmpstart(url
, "/tor/keys/fp/")) {
2459 smartlist_t
*fps
= smartlist_create();
2460 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/fp/"),
2462 SMARTLIST_FOREACH(fps
, char *, d
, {
2463 authority_cert_t
*c
= authority_cert_get_newest_by_id(d
);
2464 if (c
) smartlist_add(certs
, c
);
2467 smartlist_free(fps
);
2468 } else if (!strcmpstart(url
, "/tor/keys/sk/")) {
2469 smartlist_t
*fps
= smartlist_create();
2470 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/sk/"),
2472 SMARTLIST_FOREACH(fps
, char *, d
, {
2473 authority_cert_t
*c
= authority_cert_get_by_sk_digest(d
);
2474 if (c
) smartlist_add(certs
, c
);
2477 smartlist_free(fps
);
2479 write_http_status_line(conn
, 400, "Bad request");
2482 if (!smartlist_len(certs
)) {
2483 write_http_status_line(conn
, 404, "Not found");
2486 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2487 if (c
->cache_info
.published_on
< if_modified_since
)
2488 SMARTLIST_DEL_CURRENT(certs
, c
));
2489 if (!smartlist_len(certs
)) {
2490 write_http_status_line(conn
, 304, "Not modified");
2494 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2495 len
+= c
->cache_info
.signed_descriptor_len
);
2497 if (global_write_bucket_low(TO_CONN(conn
), deflated
?len
/2:len
, 1)) {
2498 write_http_status_line(conn
, 503, "Directory busy, try again later.");
2502 write_http_response_header(conn
, deflated
?-1:len
, deflated
, 60*60);
2504 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2505 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2506 connection_write_to_buf_zlib(c
->cache_info
.signed_descriptor_body
,
2507 c
->cache_info
.signed_descriptor_len
,
2509 connection_write_to_buf_zlib("", 0, conn
, 1);
2511 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2512 connection_write_to_buf(c
->cache_info
.signed_descriptor_body
,
2513 c
->cache_info
.signed_descriptor_len
,
2517 smartlist_free(certs
);
2521 if (options
->HidServDirectoryV2
&&
2522 !strcmpstart(url
,"/tor/rendezvous2/")) {
2523 /* Handle v2 rendezvous descriptor fetch request. */
2525 const char *query
= url
+ strlen("/tor/rendezvous2/");
2526 if (strlen(query
) == REND_DESC_ID_V2_LEN_BASE32
) {
2527 log_info(LD_REND
, "Got a v2 rendezvous descriptor request for ID '%s'",
2529 switch (rend_cache_lookup_v2_desc_as_dir(query
, &descp
)) {
2531 write_http_response_header(conn
, strlen(descp
), 0, 0);
2532 connection_write_to_buf(descp
, strlen(descp
), TO_CONN(conn
));
2534 case 0: /* well-formed but not present */
2535 write_http_status_line(conn
, 404, "Not found");
2537 case -1: /* not well-formed */
2538 write_http_status_line(conn
, 400, "Bad request");
2541 } else { /* not well-formed */
2542 write_http_status_line(conn
, 400, "Bad request");
2547 if (options
->HSAuthoritativeDir
&& !strcmpstart(url
,"/tor/rendezvous/")) {
2548 /* rendezvous descriptor fetch */
2551 const char *query
= url
+strlen("/tor/rendezvous/");
2553 log_info(LD_REND
, "Handling rendezvous descriptor get");
2554 switch (rend_cache_lookup_desc(query
, 0, &descp
, &desc_len
)) {
2556 write_http_response_header_impl(conn
, desc_len
,
2557 "application/octet-stream",
2559 note_request("/tor/rendezvous?/", desc_len
);
2560 /* need to send descp separately, because it may include nuls */
2561 connection_write_to_buf(descp
, desc_len
, TO_CONN(conn
));
2562 /* report successful fetch to statistic */
2563 if (options
->HSAuthorityRecordStats
) {
2564 hs_usage_note_fetch_total(query
, time(NULL
));
2565 hs_usage_note_fetch_successful(query
, time(NULL
));
2568 case 0: /* well-formed but not present */
2569 write_http_status_line(conn
, 404, "Not found");
2570 /* report (unsuccessful) fetch to statistic */
2571 if (options
->HSAuthorityRecordStats
) {
2572 hs_usage_note_fetch_total(query
, time(NULL
));
2575 case -1: /* not well-formed */
2576 write_http_status_line(conn
, 400, "Bad request");
2582 if (!strcmpstart(url
,"/tor/bytes.txt")) {
2583 char *bytes
= directory_dump_request_log();
2584 size_t len
= strlen(bytes
);
2585 write_http_response_header(conn
, len
, 0, 0);
2586 connection_write_to_buf(bytes
, len
, TO_CONN(conn
));
2591 if (!strcmp(url
,"/tor/robots.txt")) { /* /robots.txt will have been
2592 rewritten to /tor/robots.txt */
2593 char robots
[] = "User-agent: *\r\nDisallow: /\r\n";
2594 size_t len
= strlen(robots
);
2595 write_http_response_header(conn
, len
, 0, ROBOTS_CACHE_LIFETIME
);
2596 connection_write_to_buf(robots
, len
, TO_CONN(conn
));
2600 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
2601 #define ADD_MALLINFO_LINE(x) do { \
2602 tor_snprintf(tmp, sizeof(tmp), "%s %d\n", #x, mi.x); \
2603 smartlist_add(lines, tor_strdup(tmp)); \
2606 if (!strcmp(url
,"/tor/mallinfo.txt") &&
2607 (conn
->_base
.addr
== 0x7f000001ul
)) {
2614 memset(&mi
, 0, sizeof(mi
));
2616 lines
= smartlist_create();
2618 ADD_MALLINFO_LINE(arena
)
2619 ADD_MALLINFO_LINE(ordblks
)
2620 ADD_MALLINFO_LINE(smblks
)
2621 ADD_MALLINFO_LINE(hblks
)
2622 ADD_MALLINFO_LINE(hblkhd
)
2623 ADD_MALLINFO_LINE(usmblks
)
2624 ADD_MALLINFO_LINE(fsmblks
)
2625 ADD_MALLINFO_LINE(uordblks
)
2626 ADD_MALLINFO_LINE(fordblks
)
2627 ADD_MALLINFO_LINE(keepcost
)
2629 result
= smartlist_join_strings(lines
, "", 0, NULL
);
2630 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
2631 smartlist_free(lines
);
2633 len
= strlen(result
);
2634 write_http_response_header(conn
, len
, 0, 0);
2635 connection_write_to_buf(result
, len
, TO_CONN(conn
));
2641 /* we didn't recognize the url */
2642 write_http_status_line(conn
, 404, "Not found");
2649 /** Helper function: called when a dirserver gets a complete HTTP POST
2650 * request. Look for an uploaded server descriptor or rendezvous
2651 * service descriptor. On finding one, process it and write a
2652 * response into conn-\>outbuf. If the request is unrecognized, send a
2653 * 400. Always return 0. */
2655 directory_handle_command_post(dir_connection_t
*conn
, const char *headers
,
2656 const char *body
, size_t body_len
)
2659 or_options_t
*options
= get_options();
2661 log_debug(LD_DIRSERV
,"Received POST command.");
2663 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2665 if (parse_http_url(headers
, &url
) < 0) {
2666 write_http_status_line(conn
, 400, "Bad request");
2669 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2671 /* Handle v2 rendezvous service publish request. */
2672 if (options
->HidServDirectoryV2
&&
2673 !strcmpstart(url
,"/tor/rendezvous2/publish")) {
2674 if (rend_cache_store_v2_desc_as_dir(body
) < 0) {
2675 log_warn(LD_REND
, "Rejected rend descriptor (length %d) from %s.",
2676 (int)body_len
, conn
->_base
.address
);
2677 write_http_status_line(conn
, 400, "Invalid service descriptor rejected");
2678 log_info(LD_REND
, "Handled v2 rendezvous descriptor post: rejected");
2680 write_http_status_line(conn
, 200, "Service descriptor stored");
2681 log_info(LD_REND
, "Handled v2 rendezvous descriptor post: accepted");
2686 if (!authdir_mode(options
)) {
2687 /* we just provide cached directories; we don't want to
2688 * receive anything. */
2689 write_http_status_line(conn
, 400, "Nonauthoritative directory does not "
2690 "accept posted server descriptors");
2694 if (authdir_mode_handles_descs(options
) &&
2695 !strcmp(url
,"/tor/")) { /* server descriptor post */
2696 const char *msg
= NULL
;
2697 uint8_t purpose
= authdir_mode_bridge(options
) ?
2698 ROUTER_PURPOSE_BRIDGE
: ROUTER_PURPOSE_GENERAL
;
2699 int r
= dirserv_add_multiple_descriptors(body
, purpose
,
2700 conn
->_base
.address
, &msg
);
2703 dirserv_get_directory(); /* rebuild and write to disk */
2708 log_notice(LD_DIRSERV
,
2709 "Rejected router descriptor or extra-info from %s.",
2710 conn
->_base
.address
);
2711 /* malformed descriptor, or something wrong */
2712 write_http_status_line(conn
, 400, msg
);
2714 case 0: /* accepted but discarded */
2715 write_http_response_header_impl(conn
, -1, NULL
, NULL
,
2716 "X-Descriptor-Not-New: Yes\r\n", -1);
2718 case 2: /* accepted */
2719 write_http_status_line(conn
, 200, msg
);
2725 if (options
->HSAuthoritativeDir
&&
2726 !strcmpstart(url
,"/tor/rendezvous/publish")) {
2727 /* rendezvous descriptor post */
2728 log_info(LD_REND
, "Handling rendezvous descriptor post.");
2729 if (rend_cache_store(body
, body_len
, 1) < 0) {
2730 log_fn(LOG_PROTOCOL_WARN
, LD_DIRSERV
,
2731 "Rejected rend descriptor (length %d) from %s.",
2732 (int)body_len
, conn
->_base
.address
);
2733 write_http_status_line(conn
, 400, "Invalid service descriptor rejected");
2735 write_http_status_line(conn
, 200, "Service descriptor stored");
2740 if (authdir_mode_v3(options
) &&
2741 !strcmp(url
,"/tor/post/vote")) { /* server descriptor post */
2742 const char *msg
= "OK";
2744 if (dirvote_add_vote(body
, &msg
, &status
)) {
2745 write_http_status_line(conn
, status
, "Vote stored");
2748 write_http_status_line(conn
, status
, msg
);
2753 if (authdir_mode_v3(options
) &&
2754 !strcmp(url
,"/tor/post/consensus-signature")) { /* sigs on consensus. */
2755 const char *msg
= NULL
;
2756 if (dirvote_add_signatures(body
, &msg
)>=0) {
2757 write_http_status_line(conn
, 200, msg
?msg
:"Signatures stored");
2759 log_warn(LD_DIR
, "Unable to store signatures posted by %s: %s",
2760 conn
->_base
.address
, msg
?msg
:"???");
2761 write_http_status_line(conn
, 400, msg
?msg
:"Unable to store signatures");
2766 /* we didn't recognize the url */
2767 write_http_status_line(conn
, 404, "Not found");
2774 /** Called when a dirserver receives data on a directory connection;
2775 * looks for an HTTP request. If the request is complete, remove it
2776 * from the inbuf, try to process it; otherwise, leave it on the
2777 * buffer. Return a 0 on success, or -1 on error.
2780 directory_handle_command(dir_connection_t
*conn
)
2782 char *headers
=NULL
, *body
=NULL
;
2787 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2789 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
2790 &headers
, MAX_HEADERS_SIZE
,
2791 &body
, &body_len
, MAX_DIR_UL_SIZE
, 0)) {
2792 case -1: /* overflow */
2793 log_warn(LD_DIRSERV
,
2794 "Invalid input from address '%s'. Closing.",
2795 conn
->_base
.address
);
2798 log_debug(LD_DIRSERV
,"command not all here yet.");
2800 /* case 1, fall through */
2803 http_set_address_origin(headers
, TO_CONN(conn
));
2804 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
2806 if (!strncasecmp(headers
,"GET",3))
2807 r
= directory_handle_command_get(conn
, headers
, body
, body_len
);
2808 else if (!strncasecmp(headers
,"POST",4))
2809 r
= directory_handle_command_post(conn
, headers
, body
, body_len
);
2811 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
2812 "Got headers %s with unknown command. Closing.",
2817 tor_free(headers
); tor_free(body
);
2821 /** Write handler for directory connections; called when all data has
2822 * been flushed. Close the connection or wait for a response as
2826 connection_dir_finished_flushing(dir_connection_t
*conn
)
2829 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2831 switch (conn
->_base
.state
) {
2832 case DIR_CONN_STATE_CLIENT_SENDING
:
2833 log_debug(LD_DIR
,"client finished sending command.");
2834 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_READING
;
2835 connection_stop_writing(TO_CONN(conn
));
2837 case DIR_CONN_STATE_SERVER_WRITING
:
2838 log_debug(LD_DIRSERV
,"Finished writing server response. Closing.");
2839 connection_mark_for_close(TO_CONN(conn
));
2842 log_warn(LD_BUG
,"called in unexpected state %d.",
2844 tor_fragile_assert();
2850 /** Connected handler for directory connections: begin sending data to the
2853 connection_dir_finished_connecting(dir_connection_t
*conn
)
2856 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2857 tor_assert(conn
->_base
.state
== DIR_CONN_STATE_CONNECTING
);
2859 log_debug(LD_HTTP
,"Dir connection to router %s:%u established.",
2860 conn
->_base
.address
,conn
->_base
.port
);
2862 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
; /* start flushing conn */
2866 /** Called when one or more networkstatus fetches have failed (with uppercase
2867 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
2868 * failed once, unless they failed with status code 503. */
2870 dir_networkstatus_download_failed(smartlist_t
*failed
, int status_code
)
2872 if (status_code
== 503)
2874 SMARTLIST_FOREACH(failed
, const char *, fp
,
2876 char digest
[DIGEST_LEN
];
2877 trusted_dir_server_t
*dir
;
2878 base16_decode(digest
, DIGEST_LEN
, fp
, strlen(fp
));
2879 dir
= router_get_trusteddirserver_by_digest(digest
);
2882 download_status_failed(&dir
->v2_ns_dl_status
, status_code
);
2886 static const int server_dl_schedule
[] = {
2887 0, 0, 0, 60, 60, 60*2, 60*5, 60*15, INT_MAX
2889 static const int client_dl_schedule
[] = {
2890 0, 0, 60, 60*5, 60*10, INT_MAX
2892 static const int server_consensus_dl_schedule
[] = {
2893 0, 0, 60, 60*5, 60*10, 60*30, 60*30, 60*30, 60*30, 60*30, 60*60, 60*60*2
2895 static const int client_consensus_dl_schedule
[] = {
2896 0, 0, 60, 60*5, 60*10, 60*30, 60*60, 60*60, 60*60, 60*60*3, 60*60*6, 60*60*12
2899 /** Called when an attempt to download <b>dls</b> has failed with HTTP status
2900 * <b>status_code</b>. Increment the failure count (if the code indicates a
2901 * real failure) and set <b>dls<b>->next_attempt_at to an appropriate time in
2904 download_status_increment_failure(download_status_t
*dls
, int status_code
,
2905 const char *item
, int server
, time_t now
)
2907 const int *schedule
;
2911 if (status_code
!= 503 || server
)
2912 ++dls
->n_download_failures
;
2914 switch (dls
->schedule
) {
2915 case DL_SCHED_GENERIC
:
2917 schedule
= server_dl_schedule
;
2918 schedule_len
= sizeof(server_dl_schedule
)/sizeof(int);
2920 schedule
= client_dl_schedule
;
2921 schedule_len
= sizeof(client_dl_schedule
)/sizeof(int);
2924 case DL_SCHED_CONSENSUS
:
2926 schedule
= server_consensus_dl_schedule
;
2927 schedule_len
= sizeof(server_consensus_dl_schedule
)/sizeof(int);
2929 schedule
= client_consensus_dl_schedule
;
2930 schedule_len
= sizeof(client_consensus_dl_schedule
)/sizeof(int);
2937 if (dls
->n_download_failures
< schedule_len
)
2938 increment
= schedule
[dls
->n_download_failures
];
2940 increment
= schedule
[schedule_len
-1];
2942 if (increment
< INT_MAX
)
2943 dls
->next_attempt_at
= now
+increment
;
2945 dls
->next_attempt_at
= TIME_MAX
;
2948 if (dls
->next_attempt_at
== 0)
2949 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again immediately.",
2950 item
, (int)dls
->n_download_failures
);
2951 else if (dls
->next_attempt_at
< TIME_MAX
)
2952 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again in %d seconds.",
2953 item
, (int)dls
->n_download_failures
,
2954 (int)(dls
->next_attempt_at
-now
));
2956 log_debug(LD_DIR
, "%s failed %d time(s); Giving up for a while.",
2957 item
, (int)dls
->n_download_failures
);
2959 return dls
->next_attempt_at
;
2962 /** Reset <b>dls</b> so that it will be considered downloadable
2965 download_status_reset(download_status_t
*dls
)
2967 dls
->n_download_failures
= 0;
2968 dls
->next_attempt_at
= 0;
2971 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
2972 * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
2973 * either as descriptor digests or as identity digests based on
2974 * <b>was_descriptor_digests</b>).
2977 dir_routerdesc_download_failed(smartlist_t
*failed
, int status_code
,
2979 int was_extrainfo
, int was_descriptor_digests
)
2981 char digest
[DIGEST_LEN
];
2982 time_t now
= time(NULL
);
2983 or_options_t
*options
= get_options();
2984 int server
= server_mode(options
) && dirserver_mode(options
);
2985 if (!was_descriptor_digests
) {
2986 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
) {
2987 tor_assert(!was_extrainfo
); /* not supported yet */
2988 SMARTLIST_FOREACH(failed
, const char *, cp
,
2990 base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
));
2991 retry_bridge_descriptor_fetch_directly(digest
);
2994 return; /* FFFF should implement for other-than-router-purpose someday */
2996 SMARTLIST_FOREACH(failed
, const char *, cp
,
2998 download_status_t
*dls
= NULL
;
2999 base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
));
3000 if (was_extrainfo
) {
3001 signed_descriptor_t
*sd
=
3002 router_get_by_extrainfo_digest(digest
);
3004 dls
= &sd
->ei_dl_status
;
3006 dls
= router_get_dl_status_by_descriptor_digest(digest
);
3008 if (!dls
|| dls
->n_download_failures
>= MAX_ROUTERDESC_DOWNLOAD_FAILURES
)
3010 download_status_increment_failure(dls
, status_code
, cp
, server
, now
);
3013 /* No need to relaunch descriptor downloads here: we already do it
3014 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
3017 /** Given a directory <b>resource</b> request, containing zero
3018 * or more strings separated by plus signs, followed optionally by ".z", store
3019 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
3020 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
3021 * decode_hex is true, then delete all elements that aren't hex digests, and
3022 * decode the rest. If sort_uniq is true, then sort the list and remove
3026 dir_split_resource_into_fingerprints(const char *resource
,
3027 smartlist_t
*fp_out
, int *compressed_out
,
3028 int decode_hex
, int sort_uniq
)
3030 smartlist_t
*fp_tmp
= smartlist_create();
3032 smartlist_split_string(fp_tmp
, resource
, "+", 0, 0);
3034 *compressed_out
= 0;
3035 if (smartlist_len(fp_tmp
)) {
3036 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
3037 size_t last_len
= strlen(last
);
3038 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
3039 last
[last_len
-2] = '\0';
3041 *compressed_out
= 1;
3046 char *cp
, *d
= NULL
;
3047 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
3048 cp
= smartlist_get(fp_tmp
, i
);
3049 if (strlen(cp
) != HEX_DIGEST_LEN
) {
3051 "Skipping digest %s with non-standard length.", escaped(cp
));
3052 smartlist_del_keeporder(fp_tmp
, i
--);
3055 d
= tor_malloc_zero(DIGEST_LEN
);
3056 if (base16_decode(d
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
)<0) {
3057 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
3058 smartlist_del_keeporder(fp_tmp
, i
--);
3061 smartlist_set(fp_tmp
, i
, d
);
3069 smartlist_t
*fp_tmp2
= smartlist_create();
3072 smartlist_sort_digests(fp_tmp
);
3074 smartlist_sort_strings(fp_tmp
);
3075 if (smartlist_len(fp_tmp
))
3076 smartlist_add(fp_tmp2
, smartlist_get(fp_tmp
, 0));
3077 for (i
= 1; i
< smartlist_len(fp_tmp
); ++i
) {
3078 char *cp
= smartlist_get(fp_tmp
, i
);
3079 char *last
= smartlist_get(fp_tmp2
, smartlist_len(fp_tmp2
)-1);
3081 if ((decode_hex
&& memcmp(cp
, last
, DIGEST_LEN
))
3082 || (!decode_hex
&& strcasecmp(cp
, last
)))
3083 smartlist_add(fp_tmp2
, cp
);
3087 smartlist_free(fp_tmp
);
3090 smartlist_add_all(fp_out
, fp_tmp
);
3091 smartlist_free(fp_tmp
);
3095 /** Determine the responsible hidden service directories for
3096 * <b>desc_ids</b> and upload the appropriate descriptor from
3097 * <b>desc_strs</b> to them; each smartlist must contain
3098 * REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS entries; <b>service_id</b> and
3099 * <b>seconds_valid</b> are only passed for logging purposes.*/
3100 /* XXXX020 desc_ids and desc_strs could be merged. Should they? */
3101 /* I guess they should. -KL */
3103 directory_post_to_hs_dir(smartlist_t
*desc_ids
, smartlist_t
*desc_strs
,
3104 const char *service_id
, int seconds_valid
)
3107 smartlist_t
*responsible_dirs
;
3108 routerstatus_t
*hs_dir
;
3109 if (smartlist_len(desc_ids
) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS
||
3110 smartlist_len(desc_strs
) != REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS
) {
3111 log_warn(LD_BUG
, "Could not post descriptors to hidden service "
3112 "directories: Illegal number of descriptor "
3116 responsible_dirs
= smartlist_create();
3117 for (i
= 0; i
< REND_NUMBER_OF_NON_CONSECUTIVE_REPLICAS
; i
++) {
3118 const char *desc_id
= smartlist_get(desc_ids
, i
);
3119 const char *desc_str
= smartlist_get(desc_strs
, i
);
3120 /* Determine responsible dirs. */
3121 if (hid_serv_get_responsible_directories(responsible_dirs
, desc_id
) < 0) {
3122 log_warn(LD_REND
, "Could not determine the responsible hidden service "
3123 "directories to post descriptors to.");
3124 smartlist_free(responsible_dirs
);
3127 tor_assert(smartlist_len(responsible_dirs
) ==
3128 REND_NUMBER_OF_CONSECUTIVE_REPLICAS
);
3129 for (j
= 0; j
< REND_NUMBER_OF_CONSECUTIVE_REPLICAS
; j
++) {
3130 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
3131 hs_dir
= smartlist_get(responsible_dirs
, j
);
3132 /* Send publish request. */
3133 directory_initiate_command_routerstatus(hs_dir
,
3134 DIR_PURPOSE_UPLOAD_RENDDESC_V2
,
3135 ROUTER_PURPOSE_GENERAL
,
3137 strlen(desc_str
), 0);
3138 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
3139 desc_id
, DIGEST_LEN
);
3140 log_info(LD_REND
, "Sending publish request for v2 descriptor for "
3141 "service '%s' with descriptor ID '%s' with validity "
3142 "of %d seconds to hidden service directory '%s' on "
3150 smartlist_clear(responsible_dirs
);
3152 smartlist_free(responsible_dirs
);
3155 /** Determine the responsible hidden service directories for <b>desc_id</b>
3156 * and fetch the descriptor belonging to this ID from one of them;
3157 * <b>query</b> is only passed for pretty log statements. */
3159 directory_get_from_hs_dir(const char *desc_id
, const char *query
)
3161 smartlist_t
*responsible_dirs
= smartlist_create();
3162 routerstatus_t
*hs_dir
;
3163 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
3164 tor_assert(desc_id
);
3166 tor_assert(strlen(query
) == REND_SERVICE_ID_LEN
);
3167 /* Determine responsible dirs. */
3168 if (hid_serv_get_responsible_directories(responsible_dirs
, desc_id
) < 0) {
3169 /* XXX020 make this louder once we have some v2hidservs */
3170 log_info(LD_REND
, "Could not determine the responsible hidden service "
3171 "directories to fetch descriptors.");
3172 smartlist_free(responsible_dirs
);
3175 hs_dir
= smartlist_choose(responsible_dirs
);
3176 smartlist_free(responsible_dirs
);
3178 log_warn(LD_BUG
, "Could not pick one of the responsible hidden service "
3179 "directories to fetch descriptors.");
3182 /* XXXX020 if hsdir fails, use another one... */
3183 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
3184 desc_id
, DIGEST_LEN
);
3185 /* Send fetch request. */
3186 directory_initiate_command_routerstatus(hs_dir
,
3187 DIR_PURPOSE_FETCH_RENDDESC_V2
,
3188 ROUTER_PURPOSE_GENERAL
,
3189 1, desc_id_base32
, NULL
, 0, 0);
3190 log_info(LD_REND
, "Sending fetch request for v2 descriptor for "
3191 "service '%s' with descriptor ID '%s' to hidden "
3192 "service directory '%s' on port %d.",
3193 query
, desc_id_base32
, hs_dir
->nickname
, hs_dir
->dir_port
);