Only send reachability status events on overall success/failure
[tor/rransom.git] / src / or / directory.c
blob7fc2fb1bdcd22fb488b8b9cfedbcacfe8dd2c761
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2009, The Tor Project, Inc. */
4 /* See LICENSE for licensing information */
6 #include "or.h"
7 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
8 #ifndef OPENBSD
9 #include <malloc.h>
10 #endif
11 #endif
13 /**
14 * \file directory.c
15 * \brief Code to send and fetch directories and router
16 * descriptors via HTTP. Directories use dirserv.c to generate the
17 * results; clients use routers.c to parse them.
18 **/
20 /* In-points to directory.c:
22 * - directory_post_to_dirservers(), called from
23 * router_upload_dir_desc_to_dirservers() in router.c
24 * upload_service_descriptor() in rendservice.c
25 * - directory_get_from_dirserver(), called from
26 * rend_client_refetch_renddesc() in rendclient.c
27 * run_scheduled_events() in main.c
28 * do_hup() in main.c
29 * - connection_dir_process_inbuf(), called from
30 * connection_process_inbuf() in connection.c
31 * - connection_dir_finished_flushing(), called from
32 * connection_finished_flushing() in connection.c
33 * - connection_dir_finished_connecting(), called from
34 * connection_finished_connecting() in connection.c
36 static void directory_send_command(dir_connection_t *conn,
37 int purpose, int direct, const char *resource,
38 const char *payload, size_t payload_len,
39 int supports_conditional_consensus,
40 time_t if_modified_since);
41 static int directory_handle_command(dir_connection_t *conn);
42 static int body_is_plausible(const char *body, size_t body_len, int purpose);
43 static int purpose_needs_anonymity(uint8_t dir_purpose,
44 uint8_t router_purpose);
45 static char *http_get_header(const char *headers, const char *which);
46 static void http_set_address_origin(const char *headers, connection_t *conn);
47 static void connection_dir_download_networkstatus_failed(
48 dir_connection_t *conn, int status_code);
49 static void connection_dir_download_routerdesc_failed(dir_connection_t *conn);
50 static void connection_dir_download_cert_failed(
51 dir_connection_t *conn, int status_code);
52 static void dir_networkstatus_download_failed(smartlist_t *failed,
53 int status_code);
54 static void dir_routerdesc_download_failed(smartlist_t *failed,
55 int status_code,
56 int router_purpose,
57 int was_extrainfo,
58 int was_descriptor_digests);
59 static void note_client_request(int purpose, int compressed, size_t bytes);
60 static int client_likes_consensus(networkstatus_t *v, const char *want_url);
62 static void directory_initiate_command_rend(const char *address,
63 const tor_addr_t *addr,
64 uint16_t or_port,
65 uint16_t dir_port,
66 int supports_conditional_consensus,
67 int supports_begindir,
68 const char *digest,
69 uint8_t dir_purpose,
70 uint8_t router_purpose,
71 int anonymized_connection,
72 const char *resource,
73 const char *payload,
74 size_t payload_len,
75 time_t if_modified_since,
76 const rend_data_t *rend_query);
78 /********* START VARIABLES **********/
80 /** How far in the future do we allow a directory server to tell us it is
81 * before deciding that one of us has the wrong time? */
82 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
84 #define X_ADDRESS_HEADER "X-Your-Address-Is: "
86 /** HTTP cache control: how long do we tell proxies they can cache each
87 * kind of document we serve? */
88 #define FULL_DIR_CACHE_LIFETIME (60*60)
89 #define RUNNINGROUTERS_CACHE_LIFETIME (20*60)
90 #define DIRPORTFRONTPAGE_CACHE_LIFETIME (20*60)
91 #define NETWORKSTATUS_CACHE_LIFETIME (5*60)
92 #define ROUTERDESC_CACHE_LIFETIME (30*60)
93 #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
94 #define ROBOTS_CACHE_LIFETIME (24*60*60)
96 /********* END VARIABLES ************/
98 /** Return true iff the directory purpose 'purpose' must use an
99 * anonymous connection to a directory. */
100 static int
101 purpose_needs_anonymity(uint8_t dir_purpose, uint8_t router_purpose)
103 if (get_options()->AllDirActionsPrivate)
104 return 1;
105 if (router_purpose == ROUTER_PURPOSE_BRIDGE && has_completed_circuit)
106 return 1; /* if no circuits yet, we may need this info to bootstrap. */
107 if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR ||
108 dir_purpose == DIR_PURPOSE_UPLOAD_VOTE ||
109 dir_purpose == DIR_PURPOSE_UPLOAD_SIGNATURES ||
110 dir_purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS ||
111 dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
112 dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES ||
113 dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS ||
114 dir_purpose == DIR_PURPOSE_FETCH_CERTIFICATE ||
115 dir_purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
116 dir_purpose == DIR_PURPOSE_FETCH_EXTRAINFO)
117 return 0;
118 return 1;
121 /** Return a newly allocated string describing <b>auth</b>. */
122 char *
123 authority_type_to_string(authority_type_t auth)
125 char *result;
126 smartlist_t *lst = smartlist_create();
127 if (auth & V1_AUTHORITY)
128 smartlist_add(lst, (void*)"V1");
129 if (auth & V2_AUTHORITY)
130 smartlist_add(lst, (void*)"V2");
131 if (auth & BRIDGE_AUTHORITY)
132 smartlist_add(lst, (void*)"Bridge");
133 if (auth & HIDSERV_AUTHORITY)
134 smartlist_add(lst, (void*)"Hidden service");
135 if (smartlist_len(lst)) {
136 result = smartlist_join_strings(lst, ", ", 0, NULL);
137 } else {
138 result = tor_strdup("[Not an authority]");
140 smartlist_free(lst);
141 return result;
144 /** Return a string describing a given directory connection purpose. */
145 static const char *
146 dir_conn_purpose_to_string(int purpose)
148 switch (purpose)
150 case DIR_PURPOSE_FETCH_RENDDESC:
151 return "hidden-service descriptor fetch";
152 case DIR_PURPOSE_UPLOAD_DIR:
153 return "server descriptor upload";
154 case DIR_PURPOSE_UPLOAD_RENDDESC:
155 return "hidden-service descriptor upload";
156 case DIR_PURPOSE_UPLOAD_VOTE:
157 return "server vote upload";
158 case DIR_PURPOSE_UPLOAD_SIGNATURES:
159 return "consensus signature upload";
160 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
161 return "network-status fetch";
162 case DIR_PURPOSE_FETCH_SERVERDESC:
163 return "server descriptor fetch";
164 case DIR_PURPOSE_FETCH_EXTRAINFO:
165 return "extra-info fetch";
166 case DIR_PURPOSE_FETCH_CONSENSUS:
167 return "consensus network-status fetch";
168 case DIR_PURPOSE_FETCH_CERTIFICATE:
169 return "authority cert fetch";
170 case DIR_PURPOSE_FETCH_STATUS_VOTE:
171 return "status vote fetch";
172 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
173 return "consensus signature fetch";
174 case DIR_PURPOSE_FETCH_RENDDESC_V2:
175 return "hidden-service v2 descriptor fetch";
176 case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
177 return "hidden-service v2 descriptor upload";
180 log_warn(LD_BUG, "Called with unknown purpose %d", purpose);
181 return "(unknown)";
184 /** Return true iff <b>identity_digest</b> is the digest of a router we
185 * believe to support extrainfo downloads. (If <b>is_authority</b> we do
186 * additional checking that's only valid for authorities.) */
188 router_supports_extrainfo(const char *identity_digest, int is_authority)
190 routerinfo_t *ri = router_get_by_digest(identity_digest);
192 if (ri) {
193 if (ri->caches_extra_info)
194 return 1;
195 if (is_authority && ri->platform &&
196 tor_version_as_new_as(ri->platform, "Tor 0.2.0.0-alpha-dev (r10070)"))
197 return 1;
199 if (is_authority) {
200 routerstatus_t *rs = router_get_consensus_status_by_id(identity_digest);
201 if (rs && rs->version_supports_extrainfo_upload)
202 return 1;
204 return 0;
207 /** Return true iff any trusted directory authority has accepted our
208 * server descriptor.
210 * We consider any authority sufficient because waiting for all of
211 * them means it never happens while any authority is down; we don't
212 * go for something more complex in the middle (like \>1/3 or \>1/2 or
213 * \>=1/2) because that doesn't seem necessary yet.
216 directories_have_accepted_server_descriptor(void)
218 smartlist_t *servers = router_get_trusted_dir_servers();
219 or_options_t *options = get_options();
220 SMARTLIST_FOREACH(servers, trusted_dir_server_t *, d, {
221 if ((d->type & options->_PublishServerDescriptor) &&
222 d->has_accepted_serverdesc) {
223 return 1;
226 return 0;
229 /** Start a connection to every suitable directory authority, using
230 * connection purpose 'purpose' and uploading the payload 'payload'
231 * (length 'payload_len'). The purpose should be one of
232 * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
234 * <b>type</b> specifies what sort of dir authorities (V1, V2,
235 * HIDSERV, BRIDGE) we should upload to.
237 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
238 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
239 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
240 * to all authorities, and the extra-info document to all authorities that
241 * support it.
243 void
244 directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
245 authority_type_t type,
246 const char *payload,
247 size_t payload_len, size_t extrainfo_len)
249 int post_via_tor;
250 smartlist_t *dirservers = router_get_trusted_dir_servers();
251 int found = 0;
252 tor_assert(dirservers);
253 /* This tries dirservers which we believe to be down, but ultimately, that's
254 * harmless, and we may as well err on the side of getting things uploaded.
256 SMARTLIST_FOREACH_BEGIN(dirservers, trusted_dir_server_t *, ds) {
257 routerstatus_t *rs = &(ds->fake_status);
258 size_t upload_len = payload_len;
259 tor_addr_t ds_addr;
261 if ((type & ds->type) == 0)
262 continue;
264 found = 1; /* at least one authority of this type was listed */
265 if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR)
266 ds->has_accepted_serverdesc = 0;
268 if (extrainfo_len && router_supports_extrainfo(ds->digest, 1)) {
269 upload_len += extrainfo_len;
270 log_info(LD_DIR, "Uploading an extrainfo too (length %d)",
271 (int) extrainfo_len);
273 tor_addr_from_ipv4h(&ds_addr, ds->addr);
274 post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) ||
275 !fascist_firewall_allows_address_dir(&ds_addr, ds->dir_port);
276 directory_initiate_command_routerstatus(rs, dir_purpose,
277 router_purpose,
278 post_via_tor,
279 NULL, payload, upload_len, 0);
280 } SMARTLIST_FOREACH_END(ds);
281 if (!found) {
282 char *s = authority_type_to_string(type);
283 log_warn(LD_DIR, "Publishing server descriptor to directory authorities "
284 "of type '%s', but no authorities of that type listed!", s);
285 tor_free(s);
289 /** Start a connection to a random running directory server, using
290 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
291 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
292 * Use <b>pds_flags</b> as arguments to router_pick_directory_server()
293 * or router_pick_trusteddirserver().
295 void
296 directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
297 const char *resource, int pds_flags)
299 routerstatus_t *rs = NULL;
300 or_options_t *options = get_options();
301 int prefer_authority = directory_fetches_from_authorities(options);
302 int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose);
303 authority_type_t type;
304 time_t if_modified_since = 0;
306 /* FFFF we could break this switch into its own function, and call
307 * it elsewhere in directory.c. -RD */
308 switch (dir_purpose) {
309 case DIR_PURPOSE_FETCH_EXTRAINFO:
310 type = EXTRAINFO_CACHE |
311 (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
312 V2_AUTHORITY);
313 break;
314 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
315 case DIR_PURPOSE_FETCH_SERVERDESC:
316 type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
317 V2_AUTHORITY);
318 break;
319 case DIR_PURPOSE_FETCH_RENDDESC:
320 type = HIDSERV_AUTHORITY;
321 break;
322 case DIR_PURPOSE_FETCH_STATUS_VOTE:
323 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
324 type = V3_AUTHORITY;
325 break;
326 case DIR_PURPOSE_FETCH_CONSENSUS:
327 case DIR_PURPOSE_FETCH_CERTIFICATE:
328 type = V3_AUTHORITY;
329 break;
330 default:
331 log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose);
332 return;
335 if (DIR_PURPOSE_FETCH_CONSENSUS) {
336 networkstatus_t *v = networkstatus_get_latest_consensus();
337 if (v)
338 if_modified_since = v->valid_after + 180;
341 if (!options->FetchServerDescriptors && type != HIDSERV_AUTHORITY)
342 return;
344 if (!get_via_tor) {
345 if (options->UseBridges && type != BRIDGE_AUTHORITY) {
346 /* want to ask a running bridge for which we have a descriptor. */
347 /* XXX022 we assume that all of our bridges can answer any
348 * possible directory question. This won't be true forever. -RD */
349 /* It certainly is not true with conditional consensus downloading,
350 * so, for now, never assume the server supports that. */
351 routerinfo_t *ri = choose_random_entry(NULL);
352 if (ri) {
353 tor_addr_t addr;
354 tor_addr_from_ipv4h(&addr, ri->addr);
355 directory_initiate_command(ri->address, &addr,
356 ri->or_port, 0,
357 0, /* don't use conditional consensus url */
358 1, ri->cache_info.identity_digest,
359 dir_purpose,
360 router_purpose,
361 0, resource, NULL, 0, if_modified_since);
362 } else
363 log_notice(LD_DIR, "Ignoring directory request, since no bridge "
364 "nodes are available yet.");
365 return;
366 } else {
367 if (prefer_authority || type == BRIDGE_AUTHORITY) {
368 /* only ask authdirservers, and don't ask myself */
369 rs = router_pick_trusteddirserver(type, pds_flags);
370 if (rs == NULL && (pds_flags & PDS_NO_EXISTING_SERVERDESC_FETCH)) {
371 /* We don't want to fetch from any authorities that we're currently
372 * fetching server descriptors from, and we got no match. Did we
373 * get no match because all the authorities have connections
374 * fetching server descriptors (in which case we should just
375 * return,) or because all the authorities are down or on fire or
376 * unreachable or something (in which case we should go on with
377 * our fallback code)? */
378 pds_flags &= ~PDS_NO_EXISTING_SERVERDESC_FETCH;
379 rs = router_pick_trusteddirserver(type, pds_flags);
380 if (rs) {
381 log_debug(LD_DIR, "Deferring serverdesc fetch: all authorities "
382 "are in use.");
383 return;
387 if (!rs && type != BRIDGE_AUTHORITY) {
388 /* anybody with a non-zero dirport will do */
389 rs = router_pick_directory_server(type, pds_flags);
390 if (!rs) {
391 log_info(LD_DIR, "No router found for %s; falling back to "
392 "dirserver list.", dir_conn_purpose_to_string(dir_purpose));
393 rs = router_pick_trusteddirserver(type, pds_flags);
394 if (!rs)
395 get_via_tor = 1; /* last resort: try routing it via Tor */
399 } else { /* get_via_tor */
400 /* Never use fascistfirewall; we're going via Tor. */
401 if (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) {
402 /* only ask hidserv authorities, any of them will do */
403 pds_flags |= PDS_IGNORE_FASCISTFIREWALL|PDS_ALLOW_SELF;
404 rs = router_pick_trusteddirserver(HIDSERV_AUTHORITY, pds_flags);
405 } else {
406 /* anybody with a non-zero dirport will do. Disregard firewalls. */
407 pds_flags |= PDS_IGNORE_FASCISTFIREWALL;
408 rs = router_pick_directory_server(type, pds_flags);
409 /* If we have any hope of building an indirect conn, we know some router
410 * descriptors. If (rs==NULL), we can't build circuits anyway, so
411 * there's no point in falling back to the authorities in this case. */
415 if (rs)
416 directory_initiate_command_routerstatus(rs, dir_purpose,
417 router_purpose,
418 get_via_tor,
419 resource, NULL, 0,
420 if_modified_since);
421 else {
422 log_notice(LD_DIR,
423 "While fetching directory info, "
424 "no running dirservers known. Will try again later. "
425 "(purpose %d)", dir_purpose);
426 if (!purpose_needs_anonymity(dir_purpose, router_purpose)) {
427 /* remember we tried them all and failed. */
428 directory_all_unreachable(time(NULL));
433 /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
434 * directory authority other than ourself. Only for use by authorities when
435 * searching for missing information while voting. */
436 void
437 directory_get_from_all_authorities(uint8_t dir_purpose,
438 uint8_t router_purpose,
439 const char *resource)
441 tor_assert(dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
442 dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES);
444 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
445 trusted_dir_server_t *, ds,
447 routerstatus_t *rs;
448 if (router_digest_is_me(ds->digest))
449 continue;
450 if (!(ds->type & V3_AUTHORITY))
451 continue;
452 rs = &ds->fake_status;
453 directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose,
454 0, resource, NULL, 0, 0);
458 /** Same as directory_initiate_command_routerstatus(), but accepts
459 * rendezvous data to fetch a hidden service descriptor. */
460 void
461 directory_initiate_command_routerstatus_rend(routerstatus_t *status,
462 uint8_t dir_purpose,
463 uint8_t router_purpose,
464 int anonymized_connection,
465 const char *resource,
466 const char *payload,
467 size_t payload_len,
468 time_t if_modified_since,
469 const rend_data_t *rend_query)
471 routerinfo_t *router;
472 char address_buf[INET_NTOA_BUF_LEN+1];
473 struct in_addr in;
474 const char *address;
475 tor_addr_t addr;
476 router = router_get_by_digest(status->identity_digest);
477 if (!router && anonymized_connection) {
478 log_info(LD_DIR, "Not sending anonymized request to directory '%s'; we "
479 "don't have its router descriptor.", status->nickname);
480 return;
481 } else if (router) {
482 address = router->address;
483 } else {
484 in.s_addr = htonl(status->addr);
485 tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
486 address = address_buf;
488 tor_addr_from_ipv4h(&addr, status->addr);
489 directory_initiate_command_rend(address, &addr,
490 status->or_port, status->dir_port,
491 status->version_supports_conditional_consensus,
492 status->version_supports_begindir,
493 status->identity_digest,
494 dir_purpose, router_purpose,
495 anonymized_connection, resource,
496 payload, payload_len, if_modified_since,
497 rend_query);
500 /** Launch a new connection to the directory server <b>status</b> to
501 * upload or download a server or rendezvous
502 * descriptor. <b>dir_purpose</b> determines what
503 * kind of directory connection we're launching, and must be one of
504 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. <b>router_purpose</b>
505 * specifies the descriptor purposes we have in mind (currently only
506 * used for FETCH_DIR).
508 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
509 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
511 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
512 * want to fetch.
514 void
515 directory_initiate_command_routerstatus(routerstatus_t *status,
516 uint8_t dir_purpose,
517 uint8_t router_purpose,
518 int anonymized_connection,
519 const char *resource,
520 const char *payload,
521 size_t payload_len,
522 time_t if_modified_since)
524 directory_initiate_command_routerstatus_rend(status, dir_purpose,
525 router_purpose,
526 anonymized_connection, resource,
527 payload, payload_len,
528 if_modified_since, NULL);
531 /** Return true iff <b>conn</b> is the client side of a directory connection
532 * we launched to ourself in order to determine the reachability of our
533 * dir_port. */
534 static int
535 directory_conn_is_self_reachability_test(dir_connection_t *conn)
537 if (conn->requested_resource &&
538 !strcmpstart(conn->requested_resource,"authority")) {
539 routerinfo_t *me = router_get_my_routerinfo();
540 if (me &&
541 router_digest_is_me(conn->identity_digest) &&
542 tor_addr_eq_ipv4h(&conn->_base.addr, me->addr) && /*XXXX prop 118*/
543 me->dir_port == conn->_base.port)
544 return 1;
546 return 0;
549 /** Called when we are unable to complete the client's request to a directory
550 * server due to a network error: Mark the router as down and try again if
551 * possible.
553 void
554 connection_dir_request_failed(dir_connection_t *conn)
556 if (directory_conn_is_self_reachability_test(conn)) {
557 return; /* this was a test fetch. don't retry. */
559 if (entry_list_can_grow(get_options()))
560 router_set_status(conn->identity_digest, 0); /* don't try him again */
561 if (conn->_base.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
562 log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
563 conn->_base.address);
564 connection_dir_download_networkstatus_failed(conn, -1);
565 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
566 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
567 log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
568 conn->_base.address);
569 connection_dir_download_routerdesc_failed(conn);
570 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
571 networkstatus_consensus_download_failed(0);
572 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
573 log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
574 conn->_base.address);
575 connection_dir_download_cert_failed(conn, 0);
576 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
577 log_info(LD_DIR, "Giving up downloading detached signatures from '%s'",
578 conn->_base.address);
579 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
580 log_info(LD_DIR, "Giving up downloading votes from '%s'",
581 conn->_base.address);
585 /** Called when an attempt to download one or more network status
586 * documents on connection <b>conn</b> failed. Decide whether to
587 * retry the fetch now, later, or never.
589 static void
590 connection_dir_download_networkstatus_failed(dir_connection_t *conn,
591 int status_code)
593 if (!conn->requested_resource) {
594 /* We never reached directory_send_command, which means that we never
595 * opened a network connection. Either we're out of sockets, or the
596 * network is down. Either way, retrying would be pointless. */
597 return;
599 if (!strcmpstart(conn->requested_resource, "all")) {
600 /* We're a non-authoritative directory cache; try again. Ignore status
601 * code, since we don't want to keep trying forever in a tight loop
602 * if all the authorities are shutting us out. */
603 smartlist_t *trusted_dirs = router_get_trusted_dir_servers();
604 SMARTLIST_FOREACH(trusted_dirs, trusted_dir_server_t *, ds,
605 download_status_failed(&ds->v2_ns_dl_status, 0));
606 directory_get_from_dirserver(conn->_base.purpose, conn->router_purpose,
607 "all.z", 0 /* don't retry_if_no_servers */);
608 } else if (!strcmpstart(conn->requested_resource, "fp/")) {
609 /* We were trying to download by fingerprint; mark them all as having
610 * failed, and possibly retry them later.*/
611 smartlist_t *failed = smartlist_create();
612 dir_split_resource_into_fingerprints(conn->requested_resource+3,
613 failed, NULL, 0, 0);
614 if (smartlist_len(failed)) {
615 dir_networkstatus_download_failed(failed, status_code);
616 SMARTLIST_FOREACH(failed, char *, cp, tor_free(cp));
618 smartlist_free(failed);
622 /** Called when an attempt to download one or more router descriptors
623 * or extra-info documents on connection <b>conn</b> failed.
625 static void
626 connection_dir_download_routerdesc_failed(dir_connection_t *conn)
628 /* No need to increment the failure count for routerdescs, since
629 * it's not their fault. */
631 /* No need to relaunch descriptor downloads here: we already do it
632 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
633 tor_assert(conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
634 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO);
636 (void) conn;
639 /** Called when an attempt to fetch a certificate fails. */
640 static void
641 connection_dir_download_cert_failed(dir_connection_t *conn, int status)
643 smartlist_t *failed;
644 tor_assert(conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
646 if (!conn->requested_resource)
647 return;
648 failed = smartlist_create();
649 dir_split_resource_into_fingerprints(conn->requested_resource+3,
650 failed, NULL, 1, 0);
651 SMARTLIST_FOREACH(failed, char *, cp,
653 authority_cert_dl_failed(cp, status);
654 tor_free(cp);
656 smartlist_free(failed);
658 update_certificate_downloads(time(NULL));
661 /** Evaluate the situation and decide if we should use an encrypted
662 * "begindir-style" connection for this directory request.
663 * 1) If or_port is 0, or it's a direct conn and or_port is firewalled
664 * or we're a dir mirror, no.
665 * 2) If we prefer to avoid begindir conns, and we're not fetching or
666 * publishing a bridge relay descriptor, no.
667 * 3) Else yes.
669 static int
670 directory_command_should_use_begindir(or_options_t *options,
671 const tor_addr_t *addr,
672 int or_port, uint8_t router_purpose,
673 int anonymized_connection)
675 if (!or_port)
676 return 0; /* We don't know an ORPort -- no chance. */
677 if (!anonymized_connection)
678 if (!fascist_firewall_allows_address_or(addr, or_port) ||
679 directory_fetches_from_authorities(options) ||
680 (server_mode(options) && !options->Address))
681 return 0; /* We're firewalled or are acting like a relay -- also no. */
682 if (!options->TunnelDirConns &&
683 router_purpose != ROUTER_PURPOSE_BRIDGE)
684 return 0; /* We prefer to avoid using begindir conns. Fine. */
685 return 1;
688 /** Helper for directory_initiate_command_routerstatus: send the
689 * command to a server whose address is <b>address</b>, whose IP is
690 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
691 * <b>supports_begindir</b>, and whose identity key digest is
692 * <b>digest</b>. */
693 void
694 directory_initiate_command(const char *address, const tor_addr_t *_addr,
695 uint16_t or_port, uint16_t dir_port,
696 int supports_conditional_consensus,
697 int supports_begindir, const char *digest,
698 uint8_t dir_purpose, uint8_t router_purpose,
699 int anonymized_connection, const char *resource,
700 const char *payload, size_t payload_len,
701 time_t if_modified_since)
703 directory_initiate_command_rend(address, _addr, or_port, dir_port,
704 supports_conditional_consensus,
705 supports_begindir, digest, dir_purpose,
706 router_purpose, anonymized_connection,
707 resource, payload, payload_len,
708 if_modified_since, NULL);
711 /** Same as directory_initiate_command(), but accepts rendezvous data to
712 * fetch a hidden service descriptor. */
713 static void
714 directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
715 uint16_t or_port, uint16_t dir_port,
716 int supports_conditional_consensus,
717 int supports_begindir, const char *digest,
718 uint8_t dir_purpose, uint8_t router_purpose,
719 int anonymized_connection,
720 const char *resource,
721 const char *payload, size_t payload_len,
722 time_t if_modified_since,
723 const rend_data_t *rend_query)
725 dir_connection_t *conn;
726 or_options_t *options = get_options();
727 int socket_error = 0;
728 int use_begindir = supports_begindir &&
729 directory_command_should_use_begindir(options, _addr,
730 or_port, router_purpose, anonymized_connection);
731 tor_addr_t addr;
733 tor_assert(address);
734 tor_assert(_addr);
735 tor_assert(or_port || dir_port);
736 tor_assert(digest);
738 tor_addr_copy(&addr, _addr);
740 log_debug(LD_DIR, "anonymized %d, use_begindir %d.",
741 anonymized_connection, use_begindir);
743 log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
745 conn = dir_connection_new(AF_INET);
747 /* set up conn so it's got all the data we need to remember */
748 tor_addr_copy(&conn->_base.addr, &addr);
749 conn->_base.port = use_begindir ? or_port : dir_port;
750 conn->_base.address = tor_strdup(address);
751 memcpy(conn->identity_digest, digest, DIGEST_LEN);
753 conn->_base.purpose = dir_purpose;
754 conn->router_purpose = router_purpose;
756 /* give it an initial state */
757 conn->_base.state = DIR_CONN_STATE_CONNECTING;
759 /* decide whether we can learn our IP address from this conn */
760 conn->dirconn_direct = !anonymized_connection;
762 /* copy rendezvous data, if any */
763 if (rend_query)
764 conn->rend_data = rend_data_dup(rend_query);
766 if (!anonymized_connection && !use_begindir) {
767 /* then we want to connect to dirport directly */
769 if (options->HttpProxy) {
770 tor_addr_from_ipv4h(&addr, options->HttpProxyAddr);
771 dir_port = options->HttpProxyPort;
774 switch (connection_connect(TO_CONN(conn), conn->_base.address, &addr,
775 dir_port, &socket_error)) {
776 case -1:
777 connection_dir_request_failed(conn); /* retry if we want */
778 /* XXX we only pass 'conn' above, not 'resource', 'payload',
779 * etc. So in many situations it can't retry! -RD */
780 connection_free(TO_CONN(conn));
781 return;
782 case 1:
783 /* start flushing conn */
784 conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
785 /* fall through */
786 case 0:
787 /* queue the command on the outbuf */
788 directory_send_command(conn, dir_purpose, 1, resource,
789 payload, payload_len,
790 supports_conditional_consensus,
791 if_modified_since);
792 connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
793 /* writable indicates finish, readable indicates broken link,
794 error indicates broken link in windowsland. */
796 } else { /* we want to connect via a tor connection */
797 edge_connection_t *linked_conn;
799 /* If it's an anonymized connection, remember the fact that we
800 * wanted it for later: maybe we'll want it again soon. */
801 if (anonymized_connection && use_begindir)
802 rep_hist_note_used_internal(time(NULL), 0, 1);
803 else if (anonymized_connection && !use_begindir)
804 rep_hist_note_used_port(time(NULL), conn->_base.port);
806 /* make an AP connection
807 * populate it and add it at the right state
808 * hook up both sides
810 linked_conn =
811 connection_ap_make_link(conn->_base.address, conn->_base.port,
812 digest, use_begindir, conn->dirconn_direct);
813 if (!linked_conn) {
814 log_warn(LD_NET,"Making tunnel to dirserver failed.");
815 connection_mark_for_close(TO_CONN(conn));
816 return;
818 connection_link_connections(TO_CONN(conn), TO_CONN(linked_conn));
820 if (connection_add(TO_CONN(conn)) < 0) {
821 log_warn(LD_NET,"Unable to add connection for link to dirserver.");
822 connection_mark_for_close(TO_CONN(conn));
823 return;
825 conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
826 /* queue the command on the outbuf */
827 directory_send_command(conn, dir_purpose, 0, resource,
828 payload, payload_len,
829 supports_conditional_consensus,
830 if_modified_since);
831 connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
832 connection_start_reading(TO_CONN(linked_conn));
836 /** Return true iff anything we say on <b>conn</b> is being encrypted before
837 * we send it to the client/server. */
839 connection_dir_is_encrypted(dir_connection_t *conn)
841 /* Right now it's sufficient to see if conn is or has been linked, since
842 * the only thing it could be linked to is an edge connection on a
843 * circuit, and the only way it could have been unlinked is at the edge
844 * connection getting closed.
846 return TO_CONN(conn)->linked;
849 /** Helper for sorting
851 * sort strings alphabetically
853 static int
854 _compare_strs(const void **a, const void **b)
856 const char *s1 = *a, *s2 = *b;
857 return strcmp(s1, s2);
860 #define CONDITIONAL_CONSENSUS_FPR_LEN 3
861 #if (CONDITIONAL_CONSENSUS_FPR_LEN > DIGEST_LEN)
862 #error "conditional consensus fingerprint length is larger than digest length"
863 #endif
865 /** Return the URL we should use for a consensus download.
867 * This url depends on whether or not the server we go to
868 * is sufficiently new to support conditional consensus downloading,
869 * i.e. GET .../consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>
871 static char *
872 directory_get_consensus_url(int supports_conditional_consensus)
874 char *url;
875 int len;
877 if (supports_conditional_consensus) {
878 char *authority_id_list;
879 smartlist_t *authority_digets = smartlist_create();
881 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
882 trusted_dir_server_t *, ds,
884 char *hex;
885 if (!(ds->type & V3_AUTHORITY))
886 continue;
888 hex = tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN+1);
889 base16_encode(hex, 2*CONDITIONAL_CONSENSUS_FPR_LEN+1,
890 ds->v3_identity_digest, CONDITIONAL_CONSENSUS_FPR_LEN);
891 smartlist_add(authority_digets, hex);
893 smartlist_sort(authority_digets, _compare_strs);
894 authority_id_list = smartlist_join_strings(authority_digets,
895 "+", 0, NULL);
897 len = strlen(authority_id_list)+64;
898 url = tor_malloc(len);
899 tor_snprintf(url, len, "/tor/status-vote/current/consensus/%s.z",
900 authority_id_list);
902 SMARTLIST_FOREACH(authority_digets, char *, cp, tor_free(cp));
903 smartlist_free(authority_digets);
904 tor_free(authority_id_list);
905 } else {
906 url = tor_strdup("/tor/status-vote/current/consensus.z");
908 return url;
911 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
912 * are as in directory_initiate_command.
914 static void
915 directory_send_command(dir_connection_t *conn,
916 int purpose, int direct, const char *resource,
917 const char *payload, size_t payload_len,
918 int supports_conditional_consensus,
919 time_t if_modified_since)
921 char proxystring[256];
922 char proxyauthstring[256];
923 char hoststring[128];
924 char imsstring[RFC1123_TIME_LEN+32];
925 char *url;
926 char request[8192];
927 const char *httpcommand = NULL;
928 size_t len;
930 tor_assert(conn);
931 tor_assert(conn->_base.type == CONN_TYPE_DIR);
933 tor_free(conn->requested_resource);
934 if (resource)
935 conn->requested_resource = tor_strdup(resource);
937 /* come up with a string for which Host: we want */
938 if (conn->_base.port == 80) {
939 strlcpy(hoststring, conn->_base.address, sizeof(hoststring));
940 } else {
941 tor_snprintf(hoststring, sizeof(hoststring),"%s:%d",
942 conn->_base.address, conn->_base.port);
945 /* Format if-modified-since */
946 if (!if_modified_since) {
947 imsstring[0] = '\0';
948 } else {
949 char b[RFC1123_TIME_LEN+1];
950 format_rfc1123_time(b, if_modified_since);
951 tor_snprintf(imsstring, sizeof(imsstring), "\r\nIf-Modified-Since: %s", b);
954 /* come up with some proxy lines, if we're using one. */
955 if (direct && get_options()->HttpProxy) {
956 char *base64_authenticator=NULL;
957 const char *authenticator = get_options()->HttpProxyAuthenticator;
959 tor_snprintf(proxystring, sizeof(proxystring),"http://%s", hoststring);
960 if (authenticator) {
961 base64_authenticator = alloc_http_authenticator(authenticator);
962 if (!base64_authenticator)
963 log_warn(LD_BUG, "Encoding http authenticator failed");
965 if (base64_authenticator) {
966 tor_snprintf(proxyauthstring, sizeof(proxyauthstring),
967 "\r\nProxy-Authorization: Basic %s",
968 base64_authenticator);
969 tor_free(base64_authenticator);
970 } else {
971 proxyauthstring[0] = 0;
973 } else {
974 proxystring[0] = 0;
975 proxyauthstring[0] = 0;
978 switch (purpose) {
979 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
980 tor_assert(resource);
981 httpcommand = "GET";
982 len = strlen(resource)+32;
983 url = tor_malloc(len);
984 tor_snprintf(url, len, "/tor/status/%s", resource);
985 break;
986 case DIR_PURPOSE_FETCH_CONSENSUS:
987 tor_assert(!resource);
988 tor_assert(!payload);
989 httpcommand = "GET";
990 url = directory_get_consensus_url(supports_conditional_consensus);
991 log_info(LD_DIR, "Downloading consensus from %s using %s",
992 hoststring, url);
993 break;
994 case DIR_PURPOSE_FETCH_CERTIFICATE:
995 tor_assert(resource);
996 tor_assert(!payload);
997 httpcommand = "GET";
998 len = strlen(resource)+32;
999 url = tor_malloc(len);
1000 tor_snprintf(url, len, "/tor/keys/%s", resource);
1001 break;
1002 case DIR_PURPOSE_FETCH_STATUS_VOTE:
1003 tor_assert(resource);
1004 tor_assert(!payload);
1005 httpcommand = "GET";
1006 len = strlen(resource)+32;
1007 url = tor_malloc(len);
1008 tor_snprintf(url, len, "/tor/status-vote/next/%s.z", resource);
1009 break;
1010 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
1011 tor_assert(!resource);
1012 tor_assert(!payload);
1013 httpcommand = "GET";
1014 url = tor_strdup("/tor/status-vote/next/consensus-signatures.z");
1015 break;
1016 case DIR_PURPOSE_FETCH_SERVERDESC:
1017 tor_assert(resource);
1018 httpcommand = "GET";
1019 len = strlen(resource)+32;
1020 url = tor_malloc(len);
1021 tor_snprintf(url, len, "/tor/server/%s", resource);
1022 break;
1023 case DIR_PURPOSE_FETCH_EXTRAINFO:
1024 tor_assert(resource);
1025 httpcommand = "GET";
1026 len = strlen(resource)+32;
1027 url = tor_malloc(len);
1028 tor_snprintf(url, len, "/tor/extra/%s", resource);
1029 break;
1030 case DIR_PURPOSE_UPLOAD_DIR:
1031 tor_assert(!resource);
1032 tor_assert(payload);
1033 httpcommand = "POST";
1034 url = tor_strdup("/tor/");
1035 break;
1036 case DIR_PURPOSE_UPLOAD_VOTE:
1037 tor_assert(!resource);
1038 tor_assert(payload);
1039 httpcommand = "POST";
1040 url = tor_strdup("/tor/post/vote");
1041 break;
1042 case DIR_PURPOSE_UPLOAD_SIGNATURES:
1043 tor_assert(!resource);
1044 tor_assert(payload);
1045 httpcommand = "POST";
1046 url = tor_strdup("/tor/post/consensus-signature");
1047 break;
1048 case DIR_PURPOSE_FETCH_RENDDESC:
1049 tor_assert(resource);
1050 tor_assert(!payload);
1052 /* this must be true or we wouldn't be doing the lookup */
1053 tor_assert(strlen(resource) <= REND_SERVICE_ID_LEN_BASE32);
1054 /* This breaks the function abstraction. */
1055 conn->rend_data = tor_malloc_zero(sizeof(rend_data_t));
1056 strlcpy(conn->rend_data->onion_address, resource,
1057 sizeof(conn->rend_data->onion_address));
1058 conn->rend_data->rend_desc_version = 0;
1060 httpcommand = "GET";
1061 /* Request the most recent versioned descriptor. */
1062 // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
1063 // but that never got testing, and it wasn't a good design.)
1064 len = strlen(resource)+32;
1065 url = tor_malloc(len);
1066 tor_snprintf(url, len, "/tor/rendezvous/%s", resource);
1067 break;
1068 case DIR_PURPOSE_FETCH_RENDDESC_V2:
1069 tor_assert(resource);
1070 tor_assert(strlen(resource) <= REND_DESC_ID_V2_LEN_BASE32);
1071 tor_assert(!payload);
1072 conn->rend_data->rend_desc_version = 2;
1073 httpcommand = "GET";
1074 len = strlen(resource) + 32;
1075 url = tor_malloc(len);
1076 tor_snprintf(url, len, "/tor/rendezvous2/%s", resource);
1077 break;
1078 case DIR_PURPOSE_UPLOAD_RENDDESC:
1079 tor_assert(!resource);
1080 tor_assert(payload);
1081 httpcommand = "POST";
1082 url = tor_strdup("/tor/rendezvous/publish");
1083 break;
1084 case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
1085 tor_assert(!resource);
1086 tor_assert(payload);
1087 httpcommand = "POST";
1088 url = tor_strdup("/tor/rendezvous2/publish");
1089 break;
1090 default:
1091 tor_assert(0);
1092 return;
1095 if (strlen(proxystring) + strlen(url) >= 4096) {
1096 log_warn(LD_BUG,
1097 "Squid does not like URLs longer than 4095 bytes, and this "
1098 "one is %d bytes long: %s%s",
1099 (int)(strlen(proxystring) + strlen(url)), proxystring, url);
1102 tor_snprintf(request, sizeof(request), "%s %s", httpcommand, proxystring);
1103 connection_write_to_buf(request, strlen(request), TO_CONN(conn));
1104 connection_write_to_buf(url, strlen(url), TO_CONN(conn));
1105 tor_free(url);
1107 if (!strcmp(httpcommand, "GET") && !payload) {
1108 tor_snprintf(request, sizeof(request),
1109 " HTTP/1.0\r\nHost: %s%s%s\r\n\r\n",
1110 hoststring,
1111 imsstring,
1112 proxyauthstring);
1113 } else {
1114 tor_snprintf(request, sizeof(request),
1115 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s%s\r\n\r\n",
1116 payload ? (unsigned long)payload_len : 0,
1117 hoststring,
1118 imsstring,
1119 proxyauthstring);
1121 connection_write_to_buf(request, strlen(request), TO_CONN(conn));
1123 if (payload) {
1124 /* then send the payload afterwards too */
1125 connection_write_to_buf(payload, payload_len, TO_CONN(conn));
1129 /** Parse an HTTP request string <b>headers</b> of the form
1130 * \verbatim
1131 * "\%s [http[s]://]\%s HTTP/1..."
1132 * \endverbatim
1133 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
1134 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
1135 * so it does. Return 0.
1136 * Otherwise, return -1.
1138 static int
1139 parse_http_url(const char *headers, char **url)
1141 char *s, *start, *tmp;
1143 s = (char *)eat_whitespace_no_nl(headers);
1144 if (!*s) return -1;
1145 s = (char *)find_whitespace(s); /* get past GET/POST */
1146 if (!*s) return -1;
1147 s = (char *)eat_whitespace_no_nl(s);
1148 if (!*s) return -1;
1149 start = s; /* this is it, assuming it's valid */
1150 s = (char *)find_whitespace(start);
1151 if (!*s) return -1;
1153 /* tolerate the http[s] proxy style of putting the hostname in the url */
1154 if (s-start >= 4 && !strcmpstart(start,"http")) {
1155 tmp = start + 4;
1156 if (*tmp == 's')
1157 tmp++;
1158 if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
1159 tmp = strchr(tmp+3, '/');
1160 if (tmp && tmp < s) {
1161 log_debug(LD_DIR,"Skipping over 'http[s]://hostname' string");
1162 start = tmp;
1167 if (s-start < 5 || strcmpstart(start,"/tor/")) { /* need to rewrite it */
1168 *url = tor_malloc(s - start + 5);
1169 strlcpy(*url,"/tor", s-start+5);
1170 strlcat((*url)+4, start, s-start+1);
1171 } else {
1172 *url = tor_strndup(start, s-start);
1174 return 0;
1177 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
1178 * <b>which</b>. The key should be given with a terminating colon and space;
1179 * this function copies everything after, up to but not including the
1180 * following \\r\\n. */
1181 static char *
1182 http_get_header(const char *headers, const char *which)
1184 const char *cp = headers;
1185 while (cp) {
1186 if (!strcasecmpstart(cp, which)) {
1187 char *eos;
1188 cp += strlen(which);
1189 if ((eos = strchr(cp,'\r')))
1190 return tor_strndup(cp, eos-cp);
1191 else
1192 return tor_strdup(cp);
1194 cp = strchr(cp, '\n');
1195 if (cp)
1196 ++cp;
1198 return NULL;
1201 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
1202 * <b>conn</b>-\>address to describe our best guess of the address that
1203 * originated this HTTP request. */
1204 static void
1205 http_set_address_origin(const char *headers, connection_t *conn)
1207 char *fwd;
1209 fwd = http_get_header(headers, "Forwarded-For: ");
1210 if (!fwd)
1211 fwd = http_get_header(headers, "X-Forwarded-For: ");
1212 if (fwd) {
1213 struct in_addr in;
1214 if (!tor_inet_aton(fwd, &in) || is_internal_IP(ntohl(in.s_addr), 0)) {
1215 log_debug(LD_DIR, "Ignoring unrecognized or internal IP %s",
1216 escaped(fwd));
1217 tor_free(fwd);
1218 return;
1220 tor_free(conn->address);
1221 conn->address = tor_strdup(fwd);
1222 tor_free(fwd);
1226 /** Parse an HTTP response string <b>headers</b> of the form
1227 * \verbatim
1228 * "HTTP/1.\%d \%d\%s\r\n...".
1229 * \endverbatim
1231 * If it's well-formed, assign the status code to *<b>code</b> and
1232 * return 0. Otherwise, return -1.
1234 * On success: If <b>date</b> is provided, set *date to the Date
1235 * header in the http headers, or 0 if no such header is found. If
1236 * <b>compression</b> is provided, set *<b>compression</b> to the
1237 * compression method given in the Content-Encoding header, or 0 if no
1238 * such header is found, or -1 if the value of the header is not
1239 * recognized. If <b>reason</b> is provided, strdup the reason string
1240 * into it.
1243 parse_http_response(const char *headers, int *code, time_t *date,
1244 compress_method_t *compression, char **reason)
1246 unsigned n1, n2;
1247 char datestr[RFC1123_TIME_LEN+1];
1248 smartlist_t *parsed_headers;
1249 tor_assert(headers);
1250 tor_assert(code);
1252 while (TOR_ISSPACE(*headers)) headers++; /* tolerate leading whitespace */
1254 if (tor_sscanf(headers, "HTTP/1.%u %u", &n1, &n2) < 2 ||
1255 (n1 != 0 && n1 != 1) ||
1256 (n2 < 100 || n2 >= 600)) {
1257 log_warn(LD_HTTP,"Failed to parse header %s",escaped(headers));
1258 return -1;
1260 *code = n2;
1262 parsed_headers = smartlist_create();
1263 smartlist_split_string(parsed_headers, headers, "\n",
1264 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
1265 if (reason) {
1266 smartlist_t *status_line_elements = smartlist_create();
1267 tor_assert(smartlist_len(parsed_headers));
1268 smartlist_split_string(status_line_elements,
1269 smartlist_get(parsed_headers, 0),
1270 " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
1271 tor_assert(smartlist_len(status_line_elements) <= 3);
1272 if (smartlist_len(status_line_elements) == 3) {
1273 *reason = smartlist_get(status_line_elements, 2);
1274 smartlist_set(status_line_elements, 2, NULL); /* Prevent free */
1276 SMARTLIST_FOREACH(status_line_elements, char *, cp, tor_free(cp));
1277 smartlist_free(status_line_elements);
1279 if (date) {
1280 *date = 0;
1281 SMARTLIST_FOREACH(parsed_headers, const char *, s,
1282 if (!strcmpstart(s, "Date: ")) {
1283 strlcpy(datestr, s+6, sizeof(datestr));
1284 /* This will do nothing on failure, so we don't need to check
1285 the result. We shouldn't warn, since there are many other valid
1286 date formats besides the one we use. */
1287 parse_rfc1123_time(datestr, date);
1288 break;
1291 if (compression) {
1292 const char *enc = NULL;
1293 SMARTLIST_FOREACH(parsed_headers, const char *, s,
1294 if (!strcmpstart(s, "Content-Encoding: ")) {
1295 enc = s+18; break;
1297 if (!enc || !strcmp(enc, "identity")) {
1298 *compression = NO_METHOD;
1299 } else if (!strcmp(enc, "deflate") || !strcmp(enc, "x-deflate")) {
1300 *compression = ZLIB_METHOD;
1301 } else if (!strcmp(enc, "gzip") || !strcmp(enc, "x-gzip")) {
1302 *compression = GZIP_METHOD;
1303 } else {
1304 log_info(LD_HTTP, "Unrecognized content encoding: %s. Trying to deal.",
1305 escaped(enc));
1306 *compression = UNKNOWN_METHOD;
1309 SMARTLIST_FOREACH(parsed_headers, char *, s, tor_free(s));
1310 smartlist_free(parsed_headers);
1312 return 0;
1315 /** Return true iff <b>body</b> doesn't start with a plausible router or
1316 * running-list or directory opening. This is a sign of possible compression.
1318 static int
1319 body_is_plausible(const char *body, size_t len, int purpose)
1321 int i;
1322 if (len == 0)
1323 return 1; /* empty bodies don't need decompression */
1324 if (len < 32)
1325 return 0;
1326 if (purpose != DIR_PURPOSE_FETCH_RENDDESC) {
1327 if (!strcmpstart(body,"router") ||
1328 !strcmpstart(body,"signed-directory") ||
1329 !strcmpstart(body,"network-status") ||
1330 !strcmpstart(body,"running-routers"))
1331 return 1;
1332 for (i=0;i<32;++i) {
1333 if (!TOR_ISPRINT(body[i]) && !TOR_ISSPACE(body[i]))
1334 return 0;
1336 return 1;
1337 } else {
1338 return 1;
1342 /** Called when we've just fetched a bunch of router descriptors in
1343 * <b>body</b>. The list <b>which</b>, if present, holds digests for
1344 * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1345 * is true, or identity digests otherwise. Parse the descriptors, validate
1346 * them, and annotate them as having purpose <b>purpose</b> and as having been
1347 * downloaded from <b>source</b>.
1349 * Return the number of routers actually added. */
1350 static int
1351 load_downloaded_routers(const char *body, smartlist_t *which,
1352 int descriptor_digests,
1353 int router_purpose,
1354 const char *source)
1356 char buf[256];
1357 char time_buf[ISO_TIME_LEN+1];
1358 int added = 0;
1359 int general = router_purpose == ROUTER_PURPOSE_GENERAL;
1360 format_iso_time(time_buf, time(NULL));
1361 tor_assert(source);
1363 if (tor_snprintf(buf, sizeof(buf),
1364 "@downloaded-at %s\n"
1365 "@source %s\n"
1366 "%s%s%s", time_buf, escaped(source),
1367 !general ? "@purpose " : "",
1368 !general ? router_purpose_to_string(router_purpose) : "",
1369 !general ? "\n" : "")<0)
1370 return added;
1372 added = router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1373 descriptor_digests, buf);
1374 control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
1375 count_loading_descriptors_progress());
1376 return added;
1379 /** We are a client, and we've finished reading the server's
1380 * response. Parse it and act appropriately.
1382 * If we're still happy with using this directory server in the future, return
1383 * 0. Otherwise return -1; and the caller should consider trying the request
1384 * again.
1386 * The caller will take care of marking the connection for close.
1388 static int
1389 connection_dir_client_reached_eof(dir_connection_t *conn)
1391 char *body;
1392 char *headers;
1393 char *reason = NULL;
1394 size_t body_len=0, orig_len=0;
1395 int status_code;
1396 time_t date_header=0;
1397 long delta;
1398 compress_method_t compression;
1399 int plausible;
1400 int skewed=0;
1401 int allow_partial = (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
1402 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO);
1403 int was_compressed=0;
1404 time_t now = time(NULL);
1406 switch (fetch_from_buf_http(conn->_base.inbuf,
1407 &headers, MAX_HEADERS_SIZE,
1408 &body, &body_len, MAX_DIR_DL_SIZE,
1409 allow_partial)) {
1410 case -1: /* overflow */
1411 log_warn(LD_PROTOCOL,
1412 "'fetch' response too large (server '%s:%d'). Closing.",
1413 conn->_base.address, conn->_base.port);
1414 return -1;
1415 case 0:
1416 log_info(LD_HTTP,
1417 "'fetch' response not all here, but we're at eof. Closing.");
1418 return -1;
1419 /* case 1, fall through */
1421 orig_len = body_len;
1423 if (parse_http_response(headers, &status_code, &date_header,
1424 &compression, &reason) < 0) {
1425 log_warn(LD_HTTP,"Unparseable headers (server '%s:%d'). Closing.",
1426 conn->_base.address, conn->_base.port);
1427 tor_free(body); tor_free(headers);
1428 return -1;
1430 if (!reason) reason = tor_strdup("[no reason given]");
1432 log_debug(LD_DIR,
1433 "Received response from directory server '%s:%d': %d %s",
1434 conn->_base.address, conn->_base.port, status_code,
1435 escaped(reason));
1437 /* now check if it's got any hints for us about our IP address. */
1438 if (conn->dirconn_direct) {
1439 char *guess = http_get_header(headers, X_ADDRESS_HEADER);
1440 if (guess) {
1441 router_new_address_suggestion(guess, conn);
1442 tor_free(guess);
1446 if (date_header > 0) {
1447 /* The date header was written very soon after we sent our request,
1448 * so compute the skew as the difference between sending the request
1449 * and the date header. (We used to check now-date_header, but that's
1450 * inaccurate if we spend a lot of time downloading.)
1452 delta = conn->_base.timestamp_lastwritten - date_header;
1453 if (labs(delta)>ALLOW_DIRECTORY_TIME_SKEW) {
1454 char dbuf[64];
1455 int trusted = router_digest_is_trusted_dir(conn->identity_digest);
1456 format_time_interval(dbuf, sizeof(dbuf), delta);
1457 log_fn(trusted ? LOG_WARN : LOG_INFO,
1458 LD_HTTP,
1459 "Received directory with skewed time (server '%s:%d'): "
1460 "It seems that our clock is %s by %s, or that theirs is %s. "
1461 "Tor requires an accurate clock to work: please check your time, "
1462 "timezone, and date settings.",
1463 conn->_base.address, conn->_base.port,
1464 delta>0 ? "ahead" : "behind", dbuf,
1465 delta>0 ? "behind" : "ahead");
1466 skewed = 1; /* don't check the recommended-versions line */
1467 control_event_general_status(trusted ? LOG_WARN : LOG_NOTICE,
1468 "CLOCK_SKEW SKEW=%ld SOURCE=DIRSERV:%s:%d",
1469 delta, conn->_base.address, conn->_base.port);
1470 } else {
1471 log_debug(LD_HTTP, "Time on received directory is within tolerance; "
1472 "we are %ld seconds skewed. (That's okay.)", delta);
1475 (void) skewed; /* skewed isn't used yet. */
1477 if (status_code == 503 && body_len < 16) {
1478 routerstatus_t *rs;
1479 trusted_dir_server_t *ds;
1480 log_info(LD_DIR,"Received http status code %d (%s) from server "
1481 "'%s:%d'. I'll try again soon.",
1482 status_code, escaped(reason), conn->_base.address,
1483 conn->_base.port);
1484 if ((rs = router_get_consensus_status_by_id(conn->identity_digest)))
1485 rs->last_dir_503_at = now;
1486 if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
1487 ds->fake_status.last_dir_503_at = now;
1489 tor_free(body); tor_free(headers); tor_free(reason);
1490 return -1;
1491 } else if (status_code == 503) {
1492 /* XXXX022 Remove this once every server with bug 539 is obsolete. */
1493 log_info(LD_DIR, "Server at '%s:%d' sent us a 503 response, but included "
1494 "a body anyway. We'll pretend it gave us a 200.",
1495 conn->_base.address, conn->_base.port);
1496 status_code = 200;
1499 plausible = body_is_plausible(body, body_len, conn->_base.purpose);
1500 if (compression != NO_METHOD || !plausible) {
1501 char *new_body = NULL;
1502 size_t new_len = 0;
1503 compress_method_t guessed = detect_compression_method(body, body_len);
1504 if (compression == UNKNOWN_METHOD || guessed != compression) {
1505 /* Tell the user if we don't believe what we're told about compression.*/
1506 const char *description1, *description2;
1507 if (compression == ZLIB_METHOD)
1508 description1 = "as deflated";
1509 else if (compression == GZIP_METHOD)
1510 description1 = "as gzipped";
1511 else if (compression == NO_METHOD)
1512 description1 = "as uncompressed";
1513 else
1514 description1 = "with an unknown Content-Encoding";
1515 if (guessed == ZLIB_METHOD)
1516 description2 = "deflated";
1517 else if (guessed == GZIP_METHOD)
1518 description2 = "gzipped";
1519 else if (!plausible)
1520 description2 = "confusing binary junk";
1521 else
1522 description2 = "uncompressed";
1524 log_info(LD_HTTP, "HTTP body from server '%s:%d' was labeled %s, "
1525 "but it seems to be %s.%s",
1526 conn->_base.address, conn->_base.port, description1,
1527 description2,
1528 (compression>0 && guessed>0)?" Trying both.":"");
1530 /* Try declared compression first if we can. */
1531 if (compression == GZIP_METHOD || compression == ZLIB_METHOD)
1532 tor_gzip_uncompress(&new_body, &new_len, body, body_len, compression,
1533 !allow_partial, LOG_PROTOCOL_WARN);
1534 /* Okay, if that didn't work, and we think that it was compressed
1535 * differently, try that. */
1536 if (!new_body &&
1537 (guessed == GZIP_METHOD || guessed == ZLIB_METHOD) &&
1538 compression != guessed)
1539 tor_gzip_uncompress(&new_body, &new_len, body, body_len, guessed,
1540 !allow_partial, LOG_PROTOCOL_WARN);
1541 /* If we're pretty sure that we have a compressed directory, and
1542 * we didn't manage to uncompress it, then warn and bail. */
1543 if (!plausible && !new_body) {
1544 log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
1545 "Unable to decompress HTTP body (server '%s:%d').",
1546 conn->_base.address, conn->_base.port);
1547 tor_free(body); tor_free(headers); tor_free(reason);
1548 return -1;
1550 if (new_body) {
1551 tor_free(body);
1552 body = new_body;
1553 body_len = new_len;
1554 was_compressed = 1;
1558 if (conn->_base.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
1559 smartlist_t *which = NULL;
1560 v2_networkstatus_source_t source;
1561 char *cp;
1562 log_info(LD_DIR,"Received networkstatus objects (size %d) from server "
1563 "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
1564 if (status_code != 200) {
1565 log_warn(LD_DIR,
1566 "Received http status code %d (%s) from server "
1567 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1568 status_code, escaped(reason), conn->_base.address,
1569 conn->_base.port, conn->requested_resource);
1570 tor_free(body); tor_free(headers); tor_free(reason);
1571 connection_dir_download_networkstatus_failed(conn, status_code);
1572 return -1;
1574 if (conn->requested_resource &&
1575 !strcmpstart(conn->requested_resource,"fp/")) {
1576 source = NS_FROM_DIR_BY_FP;
1577 which = smartlist_create();
1578 dir_split_resource_into_fingerprints(conn->requested_resource+3,
1579 which, NULL, 0, 0);
1580 } else if (conn->requested_resource &&
1581 !strcmpstart(conn->requested_resource, "all")) {
1582 source = NS_FROM_DIR_ALL;
1583 which = smartlist_create();
1584 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1585 trusted_dir_server_t *, ds,
1587 char *hex = tor_malloc(HEX_DIGEST_LEN+1);
1588 base16_encode(hex, HEX_DIGEST_LEN+1, ds->digest, DIGEST_LEN);
1589 smartlist_add(which, hex);
1591 } else {
1592 /* XXXX Can we even end up here? -- weasel*/
1593 source = NS_FROM_DIR_BY_FP;
1594 log_warn(LD_BUG, "We received a networkstatus but we didn't ask "
1595 "for it by fp, nor did we ask for all.");
1597 cp = body;
1598 while (*cp) {
1599 char *next = strstr(cp, "\nnetwork-status-version");
1600 if (next)
1601 next[1] = '\0';
1602 /* learn from it, and then remove it from 'which' */
1603 if (router_set_networkstatus_v2(cp, now, source, which)<0)
1604 break;
1605 if (next) {
1606 next[1] = 'n';
1607 cp = next+1;
1608 } else
1609 break;
1611 /* launches router downloads as needed */
1612 routers_update_all_from_networkstatus(now, 2);
1613 directory_info_has_arrived(now, 0);
1614 if (which) {
1615 if (smartlist_len(which)) {
1616 dir_networkstatus_download_failed(which, status_code);
1618 SMARTLIST_FOREACH(which, char *, s, tor_free(s));
1619 smartlist_free(which);
1623 if (conn->_base.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
1624 int r;
1625 if (status_code != 200) {
1626 int severity = (status_code == 304) ? LOG_INFO : LOG_WARN;
1627 log(severity, LD_DIR,
1628 "Received http status code %d (%s) from server "
1629 "'%s:%d' while fetching consensus directory.",
1630 status_code, escaped(reason), conn->_base.address,
1631 conn->_base.port);
1632 tor_free(body); tor_free(headers); tor_free(reason);
1633 networkstatus_consensus_download_failed(status_code);
1634 return -1;
1636 log_info(LD_DIR,"Received consensus directory (size %d) from server "
1637 "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
1638 if ((r=networkstatus_set_current_consensus(body, 0))<0) {
1639 log_fn(r<-1?LOG_WARN:LOG_INFO, LD_DIR,
1640 "Unable to load consensus directory downloaded from "
1641 "server '%s:%d'. I'll try again soon.",
1642 conn->_base.address, conn->_base.port);
1643 tor_free(body); tor_free(headers); tor_free(reason);
1644 networkstatus_consensus_download_failed(0);
1645 return -1;
1647 /* launches router downloads as needed */
1648 routers_update_all_from_networkstatus(now, 3);
1649 directory_info_has_arrived(now, 0);
1650 log_info(LD_DIR, "Successfully loaded consensus.");
1653 if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
1654 if (status_code != 200) {
1655 log_warn(LD_DIR,
1656 "Received http status code %d (%s) from server "
1657 "'%s:%d' while fetching \"/tor/keys/%s\".",
1658 status_code, escaped(reason), conn->_base.address,
1659 conn->_base.port, conn->requested_resource);
1660 connection_dir_download_cert_failed(conn, status_code);
1661 tor_free(body); tor_free(headers); tor_free(reason);
1662 return -1;
1664 log_info(LD_DIR,"Received authority certificates (size %d) from server "
1665 "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
1666 if (trusted_dirs_load_certs_from_string(body, 0, 1)<0) {
1667 log_warn(LD_DIR, "Unable to parse fetched certificates");
1668 connection_dir_download_cert_failed(conn, status_code);
1669 } else {
1670 directory_info_has_arrived(now, 0);
1671 log_info(LD_DIR, "Successfully loaded certificates from fetch.");
1674 if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
1675 const char *msg;
1676 int st;
1677 log_info(LD_DIR,"Got votes (size %d) from server %s:%d",
1678 (int) body_len, conn->_base.address, conn->_base.port);
1679 if (status_code != 200) {
1680 log_warn(LD_DIR,
1681 "Received http status code %d (%s) from server "
1682 "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".",
1683 status_code, escaped(reason), conn->_base.address,
1684 conn->_base.port, conn->requested_resource);
1685 tor_free(body); tor_free(headers); tor_free(reason);
1686 return -1;
1688 dirvote_add_vote(body, &msg, &st);
1689 if (st > 299) {
1690 log_warn(LD_DIR, "Error adding retrieved vote: %s", msg);
1691 } else {
1692 log_info(LD_DIR, "Added vote(s) successfully [msg: %s]", msg);
1695 if (conn->_base.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
1696 const char *msg = NULL;
1697 log_info(LD_DIR,"Got detached signatures (size %d) from server %s:%d",
1698 (int) body_len, conn->_base.address, conn->_base.port);
1699 if (status_code != 200) {
1700 log_warn(LD_DIR,
1701 "Received http status code %d (%s) from server "
1702 "'%s:%d' while fetching \"/tor/status-vote/consensus-signatures.z\".",
1703 status_code, escaped(reason), conn->_base.address,
1704 conn->_base.port);
1705 tor_free(body); tor_free(headers); tor_free(reason);
1706 return -1;
1708 if (dirvote_add_signatures(body, conn->_base.address, &msg)<0) {
1709 log_warn(LD_DIR, "Problem adding detached signatures from %s:%d: %s",
1710 conn->_base.address, conn->_base.port, msg?msg:"???");
1714 if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
1715 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
1716 int was_ei = conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO;
1717 smartlist_t *which = NULL;
1718 int n_asked_for = 0;
1719 int descriptor_digests = conn->requested_resource &&
1720 !strcmpstart(conn->requested_resource,"d/");
1721 log_info(LD_DIR,"Received %s (size %d) from server '%s:%d'",
1722 was_ei ? "extra server info" : "server info",
1723 (int)body_len, conn->_base.address, conn->_base.port);
1724 if (conn->requested_resource &&
1725 (!strcmpstart(conn->requested_resource,"d/") ||
1726 !strcmpstart(conn->requested_resource,"fp/"))) {
1727 which = smartlist_create();
1728 dir_split_resource_into_fingerprints(conn->requested_resource +
1729 (descriptor_digests ? 2 : 3),
1730 which, NULL, 0, 0);
1731 n_asked_for = smartlist_len(which);
1733 if (status_code != 200) {
1734 int dir_okay = status_code == 404 ||
1735 (status_code == 400 && !strcmp(reason, "Servers unavailable."));
1736 /* 404 means that it didn't have them; no big deal.
1737 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1738 log_fn(dir_okay ? LOG_INFO : LOG_WARN, LD_DIR,
1739 "Received http status code %d (%s) from server '%s:%d' "
1740 "while fetching \"/tor/server/%s\". I'll try again soon.",
1741 status_code, escaped(reason), conn->_base.address,
1742 conn->_base.port, conn->requested_resource);
1743 if (!which) {
1744 connection_dir_download_routerdesc_failed(conn);
1745 } else {
1746 dir_routerdesc_download_failed(which, status_code,
1747 conn->router_purpose,
1748 was_ei, descriptor_digests);
1749 SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
1750 smartlist_free(which);
1752 tor_free(body); tor_free(headers); tor_free(reason);
1753 return dir_okay ? 0 : -1;
1755 /* Learn the routers, assuming we requested by fingerprint or "all"
1756 * or "authority".
1758 * We use "authority" to fetch our own descriptor for
1759 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1760 * the output of "authority" requests unless we are using bridges,
1761 * since otherwise they'll be the response from reachability tests,
1762 * and we don't really want to add that to our routerlist. */
1763 if (which || (conn->requested_resource &&
1764 (!strcmpstart(conn->requested_resource, "all") ||
1765 (!strcmpstart(conn->requested_resource, "authority") &&
1766 get_options()->UseBridges)))) {
1767 /* as we learn from them, we remove them from 'which' */
1768 if (was_ei) {
1769 router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which,
1770 descriptor_digests);
1771 } else {
1772 //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1773 // descriptor_digests, conn->router_purpose);
1774 if (load_downloaded_routers(body, which, descriptor_digests,
1775 conn->router_purpose,
1776 conn->_base.address))
1777 directory_info_has_arrived(now, 0);
1780 if (which) { /* mark remaining ones as failed */
1781 log_info(LD_DIR, "Received %d/%d %s requested from %s:%d",
1782 n_asked_for-smartlist_len(which), n_asked_for,
1783 was_ei ? "extra-info documents" : "router descriptors",
1784 conn->_base.address, (int)conn->_base.port);
1785 if (smartlist_len(which)) {
1786 dir_routerdesc_download_failed(which, status_code,
1787 conn->router_purpose,
1788 was_ei, descriptor_digests);
1790 SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
1791 smartlist_free(which);
1793 if (directory_conn_is_self_reachability_test(conn))
1794 router_dirport_found_reachable();
1797 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_DIR) {
1798 switch (status_code) {
1799 case 200: {
1800 trusted_dir_server_t *ds =
1801 router_get_trusteddirserver_by_digest(conn->identity_digest);
1802 char *rejected_hdr = http_get_header(headers,
1803 "X-Descriptor-Not-New: ");
1804 int rejected = 0;
1805 if (rejected_hdr) {
1806 if (!strcmp(rejected_hdr, "Yes")) {
1807 log_info(LD_GENERAL,
1808 "Authority '%s' declined our descriptor (not new)",
1809 ds->nickname);
1810 /* XXXX use this information; be sure to upload next one
1811 * sooner. -NM */
1812 /* XXXX021 On further thought, the task above implies that we're
1813 * basing our regenerate-descriptor time on when we uploaded the
1814 * last descriptor, not on the published time of the last
1815 * descriptor. If those are different, that's a bad thing to
1816 * do. -NM */
1817 rejected = 1;
1819 tor_free(rejected_hdr);
1821 log_info(LD_GENERAL,"eof (status 200) after uploading server "
1822 "descriptor: finished.");
1823 control_event_server_status(
1824 LOG_NOTICE, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1825 conn->_base.address, conn->_base.port);
1827 ds->has_accepted_serverdesc = 1;
1828 if (directories_have_accepted_server_descriptor())
1829 control_event_server_status(LOG_NOTICE, "GOOD_SERVER_DESCRIPTOR");
1831 break;
1832 case 400:
1833 log_warn(LD_GENERAL,"http status 400 (%s) response from "
1834 "dirserver '%s:%d'. Please correct.",
1835 escaped(reason), conn->_base.address, conn->_base.port);
1836 control_event_server_status(LOG_WARN,
1837 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1838 conn->_base.address, conn->_base.port, escaped(reason));
1839 break;
1840 default:
1841 log_warn(LD_GENERAL,
1842 "http status %d (%s) reason unexpected while uploading "
1843 "descriptor to server '%s:%d').",
1844 status_code, escaped(reason), conn->_base.address,
1845 conn->_base.port);
1846 break;
1848 /* return 0 in all cases, since we don't want to mark any
1849 * dirservers down just because they don't like us. */
1852 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_VOTE) {
1853 switch (status_code) {
1854 case 200: {
1855 log_notice(LD_DIR,"Uploaded a vote to dirserver %s:%d",
1856 conn->_base.address, conn->_base.port);
1858 break;
1859 case 400:
1860 log_warn(LD_DIR,"http status 400 (%s) response after uploading "
1861 "vote to dirserver '%s:%d'. Please correct.",
1862 escaped(reason), conn->_base.address, conn->_base.port);
1863 break;
1864 default:
1865 log_warn(LD_GENERAL,
1866 "http status %d (%s) reason unexpected while uploading "
1867 "vote to server '%s:%d').",
1868 status_code, escaped(reason), conn->_base.address,
1869 conn->_base.port);
1870 break;
1872 /* return 0 in all cases, since we don't want to mark any
1873 * dirservers down just because they don't like us. */
1876 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_SIGNATURES) {
1877 switch (status_code) {
1878 case 200: {
1879 log_notice(LD_DIR,"Uploaded signature(s) to dirserver %s:%d",
1880 conn->_base.address, conn->_base.port);
1882 break;
1883 case 400:
1884 log_warn(LD_DIR,"http status 400 (%s) response after uploading "
1885 "signatures to dirserver '%s:%d'. Please correct.",
1886 escaped(reason), conn->_base.address, conn->_base.port);
1887 break;
1888 default:
1889 log_warn(LD_GENERAL,
1890 "http status %d (%s) reason unexpected while uploading "
1891 "signatures to server '%s:%d').",
1892 status_code, escaped(reason), conn->_base.address,
1893 conn->_base.port);
1894 break;
1896 /* return 0 in all cases, since we don't want to mark any
1897 * dirservers down just because they don't like us. */
1900 if (conn->_base.purpose == DIR_PURPOSE_FETCH_RENDDESC) {
1901 tor_assert(conn->rend_data);
1902 log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
1903 "(%s))",
1904 (int)body_len, status_code, escaped(reason));
1905 switch (status_code) {
1906 case 200:
1907 if (rend_cache_store(body, body_len, 0) < -1) {
1908 log_warn(LD_REND,"Failed to parse rendezvous descriptor.");
1909 /* Any pending rendezvous attempts will notice when
1910 * connection_about_to_close_connection()
1911 * cleans this dir conn up. */
1912 /* We could retry. But since v0 descriptors are going out of
1913 * style, it isn't worth the hassle. We'll do better in v2. */
1914 } else {
1915 /* Success, or at least there's a v2 descriptor already
1916 * present. Notify pending connections about this. */
1917 conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
1918 rend_client_desc_trynow(conn->rend_data->onion_address, -1);
1920 break;
1921 case 404:
1922 /* Not there. Pending connections will be notified when
1923 * connection_about_to_close_connection() cleans this conn up. */
1924 break;
1925 case 400:
1926 log_warn(LD_REND,
1927 "http status 400 (%s). Dirserver didn't like our "
1928 "rendezvous query?", escaped(reason));
1929 break;
1930 default:
1931 log_warn(LD_REND,"http status %d (%s) response unexpected while "
1932 "fetching hidden service descriptor (server '%s:%d').",
1933 status_code, escaped(reason), conn->_base.address,
1934 conn->_base.port);
1935 break;
1939 if (conn->_base.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
1940 tor_assert(conn->rend_data);
1941 log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
1942 "(%s))",
1943 (int)body_len, status_code, escaped(reason));
1944 switch (status_code) {
1945 case 200:
1946 switch (rend_cache_store_v2_desc_as_client(body, conn->rend_data)) {
1947 case -2:
1948 log_warn(LD_REND,"Fetching v2 rendezvous descriptor failed. "
1949 "Retrying at another directory.");
1950 /* We'll retry when connection_about_to_close_connection()
1951 * cleans this dir conn up. */
1952 break;
1953 case -1:
1954 /* We already have a v0 descriptor here. Ignoring this one
1955 * and _not_ performing another request. */
1956 log_info(LD_REND, "Successfully fetched v2 rendezvous "
1957 "descriptor, but we already have a v0 descriptor.");
1958 conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
1959 break;
1960 default:
1961 /* success. notify pending connections about this. */
1962 log_info(LD_REND, "Successfully fetched v2 rendezvous "
1963 "descriptor.");
1964 conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
1965 rend_client_desc_trynow(conn->rend_data->onion_address, -1);
1966 break;
1968 break;
1969 case 404:
1970 /* Not there. We'll retry when
1971 * connection_about_to_close_connection() cleans this conn up. */
1972 log_info(LD_REND,"Fetching v2 rendezvous descriptor failed: "
1973 "Retrying at another directory.");
1974 break;
1975 case 400:
1976 log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
1977 "http status 400 (%s). Dirserver didn't like our "
1978 "v2 rendezvous query? Retrying at another directory.",
1979 escaped(reason));
1980 break;
1981 default:
1982 log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
1983 "http status %d (%s) response unexpected while "
1984 "fetching v2 hidden service descriptor (server '%s:%d'). "
1985 "Retrying at another directory.",
1986 status_code, escaped(reason), conn->_base.address,
1987 conn->_base.port);
1988 break;
1992 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_RENDDESC ||
1993 conn->_base.purpose == DIR_PURPOSE_UPLOAD_RENDDESC_V2) {
1994 log_info(LD_REND,"Uploaded rendezvous descriptor (status %d "
1995 "(%s))",
1996 status_code, escaped(reason));
1997 switch (status_code) {
1998 case 200:
1999 log_info(LD_REND,
2000 "Uploading rendezvous descriptor: finished with status "
2001 "200 (%s)", escaped(reason));
2002 break;
2003 case 400:
2004 log_warn(LD_REND,"http status 400 (%s) response from dirserver "
2005 "'%s:%d'. Malformed rendezvous descriptor?",
2006 escaped(reason), conn->_base.address, conn->_base.port);
2007 break;
2008 case 503:
2009 log_info(LD_REND,"http status 503 (%s) response from dirserver "
2010 "'%s:%d'. Node is (currently) not acting as v2 hidden "
2011 "service directory.",
2012 escaped(reason), conn->_base.address, conn->_base.port);
2013 break;
2014 default:
2015 log_warn(LD_REND,"http status %d (%s) response unexpected (server "
2016 "'%s:%d').",
2017 status_code, escaped(reason), conn->_base.address,
2018 conn->_base.port);
2019 break;
2022 note_client_request(conn->_base.purpose, was_compressed, orig_len);
2023 tor_free(body); tor_free(headers); tor_free(reason);
2024 return 0;
2027 /** Called when a directory connection reaches EOF. */
2029 connection_dir_reached_eof(dir_connection_t *conn)
2031 int retval;
2032 if (conn->_base.state != DIR_CONN_STATE_CLIENT_READING) {
2033 log_info(LD_HTTP,"conn reached eof, not reading. [state=%d] Closing.",
2034 conn->_base.state);
2035 connection_close_immediate(TO_CONN(conn)); /* error: give up on flushing */
2036 connection_mark_for_close(TO_CONN(conn));
2037 return -1;
2040 retval = connection_dir_client_reached_eof(conn);
2041 if (retval == 0) /* success */
2042 conn->_base.state = DIR_CONN_STATE_CLIENT_FINISHED;
2043 connection_mark_for_close(TO_CONN(conn));
2044 return retval;
2047 /** If any directory object is arriving, and it's over 10MB large, we're
2048 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
2049 * ask for more than 96 router descriptors at a time.)
2051 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
2053 /** Read handler for directory connections. (That's connections <em>to</em>
2054 * directory servers and connections <em>at</em> directory servers.)
2057 connection_dir_process_inbuf(dir_connection_t *conn)
2059 tor_assert(conn);
2060 tor_assert(conn->_base.type == CONN_TYPE_DIR);
2062 /* Directory clients write, then read data until they receive EOF;
2063 * directory servers read data until they get an HTTP command, then
2064 * write their response (when it's finished flushing, they mark for
2065 * close).
2068 /* If we're on the dirserver side, look for a command. */
2069 if (conn->_base.state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
2070 if (directory_handle_command(conn) < 0) {
2071 connection_mark_for_close(TO_CONN(conn));
2072 return -1;
2074 return 0;
2077 if (buf_datalen(conn->_base.inbuf) > MAX_DIRECTORY_OBJECT_SIZE) {
2078 log_warn(LD_HTTP, "Too much data received from directory connection: "
2079 "denial of service attempt, or you need to upgrade?");
2080 connection_mark_for_close(TO_CONN(conn));
2081 return -1;
2084 if (!conn->_base.inbuf_reached_eof)
2085 log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
2086 return 0;
2089 /** Create an http response for the client <b>conn</b> out of
2090 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
2092 static void
2093 write_http_status_line(dir_connection_t *conn, int status,
2094 const char *reason_phrase)
2096 char buf[256];
2097 if (tor_snprintf(buf, sizeof(buf), "HTTP/1.0 %d %s\r\n\r\n",
2098 status, reason_phrase ? reason_phrase : "OK") < 0) {
2099 log_warn(LD_BUG,"status line too long.");
2100 return;
2102 connection_write_to_buf(buf, strlen(buf), TO_CONN(conn));
2105 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
2106 * with <b>type</b> as the Content-Type.
2108 * If <b>length</b> is nonnegative, it is the Content-Length.
2109 * If <b>encoding</b> is provided, it is the Content-Encoding.
2110 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
2111 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
2112 static void
2113 write_http_response_header_impl(dir_connection_t *conn, ssize_t length,
2114 const char *type, const char *encoding,
2115 const char *extra_headers,
2116 long cache_lifetime)
2118 char date[RFC1123_TIME_LEN+1];
2119 char tmp[1024];
2120 char *cp;
2121 time_t now = time(NULL);
2123 tor_assert(conn);
2125 format_rfc1123_time(date, now);
2126 cp = tmp;
2127 tor_snprintf(cp, sizeof(tmp),
2128 "HTTP/1.0 200 OK\r\nDate: %s\r\n",
2129 date);
2130 cp += strlen(tmp);
2131 if (type) {
2132 tor_snprintf(cp, sizeof(tmp)-(cp-tmp), "Content-Type: %s\r\n", type);
2133 cp += strlen(cp);
2135 if (!is_local_addr(&conn->_base.addr)) {
2136 /* Don't report the source address for a nearby/private connection.
2137 * Otherwise we tend to mis-report in cases where incoming ports are
2138 * being forwarded to a Tor server running behind the firewall. */
2139 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2140 X_ADDRESS_HEADER "%s\r\n", conn->_base.address);
2141 cp += strlen(cp);
2143 if (encoding) {
2144 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2145 "Content-Encoding: %s\r\n", encoding);
2146 cp += strlen(cp);
2148 if (length >= 0) {
2149 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2150 "Content-Length: %ld\r\n", (long)length);
2151 cp += strlen(cp);
2153 if (cache_lifetime > 0) {
2154 char expbuf[RFC1123_TIME_LEN+1];
2155 format_rfc1123_time(expbuf, now + cache_lifetime);
2156 /* We could say 'Cache-control: max-age=%d' here if we start doing
2157 * http/1.1 */
2158 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2159 "Expires: %s\r\n", expbuf);
2160 cp += strlen(cp);
2161 } else if (cache_lifetime == 0) {
2162 /* We could say 'Cache-control: no-cache' here if we start doing
2163 * http/1.1 */
2164 strlcpy(cp, "Pragma: no-cache\r\n", sizeof(tmp)-(cp-tmp));
2165 cp += strlen(cp);
2167 if (extra_headers) {
2168 strlcpy(cp, extra_headers, sizeof(tmp)-(cp-tmp));
2169 cp += strlen(cp);
2171 if (sizeof(tmp)-(cp-tmp) > 3)
2172 memcpy(cp, "\r\n", 3);
2173 else
2174 tor_assert(0);
2175 connection_write_to_buf(tmp, strlen(tmp), TO_CONN(conn));
2178 /** As write_http_response_header_impl, but sets encoding and content-typed
2179 * based on whether the response will be <b>compressed</b> or not. */
2180 static void
2181 write_http_response_header(dir_connection_t *conn, ssize_t length,
2182 int compressed, long cache_lifetime)
2184 write_http_response_header_impl(conn, length,
2185 compressed?"application/octet-stream":"text/plain",
2186 compressed?"deflate":"identity",
2187 NULL,
2188 cache_lifetime);
2191 #ifdef INSTRUMENT_DOWNLOADS
2192 typedef struct request_t {
2193 uint64_t bytes; /**< How many bytes have we transferred? */
2194 uint64_t count; /**< How many requests have we made? */
2195 } request_t;
2197 /** Map used to keep track of how much data we've up/downloaded in what kind
2198 * of request. Maps from request type to pointer to request_t. */
2199 static strmap_t *request_map = NULL;
2201 /** Record that a client request of <b>purpose</b> was made, and that
2202 * <b>bytes</b> bytes of possibly <b>compressed</b> data were sent/received.
2203 * Used to keep track of how much we've up/downloaded in what kind of
2204 * request. */
2205 static void
2206 note_client_request(int purpose, int compressed, size_t bytes)
2208 char *key;
2209 const char *kind = NULL;
2210 switch (purpose) {
2211 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS: kind = "dl/status"; break;
2212 case DIR_PURPOSE_FETCH_CONSENSUS: kind = "dl/consensus"; break;
2213 case DIR_PURPOSE_FETCH_CERTIFICATE: kind = "dl/cert"; break;
2214 case DIR_PURPOSE_FETCH_STATUS_VOTE: kind = "dl/vote"; break;
2215 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES: kind = "dl/detached_sig";
2216 break;
2217 case DIR_PURPOSE_FETCH_SERVERDESC: kind = "dl/server"; break;
2218 case DIR_PURPOSE_FETCH_EXTRAINFO: kind = "dl/extra"; break;
2219 case DIR_PURPOSE_UPLOAD_DIR: kind = "dl/ul-dir"; break;
2220 case DIR_PURPOSE_UPLOAD_VOTE: kind = "dl/ul-vote"; break;
2221 case DIR_PURPOSE_UPLOAD_SIGNATURES: kind = "dl/ul-sig"; break;
2222 case DIR_PURPOSE_FETCH_RENDDESC: kind = "dl/rend"; break;
2223 case DIR_PURPOSE_FETCH_RENDDESC_V2: kind = "dl/rend2"; break;
2224 case DIR_PURPOSE_UPLOAD_RENDDESC: kind = "dl/ul-rend"; break;
2225 case DIR_PURPOSE_UPLOAD_RENDDESC_V2: kind = "dl/ul-rend2"; break;
2227 if (kind) {
2228 key = tor_malloc(256);
2229 tor_snprintf(key, 256, "%s%s", kind, compressed?".z":"");
2230 } else {
2231 key = tor_malloc(256);
2232 tor_snprintf(key, 256, "unknown purpose (%d)%s",
2233 purpose, compressed?".z":"");
2235 note_request(key, bytes);
2236 tor_free(key);
2239 /** Helper: initialize the request map to instrument downloads. */
2240 static void
2241 ensure_request_map_initialized(void)
2243 if (!request_map)
2244 request_map = strmap_new();
2247 /** Called when we just transmitted or received <b>bytes</b> worth of data
2248 * because of a request of type <b>key</b> (an arbitrary identifier): adds
2249 * <b>bytes</b> to the total associated with key. */
2250 void
2251 note_request(const char *key, size_t bytes)
2253 request_t *r;
2254 ensure_request_map_initialized();
2256 r = strmap_get(request_map, key);
2257 if (!r) {
2258 r = tor_malloc_zero(sizeof(request_t));
2259 strmap_set(request_map, key, r);
2261 r->bytes += bytes;
2262 r->count++;
2265 /** Return a newly allocated string holding a summary of bytes used per
2266 * request type. */
2267 char *
2268 directory_dump_request_log(void)
2270 smartlist_t *lines;
2271 char tmp[256];
2272 char *result;
2273 strmap_iter_t *iter;
2275 ensure_request_map_initialized();
2277 lines = smartlist_create();
2279 for (iter = strmap_iter_init(request_map);
2280 !strmap_iter_done(iter);
2281 iter = strmap_iter_next(request_map, iter)) {
2282 const char *key;
2283 void *val;
2284 request_t *r;
2285 strmap_iter_get(iter, &key, &val);
2286 r = val;
2287 tor_snprintf(tmp, sizeof(tmp), "%s "U64_FORMAT" "U64_FORMAT"\n",
2288 key, U64_PRINTF_ARG(r->bytes), U64_PRINTF_ARG(r->count));
2289 smartlist_add(lines, tor_strdup(tmp));
2291 smartlist_sort_strings(lines);
2292 result = smartlist_join_strings(lines, "", 0, NULL);
2293 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
2294 smartlist_free(lines);
2295 return result;
2297 #else
2298 static void
2299 note_client_request(int purpose, int compressed, size_t bytes)
2301 (void)purpose;
2302 (void)compressed;
2303 (void)bytes;
2306 void
2307 note_request(const char *key, size_t bytes)
2309 (void)key;
2310 (void)bytes;
2313 char *
2314 directory_dump_request_log(void)
2316 return tor_strdup("Not supported.");
2318 #endif
2320 /** Decide whether a client would accept the consensus we have
2322 * Clients can say they only want a consensus if it's signed by more
2323 * than half the authorities in a list. They pass this list in
2324 * the url as "...consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>".
2326 * <b>fpr</b> may be an abbreviated fingerprint, i.e. only a left substring
2327 * of the full authority identity digest. (Only strings of even length,
2328 * i.e. encodings of full bytes, are handled correctly. In the case
2329 * of an odd number of hex digits the last one is silently ignored.)
2331 * Returns 1 if more than half of the requested authorities signed the
2332 * consensus, 0 otherwise.
2335 client_likes_consensus(networkstatus_t *v, const char *want_url)
2337 smartlist_t *want_authorities = smartlist_create();
2338 int need_at_least;
2339 int have = 0;
2341 dir_split_resource_into_fingerprints(want_url, want_authorities, NULL, 0, 0);
2342 need_at_least = smartlist_len(want_authorities)/2+1;
2343 SMARTLIST_FOREACH(want_authorities, const char *, d, {
2344 char want_digest[DIGEST_LEN];
2345 int want_len = strlen(d)/2;
2346 if (want_len > DIGEST_LEN)
2347 want_len = DIGEST_LEN;
2349 if (base16_decode(want_digest, DIGEST_LEN, d, want_len*2) < 0) {
2350 log_warn(LD_DIR,"Failed to decode requested authority digest %s.", d);
2351 continue;
2354 SMARTLIST_FOREACH(v->voters, networkstatus_voter_info_t *, vi, {
2355 if (vi->signature &&
2356 !memcmp(vi->identity_digest, want_digest, want_len)) {
2357 have++;
2358 break;
2362 /* early exit, if we already have enough */
2363 if (have >= need_at_least)
2364 break;
2367 SMARTLIST_FOREACH(want_authorities, char *, d, tor_free(d));
2368 smartlist_free(want_authorities);
2369 return (have >= need_at_least);
2372 /** Helper function: called when a dirserver gets a complete HTTP GET
2373 * request. Look for a request for a directory or for a rendezvous
2374 * service descriptor. On finding one, write a response into
2375 * conn-\>outbuf. If the request is unrecognized, send a 400.
2376 * Always return 0. */
2377 static int
2378 directory_handle_command_get(dir_connection_t *conn, const char *headers,
2379 const char *body, size_t body_len)
2381 size_t dlen;
2382 char *url, *url_mem, *header;
2383 or_options_t *options = get_options();
2384 time_t if_modified_since = 0;
2385 int compressed;
2386 size_t url_len;
2388 /* We ignore the body of a GET request. */
2389 (void)body;
2390 (void)body_len;
2392 log_debug(LD_DIRSERV,"Received GET command.");
2394 conn->_base.state = DIR_CONN_STATE_SERVER_WRITING;
2396 if (parse_http_url(headers, &url) < 0) {
2397 write_http_status_line(conn, 400, "Bad request");
2398 return 0;
2400 if ((header = http_get_header(headers, "If-Modified-Since: "))) {
2401 struct tm tm;
2402 if (parse_http_time(header, &tm) == 0) {
2403 if_modified_since = tor_timegm(&tm);
2405 /* The correct behavior on a malformed If-Modified-Since header is to
2406 * act as if no If-Modified-Since header had been given. */
2407 tor_free(header);
2409 log_debug(LD_DIRSERV,"rewritten url as '%s'.", url);
2411 url_mem = url;
2412 url_len = strlen(url);
2413 compressed = url_len > 2 && !strcmp(url+url_len-2, ".z");
2414 if (compressed) {
2415 url[url_len-2] = '\0';
2416 url_len -= 2;
2419 if (!strcmp(url,"/tor/")) {
2420 const char *frontpage = get_dirportfrontpage();
2422 if (frontpage) {
2423 dlen = strlen(frontpage);
2424 /* Let's return a disclaimer page (users shouldn't use V1 anymore,
2425 and caches don't fetch '/', so this is safe). */
2427 /* [We don't check for write_bucket_low here, since we want to serve
2428 * this page no matter what.] */
2429 note_request(url, dlen);
2430 write_http_response_header_impl(conn, dlen, "text/html", "identity",
2431 NULL, DIRPORTFRONTPAGE_CACHE_LIFETIME);
2432 connection_write_to_buf(frontpage, dlen, TO_CONN(conn));
2433 goto done;
2435 /* if no disclaimer file, fall through and continue */
2438 if (!strcmp(url,"/tor/") || !strcmp(url,"/tor/dir")) { /* v1 dir fetch */
2439 cached_dir_t *d = dirserv_get_directory();
2441 if (!d) {
2442 log_info(LD_DIRSERV,"Client asked for the mirrored directory, but we "
2443 "don't have a good one yet. Sending 503 Dir not available.");
2444 write_http_status_line(conn, 503, "Directory unavailable");
2445 goto done;
2447 if (d->published < if_modified_since) {
2448 write_http_status_line(conn, 304, "Not modified");
2449 goto done;
2452 dlen = compressed ? d->dir_z_len : d->dir_len;
2454 if (global_write_bucket_low(TO_CONN(conn), dlen, 1)) {
2455 log_debug(LD_DIRSERV,
2456 "Client asked for the mirrored directory, but we've been "
2457 "writing too many bytes lately. Sending 503 Dir busy.");
2458 write_http_status_line(conn, 503, "Directory busy, try again later");
2459 goto done;
2462 note_request(url, dlen);
2464 log_debug(LD_DIRSERV,"Dumping %sdirectory to client.",
2465 compressed?"compressed ":"");
2466 write_http_response_header(conn, dlen, compressed,
2467 FULL_DIR_CACHE_LIFETIME);
2468 conn->cached_dir = d;
2469 conn->cached_dir_offset = 0;
2470 if (!compressed)
2471 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
2472 ++d->refcnt;
2474 /* Prime the connection with some data. */
2475 conn->dir_spool_src = DIR_SPOOL_CACHED_DIR;
2476 connection_dirserv_flushed_some(conn);
2477 goto done;
2480 if (!strcmp(url,"/tor/running-routers")) { /* running-routers fetch */
2481 cached_dir_t *d = dirserv_get_runningrouters();
2482 if (!d) {
2483 write_http_status_line(conn, 503, "Directory unavailable");
2484 goto done;
2486 if (d->published < if_modified_since) {
2487 write_http_status_line(conn, 304, "Not modified");
2488 goto done;
2490 dlen = compressed ? d->dir_z_len : d->dir_len;
2492 if (global_write_bucket_low(TO_CONN(conn), dlen, 1)) {
2493 log_info(LD_DIRSERV,
2494 "Client asked for running-routers, but we've been "
2495 "writing too many bytes lately. Sending 503 Dir busy.");
2496 write_http_status_line(conn, 503, "Directory busy, try again later");
2497 goto done;
2499 note_request(url, dlen);
2500 write_http_response_header(conn, dlen, compressed,
2501 RUNNINGROUTERS_CACHE_LIFETIME);
2502 connection_write_to_buf(compressed ? d->dir_z : d->dir, dlen,
2503 TO_CONN(conn));
2504 goto done;
2507 if (!strcmpstart(url,"/tor/status/")
2508 || !strcmpstart(url, "/tor/status-vote/current/consensus")) {
2509 /* v2 or v3 network status fetch. */
2510 smartlist_t *dir_fps = smartlist_create();
2511 int is_v3 = !strcmpstart(url, "/tor/status-vote");
2512 const char *request_type = NULL;
2513 const char *key = url + strlen("/tor/status/");
2514 long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
2515 if (!is_v3) {
2516 dirserv_get_networkstatus_v2_fingerprints(dir_fps, key);
2517 if (!strcmpstart(key, "fp/"))
2518 request_type = compressed?"/tor/status/fp.z":"/tor/status/fp";
2519 else if (!strcmpstart(key, "authority"))
2520 request_type = compressed?"/tor/status/authority.z":
2521 "/tor/status/authority";
2522 else if (!strcmpstart(key, "all"))
2523 request_type = compressed?"/tor/status/all.z":"/tor/status/all";
2524 else
2525 request_type = "/tor/status/?";
2526 } else {
2527 networkstatus_t *v = networkstatus_get_latest_consensus();
2528 time_t now = time(NULL);
2529 #define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
2530 if (v &&
2531 !strcmpstart(url, CONSENSUS_URL_PREFIX) &&
2532 !client_likes_consensus(v, url + strlen(CONSENSUS_URL_PREFIX))) {
2533 write_http_status_line(conn, 404, "Consensus not signed by sufficient "
2534 "number of requested authorities");
2535 smartlist_free(dir_fps);
2536 goto done;
2539 smartlist_add(dir_fps, tor_memdup("\0\0\0\0\0\0\0\0\0\0"
2540 "\0\0\0\0\0\0\0\0\0\0", 20));
2541 request_type = compressed?"v3.z":"v3";
2542 lifetime = (v && v->fresh_until > now) ? v->fresh_until - now : 0;
2545 if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
2546 write_http_status_line(conn, 503, "Network status object unavailable");
2547 smartlist_free(dir_fps);
2548 goto done;
2551 if (!dirserv_remove_old_statuses(dir_fps, if_modified_since)) {
2552 write_http_status_line(conn, 404, "Not found");
2553 SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
2554 smartlist_free(dir_fps);
2555 goto done;
2556 } else if (!smartlist_len(dir_fps)) {
2557 write_http_status_line(conn, 304, "Not modified");
2558 SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
2559 smartlist_free(dir_fps);
2560 goto done;
2563 dlen = dirserv_estimate_data_size(dir_fps, 0, compressed);
2564 if (global_write_bucket_low(TO_CONN(conn), dlen, 2)) {
2565 log_debug(LD_DIRSERV,
2566 "Client asked for network status lists, but we've been "
2567 "writing too many bytes lately. Sending 503 Dir busy.");
2568 write_http_status_line(conn, 503, "Directory busy, try again later");
2569 SMARTLIST_FOREACH(dir_fps, char *, fp, tor_free(fp));
2570 smartlist_free(dir_fps);
2571 goto done;
2574 #ifdef ENABLE_GEOIP_STATS
2576 geoip_client_action_t act =
2577 is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
2578 struct in_addr in;
2579 if (tor_inet_aton((TO_CONN(conn))->address, &in))
2580 geoip_note_client_seen(act, ntohl(in.s_addr), time(NULL));
2582 #endif
2584 // note_request(request_type,dlen);
2585 (void) request_type;
2586 write_http_response_header(conn, -1, compressed,
2587 smartlist_len(dir_fps) == 1 ? lifetime : 0);
2588 conn->fingerprint_stack = dir_fps;
2589 if (! compressed)
2590 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
2592 /* Prime the connection with some data. */
2593 conn->dir_spool_src = DIR_SPOOL_NETWORKSTATUS;
2594 connection_dirserv_flushed_some(conn);
2595 goto done;
2598 if (!strcmpstart(url,"/tor/status-vote/current/") ||
2599 !strcmpstart(url,"/tor/status-vote/next/")) {
2600 /* XXXX If-modified-since is only implemented for the current
2601 * consensus: that's probably fine, since it's the only vote document
2602 * people fetch much. */
2603 int current;
2604 ssize_t body_len = 0;
2605 ssize_t estimated_len = 0;
2606 smartlist_t *items = smartlist_create();
2607 smartlist_t *dir_items = smartlist_create();
2608 int lifetime = 60; /* XXXX022 should actually use vote intervals. */
2609 url += strlen("/tor/status-vote/");
2610 current = !strcmpstart(url, "current/");
2611 url = strchr(url, '/');
2612 tor_assert(url);
2613 ++url;
2614 if (!strcmp(url, "consensus")) {
2615 const char *item;
2616 tor_assert(!current); /* we handle current consensus specially above,
2617 * since it wants to be spooled. */
2618 if ((item = dirvote_get_pending_consensus()))
2619 smartlist_add(items, (char*)item);
2620 } else if (!current && !strcmp(url, "consensus-signatures")) {
2621 /* XXXX the spec says that we should implement
2622 * current/consensus-signatures too. It doesn't seem to be needed,
2623 * though. */
2624 const char *item;
2625 if ((item=dirvote_get_pending_detached_signatures()))
2626 smartlist_add(items, (char*)item);
2627 } else if (!strcmp(url, "authority")) {
2628 const cached_dir_t *d;
2629 int flags = DGV_BY_ID |
2630 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
2631 if ((d=dirvote_get_vote(NULL, flags)))
2632 smartlist_add(dir_items, (cached_dir_t*)d);
2633 } else {
2634 const cached_dir_t *d;
2635 smartlist_t *fps = smartlist_create();
2636 int flags;
2637 if (!strcmpstart(url, "d/")) {
2638 url += 2;
2639 flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
2640 } else {
2641 flags = DGV_BY_ID |
2642 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
2644 dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
2645 SMARTLIST_FOREACH(fps, char *, fp, {
2646 if ((d = dirvote_get_vote(fp, flags)))
2647 smartlist_add(dir_items, (cached_dir_t*)d);
2648 tor_free(fp);
2650 smartlist_free(fps);
2652 if (!smartlist_len(dir_items) && !smartlist_len(items)) {
2653 write_http_status_line(conn, 404, "Not found");
2654 goto vote_done;
2656 SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
2657 body_len += compressed ? d->dir_z_len : d->dir_len);
2658 estimated_len += body_len;
2659 SMARTLIST_FOREACH(items, const char *, item, {
2660 size_t ln = strlen(item);
2661 if (compressed) {
2662 estimated_len += ln/2;
2663 } else {
2664 body_len += ln; estimated_len += ln;
2668 if (global_write_bucket_low(TO_CONN(conn), estimated_len, 2)) {
2669 write_http_status_line(conn, 503, "Directory busy, try again later.");
2670 goto vote_done;
2672 write_http_response_header(conn, body_len ? body_len : -1, compressed,
2673 lifetime);
2675 if (smartlist_len(items)) {
2676 if (compressed) {
2677 conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
2678 SMARTLIST_FOREACH(items, const char *, c,
2679 connection_write_to_buf_zlib(c, strlen(c), conn, 0));
2680 connection_write_to_buf_zlib("", 0, conn, 1);
2681 } else {
2682 SMARTLIST_FOREACH(items, const char *, c,
2683 connection_write_to_buf(c, strlen(c), TO_CONN(conn)));
2685 } else {
2686 SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
2687 connection_write_to_buf(compressed ? d->dir_z : d->dir,
2688 compressed ? d->dir_z_len : d->dir_len,
2689 TO_CONN(conn)));
2691 vote_done:
2692 smartlist_free(items);
2693 smartlist_free(dir_items);
2694 goto done;
2697 if (!strcmpstart(url,"/tor/server/") ||
2698 (!options->BridgeAuthoritativeDir &&
2699 !options->BridgeRelay && !strcmpstart(url,"/tor/extra/"))) {
2700 int res;
2701 const char *msg;
2702 const char *request_type = NULL;
2703 int cache_lifetime = 0;
2704 int is_extra = !strcmpstart(url,"/tor/extra/");
2705 url += is_extra ? strlen("/tor/extra/") : strlen("/tor/server/");
2706 conn->fingerprint_stack = smartlist_create();
2707 res = dirserv_get_routerdesc_fingerprints(conn->fingerprint_stack, url,
2708 &msg,
2709 !connection_dir_is_encrypted(conn),
2710 is_extra);
2712 if (!strcmpstart(url, "fp/")) {
2713 request_type = compressed?"/tor/server/fp.z":"/tor/server/fp";
2714 if (smartlist_len(conn->fingerprint_stack) == 1)
2715 cache_lifetime = ROUTERDESC_CACHE_LIFETIME;
2716 } else if (!strcmpstart(url, "authority")) {
2717 request_type = compressed?"/tor/server/authority.z":
2718 "/tor/server/authority";
2719 cache_lifetime = ROUTERDESC_CACHE_LIFETIME;
2720 } else if (!strcmpstart(url, "all")) {
2721 request_type = compressed?"/tor/server/all.z":"/tor/server/all";
2722 cache_lifetime = FULL_DIR_CACHE_LIFETIME;
2723 } else if (!strcmpstart(url, "d/")) {
2724 request_type = compressed?"/tor/server/d.z":"/tor/server/d";
2725 if (smartlist_len(conn->fingerprint_stack) == 1)
2726 cache_lifetime = ROUTERDESC_BY_DIGEST_CACHE_LIFETIME;
2727 } else {
2728 request_type = "/tor/server/?";
2730 (void) request_type; /* usable for note_request. */
2731 if (!strcmpstart(url, "d/"))
2732 conn->dir_spool_src =
2733 is_extra ? DIR_SPOOL_EXTRA_BY_DIGEST : DIR_SPOOL_SERVER_BY_DIGEST;
2734 else
2735 conn->dir_spool_src =
2736 is_extra ? DIR_SPOOL_EXTRA_BY_FP : DIR_SPOOL_SERVER_BY_FP;
2738 if (!dirserv_have_any_serverdesc(conn->fingerprint_stack,
2739 conn->dir_spool_src)) {
2740 res = -1;
2741 msg = "Not found";
2744 if (res < 0)
2745 write_http_status_line(conn, 404, msg);
2746 else {
2747 dlen = dirserv_estimate_data_size(conn->fingerprint_stack,
2748 1, compressed);
2749 if (global_write_bucket_low(TO_CONN(conn), dlen, 2)) {
2750 log_info(LD_DIRSERV,
2751 "Client asked for server descriptors, but we've been "
2752 "writing too many bytes lately. Sending 503 Dir busy.");
2753 write_http_status_line(conn, 503, "Directory busy, try again later");
2754 conn->dir_spool_src = DIR_SPOOL_NONE;
2755 goto done;
2757 write_http_response_header(conn, -1, compressed, cache_lifetime);
2758 if (compressed)
2759 conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
2760 /* Prime the connection with some data. */
2761 connection_dirserv_flushed_some(conn);
2763 goto done;
2766 if (!strcmpstart(url,"/tor/keys/")) {
2767 smartlist_t *certs = smartlist_create();
2768 ssize_t len = -1;
2769 if (!strcmp(url, "/tor/keys/all")) {
2770 authority_cert_get_all(certs);
2771 } else if (!strcmp(url, "/tor/keys/authority")) {
2772 authority_cert_t *cert = get_my_v3_authority_cert();
2773 if (cert)
2774 smartlist_add(certs, cert);
2775 } else if (!strcmpstart(url, "/tor/keys/fp/")) {
2776 smartlist_t *fps = smartlist_create();
2777 dir_split_resource_into_fingerprints(url+strlen("/tor/keys/fp/"),
2778 fps, NULL, 1, 1);
2779 SMARTLIST_FOREACH(fps, char *, d, {
2780 authority_cert_t *c = authority_cert_get_newest_by_id(d);
2781 if (c) smartlist_add(certs, c);
2782 tor_free(d);
2784 smartlist_free(fps);
2785 } else if (!strcmpstart(url, "/tor/keys/sk/")) {
2786 smartlist_t *fps = smartlist_create();
2787 dir_split_resource_into_fingerprints(url+strlen("/tor/keys/sk/"),
2788 fps, NULL, 1, 1);
2789 SMARTLIST_FOREACH(fps, char *, d, {
2790 authority_cert_t *c = authority_cert_get_by_sk_digest(d);
2791 if (c) smartlist_add(certs, c);
2792 tor_free(d);
2794 smartlist_free(fps);
2795 } else if (!strcmpstart(url, "/tor/keys/fp-sk/")) {
2796 smartlist_t *fp_sks = smartlist_create();
2797 dir_split_resource_into_fingerprint_pairs(url+strlen("/tor/keys/fp-sk/"),
2798 fp_sks);
2799 SMARTLIST_FOREACH(fp_sks, fp_pair_t *, pair, {
2800 authority_cert_t *c = authority_cert_get_by_digests(pair->first,
2801 pair->second);
2802 if (c) smartlist_add(certs, c);
2803 tor_free(pair);
2805 smartlist_free(fp_sks);
2806 } else {
2807 write_http_status_line(conn, 400, "Bad request");
2808 goto keys_done;
2810 if (!smartlist_len(certs)) {
2811 write_http_status_line(conn, 404, "Not found");
2812 goto keys_done;
2814 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2815 if (c->cache_info.published_on < if_modified_since)
2816 SMARTLIST_DEL_CURRENT(certs, c));
2817 if (!smartlist_len(certs)) {
2818 write_http_status_line(conn, 304, "Not modified");
2819 goto keys_done;
2821 len = 0;
2822 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2823 len += c->cache_info.signed_descriptor_len);
2825 if (global_write_bucket_low(TO_CONN(conn), compressed?len/2:len, 2)) {
2826 write_http_status_line(conn, 503, "Directory busy, try again later.");
2827 goto keys_done;
2830 write_http_response_header(conn, compressed?-1:len, compressed, 60*60);
2831 if (compressed) {
2832 conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
2833 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2834 connection_write_to_buf_zlib(c->cache_info.signed_descriptor_body,
2835 c->cache_info.signed_descriptor_len,
2836 conn, 0));
2837 connection_write_to_buf_zlib("", 0, conn, 1);
2838 } else {
2839 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2840 connection_write_to_buf(c->cache_info.signed_descriptor_body,
2841 c->cache_info.signed_descriptor_len,
2842 TO_CONN(conn)));
2844 keys_done:
2845 smartlist_free(certs);
2846 goto done;
2849 if (options->HidServDirectoryV2 &&
2850 !strcmpstart(url,"/tor/rendezvous2/")) {
2851 /* Handle v2 rendezvous descriptor fetch request. */
2852 const char *descp;
2853 const char *query = url + strlen("/tor/rendezvous2/");
2854 if (strlen(query) == REND_DESC_ID_V2_LEN_BASE32) {
2855 log_info(LD_REND, "Got a v2 rendezvous descriptor request for ID '%s'",
2856 safe_str(query));
2857 switch (rend_cache_lookup_v2_desc_as_dir(query, &descp)) {
2858 case 1: /* valid */
2859 write_http_response_header(conn, strlen(descp), 0, 0);
2860 connection_write_to_buf(descp, strlen(descp), TO_CONN(conn));
2861 break;
2862 case 0: /* well-formed but not present */
2863 write_http_status_line(conn, 404, "Not found");
2864 break;
2865 case -1: /* not well-formed */
2866 write_http_status_line(conn, 400, "Bad request");
2867 break;
2869 } else { /* not well-formed */
2870 write_http_status_line(conn, 400, "Bad request");
2872 goto done;
2875 if (options->HSAuthoritativeDir && !strcmpstart(url,"/tor/rendezvous/")) {
2876 /* rendezvous descriptor fetch */
2877 const char *descp;
2878 size_t desc_len;
2879 const char *query = url+strlen("/tor/rendezvous/");
2881 log_info(LD_REND, "Handling rendezvous descriptor get");
2882 switch (rend_cache_lookup_desc(query, 0, &descp, &desc_len)) {
2883 case 1: /* valid */
2884 write_http_response_header_impl(conn, desc_len,
2885 "application/octet-stream",
2886 NULL, NULL, 0);
2887 note_request("/tor/rendezvous?/", desc_len);
2888 /* need to send descp separately, because it may include NULs */
2889 connection_write_to_buf(descp, desc_len, TO_CONN(conn));
2890 /* report successful fetch to statistic */
2891 if (options->HSAuthorityRecordStats) {
2892 hs_usage_note_fetch_total(query, time(NULL));
2893 hs_usage_note_fetch_successful(query, time(NULL));
2895 break;
2896 case 0: /* well-formed but not present */
2897 write_http_status_line(conn, 404, "Not found");
2898 /* report (unsuccessful) fetch to statistic */
2899 if (options->HSAuthorityRecordStats) {
2900 hs_usage_note_fetch_total(query, time(NULL));
2902 break;
2903 case -1: /* not well-formed */
2904 write_http_status_line(conn, 400, "Bad request");
2905 break;
2907 goto done;
2910 if (options->BridgeAuthoritativeDir &&
2911 options->BridgePassword &&
2912 connection_dir_is_encrypted(conn) &&
2913 !strcmp(url,"/tor/networkstatus-bridges")) {
2914 char *status;
2915 char *secret = alloc_http_authenticator(options->BridgePassword);
2917 header = http_get_header(headers, "Authorization: Basic ");
2919 /* now make sure the password is there and right */
2920 if (!header || strcmp(header, secret)) {
2921 write_http_status_line(conn, 404, "Not found");
2922 tor_free(secret);
2923 tor_free(header);
2924 goto done;
2926 tor_free(secret);
2927 tor_free(header);
2929 /* all happy now. send an answer. */
2930 status = networkstatus_getinfo_by_purpose("bridge", time(NULL));
2931 dlen = strlen(status);
2932 write_http_response_header(conn, dlen, 0, 0);
2933 connection_write_to_buf(status, dlen, TO_CONN(conn));
2934 tor_free(status);
2935 goto done;
2938 if (!strcmpstart(url,"/tor/bytes.txt")) {
2939 char *bytes = directory_dump_request_log();
2940 size_t len = strlen(bytes);
2941 write_http_response_header(conn, len, 0, 0);
2942 connection_write_to_buf(bytes, len, TO_CONN(conn));
2943 tor_free(bytes);
2944 goto done;
2947 if (!strcmp(url,"/tor/robots.txt")) { /* /robots.txt will have been
2948 rewritten to /tor/robots.txt */
2949 char robots[] = "User-agent: *\r\nDisallow: /\r\n";
2950 size_t len = strlen(robots);
2951 write_http_response_header(conn, len, 0, ROBOTS_CACHE_LIFETIME);
2952 connection_write_to_buf(robots, len, TO_CONN(conn));
2953 goto done;
2956 if (!strcmp(url,"/tor/dbg-stability.txt")) {
2957 const char *stability;
2958 size_t len;
2959 if (! authdir_mode_tests_reachability(options) ||
2960 ! (stability = rep_hist_get_router_stability_doc(time(NULL)))) {
2961 write_http_status_line(conn, 404, "Not found.");
2962 goto done;
2965 len = strlen(stability);
2966 write_http_response_header(conn, len, 0, 0);
2967 connection_write_to_buf(stability, len, TO_CONN(conn));
2968 goto done;
2971 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
2972 #define ADD_MALLINFO_LINE(x) do { \
2973 tor_snprintf(tmp, sizeof(tmp), "%s %d\n", #x, mi.x); \
2974 smartlist_add(lines, tor_strdup(tmp)); \
2975 }while(0);
2977 if (!strcmp(url,"/tor/mallinfo.txt") &&
2978 (tor_addr_eq_ipv4h(&conn->_base.addr, 0x7f000001ul))) {
2979 char *result;
2980 size_t len;
2981 struct mallinfo mi;
2982 smartlist_t *lines;
2983 char tmp[256];
2985 memset(&mi, 0, sizeof(mi));
2986 mi = mallinfo();
2987 lines = smartlist_create();
2989 ADD_MALLINFO_LINE(arena)
2990 ADD_MALLINFO_LINE(ordblks)
2991 ADD_MALLINFO_LINE(smblks)
2992 ADD_MALLINFO_LINE(hblks)
2993 ADD_MALLINFO_LINE(hblkhd)
2994 ADD_MALLINFO_LINE(usmblks)
2995 ADD_MALLINFO_LINE(fsmblks)
2996 ADD_MALLINFO_LINE(uordblks)
2997 ADD_MALLINFO_LINE(fordblks)
2998 ADD_MALLINFO_LINE(keepcost)
3000 result = smartlist_join_strings(lines, "", 0, NULL);
3001 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
3002 smartlist_free(lines);
3004 len = strlen(result);
3005 write_http_response_header(conn, len, 0, 0);
3006 connection_write_to_buf(result, len, TO_CONN(conn));
3007 tor_free(result);
3008 goto done;
3010 #endif
3012 /* we didn't recognize the url */
3013 write_http_status_line(conn, 404, "Not found");
3015 done:
3016 tor_free(url_mem);
3017 return 0;
3020 /** Helper function: called when a dirserver gets a complete HTTP POST
3021 * request. Look for an uploaded server descriptor or rendezvous
3022 * service descriptor. On finding one, process it and write a
3023 * response into conn-\>outbuf. If the request is unrecognized, send a
3024 * 400. Always return 0. */
3025 static int
3026 directory_handle_command_post(dir_connection_t *conn, const char *headers,
3027 const char *body, size_t body_len)
3029 char *url = NULL;
3030 or_options_t *options = get_options();
3032 log_debug(LD_DIRSERV,"Received POST command.");
3034 conn->_base.state = DIR_CONN_STATE_SERVER_WRITING;
3036 if (parse_http_url(headers, &url) < 0) {
3037 write_http_status_line(conn, 400, "Bad request");
3038 return 0;
3040 log_debug(LD_DIRSERV,"rewritten url as '%s'.", url);
3042 /* Handle v2 rendezvous service publish request. */
3043 if (options->HidServDirectoryV2 &&
3044 !strcmpstart(url,"/tor/rendezvous2/publish")) {
3045 switch (rend_cache_store_v2_desc_as_dir(body)) {
3046 case -2:
3047 log_info(LD_REND, "Rejected v2 rend descriptor (length %d) from %s "
3048 "since we're not currently a hidden service directory.",
3049 (int)body_len, conn->_base.address);
3050 write_http_status_line(conn, 503, "Currently not acting as v2 "
3051 "hidden service directory");
3052 break;
3053 case -1:
3054 log_warn(LD_REND, "Rejected v2 rend descriptor (length %d) from %s.",
3055 (int)body_len, conn->_base.address);
3056 write_http_status_line(conn, 400,
3057 "Invalid v2 service descriptor rejected");
3058 break;
3059 default:
3060 write_http_status_line(conn, 200, "Service descriptor (v2) stored");
3061 log_info(LD_REND, "Handled v2 rendezvous descriptor post: accepted");
3063 goto done;
3066 if (!authdir_mode(options)) {
3067 /* we just provide cached directories; we don't want to
3068 * receive anything. */
3069 write_http_status_line(conn, 400, "Nonauthoritative directory does not "
3070 "accept posted server descriptors");
3071 goto done;
3074 if (authdir_mode_handles_descs(options, -1) &&
3075 !strcmp(url,"/tor/")) { /* server descriptor post */
3076 const char *msg = "[None]";
3077 uint8_t purpose = authdir_mode_bridge(options) ?
3078 ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL;
3079 was_router_added_t r = dirserv_add_multiple_descriptors(body, purpose,
3080 conn->_base.address, &msg);
3081 tor_assert(msg);
3082 if (WRA_WAS_ADDED(r))
3083 dirserv_get_directory(); /* rebuild and write to disk */
3085 if (r == ROUTER_ADDED_NOTIFY_GENERATOR) {
3086 /* Accepted with a message. */
3087 log_info(LD_DIRSERV,
3088 "Problematic router descriptor or extra-info from %s "
3089 "(\"%s\").",
3090 conn->_base.address, msg);
3091 write_http_status_line(conn, 400, msg);
3092 } else if (r == ROUTER_ADDED_SUCCESSFULLY) {
3093 write_http_status_line(conn, 200, msg);
3094 } else if (WRA_WAS_OUTDATED(r)) {
3095 write_http_response_header_impl(conn, -1, NULL, NULL,
3096 "X-Descriptor-Not-New: Yes\r\n", -1);
3097 } else {
3098 log_info(LD_DIRSERV,
3099 "Rejected router descriptor or extra-info from %s "
3100 "(\"%s\").",
3101 conn->_base.address, msg);
3102 write_http_status_line(conn, 400, msg);
3104 goto done;
3107 if (options->HSAuthoritativeDir &&
3108 !strcmpstart(url,"/tor/rendezvous/publish")) {
3109 /* rendezvous descriptor post */
3110 log_info(LD_REND, "Handling rendezvous descriptor post.");
3111 if (rend_cache_store(body, body_len, 1) < 0) {
3112 log_fn(LOG_PROTOCOL_WARN, LD_DIRSERV,
3113 "Rejected rend descriptor (length %d) from %s.",
3114 (int)body_len, conn->_base.address);
3115 write_http_status_line(conn, 400,
3116 "Invalid v0 service descriptor rejected");
3117 } else {
3118 write_http_status_line(conn, 200, "Service descriptor (v0) stored");
3120 goto done;
3123 if (authdir_mode_v3(options) &&
3124 !strcmp(url,"/tor/post/vote")) { /* v3 networkstatus vote */
3125 const char *msg = "OK";
3126 int status;
3127 if (dirvote_add_vote(body, &msg, &status)) {
3128 write_http_status_line(conn, status, "Vote stored");
3129 } else {
3130 tor_assert(msg);
3131 write_http_status_line(conn, status, msg);
3133 goto done;
3136 if (authdir_mode_v3(options) &&
3137 !strcmp(url,"/tor/post/consensus-signature")) { /* sigs on consensus. */
3138 const char *msg = NULL;
3139 if (dirvote_add_signatures(body, conn->_base.address, &msg)>=0) {
3140 write_http_status_line(conn, 200, msg?msg:"Signatures stored");
3141 } else {
3142 log_warn(LD_DIR, "Unable to store signatures posted by %s: %s",
3143 conn->_base.address, msg?msg:"???");
3144 write_http_status_line(conn, 400, msg?msg:"Unable to store signatures");
3146 goto done;
3149 /* we didn't recognize the url */
3150 write_http_status_line(conn, 404, "Not found");
3152 done:
3153 tor_free(url);
3154 return 0;
3157 /** Called when a dirserver receives data on a directory connection;
3158 * looks for an HTTP request. If the request is complete, remove it
3159 * from the inbuf, try to process it; otherwise, leave it on the
3160 * buffer. Return a 0 on success, or -1 on error.
3162 static int
3163 directory_handle_command(dir_connection_t *conn)
3165 char *headers=NULL, *body=NULL;
3166 size_t body_len=0;
3167 int r;
3169 tor_assert(conn);
3170 tor_assert(conn->_base.type == CONN_TYPE_DIR);
3172 switch (fetch_from_buf_http(conn->_base.inbuf,
3173 &headers, MAX_HEADERS_SIZE,
3174 &body, &body_len, MAX_DIR_UL_SIZE, 0)) {
3175 case -1: /* overflow */
3176 log_warn(LD_DIRSERV,
3177 "Invalid input from address '%s'. Closing.",
3178 conn->_base.address);
3179 return -1;
3180 case 0:
3181 log_debug(LD_DIRSERV,"command not all here yet.");
3182 return 0;
3183 /* case 1, fall through */
3186 http_set_address_origin(headers, TO_CONN(conn));
3187 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
3189 if (!strncasecmp(headers,"GET",3))
3190 r = directory_handle_command_get(conn, headers, body, body_len);
3191 else if (!strncasecmp(headers,"POST",4))
3192 r = directory_handle_command_post(conn, headers, body, body_len);
3193 else {
3194 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
3195 "Got headers %s with unknown command. Closing.",
3196 escaped(headers));
3197 r = -1;
3200 tor_free(headers); tor_free(body);
3201 return r;
3204 /** Write handler for directory connections; called when all data has
3205 * been flushed. Close the connection or wait for a response as
3206 * appropriate.
3209 connection_dir_finished_flushing(dir_connection_t *conn)
3211 tor_assert(conn);
3212 tor_assert(conn->_base.type == CONN_TYPE_DIR);
3214 switch (conn->_base.state) {
3215 case DIR_CONN_STATE_CLIENT_SENDING:
3216 log_debug(LD_DIR,"client finished sending command.");
3217 conn->_base.state = DIR_CONN_STATE_CLIENT_READING;
3218 connection_stop_writing(TO_CONN(conn));
3219 return 0;
3220 case DIR_CONN_STATE_SERVER_WRITING:
3221 log_debug(LD_DIRSERV,"Finished writing server response. Closing.");
3222 connection_mark_for_close(TO_CONN(conn));
3223 return 0;
3224 default:
3225 log_warn(LD_BUG,"called in unexpected state %d.",
3226 conn->_base.state);
3227 tor_fragile_assert();
3228 return -1;
3230 return 0;
3233 /** Connected handler for directory connections: begin sending data to the
3234 * server */
3236 connection_dir_finished_connecting(dir_connection_t *conn)
3238 tor_assert(conn);
3239 tor_assert(conn->_base.type == CONN_TYPE_DIR);
3240 tor_assert(conn->_base.state == DIR_CONN_STATE_CONNECTING);
3242 log_debug(LD_HTTP,"Dir connection to router %s:%u established.",
3243 conn->_base.address,conn->_base.port);
3245 conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING; /* start flushing conn */
3246 return 0;
3249 /** Called when one or more networkstatus fetches have failed (with uppercase
3250 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
3251 * failed once, unless they failed with status code 503. */
3252 static void
3253 dir_networkstatus_download_failed(smartlist_t *failed, int status_code)
3255 if (status_code == 503)
3256 return;
3257 SMARTLIST_FOREACH(failed, const char *, fp,
3259 char digest[DIGEST_LEN];
3260 trusted_dir_server_t *dir;
3261 if (base16_decode(digest, DIGEST_LEN, fp, strlen(fp))<0) {
3262 log_warn(LD_BUG, "Called with bad fingerprint in list: %s",
3263 escaped(fp));
3264 continue;
3266 dir = router_get_trusteddirserver_by_digest(digest);
3268 if (dir)
3269 download_status_failed(&dir->v2_ns_dl_status, status_code);
3273 /** Schedule for when servers should download things in general. */
3274 static const int server_dl_schedule[] = {
3275 0, 0, 0, 60, 60, 60*2, 60*5, 60*15, INT_MAX
3277 /** Schedule for when clients should download things in general. */
3278 static const int client_dl_schedule[] = {
3279 0, 0, 60, 60*5, 60*10, INT_MAX
3281 /** Schedule for when servers should download consensuses. */
3282 static const int server_consensus_dl_schedule[] = {
3283 0, 0, 60, 60*5, 60*10, 60*30, 60*30, 60*30, 60*30, 60*30, 60*60, 60*60*2
3285 /** Schedule for when clients should download consensuses. */
3286 static const int client_consensus_dl_schedule[] = {
3287 0, 0, 60, 60*5, 60*10, 60*30, 60*60, 60*60, 60*60, 60*60*3, 60*60*6, 60*60*12
3289 /** Schedule for when clients should download bridge descriptors. */
3290 static const int bridge_dl_schedule[] = {
3291 60*60, 15*60, 15*60, 60*60
3294 /** Decide which download schedule we want to use, and then return a
3295 * pointer to it along with a pointer to its length. Helper function for
3296 * download_status_increment_failure() and download_status_reset(). */
3297 static void
3298 find_dl_schedule_and_len(download_status_t *dls, int server,
3299 const int **schedule, size_t *schedule_len)
3301 switch (dls->schedule) {
3302 case DL_SCHED_GENERIC:
3303 if (server) {
3304 *schedule = server_dl_schedule;
3305 *schedule_len = sizeof(server_dl_schedule)/sizeof(int);
3306 } else {
3307 *schedule = client_dl_schedule;
3308 *schedule_len = sizeof(client_dl_schedule)/sizeof(int);
3310 break;
3311 case DL_SCHED_CONSENSUS:
3312 if (server) {
3313 *schedule = server_consensus_dl_schedule;
3314 *schedule_len = sizeof(server_consensus_dl_schedule)/sizeof(int);
3315 } else {
3316 *schedule = client_consensus_dl_schedule;
3317 *schedule_len = sizeof(client_consensus_dl_schedule)/sizeof(int);
3319 break;
3320 case DL_SCHED_BRIDGE:
3321 *schedule = bridge_dl_schedule;
3322 *schedule_len = sizeof(bridge_dl_schedule)/sizeof(int);
3323 break;
3324 default:
3325 tor_assert(0);
3329 /** Called when an attempt to download <b>dls</b> has failed with HTTP status
3330 * <b>status_code</b>. Increment the failure count (if the code indicates a
3331 * real failure) and set <b>dls</b>-\>next_attempt_at to an appropriate time
3332 * in the future. */
3333 time_t
3334 download_status_increment_failure(download_status_t *dls, int status_code,
3335 const char *item, int server, time_t now)
3337 const int *schedule;
3338 size_t schedule_len;
3339 int increment;
3340 tor_assert(dls);
3341 if (status_code != 503 || server) {
3342 if (dls->n_download_failures < IMPOSSIBLE_TO_DOWNLOAD-1)
3343 ++dls->n_download_failures;
3346 find_dl_schedule_and_len(dls, server, &schedule, &schedule_len);
3348 if (dls->n_download_failures < schedule_len)
3349 increment = schedule[dls->n_download_failures];
3350 else if (dls->n_download_failures == IMPOSSIBLE_TO_DOWNLOAD)
3351 increment = INT_MAX;
3352 else
3353 increment = schedule[schedule_len-1];
3355 if (increment < INT_MAX)
3356 dls->next_attempt_at = now+increment;
3357 else
3358 dls->next_attempt_at = TIME_MAX;
3360 if (item) {
3361 if (increment == 0)
3362 log_debug(LD_DIR, "%s failed %d time(s); I'll try again immediately.",
3363 item, (int)dls->n_download_failures);
3364 else if (dls->next_attempt_at < TIME_MAX)
3365 log_debug(LD_DIR, "%s failed %d time(s); I'll try again in %d seconds.",
3366 item, (int)dls->n_download_failures,
3367 (int)(dls->next_attempt_at-now));
3368 else
3369 log_debug(LD_DIR, "%s failed %d time(s); Giving up for a while.",
3370 item, (int)dls->n_download_failures);
3372 return dls->next_attempt_at;
3375 /** Reset <b>dls</b> so that it will be considered downloadable
3376 * immediately, and/or to show that we don't need it anymore.
3378 * (We find the zeroth element of the download schedule, and set
3379 * next_attempt_at to be the appropriate offset from 'now'. In most
3380 * cases this means setting it to 'now', so the item will be immediately
3381 * downloadable; in the case of bridge descriptors, the zeroth element
3382 * is an hour from now.) */
3383 void
3384 download_status_reset(download_status_t *dls)
3386 const int *schedule;
3387 size_t schedule_len;
3389 find_dl_schedule_and_len(dls, get_options()->DirPort,
3390 &schedule, &schedule_len);
3392 dls->n_download_failures = 0;
3393 dls->next_attempt_at = time(NULL) + schedule[0];
3396 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
3397 * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
3398 * either as descriptor digests or as identity digests based on
3399 * <b>was_descriptor_digests</b>).
3401 static void
3402 dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
3403 int router_purpose,
3404 int was_extrainfo, int was_descriptor_digests)
3406 char digest[DIGEST_LEN];
3407 time_t now = time(NULL);
3408 int server = directory_fetches_from_authorities(get_options());
3409 if (!was_descriptor_digests) {
3410 if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
3411 tor_assert(!was_extrainfo); /* not supported yet */
3412 SMARTLIST_FOREACH(failed, const char *, cp,
3414 if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp))<0) {
3415 log_warn(LD_BUG, "Malformed fingerprint in list: %s",
3416 escaped(cp));
3417 continue;
3419 retry_bridge_descriptor_fetch_directly(digest);
3422 return; /* FFFF should implement for other-than-router-purpose someday */
3424 SMARTLIST_FOREACH(failed, const char *, cp,
3426 download_status_t *dls = NULL;
3427 if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp)) < 0) {
3428 log_warn(LD_BUG, "Malformed fingerprint in list: %s", escaped(cp));
3429 continue;
3431 if (was_extrainfo) {
3432 signed_descriptor_t *sd =
3433 router_get_by_extrainfo_digest(digest);
3434 if (sd)
3435 dls = &sd->ei_dl_status;
3436 } else {
3437 dls = router_get_dl_status_by_descriptor_digest(digest);
3439 if (!dls || dls->n_download_failures >= MAX_ROUTERDESC_DOWNLOAD_FAILURES)
3440 continue;
3441 download_status_increment_failure(dls, status_code, cp, server, now);
3444 /* No need to relaunch descriptor downloads here: we already do it
3445 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
3448 /** Helper. Compare two fp_pair_t objects, and return -1, 0, or 1 as
3449 * appropriate. */
3450 static int
3451 _compare_pairs(const void **a, const void **b)
3453 const fp_pair_t *fp1 = *a, *fp2 = *b;
3454 int r;
3455 if ((r = memcmp(fp1->first, fp2->first, DIGEST_LEN)))
3456 return r;
3457 else
3458 return memcmp(fp1->second, fp2->second, DIGEST_LEN);
3461 /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
3462 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
3463 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
3464 * fp_pair_t into <b>pairs_out</b>. On failure, return -1. */
3466 dir_split_resource_into_fingerprint_pairs(const char *res,
3467 smartlist_t *pairs_out)
3469 smartlist_t *pairs_tmp = smartlist_create();
3470 smartlist_t *pairs_result = smartlist_create();
3472 smartlist_split_string(pairs_tmp, res, "+", 0, 0);
3473 if (smartlist_len(pairs_tmp)) {
3474 char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
3475 size_t last_len = strlen(last);
3476 if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
3477 last[last_len-2] = '\0';
3480 SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
3481 if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
3482 log_info(LD_DIR,
3483 "Skipping digest pair %s with non-standard length.", escaped(cp));
3484 } else if (cp[HEX_DIGEST_LEN] != '-') {
3485 log_info(LD_DIR,
3486 "Skipping digest pair %s with missing dash.", escaped(cp));
3487 } else {
3488 fp_pair_t pair;
3489 if (base16_decode(pair.first, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0 ||
3490 base16_decode(pair.second,
3491 DIGEST_LEN, cp+HEX_DIGEST_LEN+1, HEX_DIGEST_LEN)<0) {
3492 log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
3493 } else {
3494 smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
3497 tor_free(cp);
3498 } SMARTLIST_FOREACH_END(cp);
3499 smartlist_free(pairs_tmp);
3501 /* Uniq-and-sort */
3502 smartlist_sort(pairs_result, _compare_pairs);
3503 smartlist_uniq(pairs_result, _compare_pairs, _tor_free);
3505 smartlist_add_all(pairs_out, pairs_result);
3506 smartlist_free(pairs_result);
3507 return 0;
3510 /** Given a directory <b>resource</b> request, containing zero
3511 * or more strings separated by plus signs, followed optionally by ".z", store
3512 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
3513 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
3514 * decode_hex is true, then delete all elements that aren't hex digests, and
3515 * decode the rest. If sort_uniq is true, then sort the list and remove
3516 * all duplicates.
3519 dir_split_resource_into_fingerprints(const char *resource,
3520 smartlist_t *fp_out, int *compressed_out,
3521 int decode_hex, int sort_uniq)
3523 smartlist_t *fp_tmp = smartlist_create();
3524 tor_assert(fp_out);
3525 smartlist_split_string(fp_tmp, resource, "+", 0, 0);
3526 if (compressed_out)
3527 *compressed_out = 0;
3528 if (smartlist_len(fp_tmp)) {
3529 char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
3530 size_t last_len = strlen(last);
3531 if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
3532 last[last_len-2] = '\0';
3533 if (compressed_out)
3534 *compressed_out = 1;
3537 if (decode_hex) {
3538 int i;
3539 char *cp, *d = NULL;
3540 for (i = 0; i < smartlist_len(fp_tmp); ++i) {
3541 cp = smartlist_get(fp_tmp, i);
3542 if (strlen(cp) != HEX_DIGEST_LEN) {
3543 log_info(LD_DIR,
3544 "Skipping digest %s with non-standard length.", escaped(cp));
3545 smartlist_del_keeporder(fp_tmp, i--);
3546 goto again;
3548 d = tor_malloc_zero(DIGEST_LEN);
3549 if (base16_decode(d, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0) {
3550 log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
3551 smartlist_del_keeporder(fp_tmp, i--);
3552 goto again;
3554 smartlist_set(fp_tmp, i, d);
3555 d = NULL;
3556 again:
3557 tor_free(cp);
3558 tor_free(d);
3561 if (sort_uniq) {
3562 smartlist_t *fp_tmp2 = smartlist_create();
3563 int i;
3564 if (decode_hex)
3565 smartlist_sort_digests(fp_tmp);
3566 else
3567 smartlist_sort_strings(fp_tmp);
3568 if (smartlist_len(fp_tmp))
3569 smartlist_add(fp_tmp2, smartlist_get(fp_tmp, 0));
3570 for (i = 1; i < smartlist_len(fp_tmp); ++i) {
3571 char *cp = smartlist_get(fp_tmp, i);
3572 char *last = smartlist_get(fp_tmp2, smartlist_len(fp_tmp2)-1);
3574 if ((decode_hex && memcmp(cp, last, DIGEST_LEN))
3575 || (!decode_hex && strcasecmp(cp, last)))
3576 smartlist_add(fp_tmp2, cp);
3577 else
3578 tor_free(cp);
3580 smartlist_free(fp_tmp);
3581 fp_tmp = fp_tmp2;
3583 smartlist_add_all(fp_out, fp_tmp);
3584 smartlist_free(fp_tmp);
3585 return 0;