Maintain separate server and client identity keys when appropriate.
[tor.git] / src / or / directory.c
blob9f9b2c1577b23c2a609945c28cf26d6187428c7f
1 /* Copyright (c) 2001-2004, Roger Dingledine.
2 * Copyright (c) 2004-2006, Roger Dingledine, Nick Mathewson.
3 * Copyright (c) 2007-2011, 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 & V3_AUTHORITY)
132 smartlist_add(lst, (void*)"V3");
133 if (auth & BRIDGE_AUTHORITY)
134 smartlist_add(lst, (void*)"Bridge");
135 if (auth & HIDSERV_AUTHORITY)
136 smartlist_add(lst, (void*)"Hidden service");
137 if (smartlist_len(lst)) {
138 result = smartlist_join_strings(lst, ", ", 0, NULL);
139 } else {
140 result = tor_strdup("[Not an authority]");
142 smartlist_free(lst);
143 return result;
146 /** Return a string describing a given directory connection purpose. */
147 static const char *
148 dir_conn_purpose_to_string(int purpose)
150 switch (purpose)
152 case DIR_PURPOSE_FETCH_RENDDESC:
153 return "hidden-service descriptor fetch";
154 case DIR_PURPOSE_UPLOAD_DIR:
155 return "server descriptor upload";
156 case DIR_PURPOSE_UPLOAD_RENDDESC:
157 return "hidden-service descriptor upload";
158 case DIR_PURPOSE_UPLOAD_VOTE:
159 return "server vote upload";
160 case DIR_PURPOSE_UPLOAD_SIGNATURES:
161 return "consensus signature upload";
162 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
163 return "network-status fetch";
164 case DIR_PURPOSE_FETCH_SERVERDESC:
165 return "server descriptor fetch";
166 case DIR_PURPOSE_FETCH_EXTRAINFO:
167 return "extra-info fetch";
168 case DIR_PURPOSE_FETCH_CONSENSUS:
169 return "consensus network-status fetch";
170 case DIR_PURPOSE_FETCH_CERTIFICATE:
171 return "authority cert fetch";
172 case DIR_PURPOSE_FETCH_STATUS_VOTE:
173 return "status vote fetch";
174 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
175 return "consensus signature fetch";
176 case DIR_PURPOSE_FETCH_RENDDESC_V2:
177 return "hidden-service v2 descriptor fetch";
178 case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
179 return "hidden-service v2 descriptor upload";
182 log_warn(LD_BUG, "Called with unknown purpose %d", purpose);
183 return "(unknown)";
186 /** Return true iff <b>identity_digest</b> is the digest of a router we
187 * believe to support extrainfo downloads. (If <b>is_authority</b> we do
188 * additional checking that's only valid for authorities.) */
190 router_supports_extrainfo(const char *identity_digest, int is_authority)
192 routerinfo_t *ri = router_get_by_digest(identity_digest);
194 if (ri) {
195 if (ri->caches_extra_info)
196 return 1;
197 if (is_authority && ri->platform &&
198 tor_version_as_new_as(ri->platform, "Tor 0.2.0.0-alpha-dev (r10070)"))
199 return 1;
201 if (is_authority) {
202 routerstatus_t *rs = router_get_consensus_status_by_id(identity_digest);
203 if (rs && rs->version_supports_extrainfo_upload)
204 return 1;
206 return 0;
209 /** Return true iff any trusted directory authority has accepted our
210 * server descriptor.
212 * We consider any authority sufficient because waiting for all of
213 * them means it never happens while any authority is down; we don't
214 * go for something more complex in the middle (like \>1/3 or \>1/2 or
215 * \>=1/2) because that doesn't seem necessary yet.
218 directories_have_accepted_server_descriptor(void)
220 smartlist_t *servers = router_get_trusted_dir_servers();
221 or_options_t *options = get_options();
222 SMARTLIST_FOREACH(servers, trusted_dir_server_t *, d, {
223 if ((d->type & options->_PublishServerDescriptor) &&
224 d->has_accepted_serverdesc) {
225 return 1;
228 return 0;
231 /** Start a connection to every suitable directory authority, using
232 * connection purpose 'purpose' and uploading the payload 'payload'
233 * (length 'payload_len'). The purpose should be one of
234 * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
236 * <b>type</b> specifies what sort of dir authorities (V1, V2,
237 * HIDSERV, BRIDGE) we should upload to.
239 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
240 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
241 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
242 * to all authorities, and the extra-info document to all authorities that
243 * support it.
245 void
246 directory_post_to_dirservers(uint8_t dir_purpose, uint8_t router_purpose,
247 authority_type_t type,
248 const char *payload,
249 size_t payload_len, size_t extrainfo_len)
251 int post_via_tor;
252 smartlist_t *dirservers = router_get_trusted_dir_servers();
253 int found = 0;
254 tor_assert(dirservers);
255 /* This tries dirservers which we believe to be down, but ultimately, that's
256 * harmless, and we may as well err on the side of getting things uploaded.
258 SMARTLIST_FOREACH_BEGIN(dirservers, trusted_dir_server_t *, ds) {
259 routerstatus_t *rs = &(ds->fake_status);
260 size_t upload_len = payload_len;
261 tor_addr_t ds_addr;
263 if ((type & ds->type) == 0)
264 continue;
266 found = 1; /* at least one authority of this type was listed */
267 if (dir_purpose == DIR_PURPOSE_UPLOAD_DIR)
268 ds->has_accepted_serverdesc = 0;
270 if (extrainfo_len && router_supports_extrainfo(ds->digest, 1)) {
271 upload_len += extrainfo_len;
272 log_info(LD_DIR, "Uploading an extrainfo too (length %d)",
273 (int) extrainfo_len);
275 tor_addr_from_ipv4h(&ds_addr, ds->addr);
276 post_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose) ||
277 !fascist_firewall_allows_address_dir(&ds_addr, ds->dir_port);
278 directory_initiate_command_routerstatus(rs, dir_purpose,
279 router_purpose,
280 post_via_tor,
281 NULL, payload, upload_len, 0);
282 } SMARTLIST_FOREACH_END(ds);
283 if (!found) {
284 char *s = authority_type_to_string(type);
285 log_warn(LD_DIR, "Publishing server descriptor to directory authorities "
286 "of type '%s', but no authorities of that type listed!", s);
287 tor_free(s);
291 /** Start a connection to a random running directory server, using
292 * connection purpose <b>dir_purpose</b>, intending to fetch descriptors
293 * of purpose <b>router_purpose</b>, and requesting <b>resource</b>.
294 * Use <b>pds_flags</b> as arguments to router_pick_directory_server()
295 * or router_pick_trusteddirserver().
297 void
298 directory_get_from_dirserver(uint8_t dir_purpose, uint8_t router_purpose,
299 const char *resource, int pds_flags)
301 routerstatus_t *rs = NULL;
302 or_options_t *options = get_options();
303 int prefer_authority = directory_fetches_from_authorities(options);
304 int get_via_tor = purpose_needs_anonymity(dir_purpose, router_purpose);
305 authority_type_t type;
306 time_t if_modified_since = 0;
308 /* FFFF we could break this switch into its own function, and call
309 * it elsewhere in directory.c. -RD */
310 switch (dir_purpose) {
311 case DIR_PURPOSE_FETCH_EXTRAINFO:
312 type = EXTRAINFO_CACHE |
313 (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
314 V3_AUTHORITY);
315 break;
316 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
317 type = V2_AUTHORITY;
318 break;
319 case DIR_PURPOSE_FETCH_SERVERDESC:
320 type = (router_purpose == ROUTER_PURPOSE_BRIDGE ? BRIDGE_AUTHORITY :
321 V3_AUTHORITY);
322 break;
323 case DIR_PURPOSE_FETCH_RENDDESC:
324 type = HIDSERV_AUTHORITY;
325 break;
326 case DIR_PURPOSE_FETCH_STATUS_VOTE:
327 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
328 type = V3_AUTHORITY;
329 break;
330 case DIR_PURPOSE_FETCH_CONSENSUS:
331 case DIR_PURPOSE_FETCH_CERTIFICATE:
332 type = V3_AUTHORITY;
333 break;
334 default:
335 log_warn(LD_BUG, "Unexpected purpose %d", (int)dir_purpose);
336 return;
339 if (dir_purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
340 networkstatus_t *v = networkstatus_get_latest_consensus();
341 if (v)
342 if_modified_since = v->valid_after + 180;
345 if (!options->FetchServerDescriptors && type != HIDSERV_AUTHORITY)
346 return;
348 if (!get_via_tor) {
349 if (options->UseBridges && type != BRIDGE_AUTHORITY) {
350 /* want to ask a running bridge for which we have a descriptor. */
351 /* XXX022 we assume that all of our bridges can answer any
352 * possible directory question. This won't be true forever. -RD */
353 /* It certainly is not true with conditional consensus downloading,
354 * so, for now, never assume the server supports that. */
355 routerinfo_t *ri = choose_random_entry(NULL);
356 if (ri) {
357 tor_addr_t addr;
358 tor_addr_from_ipv4h(&addr, ri->addr);
359 directory_initiate_command(ri->address, &addr,
360 ri->or_port, 0,
361 0, /* don't use conditional consensus url */
362 1, ri->cache_info.identity_digest,
363 dir_purpose,
364 router_purpose,
365 0, resource, NULL, 0, if_modified_since);
366 } else
367 log_notice(LD_DIR, "Ignoring directory request, since no bridge "
368 "nodes are available yet.");
369 return;
370 } else {
371 if (prefer_authority || type == BRIDGE_AUTHORITY) {
372 /* only ask authdirservers, and don't ask myself */
373 rs = router_pick_trusteddirserver(type, pds_flags);
374 if (rs == NULL && (pds_flags & PDS_NO_EXISTING_SERVERDESC_FETCH)) {
375 /* We don't want to fetch from any authorities that we're currently
376 * fetching server descriptors from, and we got no match. Did we
377 * get no match because all the authorities have connections
378 * fetching server descriptors (in which case we should just
379 * return,) or because all the authorities are down or on fire or
380 * unreachable or something (in which case we should go on with
381 * our fallback code)? */
382 pds_flags &= ~PDS_NO_EXISTING_SERVERDESC_FETCH;
383 rs = router_pick_trusteddirserver(type, pds_flags);
384 if (rs) {
385 log_debug(LD_DIR, "Deferring serverdesc fetch: all authorities "
386 "are in use.");
387 return;
391 if (!rs && type != BRIDGE_AUTHORITY) {
392 /* anybody with a non-zero dirport will do */
393 rs = router_pick_directory_server(type, pds_flags);
394 if (!rs) {
395 log_info(LD_DIR, "No router found for %s; falling back to "
396 "dirserver list.", dir_conn_purpose_to_string(dir_purpose));
397 rs = router_pick_trusteddirserver(type, pds_flags);
398 if (!rs)
399 get_via_tor = 1; /* last resort: try routing it via Tor */
403 } else { /* get_via_tor */
404 /* Never use fascistfirewall; we're going via Tor. */
405 if (dir_purpose == DIR_PURPOSE_FETCH_RENDDESC) {
406 /* only ask hidserv authorities, any of them will do */
407 pds_flags |= PDS_IGNORE_FASCISTFIREWALL|PDS_ALLOW_SELF;
408 rs = router_pick_trusteddirserver(HIDSERV_AUTHORITY, pds_flags);
409 } else {
410 /* anybody with a non-zero dirport will do. Disregard firewalls. */
411 pds_flags |= PDS_IGNORE_FASCISTFIREWALL;
412 rs = router_pick_directory_server(type, pds_flags);
413 /* If we have any hope of building an indirect conn, we know some router
414 * descriptors. If (rs==NULL), we can't build circuits anyway, so
415 * there's no point in falling back to the authorities in this case. */
419 if (rs)
420 directory_initiate_command_routerstatus(rs, dir_purpose,
421 router_purpose,
422 get_via_tor,
423 resource, NULL, 0,
424 if_modified_since);
425 else {
426 log_notice(LD_DIR,
427 "While fetching directory info, "
428 "no running dirservers known. Will try again later. "
429 "(purpose %d)", dir_purpose);
430 if (!purpose_needs_anonymity(dir_purpose, router_purpose)) {
431 /* remember we tried them all and failed. */
432 directory_all_unreachable(time(NULL));
437 /** As directory_get_from_dirserver, but initiates a request to <i>every</i>
438 * directory authority other than ourself. Only for use by authorities when
439 * searching for missing information while voting. */
440 void
441 directory_get_from_all_authorities(uint8_t dir_purpose,
442 uint8_t router_purpose,
443 const char *resource)
445 tor_assert(dir_purpose == DIR_PURPOSE_FETCH_STATUS_VOTE ||
446 dir_purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES);
448 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
449 trusted_dir_server_t *, ds,
451 routerstatus_t *rs;
452 if (router_digest_is_me(ds->digest))
453 continue;
454 if (!(ds->type & V3_AUTHORITY))
455 continue;
456 rs = &ds->fake_status;
457 directory_initiate_command_routerstatus(rs, dir_purpose, router_purpose,
458 0, resource, NULL, 0, 0);
462 /** Same as directory_initiate_command_routerstatus(), but accepts
463 * rendezvous data to fetch a hidden service descriptor. */
464 void
465 directory_initiate_command_routerstatus_rend(routerstatus_t *status,
466 uint8_t dir_purpose,
467 uint8_t router_purpose,
468 int anonymized_connection,
469 const char *resource,
470 const char *payload,
471 size_t payload_len,
472 time_t if_modified_since,
473 const rend_data_t *rend_query)
475 routerinfo_t *router;
476 char address_buf[INET_NTOA_BUF_LEN+1];
477 struct in_addr in;
478 const char *address;
479 tor_addr_t addr;
480 router = router_get_by_digest(status->identity_digest);
481 if (!router && anonymized_connection) {
482 log_info(LD_DIR, "Not sending anonymized request to directory '%s'; we "
483 "don't have its router descriptor.", status->nickname);
484 return;
485 } else if (router) {
486 address = router->address;
487 } else {
488 in.s_addr = htonl(status->addr);
489 tor_inet_ntoa(&in, address_buf, sizeof(address_buf));
490 address = address_buf;
492 tor_addr_from_ipv4h(&addr, status->addr);
493 directory_initiate_command_rend(address, &addr,
494 status->or_port, status->dir_port,
495 status->version_supports_conditional_consensus,
496 status->version_supports_begindir,
497 status->identity_digest,
498 dir_purpose, router_purpose,
499 anonymized_connection, resource,
500 payload, payload_len, if_modified_since,
501 rend_query);
504 /** Launch a new connection to the directory server <b>status</b> to
505 * upload or download a server or rendezvous
506 * descriptor. <b>dir_purpose</b> determines what
507 * kind of directory connection we're launching, and must be one of
508 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC|RENDDESC_V2}. <b>router_purpose</b>
509 * specifies the descriptor purposes we have in mind (currently only
510 * used for FETCH_DIR).
512 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
513 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
515 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
516 * want to fetch.
518 void
519 directory_initiate_command_routerstatus(routerstatus_t *status,
520 uint8_t dir_purpose,
521 uint8_t router_purpose,
522 int anonymized_connection,
523 const char *resource,
524 const char *payload,
525 size_t payload_len,
526 time_t if_modified_since)
528 directory_initiate_command_routerstatus_rend(status, dir_purpose,
529 router_purpose,
530 anonymized_connection, resource,
531 payload, payload_len,
532 if_modified_since, NULL);
535 /** Return true iff <b>conn</b> is the client side of a directory connection
536 * we launched to ourself in order to determine the reachability of our
537 * dir_port. */
538 static int
539 directory_conn_is_self_reachability_test(dir_connection_t *conn)
541 if (conn->requested_resource &&
542 !strcmpstart(conn->requested_resource,"authority")) {
543 routerinfo_t *me = router_get_my_routerinfo();
544 if (me &&
545 router_digest_is_me(conn->identity_digest) &&
546 tor_addr_eq_ipv4h(&conn->_base.addr, me->addr) && /*XXXX prop 118*/
547 me->dir_port == conn->_base.port)
548 return 1;
550 return 0;
553 /** Called when we are unable to complete the client's request to a directory
554 * server due to a network error: Mark the router as down and try again if
555 * possible.
557 void
558 connection_dir_request_failed(dir_connection_t *conn)
560 if (directory_conn_is_self_reachability_test(conn)) {
561 return; /* this was a test fetch. don't retry. */
563 if (entry_list_can_grow(get_options()))
564 router_set_status(conn->identity_digest, 0); /* don't try him again */
565 if (conn->_base.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
566 log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
567 conn->_base.address);
568 connection_dir_download_networkstatus_failed(conn, -1);
569 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
570 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
571 log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
572 conn->_base.address);
573 connection_dir_download_routerdesc_failed(conn);
574 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
575 networkstatus_consensus_download_failed(0);
576 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
577 log_info(LD_DIR, "Giving up on directory server at '%s'; retrying",
578 conn->_base.address);
579 connection_dir_download_cert_failed(conn, 0);
580 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
581 log_info(LD_DIR, "Giving up downloading detached signatures from '%s'",
582 conn->_base.address);
583 } else if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
584 log_info(LD_DIR, "Giving up downloading votes from '%s'",
585 conn->_base.address);
589 /** Called when an attempt to download one or more network status
590 * documents on connection <b>conn</b> failed. Decide whether to
591 * retry the fetch now, later, or never.
593 static void
594 connection_dir_download_networkstatus_failed(dir_connection_t *conn,
595 int status_code)
597 if (!conn->requested_resource) {
598 /* We never reached directory_send_command, which means that we never
599 * opened a network connection. Either we're out of sockets, or the
600 * network is down. Either way, retrying would be pointless. */
601 return;
603 if (!strcmpstart(conn->requested_resource, "all")) {
604 /* We're a non-authoritative directory cache; try again. Ignore status
605 * code, since we don't want to keep trying forever in a tight loop
606 * if all the authorities are shutting us out. */
607 smartlist_t *trusted_dirs = router_get_trusted_dir_servers();
608 SMARTLIST_FOREACH(trusted_dirs, trusted_dir_server_t *, ds,
609 download_status_failed(&ds->v2_ns_dl_status, 0));
610 directory_get_from_dirserver(conn->_base.purpose, conn->router_purpose,
611 "all.z", 0 /* don't retry_if_no_servers */);
612 } else if (!strcmpstart(conn->requested_resource, "fp/")) {
613 /* We were trying to download by fingerprint; mark them all as having
614 * failed, and possibly retry them later.*/
615 smartlist_t *failed = smartlist_create();
616 dir_split_resource_into_fingerprints(conn->requested_resource+3,
617 failed, NULL, 0, 0);
618 if (smartlist_len(failed)) {
619 dir_networkstatus_download_failed(failed, status_code);
620 SMARTLIST_FOREACH(failed, char *, cp, tor_free(cp));
622 smartlist_free(failed);
626 /** Called when an attempt to download one or more router descriptors
627 * or extra-info documents on connection <b>conn</b> failed.
629 static void
630 connection_dir_download_routerdesc_failed(dir_connection_t *conn)
632 /* No need to increment the failure count for routerdescs, since
633 * it's not their fault. */
635 /* No need to relaunch descriptor downloads here: we already do it
636 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
637 tor_assert(conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
638 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO);
640 (void) conn;
643 /** Called when an attempt to fetch a certificate fails. */
644 static void
645 connection_dir_download_cert_failed(dir_connection_t *conn, int status)
647 smartlist_t *failed;
648 tor_assert(conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE);
650 if (!conn->requested_resource)
651 return;
652 failed = smartlist_create();
653 dir_split_resource_into_fingerprints(conn->requested_resource+3,
654 failed, NULL, 1, 0);
655 SMARTLIST_FOREACH(failed, char *, cp,
657 authority_cert_dl_failed(cp, status);
658 tor_free(cp);
660 smartlist_free(failed);
662 update_certificate_downloads(time(NULL));
665 /** Evaluate the situation and decide if we should use an encrypted
666 * "begindir-style" connection for this directory request.
667 * 1) If or_port is 0, or it's a direct conn and or_port is firewalled
668 * or we're a dir mirror, no.
669 * 2) If we prefer to avoid begindir conns, and we're not fetching or
670 * publishing a bridge relay descriptor, no.
671 * 3) Else yes.
673 static int
674 directory_command_should_use_begindir(or_options_t *options,
675 const tor_addr_t *addr,
676 int or_port, uint8_t router_purpose,
677 int anonymized_connection)
679 if (!or_port)
680 return 0; /* We don't know an ORPort -- no chance. */
681 if (!anonymized_connection)
682 if (!fascist_firewall_allows_address_or(addr, or_port) ||
683 directory_fetches_from_authorities(options) ||
684 (server_mode(options) && !options->Address))
685 return 0; /* We're firewalled or are acting like a relay -- also no. */
686 if (!options->TunnelDirConns &&
687 router_purpose != ROUTER_PURPOSE_BRIDGE)
688 return 0; /* We prefer to avoid using begindir conns. Fine. */
689 return 1;
692 /** Helper for directory_initiate_command_routerstatus: send the
693 * command to a server whose address is <b>address</b>, whose IP is
694 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
695 * <b>supports_begindir</b>, and whose identity key digest is
696 * <b>digest</b>. */
697 void
698 directory_initiate_command(const char *address, const tor_addr_t *_addr,
699 uint16_t or_port, uint16_t dir_port,
700 int supports_conditional_consensus,
701 int supports_begindir, const char *digest,
702 uint8_t dir_purpose, uint8_t router_purpose,
703 int anonymized_connection, const char *resource,
704 const char *payload, size_t payload_len,
705 time_t if_modified_since)
707 directory_initiate_command_rend(address, _addr, or_port, dir_port,
708 supports_conditional_consensus,
709 supports_begindir, digest, dir_purpose,
710 router_purpose, anonymized_connection,
711 resource, payload, payload_len,
712 if_modified_since, NULL);
715 /** Same as directory_initiate_command(), but accepts rendezvous data to
716 * fetch a hidden service descriptor. */
717 static void
718 directory_initiate_command_rend(const char *address, const tor_addr_t *_addr,
719 uint16_t or_port, uint16_t dir_port,
720 int supports_conditional_consensus,
721 int supports_begindir, const char *digest,
722 uint8_t dir_purpose, uint8_t router_purpose,
723 int anonymized_connection,
724 const char *resource,
725 const char *payload, size_t payload_len,
726 time_t if_modified_since,
727 const rend_data_t *rend_query)
729 dir_connection_t *conn;
730 or_options_t *options = get_options();
731 int socket_error = 0;
732 int use_begindir = supports_begindir &&
733 directory_command_should_use_begindir(options, _addr,
734 or_port, router_purpose, anonymized_connection);
735 tor_addr_t addr;
737 tor_assert(address);
738 tor_assert(_addr);
739 tor_assert(or_port || dir_port);
740 tor_assert(digest);
742 tor_addr_copy(&addr, _addr);
744 log_debug(LD_DIR, "anonymized %d, use_begindir %d.",
745 anonymized_connection, use_begindir);
747 log_debug(LD_DIR, "Initiating %s", dir_conn_purpose_to_string(dir_purpose));
749 conn = dir_connection_new(AF_INET);
751 /* set up conn so it's got all the data we need to remember */
752 tor_addr_copy(&conn->_base.addr, &addr);
753 conn->_base.port = use_begindir ? or_port : dir_port;
754 conn->_base.address = tor_strdup(address);
755 memcpy(conn->identity_digest, digest, DIGEST_LEN);
757 conn->_base.purpose = dir_purpose;
758 conn->router_purpose = router_purpose;
760 /* give it an initial state */
761 conn->_base.state = DIR_CONN_STATE_CONNECTING;
763 /* decide whether we can learn our IP address from this conn */
764 conn->dirconn_direct = !anonymized_connection;
766 /* copy rendezvous data, if any */
767 if (rend_query)
768 conn->rend_data = rend_data_dup(rend_query);
770 if (!anonymized_connection && !use_begindir) {
771 /* then we want to connect to dirport directly */
773 if (options->HttpProxy) {
774 tor_addr_from_ipv4h(&addr, options->HttpProxyAddr);
775 dir_port = options->HttpProxyPort;
778 switch (connection_connect(TO_CONN(conn), conn->_base.address, &addr,
779 dir_port, &socket_error)) {
780 case -1:
781 connection_dir_request_failed(conn); /* retry if we want */
782 /* XXX we only pass 'conn' above, not 'resource', 'payload',
783 * etc. So in many situations it can't retry! -RD */
784 connection_free(TO_CONN(conn));
785 return;
786 case 1:
787 /* start flushing conn */
788 conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
789 /* fall through */
790 case 0:
791 /* queue the command on the outbuf */
792 directory_send_command(conn, dir_purpose, 1, resource,
793 payload, payload_len,
794 supports_conditional_consensus,
795 if_modified_since);
796 connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
797 /* writable indicates finish, readable indicates broken link,
798 error indicates broken link in windowsland. */
800 } else { /* we want to connect via a tor connection */
801 edge_connection_t *linked_conn;
803 /* If it's an anonymized connection, remember the fact that we
804 * wanted it for later: maybe we'll want it again soon. */
805 if (anonymized_connection && use_begindir)
806 rep_hist_note_used_internal(time(NULL), 0, 1);
807 else if (anonymized_connection && !use_begindir)
808 rep_hist_note_used_port(time(NULL), conn->_base.port);
810 /* make an AP connection
811 * populate it and add it at the right state
812 * hook up both sides
814 linked_conn =
815 connection_ap_make_link(conn->_base.address, conn->_base.port,
816 digest, use_begindir, conn->dirconn_direct);
817 if (!linked_conn) {
818 log_warn(LD_NET,"Making tunnel to dirserver failed.");
819 connection_mark_for_close(TO_CONN(conn));
820 return;
822 connection_link_connections(TO_CONN(conn), TO_CONN(linked_conn));
824 if (connection_add(TO_CONN(conn)) < 0) {
825 log_warn(LD_NET,"Unable to add connection for link to dirserver.");
826 connection_mark_for_close(TO_CONN(conn));
827 return;
829 conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING;
830 /* queue the command on the outbuf */
831 directory_send_command(conn, dir_purpose, 0, resource,
832 payload, payload_len,
833 supports_conditional_consensus,
834 if_modified_since);
835 connection_watch_events(TO_CONN(conn), EV_READ | EV_WRITE);
836 connection_start_reading(TO_CONN(linked_conn));
840 /** Return true iff anything we say on <b>conn</b> is being encrypted before
841 * we send it to the client/server. */
843 connection_dir_is_encrypted(dir_connection_t *conn)
845 /* Right now it's sufficient to see if conn is or has been linked, since
846 * the only thing it could be linked to is an edge connection on a
847 * circuit, and the only way it could have been unlinked is at the edge
848 * connection getting closed.
850 return TO_CONN(conn)->linked;
853 /** Helper for sorting
855 * sort strings alphabetically
857 static int
858 _compare_strs(const void **a, const void **b)
860 const char *s1 = *a, *s2 = *b;
861 return strcmp(s1, s2);
864 #define CONDITIONAL_CONSENSUS_FPR_LEN 3
865 #if (CONDITIONAL_CONSENSUS_FPR_LEN > DIGEST_LEN)
866 #error "conditional consensus fingerprint length is larger than digest length"
867 #endif
869 /** Return the URL we should use for a consensus download.
871 * This url depends on whether or not the server we go to
872 * is sufficiently new to support conditional consensus downloading,
873 * i.e. GET .../consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>
875 static char *
876 directory_get_consensus_url(int supports_conditional_consensus)
878 char *url;
879 size_t len;
881 if (supports_conditional_consensus) {
882 char *authority_id_list;
883 smartlist_t *authority_digets = smartlist_create();
885 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
886 trusted_dir_server_t *, ds,
888 char *hex;
889 if (!(ds->type & V3_AUTHORITY))
890 continue;
892 hex = tor_malloc(2*CONDITIONAL_CONSENSUS_FPR_LEN+1);
893 base16_encode(hex, 2*CONDITIONAL_CONSENSUS_FPR_LEN+1,
894 ds->v3_identity_digest, CONDITIONAL_CONSENSUS_FPR_LEN);
895 smartlist_add(authority_digets, hex);
897 smartlist_sort(authority_digets, _compare_strs);
898 authority_id_list = smartlist_join_strings(authority_digets,
899 "+", 0, NULL);
901 len = strlen(authority_id_list)+64;
902 url = tor_malloc(len);
903 tor_snprintf(url, len, "/tor/status-vote/current/consensus/%s.z",
904 authority_id_list);
906 SMARTLIST_FOREACH(authority_digets, char *, cp, tor_free(cp));
907 smartlist_free(authority_digets);
908 tor_free(authority_id_list);
909 } else {
910 url = tor_strdup("/tor/status-vote/current/consensus.z");
912 return url;
915 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
916 * are as in directory_initiate_command.
918 static void
919 directory_send_command(dir_connection_t *conn,
920 int purpose, int direct, const char *resource,
921 const char *payload, size_t payload_len,
922 int supports_conditional_consensus,
923 time_t if_modified_since)
925 char proxystring[256];
926 char proxyauthstring[256];
927 char hoststring[128];
928 char imsstring[RFC1123_TIME_LEN+32];
929 char *url;
930 char request[8192];
931 const char *httpcommand = NULL;
932 size_t len;
934 tor_assert(conn);
935 tor_assert(conn->_base.type == CONN_TYPE_DIR);
937 tor_free(conn->requested_resource);
938 if (resource)
939 conn->requested_resource = tor_strdup(resource);
941 /* come up with a string for which Host: we want */
942 if (conn->_base.port == 80) {
943 strlcpy(hoststring, conn->_base.address, sizeof(hoststring));
944 } else {
945 tor_snprintf(hoststring, sizeof(hoststring),"%s:%d",
946 conn->_base.address, conn->_base.port);
949 /* Format if-modified-since */
950 if (!if_modified_since) {
951 imsstring[0] = '\0';
952 } else {
953 char b[RFC1123_TIME_LEN+1];
954 format_rfc1123_time(b, if_modified_since);
955 tor_snprintf(imsstring, sizeof(imsstring), "\r\nIf-Modified-Since: %s", b);
958 /* come up with some proxy lines, if we're using one. */
959 if (direct && get_options()->HttpProxy) {
960 char *base64_authenticator=NULL;
961 const char *authenticator = get_options()->HttpProxyAuthenticator;
963 tor_snprintf(proxystring, sizeof(proxystring),"http://%s", hoststring);
964 if (authenticator) {
965 base64_authenticator = alloc_http_authenticator(authenticator);
966 if (!base64_authenticator)
967 log_warn(LD_BUG, "Encoding http authenticator failed");
969 if (base64_authenticator) {
970 tor_snprintf(proxyauthstring, sizeof(proxyauthstring),
971 "\r\nProxy-Authorization: Basic %s",
972 base64_authenticator);
973 tor_free(base64_authenticator);
974 } else {
975 proxyauthstring[0] = 0;
977 } else {
978 proxystring[0] = 0;
979 proxyauthstring[0] = 0;
982 switch (purpose) {
983 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS:
984 tor_assert(resource);
985 httpcommand = "GET";
986 len = strlen(resource)+32;
987 url = tor_malloc(len);
988 tor_snprintf(url, len, "/tor/status/%s", resource);
989 break;
990 case DIR_PURPOSE_FETCH_CONSENSUS:
991 tor_assert(!resource);
992 tor_assert(!payload);
993 httpcommand = "GET";
994 url = directory_get_consensus_url(supports_conditional_consensus);
995 log_info(LD_DIR, "Downloading consensus from %s using %s",
996 hoststring, url);
997 break;
998 case DIR_PURPOSE_FETCH_CERTIFICATE:
999 tor_assert(resource);
1000 tor_assert(!payload);
1001 httpcommand = "GET";
1002 len = strlen(resource)+32;
1003 url = tor_malloc(len);
1004 tor_snprintf(url, len, "/tor/keys/%s", resource);
1005 break;
1006 case DIR_PURPOSE_FETCH_STATUS_VOTE:
1007 tor_assert(resource);
1008 tor_assert(!payload);
1009 httpcommand = "GET";
1010 len = strlen(resource)+32;
1011 url = tor_malloc(len);
1012 tor_snprintf(url, len, "/tor/status-vote/next/%s.z", resource);
1013 break;
1014 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES:
1015 tor_assert(!resource);
1016 tor_assert(!payload);
1017 httpcommand = "GET";
1018 url = tor_strdup("/tor/status-vote/next/consensus-signatures.z");
1019 break;
1020 case DIR_PURPOSE_FETCH_SERVERDESC:
1021 tor_assert(resource);
1022 httpcommand = "GET";
1023 len = strlen(resource)+32;
1024 url = tor_malloc(len);
1025 tor_snprintf(url, len, "/tor/server/%s", resource);
1026 break;
1027 case DIR_PURPOSE_FETCH_EXTRAINFO:
1028 tor_assert(resource);
1029 httpcommand = "GET";
1030 len = strlen(resource)+32;
1031 url = tor_malloc(len);
1032 tor_snprintf(url, len, "/tor/extra/%s", resource);
1033 break;
1034 case DIR_PURPOSE_UPLOAD_DIR:
1035 tor_assert(!resource);
1036 tor_assert(payload);
1037 httpcommand = "POST";
1038 url = tor_strdup("/tor/");
1039 break;
1040 case DIR_PURPOSE_UPLOAD_VOTE:
1041 tor_assert(!resource);
1042 tor_assert(payload);
1043 httpcommand = "POST";
1044 url = tor_strdup("/tor/post/vote");
1045 break;
1046 case DIR_PURPOSE_UPLOAD_SIGNATURES:
1047 tor_assert(!resource);
1048 tor_assert(payload);
1049 httpcommand = "POST";
1050 url = tor_strdup("/tor/post/consensus-signature");
1051 break;
1052 case DIR_PURPOSE_FETCH_RENDDESC:
1053 tor_assert(resource);
1054 tor_assert(!payload);
1056 /* this must be true or we wouldn't be doing the lookup */
1057 tor_assert(strlen(resource) <= REND_SERVICE_ID_LEN_BASE32);
1058 /* This breaks the function abstraction. */
1059 conn->rend_data = tor_malloc_zero(sizeof(rend_data_t));
1060 strlcpy(conn->rend_data->onion_address, resource,
1061 sizeof(conn->rend_data->onion_address));
1062 conn->rend_data->rend_desc_version = 0;
1064 httpcommand = "GET";
1065 /* Request the most recent versioned descriptor. */
1066 // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
1067 // but that never got testing, and it wasn't a good design.)
1068 len = strlen(resource)+32;
1069 url = tor_malloc(len);
1070 tor_snprintf(url, len, "/tor/rendezvous/%s", resource);
1071 break;
1072 case DIR_PURPOSE_FETCH_RENDDESC_V2:
1073 tor_assert(resource);
1074 tor_assert(strlen(resource) <= REND_DESC_ID_V2_LEN_BASE32);
1075 tor_assert(!payload);
1076 conn->rend_data->rend_desc_version = 2;
1077 httpcommand = "GET";
1078 len = strlen(resource) + 32;
1079 url = tor_malloc(len);
1080 tor_snprintf(url, len, "/tor/rendezvous2/%s", resource);
1081 break;
1082 case DIR_PURPOSE_UPLOAD_RENDDESC:
1083 tor_assert(!resource);
1084 tor_assert(payload);
1085 httpcommand = "POST";
1086 url = tor_strdup("/tor/rendezvous/publish");
1087 break;
1088 case DIR_PURPOSE_UPLOAD_RENDDESC_V2:
1089 tor_assert(!resource);
1090 tor_assert(payload);
1091 httpcommand = "POST";
1092 url = tor_strdup("/tor/rendezvous2/publish");
1093 break;
1094 default:
1095 tor_assert(0);
1096 return;
1099 if (strlen(proxystring) + strlen(url) >= 4096) {
1100 log_warn(LD_BUG,
1101 "Squid does not like URLs longer than 4095 bytes, and this "
1102 "one is %d bytes long: %s%s",
1103 (int)(strlen(proxystring) + strlen(url)), proxystring, url);
1106 tor_snprintf(request, sizeof(request), "%s %s", httpcommand, proxystring);
1107 connection_write_to_buf(request, strlen(request), TO_CONN(conn));
1108 connection_write_to_buf(url, strlen(url), TO_CONN(conn));
1109 tor_free(url);
1111 if (!strcmp(httpcommand, "GET") && !payload) {
1112 tor_snprintf(request, sizeof(request),
1113 " HTTP/1.0\r\nHost: %s%s%s\r\n\r\n",
1114 hoststring,
1115 imsstring,
1116 proxyauthstring);
1117 } else {
1118 tor_snprintf(request, sizeof(request),
1119 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s%s\r\n\r\n",
1120 payload ? (unsigned long)payload_len : 0,
1121 hoststring,
1122 imsstring,
1123 proxyauthstring);
1125 connection_write_to_buf(request, strlen(request), TO_CONN(conn));
1127 if (payload) {
1128 /* then send the payload afterwards too */
1129 connection_write_to_buf(payload, payload_len, TO_CONN(conn));
1133 /** Parse an HTTP request string <b>headers</b> of the form
1134 * \verbatim
1135 * "\%s [http[s]://]\%s HTTP/1..."
1136 * \endverbatim
1137 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
1138 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
1139 * so it does. Return 0.
1140 * Otherwise, return -1.
1142 static int
1143 parse_http_url(const char *headers, char **url)
1145 char *s, *start, *tmp;
1147 s = (char *)eat_whitespace_no_nl(headers);
1148 if (!*s) return -1;
1149 s = (char *)find_whitespace(s); /* get past GET/POST */
1150 if (!*s) return -1;
1151 s = (char *)eat_whitespace_no_nl(s);
1152 if (!*s) return -1;
1153 start = s; /* this is it, assuming it's valid */
1154 s = (char *)find_whitespace(start);
1155 if (!*s) return -1;
1157 /* tolerate the http[s] proxy style of putting the hostname in the url */
1158 if (s-start >= 4 && !strcmpstart(start,"http")) {
1159 tmp = start + 4;
1160 if (*tmp == 's')
1161 tmp++;
1162 if (s-tmp >= 3 && !strcmpstart(tmp,"://")) {
1163 tmp = strchr(tmp+3, '/');
1164 if (tmp && tmp < s) {
1165 log_debug(LD_DIR,"Skipping over 'http[s]://hostname' string");
1166 start = tmp;
1171 if (s-start < 5 || strcmpstart(start,"/tor/")) { /* need to rewrite it */
1172 *url = tor_malloc(s - start + 5);
1173 strlcpy(*url,"/tor", s-start+5);
1174 strlcat((*url)+4, start, s-start+1);
1175 } else {
1176 *url = tor_strndup(start, s-start);
1178 return 0;
1181 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
1182 * <b>which</b>. The key should be given with a terminating colon and space;
1183 * this function copies everything after, up to but not including the
1184 * following \\r\\n. */
1185 static char *
1186 http_get_header(const char *headers, const char *which)
1188 const char *cp = headers;
1189 while (cp) {
1190 if (!strcasecmpstart(cp, which)) {
1191 char *eos;
1192 cp += strlen(which);
1193 if ((eos = strchr(cp,'\r')))
1194 return tor_strndup(cp, eos-cp);
1195 else
1196 return tor_strdup(cp);
1198 cp = strchr(cp, '\n');
1199 if (cp)
1200 ++cp;
1202 return NULL;
1205 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
1206 * <b>conn</b>-\>address to describe our best guess of the address that
1207 * originated this HTTP request. */
1208 static void
1209 http_set_address_origin(const char *headers, connection_t *conn)
1211 char *fwd;
1213 fwd = http_get_header(headers, "Forwarded-For: ");
1214 if (!fwd)
1215 fwd = http_get_header(headers, "X-Forwarded-For: ");
1216 if (fwd) {
1217 struct in_addr in;
1218 if (!tor_inet_aton(fwd, &in) || is_internal_IP(ntohl(in.s_addr), 0)) {
1219 log_debug(LD_DIR, "Ignoring unrecognized or internal IP %s",
1220 escaped(fwd));
1221 tor_free(fwd);
1222 return;
1224 tor_free(conn->address);
1225 conn->address = tor_strdup(fwd);
1226 tor_free(fwd);
1230 /** Parse an HTTP response string <b>headers</b> of the form
1231 * \verbatim
1232 * "HTTP/1.\%d \%d\%s\r\n...".
1233 * \endverbatim
1235 * If it's well-formed, assign the status code to *<b>code</b> and
1236 * return 0. Otherwise, return -1.
1238 * On success: If <b>date</b> is provided, set *date to the Date
1239 * header in the http headers, or 0 if no such header is found. If
1240 * <b>compression</b> is provided, set *<b>compression</b> to the
1241 * compression method given in the Content-Encoding header, or 0 if no
1242 * such header is found, or -1 if the value of the header is not
1243 * recognized. If <b>reason</b> is provided, strdup the reason string
1244 * into it.
1247 parse_http_response(const char *headers, int *code, time_t *date,
1248 compress_method_t *compression, char **reason)
1250 unsigned n1, n2;
1251 char datestr[RFC1123_TIME_LEN+1];
1252 smartlist_t *parsed_headers;
1253 tor_assert(headers);
1254 tor_assert(code);
1256 while (TOR_ISSPACE(*headers)) headers++; /* tolerate leading whitespace */
1258 if (tor_sscanf(headers, "HTTP/1.%u %u", &n1, &n2) < 2 ||
1259 (n1 != 0 && n1 != 1) ||
1260 (n2 < 100 || n2 >= 600)) {
1261 log_warn(LD_HTTP,"Failed to parse header %s",escaped(headers));
1262 return -1;
1264 *code = n2;
1266 parsed_headers = smartlist_create();
1267 smartlist_split_string(parsed_headers, headers, "\n",
1268 SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, -1);
1269 if (reason) {
1270 smartlist_t *status_line_elements = smartlist_create();
1271 tor_assert(smartlist_len(parsed_headers));
1272 smartlist_split_string(status_line_elements,
1273 smartlist_get(parsed_headers, 0),
1274 " ", SPLIT_SKIP_SPACE|SPLIT_IGNORE_BLANK, 3);
1275 tor_assert(smartlist_len(status_line_elements) <= 3);
1276 if (smartlist_len(status_line_elements) == 3) {
1277 *reason = smartlist_get(status_line_elements, 2);
1278 smartlist_set(status_line_elements, 2, NULL); /* Prevent free */
1280 SMARTLIST_FOREACH(status_line_elements, char *, cp, tor_free(cp));
1281 smartlist_free(status_line_elements);
1283 if (date) {
1284 *date = 0;
1285 SMARTLIST_FOREACH(parsed_headers, const char *, s,
1286 if (!strcmpstart(s, "Date: ")) {
1287 strlcpy(datestr, s+6, sizeof(datestr));
1288 /* This will do nothing on failure, so we don't need to check
1289 the result. We shouldn't warn, since there are many other valid
1290 date formats besides the one we use. */
1291 parse_rfc1123_time(datestr, date);
1292 break;
1295 if (compression) {
1296 const char *enc = NULL;
1297 SMARTLIST_FOREACH(parsed_headers, const char *, s,
1298 if (!strcmpstart(s, "Content-Encoding: ")) {
1299 enc = s+18; break;
1301 if (!enc || !strcmp(enc, "identity")) {
1302 *compression = NO_METHOD;
1303 } else if (!strcmp(enc, "deflate") || !strcmp(enc, "x-deflate")) {
1304 *compression = ZLIB_METHOD;
1305 } else if (!strcmp(enc, "gzip") || !strcmp(enc, "x-gzip")) {
1306 *compression = GZIP_METHOD;
1307 } else {
1308 log_info(LD_HTTP, "Unrecognized content encoding: %s. Trying to deal.",
1309 escaped(enc));
1310 *compression = UNKNOWN_METHOD;
1313 SMARTLIST_FOREACH(parsed_headers, char *, s, tor_free(s));
1314 smartlist_free(parsed_headers);
1316 return 0;
1319 /** Return true iff <b>body</b> doesn't start with a plausible router or
1320 * running-list or directory opening. This is a sign of possible compression.
1322 static int
1323 body_is_plausible(const char *body, size_t len, int purpose)
1325 int i;
1326 if (len == 0)
1327 return 1; /* empty bodies don't need decompression */
1328 if (len < 32)
1329 return 0;
1330 if (purpose != DIR_PURPOSE_FETCH_RENDDESC) {
1331 if (!strcmpstart(body,"router") ||
1332 !strcmpstart(body,"signed-directory") ||
1333 !strcmpstart(body,"network-status") ||
1334 !strcmpstart(body,"running-routers"))
1335 return 1;
1336 for (i=0;i<32;++i) {
1337 if (!TOR_ISPRINT(body[i]) && !TOR_ISSPACE(body[i]))
1338 return 0;
1340 return 1;
1341 } else {
1342 return 1;
1346 /** Called when we've just fetched a bunch of router descriptors in
1347 * <b>body</b>. The list <b>which</b>, if present, holds digests for
1348 * descriptors we requested: descriptor digests if <b>descriptor_digests</b>
1349 * is true, or identity digests otherwise. Parse the descriptors, validate
1350 * them, and annotate them as having purpose <b>purpose</b> and as having been
1351 * downloaded from <b>source</b>.
1353 * Return the number of routers actually added. */
1354 static int
1355 load_downloaded_routers(const char *body, smartlist_t *which,
1356 int descriptor_digests,
1357 int router_purpose,
1358 const char *source)
1360 char buf[256];
1361 char time_buf[ISO_TIME_LEN+1];
1362 int added = 0;
1363 int general = router_purpose == ROUTER_PURPOSE_GENERAL;
1364 format_iso_time(time_buf, time(NULL));
1365 tor_assert(source);
1367 if (tor_snprintf(buf, sizeof(buf),
1368 "@downloaded-at %s\n"
1369 "@source %s\n"
1370 "%s%s%s", time_buf, escaped(source),
1371 !general ? "@purpose " : "",
1372 !general ? router_purpose_to_string(router_purpose) : "",
1373 !general ? "\n" : "")<0)
1374 return added;
1376 added = router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1377 descriptor_digests, buf);
1378 control_event_bootstrap(BOOTSTRAP_STATUS_LOADING_DESCRIPTORS,
1379 count_loading_descriptors_progress());
1380 return added;
1383 /** We are a client, and we've finished reading the server's
1384 * response. Parse it and act appropriately.
1386 * If we're still happy with using this directory server in the future, return
1387 * 0. Otherwise return -1; and the caller should consider trying the request
1388 * again.
1390 * The caller will take care of marking the connection for close.
1392 static int
1393 connection_dir_client_reached_eof(dir_connection_t *conn)
1395 char *body;
1396 char *headers;
1397 char *reason = NULL;
1398 size_t body_len=0, orig_len=0;
1399 int status_code;
1400 time_t date_header=0;
1401 long delta;
1402 compress_method_t compression;
1403 int plausible;
1404 int skewed=0;
1405 int allow_partial = (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
1406 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO);
1407 int was_compressed=0;
1408 time_t now = time(NULL);
1410 switch (fetch_from_buf_http(conn->_base.inbuf,
1411 &headers, MAX_HEADERS_SIZE,
1412 &body, &body_len, MAX_DIR_DL_SIZE,
1413 allow_partial)) {
1414 case -1: /* overflow */
1415 log_warn(LD_PROTOCOL,
1416 "'fetch' response too large (server '%s:%d'). Closing.",
1417 conn->_base.address, conn->_base.port);
1418 return -1;
1419 case 0:
1420 log_info(LD_HTTP,
1421 "'fetch' response not all here, but we're at eof. Closing.");
1422 return -1;
1423 /* case 1, fall through */
1425 orig_len = body_len;
1427 if (parse_http_response(headers, &status_code, &date_header,
1428 &compression, &reason) < 0) {
1429 log_warn(LD_HTTP,"Unparseable headers (server '%s:%d'). Closing.",
1430 conn->_base.address, conn->_base.port);
1431 tor_free(body); tor_free(headers);
1432 return -1;
1434 if (!reason) reason = tor_strdup("[no reason given]");
1436 log_debug(LD_DIR,
1437 "Received response from directory server '%s:%d': %d %s",
1438 conn->_base.address, conn->_base.port, status_code,
1439 escaped(reason));
1441 /* now check if it's got any hints for us about our IP address. */
1442 if (conn->dirconn_direct) {
1443 char *guess = http_get_header(headers, X_ADDRESS_HEADER);
1444 if (guess) {
1445 router_new_address_suggestion(guess, conn);
1446 tor_free(guess);
1450 if (date_header > 0) {
1451 /* The date header was written very soon after we sent our request,
1452 * so compute the skew as the difference between sending the request
1453 * and the date header. (We used to check now-date_header, but that's
1454 * inaccurate if we spend a lot of time downloading.)
1456 delta = conn->_base.timestamp_lastwritten - date_header;
1457 if (labs(delta)>ALLOW_DIRECTORY_TIME_SKEW) {
1458 char dbuf[64];
1459 int trusted = router_digest_is_trusted_dir(conn->identity_digest);
1460 format_time_interval(dbuf, sizeof(dbuf), delta);
1461 log_fn(trusted ? LOG_WARN : LOG_INFO,
1462 LD_HTTP,
1463 "Received directory with skewed time (server '%s:%d'): "
1464 "It seems that our clock is %s by %s, or that theirs is %s. "
1465 "Tor requires an accurate clock to work: please check your time, "
1466 "timezone, and date settings.",
1467 conn->_base.address, conn->_base.port,
1468 delta>0 ? "ahead" : "behind", dbuf,
1469 delta>0 ? "behind" : "ahead");
1470 skewed = 1; /* don't check the recommended-versions line */
1471 if (trusted)
1472 control_event_general_status(LOG_WARN,
1473 "CLOCK_SKEW SKEW=%ld SOURCE=DIRSERV:%s:%d",
1474 delta, conn->_base.address, conn->_base.port);
1475 } else {
1476 log_debug(LD_HTTP, "Time on received directory is within tolerance; "
1477 "we are %ld seconds skewed. (That's okay.)", delta);
1480 (void) skewed; /* skewed isn't used yet. */
1482 if (status_code == 503 && body_len < 16) {
1483 routerstatus_t *rs;
1484 trusted_dir_server_t *ds;
1485 log_info(LD_DIR,"Received http status code %d (%s) from server "
1486 "'%s:%d'. I'll try again soon.",
1487 status_code, escaped(reason), conn->_base.address,
1488 conn->_base.port);
1489 if ((rs = router_get_consensus_status_by_id(conn->identity_digest)))
1490 rs->last_dir_503_at = now;
1491 if ((ds = router_get_trusteddirserver_by_digest(conn->identity_digest)))
1492 ds->fake_status.last_dir_503_at = now;
1494 tor_free(body); tor_free(headers); tor_free(reason);
1495 return -1;
1496 } else if (status_code == 503) {
1497 /* XXXX022 Remove this once every server with bug 539 is obsolete. */
1498 log_info(LD_DIR, "Server at '%s:%d' sent us a 503 response, but included "
1499 "a body anyway. We'll pretend it gave us a 200.",
1500 conn->_base.address, conn->_base.port);
1501 status_code = 200;
1504 plausible = body_is_plausible(body, body_len, conn->_base.purpose);
1505 if (compression != NO_METHOD || !plausible) {
1506 char *new_body = NULL;
1507 size_t new_len = 0;
1508 compress_method_t guessed = detect_compression_method(body, body_len);
1509 if (compression == UNKNOWN_METHOD || guessed != compression) {
1510 /* Tell the user if we don't believe what we're told about compression.*/
1511 const char *description1, *description2;
1512 if (compression == ZLIB_METHOD)
1513 description1 = "as deflated";
1514 else if (compression == GZIP_METHOD)
1515 description1 = "as gzipped";
1516 else if (compression == NO_METHOD)
1517 description1 = "as uncompressed";
1518 else
1519 description1 = "with an unknown Content-Encoding";
1520 if (guessed == ZLIB_METHOD)
1521 description2 = "deflated";
1522 else if (guessed == GZIP_METHOD)
1523 description2 = "gzipped";
1524 else if (!plausible)
1525 description2 = "confusing binary junk";
1526 else
1527 description2 = "uncompressed";
1529 log_info(LD_HTTP, "HTTP body from server '%s:%d' was labeled %s, "
1530 "but it seems to be %s.%s",
1531 conn->_base.address, conn->_base.port, description1,
1532 description2,
1533 (compression>0 && guessed>0)?" Trying both.":"");
1535 /* Try declared compression first if we can. */
1536 if (compression == GZIP_METHOD || compression == ZLIB_METHOD)
1537 tor_gzip_uncompress(&new_body, &new_len, body, body_len, compression,
1538 !allow_partial, LOG_PROTOCOL_WARN);
1539 /* Okay, if that didn't work, and we think that it was compressed
1540 * differently, try that. */
1541 if (!new_body &&
1542 (guessed == GZIP_METHOD || guessed == ZLIB_METHOD) &&
1543 compression != guessed)
1544 tor_gzip_uncompress(&new_body, &new_len, body, body_len, guessed,
1545 !allow_partial, LOG_PROTOCOL_WARN);
1546 /* If we're pretty sure that we have a compressed directory, and
1547 * we didn't manage to uncompress it, then warn and bail. */
1548 if (!plausible && !new_body) {
1549 log_fn(LOG_PROTOCOL_WARN, LD_HTTP,
1550 "Unable to decompress HTTP body (server '%s:%d').",
1551 conn->_base.address, conn->_base.port);
1552 tor_free(body); tor_free(headers); tor_free(reason);
1553 return -1;
1555 if (new_body) {
1556 tor_free(body);
1557 body = new_body;
1558 body_len = new_len;
1559 was_compressed = 1;
1563 if (conn->_base.purpose == DIR_PURPOSE_FETCH_V2_NETWORKSTATUS) {
1564 smartlist_t *which = NULL;
1565 v2_networkstatus_source_t source;
1566 char *cp;
1567 log_info(LD_DIR,"Received networkstatus objects (size %d) from server "
1568 "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
1569 if (status_code != 200) {
1570 log_warn(LD_DIR,
1571 "Received http status code %d (%s) from server "
1572 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1573 status_code, escaped(reason), conn->_base.address,
1574 conn->_base.port, conn->requested_resource);
1575 tor_free(body); tor_free(headers); tor_free(reason);
1576 connection_dir_download_networkstatus_failed(conn, status_code);
1577 return -1;
1579 if (conn->requested_resource &&
1580 !strcmpstart(conn->requested_resource,"fp/")) {
1581 source = NS_FROM_DIR_BY_FP;
1582 which = smartlist_create();
1583 dir_split_resource_into_fingerprints(conn->requested_resource+3,
1584 which, NULL, 0, 0);
1585 } else if (conn->requested_resource &&
1586 !strcmpstart(conn->requested_resource, "all")) {
1587 source = NS_FROM_DIR_ALL;
1588 which = smartlist_create();
1589 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1590 trusted_dir_server_t *, ds,
1592 char *hex = tor_malloc(HEX_DIGEST_LEN+1);
1593 base16_encode(hex, HEX_DIGEST_LEN+1, ds->digest, DIGEST_LEN);
1594 smartlist_add(which, hex);
1596 } else {
1597 /* XXXX Can we even end up here? -- weasel*/
1598 source = NS_FROM_DIR_BY_FP;
1599 log_warn(LD_BUG, "We received a networkstatus but we didn't ask "
1600 "for it by fp, nor did we ask for all.");
1602 cp = body;
1603 while (*cp) {
1604 char *next = strstr(cp, "\nnetwork-status-version");
1605 if (next)
1606 next[1] = '\0';
1607 /* learn from it, and then remove it from 'which' */
1608 if (router_set_networkstatus_v2(cp, now, source, which)<0)
1609 break;
1610 if (next) {
1611 next[1] = 'n';
1612 cp = next+1;
1613 } else
1614 break;
1616 /* launches router downloads as needed */
1617 routers_update_all_from_networkstatus(now, 2);
1618 directory_info_has_arrived(now, 0);
1619 if (which) {
1620 if (smartlist_len(which)) {
1621 dir_networkstatus_download_failed(which, status_code);
1623 SMARTLIST_FOREACH(which, char *, s, tor_free(s));
1624 smartlist_free(which);
1628 if (conn->_base.purpose == DIR_PURPOSE_FETCH_CONSENSUS) {
1629 int r;
1630 if (status_code != 200) {
1631 int severity = (status_code == 304) ? LOG_INFO : LOG_WARN;
1632 log(severity, LD_DIR,
1633 "Received http status code %d (%s) from server "
1634 "'%s:%d' while fetching consensus directory.",
1635 status_code, escaped(reason), conn->_base.address,
1636 conn->_base.port);
1637 tor_free(body); tor_free(headers); tor_free(reason);
1638 networkstatus_consensus_download_failed(status_code);
1639 return -1;
1641 log_info(LD_DIR,"Received consensus directory (size %d) from server "
1642 "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
1643 if ((r=networkstatus_set_current_consensus(body, 0))<0) {
1644 log_fn(r<-1?LOG_WARN:LOG_INFO, LD_DIR,
1645 "Unable to load consensus directory downloaded from "
1646 "server '%s:%d'. I'll try again soon.",
1647 conn->_base.address, conn->_base.port);
1648 tor_free(body); tor_free(headers); tor_free(reason);
1649 networkstatus_consensus_download_failed(0);
1650 return -1;
1652 /* launches router downloads as needed */
1653 routers_update_all_from_networkstatus(now, 3);
1654 directory_info_has_arrived(now, 0);
1655 log_info(LD_DIR, "Successfully loaded consensus.");
1658 if (conn->_base.purpose == DIR_PURPOSE_FETCH_CERTIFICATE) {
1659 if (status_code != 200) {
1660 log_warn(LD_DIR,
1661 "Received http status code %d (%s) from server "
1662 "'%s:%d' while fetching \"/tor/keys/%s\".",
1663 status_code, escaped(reason), conn->_base.address,
1664 conn->_base.port, conn->requested_resource);
1665 connection_dir_download_cert_failed(conn, status_code);
1666 tor_free(body); tor_free(headers); tor_free(reason);
1667 return -1;
1669 log_info(LD_DIR,"Received authority certificates (size %d) from server "
1670 "'%s:%d'",(int) body_len, conn->_base.address, conn->_base.port);
1671 if (trusted_dirs_load_certs_from_string(body, 0, 1)<0) {
1672 log_warn(LD_DIR, "Unable to parse fetched certificates");
1673 connection_dir_download_cert_failed(conn, status_code);
1674 } else {
1675 directory_info_has_arrived(now, 0);
1676 log_info(LD_DIR, "Successfully loaded certificates from fetch.");
1679 if (conn->_base.purpose == DIR_PURPOSE_FETCH_STATUS_VOTE) {
1680 const char *msg;
1681 int st;
1682 log_info(LD_DIR,"Got votes (size %d) from server %s:%d",
1683 (int) body_len, conn->_base.address, conn->_base.port);
1684 if (status_code != 200) {
1685 log_warn(LD_DIR,
1686 "Received http status code %d (%s) from server "
1687 "'%s:%d' while fetching \"/tor/status-vote/next/%s.z\".",
1688 status_code, escaped(reason), conn->_base.address,
1689 conn->_base.port, conn->requested_resource);
1690 tor_free(body); tor_free(headers); tor_free(reason);
1691 return -1;
1693 dirvote_add_vote(body, &msg, &st);
1694 if (st > 299) {
1695 log_warn(LD_DIR, "Error adding retrieved vote: %s", msg);
1696 } else {
1697 log_info(LD_DIR, "Added vote(s) successfully [msg: %s]", msg);
1700 if (conn->_base.purpose == DIR_PURPOSE_FETCH_DETACHED_SIGNATURES) {
1701 const char *msg = NULL;
1702 log_info(LD_DIR,"Got detached signatures (size %d) from server %s:%d",
1703 (int) body_len, conn->_base.address, conn->_base.port);
1704 if (status_code != 200) {
1705 log_warn(LD_DIR,
1706 "Received http status code %d (%s) from server "
1707 "'%s:%d' while fetching \"/tor/status-vote/consensus-signatures.z\".",
1708 status_code, escaped(reason), conn->_base.address,
1709 conn->_base.port);
1710 tor_free(body); tor_free(headers); tor_free(reason);
1711 return -1;
1713 if (dirvote_add_signatures(body, conn->_base.address, &msg)<0) {
1714 log_warn(LD_DIR, "Problem adding detached signatures from %s:%d: %s",
1715 conn->_base.address, conn->_base.port, msg?msg:"???");
1719 if (conn->_base.purpose == DIR_PURPOSE_FETCH_SERVERDESC ||
1720 conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO) {
1721 int was_ei = conn->_base.purpose == DIR_PURPOSE_FETCH_EXTRAINFO;
1722 smartlist_t *which = NULL;
1723 int n_asked_for = 0;
1724 int descriptor_digests = conn->requested_resource &&
1725 !strcmpstart(conn->requested_resource,"d/");
1726 log_info(LD_DIR,"Received %s (size %d) from server '%s:%d'",
1727 was_ei ? "extra server info" : "server info",
1728 (int)body_len, conn->_base.address, conn->_base.port);
1729 if (conn->requested_resource &&
1730 (!strcmpstart(conn->requested_resource,"d/") ||
1731 !strcmpstart(conn->requested_resource,"fp/"))) {
1732 which = smartlist_create();
1733 dir_split_resource_into_fingerprints(conn->requested_resource +
1734 (descriptor_digests ? 2 : 3),
1735 which, NULL, 0, 0);
1736 n_asked_for = smartlist_len(which);
1738 if (status_code != 200) {
1739 int dir_okay = status_code == 404 ||
1740 (status_code == 400 && !strcmp(reason, "Servers unavailable."));
1741 /* 404 means that it didn't have them; no big deal.
1742 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1743 log_fn(dir_okay ? LOG_INFO : LOG_WARN, LD_DIR,
1744 "Received http status code %d (%s) from server '%s:%d' "
1745 "while fetching \"/tor/server/%s\". I'll try again soon.",
1746 status_code, escaped(reason), conn->_base.address,
1747 conn->_base.port, conn->requested_resource);
1748 if (!which) {
1749 connection_dir_download_routerdesc_failed(conn);
1750 } else {
1751 dir_routerdesc_download_failed(which, status_code,
1752 conn->router_purpose,
1753 was_ei, descriptor_digests);
1754 SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
1755 smartlist_free(which);
1757 tor_free(body); tor_free(headers); tor_free(reason);
1758 return dir_okay ? 0 : -1;
1760 /* Learn the routers, assuming we requested by fingerprint or "all"
1761 * or "authority".
1763 * We use "authority" to fetch our own descriptor for
1764 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1765 * the output of "authority" requests unless we are using bridges,
1766 * since otherwise they'll be the response from reachability tests,
1767 * and we don't really want to add that to our routerlist. */
1768 if (which || (conn->requested_resource &&
1769 (!strcmpstart(conn->requested_resource, "all") ||
1770 (!strcmpstart(conn->requested_resource, "authority") &&
1771 get_options()->UseBridges)))) {
1772 /* as we learn from them, we remove them from 'which' */
1773 if (was_ei) {
1774 router_load_extrainfo_from_string(body, NULL, SAVED_NOWHERE, which,
1775 descriptor_digests);
1776 } else {
1777 //router_load_routers_from_string(body, NULL, SAVED_NOWHERE, which,
1778 // descriptor_digests, conn->router_purpose);
1779 if (load_downloaded_routers(body, which, descriptor_digests,
1780 conn->router_purpose,
1781 conn->_base.address))
1782 directory_info_has_arrived(now, 0);
1785 if (which) { /* mark remaining ones as failed */
1786 log_info(LD_DIR, "Received %d/%d %s requested from %s:%d",
1787 n_asked_for-smartlist_len(which), n_asked_for,
1788 was_ei ? "extra-info documents" : "router descriptors",
1789 conn->_base.address, (int)conn->_base.port);
1790 if (smartlist_len(which)) {
1791 dir_routerdesc_download_failed(which, status_code,
1792 conn->router_purpose,
1793 was_ei, descriptor_digests);
1795 SMARTLIST_FOREACH(which, char *, cp, tor_free(cp));
1796 smartlist_free(which);
1798 if (directory_conn_is_self_reachability_test(conn))
1799 router_dirport_found_reachable();
1802 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_DIR) {
1803 switch (status_code) {
1804 case 200: {
1805 trusted_dir_server_t *ds =
1806 router_get_trusteddirserver_by_digest(conn->identity_digest);
1807 char *rejected_hdr = http_get_header(headers,
1808 "X-Descriptor-Not-New: ");
1809 int rejected = 0;
1810 if (rejected_hdr) {
1811 if (!strcmp(rejected_hdr, "Yes")) {
1812 log_info(LD_GENERAL,
1813 "Authority '%s' declined our descriptor (not new)",
1814 ds->nickname);
1815 /* XXXX use this information; be sure to upload next one
1816 * sooner. -NM */
1817 /* XXXX021 On further thought, the task above implies that we're
1818 * basing our regenerate-descriptor time on when we uploaded the
1819 * last descriptor, not on the published time of the last
1820 * descriptor. If those are different, that's a bad thing to
1821 * do. -NM */
1822 rejected = 1;
1824 tor_free(rejected_hdr);
1826 log_info(LD_GENERAL,"eof (status 200) after uploading server "
1827 "descriptor: finished.");
1828 control_event_server_status(
1829 LOG_NOTICE, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1830 conn->_base.address, conn->_base.port);
1832 ds->has_accepted_serverdesc = 1;
1833 if (directories_have_accepted_server_descriptor())
1834 control_event_server_status(LOG_NOTICE, "GOOD_SERVER_DESCRIPTOR");
1836 break;
1837 case 400:
1838 log_warn(LD_GENERAL,"http status 400 (%s) response from "
1839 "dirserver '%s:%d'. Please correct.",
1840 escaped(reason), conn->_base.address, conn->_base.port);
1841 control_event_server_status(LOG_WARN,
1842 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1843 conn->_base.address, conn->_base.port, escaped(reason));
1844 break;
1845 default:
1846 log_warn(LD_GENERAL,
1847 "http status %d (%s) reason unexpected while uploading "
1848 "descriptor to server '%s:%d').",
1849 status_code, escaped(reason), conn->_base.address,
1850 conn->_base.port);
1851 break;
1853 /* return 0 in all cases, since we don't want to mark any
1854 * dirservers down just because they don't like us. */
1857 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_VOTE) {
1858 switch (status_code) {
1859 case 200: {
1860 log_notice(LD_DIR,"Uploaded a vote to dirserver %s:%d",
1861 conn->_base.address, conn->_base.port);
1863 break;
1864 case 400:
1865 log_warn(LD_DIR,"http status 400 (%s) response after uploading "
1866 "vote to dirserver '%s:%d'. Please correct.",
1867 escaped(reason), conn->_base.address, conn->_base.port);
1868 break;
1869 default:
1870 log_warn(LD_GENERAL,
1871 "http status %d (%s) reason unexpected while uploading "
1872 "vote to server '%s:%d').",
1873 status_code, escaped(reason), conn->_base.address,
1874 conn->_base.port);
1875 break;
1877 /* return 0 in all cases, since we don't want to mark any
1878 * dirservers down just because they don't like us. */
1881 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_SIGNATURES) {
1882 switch (status_code) {
1883 case 200: {
1884 log_notice(LD_DIR,"Uploaded signature(s) to dirserver %s:%d",
1885 conn->_base.address, conn->_base.port);
1887 break;
1888 case 400:
1889 log_warn(LD_DIR,"http status 400 (%s) response after uploading "
1890 "signatures to dirserver '%s:%d'. Please correct.",
1891 escaped(reason), conn->_base.address, conn->_base.port);
1892 break;
1893 default:
1894 log_warn(LD_GENERAL,
1895 "http status %d (%s) reason unexpected while uploading "
1896 "signatures to server '%s:%d').",
1897 status_code, escaped(reason), conn->_base.address,
1898 conn->_base.port);
1899 break;
1901 /* return 0 in all cases, since we don't want to mark any
1902 * dirservers down just because they don't like us. */
1905 if (conn->_base.purpose == DIR_PURPOSE_FETCH_RENDDESC) {
1906 tor_assert(conn->rend_data);
1907 log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
1908 "(%s))",
1909 (int)body_len, status_code, escaped(reason));
1910 switch (status_code) {
1911 case 200:
1912 if (rend_cache_store(body, body_len, 0,
1913 conn->rend_data->onion_address) < -1) {
1914 log_warn(LD_REND,"Failed to parse rendezvous descriptor.");
1915 /* Any pending rendezvous attempts will notice when
1916 * connection_about_to_close_connection()
1917 * cleans this dir conn up. */
1918 /* We could retry. But since v0 descriptors are going out of
1919 * style, it isn't worth the hassle. We'll do better in v2. */
1920 } else {
1921 /* Success, or at least there's a v2 descriptor already
1922 * present. Notify pending connections about this. */
1923 conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
1924 rend_client_desc_trynow(conn->rend_data->onion_address, -1);
1926 break;
1927 case 404:
1928 /* Not there. Pending connections will be notified when
1929 * connection_about_to_close_connection() cleans this conn up. */
1930 break;
1931 case 400:
1932 log_warn(LD_REND,
1933 "http status 400 (%s). Dirserver didn't like our "
1934 "rendezvous query?", escaped(reason));
1935 break;
1936 default:
1937 log_warn(LD_REND,"http status %d (%s) response unexpected while "
1938 "fetching hidden service descriptor (server '%s:%d').",
1939 status_code, escaped(reason), conn->_base.address,
1940 conn->_base.port);
1941 break;
1945 if (conn->_base.purpose == DIR_PURPOSE_FETCH_RENDDESC_V2) {
1946 tor_assert(conn->rend_data);
1947 log_info(LD_REND,"Received rendezvous descriptor (size %d, status %d "
1948 "(%s))",
1949 (int)body_len, status_code, escaped(reason));
1950 switch (status_code) {
1951 case 200:
1952 switch (rend_cache_store_v2_desc_as_client(body, conn->rend_data)) {
1953 case -2:
1954 log_warn(LD_REND,"Fetching v2 rendezvous descriptor failed. "
1955 "Retrying at another directory.");
1956 /* We'll retry when connection_about_to_close_connection()
1957 * cleans this dir conn up. */
1958 break;
1959 case -1:
1960 /* We already have a v0 descriptor here. Ignoring this one
1961 * and _not_ performing another request. */
1962 log_info(LD_REND, "Successfully fetched v2 rendezvous "
1963 "descriptor, but we already have a v0 descriptor.");
1964 conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
1965 break;
1966 default:
1967 /* success. notify pending connections about this. */
1968 log_info(LD_REND, "Successfully fetched v2 rendezvous "
1969 "descriptor.");
1970 conn->_base.purpose = DIR_PURPOSE_HAS_FETCHED_RENDDESC;
1971 rend_client_desc_trynow(conn->rend_data->onion_address, -1);
1972 break;
1974 break;
1975 case 404:
1976 /* Not there. We'll retry when
1977 * connection_about_to_close_connection() cleans this conn up. */
1978 log_info(LD_REND,"Fetching v2 rendezvous descriptor failed: "
1979 "Retrying at another directory.");
1980 break;
1981 case 400:
1982 log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
1983 "http status 400 (%s). Dirserver didn't like our "
1984 "v2 rendezvous query? Retrying at another directory.",
1985 escaped(reason));
1986 break;
1987 default:
1988 log_warn(LD_REND, "Fetching v2 rendezvous descriptor failed: "
1989 "http status %d (%s) response unexpected while "
1990 "fetching v2 hidden service descriptor (server '%s:%d'). "
1991 "Retrying at another directory.",
1992 status_code, escaped(reason), conn->_base.address,
1993 conn->_base.port);
1994 break;
1998 if (conn->_base.purpose == DIR_PURPOSE_UPLOAD_RENDDESC ||
1999 conn->_base.purpose == DIR_PURPOSE_UPLOAD_RENDDESC_V2) {
2000 log_info(LD_REND,"Uploaded rendezvous descriptor (status %d "
2001 "(%s))",
2002 status_code, escaped(reason));
2003 switch (status_code) {
2004 case 200:
2005 log_info(LD_REND,
2006 "Uploading rendezvous descriptor: finished with status "
2007 "200 (%s)", escaped(reason));
2008 break;
2009 case 400:
2010 log_warn(LD_REND,"http status 400 (%s) response from dirserver "
2011 "'%s:%d'. Malformed rendezvous descriptor?",
2012 escaped(reason), conn->_base.address, conn->_base.port);
2013 break;
2014 case 503:
2015 log_info(LD_REND,"http status 503 (%s) response from dirserver "
2016 "'%s:%d'. Node is (currently) not acting as v2 hidden "
2017 "service directory.",
2018 escaped(reason), conn->_base.address, conn->_base.port);
2019 break;
2020 default:
2021 log_warn(LD_REND,"http status %d (%s) response unexpected (server "
2022 "'%s:%d').",
2023 status_code, escaped(reason), conn->_base.address,
2024 conn->_base.port);
2025 break;
2028 note_client_request(conn->_base.purpose, was_compressed, orig_len);
2029 tor_free(body); tor_free(headers); tor_free(reason);
2030 return 0;
2033 /** Called when a directory connection reaches EOF. */
2035 connection_dir_reached_eof(dir_connection_t *conn)
2037 int retval;
2038 if (conn->_base.state != DIR_CONN_STATE_CLIENT_READING) {
2039 log_info(LD_HTTP,"conn reached eof, not reading. [state=%d] Closing.",
2040 conn->_base.state);
2041 connection_close_immediate(TO_CONN(conn)); /* error: give up on flushing */
2042 connection_mark_for_close(TO_CONN(conn));
2043 return -1;
2046 retval = connection_dir_client_reached_eof(conn);
2047 if (retval == 0) /* success */
2048 conn->_base.state = DIR_CONN_STATE_CLIENT_FINISHED;
2049 connection_mark_for_close(TO_CONN(conn));
2050 return retval;
2053 /** If any directory object is arriving, and it's over 10MB large, we're
2054 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
2055 * ask for more than 96 router descriptors at a time.)
2057 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
2059 /** Read handler for directory connections. (That's connections <em>to</em>
2060 * directory servers and connections <em>at</em> directory servers.)
2063 connection_dir_process_inbuf(dir_connection_t *conn)
2065 tor_assert(conn);
2066 tor_assert(conn->_base.type == CONN_TYPE_DIR);
2068 /* Directory clients write, then read data until they receive EOF;
2069 * directory servers read data until they get an HTTP command, then
2070 * write their response (when it's finished flushing, they mark for
2071 * close).
2074 /* If we're on the dirserver side, look for a command. */
2075 if (conn->_base.state == DIR_CONN_STATE_SERVER_COMMAND_WAIT) {
2076 if (directory_handle_command(conn) < 0) {
2077 connection_mark_for_close(TO_CONN(conn));
2078 return -1;
2080 return 0;
2083 if (buf_datalen(conn->_base.inbuf) > MAX_DIRECTORY_OBJECT_SIZE) {
2084 log_warn(LD_HTTP, "Too much data received from directory connection: "
2085 "denial of service attempt, or you need to upgrade?");
2086 connection_mark_for_close(TO_CONN(conn));
2087 return -1;
2090 if (!conn->_base.inbuf_reached_eof)
2091 log_debug(LD_HTTP,"Got data, not eof. Leaving on inbuf.");
2092 return 0;
2095 /** Create an http response for the client <b>conn</b> out of
2096 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
2098 static void
2099 write_http_status_line(dir_connection_t *conn, int status,
2100 const char *reason_phrase)
2102 char buf[256];
2103 if (tor_snprintf(buf, sizeof(buf), "HTTP/1.0 %d %s\r\n\r\n",
2104 status, reason_phrase ? reason_phrase : "OK") < 0) {
2105 log_warn(LD_BUG,"status line too long.");
2106 return;
2108 connection_write_to_buf(buf, strlen(buf), TO_CONN(conn));
2111 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
2112 * with <b>type</b> as the Content-Type.
2114 * If <b>length</b> is nonnegative, it is the Content-Length.
2115 * If <b>encoding</b> is provided, it is the Content-Encoding.
2116 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
2117 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
2118 static void
2119 write_http_response_header_impl(dir_connection_t *conn, ssize_t length,
2120 const char *type, const char *encoding,
2121 const char *extra_headers,
2122 long cache_lifetime)
2124 char date[RFC1123_TIME_LEN+1];
2125 char tmp[1024];
2126 char *cp;
2127 time_t now = time(NULL);
2129 tor_assert(conn);
2131 format_rfc1123_time(date, now);
2132 cp = tmp;
2133 tor_snprintf(cp, sizeof(tmp),
2134 "HTTP/1.0 200 OK\r\nDate: %s\r\n",
2135 date);
2136 cp += strlen(tmp);
2137 if (type) {
2138 tor_snprintf(cp, sizeof(tmp)-(cp-tmp), "Content-Type: %s\r\n", type);
2139 cp += strlen(cp);
2141 if (!is_local_addr(&conn->_base.addr)) {
2142 /* Don't report the source address for a nearby/private connection.
2143 * Otherwise we tend to mis-report in cases where incoming ports are
2144 * being forwarded to a Tor server running behind the firewall. */
2145 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2146 X_ADDRESS_HEADER "%s\r\n", conn->_base.address);
2147 cp += strlen(cp);
2149 if (encoding) {
2150 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2151 "Content-Encoding: %s\r\n", encoding);
2152 cp += strlen(cp);
2154 if (length >= 0) {
2155 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2156 "Content-Length: %ld\r\n", (long)length);
2157 cp += strlen(cp);
2159 if (cache_lifetime > 0) {
2160 char expbuf[RFC1123_TIME_LEN+1];
2161 format_rfc1123_time(expbuf, now + cache_lifetime);
2162 /* We could say 'Cache-control: max-age=%d' here if we start doing
2163 * http/1.1 */
2164 tor_snprintf(cp, sizeof(tmp)-(cp-tmp),
2165 "Expires: %s\r\n", expbuf);
2166 cp += strlen(cp);
2167 } else if (cache_lifetime == 0) {
2168 /* We could say 'Cache-control: no-cache' here if we start doing
2169 * http/1.1 */
2170 strlcpy(cp, "Pragma: no-cache\r\n", sizeof(tmp)-(cp-tmp));
2171 cp += strlen(cp);
2173 if (extra_headers) {
2174 strlcpy(cp, extra_headers, sizeof(tmp)-(cp-tmp));
2175 cp += strlen(cp);
2177 if (sizeof(tmp)-(cp-tmp) > 3)
2178 memcpy(cp, "\r\n", 3);
2179 else
2180 tor_assert(0);
2181 connection_write_to_buf(tmp, strlen(tmp), TO_CONN(conn));
2184 /** As write_http_response_header_impl, but sets encoding and content-typed
2185 * based on whether the response will be <b>compressed</b> or not. */
2186 static void
2187 write_http_response_header(dir_connection_t *conn, ssize_t length,
2188 int compressed, long cache_lifetime)
2190 write_http_response_header_impl(conn, length,
2191 compressed?"application/octet-stream":"text/plain",
2192 compressed?"deflate":"identity",
2193 NULL,
2194 cache_lifetime);
2197 #ifdef INSTRUMENT_DOWNLOADS
2198 typedef struct request_t {
2199 uint64_t bytes; /**< How many bytes have we transferred? */
2200 uint64_t count; /**< How many requests have we made? */
2201 } request_t;
2203 /** Map used to keep track of how much data we've up/downloaded in what kind
2204 * of request. Maps from request type to pointer to request_t. */
2205 static strmap_t *request_map = NULL;
2207 /** Record that a client request of <b>purpose</b> was made, and that
2208 * <b>bytes</b> bytes of possibly <b>compressed</b> data were sent/received.
2209 * Used to keep track of how much we've up/downloaded in what kind of
2210 * request. */
2211 static void
2212 note_client_request(int purpose, int compressed, size_t bytes)
2214 char *key;
2215 const char *kind = NULL;
2216 switch (purpose) {
2217 case DIR_PURPOSE_FETCH_V2_NETWORKSTATUS: kind = "dl/status"; break;
2218 case DIR_PURPOSE_FETCH_CONSENSUS: kind = "dl/consensus"; break;
2219 case DIR_PURPOSE_FETCH_CERTIFICATE: kind = "dl/cert"; break;
2220 case DIR_PURPOSE_FETCH_STATUS_VOTE: kind = "dl/vote"; break;
2221 case DIR_PURPOSE_FETCH_DETACHED_SIGNATURES: kind = "dl/detached_sig";
2222 break;
2223 case DIR_PURPOSE_FETCH_SERVERDESC: kind = "dl/server"; break;
2224 case DIR_PURPOSE_FETCH_EXTRAINFO: kind = "dl/extra"; break;
2225 case DIR_PURPOSE_UPLOAD_DIR: kind = "dl/ul-dir"; break;
2226 case DIR_PURPOSE_UPLOAD_VOTE: kind = "dl/ul-vote"; break;
2227 case DIR_PURPOSE_UPLOAD_SIGNATURES: kind = "dl/ul-sig"; break;
2228 case DIR_PURPOSE_FETCH_RENDDESC: kind = "dl/rend"; break;
2229 case DIR_PURPOSE_FETCH_RENDDESC_V2: kind = "dl/rend2"; break;
2230 case DIR_PURPOSE_UPLOAD_RENDDESC: kind = "dl/ul-rend"; break;
2231 case DIR_PURPOSE_UPLOAD_RENDDESC_V2: kind = "dl/ul-rend2"; break;
2233 if (kind) {
2234 key = tor_malloc(256);
2235 tor_snprintf(key, 256, "%s%s", kind, compressed?".z":"");
2236 } else {
2237 key = tor_malloc(256);
2238 tor_snprintf(key, 256, "unknown purpose (%d)%s",
2239 purpose, compressed?".z":"");
2241 note_request(key, bytes);
2242 tor_free(key);
2245 /** Helper: initialize the request map to instrument downloads. */
2246 static void
2247 ensure_request_map_initialized(void)
2249 if (!request_map)
2250 request_map = strmap_new();
2253 /** Called when we just transmitted or received <b>bytes</b> worth of data
2254 * because of a request of type <b>key</b> (an arbitrary identifier): adds
2255 * <b>bytes</b> to the total associated with key. */
2256 void
2257 note_request(const char *key, size_t bytes)
2259 request_t *r;
2260 ensure_request_map_initialized();
2262 r = strmap_get(request_map, key);
2263 if (!r) {
2264 r = tor_malloc_zero(sizeof(request_t));
2265 strmap_set(request_map, key, r);
2267 r->bytes += bytes;
2268 r->count++;
2271 /** Return a newly allocated string holding a summary of bytes used per
2272 * request type. */
2273 char *
2274 directory_dump_request_log(void)
2276 smartlist_t *lines;
2277 char tmp[256];
2278 char *result;
2279 strmap_iter_t *iter;
2281 ensure_request_map_initialized();
2283 lines = smartlist_create();
2285 for (iter = strmap_iter_init(request_map);
2286 !strmap_iter_done(iter);
2287 iter = strmap_iter_next(request_map, iter)) {
2288 const char *key;
2289 void *val;
2290 request_t *r;
2291 strmap_iter_get(iter, &key, &val);
2292 r = val;
2293 tor_snprintf(tmp, sizeof(tmp), "%s "U64_FORMAT" "U64_FORMAT"\n",
2294 key, U64_PRINTF_ARG(r->bytes), U64_PRINTF_ARG(r->count));
2295 smartlist_add(lines, tor_strdup(tmp));
2297 smartlist_sort_strings(lines);
2298 result = smartlist_join_strings(lines, "", 0, NULL);
2299 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
2300 smartlist_free(lines);
2301 return result;
2303 #else
2304 static void
2305 note_client_request(int purpose, int compressed, size_t bytes)
2307 (void)purpose;
2308 (void)compressed;
2309 (void)bytes;
2312 void
2313 note_request(const char *key, size_t bytes)
2315 (void)key;
2316 (void)bytes;
2319 char *
2320 directory_dump_request_log(void)
2322 return tor_strdup("Not supported.");
2324 #endif
2326 /** Decide whether a client would accept the consensus we have
2328 * Clients can say they only want a consensus if it's signed by more
2329 * than half the authorities in a list. They pass this list in
2330 * the url as "...consensus/<b>fpr</b>+<b>fpr</b>+<b>fpr</b>".
2332 * <b>fpr</b> may be an abbreviated fingerprint, i.e. only a left substring
2333 * of the full authority identity digest. (Only strings of even length,
2334 * i.e. encodings of full bytes, are handled correctly. In the case
2335 * of an odd number of hex digits the last one is silently ignored.)
2337 * Returns 1 if more than half of the requested authorities signed the
2338 * consensus, 0 otherwise.
2341 client_likes_consensus(networkstatus_t *v, const char *want_url)
2343 smartlist_t *want_authorities = smartlist_create();
2344 int need_at_least;
2345 int have = 0;
2347 dir_split_resource_into_fingerprints(want_url, want_authorities, NULL, 0, 0);
2348 need_at_least = smartlist_len(want_authorities)/2+1;
2349 SMARTLIST_FOREACH(want_authorities, const char *, d, {
2350 char want_digest[DIGEST_LEN];
2351 size_t want_len = strlen(d)/2;
2352 if (want_len > DIGEST_LEN)
2353 want_len = DIGEST_LEN;
2355 if (base16_decode(want_digest, DIGEST_LEN, d, want_len*2) < 0) {
2356 log_warn(LD_DIR,"Failed to decode requested authority digest %s.", d);
2357 continue;
2360 SMARTLIST_FOREACH(v->voters, networkstatus_voter_info_t *, vi, {
2361 if (vi->signature &&
2362 fast_memeq(vi->identity_digest, want_digest, want_len)) {
2363 have++;
2364 break;
2368 /* early exit, if we already have enough */
2369 if (have >= need_at_least)
2370 break;
2373 SMARTLIST_FOREACH(want_authorities, char *, d, tor_free(d));
2374 smartlist_free(want_authorities);
2375 return (have >= need_at_least);
2378 /** Helper function: called when a dirserver gets a complete HTTP GET
2379 * request. Look for a request for a directory or for a rendezvous
2380 * service descriptor. On finding one, write a response into
2381 * conn-\>outbuf. If the request is unrecognized, send a 400.
2382 * Always return 0. */
2383 static int
2384 directory_handle_command_get(dir_connection_t *conn, const char *headers,
2385 const char *body, size_t body_len)
2387 size_t dlen;
2388 char *url, *url_mem, *header;
2389 or_options_t *options = get_options();
2390 time_t if_modified_since = 0;
2391 int compressed;
2392 size_t url_len;
2394 /* We ignore the body of a GET request. */
2395 (void)body;
2396 (void)body_len;
2398 log_debug(LD_DIRSERV,"Received GET command.");
2400 conn->_base.state = DIR_CONN_STATE_SERVER_WRITING;
2402 if (parse_http_url(headers, &url) < 0) {
2403 write_http_status_line(conn, 400, "Bad request");
2404 return 0;
2406 if ((header = http_get_header(headers, "If-Modified-Since: "))) {
2407 struct tm tm;
2408 if (parse_http_time(header, &tm) == 0) {
2409 if_modified_since = tor_timegm(&tm);
2411 /* The correct behavior on a malformed If-Modified-Since header is to
2412 * act as if no If-Modified-Since header had been given. */
2413 tor_free(header);
2415 log_debug(LD_DIRSERV,"rewritten url as '%s'.", url);
2417 url_mem = url;
2418 url_len = strlen(url);
2419 compressed = url_len > 2 && !strcmp(url+url_len-2, ".z");
2420 if (compressed) {
2421 url[url_len-2] = '\0';
2422 url_len -= 2;
2425 if (!strcmp(url,"/tor/")) {
2426 const char *frontpage = get_dirportfrontpage();
2428 if (frontpage) {
2429 dlen = strlen(frontpage);
2430 /* Let's return a disclaimer page (users shouldn't use V1 anymore,
2431 and caches don't fetch '/', so this is safe). */
2433 /* [We don't check for write_bucket_low here, since we want to serve
2434 * this page no matter what.] */
2435 note_request(url, dlen);
2436 write_http_response_header_impl(conn, dlen, "text/html", "identity",
2437 NULL, DIRPORTFRONTPAGE_CACHE_LIFETIME);
2438 connection_write_to_buf(frontpage, dlen, TO_CONN(conn));
2439 goto done;
2441 /* if no disclaimer file, fall through and continue */
2444 if (!strcmp(url,"/tor/") || !strcmp(url,"/tor/dir")) { /* v1 dir fetch */
2445 cached_dir_t *d = dirserv_get_directory();
2447 if (!d) {
2448 log_info(LD_DIRSERV,"Client asked for the mirrored directory, but we "
2449 "don't have a good one yet. Sending 503 Dir not available.");
2450 write_http_status_line(conn, 503, "Directory unavailable");
2451 goto done;
2453 if (d->published < if_modified_since) {
2454 write_http_status_line(conn, 304, "Not modified");
2455 goto done;
2458 dlen = compressed ? d->dir_z_len : d->dir_len;
2460 if (global_write_bucket_low(TO_CONN(conn), dlen, 1)) {
2461 log_debug(LD_DIRSERV,
2462 "Client asked for the mirrored directory, but we've been "
2463 "writing too many bytes lately. Sending 503 Dir busy.");
2464 write_http_status_line(conn, 503, "Directory busy, try again later");
2465 goto done;
2468 note_request(url, dlen);
2470 log_debug(LD_DIRSERV,"Dumping %sdirectory to client.",
2471 compressed?"compressed ":"");
2472 write_http_response_header(conn, dlen, compressed,
2473 FULL_DIR_CACHE_LIFETIME);
2474 conn->cached_dir = d;
2475 conn->cached_dir_offset = 0;
2476 if (!compressed)
2477 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
2478 ++d->refcnt;
2480 /* Prime the connection with some data. */
2481 conn->dir_spool_src = DIR_SPOOL_CACHED_DIR;
2482 connection_dirserv_flushed_some(conn);
2483 goto done;
2486 if (!strcmp(url,"/tor/running-routers")) { /* running-routers fetch */
2487 cached_dir_t *d = dirserv_get_runningrouters();
2488 if (!d) {
2489 write_http_status_line(conn, 503, "Directory unavailable");
2490 goto done;
2492 if (d->published < if_modified_since) {
2493 write_http_status_line(conn, 304, "Not modified");
2494 goto done;
2496 dlen = compressed ? d->dir_z_len : d->dir_len;
2498 if (global_write_bucket_low(TO_CONN(conn), dlen, 1)) {
2499 log_info(LD_DIRSERV,
2500 "Client asked for running-routers, but we've been "
2501 "writing too many bytes lately. Sending 503 Dir busy.");
2502 write_http_status_line(conn, 503, "Directory busy, try again later");
2503 goto done;
2505 note_request(url, dlen);
2506 write_http_response_header(conn, dlen, compressed,
2507 RUNNINGROUTERS_CACHE_LIFETIME);
2508 connection_write_to_buf(compressed ? d->dir_z : d->dir, dlen,
2509 TO_CONN(conn));
2510 goto done;
2513 if (!strcmpstart(url,"/tor/status/")
2514 || !strcmpstart(url, "/tor/status-vote/current/consensus")) {
2515 /* v2 or v3 network status fetch. */
2516 smartlist_t *dir_fps = smartlist_create();
2517 int is_v3 = !strcmpstart(url, "/tor/status-vote");
2518 const char *request_type = NULL;
2519 const char *key = url + strlen("/tor/status/");
2520 long lifetime = NETWORKSTATUS_CACHE_LIFETIME;
2521 if (!is_v3) {
2522 dirserv_get_networkstatus_v2_fingerprints(dir_fps, key);
2523 if (!strcmpstart(key, "fp/"))
2524 request_type = compressed?"/tor/status/fp.z":"/tor/status/fp";
2525 else if (!strcmpstart(key, "authority"))
2526 request_type = compressed?"/tor/status/authority.z":
2527 "/tor/status/authority";
2528 else if (!strcmpstart(key, "all"))
2529 request_type = compressed?"/tor/status/all.z":"/tor/status/all";
2530 else
2531 request_type = "/tor/status/?";
2532 } else {
2533 networkstatus_t *v = networkstatus_get_latest_consensus();
2534 time_t now = time(NULL);
2535 #define CONSENSUS_URL_PREFIX "/tor/status-vote/current/consensus/"
2536 if (v &&
2537 !strcmpstart(url, CONSENSUS_URL_PREFIX) &&
2538 !client_likes_consensus(v, url + strlen(CONSENSUS_URL_PREFIX))) {
2539 write_http_status_line(conn, 404, "Consensus not signed by sufficient "
2540 "number of requested authorities");
2541 smartlist_free(dir_fps);
2542 goto done;
2545 smartlist_add(dir_fps, tor_memdup("\0\0\0\0\0\0\0\0\0\0"
2546 "\0\0\0\0\0\0\0\0\0\0", 20));
2547 request_type = compressed?"v3.z":"v3";
2548 lifetime = (v && v->fresh_until > now) ? v->fresh_until - now : 0;
2551 if (!smartlist_len(dir_fps)) { /* we failed to create/cache cp */
2552 write_http_status_line(conn, 503, "Network status object unavailable");
2553 smartlist_free(dir_fps);
2554 goto done;
2557 if (!dirserv_remove_old_statuses(dir_fps, if_modified_since)) {
2558 write_http_status_line(conn, 404, "Not found");
2559 SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
2560 smartlist_free(dir_fps);
2561 goto done;
2562 } else if (!smartlist_len(dir_fps)) {
2563 write_http_status_line(conn, 304, "Not modified");
2564 SMARTLIST_FOREACH(dir_fps, char *, cp, tor_free(cp));
2565 smartlist_free(dir_fps);
2566 goto done;
2569 dlen = dirserv_estimate_data_size(dir_fps, 0, compressed);
2570 if (global_write_bucket_low(TO_CONN(conn), dlen, 2)) {
2571 log_debug(LD_DIRSERV,
2572 "Client asked for network status lists, but we've been "
2573 "writing too many bytes lately. Sending 503 Dir busy.");
2574 write_http_status_line(conn, 503, "Directory busy, try again later");
2575 SMARTLIST_FOREACH(dir_fps, char *, fp, tor_free(fp));
2576 smartlist_free(dir_fps);
2577 goto done;
2580 #ifdef ENABLE_GEOIP_STATS
2582 geoip_client_action_t act =
2583 is_v3 ? GEOIP_CLIENT_NETWORKSTATUS : GEOIP_CLIENT_NETWORKSTATUS_V2;
2584 struct in_addr in;
2585 if (tor_inet_aton((TO_CONN(conn))->address, &in))
2586 geoip_note_client_seen(act, ntohl(in.s_addr), time(NULL));
2588 #endif
2590 // note_request(request_type,dlen);
2591 (void) request_type;
2592 write_http_response_header(conn, -1, compressed,
2593 smartlist_len(dir_fps) == 1 ? lifetime : 0);
2594 conn->fingerprint_stack = dir_fps;
2595 if (! compressed)
2596 conn->zlib_state = tor_zlib_new(0, ZLIB_METHOD);
2598 /* Prime the connection with some data. */
2599 conn->dir_spool_src = DIR_SPOOL_NETWORKSTATUS;
2600 connection_dirserv_flushed_some(conn);
2601 goto done;
2604 if (!strcmpstart(url,"/tor/status-vote/current/") ||
2605 !strcmpstart(url,"/tor/status-vote/next/")) {
2606 /* XXXX If-modified-since is only implemented for the current
2607 * consensus: that's probably fine, since it's the only vote document
2608 * people fetch much. */
2609 int current;
2610 ssize_t body_len = 0;
2611 ssize_t estimated_len = 0;
2612 smartlist_t *items = smartlist_create();
2613 smartlist_t *dir_items = smartlist_create();
2614 int lifetime = 60; /* XXXX022 should actually use vote intervals. */
2615 url += strlen("/tor/status-vote/");
2616 current = !strcmpstart(url, "current/");
2617 url = strchr(url, '/');
2618 tor_assert(url);
2619 ++url;
2620 if (!strcmp(url, "consensus")) {
2621 const char *item;
2622 tor_assert(!current); /* we handle current consensus specially above,
2623 * since it wants to be spooled. */
2624 if ((item = dirvote_get_pending_consensus()))
2625 smartlist_add(items, (char*)item);
2626 } else if (!current && !strcmp(url, "consensus-signatures")) {
2627 /* XXXX the spec says that we should implement
2628 * current/consensus-signatures too. It doesn't seem to be needed,
2629 * though. */
2630 const char *item;
2631 if ((item=dirvote_get_pending_detached_signatures()))
2632 smartlist_add(items, (char*)item);
2633 } else if (!strcmp(url, "authority")) {
2634 const cached_dir_t *d;
2635 int flags = DGV_BY_ID |
2636 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
2637 if ((d=dirvote_get_vote(NULL, flags)))
2638 smartlist_add(dir_items, (cached_dir_t*)d);
2639 } else {
2640 const cached_dir_t *d;
2641 smartlist_t *fps = smartlist_create();
2642 int flags;
2643 if (!strcmpstart(url, "d/")) {
2644 url += 2;
2645 flags = DGV_INCLUDE_PENDING | DGV_INCLUDE_PREVIOUS;
2646 } else {
2647 flags = DGV_BY_ID |
2648 (current ? DGV_INCLUDE_PREVIOUS : DGV_INCLUDE_PENDING);
2650 dir_split_resource_into_fingerprints(url, fps, NULL, 1, 1);
2651 SMARTLIST_FOREACH(fps, char *, fp, {
2652 if ((d = dirvote_get_vote(fp, flags)))
2653 smartlist_add(dir_items, (cached_dir_t*)d);
2654 tor_free(fp);
2656 smartlist_free(fps);
2658 if (!smartlist_len(dir_items) && !smartlist_len(items)) {
2659 write_http_status_line(conn, 404, "Not found");
2660 goto vote_done;
2662 SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
2663 body_len += compressed ? d->dir_z_len : d->dir_len);
2664 estimated_len += body_len;
2665 SMARTLIST_FOREACH(items, const char *, item, {
2666 size_t ln = strlen(item);
2667 if (compressed) {
2668 estimated_len += ln/2;
2669 } else {
2670 body_len += ln; estimated_len += ln;
2674 if (global_write_bucket_low(TO_CONN(conn), estimated_len, 2)) {
2675 write_http_status_line(conn, 503, "Directory busy, try again later.");
2676 goto vote_done;
2678 write_http_response_header(conn, body_len ? body_len : -1, compressed,
2679 lifetime);
2681 if (smartlist_len(items)) {
2682 if (compressed) {
2683 conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
2684 SMARTLIST_FOREACH(items, const char *, c,
2685 connection_write_to_buf_zlib(c, strlen(c), conn, 0));
2686 connection_write_to_buf_zlib("", 0, conn, 1);
2687 } else {
2688 SMARTLIST_FOREACH(items, const char *, c,
2689 connection_write_to_buf(c, strlen(c), TO_CONN(conn)));
2691 } else {
2692 SMARTLIST_FOREACH(dir_items, cached_dir_t *, d,
2693 connection_write_to_buf(compressed ? d->dir_z : d->dir,
2694 compressed ? d->dir_z_len : d->dir_len,
2695 TO_CONN(conn)));
2697 vote_done:
2698 smartlist_free(items);
2699 smartlist_free(dir_items);
2700 goto done;
2703 if (!strcmpstart(url,"/tor/server/") ||
2704 (!options->BridgeAuthoritativeDir &&
2705 !options->BridgeRelay && !strcmpstart(url,"/tor/extra/"))) {
2706 int res;
2707 const char *msg;
2708 const char *request_type = NULL;
2709 int cache_lifetime = 0;
2710 int is_extra = !strcmpstart(url,"/tor/extra/");
2711 url += is_extra ? strlen("/tor/extra/") : strlen("/tor/server/");
2712 conn->fingerprint_stack = smartlist_create();
2713 res = dirserv_get_routerdesc_fingerprints(conn->fingerprint_stack, url,
2714 &msg,
2715 !connection_dir_is_encrypted(conn),
2716 is_extra);
2718 if (!strcmpstart(url, "fp/")) {
2719 request_type = compressed?"/tor/server/fp.z":"/tor/server/fp";
2720 if (smartlist_len(conn->fingerprint_stack) == 1)
2721 cache_lifetime = ROUTERDESC_CACHE_LIFETIME;
2722 } else if (!strcmpstart(url, "authority")) {
2723 request_type = compressed?"/tor/server/authority.z":
2724 "/tor/server/authority";
2725 cache_lifetime = ROUTERDESC_CACHE_LIFETIME;
2726 } else if (!strcmpstart(url, "all")) {
2727 request_type = compressed?"/tor/server/all.z":"/tor/server/all";
2728 cache_lifetime = FULL_DIR_CACHE_LIFETIME;
2729 } else if (!strcmpstart(url, "d/")) {
2730 request_type = compressed?"/tor/server/d.z":"/tor/server/d";
2731 if (smartlist_len(conn->fingerprint_stack) == 1)
2732 cache_lifetime = ROUTERDESC_BY_DIGEST_CACHE_LIFETIME;
2733 } else {
2734 request_type = "/tor/server/?";
2736 (void) request_type; /* usable for note_request. */
2737 if (!strcmpstart(url, "d/"))
2738 conn->dir_spool_src =
2739 is_extra ? DIR_SPOOL_EXTRA_BY_DIGEST : DIR_SPOOL_SERVER_BY_DIGEST;
2740 else
2741 conn->dir_spool_src =
2742 is_extra ? DIR_SPOOL_EXTRA_BY_FP : DIR_SPOOL_SERVER_BY_FP;
2744 if (!dirserv_have_any_serverdesc(conn->fingerprint_stack,
2745 conn->dir_spool_src)) {
2746 res = -1;
2747 msg = "Not found";
2750 if (res < 0)
2751 write_http_status_line(conn, 404, msg);
2752 else {
2753 dlen = dirserv_estimate_data_size(conn->fingerprint_stack,
2754 1, compressed);
2755 if (global_write_bucket_low(TO_CONN(conn), dlen, 2)) {
2756 log_info(LD_DIRSERV,
2757 "Client asked for server descriptors, but we've been "
2758 "writing too many bytes lately. Sending 503 Dir busy.");
2759 write_http_status_line(conn, 503, "Directory busy, try again later");
2760 conn->dir_spool_src = DIR_SPOOL_NONE;
2761 goto done;
2763 write_http_response_header(conn, -1, compressed, cache_lifetime);
2764 if (compressed)
2765 conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
2766 /* Prime the connection with some data. */
2767 connection_dirserv_flushed_some(conn);
2769 goto done;
2772 if (!strcmpstart(url,"/tor/keys/")) {
2773 smartlist_t *certs = smartlist_create();
2774 ssize_t len = -1;
2775 if (!strcmp(url, "/tor/keys/all")) {
2776 authority_cert_get_all(certs);
2777 } else if (!strcmp(url, "/tor/keys/authority")) {
2778 authority_cert_t *cert = get_my_v3_authority_cert();
2779 if (cert)
2780 smartlist_add(certs, cert);
2781 } else if (!strcmpstart(url, "/tor/keys/fp/")) {
2782 smartlist_t *fps = smartlist_create();
2783 dir_split_resource_into_fingerprints(url+strlen("/tor/keys/fp/"),
2784 fps, NULL, 1, 1);
2785 SMARTLIST_FOREACH(fps, char *, d, {
2786 authority_cert_t *c = authority_cert_get_newest_by_id(d);
2787 if (c) smartlist_add(certs, c);
2788 tor_free(d);
2790 smartlist_free(fps);
2791 } else if (!strcmpstart(url, "/tor/keys/sk/")) {
2792 smartlist_t *fps = smartlist_create();
2793 dir_split_resource_into_fingerprints(url+strlen("/tor/keys/sk/"),
2794 fps, NULL, 1, 1);
2795 SMARTLIST_FOREACH(fps, char *, d, {
2796 authority_cert_t *c = authority_cert_get_by_sk_digest(d);
2797 if (c) smartlist_add(certs, c);
2798 tor_free(d);
2800 smartlist_free(fps);
2801 } else if (!strcmpstart(url, "/tor/keys/fp-sk/")) {
2802 smartlist_t *fp_sks = smartlist_create();
2803 dir_split_resource_into_fingerprint_pairs(url+strlen("/tor/keys/fp-sk/"),
2804 fp_sks);
2805 SMARTLIST_FOREACH(fp_sks, fp_pair_t *, pair, {
2806 authority_cert_t *c = authority_cert_get_by_digests(pair->first,
2807 pair->second);
2808 if (c) smartlist_add(certs, c);
2809 tor_free(pair);
2811 smartlist_free(fp_sks);
2812 } else {
2813 write_http_status_line(conn, 400, "Bad request");
2814 goto keys_done;
2816 if (!smartlist_len(certs)) {
2817 write_http_status_line(conn, 404, "Not found");
2818 goto keys_done;
2820 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2821 if (c->cache_info.published_on < if_modified_since)
2822 SMARTLIST_DEL_CURRENT(certs, c));
2823 if (!smartlist_len(certs)) {
2824 write_http_status_line(conn, 304, "Not modified");
2825 goto keys_done;
2827 len = 0;
2828 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2829 len += c->cache_info.signed_descriptor_len);
2831 if (global_write_bucket_low(TO_CONN(conn), compressed?len/2:len, 2)) {
2832 write_http_status_line(conn, 503, "Directory busy, try again later.");
2833 goto keys_done;
2836 write_http_response_header(conn, compressed?-1:len, compressed, 60*60);
2837 if (compressed) {
2838 conn->zlib_state = tor_zlib_new(1, ZLIB_METHOD);
2839 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2840 connection_write_to_buf_zlib(c->cache_info.signed_descriptor_body,
2841 c->cache_info.signed_descriptor_len,
2842 conn, 0));
2843 connection_write_to_buf_zlib("", 0, conn, 1);
2844 } else {
2845 SMARTLIST_FOREACH(certs, authority_cert_t *, c,
2846 connection_write_to_buf(c->cache_info.signed_descriptor_body,
2847 c->cache_info.signed_descriptor_len,
2848 TO_CONN(conn)));
2850 keys_done:
2851 smartlist_free(certs);
2852 goto done;
2855 if (options->HidServDirectoryV2 &&
2856 !strcmpstart(url,"/tor/rendezvous2/")) {
2857 /* Handle v2 rendezvous descriptor fetch request. */
2858 const char *descp;
2859 const char *query = url + strlen("/tor/rendezvous2/");
2860 if (strlen(query) == REND_DESC_ID_V2_LEN_BASE32) {
2861 log_info(LD_REND, "Got a v2 rendezvous descriptor request for ID '%s'",
2862 safe_str(query));
2863 switch (rend_cache_lookup_v2_desc_as_dir(query, &descp)) {
2864 case 1: /* valid */
2865 write_http_response_header(conn, strlen(descp), 0, 0);
2866 connection_write_to_buf(descp, strlen(descp), TO_CONN(conn));
2867 break;
2868 case 0: /* well-formed but not present */
2869 write_http_status_line(conn, 404, "Not found");
2870 break;
2871 case -1: /* not well-formed */
2872 write_http_status_line(conn, 400, "Bad request");
2873 break;
2875 } else { /* not well-formed */
2876 write_http_status_line(conn, 400, "Bad request");
2878 goto done;
2881 if (options->HSAuthoritativeDir && !strcmpstart(url,"/tor/rendezvous/")) {
2882 /* rendezvous descriptor fetch */
2883 const char *descp;
2884 size_t desc_len;
2885 const char *query = url+strlen("/tor/rendezvous/");
2887 log_info(LD_REND, "Handling rendezvous descriptor get");
2888 switch (rend_cache_lookup_desc(query, 0, &descp, &desc_len)) {
2889 case 1: /* valid */
2890 write_http_response_header_impl(conn, desc_len,
2891 "application/octet-stream",
2892 NULL, NULL, 0);
2893 note_request("/tor/rendezvous?/", desc_len);
2894 /* need to send descp separately, because it may include NULs */
2895 connection_write_to_buf(descp, desc_len, TO_CONN(conn));
2896 /* report successful fetch to statistic */
2897 if (options->HSAuthorityRecordStats) {
2898 hs_usage_note_fetch_total(query, time(NULL));
2899 hs_usage_note_fetch_successful(query, time(NULL));
2901 break;
2902 case 0: /* well-formed but not present */
2903 write_http_status_line(conn, 404, "Not found");
2904 /* report (unsuccessful) fetch to statistic */
2905 if (options->HSAuthorityRecordStats) {
2906 hs_usage_note_fetch_total(query, time(NULL));
2908 break;
2909 case -1: /* not well-formed */
2910 write_http_status_line(conn, 400, "Bad request");
2911 break;
2913 goto done;
2916 if (options->BridgeAuthoritativeDir &&
2917 options->BridgePassword &&
2918 connection_dir_is_encrypted(conn) &&
2919 !strcmp(url,"/tor/networkstatus-bridges")) {
2920 char *status;
2921 char *secret = alloc_http_authenticator(options->BridgePassword);
2923 header = http_get_header(headers, "Authorization: Basic ");
2925 /* now make sure the password is there and right */
2926 if (!header || strcmp(header, secret)) {
2927 write_http_status_line(conn, 404, "Not found");
2928 tor_free(secret);
2929 tor_free(header);
2930 goto done;
2932 tor_free(secret);
2933 tor_free(header);
2935 /* all happy now. send an answer. */
2936 status = networkstatus_getinfo_by_purpose("bridge", time(NULL));
2937 dlen = strlen(status);
2938 write_http_response_header(conn, dlen, 0, 0);
2939 connection_write_to_buf(status, dlen, TO_CONN(conn));
2940 tor_free(status);
2941 goto done;
2944 if (!strcmpstart(url,"/tor/bytes.txt")) {
2945 char *bytes = directory_dump_request_log();
2946 size_t len = strlen(bytes);
2947 write_http_response_header(conn, len, 0, 0);
2948 connection_write_to_buf(bytes, len, TO_CONN(conn));
2949 tor_free(bytes);
2950 goto done;
2953 if (!strcmp(url,"/tor/robots.txt")) { /* /robots.txt will have been
2954 rewritten to /tor/robots.txt */
2955 char robots[] = "User-agent: *\r\nDisallow: /\r\n";
2956 size_t len = strlen(robots);
2957 write_http_response_header(conn, len, 0, ROBOTS_CACHE_LIFETIME);
2958 connection_write_to_buf(robots, len, TO_CONN(conn));
2959 goto done;
2962 if (!strcmp(url,"/tor/dbg-stability.txt")) {
2963 const char *stability;
2964 size_t len;
2965 if (options->BridgeAuthoritativeDir ||
2966 ! authdir_mode_tests_reachability(options) ||
2967 ! (stability = rep_hist_get_router_stability_doc(time(NULL)))) {
2968 write_http_status_line(conn, 404, "Not found.");
2969 goto done;
2972 len = strlen(stability);
2973 write_http_response_header(conn, len, 0, 0);
2974 connection_write_to_buf(stability, len, TO_CONN(conn));
2975 goto done;
2978 #if defined(EXPORTMALLINFO) && defined(HAVE_MALLOC_H) && defined(HAVE_MALLINFO)
2979 #define ADD_MALLINFO_LINE(x) do { \
2980 tor_snprintf(tmp, sizeof(tmp), "%s %d\n", #x, mi.x); \
2981 smartlist_add(lines, tor_strdup(tmp)); \
2982 }while(0);
2984 if (!strcmp(url,"/tor/mallinfo.txt") &&
2985 (tor_addr_eq_ipv4h(&conn->_base.addr, 0x7f000001ul))) {
2986 char *result;
2987 size_t len;
2988 struct mallinfo mi;
2989 smartlist_t *lines;
2990 char tmp[256];
2992 memset(&mi, 0, sizeof(mi));
2993 mi = mallinfo();
2994 lines = smartlist_create();
2996 ADD_MALLINFO_LINE(arena)
2997 ADD_MALLINFO_LINE(ordblks)
2998 ADD_MALLINFO_LINE(smblks)
2999 ADD_MALLINFO_LINE(hblks)
3000 ADD_MALLINFO_LINE(hblkhd)
3001 ADD_MALLINFO_LINE(usmblks)
3002 ADD_MALLINFO_LINE(fsmblks)
3003 ADD_MALLINFO_LINE(uordblks)
3004 ADD_MALLINFO_LINE(fordblks)
3005 ADD_MALLINFO_LINE(keepcost)
3007 result = smartlist_join_strings(lines, "", 0, NULL);
3008 SMARTLIST_FOREACH(lines, char *, cp, tor_free(cp));
3009 smartlist_free(lines);
3011 len = strlen(result);
3012 write_http_response_header(conn, len, 0, 0);
3013 connection_write_to_buf(result, len, TO_CONN(conn));
3014 tor_free(result);
3015 goto done;
3017 #endif
3019 /* we didn't recognize the url */
3020 write_http_status_line(conn, 404, "Not found");
3022 done:
3023 tor_free(url_mem);
3024 return 0;
3027 /** Helper function: called when a dirserver gets a complete HTTP POST
3028 * request. Look for an uploaded server descriptor or rendezvous
3029 * service descriptor. On finding one, process it and write a
3030 * response into conn-\>outbuf. If the request is unrecognized, send a
3031 * 400. Always return 0. */
3032 static int
3033 directory_handle_command_post(dir_connection_t *conn, const char *headers,
3034 const char *body, size_t body_len)
3036 char *url = NULL;
3037 or_options_t *options = get_options();
3039 log_debug(LD_DIRSERV,"Received POST command.");
3041 conn->_base.state = DIR_CONN_STATE_SERVER_WRITING;
3043 if (parse_http_url(headers, &url) < 0) {
3044 write_http_status_line(conn, 400, "Bad request");
3045 return 0;
3047 log_debug(LD_DIRSERV,"rewritten url as '%s'.", url);
3049 /* Handle v2 rendezvous service publish request. */
3050 if (options->HidServDirectoryV2 &&
3051 !strcmpstart(url,"/tor/rendezvous2/publish")) {
3052 switch (rend_cache_store_v2_desc_as_dir(body)) {
3053 case -2:
3054 log_info(LD_REND, "Rejected v2 rend descriptor (length %d) from %s "
3055 "since we're not currently a hidden service directory.",
3056 (int)body_len, conn->_base.address);
3057 write_http_status_line(conn, 503, "Currently not acting as v2 "
3058 "hidden service directory");
3059 break;
3060 case -1:
3061 log_warn(LD_REND, "Rejected v2 rend descriptor (length %d) from %s.",
3062 (int)body_len, conn->_base.address);
3063 write_http_status_line(conn, 400,
3064 "Invalid v2 service descriptor rejected");
3065 break;
3066 default:
3067 write_http_status_line(conn, 200, "Service descriptor (v2) stored");
3068 log_info(LD_REND, "Handled v2 rendezvous descriptor post: accepted");
3070 goto done;
3073 if (!authdir_mode(options)) {
3074 /* we just provide cached directories; we don't want to
3075 * receive anything. */
3076 write_http_status_line(conn, 400, "Nonauthoritative directory does not "
3077 "accept posted server descriptors");
3078 goto done;
3081 if (authdir_mode_handles_descs(options, -1) &&
3082 !strcmp(url,"/tor/")) { /* server descriptor post */
3083 const char *msg = "[None]";
3084 uint8_t purpose = authdir_mode_bridge(options) ?
3085 ROUTER_PURPOSE_BRIDGE : ROUTER_PURPOSE_GENERAL;
3086 was_router_added_t r = dirserv_add_multiple_descriptors(body, purpose,
3087 conn->_base.address, &msg);
3088 tor_assert(msg);
3089 if (WRA_WAS_ADDED(r))
3090 dirserv_get_directory(); /* rebuild and write to disk */
3092 if (r == ROUTER_ADDED_NOTIFY_GENERATOR) {
3093 /* Accepted with a message. */
3094 log_info(LD_DIRSERV,
3095 "Problematic router descriptor or extra-info from %s "
3096 "(\"%s\").",
3097 conn->_base.address, msg);
3098 write_http_status_line(conn, 400, msg);
3099 } else if (r == ROUTER_ADDED_SUCCESSFULLY) {
3100 write_http_status_line(conn, 200, msg);
3101 } else if (WRA_WAS_OUTDATED(r)) {
3102 write_http_response_header_impl(conn, -1, NULL, NULL,
3103 "X-Descriptor-Not-New: Yes\r\n", -1);
3104 } else {
3105 log_info(LD_DIRSERV,
3106 "Rejected router descriptor or extra-info from %s "
3107 "(\"%s\").",
3108 conn->_base.address, msg);
3109 write_http_status_line(conn, 400, msg);
3111 goto done;
3114 if (options->HSAuthoritativeDir &&
3115 !strcmpstart(url,"/tor/rendezvous/publish")) {
3116 /* rendezvous descriptor post */
3117 log_info(LD_REND, "Handling rendezvous descriptor post.");
3118 if (rend_cache_store(body, body_len, 1, NULL) < 0) {
3119 log_fn(LOG_PROTOCOL_WARN, LD_DIRSERV,
3120 "Rejected rend descriptor (length %d) from %s.",
3121 (int)body_len, conn->_base.address);
3122 write_http_status_line(conn, 400,
3123 "Invalid v0 service descriptor rejected");
3124 } else {
3125 write_http_status_line(conn, 200, "Service descriptor (v0) stored");
3127 goto done;
3130 if (authdir_mode_v3(options) &&
3131 !strcmp(url,"/tor/post/vote")) { /* v3 networkstatus vote */
3132 const char *msg = "OK";
3133 int status;
3134 if (dirvote_add_vote(body, &msg, &status)) {
3135 write_http_status_line(conn, status, "Vote stored");
3136 } else {
3137 tor_assert(msg);
3138 write_http_status_line(conn, status, msg);
3140 goto done;
3143 if (authdir_mode_v3(options) &&
3144 !strcmp(url,"/tor/post/consensus-signature")) { /* sigs on consensus. */
3145 const char *msg = NULL;
3146 if (dirvote_add_signatures(body, conn->_base.address, &msg)>=0) {
3147 write_http_status_line(conn, 200, msg?msg:"Signatures stored");
3148 } else {
3149 log_warn(LD_DIR, "Unable to store signatures posted by %s: %s",
3150 conn->_base.address, msg?msg:"???");
3151 write_http_status_line(conn, 400, msg?msg:"Unable to store signatures");
3153 goto done;
3156 /* we didn't recognize the url */
3157 write_http_status_line(conn, 404, "Not found");
3159 done:
3160 tor_free(url);
3161 return 0;
3164 /** Called when a dirserver receives data on a directory connection;
3165 * looks for an HTTP request. If the request is complete, remove it
3166 * from the inbuf, try to process it; otherwise, leave it on the
3167 * buffer. Return a 0 on success, or -1 on error.
3169 static int
3170 directory_handle_command(dir_connection_t *conn)
3172 char *headers=NULL, *body=NULL;
3173 size_t body_len=0;
3174 int r;
3176 tor_assert(conn);
3177 tor_assert(conn->_base.type == CONN_TYPE_DIR);
3179 switch (fetch_from_buf_http(conn->_base.inbuf,
3180 &headers, MAX_HEADERS_SIZE,
3181 &body, &body_len, MAX_DIR_UL_SIZE, 0)) {
3182 case -1: /* overflow */
3183 log_warn(LD_DIRSERV,
3184 "Invalid input from address '%s'. Closing.",
3185 conn->_base.address);
3186 return -1;
3187 case 0:
3188 log_debug(LD_DIRSERV,"command not all here yet.");
3189 return 0;
3190 /* case 1, fall through */
3193 http_set_address_origin(headers, TO_CONN(conn));
3194 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
3196 if (!strncasecmp(headers,"GET",3))
3197 r = directory_handle_command_get(conn, headers, body, body_len);
3198 else if (!strncasecmp(headers,"POST",4))
3199 r = directory_handle_command_post(conn, headers, body, body_len);
3200 else {
3201 log_fn(LOG_PROTOCOL_WARN, LD_PROTOCOL,
3202 "Got headers %s with unknown command. Closing.",
3203 escaped(headers));
3204 r = -1;
3207 tor_free(headers); tor_free(body);
3208 return r;
3211 /** Write handler for directory connections; called when all data has
3212 * been flushed. Close the connection or wait for a response as
3213 * appropriate.
3216 connection_dir_finished_flushing(dir_connection_t *conn)
3218 tor_assert(conn);
3219 tor_assert(conn->_base.type == CONN_TYPE_DIR);
3221 switch (conn->_base.state) {
3222 case DIR_CONN_STATE_CLIENT_SENDING:
3223 log_debug(LD_DIR,"client finished sending command.");
3224 conn->_base.state = DIR_CONN_STATE_CLIENT_READING;
3225 connection_stop_writing(TO_CONN(conn));
3226 return 0;
3227 case DIR_CONN_STATE_SERVER_WRITING:
3228 log_debug(LD_DIRSERV,"Finished writing server response. Closing.");
3229 connection_mark_for_close(TO_CONN(conn));
3230 return 0;
3231 default:
3232 log_warn(LD_BUG,"called in unexpected state %d.",
3233 conn->_base.state);
3234 tor_fragile_assert();
3235 return -1;
3237 return 0;
3240 /** Connected handler for directory connections: begin sending data to the
3241 * server */
3243 connection_dir_finished_connecting(dir_connection_t *conn)
3245 tor_assert(conn);
3246 tor_assert(conn->_base.type == CONN_TYPE_DIR);
3247 tor_assert(conn->_base.state == DIR_CONN_STATE_CONNECTING);
3249 log_debug(LD_HTTP,"Dir connection to router %s:%u established.",
3250 conn->_base.address,conn->_base.port);
3252 conn->_base.state = DIR_CONN_STATE_CLIENT_SENDING; /* start flushing conn */
3253 return 0;
3256 /** Called when one or more networkstatus fetches have failed (with uppercase
3257 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
3258 * failed once, unless they failed with status code 503. */
3259 static void
3260 dir_networkstatus_download_failed(smartlist_t *failed, int status_code)
3262 if (status_code == 503)
3263 return;
3264 SMARTLIST_FOREACH(failed, const char *, fp,
3266 char digest[DIGEST_LEN];
3267 trusted_dir_server_t *dir;
3268 if (base16_decode(digest, DIGEST_LEN, fp, strlen(fp))<0) {
3269 log_warn(LD_BUG, "Called with bad fingerprint in list: %s",
3270 escaped(fp));
3271 continue;
3273 dir = router_get_trusteddirserver_by_digest(digest);
3275 if (dir)
3276 download_status_failed(&dir->v2_ns_dl_status, status_code);
3280 /** Schedule for when servers should download things in general. */
3281 static const int server_dl_schedule[] = {
3282 0, 0, 0, 60, 60, 60*2, 60*5, 60*15, INT_MAX
3284 /** Schedule for when clients should download things in general. */
3285 static const int client_dl_schedule[] = {
3286 0, 0, 60, 60*5, 60*10, INT_MAX
3288 /** Schedule for when servers should download consensuses. */
3289 static const int server_consensus_dl_schedule[] = {
3290 0, 0, 60, 60*5, 60*10, 60*30, 60*30, 60*30, 60*30, 60*30, 60*60, 60*60*2
3292 /** Schedule for when clients should download consensuses. */
3293 static const int client_consensus_dl_schedule[] = {
3294 0, 0, 60, 60*5, 60*10, 60*30, 60*60, 60*60, 60*60, 60*60*3, 60*60*6, 60*60*12
3296 /** Schedule for when clients should download bridge descriptors. */
3297 static const int bridge_dl_schedule[] = {
3298 60*60, 15*60, 15*60, 60*60
3301 /** Decide which download schedule we want to use, and then return a
3302 * pointer to it along with a pointer to its length. Helper function for
3303 * download_status_increment_failure() and download_status_reset(). */
3304 static void
3305 find_dl_schedule_and_len(download_status_t *dls, int server,
3306 const int **schedule, size_t *schedule_len)
3308 switch (dls->schedule) {
3309 case DL_SCHED_GENERIC:
3310 if (server) {
3311 *schedule = server_dl_schedule;
3312 *schedule_len = sizeof(server_dl_schedule)/sizeof(int);
3313 } else {
3314 *schedule = client_dl_schedule;
3315 *schedule_len = sizeof(client_dl_schedule)/sizeof(int);
3317 break;
3318 case DL_SCHED_CONSENSUS:
3319 if (server) {
3320 *schedule = server_consensus_dl_schedule;
3321 *schedule_len = sizeof(server_consensus_dl_schedule)/sizeof(int);
3322 } else {
3323 *schedule = client_consensus_dl_schedule;
3324 *schedule_len = sizeof(client_consensus_dl_schedule)/sizeof(int);
3326 break;
3327 case DL_SCHED_BRIDGE:
3328 *schedule = bridge_dl_schedule;
3329 *schedule_len = sizeof(bridge_dl_schedule)/sizeof(int);
3330 break;
3331 default:
3332 tor_assert(0);
3336 /** Called when an attempt to download <b>dls</b> has failed with HTTP status
3337 * <b>status_code</b>. Increment the failure count (if the code indicates a
3338 * real failure) and set <b>dls</b>-\>next_attempt_at to an appropriate time
3339 * in the future. */
3340 time_t
3341 download_status_increment_failure(download_status_t *dls, int status_code,
3342 const char *item, int server, time_t now)
3344 const int *schedule;
3345 size_t schedule_len;
3346 int increment;
3347 tor_assert(dls);
3348 if (status_code != 503 || server) {
3349 if (dls->n_download_failures < IMPOSSIBLE_TO_DOWNLOAD-1)
3350 ++dls->n_download_failures;
3353 find_dl_schedule_and_len(dls, server, &schedule, &schedule_len);
3355 if (dls->n_download_failures < schedule_len)
3356 increment = schedule[dls->n_download_failures];
3357 else if (dls->n_download_failures == IMPOSSIBLE_TO_DOWNLOAD)
3358 increment = INT_MAX;
3359 else
3360 increment = schedule[schedule_len-1];
3362 if (increment < INT_MAX)
3363 dls->next_attempt_at = now+increment;
3364 else
3365 dls->next_attempt_at = TIME_MAX;
3367 if (item) {
3368 if (increment == 0)
3369 log_debug(LD_DIR, "%s failed %d time(s); I'll try again immediately.",
3370 item, (int)dls->n_download_failures);
3371 else if (dls->next_attempt_at < TIME_MAX)
3372 log_debug(LD_DIR, "%s failed %d time(s); I'll try again in %d seconds.",
3373 item, (int)dls->n_download_failures,
3374 (int)(dls->next_attempt_at-now));
3375 else
3376 log_debug(LD_DIR, "%s failed %d time(s); Giving up for a while.",
3377 item, (int)dls->n_download_failures);
3379 return dls->next_attempt_at;
3382 /** Reset <b>dls</b> so that it will be considered downloadable
3383 * immediately, and/or to show that we don't need it anymore.
3385 * (We find the zeroth element of the download schedule, and set
3386 * next_attempt_at to be the appropriate offset from 'now'. In most
3387 * cases this means setting it to 'now', so the item will be immediately
3388 * downloadable; in the case of bridge descriptors, the zeroth element
3389 * is an hour from now.) */
3390 void
3391 download_status_reset(download_status_t *dls)
3393 const int *schedule;
3394 size_t schedule_len;
3396 find_dl_schedule_and_len(dls, get_options()->DirPort,
3397 &schedule, &schedule_len);
3399 dls->n_download_failures = 0;
3400 dls->next_attempt_at = time(NULL) + schedule[0];
3403 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
3404 * fetches have failed (with uppercase fingerprints listed in <b>failed</b>,
3405 * either as descriptor digests or as identity digests based on
3406 * <b>was_descriptor_digests</b>).
3408 static void
3409 dir_routerdesc_download_failed(smartlist_t *failed, int status_code,
3410 int router_purpose,
3411 int was_extrainfo, int was_descriptor_digests)
3413 char digest[DIGEST_LEN];
3414 time_t now = time(NULL);
3415 int server = directory_fetches_from_authorities(get_options());
3416 if (!was_descriptor_digests) {
3417 if (router_purpose == ROUTER_PURPOSE_BRIDGE) {
3418 tor_assert(!was_extrainfo); /* not supported yet */
3419 SMARTLIST_FOREACH(failed, const char *, cp,
3421 if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp))<0) {
3422 log_warn(LD_BUG, "Malformed fingerprint in list: %s",
3423 escaped(cp));
3424 continue;
3426 retry_bridge_descriptor_fetch_directly(digest);
3429 return; /* FFFF should implement for other-than-router-purpose someday */
3431 SMARTLIST_FOREACH(failed, const char *, cp,
3433 download_status_t *dls = NULL;
3434 if (base16_decode(digest, DIGEST_LEN, cp, strlen(cp)) < 0) {
3435 log_warn(LD_BUG, "Malformed fingerprint in list: %s", escaped(cp));
3436 continue;
3438 if (was_extrainfo) {
3439 signed_descriptor_t *sd =
3440 router_get_by_extrainfo_digest(digest);
3441 if (sd)
3442 dls = &sd->ei_dl_status;
3443 } else {
3444 dls = router_get_dl_status_by_descriptor_digest(digest);
3446 if (!dls || dls->n_download_failures >= MAX_ROUTERDESC_DOWNLOAD_FAILURES)
3447 continue;
3448 download_status_increment_failure(dls, status_code, cp, server, now);
3451 /* No need to relaunch descriptor downloads here: we already do it
3452 * every 10 or 60 seconds (FOO_DESCRIPTOR_RETRY_INTERVAL) in main.c. */
3455 /** Helper. Compare two fp_pair_t objects, and return negative, 0, or
3456 * positive as appropriate. */
3457 static int
3458 _compare_pairs(const void **a, const void **b)
3460 const fp_pair_t *fp1 = *a, *fp2 = *b;
3461 int r;
3462 if ((r = fast_memcmp(fp1->first, fp2->first, DIGEST_LEN)))
3463 return r;
3464 else
3465 return fast_memcmp(fp1->second, fp2->second, DIGEST_LEN);
3468 /** Divide a string <b>res</b> of the form FP1-FP2+FP3-FP4...[.z], where each
3469 * FP is a hex-encoded fingerprint, into a sequence of distinct sorted
3470 * fp_pair_t. Skip malformed pairs. On success, return 0 and add those
3471 * fp_pair_t into <b>pairs_out</b>. On failure, return -1. */
3473 dir_split_resource_into_fingerprint_pairs(const char *res,
3474 smartlist_t *pairs_out)
3476 smartlist_t *pairs_tmp = smartlist_create();
3477 smartlist_t *pairs_result = smartlist_create();
3479 smartlist_split_string(pairs_tmp, res, "+", 0, 0);
3480 if (smartlist_len(pairs_tmp)) {
3481 char *last = smartlist_get(pairs_tmp,smartlist_len(pairs_tmp)-1);
3482 size_t last_len = strlen(last);
3483 if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
3484 last[last_len-2] = '\0';
3487 SMARTLIST_FOREACH_BEGIN(pairs_tmp, char *, cp) {
3488 if (strlen(cp) != HEX_DIGEST_LEN*2+1) {
3489 log_info(LD_DIR,
3490 "Skipping digest pair %s with non-standard length.", escaped(cp));
3491 } else if (cp[HEX_DIGEST_LEN] != '-') {
3492 log_info(LD_DIR,
3493 "Skipping digest pair %s with missing dash.", escaped(cp));
3494 } else {
3495 fp_pair_t pair;
3496 if (base16_decode(pair.first, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0 ||
3497 base16_decode(pair.second,
3498 DIGEST_LEN, cp+HEX_DIGEST_LEN+1, HEX_DIGEST_LEN)<0) {
3499 log_info(LD_DIR, "Skipping non-decodable digest pair %s", escaped(cp));
3500 } else {
3501 smartlist_add(pairs_result, tor_memdup(&pair, sizeof(pair)));
3504 tor_free(cp);
3505 } SMARTLIST_FOREACH_END(cp);
3506 smartlist_free(pairs_tmp);
3508 /* Uniq-and-sort */
3509 smartlist_sort(pairs_result, _compare_pairs);
3510 smartlist_uniq(pairs_result, _compare_pairs, _tor_free);
3512 smartlist_add_all(pairs_out, pairs_result);
3513 smartlist_free(pairs_result);
3514 return 0;
3517 /** Given a directory <b>resource</b> request, containing zero
3518 * or more strings separated by plus signs, followed optionally by ".z", store
3519 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
3520 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
3521 * decode_hex is true, then delete all elements that aren't hex digests, and
3522 * decode the rest. If sort_uniq is true, then sort the list and remove
3523 * all duplicates.
3526 dir_split_resource_into_fingerprints(const char *resource,
3527 smartlist_t *fp_out, int *compressed_out,
3528 int decode_hex, int sort_uniq)
3530 smartlist_t *fp_tmp = smartlist_create();
3531 tor_assert(fp_out);
3532 smartlist_split_string(fp_tmp, resource, "+", 0, 0);
3533 if (compressed_out)
3534 *compressed_out = 0;
3535 if (smartlist_len(fp_tmp)) {
3536 char *last = smartlist_get(fp_tmp,smartlist_len(fp_tmp)-1);
3537 size_t last_len = strlen(last);
3538 if (last_len > 2 && !strcmp(last+last_len-2, ".z")) {
3539 last[last_len-2] = '\0';
3540 if (compressed_out)
3541 *compressed_out = 1;
3544 if (decode_hex) {
3545 int i;
3546 char *cp, *d = NULL;
3547 for (i = 0; i < smartlist_len(fp_tmp); ++i) {
3548 cp = smartlist_get(fp_tmp, i);
3549 if (strlen(cp) != HEX_DIGEST_LEN) {
3550 log_info(LD_DIR,
3551 "Skipping digest %s with non-standard length.", escaped(cp));
3552 smartlist_del_keeporder(fp_tmp, i--);
3553 goto again;
3555 d = tor_malloc_zero(DIGEST_LEN);
3556 if (base16_decode(d, DIGEST_LEN, cp, HEX_DIGEST_LEN)<0) {
3557 log_info(LD_DIR, "Skipping non-decodable digest %s", escaped(cp));
3558 smartlist_del_keeporder(fp_tmp, i--);
3559 goto again;
3561 smartlist_set(fp_tmp, i, d);
3562 d = NULL;
3563 again:
3564 tor_free(cp);
3565 tor_free(d);
3568 if (sort_uniq) {
3569 smartlist_t *fp_tmp2 = smartlist_create();
3570 int i;
3571 if (decode_hex)
3572 smartlist_sort_digests(fp_tmp);
3573 else
3574 smartlist_sort_strings(fp_tmp);
3575 if (smartlist_len(fp_tmp))
3576 smartlist_add(fp_tmp2, smartlist_get(fp_tmp, 0));
3577 for (i = 1; i < smartlist_len(fp_tmp); ++i) {
3578 char *cp = smartlist_get(fp_tmp, i);
3579 char *last = smartlist_get(fp_tmp2, smartlist_len(fp_tmp2)-1);
3581 if ((decode_hex && fast_memcmp(cp, last, DIGEST_LEN))
3582 || (!decode_hex && strcasecmp(cp, last)))
3583 smartlist_add(fp_tmp2, cp);
3584 else
3585 tor_free(cp);
3587 smartlist_free(fp_tmp);
3588 fp_tmp = fp_tmp2;
3590 smartlist_add_all(fp_out, fp_tmp);
3591 smartlist_free(fp_tmp);
3592 return 0;