1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 const char directory_c_id
[] =
10 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
16 * \brief Code to send and fetch directories and router
17 * descriptors via HTTP. Directories use dirserv.c to generate the
18 * results; clients use routers.c to parse them.
21 /* In-points to directory.c:
23 * - directory_post_to_dirservers(), called from
24 * router_upload_dir_desc_to_dirservers() in router.c
25 * upload_service_descriptor() in rendservice.c
26 * - directory_get_from_dirserver(), called from
27 * rend_client_refetch_renddesc() in rendclient.c
28 * run_scheduled_events() in main.c
30 * - connection_dir_process_inbuf(), called from
31 * connection_process_inbuf() in connection.c
32 * - connection_dir_finished_flushing(), called from
33 * connection_finished_flushing() in connection.c
34 * - connection_dir_finished_connecting(), called from
35 * connection_finished_connecting() in connection.c
37 static void directory_send_command(dir_connection_t
*conn
,
38 int purpose
, int direct
, const char *resource
,
39 const char *payload
, size_t payload_len
,
40 time_t if_modified_since
);
41 static int directory_handle_command(dir_connection_t
*conn
);
42 static int body_is_plausible(const char *body
, size_t body_len
, int purpose
);
43 static int purpose_needs_anonymity(uint8_t dir_purpose
,
44 uint8_t router_purpose
);
45 static char *http_get_header(const char *headers
, const char *which
);
46 static void http_set_address_origin(const char *headers
, connection_t
*conn
);
47 static void connection_dir_download_networkstatus_failed(
48 dir_connection_t
*conn
, int status_code
);
49 static void connection_dir_download_routerdesc_failed(dir_connection_t
*conn
);
50 static void connection_dir_download_cert_failed(
51 dir_connection_t
*conn
, int status_code
);
52 static void dir_networkstatus_download_failed(smartlist_t
*failed
,
54 static void dir_routerdesc_download_failed(smartlist_t
*failed
,
58 int was_descriptor_digests
);
59 static void note_request(const char *key
, size_t bytes
);
61 /********* START VARIABLES **********/
63 /** How far in the future do we allow a directory server to tell us it is
64 * before deciding that one of us has the wrong time? */
65 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
67 #define X_ADDRESS_HEADER "X-Your-Address-Is: "
69 /** HTTP cache control: how long do we tell proxies they can cache each
70 * kind of document we serve? */
71 #define FULL_DIR_CACHE_LIFETIME (60*60)
72 #define RUNNINGROUTERS_CACHE_LIFETIME (20*60)
73 #define NETWORKSTATUS_CACHE_LIFETIME (5*60)
74 #define ROUTERDESC_CACHE_LIFETIME (30*60)
75 #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
76 #define ROBOTS_CACHE_LIFETIME (24*60*60)
78 /********* END VARIABLES ************/
80 /** Return true iff the directory purpose 'purpose' must use an
81 * anonymous connection to a directory. */
83 purpose_needs_anonymity(uint8_t dir_purpose
, uint8_t router_purpose
)
85 if (get_options()->AllDirActionsPrivate
)
87 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
&& has_completed_circuit
)
88 return 1; /* if no circuits yet, we may need this info to bootstrap. */
89 if (dir_purpose
== DIR_PURPOSE_FETCH_DIR
||
90 dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
||
91 dir_purpose
== DIR_PURPOSE_UPLOAD_VOTE
||
92 dir_purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
||
93 dir_purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
||
94 dir_purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
||
95 dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
96 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
||
97 dir_purpose
== DIR_PURPOSE_FETCH_CONSENSUS
||
98 dir_purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
||
99 dir_purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
100 dir_purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
)
105 /** Return a newly allocated string describing <b>auth</b>. */
107 authority_type_to_string(authority_type_t auth
)
110 smartlist_t
*lst
= smartlist_create();
111 if (auth
& V1_AUTHORITY
)
112 smartlist_add(lst
, (void*)"V1");
113 if (auth
& V2_AUTHORITY
)
114 smartlist_add(lst
, (void*)"V2");
115 if (auth
& BRIDGE_AUTHORITY
)
116 smartlist_add(lst
, (void*)"Bridge");
117 if (auth
& HIDSERV_AUTHORITY
)
118 smartlist_add(lst
, (void*)"Hidden service");
119 if (smartlist_len(lst
)) {
120 result
= smartlist_join_strings(lst
, ", ", 0, NULL
);
122 result
= tor_strdup("[Not an authority]");
128 /** Return a string describing a given directory connection purpose. */
130 dir_conn_purpose_to_string(int purpose
)
134 case DIR_PURPOSE_FETCH_DIR
:
135 return "v1 directory fetch";
136 case DIR_PURPOSE_FETCH_RENDDESC
:
137 return "hidden-service descriptor fetch";
138 case DIR_PURPOSE_UPLOAD_DIR
:
139 return "server descriptor upload";
140 case DIR_PURPOSE_UPLOAD_RENDDESC
:
141 return "hidden-service descriptor upload";
142 case DIR_PURPOSE_UPLOAD_VOTE
:
143 return "server vote upload";
144 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
145 return "consensus signature upload";
146 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
147 return "running-routers fetch";
148 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
149 return "network-status fetch";
150 case DIR_PURPOSE_FETCH_SERVERDESC
:
151 return "server descriptor fetch";
152 case DIR_PURPOSE_FETCH_EXTRAINFO
:
153 return "extra-info fetch";
154 case DIR_PURPOSE_FETCH_CONSENSUS
:
155 return "consensus network-status fetch";
156 case DIR_PURPOSE_FETCH_CERTIFICATE
:
157 return "authority cert fetch";
158 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
159 return "status vote fetch";
160 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
161 return "consensus signature fetch";
162 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
163 return "hidden-service v2 descriptor fetch";
164 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
165 return "hidden-service v2 descriptor upload";
168 log_warn(LD_BUG
, "Called with unknown purpose %d", purpose
);
172 /** Return true iff <b>identity_digest</b> is the digest of a router we
173 * believe to support extrainfo downloads. (If <b>is_authority</b> we do
174 * additional checking that's only valid for authorities.) */
176 router_supports_extrainfo(const char *identity_digest
, int is_authority
)
178 routerinfo_t
*ri
= router_get_by_digest(identity_digest
);
181 if (ri
->caches_extra_info
)
183 if (is_authority
&& ri
->platform
&&
184 tor_version_as_new_as(ri
->platform
, "Tor 0.2.0.0-alpha-dev (r10070)"))
188 routerstatus_t
*rs
= router_get_consensus_status_by_id(identity_digest
);
189 if (rs
&& rs
->version_supports_extrainfo_upload
)
195 /** Return true iff all trusted directory servers have accepted our
196 * server descriptor. */
198 directories_have_accepted_server_descriptor(void)
200 smartlist_t
*servers
= router_get_trusted_dir_servers();
201 or_options_t
*options
= get_options();
202 /* XXX020 If any authority of the needed type is down, this
203 * function will never return true. Perhaps we need to be
204 * tolerant of down servers? Or even better, should we change
205 * this so one successful upload is enough? -RD */
206 SMARTLIST_FOREACH(servers
, trusted_dir_server_t
*, d
, {
207 if ((d
->type
& options
->_PublishServerDescriptor
) &&
208 !d
->has_accepted_serverdesc
) {
215 /** Start a connection to every suitable directory authority, using
216 * connection purpose 'purpose' and uploading the payload 'payload'
217 * (length 'payload_len'). The purpose should be one of
218 * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
220 * <b>type</b> specifies what sort of dir authorities (V1, V2,
221 * HIDSERV, BRIDGE) we should upload to.
223 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
224 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
225 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
226 * to all authorities, and the extra-info document to all authorities that
230 directory_post_to_dirservers(uint8_t dir_purpose
, uint8_t router_purpose
,
231 authority_type_t type
,
233 size_t payload_len
, size_t extrainfo_len
)
236 smartlist_t
*dirservers
= router_get_trusted_dir_servers();
238 tor_assert(dirservers
);
239 /* This tries dirservers which we believe to be down, but ultimately, that's
240 * harmless, and we may as well err on the side of getting things uploaded.
242 SMARTLIST_FOREACH(dirservers
, trusted_dir_server_t
*, ds
,
244 routerstatus_t
*rs
= &(ds
->fake_status
);
245 size_t upload_len
= payload_len
;
247 if ((type
& ds
->type
) == 0)
250 found
= 1; /* at least one authority of this type was listed */
251 if (dir_purpose
== DIR_PURPOSE_UPLOAD_DIR
)
252 ds
->has_accepted_serverdesc
= 0;
254 if (extrainfo_len
&& router_supports_extrainfo(ds
->digest
, 1)) {
255 upload_len
+= extrainfo_len
;
256 log_info(LD_DIR
, "Uploading an extrainfo (length %d)",
257 (int) extrainfo_len
);
259 post_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
) ||
260 !fascist_firewall_allows_address_dir(ds
->addr
, ds
->dir_port
);
261 directory_initiate_command_routerstatus(rs
, dir_purpose
,
264 NULL
, payload
, upload_len
, 0);
267 char *s
= authority_type_to_string(type
);
268 log_warn(LD_DIR
, "Publishing server descriptor to directory authorities "
269 "of type '%s', but no authorities of that type listed!", s
);
274 /** Start a connection to a random running directory server, using
275 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
276 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
277 * If <b>retry_if_no_servers</b>, then if all the possible servers seem
278 * down, mark them up and try again.
281 directory_get_from_dirserver(uint8_t dir_purpose
, uint8_t router_purpose
,
282 const char *resource
, int retry_if_no_servers
)
284 routerstatus_t
*rs
= NULL
;
285 or_options_t
*options
= get_options();
286 int prefer_authority
= directory_fetches_from_authorities(options
);
287 int get_via_tor
= purpose_needs_anonymity(dir_purpose
, router_purpose
);
288 authority_type_t type
;
289 int flags
= retry_if_no_servers
? PDS_RETRY_IF_NO_SERVERS
: 0;
290 time_t if_modified_since
= 0;
292 /* FFFF we could break this switch into its own function, and call
293 * it elsewhere in directory.c. -RD */
294 switch (dir_purpose
) {
295 case DIR_PURPOSE_FETCH_EXTRAINFO
:
296 type
= EXTRAINFO_CACHE
|
297 (router_purpose
== ROUTER_PURPOSE_BRIDGE
? BRIDGE_AUTHORITY
:
300 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
301 case DIR_PURPOSE_FETCH_SERVERDESC
:
302 type
= (router_purpose
== ROUTER_PURPOSE_BRIDGE
? BRIDGE_AUTHORITY
:
305 case DIR_PURPOSE_FETCH_DIR
:
306 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
309 case DIR_PURPOSE_FETCH_RENDDESC
:
310 type
= HIDSERV_AUTHORITY
;
312 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
313 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
316 case DIR_PURPOSE_FETCH_CONSENSUS
:
317 case DIR_PURPOSE_FETCH_CERTIFICATE
:
321 log_warn(LD_BUG
, "Unexpected purpose %d", (int)dir_purpose
);
325 if (DIR_PURPOSE_FETCH_CONSENSUS
) {
326 networkstatus_vote_t
*v
= networkstatus_get_latest_consensus();
328 if_modified_since
= v
->valid_after
+ 180;
331 if (!options
->FetchServerDescriptors
&& type
!= HIDSERV_AUTHORITY
)
335 if (options
->UseBridges
&& type
!= BRIDGE_AUTHORITY
) {
336 /* want to ask a running bridge for which we have a descriptor. */
337 /* XXX021 we assume that all of our bridges can answer any
338 * possible directory question. This won't be true forever. -RD */
339 routerinfo_t
*ri
= choose_random_entry(NULL
);
341 directory_initiate_command(ri
->address
, ri
->addr
,
343 1, ri
->cache_info
.identity_digest
,
346 0, resource
, NULL
, 0, if_modified_since
);
348 log_notice(LD_DIR
, "Ignoring directory request, since no bridge "
349 "nodes are available yet.");
352 if (prefer_authority
|| type
== BRIDGE_AUTHORITY
) {
353 /* only ask authdirservers, and don't ask myself */
354 rs
= router_pick_trusteddirserver(type
, flags
);
356 if (!rs
&& type
!= BRIDGE_AUTHORITY
) {
357 /* anybody with a non-zero dirport will do */
358 rs
= router_pick_directory_server(type
, flags
);
360 log_info(LD_DIR
, "No router found for %s; falling back to "
361 "dirserver list.", dir_conn_purpose_to_string(dir_purpose
));
362 rs
= router_pick_trusteddirserver(type
, flags
);
364 get_via_tor
= 1; /* last resort: try routing it via Tor */
368 } else { /* get_via_tor */
369 /* Never use fascistfirewall; we're going via Tor. */
370 if (dir_purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
371 /* only ask hidserv authorities, any of them will do */
372 flags
|= PDS_IGNORE_FASCISTFIREWALL
|PDS_ALLOW_SELF
;
373 rs
= router_pick_trusteddirserver(HIDSERV_AUTHORITY
, flags
);
375 /* anybody with a non-zero dirport will do. Disregard firewalls. */
376 flags
|= PDS_IGNORE_FASCISTFIREWALL
;
377 rs
= router_pick_directory_server(type
, flags
);
378 /* If we have any hope of building an indirect conn, we know some router
379 * descriptors. If (rs==NULL), we can't build circuits anyway, so
380 * there's no point in falling back to the authorities in this case. */
385 directory_initiate_command_routerstatus(rs
, dir_purpose
,
392 "While fetching directory info, "
393 "no running dirservers known. Will try again later. "
394 "(purpose %d)", dir_purpose
);
395 if (!purpose_needs_anonymity(dir_purpose
, router_purpose
)) {
396 /* remember we tried them all and failed. */
397 directory_all_unreachable(time(NULL
));
402 /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
403 * directory authority other than ourself. Only for use by authorities when
404 * searching for missing information while voting. */
406 directory_get_from_all_authorities(uint8_t dir_purpose
,
407 uint8_t router_purpose
,
408 const char *resource
)
410 tor_assert(dir_purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
||
411 dir_purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
);
413 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
414 trusted_dir_server_t
*, ds
,
417 if (router_digest_is_me(ds
->digest
))
419 if (!(ds
->type
& V3_AUTHORITY
))
421 rs
= &ds
->fake_status
;
422 directory_initiate_command_routerstatus(rs
, dir_purpose
, router_purpose
,
423 0, resource
, NULL
, 0, 0);
427 /** Launch a new connection to the directory server <b>status</b> to
428 * upload or download a server or rendezvous
429 * descriptor. <b>dir_purpose</b> determines what
430 * kind of directory connection we're launching, and must be one of
431 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. <b>router_purpose</b>
432 * specifies the descriptor purposes we have in mind (currently only
433 * used for FETCH_DIR).
435 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
436 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
438 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
442 directory_initiate_command_routerstatus(routerstatus_t
*status
,
444 uint8_t router_purpose
,
445 int anonymized_connection
,
446 const char *resource
,
449 time_t if_modified_since
)
451 routerinfo_t
*router
;
452 char address_buf
[INET_NTOA_BUF_LEN
+1];
455 if ((router
= router_get_by_digest(status
->identity_digest
))) {
456 address
= router
->address
;
458 in
.s_addr
= htonl(status
->addr
);
459 tor_inet_ntoa(&in
, address_buf
, sizeof(address_buf
));
460 address
= address_buf
;
462 directory_initiate_command(address
, status
->addr
,
463 status
->or_port
, status
->dir_port
,
464 status
->version_supports_begindir
,
465 status
->identity_digest
,
466 dir_purpose
, router_purpose
,
467 anonymized_connection
, resource
,
468 payload
, payload_len
, if_modified_since
);
471 /** Return true iff <b>conn</b> is the client side of a directory connection
472 * we launched to ourself in order to determine the reachability of our
475 directory_conn_is_self_reachability_test(dir_connection_t
*conn
)
477 if (conn
->requested_resource
&&
478 !strcmpstart(conn
->requested_resource
,"authority")) {
479 routerinfo_t
*me
= router_get_my_routerinfo();
481 router_digest_is_me(conn
->identity_digest
) &&
482 me
->addr
== conn
->_base
.addr
&&
483 me
->dir_port
== conn
->_base
.port
)
489 /** Called when we are unable to complete the client's request to a directory
490 * server due to a network error: Mark the router as down and try again if
494 connection_dir_request_failed(dir_connection_t
*conn
)
496 if (directory_conn_is_self_reachability_test(conn
)) {
497 routerinfo_t
*me
= router_get_my_routerinfo();
499 control_event_server_status(LOG_WARN
,
500 "REACHABILITY_FAILED DIRADDRESS=%s:%d",
501 me
->address
, me
->dir_port
);
502 return; /* this was a test fetch. don't retry. */
504 if (entry_list_can_grow(get_options()))
505 router_set_status(conn
->identity_digest
, 0); /* don't try him again */
506 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
||
507 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
508 log_info(LD_DIR
, "Giving up on directory server at '%s:%d'; retrying",
509 conn
->_base
.address
, conn
->_base
.port
);
510 directory_get_from_dirserver(conn
->_base
.purpose
, conn
->router_purpose
,
511 NULL
, 0 /* don't retry_if_no_servers */);
512 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
513 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
514 conn
->_base
.address
);
515 connection_dir_download_networkstatus_failed(conn
, -1);
516 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
517 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
518 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
519 conn
->_base
.address
);
520 connection_dir_download_routerdesc_failed(conn
);
521 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
522 networkstatus_consensus_download_failed(0);
523 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
524 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
525 conn
->_base
.address
);
526 connection_dir_download_cert_failed(conn
, 0);
527 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
528 log_info(LD_DIR
, "Giving up downloading detached signatures from '%s'",
529 conn
->_base
.address
);
530 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
531 log_info(LD_DIR
, "Giving up downloading votes from '%s'",
532 conn
->_base
.address
);
536 /** Called when an attempt to download one or more network status
537 * documents on connection <b>conn</b> failed. Decide whether to
538 * retry the fetch now, later, or never.
541 connection_dir_download_networkstatus_failed(dir_connection_t
*conn
,
544 if (!conn
->requested_resource
) {
545 /* We never reached directory_send_command, which means that we never
546 * opened a network connection. Either we're out of sockets, or the
547 * network is down. Either way, retrying would be pointless. */
550 if (!strcmpstart(conn
->requested_resource
, "all")) {
551 /* We're a non-authoritative directory cache; try again. Ignore status
552 * code, since we don't want to keep trying forever in a tight loop
553 * if all the authorities are shutting us out. */
554 smartlist_t
*trusted_dirs
= router_get_trusted_dir_servers();
555 SMARTLIST_FOREACH(trusted_dirs
, trusted_dir_server_t
*, ds
,
556 download_status_failed(&ds
->v2_ns_dl_status
, 0));
557 directory_get_from_dirserver(conn
->_base
.purpose
, conn
->router_purpose
,
558 "all.z", 0 /* don't retry_if_no_servers */);
559 } else if (!strcmpstart(conn
->requested_resource
, "fp/")) {
560 /* We were trying to download by fingerprint; mark them all as having
561 * failed, and possibly retry them later.*/
562 smartlist_t
*failed
= smartlist_create();
563 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
565 if (smartlist_len(failed
)) {
566 dir_networkstatus_download_failed(failed
, status_code
);
567 SMARTLIST_FOREACH(failed
, char *, cp
, tor_free(cp
));
569 smartlist_free(failed
);
573 /** Called when an attempt to download one or more router descriptors
574 * or extra-info documents on connection <b>conn</b> failed.
577 connection_dir_download_routerdesc_failed(dir_connection_t
*conn
)
579 /* No need to increment the failure count for routerdescs, since
580 * it's not their fault. */
582 /* No need to relaunch descriptor downloads here: we already do it
583 * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
584 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
585 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
590 /** Called when an attempt to fetch a certificate fails. */
592 connection_dir_download_cert_failed(dir_connection_t
*conn
, int status
)
595 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
);
597 if (!conn
->requested_resource
)
599 failed
= smartlist_create();
600 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
602 SMARTLIST_FOREACH(failed
, char *, cp
,
604 trusted_dir_server_t
*dir
= trusteddirserver_get_by_v3_auth_digest(cp
);
606 download_status_failed(&dir
->cert_dl_status
, status
);
609 smartlist_free(failed
);
611 update_certificate_downloads(time(NULL
));
614 /** Helper for directory_initiate_command_routerstatus: send the
615 * command to a server whose address is <b>address</b>, whose IP is
616 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
617 * <b>supports_begindir</b>, and whose identity key digest is
620 directory_initiate_command(const char *address
, uint32_t addr
,
621 uint16_t or_port
, uint16_t dir_port
,
622 int supports_begindir
, const char *digest
,
623 uint8_t dir_purpose
, uint8_t router_purpose
,
624 int anonymized_connection
, const char *resource
,
625 const char *payload
, size_t payload_len
,
626 time_t if_modified_since
)
628 dir_connection_t
*conn
;
629 or_options_t
*options
= get_options();
630 int use_begindir
= supports_begindir
&& or_port
&&
631 (options
->TunnelDirConns
||
632 router_purpose
== ROUTER_PURPOSE_BRIDGE
) &&
633 (anonymized_connection
||
634 fascist_firewall_allows_address_or(addr
, or_port
));
638 tor_assert(or_port
|| dir_port
);
641 log_debug(LD_DIR
, "anonymized %d, use_begindir %d.",
642 anonymized_connection
, use_begindir
);
644 log_debug(LD_DIR
, "Initiating %s", dir_conn_purpose_to_string(dir_purpose
));
646 conn
= TO_DIR_CONN(connection_new(CONN_TYPE_DIR
, AF_INET
));
648 /* set up conn so it's got all the data we need to remember */
649 conn
->_base
.addr
= addr
;
650 conn
->_base
.port
= use_begindir
? or_port
: dir_port
;
651 conn
->_base
.address
= tor_strdup(address
);
652 memcpy(conn
->identity_digest
, digest
, DIGEST_LEN
);
654 conn
->_base
.purpose
= dir_purpose
;
655 conn
->router_purpose
= router_purpose
;
657 /* give it an initial state */
658 conn
->_base
.state
= DIR_CONN_STATE_CONNECTING
;
660 /* decide whether we can learn our IP address from this conn */
661 conn
->dirconn_direct
= !anonymized_connection
;
663 if (!anonymized_connection
&& !use_begindir
) {
664 /* then we want to connect to dirport directly */
666 if (options
->HttpProxy
) {
667 addr
= options
->HttpProxyAddr
;
668 dir_port
= options
->HttpProxyPort
;
671 switch (connection_connect(TO_CONN(conn
), conn
->_base
.address
, addr
,
674 connection_dir_request_failed(conn
); /* retry if we want */
675 /* XXX we only pass 'conn' above, not 'resource', 'payload',
676 * etc. So in many situations it can't retry! -RD */
677 connection_free(TO_CONN(conn
));
680 /* start flushing conn */
681 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
684 /* queue the command on the outbuf */
685 directory_send_command(conn
, dir_purpose
, 1, resource
,
686 payload
, payload_len
, if_modified_since
);
687 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
688 /* writable indicates finish, readable indicates broken link,
689 error indicates broken link in windowsland. */
691 } else { /* we want to connect via a tor connection */
692 edge_connection_t
*linked_conn
;
693 /* make an AP connection
694 * populate it and add it at the right state
698 connection_ap_make_link(conn
->_base
.address
, conn
->_base
.port
,
699 digest
, use_begindir
, conn
->dirconn_direct
);
701 log_warn(LD_NET
,"Making tunnel to dirserver failed.");
702 connection_mark_for_close(TO_CONN(conn
));
705 connection_link_connections(TO_CONN(conn
), TO_CONN(linked_conn
));
707 if (connection_add(TO_CONN(conn
)) < 0) {
708 log_warn(LD_NET
,"Unable to add connection for link to dirserver.");
709 connection_mark_for_close(TO_CONN(conn
));
712 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
713 /* queue the command on the outbuf */
714 directory_send_command(conn
, dir_purpose
, 0, resource
,
715 payload
, payload_len
, if_modified_since
);
716 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
717 connection_start_reading(TO_CONN(linked_conn
));
721 /** Return true iff anything we say on <b>conn</b> is being encrypted before
722 * we send it to the client/server. */
724 connection_dir_is_encrypted(dir_connection_t
*conn
)
726 /* Right now it's sufficient to see if conn is or has been linked, since
727 * the only thing it could be linked to is an edge connection on a
728 * circuit, and the only way it could have been unlinked is at the edge
729 * connection getting closed.
731 return TO_CONN(conn
)->linked
;
734 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
735 * are as in directory_initiate_command.
738 directory_send_command(dir_connection_t
*conn
,
739 int purpose
, int direct
, const char *resource
,
740 const char *payload
, size_t payload_len
,
741 time_t if_modified_since
)
743 char proxystring
[256];
744 char proxyauthstring
[256];
745 char hoststring
[128];
746 char imsstring
[RFC1123_TIME_LEN
+32];
749 const char *httpcommand
= NULL
;
753 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
755 tor_free(conn
->requested_resource
);
757 conn
->requested_resource
= tor_strdup(resource
);
759 /* come up with a string for which Host: we want */
760 if (conn
->_base
.port
== 80) {
761 strlcpy(hoststring
, conn
->_base
.address
, sizeof(hoststring
));
763 tor_snprintf(hoststring
, sizeof(hoststring
),"%s:%d",
764 conn
->_base
.address
, conn
->_base
.port
);
767 /* Format if-modified-since */
768 if (!if_modified_since
) {
771 char b
[RFC1123_TIME_LEN
+1];
772 format_rfc1123_time(b
, if_modified_since
);
773 tor_snprintf(imsstring
, sizeof(imsstring
), "\r\nIf-Modified-Since: %s", b
);
776 /* come up with some proxy lines, if we're using one. */
777 if (direct
&& get_options()->HttpProxy
) {
778 char *base64_authenticator
=NULL
;
779 const char *authenticator
= get_options()->HttpProxyAuthenticator
;
781 tor_snprintf(proxystring
, sizeof(proxystring
),"http://%s", hoststring
);
783 base64_authenticator
= alloc_http_authenticator(authenticator
);
784 if (!base64_authenticator
)
785 log_warn(LD_BUG
, "Encoding http authenticator failed");
787 if (base64_authenticator
) {
788 tor_snprintf(proxyauthstring
, sizeof(proxyauthstring
),
789 "\r\nProxy-Authorization: Basic %s",
790 base64_authenticator
);
791 tor_free(base64_authenticator
);
793 proxyauthstring
[0] = 0;
797 proxyauthstring
[0] = 0;
801 case DIR_PURPOSE_FETCH_DIR
:
802 tor_assert(!resource
);
803 tor_assert(!payload
);
805 url
= tor_strdup("/tor/dir.z");
807 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
808 tor_assert(!resource
);
809 tor_assert(!payload
);
811 url
= tor_strdup("/tor/running-routers");
813 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
815 len
= strlen(resource
)+32;
816 url
= tor_malloc(len
);
817 tor_snprintf(url
, len
, "/tor/status/%s", resource
);
819 case DIR_PURPOSE_FETCH_CONSENSUS
:
820 tor_assert(!resource
);
821 tor_assert(!payload
);
823 url
= tor_strdup("/tor/status-vote/current/consensus.z");
825 case DIR_PURPOSE_FETCH_CERTIFICATE
:
826 tor_assert(resource
);
827 tor_assert(!payload
);
829 len
= strlen(resource
)+32;
830 url
= tor_malloc(len
);
831 tor_snprintf(url
, len
, "/tor/keys/%s", resource
);
833 case DIR_PURPOSE_FETCH_STATUS_VOTE
:
834 tor_assert(resource
);
835 tor_assert(!payload
);
837 len
= strlen(resource
)+32;
838 url
= tor_malloc(len
);
839 tor_snprintf(url
, len
, "/tor/status-vote/next/%s.z", resource
);
841 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
:
842 tor_assert(!resource
);
843 tor_assert(!payload
);
845 url
= tor_strdup("/tor/status-vote/next/consensus-signatures.z");
847 case DIR_PURPOSE_FETCH_SERVERDESC
:
849 len
= strlen(resource
)+32;
850 url
= tor_malloc(len
);
851 tor_snprintf(url
, len
, "/tor/server/%s", resource
);
853 case DIR_PURPOSE_FETCH_EXTRAINFO
:
855 len
= strlen(resource
)+32;
856 url
= tor_malloc(len
);
857 tor_snprintf(url
, len
, "/tor/extra/%s", resource
);
859 case DIR_PURPOSE_UPLOAD_DIR
:
860 tor_assert(!resource
);
862 httpcommand
= "POST";
863 url
= tor_strdup("/tor/");
865 case DIR_PURPOSE_UPLOAD_VOTE
:
866 tor_assert(!resource
);
868 httpcommand
= "POST";
869 url
= tor_strdup("/tor/post/vote");
871 case DIR_PURPOSE_UPLOAD_SIGNATURES
:
872 tor_assert(!resource
);
874 httpcommand
= "POST";
875 url
= tor_strdup("/tor/post/consensus-signature");
877 case DIR_PURPOSE_FETCH_RENDDESC
:
878 tor_assert(resource
);
879 tor_assert(!payload
);
881 /* this must be true or we wouldn't be doing the lookup */
882 tor_assert(strlen(resource
) <= REND_SERVICE_ID_LEN_BASE32
);
883 /* This breaks the function abstraction. */
884 strlcpy(conn
->rend_query
, resource
, sizeof(conn
->rend_query
));
887 /* Request the most recent versioned descriptor. */
888 // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
889 // but that never got testing, and it wasn't a good design.)
890 len
= strlen(resource
)+32;
891 url
= tor_malloc(len
);
892 tor_snprintf(url
, len
, "/tor/rendezvous/%s", resource
);
894 case DIR_PURPOSE_FETCH_RENDDESC_V2
:
895 tor_assert(resource
);
896 tor_assert(strlen(resource
) <= REND_DESC_ID_V2_LEN_BASE32
);
897 /* Remember the query to refer to it when a response arrives. */
898 strlcpy(conn
->rend_query
, payload
, sizeof(conn
->rend_query
));
901 len
= strlen(resource
) + 32;
902 url
= tor_malloc(len
);
903 tor_snprintf(url
, len
, "/tor/rendezvous2/%s", resource
);
905 case DIR_PURPOSE_UPLOAD_RENDDESC
:
906 tor_assert(!resource
);
908 httpcommand
= "POST";
909 url
= tor_strdup("/tor/rendezvous/publish");
911 case DIR_PURPOSE_UPLOAD_RENDDESC_V2
:
912 tor_assert(!resource
);
914 httpcommand
= "POST";
915 url
= tor_strdup("/tor/rendezvous2/publish");
922 if (strlen(proxystring
) + strlen(url
) >= 4096) {
924 "Squid does not like URLs longer than 4095 bytes, and this "
925 "one is %d bytes long: %s%s",
926 (int)(strlen(proxystring
) + strlen(url
)), proxystring
, url
);
929 tor_snprintf(request
, sizeof(request
), "%s %s", httpcommand
, proxystring
);
930 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
931 connection_write_to_buf(url
, strlen(url
), TO_CONN(conn
));
934 if (!strcmp(httpcommand
, "GET") && !payload
) {
935 tor_snprintf(request
, sizeof(request
),
936 " HTTP/1.0\r\nHost: %s%s%s\r\n\r\n",
941 tor_snprintf(request
, sizeof(request
),
942 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s%s\r\n\r\n",
943 payload
? (unsigned long)payload_len
: 0,
948 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
951 /* then send the payload afterwards too */
952 connection_write_to_buf(payload
, payload_len
, TO_CONN(conn
));
956 /** Parse an HTTP request string <b>headers</b> of the form
958 * "\%s [http[s]://]\%s HTTP/1..."
960 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
961 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
962 * so it does. Return 0.
963 * Otherwise, return -1.
966 parse_http_url(const char *headers
, char **url
)
968 char *s
, *start
, *tmp
;
970 s
= (char *)eat_whitespace_no_nl(headers
);
972 s
= (char *)find_whitespace(s
); /* get past GET/POST */
974 s
= (char *)eat_whitespace_no_nl(s
);
976 start
= s
; /* this is it, assuming it's valid */
977 s
= (char *)find_whitespace(start
);
980 /* tolerate the http[s] proxy style of putting the hostname in the url */
981 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
985 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
986 tmp
= strchr(tmp
+3, '/');
987 if (tmp
&& tmp
< s
) {
988 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname' string");
994 if (s
-start
< 5 || strcmpstart(start
,"/tor/")) { /* need to rewrite it */
995 *url
= tor_malloc(s
- start
+ 5);
996 strlcpy(*url
,"/tor", s
-start
+5);
997 strlcat((*url
)+4, start
, s
-start
+1);
999 *url
= tor_strndup(start
, s
-start
);
1004 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
1005 * <b>which</b>. The key should be given with a terminating colon and space;
1006 * this function copies everything after, up to but not including the
1007 * following \\r\\n. */
1009 http_get_header(const char *headers
, const char *which
)
1011 const char *cp
= headers
;
1013 if (!strcasecmpstart(cp
, which
)) {
1015 cp
+= strlen(which
);
1016 if ((eos
= strchr(cp
,'\r')))
1017 return tor_strndup(cp
, eos
-cp
);
1019 return tor_strdup(cp
);
1021 cp
= strchr(cp
, '\n');
1028 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
1029 * <b>conn</b>-\>address to describe our best guess of the address that
1030 * originated this HTTP request. */
1032 http_set_address_origin(const char *headers
, connection_t
*conn
)
1036 fwd
= http_get_header(headers
, "Forwarded-For: ");
1038 fwd
= http_get_header(headers
, "X-Forwarded-For: ");
1041 if (!tor_inet_aton(fwd
, &in
) || is_internal_IP(ntohl(in
.s_addr
), 0)) {
1042 log_debug(LD_DIR
, "Ignoring unrecognized or internal IP %s",
1047 tor_free(conn
->address
);
1048 conn
->address
= tor_strdup(fwd
);
1053 /** Parse an HTTP response string <b>headers</b> of the form
1055 * "HTTP/1.\%d \%d\%s\r\n...".
1058 * If it's well-formed, assign the status code to *<b>code</b> and
1059 * return 0. Otherwise, return -1.
1061 * On success: If <b>date</b> is provided, set *date to the Date
1062 * header in the http headers, or 0 if no such header is found. If
1063 * <b>compression</b> is provided, set *<b>compression</b> to the
1064 * compression method given in the Content-Encoding header, or 0 if no
1065 * such header is found, or -1 if the value of the header is not
1066 * recognized. If <b>reason</b> is provided, strdup the reason string
1070 parse_http_response(const char *headers
, int *code
, time_t *date
,
1071 compress_method_t
*compression
, char **reason
)
1074 char datestr
[RFC1123_TIME_LEN
+1];
1075 smartlist_t
*parsed_headers
;
1076 tor_assert(headers
);
1079 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
1081 if (sscanf(headers
, "HTTP/1.%d %d", &n1
, &n2
) < 2 ||
1082 (n1
!= 0 && n1
!= 1) ||
1083 (n2
< 100 || n2
>= 600)) {
1084 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
1089 parsed_headers
= smartlist_create();
1090 smartlist_split_string(parsed_headers
, headers
, "\n",
1091 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
1093 smartlist_t
*status_line_elements
= smartlist_create();
1094 tor_assert(smartlist_len(parsed_headers
));
1095 smartlist_split_string(status_line_elements
,
1096 smartlist_get(parsed_headers
, 0),
1097 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
1098 tor_assert(smartlist_len(status_line_elements
) <= 3);
1099 if (smartlist_len(status_line_elements
) == 3) {
1100 *reason
= smartlist_get(status_line_elements
, 2);
1101 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
1103 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
1104 smartlist_free(status_line_elements
);
1108 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1109 if (!strcmpstart(s
, "Date: ")) {
1110 strlcpy(datestr
, s
+6, sizeof(datestr
));
1111 /* This will do nothing on failure, so we don't need to check
1112 the result. We shouldn't warn, since there are many other valid
1113 date formats besides the one we use. */
1114 parse_rfc1123_time(datestr
, date
);
1119 const char *enc
= NULL
;
1120 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
1121 if (!strcmpstart(s
, "Content-Encoding: ")) {
1124 if (!enc
|| !strcmp(enc
, "identity")) {
1125 *compression
= NO_METHOD
;
1126 } else if (!strcmp(enc
, "deflate") || !strcmp(enc
, "x-deflate")) {
1127 *compression
= ZLIB_METHOD
;
1128 } else if (!strcmp(enc
, "gzip") || !strcmp(enc
, "x-gzip")) {
1129 *compression
= GZIP_METHOD
;
1131 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
1133 *compression
= UNKNOWN_METHOD
;
1136 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
1137 smartlist_free(parsed_headers
);
1142 /** Return true iff <b>body</b> doesn't start with a plausible router or
1143 * running-list or directory opening. This is a sign of possible compression.
1146 body_is_plausible(const char *body
, size_t len
, int purpose
)
1150 return 1; /* empty bodies don't need decompression */
1153 if (purpose
!= DIR_PURPOSE_FETCH_RENDDESC
) {
1154 if (!strcmpstart(body
,"router") ||
1155 !strcmpstart(body
,"signed-directory") ||
1156 !strcmpstart(body
,"network-status") ||
1157 !strcmpstart(body
,"running-routers"))
1159 for (i
=0;i
<32;++i
) {
1160 if (!TOR_ISPRINT(body
[i
]) && !TOR_ISSPACE(body
[i
]))
1169 /** Called when we've just fetched a bunch of router descriptors in
1170 * <b>body</b>. The list <b>which</b>, if present, holds digests for
1171 * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1172 * is true, or identity digests otherwise. Parse the descriptors, validate
1173 * them, and annotate them as having purpose <b>purpose</b> and as having been
1174 * downloaded from <b>source</b>. */
1176 load_downloaded_routers(const char *body
, smartlist_t
*which
,
1177 int descriptor_digests
,
1182 char time_buf
[ISO_TIME_LEN
+1];
1183 int general
= router_purpose
== ROUTER_PURPOSE_GENERAL
;
1184 format_iso_time(time_buf
, time(NULL
));
1187 if (tor_snprintf(buf
, sizeof(buf
),
1188 "@downloaded-at %s\n"
1190 "%s%s%s", time_buf
, escaped(source
),
1191 !general
? "@purpose " : "",
1192 !general
? router_purpose_to_string(router_purpose
) : "",
1193 !general
? "\n" : "")<0)
1196 router_load_routers_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1197 descriptor_digests
, buf
);
1200 /** We are a client, and we've finished reading the server's
1201 * response. Parse it and act appropriately.
1203 * If we're still happy with using this directory server in the future, return
1204 * 0. Otherwise return -1; and the caller should consider trying the request
1207 * The caller will take care of marking the connection for close.
1210 connection_dir_client_reached_eof(dir_connection_t
*conn
)
1214 char *reason
= NULL
;
1215 size_t body_len
=0, orig_len
=0;
1217 time_t date_header
=0;
1219 compress_method_t compression
;
1222 int allow_partial
= (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1223 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
1224 int was_compressed
=0;
1225 time_t now
= time(NULL
);
1227 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
1228 &headers
, MAX_HEADERS_SIZE
,
1229 &body
, &body_len
, MAX_DIR_DL_SIZE
,
1231 case -1: /* overflow */
1232 log_warn(LD_PROTOCOL
,
1233 "'fetch' response too large (server '%s:%d'). Closing.",
1234 conn
->_base
.address
, conn
->_base
.port
);
1238 "'fetch' response not all here, but we're at eof. Closing.");
1240 /* case 1, fall through */
1242 orig_len
= body_len
;
1244 if (parse_http_response(headers
, &status_code
, &date_header
,
1245 &compression
, &reason
) < 0) {
1246 log_warn(LD_HTTP
,"Unparseable headers (server '%s:%d'). Closing.",
1247 conn
->_base
.address
, conn
->_base
.port
);
1248 tor_free(body
); tor_free(headers
);
1251 if (!reason
) reason
= tor_strdup("[no reason given]");
1254 "Received response from directory server '%s:%d': %d %s",
1255 conn
->_base
.address
, conn
->_base
.port
, status_code
,
1258 /* now check if it's got any hints for us about our IP address. */
1259 if (conn
->dirconn_direct
) {
1260 char *guess
= http_get_header(headers
, X_ADDRESS_HEADER
);
1262 router_new_address_suggestion(guess
);
1267 if (date_header
> 0) {
1268 /* The date header was written very soon after we sent our request,
1269 * so compute the skew as the difference between sending the request
1270 * and the date header. (We used to check now-date_header, but that's
1271 * inaccurate if we spend a lot of time downloading.)
1273 delta
= conn
->_base
.timestamp_lastwritten
- date_header
;
1274 if (abs(delta
)>ALLOW_DIRECTORY_TIME_SKEW
) {
1276 int trusted
= router_digest_is_trusted_dir(conn
->identity_digest
);
1277 format_time_interval(dbuf
, sizeof(dbuf
), delta
);
1278 log_fn(trusted
? LOG_WARN
: LOG_INFO
,
1280 "Received directory with skewed time (server '%s:%d'): "
1281 "It seems that our clock is %s by %s, or that theirs is %s. "
1282 "Tor requires an accurate clock to work: please check your time "
1283 "and date settings.",
1284 conn
->_base
.address
, conn
->_base
.port
,
1285 delta
>0 ? "ahead" : "behind", dbuf
,
1286 delta
>0 ? "behind" : "ahead");
1287 skewed
= 1; /* don't check the recommended-versions line */
1288 control_event_general_status(trusted
? LOG_WARN
: LOG_NOTICE
,
1289 "CLOCK_SKEW SKEW=%d SOURCE=DIRSERV:%s:%d",
1290 delta
, conn
->_base
.address
, conn
->_base
.port
);
1292 log_debug(LD_HTTP
, "Time on received directory is within tolerance; "
1293 "we are %d seconds skewed. (That's okay.)", delta
);
1296 (void) skewed
; /* skewed isn't used yet. */
1298 if (status_code
== 503 && body_len
< 16) {
1300 trusted_dir_server_t
*ds
;
1301 log_info(LD_DIR
,"Received http status code %d (%s) from server "
1302 "'%s:%d'. I'll try again soon.",
1303 status_code
, escaped(reason
), conn
->_base
.address
,
1305 if ((rs
= router_get_consensus_status_by_id(conn
->identity_digest
)))
1306 rs
->last_dir_503_at
= now
;
1307 if ((ds
= router_get_trusteddirserver_by_digest(conn
->identity_digest
)))
1308 ds
->fake_status
.last_dir_503_at
= now
;
1310 tor_free(body
); tor_free(headers
); tor_free(reason
);
1312 } else if (status_code
== 503) {
1313 /* XXXX022 Remove this once every server with bug 539 is obsolete. */
1314 log_info(LD_DIR
, "Server at '%s:%d' sent us a 503 response, but included "
1315 "a body anyway. We'll pretend it gave us a 200.",
1316 conn
->_base
.address
, conn
->_base
.port
);
1320 plausible
= body_is_plausible(body
, body_len
, conn
->_base
.purpose
);
1321 if (compression
!= NO_METHOD
|| !plausible
) {
1322 char *new_body
= NULL
;
1324 compress_method_t guessed
= detect_compression_method(body
, body_len
);
1325 if (compression
== UNKNOWN_METHOD
|| guessed
!= compression
) {
1326 /* Tell the user if we don't believe what we're told about compression.*/
1327 const char *description1
, *description2
;
1328 if (compression
== ZLIB_METHOD
)
1329 description1
= "as deflated";
1330 else if (compression
== GZIP_METHOD
)
1331 description1
= "as gzipped";
1332 else if (compression
== NO_METHOD
)
1333 description1
= "as uncompressed";
1335 description1
= "with an unknown Content-Encoding";
1336 if (guessed
== ZLIB_METHOD
)
1337 description2
= "deflated";
1338 else if (guessed
== GZIP_METHOD
)
1339 description2
= "gzipped";
1340 else if (!plausible
)
1341 description2
= "confusing binary junk";
1343 description2
= "uncompressed";
1345 log_info(LD_HTTP
, "HTTP body from server '%s:%d' was labeled %s, "
1346 "but it seems to be %s.%s",
1347 conn
->_base
.address
, conn
->_base
.port
, description1
,
1349 (compression
>0 && guessed
>0)?" Trying both.":"");
1351 /* Try declared compression first if we can. */
1352 if (compression
== GZIP_METHOD
|| compression
== ZLIB_METHOD
)
1353 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, compression
,
1354 !allow_partial
, LOG_PROTOCOL_WARN
);
1355 /* Okay, if that didn't work, and we think that it was compressed
1356 * differently, try that. */
1358 (guessed
== GZIP_METHOD
|| guessed
== ZLIB_METHOD
) &&
1359 compression
!= guessed
)
1360 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, guessed
,
1361 !allow_partial
, LOG_PROTOCOL_WARN
);
1362 /* If we're pretty sure that we have a compressed directory, and
1363 * we didn't manage to uncompress it, then warn and bail. */
1364 if (!plausible
&& !new_body
) {
1365 log_fn(LOG_PROTOCOL_WARN
, LD_HTTP
,
1366 "Unable to decompress HTTP body (server '%s:%d').",
1367 conn
->_base
.address
, conn
->_base
.port
);
1368 tor_free(body
); tor_free(headers
); tor_free(reason
);
1379 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
) {
1380 /* fetch/process the directory to cache it. */
1381 log_info(LD_DIR
,"Received directory (size %d) from server '%s:%d'",
1382 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1383 if (status_code
!= 200) {
1384 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1385 "'%s:%d' while fetching directory. I'll try again soon.",
1386 status_code
, escaped(reason
), conn
->_base
.address
,
1388 tor_free(body
); tor_free(headers
); tor_free(reason
);
1391 if (router_parse_directory(body
) < 0) {
1392 log_notice(LD_DIR
,"I failed to parse the directory I fetched from "
1393 "'%s:%d'. Ignoring.", conn
->_base
.address
, conn
->_base
.port
);
1395 note_request(was_compressed
?"dl/dir.z":"dl/dir", orig_len
);
1398 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
1399 /* just update our list of running routers, if this list is new info */
1400 log_info(LD_DIR
,"Received running-routers list (size %d)", (int)body_len
);
1401 if (status_code
!= 200) {
1402 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1403 "'%s:%d' while fetching running-routers. I'll try again soon.",
1404 status_code
, escaped(reason
), conn
->_base
.address
,
1406 tor_free(body
); tor_free(headers
); tor_free(reason
);
1409 if (router_parse_runningrouters(body
)<0) {
1411 "Bad running-routers from server '%s:%d'. I'll try again soon.",
1412 conn
->_base
.address
, conn
->_base
.port
);
1413 tor_free(body
); tor_free(headers
); tor_free(reason
);
1416 note_request(was_compressed
?"dl/running-routers.z":
1417 "dl/running-routers", orig_len
);
1420 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
1421 smartlist_t
*which
= NULL
;
1422 networkstatus_source_t source
;
1424 log_info(LD_DIR
,"Received networkstatus objects (size %d) from server "
1425 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1426 if (status_code
!= 200) {
1428 "Received http status code %d (%s) from server "
1429 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1430 status_code
, escaped(reason
), conn
->_base
.address
,
1431 conn
->_base
.port
, conn
->requested_resource
);
1432 tor_free(body
); tor_free(headers
); tor_free(reason
);
1433 connection_dir_download_networkstatus_failed(conn
, status_code
);
1436 note_request(was_compressed
?"dl/status.z":"dl/status", orig_len
);
1437 if (conn
->requested_resource
&&
1438 !strcmpstart(conn
->requested_resource
,"fp/")) {
1439 source
= NS_FROM_DIR_BY_FP
;
1440 which
= smartlist_create();
1441 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
1443 } else if (conn
->requested_resource
&&
1444 !strcmpstart(conn
->requested_resource
, "all")) {
1445 source
= NS_FROM_DIR_ALL
;
1446 which
= smartlist_create();
1447 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1448 trusted_dir_server_t
*, ds
,
1450 char *hex
= tor_malloc(HEX_DIGEST_LEN
+1);
1451 base16_encode(hex
, HEX_DIGEST_LEN
+1, ds
->digest
, DIGEST_LEN
);
1452 smartlist_add(which
, hex
);
1455 /* XXXX Can we even end up here? -- weasel*/
1456 source
= NS_FROM_DIR_BY_FP
;
1457 log_warn(LD_BUG
, "We received a networkstatus but we didn't ask "
1458 "for it by fp, nor did we ask for all.");
1462 char *next
= strstr(cp
, "\nnetwork-status-version");
1465 /* learn from it, and then remove it from 'which' */
1466 if (router_set_networkstatus_v2(cp
, now
, source
, which
)<0)
1474 /* launches router downloads as needed */
1475 routers_update_all_from_networkstatus(now
, 2);
1476 directory_info_has_arrived(now
, 0);
1478 if (smartlist_len(which
)) {
1479 dir_networkstatus_download_failed(which
, status_code
);
1481 SMARTLIST_FOREACH(which
, char *, s
, tor_free(s
));
1482 smartlist_free(which
);
1486 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CONSENSUS
) {
1488 if (status_code
!= 200) {
1489 int severity
= (status_code
== 304) ? LOG_INFO
: LOG_WARN
;
1490 log(severity
, LD_DIR
,
1491 "Received http status code %d (%s) from server "
1492 "'%s:%d' while fetching consensus directory.",
1493 status_code
, escaped(reason
), conn
->_base
.address
,
1495 tor_free(body
); tor_free(headers
); tor_free(reason
);
1496 networkstatus_consensus_download_failed(status_code
);
1499 log_info(LD_DIR
,"Received consensus directory (size %d) from server "
1500 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1501 if ((r
=networkstatus_set_current_consensus(body
, 0))<0) {
1502 log_fn(r
<-1?LOG_WARN
:LOG_INFO
, LD_DIR
,
1503 "Unable to load consensus directory downloaded from "
1504 "server '%s:%d'", conn
->_base
.address
, conn
->_base
.port
);
1505 tor_free(body
); tor_free(headers
); tor_free(reason
);
1506 networkstatus_consensus_download_failed(0);
1509 /* launches router downloads as needed */
1510 routers_update_all_from_networkstatus(now
, 3);
1511 directory_info_has_arrived(now
, 0);
1512 log_info(LD_DIR
, "Successfully loaded consensus.");
1515 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_CERTIFICATE
) {
1516 if (status_code
!= 200) {
1518 "Received http status code %d (%s) from server "
1519 "'%s:%d' while fetching \"/tor/keys/%s\".",
1520 status_code
, escaped(reason
), conn
->_base
.address
,
1521 conn
->_base
.port
, conn
->requested_resource
);
1522 connection_dir_download_cert_failed(conn
, status_code
);
1523 tor_free(body
); tor_free(headers
); tor_free(reason
);
1526 log_info(LD_DIR
,"Received authority certificates (size %d) from server "
1527 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1528 if (trusted_dirs_load_certs_from_string(body
, 0)<0) {
1529 log_warn(LD_DIR
, "Unable to parse fetched certificates");
1530 connection_dir_download_cert_failed(conn
, status_code
);
1532 directory_info_has_arrived(now
, 0);
1533 log_info(LD_DIR
, "Successfully loaded certificates from fetch.");
1536 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_STATUS_VOTE
) {
1539 log_info(LD_DIR
,"Got votes (size %d) from server %s:%d",
1540 (int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1541 if (status_code
!= 200) {
1543 "Received http status code %d (%s) from server "
1544 "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".",
1545 status_code
, escaped(reason
), conn
->_base
.address
,
1546 conn
->_base
.port
, conn
->requested_resource
);
1547 tor_free(body
); tor_free(headers
); tor_free(reason
);
1550 dirvote_add_vote(body
, &msg
, &st
);
1552 log_warn(LD_DIR
, "Error adding retrieved vote: %s", msg
);
1554 log_info(LD_DIR
, "Added vote(s) successfully [msg: %s]", msg
);
1557 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DETACHED_SIGNATURES
) {
1558 const char *msg
= NULL
;
1559 log_info(LD_DIR
,"Got detached signatures (size %d) from server %s:%d",
1560 (int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1561 if (status_code
!= 200) {
1563 "Received http status code %d (%s) from server "
1564 "'%s:%d' while fetching \"/tor/status-vote/consensus-signatures.z\".",
1565 status_code
, escaped(reason
), conn
->_base
.address
,
1567 tor_free(body
); tor_free(headers
); tor_free(reason
);
1570 if (dirvote_add_signatures(body
, conn
->_base
.address
, &msg
)<0) {
1571 log_warn(LD_DIR
, "Problem adding detached signatures from %s:%d: %s",
1572 conn
->_base
.address
, conn
->_base
.port
, msg
?msg
:"???");
1576 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1577 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
1578 int was_ei
= conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
;
1579 smartlist_t
*which
= NULL
;
1580 int n_asked_for
= 0;
1581 int descriptor_digests
= conn
->requested_resource
&&
1582 !strcmpstart(conn
->requested_resource
,"d/");
1583 log_info(LD_DIR
,"Received %s (size %d) from server '%s:%d'",
1584 was_ei
? "extra server info" : "server info",
1585 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1587 note_request(was_compressed
?"dl/extra.z":"dl/extra", orig_len
);
1589 note_request(was_compressed
?"dl/server.z":"dl/server", orig_len
);
1590 if (conn
->requested_resource
&&
1591 (!strcmpstart(conn
->requested_resource
,"d/") ||
1592 !strcmpstart(conn
->requested_resource
,"fp/"))) {
1593 which
= smartlist_create();
1594 dir_split_resource_into_fingerprints(conn
->requested_resource
+
1595 (descriptor_digests
? 2 : 3),
1597 n_asked_for
= smartlist_len(which
);
1599 if (status_code
!= 200) {
1600 int dir_okay
= status_code
== 404 ||
1601 (status_code
== 400 && !strcmp(reason
, "Servers unavailable."));
1602 /* 404 means that it didn't have them; no big deal.
1603 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1604 log_fn(dir_okay
? LOG_INFO
: LOG_WARN
, LD_DIR
,
1605 "Received http status code %d (%s) from server '%s:%d' "
1606 "while fetching \"/tor/server/%s\". I'll try again soon.",
1607 status_code
, escaped(reason
), conn
->_base
.address
,
1608 conn
->_base
.port
, conn
->requested_resource
);
1610 connection_dir_download_routerdesc_failed(conn
);
1612 dir_routerdesc_download_failed(which
, status_code
,
1613 conn
->router_purpose
,
1614 was_ei
, descriptor_digests
);
1615 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1616 smartlist_free(which
);
1618 tor_free(body
); tor_free(headers
); tor_free(reason
);
1619 return dir_okay
? 0 : -1;
1621 /* Learn the routers, assuming we requested by fingerprint or "all"
1624 * We use "authority" to fetch our own descriptor for
1625 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1626 * the output of "authority" requests unless we are using bridges,
1627 * since otherwise they'll be the response from reachability tests,
1628 * and we don't really want to add that to our routerlist. */
1629 if (which
|| (conn
->requested_resource
&&
1630 (!strcmpstart(conn
->requested_resource
, "all") ||
1631 (!strcmpstart(conn
->requested_resource
, "authority") &&
1632 get_options()->UseBridges
)))) {
1633 /* as we learn from them, we remove them from 'which' */
1635 router_load_extrainfo_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1636 descriptor_digests
);
1638 //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1639 // descriptor_digests, conn->router_purpose);
1640 load_downloaded_routers(body
, which
, descriptor_digests
,
1641 conn
->router_purpose
,
1642 conn
->_base
.address
);
1643 directory_info_has_arrived(now
, 0);
1646 if (which
) { /* mark remaining ones as failed */
1647 log_info(LD_DIR
, "Received %d/%d %s requested from %s:%d",
1648 n_asked_for
-smartlist_len(which
), n_asked_for
,
1649 was_ei
? "extra-info documents" : "router descriptors",
1650 conn
->_base
.address
, (int)conn
->_base
.port
);
1651 if (smartlist_len(which
)) {
1652 dir_routerdesc_download_failed(which
, status_code
,
1653 conn
->router_purpose
,
1654 was_ei
, descriptor_digests
);
1656 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1657 smartlist_free(which
);
1659 if (directory_conn_is_self_reachability_test(conn
))
1660 router_dirport_found_reachable();
1663 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_DIR
) {
1664 switch (status_code
) {
1666 trusted_dir_server_t
*ds
=
1667 router_get_trusteddirserver_by_digest(conn
->identity_digest
);
1668 char *rejected_hdr
= http_get_header(headers
,
1669 "X-Descriptor-Not-New: ");
1672 if (!strcmp(rejected_hdr
, "Yes")) {
1673 /* XXXX020 use this information; be sure to upload next one
1677 tor_free(rejected_hdr
);
1679 log_info(LD_GENERAL
,"eof (status 200) after uploading server "
1680 "descriptor: finished.");
1681 control_event_server_status(
1682 LOG_NOTICE
, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1683 conn
->_base
.address
, conn
->_base
.port
);
1685 ds
->has_accepted_serverdesc
= 1;
1686 if (directories_have_accepted_server_descriptor())
1687 control_event_server_status(LOG_NOTICE
, "GOOD_SERVER_DESCRIPTOR");
1691 log_warn(LD_GENERAL
,"http status 400 (%s) response from "
1692 "dirserver '%s:%d'. Please correct.",
1693 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1694 control_event_server_status(LOG_WARN
,
1695 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1696 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1699 log_warn(LD_GENERAL
,
1700 "http status %d (%s) reason unexpected while uploading "
1701 "descriptor to server '%s:%d').",
1702 status_code
, escaped(reason
), conn
->_base
.address
,
1706 /* return 0 in all cases, since we don't want to mark any
1707 * dirservers down just because they don't like us. */
1710 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_VOTE
) {
1711 switch (status_code
) {
1713 log_notice(LD_DIR
,"Uploaded a vote to dirserver %s:%d",
1714 conn
->_base
.address
, conn
->_base
.port
);
1718 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
1719 "vote to dirserver '%s:%d'. Please correct.",
1720 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1723 log_warn(LD_GENERAL
,
1724 "http status %d (%s) reason unexpected while uploading "
1725 "vote to server '%s:%d').",
1726 status_code
, escaped(reason
), conn
->_base
.address
,
1730 /* return 0 in all cases, since we don't want to mark any
1731 * dirservers down just because they don't like us. */
1734 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_SIGNATURES
) {
1735 switch (status_code
) {
1737 log_notice(LD_DIR
,"Uploaded signature(s) to dirserver %s:%d",
1738 conn
->_base
.address
, conn
->_base
.port
);
1742 log_warn(LD_DIR
,"http status 400 (%s) response after uploading "
1743 "signatures to dirserver '%s:%d'. Please correct.",
1744 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1747 log_warn(LD_GENERAL
,
1748 "http status %d (%s) reason unexpected while uploading "
1749 "signatures to server '%s:%d').",
1750 status_code
, escaped(reason
), conn
->_base
.address
,
1754 /* return 0 in all cases, since we don't want to mark any
1755 * dirservers down just because they don't like us. */
1758 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
1759 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1761 (int)body_len
, status_code
, escaped(reason
));
1762 switch (status_code
) {
1764 if (rend_cache_store(body
, body_len
, 0) < 0) {
1765 log_warn(LD_REND
,"Failed to fetch rendezvous descriptor.");
1766 /* Any pending rendezvous attempts will notice when
1767 * connection_about_to_close_connection()
1768 * cleans this dir conn up. */
1769 /* We could retry. But since v0 descriptors are going out of
1770 * style, it isn't worth the hassle. We'll do better in v2. */
1772 /* success. notify pending connections about this. */
1773 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1774 rend_client_desc_here(conn
->rend_query
);
1778 /* Not there. Pending connections will be notified when
1779 * connection_about_to_close_connection() cleans this conn up. */
1783 "http status 400 (%s). Dirserver didn't like our "
1784 "rendezvous query?", escaped(reason
));
1787 log_warn(LD_REND
,"http status %d (%s) response unexpected while "
1788 "fetching hidden service descriptor (server '%s:%d').",
1789 status_code
, escaped(reason
), conn
->_base
.address
,
1795 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC_V2
) {
1796 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1798 (int)body_len
, status_code
, escaped(reason
));
1799 switch (status_code
) {
1801 if (rend_cache_store_v2_desc_as_client(body
, NULL
) < 0) {
1802 log_warn(LD_REND
,"Fetching v2 rendezvous descriptor failed. "
1803 "Retrying at another directory.");
1804 /* We'll retry when connection_about_to_close_connection()
1805 * cleans this dir conn up. */
1807 /* success. notify pending connections about this. */
1808 log_info(LD_REND
, "Successfully fetched rendezvous descriptor.");
1809 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1810 rend_client_desc_here(conn
->rend_query
);
1814 /* Not there. We'll retry when
1815 * connection_about_to_close_connection() cleans this conn up. */
1816 log_info(LD_REND
,"Fetching v2 rendezvous descriptor failed: "
1817 "Retrying at another directory.");
1820 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
1821 "http status 400 (%s). Dirserver didn't like our "
1822 "v2 rendezvous query? Retrying at another directory.",
1826 log_warn(LD_REND
, "Fetching v2 rendezvous descriptor failed: "
1827 "http status %d (%s) response unexpected while "
1828 "fetching v2 hidden service descriptor (server '%s:%d'). "
1829 "Retrying at another directory.",
1830 status_code
, escaped(reason
), conn
->_base
.address
,
1836 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC
||
1837 conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC_V2
) {
1838 log_info(LD_REND
,"Uploaded rendezvous descriptor (status %d "
1840 status_code
, escaped(reason
));
1841 switch (status_code
) {
1844 "Uploading rendezvous descriptor: finished with status "
1845 "200 (%s)", escaped(reason
));
1848 log_warn(LD_REND
,"http status 400 (%s) response from dirserver "
1849 "'%s:%d'. Malformed rendezvous descriptor?",
1850 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1853 log_info(LD_REND
,"http status 503 (%s) response from dirserver "
1854 "'%s:%d'. Node is (currently) not acting as v2 hidden "
1855 "service directory.",
1856 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1859 log_warn(LD_REND
,"http status %d (%s) response unexpected (server "
1861 status_code
, escaped(reason
), conn
->_base
.address
,
1866 tor_free(body
); tor_free(headers
); tor_free(reason
);
1870 /** Called when a directory connection reaches EOF */
1872 connection_dir_reached_eof(dir_connection_t
*conn
)
1875 if (conn
->_base
.state
!= DIR_CONN_STATE_CLIENT_READING
) {
1876 log_info(LD_HTTP
,"conn reached eof, not reading. [state=%d] Closing.",
1878 connection_close_immediate(TO_CONN(conn
)); /* error: give up on flushing */
1879 connection_mark_for_close(TO_CONN(conn
));
1883 retval
= connection_dir_client_reached_eof(conn
);
1884 if (retval
== 0) /* success */
1885 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_FINISHED
;
1886 connection_mark_for_close(TO_CONN(conn
));
1890 /** If any directory object is arriving, and it's over 10MB large, we're
1891 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
1892 * ask for more than 96 router descriptors at a time.)
1894 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
1896 /** Read handler for directory connections. (That's connections <em>to</em>
1897 * directory servers and connections <em>at</em> directory servers.)
1900 connection_dir_process_inbuf(dir_connection_t
*conn
)
1903 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
1905 /* Directory clients write, then read data until they receive EOF;
1906 * directory servers read data until they get an HTTP command, then
1907 * write their response (when it's finished flushing, they mark for
1911 /* If we're on the dirserver side, look for a command. */
1912 if (conn
->_base
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
1913 if (directory_handle_command(conn
) < 0) {
1914 connection_mark_for_close(TO_CONN(conn
));
1920 if (buf_datalen(conn
->_base
.inbuf
) > MAX_DIRECTORY_OBJECT_SIZE
) {
1921 log_warn(LD_HTTP
, "Too much data received from directory connection: "
1922 "denial of service attempt, or you need to upgrade?");
1923 connection_mark_for_close(TO_CONN(conn
));
1927 if (!conn
->_base
.inbuf_reached_eof
)
1928 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
1932 /** Create an http response for the client <b>conn</b> out of
1933 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
1936 write_http_status_line(dir_connection_t
*conn
, int status
,
1937 const char *reason_phrase
)
1940 if (tor_snprintf(buf
, sizeof(buf
), "HTTP/1.0 %d %s\r\n\r\n",
1941 status
, reason_phrase
? reason_phrase
: "OK") < 0) {
1942 log_warn(LD_BUG
,"status line too long.");
1945 connection_write_to_buf(buf
, strlen(buf
), TO_CONN(conn
));
1948 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
1949 * with <b>type</b> as the Content-Type.
1951 * If <b>length</b> is nonnegative, it is the Content-Length.
1952 * If <b>encoding</b> is provided, it is the Content-Encoding.
1953 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
1954 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
1956 write_http_response_header_impl(dir_connection_t
*conn
, ssize_t length
,
1957 const char *type
, const char *encoding
,
1958 const char *extra_headers
,
1961 char date
[RFC1123_TIME_LEN
+1];
1964 time_t now
= time(NULL
);
1968 format_rfc1123_time(date
, now
);
1970 tor_snprintf(cp
, sizeof(tmp
),
1971 "HTTP/1.0 200 OK\r\nDate: %s\r\n",
1975 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
), "Content-Type: %s\r\n", type
);
1978 if (!is_internal_IP(conn
->_base
.addr
, 0)) {
1979 /* Don't report the source address for a localhost/private connection. */
1980 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1981 X_ADDRESS_HEADER
"%s\r\n", conn
->_base
.address
);
1985 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1986 "Content-Encoding: %s\r\n", encoding
);
1990 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1991 "Content-Length: %ld\r\n", (long)length
);
1994 if (cache_lifetime
> 0) {
1995 char expbuf
[RFC1123_TIME_LEN
+1];
1996 format_rfc1123_time(expbuf
, now
+ cache_lifetime
);
1997 /* We could say 'Cache-control: max-age=%d' here if we start doing
1999 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
2000 "Expires: %s\r\n", expbuf
);
2002 } else if (cache_lifetime
== 0) {
2003 /* We could say 'Cache-control: no-cache' here if we start doing
2005 strlcpy(cp
, "Pragma: no-cache\r\n", sizeof(tmp
)-(cp
-tmp
));
2009 strlcpy(cp
, extra_headers
, sizeof(tmp
)-(cp
-tmp
));
2010 if (sizeof(tmp
)-(cp
-tmp
) > 3)
2011 memcpy(cp
, "\r\n", 3);
2014 connection_write_to_buf(tmp
, strlen(tmp
), TO_CONN(conn
));
2017 /** As write_http_response_header_impl, but sets encoding and content-typed
2018 * based on whether the response will be <b>deflated</b> or not. */
2020 write_http_response_header(dir_connection_t
*conn
, ssize_t length
,
2021 int deflated
, int cache_lifetime
)
2023 write_http_response_header_impl(conn
, length
,
2024 deflated
?"application/octet-stream":"text/plain",
2025 deflated
?"deflate":"identity",
2030 /** Helper function: return 1 if there are any dir conns of purpose
2031 * <b>purpose</b> that are going elsewhere than our own ORPort/Dirport.
2035 already_fetching_directory(int purpose
)
2037 smartlist_t
*conns
= get_connection_array();
2038 SMARTLIST_FOREACH(conns
, connection_t
*, conn
,
2040 if (conn
->type
== CONN_TYPE_DIR
&&
2041 conn
->purpose
== purpose
&&
2042 !conn
->marked_for_close
&&
2043 !router_digest_is_me(TO_DIR_CONN(conn
)->identity_digest
))
2049 #ifdef INSTRUMENT_DOWNLOADS
2050 /** Map used to keep track of how much data we've up/downloaded in what kind
2051 * of request. Maps from request type to pointer to uint64_t. */
2052 static strmap_t
*request_bytes_map
= NULL
;
2054 /** Called when we just transmitted or received <b>bytes</b> worth of data
2055 * because of a request of type <b>key</b> (an arbitrary identifier): adds
2056 * <b>bytes</b> to the total associated with key. */
2058 note_request(const char *key
, size_t bytes
)
2061 if (!request_bytes_map
)
2062 request_bytes_map
= strmap_new();
2064 n
= strmap_get(request_bytes_map
, key
);
2066 n
= tor_malloc_zero(sizeof(uint64_t));
2067 strmap_set(request_bytes_map
, key
, n
);
2072 /** Return a newly allocated string holding a summary of bytes used per
2075 directory_dump_request_log(void)
2080 strmap_iter_t
*iter
;
2082 if (!request_bytes_map
)
2083 request_bytes_map
= strmap_new();
2085 lines
= smartlist_create();
2087 for (iter
= strmap_iter_init(request_bytes_map
);
2088 !strmap_iter_done(iter
);
2089 iter
= strmap_iter_next(request_bytes_map
, iter
)) {
2093 strmap_iter_get(iter
, &key
, &val
);
2095 tor_snprintf(tmp
, sizeof(tmp
), "%s "U64_FORMAT
"\n",
2096 key
, U64_PRINTF_ARG(*n
));
2097 smartlist_add(lines
, tor_strdup(tmp
));
2099 smartlist_sort_strings(lines
);
2100 result
= smartlist_join_strings(lines
, "", 0, NULL
);
2101 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
2102 smartlist_free(lines
);
2107 note_request(const char *key
, size_t bytes
)
2114 directory_dump_request_log(void)
2116 return tor_strdup("Not supported.");
2120 /** Helper function: called when a dirserver gets a complete HTTP GET
2121 * request. Look for a request for a directory or for a rendezvous
2122 * service descriptor. On finding one, write a response into
2123 * conn-\>outbuf. If the request is unrecognized, send a 400.
2124 * Always return 0. */
2126 directory_handle_command_get(dir_connection_t
*conn
, const char *headers
,
2127 const char *body
, size_t body_len
)
2130 char *url
, *url_mem
, *header
;
2131 or_options_t
*options
= get_options();
2132 time_t if_modified_since
= 0;
2136 /* We ignore the body of a GET request. */
2140 log_debug(LD_DIRSERV
,"Received GET command.");
2142 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2144 if (parse_http_url(headers
, &url
) < 0) {
2145 write_http_status_line(conn
, 400, "Bad request");
2148 if ((header
= http_get_header(headers
, "If-Modified-Since: "))) {
2150 if (parse_http_time(header
, &tm
) == 0) {
2151 if_modified_since
= tor_timegm(&tm
);
2153 /* The correct behavior on a malformed If-Modified-Since header is to
2154 * act as if no If-Modified-Since header had been given. */
2157 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2160 url_len
= strlen(url
);
2161 deflated
= url_len
> 2 && !strcmp(url
+url_len
-2, ".z");
2163 url
[url_len
-2] = '\0';
2167 if (!strcmp(url
,"/tor/") || !strcmp(url
,"/tor/dir")) { /* dir fetch */
2168 cached_dir_t
*d
= dirserv_get_directory();
2171 log_notice(LD_DIRSERV
,"Client asked for the mirrored directory, but we "
2172 "don't have a good one yet. Sending 503 Dir not available.");
2173 write_http_status_line(conn
, 503, "Directory unavailable");
2174 /* try to get a new one now */
2175 if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR
) &&
2176 !should_delay_dir_fetches(options
))
2177 directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR
,
2178 ROUTER_PURPOSE_GENERAL
, NULL
, 1);
2181 if (d
->published
< if_modified_since
) {
2182 write_http_status_line(conn
, 304, "Not modified");
2186 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
2188 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
2189 log_info(LD_DIRSERV
,
2190 "Client asked for the mirrored directory, but we've been "
2191 "writing too many bytes lately. Sending 503 Dir busy.");
2192 write_http_status_line(conn
, 503, "Directory busy, try again later");
2196 note_request(url
, dlen
);
2198 log_debug(LD_DIRSERV
,"Dumping %sdirectory to client.",
2199 deflated
?"deflated ":"");
2200 write_http_response_header(conn
, dlen
, deflated
,
2201 FULL_DIR_CACHE_LIFETIME
);
2202 conn
->cached_dir
= d
;
2203 conn
->cached_dir_offset
= 0;
2205 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2208 /* Prime the connection with some data. */
2209 conn
->dir_spool_src
= DIR_SPOOL_CACHED_DIR
;
2210 connection_dirserv_flushed_some(conn
);
2214 if (!strcmp(url
,"/tor/running-routers")) { /* running-routers fetch */
2215 cached_dir_t
*d
= dirserv_get_runningrouters();
2217 write_http_status_line(conn
, 503, "Directory unavailable");
2218 /* try to get a new one now */
2219 if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST
) &&
2220 !should_delay_dir_fetches(options
))
2221 directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST
,
2222 ROUTER_PURPOSE_GENERAL
, NULL
, 1);
2225 if (d
->published
< if_modified_since
) {
2226 write_http_status_line(conn
, 304, "Not modified");
2229 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
2231 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
2232 log_info(LD_DIRSERV
,
2233 "Client asked for running-routers, but we've been "
2234 "writing too many bytes lately. Sending 503 Dir busy.");
2235 write_http_status_line(conn
, 503, "Directory busy, try again later");
2238 note_request(url
, dlen
);
2239 write_http_response_header(conn
, dlen
, deflated
,
2240 RUNNINGROUTERS_CACHE_LIFETIME
);
2241 connection_write_to_buf(deflated
? d
->dir_z
: d
->dir
, dlen
, TO_CONN(conn
));
2245 if (!strcmpstart(url
,"/tor/status/")
2246 || !strcmp(url
, "/tor/status-vote/current/consensus")) {
2247 /* v2 or v3 network status fetch. */
2248 smartlist_t
*dir_fps
= smartlist_create();
2249 int is_v3
= !strcmpstart(url
, "/tor/status-vote");
2250 const char *request_type
= NULL
;
2251 const char *key
= url
+ strlen("/tor/status/");
2252 int lifetime
= NETWORKSTATUS_CACHE_LIFETIME
;
2254 dirserv_get_networkstatus_v2_fingerprints(dir_fps
, key
);
2255 if (!strcmpstart(key
, "fp/"))
2256 request_type
= deflated
?"/tor/status/fp.z":"/tor/status/fp";
2257 else if (!strcmpstart(key
, "authority"))
2258 request_type
= deflated
?"/tor/status/authority.z":
2259 "/tor/status/authority";
2260 else if (!strcmpstart(key
, "all"))
2261 request_type
= deflated
?"/tor/status/all.z":"/tor/status/all";
2263 request_type
= "/tor/status/?";
2265 networkstatus_vote_t
*v
= networkstatus_get_latest_consensus();
2266 time_t now
= time(NULL
);
2267 smartlist_add(dir_fps
, tor_memdup("\0\0\0\0\0\0\0\0\0\0"
2268 "\0\0\0\0\0\0\0\0\0\0", 20));
2269 request_type
= deflated
?"v3.z":"v3";
2270 lifetime
= (v
&& v
->fresh_until
> now
) ? v
->fresh_until
- now
: 0;
2273 if (!smartlist_len(dir_fps
)) { /* we failed to create/cache cp */
2274 write_http_status_line(conn
, 503, "Network status object unavailable");
2275 smartlist_free(dir_fps
);
2279 if (!dirserv_remove_old_statuses(dir_fps
, if_modified_since
)) {
2280 write_http_status_line(conn
, 404, "Not found");
2281 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2282 smartlist_free(dir_fps
);
2284 } else if (!smartlist_len(dir_fps
)) {
2285 write_http_status_line(conn
, 304, "Not modified");
2286 SMARTLIST_FOREACH(dir_fps
, char *, cp
, tor_free(cp
));
2287 smartlist_free(dir_fps
);
2291 dlen
= dirserv_estimate_data_size(dir_fps
, 0, deflated
);
2292 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2293 log_info(LD_DIRSERV
,
2294 "Client asked for network status lists, but we've been "
2295 "writing too many bytes lately. Sending 503 Dir busy.");
2296 write_http_status_line(conn
, 503, "Directory busy, try again later");
2297 SMARTLIST_FOREACH(dir_fps
, char *, fp
, tor_free(fp
));
2298 smartlist_free(dir_fps
);
2302 // note_request(request_type,dlen);
2303 (void) request_type
;
2304 write_http_response_header(conn
, -1, deflated
,
2305 smartlist_len(dir_fps
) == 1 ? lifetime
: 0);
2306 conn
->fingerprint_stack
= dir_fps
;
2308 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
2310 /* Prime the connection with some data. */
2311 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
2312 connection_dirserv_flushed_some(conn
);
2316 if (!strcmpstart(url
,"/tor/status-vote/current/") ||
2317 !strcmpstart(url
,"/tor/status-vote/next/")) {
2318 /* XXXX If-modified-since is only implemented for the current
2319 * consensus: that's probably fine, since it's the only vote document
2320 * people fetch much.*/
2322 ssize_t body_len
= 0;
2323 ssize_t estimated_len
= 0;
2324 smartlist_t
*items
= smartlist_create();
2325 smartlist_t
*dir_items
= smartlist_create();
2326 int lifetime
= 60; /* XXXX020 should actually use vote intervals. */
2327 url
+= strlen("/tor/status-vote/");
2328 current
= !strcmpstart(url
, "current/");
2329 url
= strchr(url
, '/');
2332 if (!strcmp(url
, "consensus")) {
2334 tor_assert(!current
); /* we handle current consensus specially above,
2335 * since it wants to be spooled. */
2336 if ((item
= dirvote_get_pending_consensus()))
2337 smartlist_add(items
, (char*)item
);
2338 } else if (!current
&& !strcmp(url
, "consensus-signatures")) {
2339 /* XXXX020 the spec says that we should implement
2340 * current/consensus-signatures too. Why? -NM */
2342 if ((item
=dirvote_get_pending_detached_signatures()))
2343 smartlist_add(items
, (char*)item
);
2344 } else if (!strcmp(url
, "authority")) {
2345 const cached_dir_t
*d
;
2346 int flags
= DGV_BY_ID
|
2347 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2348 if ((d
=dirvote_get_vote(NULL
, flags
)))
2349 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2351 const cached_dir_t
*d
;
2352 smartlist_t
*fps
= smartlist_create();
2354 if (!strcmpstart(url
, "d/")) {
2356 flags
= DGV_INCLUDE_PENDING
| DGV_INCLUDE_PREVIOUS
;
2359 (current
? DGV_INCLUDE_PREVIOUS
: DGV_INCLUDE_PENDING
);
2361 dir_split_resource_into_fingerprints(url
, fps
, NULL
, 1, 1);
2362 SMARTLIST_FOREACH(fps
, char *, fp
, {
2363 if ((d
= dirvote_get_vote(fp
, flags
)))
2364 smartlist_add(dir_items
, (cached_dir_t
*)d
);
2367 smartlist_free(fps
);
2369 if (!smartlist_len(dir_items
) && !smartlist_len(items
)) {
2370 write_http_status_line(conn
, 404, "Not found");
2373 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2374 body_len
+= deflated
? d
->dir_z_len
: d
->dir_len
);
2375 estimated_len
+= body_len
;
2376 SMARTLIST_FOREACH(items
, const char *, item
, {
2377 size_t ln
= strlen(item
);
2379 body_len
+= ln
; estimated_len
+= ln
;
2381 estimated_len
+= ln
/2;
2385 if (global_write_bucket_low(TO_CONN(conn
), estimated_len
, 1)) {
2386 write_http_status_line(conn
, 503, "Directory busy, try again later.");
2389 write_http_response_header(conn
, body_len
? body_len
: -1, deflated
,
2392 if (smartlist_len(items
)) {
2394 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2395 SMARTLIST_FOREACH(items
, const char *, c
,
2396 connection_write_to_buf_zlib(c
, strlen(c
), conn
, 0));
2397 connection_write_to_buf_zlib("", 0, conn
, 1);
2399 SMARTLIST_FOREACH(items
, const char *, c
,
2400 connection_write_to_buf(c
, strlen(c
), TO_CONN(conn
)));
2403 SMARTLIST_FOREACH(dir_items
, cached_dir_t
*, d
,
2404 connection_write_to_buf(deflated
? d
->dir_z
: d
->dir
,
2405 deflated
? d
->dir_z_len
: d
->dir_len
,
2409 smartlist_free(items
);
2410 smartlist_free(dir_items
);
2414 if (!strcmpstart(url
,"/tor/server/") ||
2415 !strcmpstart(url
,"/tor/extra/")) {
2418 const char *request_type
= NULL
;
2419 int cache_lifetime
= 0;
2420 int is_extra
= !strcmpstart(url
,"/tor/extra/");
2421 url
+= is_extra
? strlen("/tor/extra/") : strlen("/tor/server/");
2422 conn
->fingerprint_stack
= smartlist_create();
2423 res
= dirserv_get_routerdesc_fingerprints(conn
->fingerprint_stack
, url
,
2425 !connection_dir_is_encrypted(conn
));
2427 if (!strcmpstart(url
, "fp/")) {
2428 request_type
= deflated
?"/tor/server/fp.z":"/tor/server/fp";
2429 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2430 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2431 } else if (!strcmpstart(url
, "authority")) {
2432 request_type
= deflated
?"/tor/server/authority.z":
2433 "/tor/server/authority";
2434 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
2435 } else if (!strcmpstart(url
, "all")) {
2436 request_type
= deflated
?"/tor/server/all.z":"/tor/server/all";
2437 cache_lifetime
= FULL_DIR_CACHE_LIFETIME
;
2438 } else if (!strcmpstart(url
, "d/")) {
2439 request_type
= deflated
?"/tor/server/d.z":"/tor/server/d";
2440 if (smartlist_len(conn
->fingerprint_stack
) == 1)
2441 cache_lifetime
= ROUTERDESC_BY_DIGEST_CACHE_LIFETIME
;
2443 request_type
= "/tor/server/?";
2445 (void) request_type
; /* usable for note_request. */
2446 if (!strcmpstart(url
, "d/"))
2447 conn
->dir_spool_src
=
2448 is_extra
? DIR_SPOOL_EXTRA_BY_DIGEST
: DIR_SPOOL_SERVER_BY_DIGEST
;
2450 conn
->dir_spool_src
=
2451 is_extra
? DIR_SPOOL_EXTRA_BY_FP
: DIR_SPOOL_SERVER_BY_FP
;
2453 if (!dirserv_have_any_serverdesc(conn
->fingerprint_stack
,
2454 conn
->dir_spool_src
)) {
2460 write_http_status_line(conn
, 404, msg
);
2462 dlen
= dirserv_estimate_data_size(conn
->fingerprint_stack
,
2464 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
2465 log_info(LD_DIRSERV
,
2466 "Client asked for server descriptors, but we've been "
2467 "writing too many bytes lately. Sending 503 Dir busy.");
2468 write_http_status_line(conn
, 503, "Directory busy, try again later");
2469 conn
->dir_spool_src
= DIR_SPOOL_NONE
;
2472 write_http_response_header(conn
, -1, deflated
, cache_lifetime
);
2474 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2475 /* Prime the connection with some data. */
2476 connection_dirserv_flushed_some(conn
);
2481 if (!strcmpstart(url
,"/tor/keys/")) {
2482 smartlist_t
*certs
= smartlist_create();
2484 if (!strcmp(url
, "/tor/keys/all")) {
2485 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
2486 trusted_dir_server_t
*, ds
,
2490 SMARTLIST_FOREACH(ds
->v3_certs
, authority_cert_t
*, cert
,
2491 smartlist_add(certs
, cert
));
2493 } else if (!strcmp(url
, "/tor/keys/authority")) {
2494 authority_cert_t
*cert
= get_my_v3_authority_cert();
2496 smartlist_add(certs
, cert
);
2497 } else if (!strcmpstart(url
, "/tor/keys/fp/")) {
2498 smartlist_t
*fps
= smartlist_create();
2499 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/fp/"),
2501 SMARTLIST_FOREACH(fps
, char *, d
, {
2502 authority_cert_t
*c
= authority_cert_get_newest_by_id(d
);
2503 if (c
) smartlist_add(certs
, c
);
2506 smartlist_free(fps
);
2507 } else if (!strcmpstart(url
, "/tor/keys/sk/")) {
2508 smartlist_t
*fps
= smartlist_create();
2509 dir_split_resource_into_fingerprints(url
+strlen("/tor/keys/sk/"),
2511 SMARTLIST_FOREACH(fps
, char *, d
, {
2512 authority_cert_t
*c
= authority_cert_get_by_sk_digest(d
);
2513 if (c
) smartlist_add(certs
, c
);
2516 smartlist_free(fps
);
2518 write_http_status_line(conn
, 400, "Bad request");
2521 if (!smartlist_len(certs
)) {
2522 write_http_status_line(conn
, 404, "Not found");
2525 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2526 if (c
->cache_info
.published_on
< if_modified_since
)
2527 SMARTLIST_DEL_CURRENT(certs
, c
));
2528 if (!smartlist_len(certs
)) {
2529 write_http_status_line(conn
, 304, "Not modified");
2533 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2534 len
+= c
->cache_info
.signed_descriptor_len
);
2536 if (global_write_bucket_low(TO_CONN(conn
), deflated
?len
/2:len
, 1)) {
2537 write_http_status_line(conn
, 503, "Directory busy, try again later.");
2541 write_http_response_header(conn
, deflated
?-1:len
, deflated
, 60*60);
2543 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
2544 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2545 connection_write_to_buf_zlib(c
->cache_info
.signed_descriptor_body
,
2546 c
->cache_info
.signed_descriptor_len
,
2548 connection_write_to_buf_zlib("", 0, conn
, 1);
2550 SMARTLIST_FOREACH(certs
, authority_cert_t
*, c
,
2551 connection_write_to_buf(c
->cache_info
.signed_descriptor_body
,
2552 c
->cache_info
.signed_descriptor_len
,
2556 smartlist_free(certs
);
2560 if (options
->HidServDirectoryV2
&&
2561 !strcmpstart(url
,"/tor/rendezvous2/")) {
2562 /* Handle v2 rendezvous descriptor fetch request. */
2564 const char *query
= url
+ strlen("/tor/rendezvous2/");
2565 if (strlen(query
) == REND_DESC_ID_V2_LEN_BASE32
) {
2566 log_info(LD_REND
, "Got a v2 rendezvous descriptor request for ID '%s'",
2568 switch (rend_cache_lookup_v2_desc_as_dir(query
, &descp
)) {
2570 write_http_response_header(conn
, strlen(descp
), 0, 0);
2571 connection_write_to_buf(descp
, strlen(descp
), TO_CONN(conn
));
2573 case 0: /* well-formed but not present */
2574 write_http_status_line(conn
, 404, "Not found");
2576 case -1: /* not well-formed */
2577 write_http_status_line(conn
, 400, "Bad request");
2580 } else { /* not well-formed */
2581 write_http_status_line(conn
, 400, "Bad request");
2586 if (options
->HSAuthoritativeDir
&& !strcmpstart(url
,"/tor/rendezvous/")) {
2587 /* rendezvous descriptor fetch */
2590 const char *query
= url
+strlen("/tor/rendezvous/");
2592 log_info(LD_REND
, "Handling rendezvous descriptor get");
2593 switch (rend_cache_lookup_desc(query
, 0, &descp
, &desc_len
)) {
2595 write_http_response_header_impl(conn
, desc_len
,
2596 "application/octet-stream",
2598 note_request("/tor/rendezvous?/", desc_len
);
2599 /* need to send descp separately, because it may include nuls */
2600 connection_write_to_buf(descp
, desc_len
, TO_CONN(conn
));
2601 /* report successful fetch to statistic */
2602 if (options
->HSAuthorityRecordStats
) {
2603 hs_usage_note_fetch_total(query
, time(NULL
));
2604 hs_usage_note_fetch_successful(query
, time(NULL
));
2607 case 0: /* well-formed but not present */
2608 write_http_status_line(conn
, 404, "Not found");
2609 /* report (unsuccessful) fetch to statistic */
2610 if (options
->HSAuthorityRecordStats
) {
2611 hs_usage_note_fetch_total(query
, time(NULL
));
2614 case -1: /* not well-formed */
2615 write_http_status_line(conn
, 400, "Bad request");
2621 if (options
->BridgeAuthoritativeDir
&&
2622 options
->BridgePassword
&&
2623 connection_dir_is_encrypted(conn
) &&
2624 !strcmp(url
,"/tor/networkstatus-bridges")) {
2630 header
= http_get_header(headers
, "Authorization: Basic ");
2633 write_http_status_line(conn
, 404, "Not found");
2637 /* now make sure the password is right */
2638 r
= base64_decode(decoded
, sizeof(decoded
), header
, strlen(header
));
2639 secret
= alloc_http_authenticator(options
->BridgePassword
);
2640 if (r
< 0 || (unsigned)r
!= strlen(secret
) || memcmp(decoded
, secret
, r
)) {
2641 /* failed to decode, or didn't match. Refuse. */
2642 write_http_status_line(conn
, 404, "Not found");
2648 /* all happy now. send an answer. */
2649 status
= networkstatus_getinfo_by_purpose("bridge", time(NULL
));
2650 dlen
= strlen(status
);
2651 write_http_response_header(conn
, dlen
, 0, 0);
2652 connection_write_to_buf(status
, dlen
, TO_CONN(conn
));
2657 if (!strcmpstart(url
,"/tor/bytes.txt")) {
2658 char *bytes
= directory_dump_request_log();
2659 size_t len
= strlen(bytes
);
2660 write_http_response_header(conn
, len
, 0, 0);
2661 connection_write_to_buf(bytes
, len
, TO_CONN(conn
));
2666 if (!strcmp(url
,"/tor/robots.txt")) { /* /robots.txt will have been
2667 rewritten to /tor/robots.txt */
2668 char robots
[] = "User-agent: *\r\nDisallow: /\r\n";
2669 size_t len
= strlen(robots
);
2670 write_http_response_header(conn
, len
, 0, ROBOTS_CACHE_LIFETIME
);
2671 connection_write_to_buf(robots
, len
, TO_CONN(conn
));
2675 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
2676 #define ADD_MALLINFO_LINE(x) do { \
2677 tor_snprintf(tmp, sizeof(tmp), "%s %d\n", #x, mi.x); \
2678 smartlist_add(lines, tor_strdup(tmp)); \
2681 if (!strcmp(url
,"/tor/mallinfo.txt") &&
2682 (conn
->_base
.addr
== 0x7f000001ul
)) {
2689 memset(&mi
, 0, sizeof(mi
));
2691 lines
= smartlist_create();
2693 ADD_MALLINFO_LINE(arena
)
2694 ADD_MALLINFO_LINE(ordblks
)
2695 ADD_MALLINFO_LINE(smblks
)
2696 ADD_MALLINFO_LINE(hblks
)
2697 ADD_MALLINFO_LINE(hblkhd
)
2698 ADD_MALLINFO_LINE(usmblks
)
2699 ADD_MALLINFO_LINE(fsmblks
)
2700 ADD_MALLINFO_LINE(uordblks
)
2701 ADD_MALLINFO_LINE(fordblks
)
2702 ADD_MALLINFO_LINE(keepcost
)
2704 result
= smartlist_join_strings(lines
, "", 0, NULL
);
2705 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
2706 smartlist_free(lines
);
2708 len
= strlen(result
);
2709 write_http_response_header(conn
, len
, 0, 0);
2710 connection_write_to_buf(result
, len
, TO_CONN(conn
));
2716 /* we didn't recognize the url */
2717 write_http_status_line(conn
, 404, "Not found");
2724 /** Helper function: called when a dirserver gets a complete HTTP POST
2725 * request. Look for an uploaded server descriptor or rendezvous
2726 * service descriptor. On finding one, process it and write a
2727 * response into conn-\>outbuf. If the request is unrecognized, send a
2728 * 400. Always return 0. */
2730 directory_handle_command_post(dir_connection_t
*conn
, const char *headers
,
2731 const char *body
, size_t body_len
)
2734 or_options_t
*options
= get_options();
2736 log_debug(LD_DIRSERV
,"Received POST command.");
2738 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2740 if (parse_http_url(headers
, &url
) < 0) {
2741 write_http_status_line(conn
, 400, "Bad request");
2744 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2746 /* Handle v2 rendezvous service publish request. */
2747 if (options
->HidServDirectoryV2
&&
2748 !strcmpstart(url
,"/tor/rendezvous2/publish")) {
2749 switch (rend_cache_store_v2_desc_as_dir(body
)) {
2751 log_info(LD_REND
, "Rejected v2 rend descriptor (length %d) from %s "
2752 "since we're not currently a hidden service directory.",
2753 (int)body_len
, conn
->_base
.address
);
2754 write_http_status_line(conn
, 503, "Currently not acting as v2 "
2755 "hidden service directory");
2758 log_warn(LD_REND
, "Rejected v2 rend descriptor (length %d) from %s.",
2759 (int)body_len
, conn
->_base
.address
);
2760 write_http_status_line(conn
, 400, "Invalid service descriptor "
2764 write_http_status_line(conn
, 200, "Service descriptor stored");
2765 log_info(LD_REND
, "Handled v2 rendezvous descriptor post: accepted");
2770 if (!authdir_mode(options
)) {
2771 /* we just provide cached directories; we don't want to
2772 * receive anything. */
2773 write_http_status_line(conn
, 400, "Nonauthoritative directory does not "
2774 "accept posted server descriptors");
2778 if (authdir_mode_handles_descs(options
, -1) &&
2779 !strcmp(url
,"/tor/")) { /* server descriptor post */
2780 const char *msg
= NULL
;
2781 uint8_t purpose
= authdir_mode_bridge(options
) ?
2782 ROUTER_PURPOSE_BRIDGE
: ROUTER_PURPOSE_GENERAL
;
2783 int r
= dirserv_add_multiple_descriptors(body
, purpose
,
2784 conn
->_base
.address
, &msg
);
2787 dirserv_get_directory(); /* rebuild and write to disk */
2790 log_notice(LD_DIRSERV
,
2791 "Rejected router descriptor or extra-info from %s "
2793 conn
->_base
.address
, msg
);
2796 /* malformed descriptor, or something wrong */
2797 write_http_status_line(conn
, 400, msg
);
2799 case 0: /* accepted but discarded */
2800 write_http_response_header_impl(conn
, -1, NULL
, NULL
,
2801 "X-Descriptor-Not-New: Yes\r\n", -1);
2803 case 2: /* accepted */
2804 write_http_status_line(conn
, 200, msg
);
2810 if (options
->HSAuthoritativeDir
&&
2811 !strcmpstart(url
,"/tor/rendezvous/publish")) {
2812 /* rendezvous descriptor post */
2813 log_info(LD_REND
, "Handling rendezvous descriptor post.");
2814 if (rend_cache_store(body
, body_len
, 1) < 0) {
2815 log_fn(LOG_PROTOCOL_WARN
, LD_DIRSERV
,
2816 "Rejected rend descriptor (length %d) from %s.",
2817 (int)body_len
, conn
->_base
.address
);
2818 write_http_status_line(conn
, 400, "Invalid service descriptor rejected");
2820 write_http_status_line(conn
, 200, "Service descriptor stored");
2825 if (authdir_mode_v3(options
) &&
2826 !strcmp(url
,"/tor/post/vote")) { /* v3 networkstatus vote */
2827 const char *msg
= "OK";
2829 if (dirvote_add_vote(body
, &msg
, &status
)) {
2830 write_http_status_line(conn
, status
, "Vote stored");
2833 write_http_status_line(conn
, status
, msg
);
2838 if (authdir_mode_v3(options
) &&
2839 !strcmp(url
,"/tor/post/consensus-signature")) { /* sigs on consensus. */
2840 const char *msg
= NULL
;
2841 if (dirvote_add_signatures(body
, conn
->_base
.address
, &msg
)>=0) {
2842 write_http_status_line(conn
, 200, msg
?msg
:"Signatures stored");
2844 log_warn(LD_DIR
, "Unable to store signatures posted by %s: %s",
2845 conn
->_base
.address
, msg
?msg
:"???");
2846 write_http_status_line(conn
, 400, msg
?msg
:"Unable to store signatures");
2851 /* we didn't recognize the url */
2852 write_http_status_line(conn
, 404, "Not found");
2859 /** Called when a dirserver receives data on a directory connection;
2860 * looks for an HTTP request. If the request is complete, remove it
2861 * from the inbuf, try to process it; otherwise, leave it on the
2862 * buffer. Return a 0 on success, or -1 on error.
2865 directory_handle_command(dir_connection_t
*conn
)
2867 char *headers
=NULL
, *body
=NULL
;
2872 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2874 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
2875 &headers
, MAX_HEADERS_SIZE
,
2876 &body
, &body_len
, MAX_DIR_UL_SIZE
, 0)) {
2877 case -1: /* overflow */
2878 log_warn(LD_DIRSERV
,
2879 "Invalid input from address '%s'. Closing.",
2880 conn
->_base
.address
);
2883 log_debug(LD_DIRSERV
,"command not all here yet.");
2885 /* case 1, fall through */
2888 http_set_address_origin(headers
, TO_CONN(conn
));
2889 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
2891 if (!strncasecmp(headers
,"GET",3))
2892 r
= directory_handle_command_get(conn
, headers
, body
, body_len
);
2893 else if (!strncasecmp(headers
,"POST",4))
2894 r
= directory_handle_command_post(conn
, headers
, body
, body_len
);
2896 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
2897 "Got headers %s with unknown command. Closing.",
2902 tor_free(headers
); tor_free(body
);
2906 /** Write handler for directory connections; called when all data has
2907 * been flushed. Close the connection or wait for a response as
2911 connection_dir_finished_flushing(dir_connection_t
*conn
)
2914 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2916 switch (conn
->_base
.state
) {
2917 case DIR_CONN_STATE_CLIENT_SENDING
:
2918 log_debug(LD_DIR
,"client finished sending command.");
2919 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_READING
;
2920 connection_stop_writing(TO_CONN(conn
));
2922 case DIR_CONN_STATE_SERVER_WRITING
:
2923 log_debug(LD_DIRSERV
,"Finished writing server response. Closing.");
2924 connection_mark_for_close(TO_CONN(conn
));
2927 log_warn(LD_BUG
,"called in unexpected state %d.",
2929 tor_fragile_assert();
2935 /** Connected handler for directory connections: begin sending data to the
2938 connection_dir_finished_connecting(dir_connection_t
*conn
)
2941 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2942 tor_assert(conn
->_base
.state
== DIR_CONN_STATE_CONNECTING
);
2944 log_debug(LD_HTTP
,"Dir connection to router %s:%u established.",
2945 conn
->_base
.address
,conn
->_base
.port
);
2947 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
; /* start flushing conn */
2951 /** Called when one or more networkstatus fetches have failed (with uppercase
2952 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
2953 * failed once, unless they failed with status code 503. */
2955 dir_networkstatus_download_failed(smartlist_t
*failed
, int status_code
)
2957 if (status_code
== 503)
2959 SMARTLIST_FOREACH(failed
, const char *, fp
,
2961 char digest
[DIGEST_LEN
];
2962 trusted_dir_server_t
*dir
;
2963 if (base16_decode(digest
, DIGEST_LEN
, fp
, strlen(fp
))<0) {
2964 log_warn(LD_BUG
, "Called with bad fingerprint in list: %s",
2968 dir
= router_get_trusteddirserver_by_digest(digest
);
2971 download_status_failed(&dir
->v2_ns_dl_status
, status_code
);
2975 static const int server_dl_schedule
[] = {
2976 0, 0, 0, 60, 60, 60*2, 60*5, 60*15, INT_MAX
2978 static const int client_dl_schedule
[] = {
2979 0, 0, 60, 60*5, 60*10, INT_MAX
2981 static const int server_consensus_dl_schedule
[] = {
2982 0, 0, 60, 60*5, 60*10, 60*30, 60*30, 60*30, 60*30, 60*30, 60*60, 60*60*2
2984 static const int client_consensus_dl_schedule
[] = {
2985 0, 0, 60, 60*5, 60*10, 60*30, 60*60, 60*60, 60*60, 60*60*3, 60*60*6, 60*60*12
2988 /** Called when an attempt to download <b>dls</b> has failed with HTTP status
2989 * <b>status_code</b>. Increment the failure count (if the code indicates a
2990 * real failure) and set <b>dls<b>->next_attempt_at to an appropriate time in
2993 download_status_increment_failure(download_status_t
*dls
, int status_code
,
2994 const char *item
, int server
, time_t now
)
2996 const int *schedule
;
3000 if (status_code
!= 503 || server
)
3001 ++dls
->n_download_failures
;
3003 switch (dls
->schedule
) {
3004 case DL_SCHED_GENERIC
:
3006 schedule
= server_dl_schedule
;
3007 schedule_len
= sizeof(server_dl_schedule
)/sizeof(int);
3009 schedule
= client_dl_schedule
;
3010 schedule_len
= sizeof(client_dl_schedule
)/sizeof(int);
3013 case DL_SCHED_CONSENSUS
:
3015 schedule
= server_consensus_dl_schedule
;
3016 schedule_len
= sizeof(server_consensus_dl_schedule
)/sizeof(int);
3018 schedule
= client_consensus_dl_schedule
;
3019 schedule_len
= sizeof(client_consensus_dl_schedule
)/sizeof(int);
3026 if (dls
->n_download_failures
< schedule_len
)
3027 increment
= schedule
[dls
->n_download_failures
];
3029 increment
= schedule
[schedule_len
-1];
3031 if (increment
< INT_MAX
)
3032 dls
->next_attempt_at
= now
+increment
;
3034 dls
->next_attempt_at
= TIME_MAX
;
3037 if (dls
->next_attempt_at
== 0)
3038 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again immediately.",
3039 item
, (int)dls
->n_download_failures
);
3040 else if (dls
->next_attempt_at
< TIME_MAX
)
3041 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again in %d seconds.",
3042 item
, (int)dls
->n_download_failures
,
3043 (int)(dls
->next_attempt_at
-now
));
3045 log_debug(LD_DIR
, "%s failed %d time(s); Giving up for a while.",
3046 item
, (int)dls
->n_download_failures
);
3048 return dls
->next_attempt_at
;
3051 /** Reset <b>dls</b> so that it will be considered downloadable
3054 download_status_reset(download_status_t
*dls
)
3056 dls
->n_download_failures
= 0;
3057 dls
->next_attempt_at
= 0;
3060 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
3061 * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
3062 * either as descriptor digests or as identity digests based on
3063 * <b>was_descriptor_digests</b>).
3066 dir_routerdesc_download_failed(smartlist_t
*failed
, int status_code
,
3068 int was_extrainfo
, int was_descriptor_digests
)
3070 char digest
[DIGEST_LEN
];
3071 time_t now
= time(NULL
);
3072 int server
= directory_fetches_from_authorities(get_options());
3073 if (!was_descriptor_digests
) {
3074 if (router_purpose
== ROUTER_PURPOSE_BRIDGE
) {
3075 tor_assert(!was_extrainfo
); /* not supported yet */
3076 SMARTLIST_FOREACH(failed
, const char *, cp
,
3078 if (base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
))<0) {
3079 log_warn(LD_BUG
, "Malformed fingerprint in list: %s",
3083 retry_bridge_descriptor_fetch_directly(digest
);
3086 return; /* FFFF should implement for other-than-router-purpose someday */
3088 SMARTLIST_FOREACH(failed
, const char *, cp
,
3090 download_status_t
*dls
= NULL
;
3091 if (base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
)) < 0) {
3092 log_warn(LD_BUG
, "Malformed fingerprint in list: %s", escaped(cp
));
3095 if (was_extrainfo
) {
3096 signed_descriptor_t
*sd
=
3097 router_get_by_extrainfo_digest(digest
);
3099 dls
= &sd
->ei_dl_status
;
3101 dls
= router_get_dl_status_by_descriptor_digest(digest
);
3103 if (!dls
|| dls
->n_download_failures
>= MAX_ROUTERDESC_DOWNLOAD_FAILURES
)
3105 download_status_increment_failure(dls
, status_code
, cp
, server
, now
);
3108 /* No need to relaunch descriptor downloads here: we already do it
3109 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
3112 /** Given a directory <b>resource</b> request, containing zero
3113 * or more strings separated by plus signs, followed optionally by ".z", store
3114 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
3115 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
3116 * decode_hex is true, then delete all elements that aren't hex digests, and
3117 * decode the rest. If sort_uniq is true, then sort the list and remove
3121 dir_split_resource_into_fingerprints(const char *resource
,
3122 smartlist_t
*fp_out
, int *compressed_out
,
3123 int decode_hex
, int sort_uniq
)
3125 smartlist_t
*fp_tmp
= smartlist_create();
3127 smartlist_split_string(fp_tmp
, resource
, "+", 0, 0);
3129 *compressed_out
= 0;
3130 if (smartlist_len(fp_tmp
)) {
3131 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
3132 size_t last_len
= strlen(last
);
3133 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
3134 last
[last_len
-2] = '\0';
3136 *compressed_out
= 1;
3141 char *cp
, *d
= NULL
;
3142 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
3143 cp
= smartlist_get(fp_tmp
, i
);
3144 if (strlen(cp
) != HEX_DIGEST_LEN
) {
3146 "Skipping digest %s with non-standard length.", escaped(cp
));
3147 smartlist_del_keeporder(fp_tmp
, i
--);
3150 d
= tor_malloc_zero(DIGEST_LEN
);
3151 if (base16_decode(d
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
)<0) {
3152 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
3153 smartlist_del_keeporder(fp_tmp
, i
--);
3156 smartlist_set(fp_tmp
, i
, d
);
3164 smartlist_t
*fp_tmp2
= smartlist_create();
3167 smartlist_sort_digests(fp_tmp
);
3169 smartlist_sort_strings(fp_tmp
);
3170 if (smartlist_len(fp_tmp
))
3171 smartlist_add(fp_tmp2
, smartlist_get(fp_tmp
, 0));
3172 for (i
= 1; i
< smartlist_len(fp_tmp
); ++i
) {
3173 char *cp
= smartlist_get(fp_tmp
, i
);
3174 char *last
= smartlist_get(fp_tmp2
, smartlist_len(fp_tmp2
)-1);
3176 if ((decode_hex
&& memcmp(cp
, last
, DIGEST_LEN
))
3177 || (!decode_hex
&& strcasecmp(cp
, last
)))
3178 smartlist_add(fp_tmp2
, cp
);
3182 smartlist_free(fp_tmp
);
3185 smartlist_add_all(fp_out
, fp_tmp
);
3186 smartlist_free(fp_tmp
);
3190 /** Determine the responsible hidden service directories for the
3191 * rend_encoded_v2_service_descriptor_t's in <b>descs</b> and upload them;
3192 * <b>service_id</b> and <b>seconds_valid</b> are only passed for logging
3195 directory_post_to_hs_dir(smartlist_t
*descs
, const char *service_id
,
3199 smartlist_t
*responsible_dirs
;
3200 routerstatus_t
*hs_dir
;
3201 responsible_dirs
= smartlist_create();
3202 for (i
= 0; i
< smartlist_len(descs
); i
++) {
3203 rend_encoded_v2_service_descriptor_t
*desc
= smartlist_get(descs
, i
);
3204 /* Determine responsible dirs. */
3205 if (hid_serv_get_responsible_directories(responsible_dirs
,
3206 desc
->desc_id
) < 0) {
3207 log_warn(LD_REND
, "Could not determine the responsible hidden service "
3208 "directories to post descriptors to.");
3209 smartlist_free(responsible_dirs
);
3212 tor_assert(smartlist_len(responsible_dirs
) ==
3213 REND_NUMBER_OF_CONSECUTIVE_REPLICAS
);
3214 for (j
= 0; j
< REND_NUMBER_OF_CONSECUTIVE_REPLICAS
; j
++) {
3215 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
3216 hs_dir
= smartlist_get(responsible_dirs
, j
);
3217 /* Send publish request. */
3218 directory_initiate_command_routerstatus(hs_dir
,
3219 DIR_PURPOSE_UPLOAD_RENDDESC_V2
,
3220 ROUTER_PURPOSE_GENERAL
,
3221 1, NULL
, desc
->desc_str
,
3222 strlen(desc
->desc_str
), 0);
3223 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
3224 desc
->desc_id
, DIGEST_LEN
);
3225 log_info(LD_REND
, "Sending publish request for v2 descriptor for "
3226 "service '%s' with descriptor ID '%s' with validity "
3227 "of %d seconds to hidden service directory '%s' on "
3235 smartlist_clear(responsible_dirs
);
3237 smartlist_free(responsible_dirs
);
3240 /** The period for which a hidden service directory cannot be queried for
3241 * the same descriptor ID again. */
3242 #define REND_HID_SERV_DIR_REQUERY_PERIOD (15 * 60)
3244 /** Contains the last request times to hidden service directories for
3245 * certain queries; keys are strings consisting of base32-encoded
3246 * hidden service directory identities and base32-encoded descriptor IDs;
3247 * values are pointers to timestamps of the last requests. */
3248 static strmap_t
*last_hid_serv_requests
= NULL
;
3250 /** Look up the last request time to hidden service directory <b>hs_dir</b>
3251 * for descriptor ID <b>desc_id_base32</b>. If <b>set</b> is non-zero,
3252 * assign the current time <b>now</b> and return that. Otherwise, return
3253 * the most recent request time, or 0 if no such request has been sent
3256 lookup_last_hid_serv_request(routerstatus_t
*hs_dir
,
3257 const char *desc_id_base32
, time_t now
, int set
)
3259 char hsdir_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
3260 char hsdir_desc_comb_id
[2 * REND_DESC_ID_V2_LEN_BASE32
+ 1];
3261 time_t *last_request_ptr
;
3262 if (!last_hid_serv_requests
) last_hid_serv_requests
= strmap_new();
3263 base32_encode(hsdir_id_base32
, sizeof(hsdir_id_base32
),
3264 hs_dir
->identity_digest
, DIGEST_LEN
);
3265 tor_snprintf(hsdir_desc_comb_id
, sizeof(hsdir_desc_comb_id
), "%s%s",
3266 hsdir_id_base32
, desc_id_base32
);
3268 last_request_ptr
= tor_malloc_zero(sizeof(time_t *));
3269 *last_request_ptr
= now
;
3270 strmap_set(last_hid_serv_requests
, hsdir_desc_comb_id
, last_request_ptr
);
3272 last_request_ptr
= strmap_get_lc(last_hid_serv_requests
,
3273 hsdir_desc_comb_id
);
3274 return (last_request_ptr
) ? *last_request_ptr
: 0;
3277 /** Clean the history of request times to hidden service directories, so that
3278 * it does not contain requests older than REND_HID_SERV_DIR_REQUERY_PERIOD
3279 * seconds any more. */
3281 directory_clean_last_hid_serv_requests(void)
3283 strmap_iter_t
*iter
;
3284 time_t cutoff
= time(NULL
) - REND_HID_SERV_DIR_REQUERY_PERIOD
;
3285 for (iter
= strmap_iter_init(last_hid_serv_requests
);
3286 !strmap_iter_done(iter
); ) {
3290 strmap_iter_get(iter
, &key
, &val
);
3291 ent
= (time_t *) val
;
3292 if (*ent
< cutoff
) {
3293 iter
= strmap_iter_next_rmv(last_hid_serv_requests
, iter
);
3296 iter
= strmap_iter_next(last_hid_serv_requests
, iter
);
3301 /** Determine the responsible hidden service directories for <b>desc_id</b>
3302 * and fetch the descriptor belonging to that ID from one of them. Only
3303 * send a request to hidden service directories that we did not try within
3304 * the last REND_HID_SERV_DIR_REQUERY_PERIOD seconds; on success, return 1,
3305 * in the case that no hidden service directory is left to ask for the
3306 * descriptor, return 0, and in case of a failure -1. <b>query</b> is only
3307 * passed for pretty log statements. */
3309 directory_get_from_hs_dir(const char *desc_id
, const char *query
)
3311 smartlist_t
*responsible_dirs
= smartlist_create();
3312 smartlist_t
*selectible_dirs
= smartlist_create();
3313 routerstatus_t
*hs_dir
;
3314 char desc_id_base32
[REND_DESC_ID_V2_LEN_BASE32
+ 1];
3315 time_t now
= time(NULL
);
3316 tor_assert(desc_id
);
3318 tor_assert(strlen(query
) == REND_SERVICE_ID_LEN_BASE32
);
3319 /* Determine responsible dirs. */
3320 if (hid_serv_get_responsible_directories(responsible_dirs
, desc_id
) < 0) {
3321 /* XXX020 make this louder once we have some v2hidservs */
3322 log_info(LD_REND
, "Could not determine the responsible hidden service "
3323 "directories to fetch descriptors.");
3324 smartlist_free(responsible_dirs
);
3328 base32_encode(desc_id_base32
, sizeof(desc_id_base32
),
3329 desc_id
, DIGEST_LEN
);
3331 /* Only select those hidden service directories to which we did not send
3332 * a request earlier. */
3333 if (last_hid_serv_requests
) {
3334 /* Clean up request history first. */
3335 directory_clean_last_hid_serv_requests();
3337 SMARTLIST_FOREACH(responsible_dirs
, routerstatus_t
*, dir
, {
3338 time_t last_request
=
3339 lookup_last_hid_serv_request(dir
, desc_id_base32
, 0, 0);
3340 if (!last_request
||
3341 last_request
+ REND_HID_SERV_DIR_REQUERY_PERIOD
< now
)
3342 smartlist_add(selectible_dirs
, dir
);
3345 smartlist_add_all(selectible_dirs
, responsible_dirs
);
3347 smartlist_free(responsible_dirs
);
3349 if (smartlist_len(selectible_dirs
) == 0) {
3350 log_info(LD_REND
, "Could not pick one of the responsible hidden "
3351 "service directories, because we requested them all "
3352 "recently without success.");
3355 hs_dir
= smartlist_choose(selectible_dirs
);
3356 smartlist_free(selectible_dirs
);
3358 log_warn(LD_BUG
, "Could not pick one of the responsible hidden service "
3359 "directories to fetch descriptors.");
3363 /* Remember, that we are requesting a descriptor from this hidden service
3365 lookup_last_hid_serv_request(hs_dir
, desc_id_base32
, now
, 1);
3367 /* Send fetch request. (Pass query as payload to write it to the directory
3368 * connection so that it can be referred to when the response arrives.) */
3369 directory_initiate_command_routerstatus(hs_dir
,
3370 DIR_PURPOSE_FETCH_RENDDESC_V2
,
3371 ROUTER_PURPOSE_GENERAL
,
3372 1, desc_id_base32
, query
, 0, 0);
3373 log_info(LD_REND
, "Sending fetch request for v2 descriptor for "
3374 "service '%s' with descriptor ID '%s' to hidden "
3375 "service directory '%s' on port %d.",
3376 query
, desc_id_base32
, hs_dir
->nickname
, hs_dir
->dir_port
);