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