1 /* Copyright 2001-2004 Roger Dingledine.
2 * Copyright 2004-2007 Roger Dingledine, Nick Mathewson. */
3 /* See LICENSE for licensing information */
5 const char directory_c_id
[] =
12 * \brief Code to send and fetch directories and router
13 * descriptors via HTTP. Directories use dirserv.c to generate the
14 * results; clients use routers.c to parse them.
17 /* In-points to directory.c:
19 * - directory_post_to_dirservers(), called from
20 * router_upload_dir_desc_to_dirservers() in router.c
21 * upload_service_descriptor() in rendservice.c
22 * - directory_get_from_dirserver(), called from
23 * rend_client_refetch_renddesc() in rendclient.c
24 * run_scheduled_events() in main.c
26 * - connection_dir_process_inbuf(), called from
27 * connection_process_inbuf() in connection.c
28 * - connection_dir_finished_flushing(), called from
29 * connection_finished_flushing() in connection.c
30 * - connection_dir_finished_connecting(), called from
31 * connection_finished_connecting() in connection.c
34 directory_send_command(dir_connection_t
*conn
,
35 int purpose
, int direct
, const char *resource
,
36 const char *payload
, size_t payload_len
);
37 static int directory_handle_command(dir_connection_t
*conn
);
38 static int body_is_plausible(const char *body
, size_t body_len
, int purpose
);
39 static int purpose_needs_anonymity(uint8_t purpose
);
40 static char *http_get_header(const char *headers
, const char *which
);
41 static void http_set_address_origin(const char *headers
, connection_t
*conn
);
42 static void connection_dir_download_networkstatus_failed(
43 dir_connection_t
*conn
, int status_code
);
44 static void connection_dir_download_routerdesc_failed(dir_connection_t
*conn
);
45 static void dir_networkstatus_download_failed(smartlist_t
*failed
,
47 static void dir_routerdesc_download_failed(smartlist_t
*failed
,
50 static void note_request(const char *key
, size_t bytes
);
52 /********* START VARIABLES **********/
54 /** How far in the future do we allow a directory server to tell us it is
55 * before deciding that one of us has the wrong time? */
56 #define ALLOW_DIRECTORY_TIME_SKEW (30*60)
58 #define X_ADDRESS_HEADER "X-Your-Address-Is: "
60 /** HTTP cache control: how long do we tell proxies they can cache each
61 * kind of document we serve? */
62 #define FULL_DIR_CACHE_LIFETIME (60*60)
63 #define RUNNINGROUTERS_CACHE_LIFETIME (20*60)
64 #define NETWORKSTATUS_CACHE_LIFETIME (5*60)
65 #define ROUTERDESC_CACHE_LIFETIME (30*60)
66 #define ROUTERDESC_BY_DIGEST_CACHE_LIFETIME (48*60*60)
67 #define ROBOTS_CACHE_LIFETIME (24*60*60)
69 /********* END VARIABLES ************/
71 /** Return true iff the directory purpose 'purpose' must use an
72 * anonymous connection to a directory. */
74 purpose_needs_anonymity(uint8_t purpose
)
76 if (get_options()->AllDirActionsPrivate
)
78 if (purpose
== DIR_PURPOSE_FETCH_DIR
||
79 purpose
== DIR_PURPOSE_UPLOAD_DIR
||
80 purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
||
81 purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
||
82 purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
83 purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
)
88 /** Return a newly allocated string describing <b>auth</b>. */
90 authority_type_to_string(authority_type_t auth
)
93 smartlist_t
*lst
= smartlist_create();
94 if (auth
& V1_AUTHORITY
)
95 smartlist_add(lst
, (void*)"V1");
96 if (auth
& V2_AUTHORITY
)
97 smartlist_add(lst
, (void*)"V2");
98 if (auth
& BRIDGE_AUTHORITY
)
99 smartlist_add(lst
, (void*)"Bridge");
100 if (auth
& HIDSERV_AUTHORITY
)
101 smartlist_add(lst
, (void*)"Hidden service");
102 if (smartlist_len(lst
)) {
103 result
= smartlist_join_strings(lst
, ", ", 0, NULL
);
105 result
= tor_strdup("[Not an authority]");
111 /** Return true iff <b>identity_digest</b> is the digest of a router we
112 * believe to support extrainfo downloads. (If <b>is_authority</b> we do
113 * additional checking that's only valid for authorities.) */
115 router_supports_extrainfo(const char *identity_digest
, int is_authority
)
117 routerinfo_t
*ri
= router_get_by_digest(identity_digest
);
118 local_routerstatus_t
*lrs
;
121 if (ri
->caches_extra_info
)
123 if (is_authority
&& ri
->platform
&&
124 tor_version_as_new_as(ri
->platform
, "Tor 0.2.0.0-alpha-dev (r10070)"))
128 lrs
= router_get_combined_status_by_digest(identity_digest
);
129 if (lrs
&& lrs
->status
.version_supports_extrainfo_upload
)
135 /** Start a connection to every suitable directory authority, using
136 * connection purpose 'purpose' and uploading the payload 'payload'
137 * (length 'payload_len'). The purpose should be one of
138 * 'DIR_PURPOSE_UPLOAD_DIR' or 'DIR_PURPOSE_UPLOAD_RENDDESC'.
140 * <b>type</b> specifies what sort of dir authorities (V1, V2,
141 * HIDSERV, BRIDGE) we should upload to.
143 * If <b>extrainfo_len</b> is nonzero, the first <b>payload_len</b> bytes of
144 * <b>payload</b> hold a router descriptor, and the next <b>extrainfo_len</b>
145 * bytes of <b>payload</b> hold an extra-info document. Upload the descriptor
146 * to all authorities, and the extra-info document to all authorities that
150 directory_post_to_dirservers(uint8_t purpose
, authority_type_t type
,
152 size_t payload_len
, size_t extrainfo_len
)
155 smartlist_t
*dirservers
= router_get_trusted_dir_servers();
157 tor_assert(dirservers
);
158 /* This tries dirservers which we believe to be down, but ultimately, that's
159 * harmless, and we may as well err on the side of getting things uploaded.
161 SMARTLIST_FOREACH(dirservers
, trusted_dir_server_t
*, ds
,
163 routerstatus_t
*rs
= &(ds
->fake_status
.status
);
164 size_t upload_len
= payload_len
;
166 if ((type
& ds
->type
) == 0)
169 found
= 1; /* at least one authority of this type was listed */
170 if (purpose
== DIR_PURPOSE_UPLOAD_DIR
)
171 ds
->has_accepted_serverdesc
= 0;
173 if (extrainfo_len
&& router_supports_extrainfo(ds
->digest
, 1)) {
174 upload_len
+= extrainfo_len
;
175 log_info(LD_DIR
, "Uploading an extrainfo (length %d)",
176 (int) extrainfo_len
);
178 post_via_tor
= purpose_needs_anonymity(purpose
) ||
179 !fascist_firewall_allows_address_dir(ds
->addr
, ds
->dir_port
);
180 directory_initiate_command_routerstatus(rs
, purpose
,
181 ROUTER_PURPOSE_GENERAL
,
183 NULL
, payload
, upload_len
);
186 char *s
= authority_type_to_string(type
);
187 log_warn(LD_DIR
, "Publishing server descriptor to directory authorities "
188 "of type '%s', but no authorities of that type listed!", s
);
193 /** Start a connection to a random running directory server, using
194 * connection purpose 'purpose' and requesting 'resource'.
195 * If <b>retry_if_no_servers</b>, then if all the possible servers seem
196 * down, mark them up and try again.
199 directory_get_from_dirserver(uint8_t dir_purpose
, const char *resource
,
200 int retry_if_no_servers
)
202 routerstatus_t
*rs
= NULL
;
203 or_options_t
*options
= get_options();
204 int prefer_authority
= server_mode(options
) && options
->DirPort
!= 0;
205 int directconn
= !purpose_needs_anonymity(dir_purpose
);
206 authority_type_t type
;
208 /* FFFF we could break this switch into its own function, and call
209 * it elsewhere in directory.c. -RD */
210 switch (dir_purpose
) {
211 case DIR_PURPOSE_FETCH_EXTRAINFO
:
212 type
= EXTRAINFO_CACHE
| V2_AUTHORITY
;
214 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
215 case DIR_PURPOSE_FETCH_SERVERDESC
:
218 case DIR_PURPOSE_FETCH_DIR
:
219 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
222 case DIR_PURPOSE_FETCH_RENDDESC
:
223 type
= HIDSERV_AUTHORITY
;
226 log_warn(LD_BUG
, "Unexpected purpose %d", (int)dir_purpose
);
230 if (!options
->FetchServerDescriptors
&& type
!= HIDSERV_AUTHORITY
)
233 if (directconn
&& options
->UseBridges
) {
234 /* want to pick a bridge for which we have a descriptor. */
235 routerinfo_t
*ri
= choose_random_entry(NULL
);
237 directory_initiate_command(ri
->address
, ri
->addr
,
239 1, ri
->cache_info
.identity_digest
,
241 ROUTER_PURPOSE_GENERAL
,
242 0, resource
, NULL
, 0);
244 log_notice(LD_DIR
, "Ignoring directory request, since no bridge "
245 "nodes are available yet.");
247 } else if (directconn
) {
248 if (prefer_authority
) {
249 /* only ask authdirservers, and don't ask myself */
250 rs
= router_pick_trusteddirserver(type
, 1, 1,
251 retry_if_no_servers
);
254 /* anybody with a non-zero dirport will do */
255 rs
= router_pick_directory_server(1, 1, type
,
256 retry_if_no_servers
);
259 if (dir_purpose
== DIR_PURPOSE_FETCH_DIR
)
261 else if (dir_purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
)
262 which
= "status list";
263 else if (dir_purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
)
264 which
= "network status";
265 else // if (dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
266 which
= "server descriptors";
268 "No router found for %s; falling back to dirserver list",
270 rs
= router_pick_trusteddirserver(type
, 1, 1,
271 retry_if_no_servers
);
273 directconn
= 0; /* last resort: try routing it via Tor */
276 } else { /* !directconn */
277 /* Never use fascistfirewall; we're going via Tor. */
278 if (dir_purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
279 /* only ask hidserv authorities, any of them will do */
280 rs
= router_pick_trusteddirserver(HIDSERV_AUTHORITY
, 0, 0,
281 retry_if_no_servers
);
283 /* anybody with a non-zero dirport will do. Disregard firewalls. */
284 rs
= router_pick_directory_server(1, 0, type
,
285 retry_if_no_servers
);
286 /* If we have any hope of building an indirect conn, we know some router
287 * descriptors. If (rs==NULL), we can't build circuits anyway, so
288 * there's no point in falling back to the authorities in this case. */
293 directory_initiate_command_routerstatus(rs
, dir_purpose
,
294 ROUTER_PURPOSE_GENERAL
,
299 "While fetching directory info, "
300 "no running dirservers known. Will try again later. "
301 "(purpose %d)", dir_purpose
);
302 if (!purpose_needs_anonymity(dir_purpose
)) {
303 /* remember we tried them all and failed. */
304 directory_all_unreachable(time(NULL
));
309 /** Launch a new connection to the directory server <b>status</b> to
310 * upload or download a server or rendezvous
311 * descriptor. <b>dir_purpose</b> determines what
312 * kind of directory connection we're launching, and must be one of
313 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}. <b>router_purpose</b>
314 * specifies the descriptor purposes we have in mind (currently only
315 * used for FETCH_DIR).
317 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
318 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
320 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
324 directory_initiate_command_routerstatus(routerstatus_t
*status
,
326 uint8_t router_purpose
,
327 int anonymized_connection
,
328 const char *resource
,
332 routerinfo_t
*router
;
333 char address_buf
[INET_NTOA_BUF_LEN
+1];
336 if ((router
= router_get_by_digest(status
->identity_digest
))) {
337 address
= router
->address
;
339 in
.s_addr
= htonl(status
->addr
);
340 tor_inet_ntoa(&in
, address_buf
, sizeof(address_buf
));
341 address
= address_buf
;
343 directory_initiate_command(address
, status
->addr
,
344 status
->or_port
, status
->dir_port
,
345 status
->version_supports_begindir
,
346 status
->identity_digest
,
347 dir_purpose
, router_purpose
,
348 anonymized_connection
, resource
,
349 payload
, payload_len
);
352 /** Return true iff <b>conn</b> is the client side of a directory connection
353 * we launched to ourself in order to determine the reachability of our
356 directory_conn_is_self_reachability_test(dir_connection_t
*conn
)
358 if (conn
->requested_resource
&&
359 !strcmpstart(conn
->requested_resource
,"authority")) {
360 routerinfo_t
*me
= router_get_my_routerinfo();
362 router_digest_is_me(conn
->identity_digest
) &&
363 me
->addr
== conn
->_base
.addr
&&
364 me
->dir_port
== conn
->_base
.port
)
370 /** Called when we are unable to complete the client's request to a directory
371 * server due to a network error: Mark the router as down and try again if
375 connection_dir_request_failed(dir_connection_t
*conn
)
377 if (directory_conn_is_self_reachability_test(conn
)) {
378 routerinfo_t
*me
= router_get_my_routerinfo();
380 control_event_server_status(LOG_WARN
,
381 "REACHABILITY_FAILED DIRADDRESS=%s:%d",
382 me
->address
, me
->dir_port
);
383 return; /* this was a test fetch. don't retry. */
385 router_set_status(conn
->identity_digest
, 0); /* don't try him again */
386 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
||
387 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
388 log_info(LD_DIR
, "Giving up on directory server at '%s:%d'; retrying",
389 conn
->_base
.address
, conn
->_base
.port
);
390 directory_get_from_dirserver(conn
->_base
.purpose
, NULL
,
391 0 /* don't retry_if_no_servers */);
392 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
393 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
394 conn
->_base
.address
);
395 connection_dir_download_networkstatus_failed(conn
, -1);
396 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
397 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
398 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
399 conn
->_base
.address
);
400 connection_dir_download_routerdesc_failed(conn
);
404 /** Called when an attempt to download one or more network status
405 * documents on connection <b>conn</b> failed. Decide whether to
406 * retry the fetch now, later, or never.
409 connection_dir_download_networkstatus_failed(dir_connection_t
*conn
,
412 if (!conn
->requested_resource
) {
413 /* We never reached directory_send_command, which means that we never
414 * opened a network connection. Either we're out of sockets, or the
415 * network is down. Either way, retrying would be pointless. */
418 if (!strcmpstart(conn
->requested_resource
, "all")) {
419 /* We're a non-authoritative directory cache; try again. Ignore status
420 * code, since we don't want to keep trying forever in a tight loop
421 * if all the authorities are shutting us out. */
422 smartlist_t
*trusted_dirs
= router_get_trusted_dir_servers();
423 SMARTLIST_FOREACH(trusted_dirs
, trusted_dir_server_t
*, ds
,
424 ++ds
->n_networkstatus_failures
);
425 directory_get_from_dirserver(conn
->_base
.purpose
, "all.z",
426 0 /* don't retry_if_no_servers */);
427 } else if (!strcmpstart(conn
->requested_resource
, "fp/")) {
428 /* We were trying to download by fingerprint; mark them all as having
429 * failed, and possibly retry them later.*/
430 smartlist_t
*failed
= smartlist_create();
431 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
433 if (smartlist_len(failed
)) {
434 dir_networkstatus_download_failed(failed
, status_code
);
435 SMARTLIST_FOREACH(failed
, char *, cp
, tor_free(cp
));
437 smartlist_free(failed
);
441 /** Called when an attempt to download one or more router descriptors
442 * or extra-info documents on connection <b>conn</b> failed.
445 connection_dir_download_routerdesc_failed(dir_connection_t
*conn
)
447 /* No need to increment the failure count for routerdescs, since
448 * it's not their fault. */
450 /* No need to relaunch descriptor downloads here: we already do it
451 * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
452 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
453 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
458 /** Helper for directory_initiate_command_(router|trusted_dir): send the
459 * command to a server whose address is <b>address</b>, whose IP is
460 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
461 * <b>supports_begindir</b>, and whose identity key digest is
464 directory_initiate_command(const char *address
, uint32_t addr
,
465 uint16_t or_port
, uint16_t dir_port
,
466 int supports_begindir
, const char *digest
,
467 uint8_t dir_purpose
, uint8_t router_purpose
,
468 int anonymized_connection
, const char *resource
,
469 const char *payload
, size_t payload_len
)
471 dir_connection_t
*conn
;
472 or_options_t
*options
= get_options();
473 int want_to_tunnel
= options
->TunnelDirConns
&& supports_begindir
&&
474 !anonymized_connection
&& or_port
&&
475 fascist_firewall_allows_address_or(addr
, or_port
);
479 tor_assert(or_port
|| dir_port
);
482 log_debug(LD_DIR
, "anonymized %d, want_to_tunnel %d.",
483 anonymized_connection
, want_to_tunnel
);
485 switch (dir_purpose
) {
486 case DIR_PURPOSE_FETCH_DIR
:
487 log_debug(LD_DIR
,"initiating directory fetch");
489 case DIR_PURPOSE_FETCH_RENDDESC
:
490 log_debug(LD_DIR
,"initiating hidden-service descriptor fetch");
492 case DIR_PURPOSE_UPLOAD_DIR
:
493 log_debug(LD_OR
,"initiating server descriptor upload");
495 case DIR_PURPOSE_UPLOAD_RENDDESC
:
496 log_debug(LD_REND
,"initiating hidden-service descriptor upload");
498 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
499 log_debug(LD_DIR
,"initiating running-routers fetch");
501 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
502 log_debug(LD_DIR
,"initiating network-status fetch");
504 case DIR_PURPOSE_FETCH_SERVERDESC
:
505 log_debug(LD_DIR
,"initiating server descriptor fetch");
507 case DIR_PURPOSE_FETCH_EXTRAINFO
:
508 log_debug(LD_DIR
,"initiating extra-info fetch");
511 log_err(LD_BUG
, "Unrecognized directory connection purpose.");
515 conn
= TO_DIR_CONN(connection_new(CONN_TYPE_DIR
, AF_INET
));
517 /* set up conn so it's got all the data we need to remember */
518 conn
->_base
.addr
= addr
;
519 conn
->_base
.port
= want_to_tunnel
? or_port
: dir_port
;
520 conn
->_base
.address
= tor_strdup(address
);
521 memcpy(conn
->identity_digest
, digest
, DIGEST_LEN
);
523 conn
->_base
.purpose
= dir_purpose
;
524 conn
->router_purpose
= router_purpose
;
526 /* give it an initial state */
527 conn
->_base
.state
= DIR_CONN_STATE_CONNECTING
;
529 if (!anonymized_connection
&& !want_to_tunnel
) {
530 /* then we want to connect directly */
532 conn
->dirconn_direct
= 1;
533 if (options
->HttpProxy
) {
534 addr
= options
->HttpProxyAddr
;
535 dir_port
= options
->HttpProxyPort
;
538 switch (connection_connect(TO_CONN(conn
), conn
->_base
.address
, addr
,
541 connection_dir_request_failed(conn
); /* retry if we want */
542 connection_free(TO_CONN(conn
));
545 /* start flushing conn */
546 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
549 /* queue the command on the outbuf */
550 directory_send_command(conn
, dir_purpose
, 1, resource
,
551 payload
, payload_len
);
552 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
553 /* writable indicates finish, readable indicates broken link,
554 error indicates broken link in windowsland. */
556 } else { /* we want to connect via tor */
557 edge_connection_t
*linked_conn
;
558 /* make an AP connection
559 * populate it and add it at the right state
562 conn
->dirconn_direct
= 0;
564 connection_ap_make_link(conn
->_base
.address
, conn
->_base
.port
,
566 anonymized_connection
?
567 SOCKS_COMMAND_CONNECT
:
568 SOCKS_COMMAND_CONNECT_DIR
);
570 log_warn(LD_NET
,"Making tunnel to dirserver failed.");
571 connection_mark_for_close(TO_CONN(conn
));
574 connection_link_connections(TO_CONN(conn
), TO_CONN(linked_conn
));
576 if (connection_add(TO_CONN(conn
)) < 0) {
577 log_warn(LD_NET
,"Unable to add connection for link to dirserver.");
578 connection_mark_for_close(TO_CONN(conn
));
581 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
582 /* queue the command on the outbuf */
583 directory_send_command(conn
, dir_purpose
, 0, resource
,
584 payload
, payload_len
);
585 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
586 connection_start_reading(TO_CONN(linked_conn
));
590 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
591 * are as in directory_initiate_command.
594 directory_send_command(dir_connection_t
*conn
,
595 int purpose
, int direct
, const char *resource
,
596 const char *payload
, size_t payload_len
)
598 char proxystring
[256];
599 char proxyauthstring
[256];
600 char hoststring
[128];
603 const char *httpcommand
= NULL
;
607 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
609 tor_free(conn
->requested_resource
);
611 conn
->requested_resource
= tor_strdup(resource
);
613 /* come up with a string for which Host: we want */
614 if (conn
->_base
.port
== 80) {
615 strlcpy(hoststring
, conn
->_base
.address
, sizeof(hoststring
));
617 tor_snprintf(hoststring
, sizeof(hoststring
),"%s:%d",
618 conn
->_base
.address
, conn
->_base
.port
);
621 /* come up with some proxy lines, if we're using one. */
622 if (direct
&& get_options()->HttpProxy
) {
623 char *base64_authenticator
=NULL
;
624 const char *authenticator
= get_options()->HttpProxyAuthenticator
;
626 tor_snprintf(proxystring
, sizeof(proxystring
),"http://%s", hoststring
);
628 base64_authenticator
= alloc_http_authenticator(authenticator
);
629 if (!base64_authenticator
)
630 log_warn(LD_BUG
, "Encoding http authenticator failed");
632 if (base64_authenticator
) {
633 tor_snprintf(proxyauthstring
, sizeof(proxyauthstring
),
634 "\r\nProxy-Authorization: Basic %s",
635 base64_authenticator
);
636 tor_free(base64_authenticator
);
638 proxyauthstring
[0] = 0;
642 proxyauthstring
[0] = 0;
646 case DIR_PURPOSE_FETCH_DIR
:
647 tor_assert(!resource
);
648 tor_assert(!payload
);
650 url
= tor_strdup("/tor/dir.z");
652 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
653 tor_assert(!resource
);
654 tor_assert(!payload
);
656 url
= tor_strdup("/tor/running-routers");
658 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
660 len
= strlen(resource
)+32;
661 url
= tor_malloc(len
);
662 tor_snprintf(url
, len
, "/tor/status/%s", resource
);
664 case DIR_PURPOSE_FETCH_SERVERDESC
:
666 len
= strlen(resource
)+32;
667 url
= tor_malloc(len
);
668 tor_snprintf(url
, len
, "/tor/server/%s", resource
);
670 case DIR_PURPOSE_FETCH_EXTRAINFO
:
672 len
= strlen(resource
)+32;
673 url
= tor_malloc(len
);
674 tor_snprintf(url
, len
, "/tor/extra/%s", resource
);
676 case DIR_PURPOSE_UPLOAD_DIR
:
677 tor_assert(!resource
);
679 httpcommand
= "POST";
680 url
= tor_strdup("/tor/");
682 case DIR_PURPOSE_FETCH_RENDDESC
:
683 tor_assert(resource
);
684 tor_assert(!payload
);
686 /* this must be true or we wouldn't be doing the lookup */
687 tor_assert(strlen(resource
) <= REND_SERVICE_ID_LEN
);
688 /* This breaks the function abstraction. */
689 strlcpy(conn
->rend_query
, resource
, sizeof(conn
->rend_query
));
692 /* Request the most recent versioned descriptor. */
693 // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
694 // but that never got testing, and it wasn't a good design.)
695 len
= strlen(resource
)+32;
696 url
= tor_malloc(len
);
697 tor_snprintf(url
, len
, "/tor/rendezvous/%s", resource
);
699 case DIR_PURPOSE_UPLOAD_RENDDESC
:
700 tor_assert(!resource
);
702 httpcommand
= "POST";
703 url
= tor_strdup("/tor/rendezvous/publish");
710 if (strlen(proxystring
) + strlen(url
) >= 4096) {
712 "Squid does not like URLs longer than 4095 bytes, and this "
713 "one is %d bytes long: %s%s",
714 (int)(strlen(proxystring
) + strlen(url
)), proxystring
, url
);
717 tor_snprintf(request
, sizeof(request
), "%s %s", httpcommand
, proxystring
);
718 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
719 connection_write_to_buf(url
, strlen(url
), TO_CONN(conn
));
722 if (!strcmp(httpcommand
, "GET") && !payload
) {
723 tor_snprintf(request
, sizeof(request
),
724 " HTTP/1.0\r\nHost: %s%s\r\n\r\n",
728 tor_snprintf(request
, sizeof(request
),
729 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s\r\n\r\n",
730 payload
? (unsigned long)payload_len
: 0,
734 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
737 /* then send the payload afterwards too */
738 connection_write_to_buf(payload
, payload_len
, TO_CONN(conn
));
742 /** Parse an HTTP request string <b>headers</b> of the form
744 * "\%s [http[s]://]\%s HTTP/1..."
746 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
747 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
748 * so it does. Return 0.
749 * Otherwise, return -1.
752 parse_http_url(const char *headers
, char **url
)
754 char *s
, *start
, *tmp
;
756 s
= (char *)eat_whitespace_no_nl(headers
);
758 s
= (char *)find_whitespace(s
); /* get past GET/POST */
760 s
= (char *)eat_whitespace_no_nl(s
);
762 start
= s
; /* this is it, assuming it's valid */
763 s
= (char *)find_whitespace(start
);
766 /* tolerate the http[s] proxy style of putting the hostname in the url */
767 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
771 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
772 tmp
= strchr(tmp
+3, '/');
773 if (tmp
&& tmp
< s
) {
774 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname' string");
780 if (s
-start
< 5 || strcmpstart(start
,"/tor/")) { /* need to rewrite it */
781 *url
= tor_malloc(s
- start
+ 5);
782 strlcpy(*url
,"/tor", s
-start
+5);
783 strlcat((*url
)+4, start
, s
-start
+1);
785 *url
= tor_strndup(start
, s
-start
);
790 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
791 * <b>which</b>. The key should be given with a terminating colon and space;
792 * this function copies everything after, up to but not including the
793 * following \\r\\n. */
795 http_get_header(const char *headers
, const char *which
)
797 const char *cp
= headers
;
799 if (!strcmpstart(cp
, which
)) {
802 if ((eos
= strchr(cp
,'\r')))
803 return tor_strndup(cp
, eos
-cp
);
805 return tor_strdup(cp
);
807 cp
= strchr(cp
, '\n');
814 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
815 * <b>conn</b>-\>address to describe our best guess of the address that
816 * originated this HTTP request. */
818 http_set_address_origin(const char *headers
, connection_t
*conn
)
822 fwd
= http_get_header(headers
, "Forwarded-For: ");
824 fwd
= http_get_header(headers
, "X-Forwarded-For: ");
827 if (!tor_inet_aton(fwd
, &in
) || is_internal_IP(ntohl(in
.s_addr
), 0)) {
828 log_debug(LD_DIR
, "Ignoring unrecognized or internal IP %s",
833 tor_free(conn
->address
);
834 conn
->address
= tor_strdup(fwd
);
839 /** Parse an HTTP response string <b>headers</b> of the form
841 * "HTTP/1.\%d \%d\%s\r\n...".
844 * If it's well-formed, assign the status code to *<b>code</b> and
845 * return 0. Otherwise, return -1.
847 * On success: If <b>date</b> is provided, set *date to the Date
848 * header in the http headers, or 0 if no such header is found. If
849 * <b>compression</b> is provided, set *<b>compression</b> to the
850 * compression method given in the Content-Encoding header, or 0 if no
851 * such header is found, or -1 if the value of the header is not
852 * recognized. If <b>reason</b> is provided, strdup the reason string
856 parse_http_response(const char *headers
, int *code
, time_t *date
,
857 compress_method_t
*compression
, char **reason
)
860 char datestr
[RFC1123_TIME_LEN
+1];
861 smartlist_t
*parsed_headers
;
865 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
867 if (sscanf(headers
, "HTTP/1.%d %d", &n1
, &n2
) < 2 ||
868 (n1
!= 0 && n1
!= 1) ||
869 (n2
< 100 || n2
>= 600)) {
870 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
875 parsed_headers
= smartlist_create();
876 smartlist_split_string(parsed_headers
, headers
, "\n",
877 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
879 smartlist_t
*status_line_elements
= smartlist_create();
880 tor_assert(smartlist_len(parsed_headers
));
881 smartlist_split_string(status_line_elements
,
882 smartlist_get(parsed_headers
, 0),
883 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
884 tor_assert(smartlist_len(status_line_elements
) <= 3);
885 if (smartlist_len(status_line_elements
) == 3) {
886 *reason
= smartlist_get(status_line_elements
, 2);
887 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
889 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
890 smartlist_free(status_line_elements
);
894 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
895 if (!strcmpstart(s
, "Date: ")) {
896 strlcpy(datestr
, s
+6, sizeof(datestr
));
897 /* This will do nothing on failure, so we don't need to check
898 the result. We shouldn't warn, since there are many other valid
899 date formats besides the one we use. */
900 parse_rfc1123_time(datestr
, date
);
905 const char *enc
= NULL
;
906 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
907 if (!strcmpstart(s
, "Content-Encoding: ")) {
910 if (!enc
|| !strcmp(enc
, "identity")) {
911 *compression
= NO_METHOD
;
912 } else if (!strcmp(enc
, "deflate") || !strcmp(enc
, "x-deflate")) {
913 *compression
= ZLIB_METHOD
;
914 } else if (!strcmp(enc
, "gzip") || !strcmp(enc
, "x-gzip")) {
915 *compression
= GZIP_METHOD
;
917 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
919 *compression
= UNKNOWN_METHOD
;
922 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
923 smartlist_free(parsed_headers
);
928 /** Return true iff <b>body</b> doesn't start with a plausible router or
929 * running-list or directory opening. This is a sign of possible compression.
932 body_is_plausible(const char *body
, size_t len
, int purpose
)
936 return 1; /* empty bodies don't need decompression */
939 if (purpose
!= DIR_PURPOSE_FETCH_RENDDESC
) {
940 if (!strcmpstart(body
,"router") ||
941 !strcmpstart(body
,"signed-directory") ||
942 !strcmpstart(body
,"network-status") ||
943 !strcmpstart(body
,"running-routers"))
946 if (!TOR_ISPRINT(body
[i
]) && !TOR_ISSPACE(body
[i
]))
955 /** We are a client, and we've finished reading the server's
956 * response. Parse and it and act appropriately.
958 * If we're still happy with using this directory server in the future, return
959 * 0. Otherwise return -1; and the caller should consider trying the request
962 * The caller will take care of marking the connection for close.
965 connection_dir_client_reached_eof(dir_connection_t
*conn
)
970 size_t body_len
=0, orig_len
=0;
972 time_t date_header
=0;
974 compress_method_t compression
;
977 int allow_partial
= (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
978 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
979 int was_compressed
=0;
980 time_t now
= time(NULL
);
982 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
983 &headers
, MAX_HEADERS_SIZE
,
984 &body
, &body_len
, MAX_DIR_DL_SIZE
,
986 case -1: /* overflow */
987 log_warn(LD_PROTOCOL
,
988 "'fetch' response too large (server '%s:%d'). Closing.",
989 conn
->_base
.address
, conn
->_base
.port
);
993 "'fetch' response not all here, but we're at eof. Closing.");
995 /* case 1, fall through */
999 if (parse_http_response(headers
, &status_code
, &date_header
,
1000 &compression
, &reason
) < 0) {
1001 log_warn(LD_HTTP
,"Unparseable headers (server '%s:%d'). Closing.",
1002 conn
->_base
.address
, conn
->_base
.port
);
1003 tor_free(body
); tor_free(headers
);
1006 if (!reason
) reason
= tor_strdup("[no reason given]");
1009 "Received response from directory server '%s:%d': %d %s",
1010 conn
->_base
.address
, conn
->_base
.port
, status_code
,
1013 /* now check if it's got any hints for us about our IP address. */
1014 if (conn
->dirconn_direct
) {
1015 char *guess
= http_get_header(headers
, X_ADDRESS_HEADER
);
1017 router_new_address_suggestion(guess
);
1022 if (date_header
> 0) {
1023 /* The date header was written very soon after we sent our request,
1024 * so compute the skew as the difference between sending the request
1025 * and the date header. (We used to check now-date_header, but that's
1026 * inaccurate if we spend a lot of time downloading.)
1028 delta
= conn
->_base
.timestamp_lastwritten
- date_header
;
1029 if (abs(delta
)>ALLOW_DIRECTORY_TIME_SKEW
) {
1030 int trusted
= router_digest_is_trusted_dir(conn
->identity_digest
);
1031 log_fn(trusted
? LOG_WARN
: LOG_INFO
,
1033 "Received directory with skewed time (server '%s:%d'): "
1034 "we are %d minutes %s, or the directory is %d minutes %s.",
1035 conn
->_base
.address
, conn
->_base
.port
,
1036 abs(delta
)/60, delta
>0 ? "ahead" : "behind",
1037 abs(delta
)/60, delta
>0 ? "behind" : "ahead");
1038 skewed
= 1; /* don't check the recommended-versions line */
1039 control_event_general_status(trusted
? LOG_WARN
: LOG_NOTICE
,
1040 "CLOCK_SKEW SKEW=%d SOURCE=DIRSERV:%s:%d",
1041 delta
, conn
->_base
.address
, conn
->_base
.port
);
1043 log_debug(LD_HTTP
, "Time on received directory is within tolerance; "
1044 "we are %d seconds skewed. (That's okay.)", delta
);
1047 (void) skewed
; /* skewed isn't used yet. */
1049 if (status_code
== 503) {
1050 local_routerstatus_t
*rs
;
1051 trusted_dir_server_t
*ds
;
1052 log_info(LD_DIR
,"Received http status code %d (%s) from server "
1053 "'%s:%d'. I'll try again soon.",
1054 status_code
, escaped(reason
), conn
->_base
.address
,
1056 if ((rs
= router_get_combined_status_by_digest(conn
->identity_digest
)))
1057 rs
->last_dir_503_at
= now
;
1058 if ((ds
= router_get_trusteddirserver_by_digest(conn
->identity_digest
)))
1059 ds
->fake_status
.last_dir_503_at
= now
;
1061 tor_free(body
); tor_free(headers
); tor_free(reason
);
1065 plausible
= body_is_plausible(body
, body_len
, conn
->_base
.purpose
);
1066 if (compression
!= NO_METHOD
|| !plausible
) {
1067 char *new_body
= NULL
;
1069 compress_method_t guessed
= detect_compression_method(body
, body_len
);
1070 if (compression
== UNKNOWN_METHOD
|| guessed
!= compression
) {
1071 /* Tell the user if we don't believe what we're told about compression.*/
1072 const char *description1
, *description2
;
1073 if (compression
== ZLIB_METHOD
)
1074 description1
= "as deflated";
1075 else if (compression
== GZIP_METHOD
)
1076 description1
= "as gzipped";
1077 else if (compression
== NO_METHOD
)
1078 description1
= "as uncompressed";
1080 description1
= "with an unknown Content-Encoding";
1081 if (guessed
== ZLIB_METHOD
)
1082 description2
= "deflated";
1083 else if (guessed
== GZIP_METHOD
)
1084 description2
= "gzipped";
1085 else if (!plausible
)
1086 description2
= "confusing binary junk";
1088 description2
= "uncompressed";
1090 log_info(LD_HTTP
, "HTTP body from server '%s:%d' was labeled %s, "
1091 "but it seems to be %s.%s",
1092 conn
->_base
.address
, conn
->_base
.port
, description1
,
1094 (compression
>0 && guessed
>0)?" Trying both.":"");
1096 /* Try declared compression first if we can. */
1097 if (compression
== GZIP_METHOD
|| compression
== ZLIB_METHOD
)
1098 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, compression
,
1099 !allow_partial
, LOG_PROTOCOL_WARN
);
1100 /* Okay, if that didn't work, and we think that it was compressed
1101 * differently, try that. */
1103 (guessed
== GZIP_METHOD
|| guessed
== ZLIB_METHOD
) &&
1104 compression
!= guessed
)
1105 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, guessed
,
1106 !allow_partial
, LOG_PROTOCOL_WARN
);
1107 /* If we're pretty sure that we have a compressed directory, and
1108 * we didn't manage to uncompress it, then warn and bail. */
1109 if (!plausible
&& !new_body
) {
1110 log_fn(LOG_PROTOCOL_WARN
, LD_HTTP
,
1111 "Unable to decompress HTTP body (server '%s:%d').",
1112 conn
->_base
.address
, conn
->_base
.port
);
1113 tor_free(body
); tor_free(headers
); tor_free(reason
);
1124 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
) {
1125 /* fetch/process the directory to cache it. */
1126 log_info(LD_DIR
,"Received directory (size %d) from server '%s:%d'",
1127 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1128 if (status_code
!= 200) {
1129 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1130 "'%s:%d' while fetching directory. I'll try again soon.",
1131 status_code
, escaped(reason
), conn
->_base
.address
,
1133 tor_free(body
); tor_free(headers
); tor_free(reason
);
1136 if (router_parse_directory(body
) < 0) {
1137 log_notice(LD_DIR
,"I failed to parse the directory I fetched from "
1138 "'%s:%d'. Ignoring.", conn
->_base
.address
, conn
->_base
.port
);
1140 note_request(was_compressed
?"dl/dir.z":"dl/dir", orig_len
);
1143 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
1144 /* just update our list of running routers, if this list is new info */
1145 log_info(LD_DIR
,"Received running-routers list (size %d)", (int)body_len
);
1146 if (status_code
!= 200) {
1147 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1148 "'%s:%d' while fetching running-routers. I'll try again soon.",
1149 status_code
, escaped(reason
), conn
->_base
.address
,
1151 tor_free(body
); tor_free(headers
); tor_free(reason
);
1154 if (router_parse_runningrouters(body
)<0) {
1156 "Bad running-routers from server '%s:%d'. I'll try again soon.",
1157 conn
->_base
.address
, conn
->_base
.port
);
1158 tor_free(body
); tor_free(headers
); tor_free(reason
);
1161 note_request(was_compressed
?"dl/running-routers.z":
1162 "dl/running-routers", orig_len
);
1165 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
1166 smartlist_t
*which
= NULL
;
1167 networkstatus_source_t source
;
1169 log_info(LD_DIR
,"Received networkstatus objects (size %d) from server "
1170 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1171 if (status_code
!= 200) {
1172 /* XXXX020 This warning tends to freak out clients who get a 403. */
1174 "Received http status code %d (%s) from server "
1175 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1176 status_code
, escaped(reason
), conn
->_base
.address
,
1177 conn
->_base
.port
, conn
->requested_resource
);
1178 tor_free(body
); tor_free(headers
); tor_free(reason
);
1179 connection_dir_download_networkstatus_failed(conn
, status_code
);
1182 note_request(was_compressed
?"dl/status.z":"dl/status", orig_len
);
1183 if (conn
->requested_resource
&&
1184 !strcmpstart(conn
->requested_resource
,"fp/")) {
1185 source
= NS_FROM_DIR_BY_FP
;
1186 which
= smartlist_create();
1187 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
1189 } else if (conn
->requested_resource
&&
1190 !strcmpstart(conn
->requested_resource
, "all")) {
1191 source
= NS_FROM_DIR_ALL
;
1192 which
= smartlist_create();
1193 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1194 trusted_dir_server_t
*, ds
,
1196 char *hex
= tor_malloc(HEX_DIGEST_LEN
+1);
1197 base16_encode(hex
, HEX_DIGEST_LEN
+1, ds
->digest
, DIGEST_LEN
);
1198 smartlist_add(which
, hex
);
1201 /* Can we even end up here? -- weasel*/
1202 source
= NS_FROM_DIR_BY_FP
;
1203 log_warn(LD_BUG
, "We received a networkstatus but we didn't ask "
1204 "for it by fp, nor did we ask for all.");
1208 char *next
= strstr(cp
, "\nnetwork-status-version");
1211 /* learn from it, and then remove it from 'which' */
1212 if (router_set_networkstatus(cp
, now
, source
, which
)<0)
1220 routers_update_all_from_networkstatus(now
); /*launches router downloads*/
1221 directory_info_has_arrived(now
, 0);
1223 if (smartlist_len(which
)) {
1224 dir_networkstatus_download_failed(which
, status_code
);
1226 SMARTLIST_FOREACH(which
, char *, s
, tor_free(s
));
1227 smartlist_free(which
);
1231 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1232 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
1233 int was_ei
= conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
;
1234 smartlist_t
*which
= NULL
;
1235 int n_asked_for
= 0;
1236 log_info(LD_DIR
,"Received %s (size %d) from server '%s:%d'",
1237 was_ei
? "extra server info" : "server info",
1238 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1240 note_request(was_compressed
?"dl/extra.z":"dl/extra", orig_len
);
1242 note_request(was_compressed
?"dl/server.z":"dl/server", orig_len
);
1243 if (conn
->requested_resource
&&
1244 !strcmpstart(conn
->requested_resource
,"d/")) {
1245 which
= smartlist_create();
1246 dir_split_resource_into_fingerprints(conn
->requested_resource
+2,
1248 n_asked_for
= smartlist_len(which
);
1250 if (status_code
!= 200) {
1251 int dir_okay
= status_code
== 404 ||
1252 (status_code
== 400 && !strcmp(reason
, "Servers unavailable."));
1253 /* 404 means that it didn't have them; no big deal.
1254 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1255 /* XXXX020 This warning tends to freak out clients who get a 403. */
1256 log_fn(dir_okay
? LOG_INFO
: LOG_WARN
, LD_DIR
,
1257 "Received http status code %d (%s) from server '%s:%d' "
1258 "while fetching \"/tor/server/%s\". I'll try again soon.",
1259 status_code
, escaped(reason
), conn
->_base
.address
,
1260 conn
->_base
.port
, conn
->requested_resource
);
1262 connection_dir_download_routerdesc_failed(conn
);
1264 dir_routerdesc_download_failed(which
, status_code
, was_ei
);
1265 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1266 smartlist_free(which
);
1268 tor_free(body
); tor_free(headers
); tor_free(reason
);
1269 return dir_okay
? 0 : -1;
1271 /* Learn the routers, assuming we requested by fingerprint or "all"
1274 * We use "authority" to fetch our own descriptor for
1275 * testing, and to fetch bridge descriptors for bootstrapping. Ignore
1276 * the output of "authority" requests unless we are using bridges,
1277 * since otherwise they'll be the response from reachability tests,
1278 * and we don't really want to add that to our routerlist. */
1279 if (which
|| (conn
->requested_resource
&&
1280 (!strcmpstart(conn
->requested_resource
, "all") ||
1281 (!strcmpstart(conn
->requested_resource
, "authority") &&
1282 get_options()->UseBridges
)))) {
1283 /* as we learn from them, we remove them from 'which' */
1285 router_load_extrainfo_from_string(body
, NULL
, SAVED_NOWHERE
, which
);
1287 router_load_routers_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1288 conn
->router_purpose
);
1289 directory_info_has_arrived(now
, 0);
1292 if (which
) { /* mark remaining ones as failed */
1293 log_info(LD_DIR
, "Received %d/%d routers requested from %s:%d",
1294 n_asked_for
-smartlist_len(which
), n_asked_for
,
1295 conn
->_base
.address
, (int)conn
->_base
.port
);
1296 if (smartlist_len(which
)) {
1297 dir_routerdesc_download_failed(which
, status_code
, was_ei
);
1299 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1300 smartlist_free(which
);
1302 if (directory_conn_is_self_reachability_test(conn
))
1303 router_dirport_found_reachable();
1306 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_DIR
) {
1307 switch (status_code
) {
1310 trusted_dir_server_t
*ds
=
1311 router_get_trusteddirserver_by_digest(conn
->identity_digest
);
1312 smartlist_t
*servers
;
1313 log_info(LD_GENERAL
,"eof (status 200) after uploading server "
1314 "descriptor: finished.");
1315 control_event_server_status(
1316 LOG_NOTICE
, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1317 conn
->_base
.address
, conn
->_base
.port
);
1319 ds
->has_accepted_serverdesc
= 1;
1320 servers
= router_get_trusted_dir_servers();
1321 SMARTLIST_FOREACH(servers
, trusted_dir_server_t
*, d
, {
1322 if ((d
->type
& (V1_AUTHORITY
|V2_AUTHORITY
)) &&
1323 !d
->has_accepted_serverdesc
) {
1329 control_event_server_status(LOG_NOTICE
, "GOOD_SERVER_DESCRIPTOR");
1333 log_warn(LD_GENERAL
,"http status 400 (%s) response from "
1334 "dirserver '%s:%d'. Please correct.",
1335 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1336 control_event_server_status(LOG_WARN
,
1337 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1338 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1341 log_warn(LD_GENERAL
,
1342 "http status 403 (%s) response from dirserver "
1343 "'%s:%d'. Is your clock skewed? Have you mailed us your key "
1344 "fingerprint? Are you using the right key? Are you using a "
1345 "private IP address? See http://tor.eff.org/doc/"
1346 "tor-doc-server.html",escaped(reason
), conn
->_base
.address
,
1348 control_event_server_status(LOG_WARN
,
1349 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1350 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1353 log_warn(LD_GENERAL
,
1354 "http status %d (%s) reason unexpected while uploading "
1355 "descriptor to server '%s:%d').",
1356 status_code
, escaped(reason
), conn
->_base
.address
,
1360 /* return 0 in all cases, since we don't want to mark any
1361 * dirservers down just because they don't like us. */
1364 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
1365 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1367 (int)body_len
, status_code
, escaped(reason
));
1368 switch (status_code
) {
1370 if (rend_cache_store(body
, body_len
, 0) < 0) {
1371 log_warn(LD_REND
,"Failed to store rendezvous descriptor.");
1372 /* alice's ap_stream will notice when connection_mark_for_close
1375 /* success. notify pending connections about this. */
1376 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1377 rend_client_desc_here(conn
->rend_query
);
1381 /* not there. pending connections will be notified when
1382 * connection_mark_for_close cleans it up. */
1386 "http status 400 (%s). Dirserver didn't like our "
1387 "rendezvous query?", escaped(reason
));
1390 log_warn(LD_REND
,"http status %d (%s) response unexpected while "
1391 "fetching hidden service descriptor (server '%s:%d').",
1392 status_code
, escaped(reason
), conn
->_base
.address
,
1398 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC
) {
1399 switch (status_code
) {
1402 "Uploading rendezvous descriptor: finished with status "
1403 "200 (%s)", escaped(reason
));
1406 log_warn(LD_REND
,"http status 400 (%s) response from dirserver "
1407 "'%s:%d'. Malformed rendezvous descriptor?",
1408 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1411 log_warn(LD_REND
,"http status %d (%s) response unexpected (server "
1413 status_code
, escaped(reason
), conn
->_base
.address
,
1418 tor_free(body
); tor_free(headers
); tor_free(reason
);
1422 /** Called when a directory connection reaches EOF */
1424 connection_dir_reached_eof(dir_connection_t
*conn
)
1427 if (conn
->_base
.state
!= DIR_CONN_STATE_CLIENT_READING
) {
1428 log_info(LD_HTTP
,"conn reached eof, not reading. [state=%d] Closing.",
1430 connection_close_immediate(TO_CONN(conn
)); /* error: give up on flushing */
1431 connection_mark_for_close(TO_CONN(conn
));
1435 retval
= connection_dir_client_reached_eof(conn
);
1436 if (retval
== 0) /* success */
1437 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_FINISHED
;
1438 connection_mark_for_close(TO_CONN(conn
));
1442 /** If any directory object is arriving, and it's over 10MB large, we're
1443 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
1444 * ask for more than 96 router descriptors at a time.)
1446 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
1448 /** Read handler for directory connections. (That's connections <em>to</em>
1449 * directory servers and connections <em>at</em> directory servers.)
1452 connection_dir_process_inbuf(dir_connection_t
*conn
)
1455 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
1457 /* Directory clients write, then read data until they receive EOF;
1458 * directory servers read data until they get an HTTP command, then
1459 * write their response (when it's finished flushing, they mark for
1463 /* If we're on the dirserver side, look for a command. */
1464 if (conn
->_base
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
1465 if (directory_handle_command(conn
) < 0) {
1466 connection_mark_for_close(TO_CONN(conn
));
1472 if (buf_datalen(conn
->_base
.inbuf
) > MAX_DIRECTORY_OBJECT_SIZE
) {
1473 log_warn(LD_HTTP
, "Too much data received from directory connection: "
1474 "denial of service attempt, or you need to upgrade?");
1475 connection_mark_for_close(TO_CONN(conn
));
1479 if (!conn
->_base
.inbuf_reached_eof
)
1480 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
1484 /** Create an http response for the client <b>conn</b> out of
1485 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
1488 write_http_status_line(dir_connection_t
*conn
, int status
,
1489 const char *reason_phrase
)
1492 if (tor_snprintf(buf
, sizeof(buf
), "HTTP/1.0 %d %s\r\n\r\n",
1493 status
, reason_phrase
? reason_phrase
: "OK") < 0) {
1494 log_warn(LD_BUG
,"status line too long.");
1497 connection_write_to_buf(buf
, strlen(buf
), TO_CONN(conn
));
1500 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
1501 * with <b>type</b> as the Content-Type.
1503 * If <b>length</b> is nonnegative, it is the Content-Length.
1504 * If <b>encoding</b> is provided, it is the Content-Encoding.
1505 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
1506 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
1508 write_http_response_header(dir_connection_t
*conn
, ssize_t length
,
1509 const char *type
, const char *encoding
,
1512 char date
[RFC1123_TIME_LEN
+1];
1515 time_t now
= time(NULL
);
1520 format_rfc1123_time(date
, now
);
1522 tor_snprintf(cp
, sizeof(tmp
),
1523 "HTTP/1.0 200 OK\r\nDate: %s\r\nContent-Type: %s\r\n",
1526 if (!is_internal_IP(conn
->_base
.addr
, 0)) {
1527 /* Don't report the source address for a localhost/private connection. */
1528 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1529 X_ADDRESS_HEADER
"%s\r\n", conn
->_base
.address
);
1533 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1534 "Content-Encoding: %s\r\n", encoding
);
1538 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1539 "Content-Length: %ld\r\n", (long)length
);
1542 if (cache_lifetime
> 0) {
1543 char expbuf
[RFC1123_TIME_LEN
+1];
1544 format_rfc1123_time(expbuf
, now
+ cache_lifetime
);
1545 /* We could say 'Cache-control: max-age=%d' here if we start doing
1547 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1548 "Expires: %s\r\n", expbuf
);
1551 /* We could say 'Cache-control: no-cache' here if we start doing
1553 strlcpy(cp
, "Pragma: no-cache\r\n", sizeof(tmp
)-(cp
-tmp
));
1556 if (sizeof(tmp
)-(cp
-tmp
) > 3)
1557 memcpy(cp
, "\r\n", 3);
1560 connection_write_to_buf(tmp
, strlen(tmp
), TO_CONN(conn
));
1563 /** Helper function: return 1 if there are any dir conns of purpose
1564 * <b>purpose</b> that are going elsewhere than our own ORPort/Dirport.
1568 already_fetching_directory(int purpose
)
1570 smartlist_t
*conns
= get_connection_array();
1571 SMARTLIST_FOREACH(conns
, connection_t
*, conn
,
1573 if (conn
->type
== CONN_TYPE_DIR
&&
1574 conn
->purpose
== purpose
&&
1575 !conn
->marked_for_close
&&
1576 !router_digest_is_me(TO_DIR_CONN(conn
)->identity_digest
))
1582 #ifdef INSTRUMENT_DOWNLOADS
1583 /** Map used to keep track of how much data we've up/downloaded in what kind
1584 * of request. Maps from request type to pointer to uint64_t. */
1585 static strmap_t
*request_bytes_map
= NULL
;
1587 /** Called when we just transmitted or received <b>bytes</b> worth of data
1588 * because of a request of type <b>key</b> (an arbitrary identifier): adds
1589 * <b>bytes</b> to the total associated with key. */
1591 note_request(const char *key
, size_t bytes
)
1594 if (!request_bytes_map
)
1595 request_bytes_map
= strmap_new();
1597 n
= strmap_get(request_bytes_map
, key
);
1599 n
= tor_malloc_zero(sizeof(uint64_t));
1600 strmap_set(request_bytes_map
, key
, n
);
1605 /** Return a newly allocated string holding a summary of bytes used per
1608 directory_dump_request_log(void)
1613 strmap_iter_t
*iter
;
1615 if (!request_bytes_map
)
1616 request_bytes_map
= strmap_new();
1618 lines
= smartlist_create();
1620 for (iter
= strmap_iter_init(request_bytes_map
);
1621 !strmap_iter_done(iter
);
1622 iter
= strmap_iter_next(request_bytes_map
, iter
)) {
1626 strmap_iter_get(iter
, &key
, &val
);
1628 tor_snprintf(tmp
, sizeof(tmp
), "%s "U64_FORMAT
"\n",
1629 key
, U64_PRINTF_ARG(*n
));
1630 smartlist_add(lines
, tor_strdup(tmp
));
1632 smartlist_sort_strings(lines
);
1633 result
= smartlist_join_strings(lines
, "", 0, NULL
);
1634 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
1635 smartlist_free(lines
);
1640 note_request(const char *key
, size_t bytes
)
1647 directory_dump_request_log(void)
1649 return tor_strdup("Not supported.");
1653 /** Helper function: called when a dirserver gets a complete HTTP GET
1654 * request. Look for a request for a directory or for a rendezvous
1655 * service descriptor. On finding one, write a response into
1656 * conn-\>outbuf. If the request is unrecognized, send a 400.
1657 * Always return 0. */
1659 directory_handle_command_get(dir_connection_t
*conn
, const char *headers
,
1660 const char *body
, size_t body_len
)
1664 or_options_t
*options
= get_options();
1665 time_t if_modified_since
= 0;
1668 /* We ignore the body of a GET request. */
1672 log_debug(LD_DIRSERV
,"Received GET command.");
1674 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
1676 if (parse_http_url(headers
, &url
) < 0) {
1677 write_http_status_line(conn
, 400, "Bad request");
1680 if ((header
= http_get_header(headers
, "If-Modified-Since: "))) {
1682 if (parse_http_time(header
, &tm
) == 0) {
1683 if_modified_since
= tor_timegm(&tm
);
1685 /* The correct behavior on a malformed If-Modified-Since header is to
1686 * act as if no If-Modified-Since header had been given. */
1689 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
1691 if (!strcmp(url
,"/tor/") || !strcmp(url
,"/tor/dir.z")) { /* dir fetch */
1692 int deflated
= !strcmp(url
,"/tor/dir.z");
1693 cached_dir_t
*d
= dirserv_get_directory();
1696 log_notice(LD_DIRSERV
,"Client asked for the mirrored directory, but we "
1697 "don't have a good one yet. Sending 503 Dir not available.");
1698 write_http_status_line(conn
, 503, "Directory unavailable");
1699 /* try to get a new one now */
1700 if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR
) &&
1701 !should_delay_dir_fetches(options
))
1702 directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR
, NULL
, 1);
1706 if (d
->published
< if_modified_since
) {
1707 write_http_status_line(conn
, 304, "Not modified");
1712 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
1714 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
1715 log_info(LD_DIRSERV
,
1716 "Client asked for the mirrored directory, but we've been "
1717 "writing too many bytes lately. Sending 503 Dir busy.");
1718 write_http_status_line(conn
, 503, "Directory busy, try again later");
1723 note_request(url
, dlen
);
1726 log_debug(LD_DIRSERV
,"Dumping %sdirectory to client.",
1727 deflated
?"deflated ":"");
1728 write_http_response_header(conn
, dlen
,
1729 deflated
?"application/octet-stream":"text/plain",
1730 deflated
?"deflate":"identity",
1731 FULL_DIR_CACHE_LIFETIME
);
1732 conn
->cached_dir
= d
;
1733 conn
->cached_dir_offset
= 0;
1735 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
1738 /* Prime the connection with some data. */
1739 conn
->dir_spool_src
= DIR_SPOOL_CACHED_DIR
;
1740 connection_dirserv_flushed_some(conn
);
1744 if (!strcmp(url
,"/tor/running-routers") ||
1745 !strcmp(url
,"/tor/running-routers.z")) { /* running-routers fetch */
1746 int deflated
= !strcmp(url
,"/tor/running-routers.z");
1747 cached_dir_t
*d
= dirserv_get_runningrouters();
1749 write_http_status_line(conn
, 503, "Directory unavailable");
1750 /* try to get a new one now */
1751 if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST
) &&
1752 !should_delay_dir_fetches(options
))
1753 directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST
, NULL
, 1);
1757 if (d
->published
< if_modified_since
) {
1758 write_http_status_line(conn
, 304, "Not modified");
1762 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
1764 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
1765 log_info(LD_DIRSERV
,
1766 "Client asked for running-routers, but we've been "
1767 "writing too many bytes lately. Sending 503 Dir busy.");
1768 write_http_status_line(conn
, 503, "Directory busy, try again later");
1772 note_request(url
, dlen
);
1774 write_http_response_header(conn
, dlen
,
1775 deflated
?"application/octet-stream":"text/plain",
1776 deflated
?"deflate":"identity",
1777 RUNNINGROUTERS_CACHE_LIFETIME
);
1778 connection_write_to_buf(deflated
? d
->dir_z
: d
->dir
, dlen
, TO_CONN(conn
));
1782 if (!strcmpstart(url
,"/tor/status/")) {
1783 /* v2 network status fetch. */
1784 size_t url_len
= strlen(url
);
1785 int deflated
= !strcmp(url
+url_len
-2, ".z");
1786 smartlist_t
*dir_fps
= smartlist_create();
1787 const char *request_type
= NULL
;
1788 const char *key
= url
+ strlen("/tor/status/");
1790 url
[url_len
-2] = '\0';
1791 dirserv_get_networkstatus_v2_fingerprints(dir_fps
, key
);
1792 if (!strcmpstart(key
, "fp/"))
1793 request_type
= deflated
?"/tor/status/fp.z":"/tor/status/fp";
1794 else if (!strcmpstart(key
, "authority"))
1795 request_type
= deflated
?"/tor/status/authority.z":
1796 "/tor/status/authority";
1797 else if (!strcmpstart(key
, "all"))
1798 request_type
= deflated
?"/tor/status/all.z":"/tor/status/all";
1800 request_type
= "/tor/status/?";
1802 if (!smartlist_len(dir_fps
)) { /* we failed to create/cache cp */
1803 write_http_status_line(conn
, 503, "Network status object unavailable");
1804 smartlist_free(dir_fps
);
1807 if (dirserv_statuses_are_old(dir_fps
, if_modified_since
)) {
1808 write_http_status_line(conn
, 304, "Not modified");
1809 smartlist_free(dir_fps
);
1813 dlen
= dirserv_estimate_data_size(dir_fps
, 0, deflated
);
1814 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
1815 log_info(LD_DIRSERV
,
1816 "Client asked for network status lists, but we've been "
1817 "writing too many bytes lately. Sending 503 Dir busy.");
1818 write_http_status_line(conn
, 503, "Directory busy, try again later");
1819 SMARTLIST_FOREACH(dir_fps
, char *, fp
, tor_free(fp
));
1820 smartlist_free(dir_fps
);
1824 // note_request(request_type,dlen);
1825 (void) request_type
;
1826 write_http_response_header(conn
, -1,
1827 deflated
?"application/octet_stream":"text/plain",
1828 deflated
?"deflate":NULL
,
1829 smartlist_len(dir_fps
) == 1 ? NETWORKSTATUS_CACHE_LIFETIME
:0);
1830 conn
->fingerprint_stack
= dir_fps
;
1832 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
1834 /* Prime the connection with some data. */
1835 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
1836 connection_dirserv_flushed_some(conn
);
1841 if (!strcmpstart(url
,"/tor/server/") ||
1842 !strcmpstart(url
,"/tor/extra/")) {
1843 char *url_mem
= url
;
1844 size_t url_len
= strlen(url
);
1845 int deflated
= !strcmp(url
+url_len
-2, ".z");
1848 const char *request_type
= NULL
;
1849 int cache_lifetime
= 0;
1850 int is_extra
= !strcmpstart(url
,"/tor/extra/");
1852 url
[url_len
-2] = '\0';
1853 url
+= is_extra
? strlen("/tor/extra/") : strlen("/tor/server/");
1854 conn
->fingerprint_stack
= smartlist_create();
1855 res
= dirserv_get_routerdesc_fingerprints(conn
->fingerprint_stack
, url
,
1858 if (!strcmpstart(url
, "fp/")) {
1859 request_type
= deflated
?"/tor/server/fp.z":"/tor/server/fp";
1860 if (smartlist_len(conn
->fingerprint_stack
) == 1)
1861 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
1862 } else if (!strcmpstart(url
, "authority")) {
1863 request_type
= deflated
?"/tor/server/authority.z":
1864 "/tor/server/authority";
1865 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
1866 } else if (!strcmpstart(url
, "all")) {
1867 request_type
= deflated
?"/tor/server/all.z":"/tor/server/all";
1868 cache_lifetime
= FULL_DIR_CACHE_LIFETIME
;
1869 } else if (!strcmpstart(url
, "d/")) {
1870 request_type
= deflated
?"/tor/server/d.z":"/tor/server/d";
1871 if (smartlist_len(conn
->fingerprint_stack
) == 1)
1872 cache_lifetime
= ROUTERDESC_BY_DIGEST_CACHE_LIFETIME
;
1874 request_type
= "/tor/server/?";
1876 (void) request_type
; /* usable for note_request. */
1877 if (!strcmpstart(url
, "d/"))
1878 conn
->dir_spool_src
=
1879 is_extra
? DIR_SPOOL_EXTRA_BY_DIGEST
: DIR_SPOOL_SERVER_BY_DIGEST
;
1881 conn
->dir_spool_src
=
1882 is_extra
? DIR_SPOOL_EXTRA_BY_FP
: DIR_SPOOL_SERVER_BY_FP
;
1885 write_http_status_line(conn
, 404, msg
);
1887 dlen
= dirserv_estimate_data_size(conn
->fingerprint_stack
,
1889 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
1890 log_info(LD_DIRSERV
,
1891 "Client asked for server descriptors, but we've been "
1892 "writing too many bytes lately. Sending 503 Dir busy.");
1893 write_http_status_line(conn
, 503, "Directory busy, try again later");
1896 write_http_response_header(conn
, -1,
1897 deflated
?"application/octet_stream":"text/plain",
1898 deflated
?"deflate":NULL
, cache_lifetime
);
1900 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
1901 /* Prime the connection with some data. */
1902 connection_dirserv_flushed_some(conn
);
1907 if (options
->HSAuthoritativeDir
&&
1908 (!strcmpstart(url
,"/tor/rendezvous/") ||
1909 !strcmpstart(url
,"/tor/rendezvous1/"))) {
1910 /* rendezvous descriptor fetch */
1913 int versioned
= !strcmpstart(url
,"/tor/rendezvous1/");
1914 const char *query
= url
+strlen("/tor/rendezvous/")+(versioned
?1:0);
1916 switch (rend_cache_lookup_desc(query
, versioned
?-1:0, &descp
, &desc_len
)) {
1918 write_http_response_header(conn
, desc_len
, "application/octet-stream",
1920 note_request("/tor/rendezvous?/", desc_len
);
1921 /* need to send descp separately, because it may include nuls */
1922 connection_write_to_buf(descp
, desc_len
, TO_CONN(conn
));
1923 /* report successful fetch to statistic */
1924 if (options
->HSAuthorityRecordStats
) {
1925 hs_usage_note_fetch_total(query
, time(NULL
));
1926 hs_usage_note_fetch_successful(query
, time(NULL
));
1929 case 0: /* well-formed but not present */
1930 write_http_status_line(conn
, 404, "Not found");
1931 /* report (unsuccessful) fetch to statistic */
1932 if (options
->HSAuthorityRecordStats
) {
1933 hs_usage_note_fetch_total(query
, time(NULL
));
1936 case -1: /* not well-formed */
1937 write_http_status_line(conn
, 400, "Bad request");
1944 if (!strcmpstart(url
,"/tor/bytes.txt")) {
1945 char *bytes
= directory_dump_request_log();
1946 size_t len
= strlen(bytes
);
1947 write_http_response_header(conn
, len
, "text/plain", NULL
, 0);
1948 connection_write_to_buf(bytes
, len
, TO_CONN(conn
));
1954 if (!strcmp(url
,"/tor/robots.txt")) { /* /robots.txt will have been
1955 rewritten to /tor/robots.txt */
1956 char robots
[] = "User-agent: *\r\nDisallow: /\r\n";
1957 size_t len
= strlen(robots
);
1958 write_http_response_header(conn
, len
, "text/plain", NULL
,
1959 ROBOTS_CACHE_LIFETIME
);
1960 connection_write_to_buf(robots
, len
, TO_CONN(conn
));
1965 if (!strcmp(url
,"/tor/dir-all-weaselhack") &&
1966 (conn
->_base
.addr
== 0x7f000001ul
) &&
1967 authdir_mode_v2(options
) &&
1968 !authdir_mode_bridge(options
)) {
1969 /* until weasel rewrites his scripts at noreply */
1970 char *new_directory
=NULL
;
1972 if (dirserv_dump_directory_to_string(&new_directory
,
1973 get_identity_key(), 1)) {
1974 log_warn(LD_BUG
, "Error creating full v1 directory.");
1975 tor_free(new_directory
);
1976 write_http_status_line(conn
, 503, "Directory unavailable");
1980 dlen
= strlen(new_directory
);
1982 write_http_response_header(conn
, dlen
, "text/plain", "identity", 0);
1984 connection_write_to_buf(new_directory
, dlen
, TO_CONN(conn
));
1985 tor_free(new_directory
);
1990 /* we didn't recognize the url */
1991 write_http_status_line(conn
, 404, "Not found");
1996 /** Helper function: called when a dirserver gets a complete HTTP POST
1997 * request. Look for an uploaded server descriptor or rendezvous
1998 * service descriptor. On finding one, process it and write a
1999 * response into conn-\>outbuf. If the request is unrecognized, send a
2000 * 400. Always return 0. */
2002 directory_handle_command_post(dir_connection_t
*conn
, const char *headers
,
2003 const char *body
, size_t body_len
)
2006 or_options_t
*options
= get_options();
2008 log_debug(LD_DIRSERV
,"Received POST command.");
2010 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
2012 if (!authdir_mode(options
)) {
2013 /* we just provide cached directories; we don't want to
2014 * receive anything. */
2015 write_http_status_line(conn
, 400, "Nonauthoritative directory does not "
2016 "accept posted server descriptors");
2020 if (parse_http_url(headers
, &url
) < 0) {
2021 write_http_status_line(conn
, 400, "Bad request");
2024 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2026 if (authdir_mode_handles_descs(options
) &&
2027 !strcmp(url
,"/tor/")) { /* server descriptor post */
2028 const char *msg
= NULL
;
2029 uint8_t purpose
= authdir_mode_bridge(options
) ?
2030 ROUTER_PURPOSE_CONTROLLER
: ROUTER_PURPOSE_GENERAL
;
2031 int r
= dirserv_add_multiple_descriptors(body
, purpose
, &msg
);
2034 dirserv_get_directory(); /* rebuild and write to disk */
2039 log_notice(LD_DIRSERV
,
2040 "Rejected router descriptor or extra-info from %s.",
2041 conn
->_base
.address
);
2042 /* malformed descriptor, or something wrong */
2043 write_http_status_line(conn
, 400, msg
);
2045 case 0: /* accepted but discarded */
2046 case 2: /* accepted */
2047 write_http_status_line(conn
, 200, msg
);
2053 if (options
->HSAuthoritativeDir
&&
2054 !strcmpstart(url
,"/tor/rendezvous/publish")) {
2055 /* rendezvous descriptor post */
2056 if (rend_cache_store(body
, body_len
, 1) < 0) {
2057 // char tmp[1024*2+1];
2058 log_fn(LOG_PROTOCOL_WARN
, LD_DIRSERV
,
2059 "Rejected rend descriptor (length %d) from %s.",
2060 (int)body_len
, conn
->_base
.address
);
2061 write_http_status_line(conn
, 400, "Invalid service descriptor rejected");
2063 write_http_status_line(conn
, 200, "Service descriptor stored");
2068 /* we didn't recognize the url */
2069 write_http_status_line(conn
, 404, "Not found");
2076 /** Called when a dirserver receives data on a directory connection;
2077 * looks for an HTTP request. If the request is complete, remove it
2078 * from the inbuf, try to process it; otherwise, leave it on the
2079 * buffer. Return a 0 on success, or -1 on error.
2082 directory_handle_command(dir_connection_t
*conn
)
2084 char *headers
=NULL
, *body
=NULL
;
2089 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2091 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
2092 &headers
, MAX_HEADERS_SIZE
,
2093 &body
, &body_len
, MAX_DIR_UL_SIZE
, 0)) {
2094 case -1: /* overflow */
2095 log_warn(LD_DIRSERV
,
2096 "Invalid input from address '%s'. Closing.",
2097 conn
->_base
.address
);
2100 log_debug(LD_DIRSERV
,"command not all here yet.");
2102 /* case 1, fall through */
2105 http_set_address_origin(headers
, TO_CONN(conn
));
2106 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
2108 if (!strncasecmp(headers
,"GET",3))
2109 r
= directory_handle_command_get(conn
, headers
, body
, body_len
);
2110 else if (!strncasecmp(headers
,"POST",4))
2111 r
= directory_handle_command_post(conn
, headers
, body
, body_len
);
2113 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
2114 "Got headers %s with unknown command. Closing.",
2119 tor_free(headers
); tor_free(body
);
2123 /** Write handler for directory connections; called when all data has
2124 * been flushed. Close the connection or wait for a response as
2128 connection_dir_finished_flushing(dir_connection_t
*conn
)
2131 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2133 switch (conn
->_base
.state
) {
2134 case DIR_CONN_STATE_CLIENT_SENDING
:
2135 log_debug(LD_DIR
,"client finished sending command.");
2136 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_READING
;
2137 connection_stop_writing(TO_CONN(conn
));
2139 case DIR_CONN_STATE_SERVER_WRITING
:
2140 log_debug(LD_DIRSERV
,"Finished writing server response. Closing.");
2141 connection_mark_for_close(TO_CONN(conn
));
2144 log_warn(LD_BUG
,"called in unexpected state %d.",
2146 tor_fragile_assert();
2152 /** Connected handler for directory connections: begin sending data to the
2155 connection_dir_finished_connecting(dir_connection_t
*conn
)
2158 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2159 tor_assert(conn
->_base
.state
== DIR_CONN_STATE_CONNECTING
);
2161 log_debug(LD_HTTP
,"Dir connection to router %s:%u established.",
2162 conn
->_base
.address
,conn
->_base
.port
);
2164 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
; /* start flushing conn */
2168 /** Called when one or more networkstatus fetches have failed (with uppercase
2169 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
2170 * failed once, unless they failed with status code 503. */
2172 dir_networkstatus_download_failed(smartlist_t
*failed
, int status_code
)
2174 if (status_code
== 503)
2176 SMARTLIST_FOREACH(failed
, const char *, fp
,
2178 char digest
[DIGEST_LEN
];
2179 trusted_dir_server_t
*dir
;
2180 base16_decode(digest
, DIGEST_LEN
, fp
, strlen(fp
));
2181 dir
= router_get_trusteddirserver_by_digest(digest
);
2184 ++dir
->n_networkstatus_failures
;
2188 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
2189 * fetches have failed (with uppercase fingerprints listed in
2190 * <b>failed</b>). */
2192 dir_routerdesc_download_failed(smartlist_t
*failed
, int status_code
,
2195 char digest
[DIGEST_LEN
];
2196 time_t now
= time(NULL
);
2197 int server
= server_mode(get_options()) && get_options()->DirPort
;
2198 SMARTLIST_FOREACH(failed
, const char *, cp
,
2200 download_status_t
*dls
= NULL
;
2201 base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
));
2202 if (was_extrainfo
) {
2203 signed_descriptor_t
*sd
=
2204 router_get_by_extrainfo_digest(digest
);
2206 dls
= &sd
->ei_dl_status
;
2208 local_routerstatus_t
*rs
=
2209 router_get_combined_status_by_descriptor_digest(digest
);
2211 dls
= &rs
->dl_status
;
2213 if (!dls
|| dls
->n_download_failures
>= MAX_ROUTERDESC_DOWNLOAD_FAILURES
)
2215 if (status_code
!= 503 || server
)
2216 ++dls
->n_download_failures
;
2218 switch (dls
->n_download_failures
) {
2219 case 0: dls
->next_attempt_at
= 0; break;
2220 case 1: dls
->next_attempt_at
= 0; break;
2221 case 2: dls
->next_attempt_at
= 0; break;
2222 case 3: dls
->next_attempt_at
= now
+60; break;
2223 case 4: dls
->next_attempt_at
= now
+60; break;
2224 case 5: dls
->next_attempt_at
= now
+60*2; break;
2225 case 6: dls
->next_attempt_at
= now
+60*5; break;
2226 case 7: dls
->next_attempt_at
= now
+60*15; break;
2227 default: dls
->next_attempt_at
= TIME_MAX
; break;
2230 switch (dls
->n_download_failures
) {
2231 case 0: dls
->next_attempt_at
= 0; break;
2232 case 1: dls
->next_attempt_at
= 0; break;
2233 case 2: dls
->next_attempt_at
= now
+60; break;
2234 case 3: dls
->next_attempt_at
= now
+60*5; break;
2235 case 4: dls
->next_attempt_at
= now
+60*10; break;
2236 default: dls
->next_attempt_at
= TIME_MAX
; break;
2239 if (dls
->next_attempt_at
== 0)
2240 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again immediately.",
2241 cp
, (int)dls
->n_download_failures
);
2242 else if (dls
->next_attempt_at
< TIME_MAX
)
2243 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again in %d seconds.",
2244 cp
, (int)dls
->n_download_failures
,
2245 (int)(dls
->next_attempt_at
-now
));
2247 log_debug(LD_DIR
, "%s failed %d time(s); Giving up for a while.",
2248 cp
, (int)dls
->n_download_failures
);
2251 /* No need to relaunch descriptor downloads here: we already do it
2252 * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
2255 /** Given a directory <b>resource</b> request, containing zero
2256 * or more strings separated by plus signs, followed optionally by ".z", store
2257 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
2258 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
2259 * decode_hex is true, then delete all elements that aren't hex digests, and
2260 * decode the rest. If sort_uniq is true, then sort the list and remove
2264 dir_split_resource_into_fingerprints(const char *resource
,
2265 smartlist_t
*fp_out
, int *compressed_out
,
2266 int decode_hex
, int sort_uniq
)
2268 smartlist_t
*fp_tmp
= smartlist_create();
2270 smartlist_split_string(fp_tmp
, resource
, "+", 0, 0);
2272 *compressed_out
= 0;
2273 if (smartlist_len(fp_tmp
)) {
2274 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
2275 size_t last_len
= strlen(last
);
2276 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
2277 last
[last_len
-2] = '\0';
2279 *compressed_out
= 1;
2284 char *cp
, *d
= NULL
;
2285 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
2286 cp
= smartlist_get(fp_tmp
, i
);
2287 if (strlen(cp
) != HEX_DIGEST_LEN
) {
2289 "Skipping digest %s with non-standard length.", escaped(cp
));
2290 smartlist_del_keeporder(fp_tmp
, i
--);
2293 d
= tor_malloc_zero(DIGEST_LEN
);
2294 if (base16_decode(d
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
)<0) {
2295 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
2296 smartlist_del_keeporder(fp_tmp
, i
--);
2299 smartlist_set(fp_tmp
, i
, d
);
2307 smartlist_t
*fp_tmp2
= smartlist_create();
2310 smartlist_sort_digests(fp_tmp
);
2312 smartlist_sort_strings(fp_tmp
);
2313 if (smartlist_len(fp_tmp
))
2314 smartlist_add(fp_tmp2
, smartlist_get(fp_tmp
, 0));
2315 for (i
= 1; i
< smartlist_len(fp_tmp
); ++i
) {
2316 char *cp
= smartlist_get(fp_tmp
, i
);
2317 char *last
= smartlist_get(fp_tmp2
, smartlist_len(fp_tmp2
)-1);
2319 if ((decode_hex
&& memcmp(cp
, last
, DIGEST_LEN
))
2320 || (!decode_hex
&& strcasecmp(cp
, last
)))
2321 smartlist_add(fp_tmp2
, cp
);
2325 smartlist_free(fp_tmp
);
2328 smartlist_add_all(fp_out
, fp_tmp
);
2329 smartlist_free(fp_tmp
);