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
)
234 if (prefer_authority
) {
235 /* only ask authdirservers, and don't ask myself */
236 rs
= router_pick_trusteddirserver(type
, 1, 1,
237 retry_if_no_servers
);
240 /* anybody with a non-zero dirport will do */
241 rs
= router_pick_directory_server(1, 1, type
,
242 retry_if_no_servers
);
245 if (dir_purpose
== DIR_PURPOSE_FETCH_DIR
)
247 else if (dir_purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
)
248 which
= "status list";
249 else if (dir_purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
)
250 which
= "network status";
251 else // if (dir_purpose == DIR_PURPOSE_FETCH_NETWORKSTATUS)
252 which
= "server descriptors";
254 "No router found for %s; falling back to dirserver list",
256 rs
= router_pick_trusteddirserver(type
, 1, 1,
257 retry_if_no_servers
);
259 directconn
= 0; /* last resort: try routing it via Tor */
264 /* Never use fascistfirewall; we're going via Tor. */
265 if (dir_purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
266 /* only ask hidserv authorities, any of them will do */
267 rs
= router_pick_trusteddirserver(HIDSERV_AUTHORITY
, 0, 0,
268 retry_if_no_servers
);
270 /* anybody with a non-zero dirport will do. Disregard firewalls. */
271 rs
= router_pick_directory_server(1, 0, type
,
272 retry_if_no_servers
);
273 /* If we have any hope of building an indirect conn, we know some router
274 * descriptors. If (rs==NULL), we can't build circuits anyway, so
275 * there's no point in falling back to the authorities in this case. */
280 directory_initiate_command_routerstatus(rs
, dir_purpose
,
281 ROUTER_PURPOSE_GENERAL
,
286 "While fetching directory info, "
287 "no running dirservers known. Will try again later. "
288 "(purpose %d)", dir_purpose
);
289 if (!purpose_needs_anonymity(dir_purpose
)) {
290 /* remember we tried them all and failed. */
291 directory_all_unreachable(time(NULL
));
296 /** Launch a new connection to the directory server <b>status</b> to
297 * upload or download a server or rendezvous
298 * descriptor. <b>dir_purpose</b> determines what
299 * kind of directory connection we're launching, and must be one of
300 * DIR_PURPOSE_{FETCH|UPLOAD}_{DIR|RENDDESC}. <b>router_purpose</b>
301 * specifies the descriptor purposes we have in mind (currently only
302 * used for FETCH_DIR).
304 * When uploading, <b>payload</b> and <b>payload_len</b> determine the content
305 * of the HTTP post. Otherwise, <b>payload</b> should be NULL.
307 * When fetching a rendezvous descriptor, <b>resource</b> is the service ID we
311 directory_initiate_command_routerstatus(routerstatus_t
*status
,
313 uint8_t router_purpose
,
314 int anonymized_connection
,
315 const char *resource
,
319 routerinfo_t
*router
;
320 char address_buf
[INET_NTOA_BUF_LEN
+1];
323 if ((router
= router_get_by_digest(status
->identity_digest
))) {
324 address
= router
->address
;
326 in
.s_addr
= htonl(status
->addr
);
327 tor_inet_ntoa(&in
, address_buf
, sizeof(address_buf
));
328 address
= address_buf
;
330 directory_initiate_command(address
, status
->addr
,
331 status
->or_port
, status
->dir_port
,
332 status
->version_supports_begindir
,
333 status
->identity_digest
,
334 dir_purpose
, router_purpose
,
335 anonymized_connection
, resource
,
336 payload
, payload_len
);
339 /** Return true iff <b>conn</b> is the client side of a directory connection
340 * we launched to ourself in order to determine the reachability of our
343 directory_conn_is_self_reachability_test(dir_connection_t
*conn
)
345 if (conn
->requested_resource
&&
346 !strcmpstart(conn
->requested_resource
,"authority")) {
347 routerinfo_t
*me
= router_get_my_routerinfo();
349 router_digest_is_me(conn
->identity_digest
) &&
350 me
->addr
== conn
->_base
.addr
&&
351 me
->dir_port
== conn
->_base
.port
)
357 /** Called when we are unable to complete the client's request to a directory
358 * server due to a network error: Mark the router as down and try again if
362 connection_dir_request_failed(dir_connection_t
*conn
)
364 if (directory_conn_is_self_reachability_test(conn
)) {
365 routerinfo_t
*me
= router_get_my_routerinfo();
367 control_event_server_status(LOG_WARN
,
368 "REACHABILITY_FAILED DIRADDRESS=%s:%d",
369 me
->address
, me
->dir_port
);
370 return; /* this was a test fetch. don't retry. */
372 router_set_status(conn
->identity_digest
, 0); /* don't try him again */
373 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
||
374 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
375 log_info(LD_DIR
, "Giving up on directory server at '%s:%d'; retrying",
376 conn
->_base
.address
, conn
->_base
.port
);
377 directory_get_from_dirserver(conn
->_base
.purpose
, NULL
,
378 0 /* don't retry_if_no_servers */);
379 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
380 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
381 conn
->_base
.address
);
382 connection_dir_download_networkstatus_failed(conn
, -1);
383 } else if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
384 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
385 log_info(LD_DIR
, "Giving up on directory server at '%s'; retrying",
386 conn
->_base
.address
);
387 connection_dir_download_routerdesc_failed(conn
);
391 /** Called when an attempt to download one or more network status
392 * documents on connection <b>conn</b> failed. Decide whether to
393 * retry the fetch now, later, or never.
396 connection_dir_download_networkstatus_failed(dir_connection_t
*conn
,
399 if (!conn
->requested_resource
) {
400 /* We never reached directory_send_command, which means that we never
401 * opened a network connection. Either we're out of sockets, or the
402 * network is down. Either way, retrying would be pointless. */
405 if (!strcmpstart(conn
->requested_resource
, "all")) {
406 /* We're a non-authoritative directory cache; try again. Ignore status
407 * code, since we don't want to keep trying forever in a tight loop
408 * if all the authorities are shutting us out. */
409 smartlist_t
*trusted_dirs
= router_get_trusted_dir_servers();
410 SMARTLIST_FOREACH(trusted_dirs
, trusted_dir_server_t
*, ds
,
411 ++ds
->n_networkstatus_failures
);
412 directory_get_from_dirserver(conn
->_base
.purpose
, "all.z",
413 0 /* don't retry_if_no_servers */);
414 } else if (!strcmpstart(conn
->requested_resource
, "fp/")) {
415 /* We were trying to download by fingerprint; mark them all as having
416 * failed, and possibly retry them later.*/
417 smartlist_t
*failed
= smartlist_create();
418 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
420 if (smartlist_len(failed
)) {
421 dir_networkstatus_download_failed(failed
, status_code
);
422 SMARTLIST_FOREACH(failed
, char *, cp
, tor_free(cp
));
424 smartlist_free(failed
);
428 /** Called when an attempt to download one or more router descriptors
429 * or extra-info documents on connection <b>conn</b> failed.
432 connection_dir_download_routerdesc_failed(dir_connection_t
*conn
)
434 /* No need to increment the failure count for routerdescs, since
435 * it's not their fault. */
437 /* No need to relaunch descriptor downloads here: we already do it
438 * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
439 tor_assert(conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
440 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
445 /** Helper for directory_initiate_command_(router|trusted_dir): send the
446 * command to a server whose address is <b>address</b>, whose IP is
447 * <b>addr</b>, whose directory port is <b>dir_port</b>, whose tor version
448 * <b>supports_begindir</b>, and whose identity key digest is
451 directory_initiate_command(const char *address
, uint32_t addr
,
452 uint16_t or_port
, uint16_t dir_port
,
453 int supports_begindir
, const char *digest
,
454 uint8_t dir_purpose
, uint8_t router_purpose
,
455 int anonymized_connection
, const char *resource
,
456 const char *payload
, size_t payload_len
)
458 dir_connection_t
*conn
;
459 or_options_t
*options
= get_options();
460 int want_to_tunnel
= options
->TunnelDirConns
&& supports_begindir
&&
461 !anonymized_connection
&& or_port
&&
462 fascist_firewall_allows_address_or(addr
, or_port
);
466 tor_assert(dir_port
);
469 log_debug(LD_DIR
, "anonymized %d, want_to_tunnel %d.",
470 anonymized_connection
, want_to_tunnel
);
472 switch (dir_purpose
) {
473 case DIR_PURPOSE_FETCH_DIR
:
474 log_debug(LD_DIR
,"initiating directory fetch");
476 case DIR_PURPOSE_FETCH_RENDDESC
:
477 log_debug(LD_DIR
,"initiating hidden-service descriptor fetch");
479 case DIR_PURPOSE_UPLOAD_DIR
:
480 log_debug(LD_OR
,"initiating server descriptor upload");
482 case DIR_PURPOSE_UPLOAD_RENDDESC
:
483 log_debug(LD_REND
,"initiating hidden-service descriptor upload");
485 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
486 log_debug(LD_DIR
,"initiating running-routers fetch");
488 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
489 log_debug(LD_DIR
,"initiating network-status fetch");
491 case DIR_PURPOSE_FETCH_SERVERDESC
:
492 log_debug(LD_DIR
,"initiating server descriptor fetch");
494 case DIR_PURPOSE_FETCH_EXTRAINFO
:
495 log_debug(LD_DIR
,"initiating extra-info fetch");
498 log_err(LD_BUG
, "Unrecognized directory connection purpose.");
502 conn
= TO_DIR_CONN(connection_new(CONN_TYPE_DIR
, AF_INET
));
504 /* set up conn so it's got all the data we need to remember */
505 conn
->_base
.addr
= addr
;
506 conn
->_base
.port
= want_to_tunnel
? or_port
: dir_port
;
507 conn
->_base
.address
= tor_strdup(address
);
508 memcpy(conn
->identity_digest
, digest
, DIGEST_LEN
);
510 conn
->_base
.purpose
= dir_purpose
;
511 conn
->router_purpose
= router_purpose
;
513 /* give it an initial state */
514 conn
->_base
.state
= DIR_CONN_STATE_CONNECTING
;
516 if (!anonymized_connection
&& !want_to_tunnel
) {
517 /* then we want to connect directly */
519 conn
->dirconn_direct
= 1;
520 if (options
->HttpProxy
) {
521 addr
= options
->HttpProxyAddr
;
522 dir_port
= options
->HttpProxyPort
;
525 switch (connection_connect(TO_CONN(conn
), conn
->_base
.address
, addr
,
528 connection_dir_request_failed(conn
); /* retry if we want */
529 connection_free(TO_CONN(conn
));
532 /* start flushing conn */
533 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
536 /* queue the command on the outbuf */
537 directory_send_command(conn
, dir_purpose
, 1, resource
,
538 payload
, payload_len
);
539 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
540 /* writable indicates finish, readable indicates broken link,
541 error indicates broken link in windowsland. */
543 } else { /* we want to connect via tor */
544 edge_connection_t
*linked_conn
;
545 /* make an AP connection
546 * populate it and add it at the right state
549 conn
->dirconn_direct
= 0;
551 connection_ap_make_link(conn
->_base
.address
, conn
->_base
.port
,
553 anonymized_connection
?
554 SOCKS_COMMAND_CONNECT
:
555 SOCKS_COMMAND_CONNECT_DIR
);
557 log_warn(LD_NET
,"Making tunnel to dirserver failed.");
558 connection_mark_for_close(TO_CONN(conn
));
561 connection_link_connections(TO_CONN(conn
), TO_CONN(linked_conn
));
563 if (connection_add(TO_CONN(conn
)) < 0) {
564 log_warn(LD_NET
,"Unable to add connection for link to dirserver.");
565 connection_mark_for_close(TO_CONN(conn
));
568 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
;
569 /* queue the command on the outbuf */
570 directory_send_command(conn
, dir_purpose
, 0, resource
,
571 payload
, payload_len
);
572 connection_watch_events(TO_CONN(conn
), EV_READ
| EV_WRITE
);
573 connection_start_reading(TO_CONN(linked_conn
));
577 /** Queue an appropriate HTTP command on conn-\>outbuf. The other args
578 * are as in directory_initiate_command.
581 directory_send_command(dir_connection_t
*conn
,
582 int purpose
, int direct
, const char *resource
,
583 const char *payload
, size_t payload_len
)
585 char proxystring
[256];
586 char proxyauthstring
[256];
587 char hoststring
[128];
590 const char *httpcommand
= NULL
;
594 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
596 tor_free(conn
->requested_resource
);
598 conn
->requested_resource
= tor_strdup(resource
);
600 /* come up with a string for which Host: we want */
601 if (conn
->_base
.port
== 80) {
602 strlcpy(hoststring
, conn
->_base
.address
, sizeof(hoststring
));
604 tor_snprintf(hoststring
, sizeof(hoststring
),"%s:%d",
605 conn
->_base
.address
, conn
->_base
.port
);
608 /* come up with some proxy lines, if we're using one. */
609 if (direct
&& get_options()->HttpProxy
) {
610 char *base64_authenticator
=NULL
;
611 const char *authenticator
= get_options()->HttpProxyAuthenticator
;
613 tor_snprintf(proxystring
, sizeof(proxystring
),"http://%s", hoststring
);
615 base64_authenticator
= alloc_http_authenticator(authenticator
);
616 if (!base64_authenticator
)
617 log_warn(LD_BUG
, "Encoding http authenticator failed");
619 if (base64_authenticator
) {
620 tor_snprintf(proxyauthstring
, sizeof(proxyauthstring
),
621 "\r\nProxy-Authorization: Basic %s",
622 base64_authenticator
);
623 tor_free(base64_authenticator
);
625 proxyauthstring
[0] = 0;
629 proxyauthstring
[0] = 0;
633 case DIR_PURPOSE_FETCH_DIR
:
634 tor_assert(!resource
);
635 tor_assert(!payload
);
637 url
= tor_strdup("/tor/dir.z");
639 case DIR_PURPOSE_FETCH_RUNNING_LIST
:
640 tor_assert(!resource
);
641 tor_assert(!payload
);
643 url
= tor_strdup("/tor/running-routers");
645 case DIR_PURPOSE_FETCH_NETWORKSTATUS
:
647 len
= strlen(resource
)+32;
648 url
= tor_malloc(len
);
649 tor_snprintf(url
, len
, "/tor/status/%s", resource
);
651 case DIR_PURPOSE_FETCH_SERVERDESC
:
653 len
= strlen(resource
)+32;
654 url
= tor_malloc(len
);
655 tor_snprintf(url
, len
, "/tor/server/%s", resource
);
657 case DIR_PURPOSE_FETCH_EXTRAINFO
:
659 len
= strlen(resource
)+32;
660 url
= tor_malloc(len
);
661 tor_snprintf(url
, len
, "/tor/extra/%s", resource
);
663 case DIR_PURPOSE_UPLOAD_DIR
:
664 tor_assert(!resource
);
666 httpcommand
= "POST";
667 url
= tor_strdup("/tor/");
669 case DIR_PURPOSE_FETCH_RENDDESC
:
670 tor_assert(resource
);
671 tor_assert(!payload
);
673 /* this must be true or we wouldn't be doing the lookup */
674 tor_assert(strlen(resource
) <= REND_SERVICE_ID_LEN
);
675 /* This breaks the function abstraction. */
676 strlcpy(conn
->rend_query
, resource
, sizeof(conn
->rend_query
));
679 /* Request the most recent versioned descriptor. */
680 // (XXXX We were going to switch this to fetch rendezvous1 descriptors,
681 // but that never got testing, and it wasn't a good design.)
682 len
= strlen(resource
)+32;
683 url
= tor_malloc(len
);
684 tor_snprintf(url
, len
, "/tor/rendezvous/%s", resource
);
686 case DIR_PURPOSE_UPLOAD_RENDDESC
:
687 tor_assert(!resource
);
689 httpcommand
= "POST";
690 url
= tor_strdup("/tor/rendezvous/publish");
697 if (strlen(proxystring
) + strlen(url
) >= 4096) {
699 "Squid does not like URLs longer than 4095 bytes, and this "
700 "one is %d bytes long: %s%s",
701 (int)(strlen(proxystring
) + strlen(url
)), proxystring
, url
);
704 tor_snprintf(request
, sizeof(request
), "%s %s", httpcommand
, proxystring
);
705 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
706 connection_write_to_buf(url
, strlen(url
), TO_CONN(conn
));
709 if (!strcmp(httpcommand
, "GET") && !payload
) {
710 tor_snprintf(request
, sizeof(request
),
711 " HTTP/1.0\r\nHost: %s%s\r\n\r\n",
715 tor_snprintf(request
, sizeof(request
),
716 " HTTP/1.0\r\nContent-Length: %lu\r\nHost: %s%s\r\n\r\n",
717 payload
? (unsigned long)payload_len
: 0,
721 connection_write_to_buf(request
, strlen(request
), TO_CONN(conn
));
724 /* then send the payload afterwards too */
725 connection_write_to_buf(payload
, payload_len
, TO_CONN(conn
));
729 /** Parse an HTTP request string <b>headers</b> of the form
731 * "\%s [http[s]://]\%s HTTP/1..."
733 * If it's well-formed, strdup the second \%s into *<b>url</b>, and
734 * nul-terminate it. If the url doesn't start with "/tor/", rewrite it
735 * so it does. Return 0.
736 * Otherwise, return -1.
739 parse_http_url(const char *headers
, char **url
)
741 char *s
, *start
, *tmp
;
743 s
= (char *)eat_whitespace_no_nl(headers
);
745 s
= (char *)find_whitespace(s
); /* get past GET/POST */
747 s
= (char *)eat_whitespace_no_nl(s
);
749 start
= s
; /* this is it, assuming it's valid */
750 s
= (char *)find_whitespace(start
);
753 /* tolerate the http[s] proxy style of putting the hostname in the url */
754 if (s
-start
>= 4 && !strcmpstart(start
,"http")) {
758 if (s
-tmp
>= 3 && !strcmpstart(tmp
,"://")) {
759 tmp
= strchr(tmp
+3, '/');
760 if (tmp
&& tmp
< s
) {
761 log_debug(LD_DIR
,"Skipping over 'http[s]://hostname' string");
767 if (s
-start
< 5 || strcmpstart(start
,"/tor/")) { /* need to rewrite it */
768 *url
= tor_malloc(s
- start
+ 5);
769 strlcpy(*url
,"/tor", s
-start
+5);
770 strlcat((*url
)+4, start
, s
-start
+1);
772 *url
= tor_strndup(start
, s
-start
);
777 /** Return a copy of the first HTTP header in <b>headers</b> whose key is
778 * <b>which</b>. The key should be given with a terminating colon and space;
779 * this function copies everything after, up to but not including the
780 * following \\r\\n. */
782 http_get_header(const char *headers
, const char *which
)
784 const char *cp
= headers
;
786 if (!strcmpstart(cp
, which
)) {
789 if ((eos
= strchr(cp
,'\r')))
790 return tor_strndup(cp
, eos
-cp
);
792 return tor_strdup(cp
);
794 cp
= strchr(cp
, '\n');
801 /** If <b>headers</b> indicates that a proxy was involved, then rewrite
802 * <b>conn</b>-\>address to describe our best guess of the address that
803 * originated this HTTP request. */
805 http_set_address_origin(const char *headers
, connection_t
*conn
)
809 fwd
= http_get_header(headers
, "Forwarded-For: ");
811 fwd
= http_get_header(headers
, "X-Forwarded-For: ");
814 if (!tor_inet_aton(fwd
, &in
) || is_internal_IP(ntohl(in
.s_addr
), 0)) {
815 log_debug(LD_DIR
, "Ignoring unrecognized or internal IP %s",
820 tor_free(conn
->address
);
821 conn
->address
= tor_strdup(fwd
);
826 /** Parse an HTTP response string <b>headers</b> of the form
828 * "HTTP/1.\%d \%d\%s\r\n...".
831 * If it's well-formed, assign the status code to *<b>code</b> and
832 * return 0. Otherwise, return -1.
834 * On success: If <b>date</b> is provided, set *date to the Date
835 * header in the http headers, or 0 if no such header is found. If
836 * <b>compression</b> is provided, set *<b>compression</b> to the
837 * compression method given in the Content-Encoding header, or 0 if no
838 * such header is found, or -1 if the value of the header is not
839 * recognized. If <b>reason</b> is provided, strdup the reason string
843 parse_http_response(const char *headers
, int *code
, time_t *date
,
844 compress_method_t
*compression
, char **reason
)
847 char datestr
[RFC1123_TIME_LEN
+1];
848 smartlist_t
*parsed_headers
;
852 while (TOR_ISSPACE(*headers
)) headers
++; /* tolerate leading whitespace */
854 if (sscanf(headers
, "HTTP/1.%d %d", &n1
, &n2
) < 2 ||
855 (n1
!= 0 && n1
!= 1) ||
856 (n2
< 100 || n2
>= 600)) {
857 log_warn(LD_HTTP
,"Failed to parse header %s",escaped(headers
));
862 parsed_headers
= smartlist_create();
863 smartlist_split_string(parsed_headers
, headers
, "\n",
864 SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, -1);
866 smartlist_t
*status_line_elements
= smartlist_create();
867 tor_assert(smartlist_len(parsed_headers
));
868 smartlist_split_string(status_line_elements
,
869 smartlist_get(parsed_headers
, 0),
870 " ", SPLIT_SKIP_SPACE
|SPLIT_IGNORE_BLANK
, 3);
871 tor_assert(smartlist_len(status_line_elements
) <= 3);
872 if (smartlist_len(status_line_elements
) == 3) {
873 *reason
= smartlist_get(status_line_elements
, 2);
874 smartlist_set(status_line_elements
, 2, NULL
); /* Prevent free */
876 SMARTLIST_FOREACH(status_line_elements
, char *, cp
, tor_free(cp
));
877 smartlist_free(status_line_elements
);
881 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
882 if (!strcmpstart(s
, "Date: ")) {
883 strlcpy(datestr
, s
+6, sizeof(datestr
));
884 /* This will do nothing on failure, so we don't need to check
885 the result. We shouldn't warn, since there are many other valid
886 date formats besides the one we use. */
887 parse_rfc1123_time(datestr
, date
);
892 const char *enc
= NULL
;
893 SMARTLIST_FOREACH(parsed_headers
, const char *, s
,
894 if (!strcmpstart(s
, "Content-Encoding: ")) {
897 if (!enc
|| !strcmp(enc
, "identity")) {
898 *compression
= NO_METHOD
;
899 } else if (!strcmp(enc
, "deflate") || !strcmp(enc
, "x-deflate")) {
900 *compression
= ZLIB_METHOD
;
901 } else if (!strcmp(enc
, "gzip") || !strcmp(enc
, "x-gzip")) {
902 *compression
= GZIP_METHOD
;
904 log_info(LD_HTTP
, "Unrecognized content encoding: %s. Trying to deal.",
906 *compression
= UNKNOWN_METHOD
;
909 SMARTLIST_FOREACH(parsed_headers
, char *, s
, tor_free(s
));
910 smartlist_free(parsed_headers
);
915 /** Return true iff <b>body</b> doesn't start with a plausible router or
916 * running-list or directory opening. This is a sign of possible compression.
919 body_is_plausible(const char *body
, size_t len
, int purpose
)
923 return 1; /* empty bodies don't need decompression */
926 if (purpose
!= DIR_PURPOSE_FETCH_RENDDESC
) {
927 if (!strcmpstart(body
,"router") ||
928 !strcmpstart(body
,"signed-directory") ||
929 !strcmpstart(body
,"network-status") ||
930 !strcmpstart(body
,"running-routers"))
933 if (!TOR_ISPRINT(body
[i
]) && !TOR_ISSPACE(body
[i
]))
942 /** We are a client, and we've finished reading the server's
943 * response. Parse and it and act appropriately.
945 * If we're still happy with using this directory server in the future, return
946 * 0. Otherwise return -1; and the caller should consider trying the request
949 * The caller will take care of marking the connection for close.
952 connection_dir_client_reached_eof(dir_connection_t
*conn
)
957 size_t body_len
=0, orig_len
=0;
959 time_t date_header
=0;
961 compress_method_t compression
;
964 int allow_partial
= (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
965 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
);
966 int was_compressed
=0;
967 time_t now
= time(NULL
);
969 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
970 &headers
, MAX_HEADERS_SIZE
,
971 &body
, &body_len
, MAX_DIR_DL_SIZE
,
973 case -1: /* overflow */
974 log_warn(LD_PROTOCOL
,
975 "'fetch' response too large (server '%s:%d'). Closing.",
976 conn
->_base
.address
, conn
->_base
.port
);
980 "'fetch' response not all here, but we're at eof. Closing.");
982 /* case 1, fall through */
986 if (parse_http_response(headers
, &status_code
, &date_header
,
987 &compression
, &reason
) < 0) {
988 log_warn(LD_HTTP
,"Unparseable headers (server '%s:%d'). Closing.",
989 conn
->_base
.address
, conn
->_base
.port
);
990 tor_free(body
); tor_free(headers
);
993 if (!reason
) reason
= tor_strdup("[no reason given]");
996 "Received response from directory server '%s:%d': %d %s",
997 conn
->_base
.address
, conn
->_base
.port
, status_code
,
1000 /* now check if it's got any hints for us about our IP address. */
1001 if (conn
->dirconn_direct
) {
1002 char *guess
= http_get_header(headers
, X_ADDRESS_HEADER
);
1004 router_new_address_suggestion(guess
);
1009 if (date_header
> 0) {
1010 /* The date header was written very soon after we sent our request,
1011 * so compute the skew as the difference between sending the request
1012 * and the date header. (We used to check now-date_header, but that's
1013 * inaccurate if we spend a lot of time downloading.)
1015 delta
= conn
->_base
.timestamp_lastwritten
- date_header
;
1016 if (abs(delta
)>ALLOW_DIRECTORY_TIME_SKEW
) {
1017 int trusted
= router_digest_is_trusted_dir(conn
->identity_digest
);
1018 log_fn(trusted
? LOG_WARN
: LOG_INFO
,
1020 "Received directory with skewed time (server '%s:%d'): "
1021 "we are %d minutes %s, or the directory is %d minutes %s.",
1022 conn
->_base
.address
, conn
->_base
.port
,
1023 abs(delta
)/60, delta
>0 ? "ahead" : "behind",
1024 abs(delta
)/60, delta
>0 ? "behind" : "ahead");
1025 skewed
= 1; /* don't check the recommended-versions line */
1026 control_event_general_status(trusted
? LOG_WARN
: LOG_NOTICE
,
1027 "CLOCK_SKEW SKEW=%d SOURCE=DIRSERV:%s:%d",
1028 delta
, conn
->_base
.address
, conn
->_base
.port
);
1030 log_debug(LD_HTTP
, "Time on received directory is within tolerance; "
1031 "we are %d seconds skewed. (That's okay.)", delta
);
1034 (void) skewed
; /* skewed isn't used yet. */
1036 if (status_code
== 503) {
1037 local_routerstatus_t
*rs
;
1038 trusted_dir_server_t
*ds
;
1039 log_info(LD_DIR
,"Received http status code %d (%s) from server "
1040 "'%s:%d'. I'll try again soon.",
1041 status_code
, escaped(reason
), conn
->_base
.address
,
1043 if ((rs
= router_get_combined_status_by_digest(conn
->identity_digest
)))
1044 rs
->last_dir_503_at
= now
;
1045 if ((ds
= router_get_trusteddirserver_by_digest(conn
->identity_digest
)))
1046 ds
->fake_status
.last_dir_503_at
= now
;
1048 tor_free(body
); tor_free(headers
); tor_free(reason
);
1052 plausible
= body_is_plausible(body
, body_len
, conn
->_base
.purpose
);
1053 if (compression
!= NO_METHOD
|| !plausible
) {
1054 char *new_body
= NULL
;
1056 compress_method_t guessed
= detect_compression_method(body
, body_len
);
1057 if (compression
== UNKNOWN_METHOD
|| guessed
!= compression
) {
1058 /* Tell the user if we don't believe what we're told about compression.*/
1059 const char *description1
, *description2
;
1060 if (compression
== ZLIB_METHOD
)
1061 description1
= "as deflated";
1062 else if (compression
== GZIP_METHOD
)
1063 description1
= "as gzipped";
1064 else if (compression
== NO_METHOD
)
1065 description1
= "as uncompressed";
1067 description1
= "with an unknown Content-Encoding";
1068 if (guessed
== ZLIB_METHOD
)
1069 description2
= "deflated";
1070 else if (guessed
== GZIP_METHOD
)
1071 description2
= "gzipped";
1072 else if (!plausible
)
1073 description2
= "confusing binary junk";
1075 description2
= "uncompressed";
1077 log_info(LD_HTTP
, "HTTP body from server '%s:%d' was labeled %s, "
1078 "but it seems to be %s.%s",
1079 conn
->_base
.address
, conn
->_base
.port
, description1
,
1081 (compression
>0 && guessed
>0)?" Trying both.":"");
1083 /* Try declared compression first if we can. */
1084 if (compression
== GZIP_METHOD
|| compression
== ZLIB_METHOD
)
1085 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, compression
,
1086 !allow_partial
, LOG_PROTOCOL_WARN
);
1087 /* Okay, if that didn't work, and we think that it was compressed
1088 * differently, try that. */
1090 (guessed
== GZIP_METHOD
|| guessed
== ZLIB_METHOD
) &&
1091 compression
!= guessed
)
1092 tor_gzip_uncompress(&new_body
, &new_len
, body
, body_len
, guessed
,
1093 !allow_partial
, LOG_PROTOCOL_WARN
);
1094 /* If we're pretty sure that we have a compressed directory, and
1095 * we didn't manage to uncompress it, then warn and bail. */
1096 if (!plausible
&& !new_body
) {
1097 log_fn(LOG_PROTOCOL_WARN
, LD_HTTP
,
1098 "Unable to decompress HTTP body (server '%s:%d').",
1099 conn
->_base
.address
, conn
->_base
.port
);
1100 tor_free(body
); tor_free(headers
); tor_free(reason
);
1111 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_DIR
) {
1112 /* fetch/process the directory to cache it. */
1113 log_info(LD_DIR
,"Received directory (size %d) from server '%s:%d'",
1114 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1115 if (status_code
!= 200) {
1116 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1117 "'%s:%d' while fetching directory. I'll try again soon.",
1118 status_code
, escaped(reason
), conn
->_base
.address
,
1120 tor_free(body
); tor_free(headers
); tor_free(reason
);
1123 if (router_parse_directory(body
) < 0) {
1124 log_notice(LD_DIR
,"I failed to parse the directory I fetched from "
1125 "'%s:%d'. Ignoring.", conn
->_base
.address
, conn
->_base
.port
);
1127 note_request(was_compressed
?"dl/dir.z":"dl/dir", orig_len
);
1130 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RUNNING_LIST
) {
1131 /* just update our list of running routers, if this list is new info */
1132 log_info(LD_DIR
,"Received running-routers list (size %d)", (int)body_len
);
1133 if (status_code
!= 200) {
1134 log_warn(LD_DIR
,"Received http status code %d (%s) from server "
1135 "'%s:%d' while fetching running-routers. I'll try again soon.",
1136 status_code
, escaped(reason
), conn
->_base
.address
,
1138 tor_free(body
); tor_free(headers
); tor_free(reason
);
1141 if (router_parse_runningrouters(body
)<0) {
1143 "Bad running-routers from server '%s:%d'. I'll try again soon.",
1144 conn
->_base
.address
, conn
->_base
.port
);
1145 tor_free(body
); tor_free(headers
); tor_free(reason
);
1148 note_request(was_compressed
?"dl/running-routers.z":
1149 "dl/running-routers", orig_len
);
1152 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_NETWORKSTATUS
) {
1153 smartlist_t
*which
= NULL
;
1154 networkstatus_source_t source
;
1156 log_info(LD_DIR
,"Received networkstatus objects (size %d) from server "
1157 "'%s:%d'",(int) body_len
, conn
->_base
.address
, conn
->_base
.port
);
1158 if (status_code
!= 200) {
1159 /* XXXX020 This warning tends to freak out clients who get a 403. */
1161 "Received http status code %d (%s) from server "
1162 "'%s:%d' while fetching \"/tor/status/%s\". I'll try again soon.",
1163 status_code
, escaped(reason
), conn
->_base
.address
,
1164 conn
->_base
.port
, conn
->requested_resource
);
1165 tor_free(body
); tor_free(headers
); tor_free(reason
);
1166 connection_dir_download_networkstatus_failed(conn
, status_code
);
1169 note_request(was_compressed
?"dl/status.z":"dl/status", orig_len
);
1170 if (conn
->requested_resource
&&
1171 !strcmpstart(conn
->requested_resource
,"fp/")) {
1172 source
= NS_FROM_DIR_BY_FP
;
1173 which
= smartlist_create();
1174 dir_split_resource_into_fingerprints(conn
->requested_resource
+3,
1176 } else if (conn
->requested_resource
&&
1177 !strcmpstart(conn
->requested_resource
, "all")) {
1178 source
= NS_FROM_DIR_ALL
;
1179 which
= smartlist_create();
1180 SMARTLIST_FOREACH(router_get_trusted_dir_servers(),
1181 trusted_dir_server_t
*, ds
,
1183 char *hex
= tor_malloc(HEX_DIGEST_LEN
+1);
1184 base16_encode(hex
, HEX_DIGEST_LEN
+1, ds
->digest
, DIGEST_LEN
);
1185 smartlist_add(which
, hex
);
1188 /* Can we even end up here? -- weasel*/
1189 source
= NS_FROM_DIR_BY_FP
;
1190 log_warn(LD_BUG
, "We received a networkstatus but we didn't ask "
1191 "for it by fp, nor did we ask for all.");
1195 char *next
= strstr(cp
, "\nnetwork-status-version");
1198 /* learn from it, and then remove it from 'which' */
1199 if (router_set_networkstatus(cp
, now
, source
, which
)<0)
1207 routers_update_all_from_networkstatus(now
); /*launches router downloads*/
1208 directory_info_has_arrived(now
, 0);
1210 if (smartlist_len(which
)) {
1211 dir_networkstatus_download_failed(which
, status_code
);
1213 SMARTLIST_FOREACH(which
, char *, s
, tor_free(s
));
1214 smartlist_free(which
);
1218 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_SERVERDESC
||
1219 conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
) {
1220 int was_ei
= conn
->_base
.purpose
== DIR_PURPOSE_FETCH_EXTRAINFO
;
1221 smartlist_t
*which
= NULL
;
1222 int n_asked_for
= 0;
1223 log_info(LD_DIR
,"Received %s (size %d) from server '%s:%d'",
1224 was_ei
? "server info" : "extra server info",
1225 (int)body_len
, conn
->_base
.address
, conn
->_base
.port
);
1227 note_request(was_compressed
?"dl/extra.z":"dl/extra", orig_len
);
1229 note_request(was_compressed
?"dl/server.z":"dl/server", orig_len
);
1230 if (conn
->requested_resource
&&
1231 !strcmpstart(conn
->requested_resource
,"d/")) {
1232 which
= smartlist_create();
1233 dir_split_resource_into_fingerprints(conn
->requested_resource
+2,
1235 n_asked_for
= smartlist_len(which
);
1237 if (status_code
!= 200) {
1238 int dir_okay
= status_code
== 404 ||
1239 (status_code
== 400 && !strcmp(reason
, "Servers unavailable."));
1240 /* 404 means that it didn't have them; no big deal.
1241 * Older (pre-0.1.1.8) servers said 400 Servers unavailable instead. */
1242 /* XXXX020 This warning tends to freak out clients who get a 403. */
1243 log_fn(dir_okay
? LOG_INFO
: LOG_WARN
, LD_DIR
,
1244 "Received http status code %d (%s) from server '%s:%d' "
1245 "while fetching \"/tor/server/%s\". I'll try again soon.",
1246 status_code
, escaped(reason
), conn
->_base
.address
,
1247 conn
->_base
.port
, conn
->requested_resource
);
1249 connection_dir_download_routerdesc_failed(conn
);
1251 dir_routerdesc_download_failed(which
, status_code
, was_ei
);
1252 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1253 smartlist_free(which
);
1255 tor_free(body
); tor_free(headers
); tor_free(reason
);
1256 return dir_okay
? 0 : -1;
1258 /* Learn the routers, assuming we requested by fingerprint or "all".
1259 * Right now, we only use "authority" to fetch ourself, so we don't want
1260 * to risk replacing ourself with a router running at the addr:port we
1263 if (which
|| (conn
->requested_resource
&&
1264 !strcmpstart(conn
->requested_resource
, "all"))) {
1265 /* as we learn from them, we remove them from 'which' */
1267 router_load_extrainfo_from_string(body
, NULL
, SAVED_NOWHERE
, which
);
1269 router_load_routers_from_string(body
, NULL
, SAVED_NOWHERE
, which
,
1270 conn
->router_purpose
);
1271 directory_info_has_arrived(now
, 0);
1274 if (which
) { /* mark remaining ones as failed */
1275 log_info(LD_DIR
, "Received %d/%d routers requested from %s:%d",
1276 n_asked_for
-smartlist_len(which
), n_asked_for
,
1277 conn
->_base
.address
, (int)conn
->_base
.port
);
1278 if (smartlist_len(which
)) {
1279 dir_routerdesc_download_failed(which
, status_code
, was_ei
);
1281 SMARTLIST_FOREACH(which
, char *, cp
, tor_free(cp
));
1282 smartlist_free(which
);
1284 if (directory_conn_is_self_reachability_test(conn
))
1285 router_dirport_found_reachable();
1288 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_DIR
) {
1289 switch (status_code
) {
1292 trusted_dir_server_t
*ds
=
1293 router_get_trusteddirserver_by_digest(conn
->identity_digest
);
1294 smartlist_t
*servers
;
1295 log_info(LD_GENERAL
,"eof (status 200) after uploading server "
1296 "descriptor: finished.");
1297 control_event_server_status(
1298 LOG_NOTICE
, "ACCEPTED_SERVER_DESCRIPTOR DIRAUTH=%s:%d",
1299 conn
->_base
.address
, conn
->_base
.port
);
1301 ds
->has_accepted_serverdesc
= 1;
1302 servers
= router_get_trusted_dir_servers();
1303 SMARTLIST_FOREACH(servers
, trusted_dir_server_t
*, d
, {
1304 if ((d
->type
& (V1_AUTHORITY
|V2_AUTHORITY
)) &&
1305 !d
->has_accepted_serverdesc
) {
1311 control_event_server_status(LOG_NOTICE
, "GOOD_SERVER_DESCRIPTOR");
1315 log_warn(LD_GENERAL
,"http status 400 (%s) response from "
1316 "dirserver '%s:%d'. Please correct.",
1317 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1318 control_event_server_status(LOG_WARN
,
1319 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1320 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1323 log_warn(LD_GENERAL
,
1324 "http status 403 (%s) response from dirserver "
1325 "'%s:%d'. Is your clock skewed? Have you mailed us your key "
1326 "fingerprint? Are you using the right key? Are you using a "
1327 "private IP address? See http://tor.eff.org/doc/"
1328 "tor-doc-server.html",escaped(reason
), conn
->_base
.address
,
1330 control_event_server_status(LOG_WARN
,
1331 "BAD_SERVER_DESCRIPTOR DIRAUTH=%s:%d REASON=\"%s\"",
1332 conn
->_base
.address
, conn
->_base
.port
, escaped(reason
));
1335 log_warn(LD_GENERAL
,
1336 "http status %d (%s) reason unexpected while uploading "
1337 "descriptor to server '%s:%d').",
1338 status_code
, escaped(reason
), conn
->_base
.address
,
1342 /* return 0 in all cases, since we don't want to mark any
1343 * dirservers down just because they don't like us. */
1346 if (conn
->_base
.purpose
== DIR_PURPOSE_FETCH_RENDDESC
) {
1347 log_info(LD_REND
,"Received rendezvous descriptor (size %d, status %d "
1349 (int)body_len
, status_code
, escaped(reason
));
1350 switch (status_code
) {
1352 if (rend_cache_store(body
, body_len
, 0) < 0) {
1353 log_warn(LD_REND
,"Failed to store rendezvous descriptor.");
1354 /* alice's ap_stream will notice when connection_mark_for_close
1357 /* success. notify pending connections about this. */
1358 conn
->_base
.purpose
= DIR_PURPOSE_HAS_FETCHED_RENDDESC
;
1359 rend_client_desc_here(conn
->rend_query
);
1363 /* not there. pending connections will be notified when
1364 * connection_mark_for_close cleans it up. */
1368 "http status 400 (%s). Dirserver didn't like our "
1369 "rendezvous query?", escaped(reason
));
1372 log_warn(LD_REND
,"http status %d (%s) response unexpected while "
1373 "fetching hidden service descriptor (server '%s:%d').",
1374 status_code
, escaped(reason
), conn
->_base
.address
,
1380 if (conn
->_base
.purpose
== DIR_PURPOSE_UPLOAD_RENDDESC
) {
1381 switch (status_code
) {
1384 "Uploading rendezvous descriptor: finished with status "
1385 "200 (%s)", escaped(reason
));
1388 log_warn(LD_REND
,"http status 400 (%s) response from dirserver "
1389 "'%s:%d'. Malformed rendezvous descriptor?",
1390 escaped(reason
), conn
->_base
.address
, conn
->_base
.port
);
1393 log_warn(LD_REND
,"http status %d (%s) response unexpected (server "
1395 status_code
, escaped(reason
), conn
->_base
.address
,
1400 tor_free(body
); tor_free(headers
); tor_free(reason
);
1404 /** Called when a directory connection reaches EOF */
1406 connection_dir_reached_eof(dir_connection_t
*conn
)
1409 if (conn
->_base
.state
!= DIR_CONN_STATE_CLIENT_READING
) {
1410 log_info(LD_HTTP
,"conn reached eof, not reading. [state=%d] Closing.",
1412 connection_close_immediate(TO_CONN(conn
)); /* error: give up on flushing */
1413 connection_mark_for_close(TO_CONN(conn
));
1417 retval
= connection_dir_client_reached_eof(conn
);
1418 if (retval
== 0) /* success */
1419 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_FINISHED
;
1420 connection_mark_for_close(TO_CONN(conn
));
1424 /** If any directory object is arriving, and it's over 10MB large, we're
1425 * getting DoS'd. (As of 0.1.2.x, raw directories are about 1MB, and we never
1426 * ask for more than 96 router descriptors at a time.)
1428 #define MAX_DIRECTORY_OBJECT_SIZE (10*(1<<20))
1430 /** Read handler for directory connections. (That's connections <em>to</em>
1431 * directory servers and connections <em>at</em> directory servers.)
1434 connection_dir_process_inbuf(dir_connection_t
*conn
)
1437 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
1439 /* Directory clients write, then read data until they receive EOF;
1440 * directory servers read data until they get an HTTP command, then
1441 * write their response (when it's finished flushing, they mark for
1445 /* If we're on the dirserver side, look for a command. */
1446 if (conn
->_base
.state
== DIR_CONN_STATE_SERVER_COMMAND_WAIT
) {
1447 if (directory_handle_command(conn
) < 0) {
1448 connection_mark_for_close(TO_CONN(conn
));
1454 if (buf_datalen(conn
->_base
.inbuf
) > MAX_DIRECTORY_OBJECT_SIZE
) {
1455 log_warn(LD_HTTP
, "Too much data received from directory connection: "
1456 "denial of service attempt, or you need to upgrade?");
1457 connection_mark_for_close(TO_CONN(conn
));
1461 if (!conn
->_base
.inbuf_reached_eof
)
1462 log_debug(LD_HTTP
,"Got data, not eof. Leaving on inbuf.");
1466 /** Create an http response for the client <b>conn</b> out of
1467 * <b>status</b> and <b>reason_phrase</b>. Write it to <b>conn</b>.
1470 write_http_status_line(dir_connection_t
*conn
, int status
,
1471 const char *reason_phrase
)
1474 if (tor_snprintf(buf
, sizeof(buf
), "HTTP/1.0 %d %s\r\n\r\n",
1475 status
, reason_phrase
? reason_phrase
: "OK") < 0) {
1476 log_warn(LD_BUG
,"status line too long.");
1479 connection_write_to_buf(buf
, strlen(buf
), TO_CONN(conn
));
1482 /** Write the header for an HTTP/1.0 response onto <b>conn</b>-\>outbuf,
1483 * with <b>type</b> as the Content-Type.
1485 * If <b>length</b> is nonnegative, it is the Content-Length.
1486 * If <b>encoding</b> is provided, it is the Content-Encoding.
1487 * If <b>cache_lifetime</b> is greater than 0, the content may be cached for
1488 * up to cache_lifetime seconds. Otherwise, the content may not be cached. */
1490 write_http_response_header(dir_connection_t
*conn
, ssize_t length
,
1491 const char *type
, const char *encoding
,
1494 char date
[RFC1123_TIME_LEN
+1];
1497 time_t now
= time(NULL
);
1502 format_rfc1123_time(date
, now
);
1504 tor_snprintf(cp
, sizeof(tmp
),
1505 "HTTP/1.0 200 OK\r\nDate: %s\r\nContent-Type: %s\r\n",
1508 if (!is_internal_IP(conn
->_base
.addr
, 0)) {
1509 /* Don't report the source address for a localhost/private connection. */
1510 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1511 X_ADDRESS_HEADER
"%s\r\n", conn
->_base
.address
);
1515 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1516 "Content-Encoding: %s\r\n", encoding
);
1520 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1521 "Content-Length: %ld\r\n", (long)length
);
1524 if (cache_lifetime
> 0) {
1525 char expbuf
[RFC1123_TIME_LEN
+1];
1526 format_rfc1123_time(expbuf
, now
+ cache_lifetime
);
1527 /* We could say 'Cache-control: max-age=%d' here if we start doing
1529 tor_snprintf(cp
, sizeof(tmp
)-(cp
-tmp
),
1530 "Expires: %s\r\n", expbuf
);
1533 /* We could say 'Cache-control: no-cache' here if we start doing
1535 strlcpy(cp
, "Pragma: no-cache\r\n", sizeof(tmp
)-(cp
-tmp
));
1538 if (sizeof(tmp
)-(cp
-tmp
) > 3)
1539 memcpy(cp
, "\r\n", 3);
1542 connection_write_to_buf(tmp
, strlen(tmp
), TO_CONN(conn
));
1545 /** Helper function: return 1 if there are any dir conns of purpose
1546 * <b>purpose</b> that are going elsewhere than our own ORPort/Dirport.
1550 already_fetching_directory(int purpose
)
1552 smartlist_t
*conns
= get_connection_array();
1553 SMARTLIST_FOREACH(conns
, connection_t
*, conn
,
1555 if (conn
->type
== CONN_TYPE_DIR
&&
1556 conn
->purpose
== purpose
&&
1557 !conn
->marked_for_close
&&
1558 !router_digest_is_me(TO_DIR_CONN(conn
)->identity_digest
))
1564 #undef INSTRUMENT_DOWNLOADS
1566 #ifdef INSTRUMENT_DOWNLOADS
1567 /** Map used to keep track of how much data we've up/downloaded in what kind
1568 * of request. Maps from request type to pointer to uint64_t. */
1569 static strmap_t
*request_bytes_map
= NULL
;
1571 /** Called when we just transmitted or received <b>bytes</b> worth of data
1572 * because of a request of type <b>key</b> (an arbitrary identifier): adds
1573 * <b>bytes</b> to the total associated with key. */
1575 note_request(const char *key
, size_t bytes
)
1578 if (!request_bytes_map
)
1579 request_bytes_map
= strmap_new();
1581 n
= strmap_get(request_bytes_map
, key
);
1583 n
= tor_malloc_zero(sizeof(uint64_t));
1584 strmap_set(request_bytes_map
, key
, n
);
1589 /** Return a newly allocated string holding a summary of bytes used per
1592 directory_dump_request_log(void)
1597 strmap_iter_t
*iter
;
1599 if (!request_bytes_map
)
1600 request_bytes_map
= strmap_new();
1602 lines
= smartlist_create();
1604 for (iter
= strmap_iter_init(request_bytes_map
);
1605 !strmap_iter_done(iter
);
1606 iter
= strmap_iter_next(request_bytes_map
, iter
)) {
1610 strmap_iter_get(iter
, &key
, &val
);
1612 tor_snprintf(tmp
, sizeof(tmp
), "%s "U64_FORMAT
"\n",
1613 key
, U64_PRINTF_ARG(*n
));
1614 smartlist_add(lines
, tor_strdup(tmp
));
1616 smartlist_sort_strings(lines
);
1617 result
= smartlist_join_strings(lines
, "", 0, NULL
);
1618 SMARTLIST_FOREACH(lines
, char *, cp
, tor_free(cp
));
1619 smartlist_free(lines
);
1624 note_request(const char *key
, size_t bytes
)
1631 directory_dump_request_log(void)
1633 return tor_strdup("Not supported.");
1637 /** Helper function: called when a dirserver gets a complete HTTP GET
1638 * request. Look for a request for a directory or for a rendezvous
1639 * service descriptor. On finding one, write a response into
1640 * conn-\>outbuf. If the request is unrecognized, send a 400.
1641 * Always return 0. */
1643 directory_handle_command_get(dir_connection_t
*conn
, const char *headers
,
1644 const char *body
, size_t body_len
)
1648 or_options_t
*options
= get_options();
1649 time_t if_modified_since
= 0;
1652 /* We ignore the body of a GET request. */
1656 log_debug(LD_DIRSERV
,"Received GET command.");
1658 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
1660 if (parse_http_url(headers
, &url
) < 0) {
1661 write_http_status_line(conn
, 400, "Bad request");
1664 if ((header
= http_get_header(headers
, "If-Modified-Since: "))) {
1666 if (parse_http_time(header
, &tm
) == 0) {
1667 if_modified_since
= tor_timegm(&tm
);
1669 /* The correct behavior on a malformed If-Modified-Since header is to
1670 * act as if no If-Modified-Since header had been given. */
1673 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
1675 if (!strcmp(url
,"/tor/") || !strcmp(url
,"/tor/dir.z")) { /* dir fetch */
1676 int deflated
= !strcmp(url
,"/tor/dir.z");
1677 cached_dir_t
*d
= dirserv_get_directory();
1680 log_notice(LD_DIRSERV
,"Client asked for the mirrored directory, but we "
1681 "don't have a good one yet. Sending 503 Dir not available.");
1682 write_http_status_line(conn
, 503, "Directory unavailable");
1683 /* try to get a new one now */
1684 if (!already_fetching_directory(DIR_PURPOSE_FETCH_DIR
))
1685 directory_get_from_dirserver(DIR_PURPOSE_FETCH_DIR
, NULL
, 1);
1689 if (d
->published
< if_modified_since
) {
1690 write_http_status_line(conn
, 304, "Not modified");
1695 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
1697 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
1698 log_info(LD_DIRSERV
,
1699 "Client asked for the mirrored directory, but we've been "
1700 "writing too many bytes lately. Sending 503 Dir busy.");
1701 write_http_status_line(conn
, 503, "Directory busy, try again later");
1706 note_request(url
, dlen
);
1709 log_debug(LD_DIRSERV
,"Dumping %sdirectory to client.",
1710 deflated
?"deflated ":"");
1711 write_http_response_header(conn
, dlen
,
1712 deflated
?"application/octet-stream":"text/plain",
1713 deflated
?"deflate":"identity",
1714 FULL_DIR_CACHE_LIFETIME
);
1715 conn
->cached_dir
= d
;
1716 conn
->cached_dir_offset
= 0;
1718 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
1721 /* Prime the connection with some data. */
1722 conn
->dir_spool_src
= DIR_SPOOL_CACHED_DIR
;
1723 connection_dirserv_flushed_some(conn
);
1727 if (!strcmp(url
,"/tor/running-routers") ||
1728 !strcmp(url
,"/tor/running-routers.z")) { /* running-routers fetch */
1729 int deflated
= !strcmp(url
,"/tor/running-routers.z");
1730 cached_dir_t
*d
= dirserv_get_runningrouters();
1732 write_http_status_line(conn
, 503, "Directory unavailable");
1733 /* try to get a new one now */
1734 if (!already_fetching_directory(DIR_PURPOSE_FETCH_RUNNING_LIST
))
1735 directory_get_from_dirserver(DIR_PURPOSE_FETCH_RUNNING_LIST
, NULL
, 1);
1739 if (d
->published
< if_modified_since
) {
1740 write_http_status_line(conn
, 304, "Not modified");
1744 dlen
= deflated
? d
->dir_z_len
: d
->dir_len
;
1746 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 1)) {
1747 log_info(LD_DIRSERV
,
1748 "Client asked for running-routers, but we've been "
1749 "writing too many bytes lately. Sending 503 Dir busy.");
1750 write_http_status_line(conn
, 503, "Directory busy, try again later");
1754 note_request(url
, dlen
);
1756 write_http_response_header(conn
, dlen
,
1757 deflated
?"application/octet-stream":"text/plain",
1758 deflated
?"deflate":"identity",
1759 RUNNINGROUTERS_CACHE_LIFETIME
);
1760 connection_write_to_buf(deflated
? d
->dir_z
: d
->dir
, dlen
, TO_CONN(conn
));
1764 if (!strcmpstart(url
,"/tor/status/")) {
1765 /* v2 network status fetch. */
1766 size_t url_len
= strlen(url
);
1767 int deflated
= !strcmp(url
+url_len
-2, ".z");
1768 smartlist_t
*dir_fps
= smartlist_create();
1769 const char *request_type
= NULL
;
1770 const char *key
= url
+ strlen("/tor/status/");
1772 url
[url_len
-2] = '\0';
1773 dirserv_get_networkstatus_v2_fingerprints(dir_fps
, key
);
1774 if (!strcmpstart(key
, "fp/"))
1775 request_type
= deflated
?"/tor/status/fp.z":"/tor/status/fp";
1776 else if (!strcmpstart(key
, "authority"))
1777 request_type
= deflated
?"/tor/status/authority.z":
1778 "/tor/status/authority";
1779 else if (!strcmpstart(key
, "all"))
1780 request_type
= deflated
?"/tor/status/all.z":"/tor/status/all";
1782 request_type
= "/tor/status/?";
1784 if (!smartlist_len(dir_fps
)) { /* we failed to create/cache cp */
1785 write_http_status_line(conn
, 503, "Network status object unavailable");
1786 smartlist_free(dir_fps
);
1789 if (dirserv_statuses_are_old(dir_fps
, if_modified_since
)) {
1790 write_http_status_line(conn
, 304, "Not modified");
1791 smartlist_free(dir_fps
);
1795 dlen
= dirserv_estimate_data_size(dir_fps
, 0, deflated
);
1796 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
1797 log_info(LD_DIRSERV
,
1798 "Client asked for network status lists, but we've been "
1799 "writing too many bytes lately. Sending 503 Dir busy.");
1800 write_http_status_line(conn
, 503, "Directory busy, try again later");
1801 SMARTLIST_FOREACH(dir_fps
, char *, fp
, tor_free(fp
));
1802 smartlist_free(dir_fps
);
1806 // note_request(request_type,dlen);
1807 (void) request_type
;
1808 write_http_response_header(conn
, -1,
1809 deflated
?"application/octet_stream":"text/plain",
1810 deflated
?"deflate":NULL
,
1811 smartlist_len(dir_fps
) == 1 ? NETWORKSTATUS_CACHE_LIFETIME
:0);
1812 conn
->fingerprint_stack
= dir_fps
;
1814 conn
->zlib_state
= tor_zlib_new(0, ZLIB_METHOD
);
1816 /* Prime the connection with some data. */
1817 conn
->dir_spool_src
= DIR_SPOOL_NETWORKSTATUS
;
1818 connection_dirserv_flushed_some(conn
);
1823 if (!strcmpstart(url
,"/tor/server/") ||
1824 !strcmpstart(url
,"/tor/extra/")) {
1825 char *url_mem
= url
;
1826 size_t url_len
= strlen(url
);
1827 int deflated
= !strcmp(url
+url_len
-2, ".z");
1830 const char *request_type
= NULL
;
1831 int cache_lifetime
= 0;
1832 int is_extra
= !strcmpstart(url
,"/tor/extra/");
1834 url
[url_len
-2] = '\0';
1835 url
+= is_extra
? strlen("/tor/extra/") : strlen("/tor/server/");
1836 conn
->fingerprint_stack
= smartlist_create();
1837 res
= dirserv_get_routerdesc_fingerprints(conn
->fingerprint_stack
, url
,
1840 if (!strcmpstart(url
, "fp/")) {
1841 request_type
= deflated
?"/tor/server/fp.z":"/tor/server/fp";
1842 if (smartlist_len(conn
->fingerprint_stack
) == 1)
1843 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
1844 } else if (!strcmpstart(url
, "authority")) {
1845 request_type
= deflated
?"/tor/server/authority.z":
1846 "/tor/server/authority";
1847 cache_lifetime
= ROUTERDESC_CACHE_LIFETIME
;
1848 } else if (!strcmpstart(url
, "all")) {
1849 request_type
= deflated
?"/tor/server/all.z":"/tor/server/all";
1850 cache_lifetime
= FULL_DIR_CACHE_LIFETIME
;
1851 } else if (!strcmpstart(url
, "d/")) {
1852 request_type
= deflated
?"/tor/server/d.z":"/tor/server/d";
1853 if (smartlist_len(conn
->fingerprint_stack
) == 1)
1854 cache_lifetime
= ROUTERDESC_BY_DIGEST_CACHE_LIFETIME
;
1856 request_type
= "/tor/server/?";
1858 (void) request_type
; /* usable for note_request. */
1859 if (!strcmpstart(url
, "d/"))
1860 conn
->dir_spool_src
=
1861 is_extra
? DIR_SPOOL_EXTRA_BY_DIGEST
: DIR_SPOOL_SERVER_BY_DIGEST
;
1863 conn
->dir_spool_src
=
1864 is_extra
? DIR_SPOOL_EXTRA_BY_FP
: DIR_SPOOL_SERVER_BY_FP
;
1867 write_http_status_line(conn
, 404, msg
);
1869 dlen
= dirserv_estimate_data_size(conn
->fingerprint_stack
,
1871 if (global_write_bucket_low(TO_CONN(conn
), dlen
, 2)) {
1872 log_info(LD_DIRSERV
,
1873 "Client asked for server descriptors, but we've been "
1874 "writing too many bytes lately. Sending 503 Dir busy.");
1875 write_http_status_line(conn
, 503, "Directory busy, try again later");
1878 write_http_response_header(conn
, -1,
1879 deflated
?"application/octet_stream":"text/plain",
1880 deflated
?"deflate":NULL
, cache_lifetime
);
1882 conn
->zlib_state
= tor_zlib_new(1, ZLIB_METHOD
);
1883 /* Prime the connection with some data. */
1884 connection_dirserv_flushed_some(conn
);
1889 if (options
->HSAuthoritativeDir
&&
1890 (!strcmpstart(url
,"/tor/rendezvous/") ||
1891 !strcmpstart(url
,"/tor/rendezvous1/"))) {
1892 /* rendezvous descriptor fetch */
1895 int versioned
= !strcmpstart(url
,"/tor/rendezvous1/");
1896 const char *query
= url
+strlen("/tor/rendezvous/")+(versioned
?1:0);
1898 switch (rend_cache_lookup_desc(query
, versioned
?-1:0, &descp
, &desc_len
)) {
1900 write_http_response_header(conn
, desc_len
, "application/octet-stream",
1902 note_request("/tor/rendezvous?/", desc_len
);
1903 /* need to send descp separately, because it may include nuls */
1904 connection_write_to_buf(descp
, desc_len
, TO_CONN(conn
));
1905 /* report successful fetch to statistic */
1906 if (options
->HSAuthorityRecordStats
) {
1907 hs_usage_note_fetch_total(query
, time(NULL
));
1908 hs_usage_note_fetch_successful(query
, time(NULL
));
1911 case 0: /* well-formed but not present */
1912 write_http_status_line(conn
, 404, "Not found");
1913 /* report (unsuccessful) fetch to statistic */
1914 if (options
->HSAuthorityRecordStats
) {
1915 hs_usage_note_fetch_total(query
, time(NULL
));
1918 case -1: /* not well-formed */
1919 write_http_status_line(conn
, 400, "Bad request");
1926 if (!strcmpstart(url
,"/tor/bytes.txt")) {
1927 char *bytes
= directory_dump_request_log();
1928 size_t len
= strlen(bytes
);
1929 write_http_response_header(conn
, len
, "text/plain", NULL
, 0);
1930 connection_write_to_buf(bytes
, len
, TO_CONN(conn
));
1936 if (!strcmp(url
,"/tor/robots.txt")) { /* /robots.txt will have been
1937 rewritten to /tor/robots.txt */
1938 char robots
[] = "User-agent: *\r\nDisallow: /\r\n";
1939 size_t len
= strlen(robots
);
1940 write_http_response_header(conn
, len
, "text/plain", NULL
,
1941 ROBOTS_CACHE_LIFETIME
);
1942 connection_write_to_buf(robots
, len
, TO_CONN(conn
));
1947 if (!strcmp(url
,"/tor/dir-all-weaselhack") &&
1948 (conn
->_base
.addr
== 0x7f000001ul
) &&
1949 authdir_mode_v2(options
) &&
1950 !authdir_mode_bridge(options
)) {
1951 /* until weasel rewrites his scripts at noreply */
1952 char *new_directory
=NULL
;
1954 if (dirserv_dump_directory_to_string(&new_directory
,
1955 get_identity_key(), 1)) {
1956 log_warn(LD_BUG
, "Error creating full v1 directory.");
1957 tor_free(new_directory
);
1958 write_http_status_line(conn
, 503, "Directory unavailable");
1962 dlen
= strlen(new_directory
);
1964 write_http_response_header(conn
, dlen
, "text/plain", "identity", 0);
1966 connection_write_to_buf(new_directory
, dlen
, TO_CONN(conn
));
1967 tor_free(new_directory
);
1972 /* we didn't recognize the url */
1973 write_http_status_line(conn
, 404, "Not found");
1978 /** Helper function: called when a dirserver gets a complete HTTP POST
1979 * request. Look for an uploaded server descriptor or rendezvous
1980 * service descriptor. On finding one, process it and write a
1981 * response into conn-\>outbuf. If the request is unrecognized, send a
1982 * 400. Always return 0. */
1984 directory_handle_command_post(dir_connection_t
*conn
, const char *headers
,
1985 const char *body
, size_t body_len
)
1988 or_options_t
*options
= get_options();
1990 log_debug(LD_DIRSERV
,"Received POST command.");
1992 conn
->_base
.state
= DIR_CONN_STATE_SERVER_WRITING
;
1994 if (!authdir_mode(options
)) {
1995 /* we just provide cached directories; we don't want to
1996 * receive anything. */
1997 write_http_status_line(conn
, 400, "Nonauthoritative directory does not "
1998 "accept posted server descriptors");
2002 if (parse_http_url(headers
, &url
) < 0) {
2003 write_http_status_line(conn
, 400, "Bad request");
2006 log_debug(LD_DIRSERV
,"rewritten url as '%s'.", url
);
2008 if (authdir_mode_handles_descs(options
) &&
2009 !strcmp(url
,"/tor/")) { /* server descriptor post */
2010 const char *msg
= NULL
;
2011 uint8_t purpose
= authdir_mode_bridge(options
) ?
2012 ROUTER_PURPOSE_CONTROLLER
: ROUTER_PURPOSE_GENERAL
;
2013 int r
= dirserv_add_multiple_descriptors(body
, purpose
, &msg
);
2016 dirserv_get_directory(); /* rebuild and write to disk */
2021 log_notice(LD_DIRSERV
,
2022 "Rejected router descriptor or extra-info from %s.",
2023 conn
->_base
.address
);
2024 /* malformed descriptor, or something wrong */
2025 write_http_status_line(conn
, 400, msg
);
2027 case 0: /* accepted but discarded */
2028 case 2: /* accepted */
2029 write_http_status_line(conn
, 200, msg
);
2035 if (options
->HSAuthoritativeDir
&&
2036 !strcmpstart(url
,"/tor/rendezvous/publish")) {
2037 /* rendezvous descriptor post */
2038 if (rend_cache_store(body
, body_len
, 1) < 0) {
2039 // char tmp[1024*2+1];
2040 log_fn(LOG_PROTOCOL_WARN
, LD_DIRSERV
,
2041 "Rejected rend descriptor (length %d) from %s.",
2042 (int)body_len
, conn
->_base
.address
);
2043 write_http_status_line(conn
, 400, "Invalid service descriptor rejected");
2045 write_http_status_line(conn
, 200, "Service descriptor stored");
2050 /* we didn't recognize the url */
2051 write_http_status_line(conn
, 404, "Not found");
2058 /** Called when a dirserver receives data on a directory connection;
2059 * looks for an HTTP request. If the request is complete, remove it
2060 * from the inbuf, try to process it; otherwise, leave it on the
2061 * buffer. Return a 0 on success, or -1 on error.
2064 directory_handle_command(dir_connection_t
*conn
)
2066 char *headers
=NULL
, *body
=NULL
;
2071 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2073 switch (fetch_from_buf_http(conn
->_base
.inbuf
,
2074 &headers
, MAX_HEADERS_SIZE
,
2075 &body
, &body_len
, MAX_DIR_UL_SIZE
, 0)) {
2076 case -1: /* overflow */
2077 log_warn(LD_DIRSERV
,
2078 "Invalid input from address '%s'. Closing.",
2079 conn
->_base
.address
);
2082 log_debug(LD_DIRSERV
,"command not all here yet.");
2084 /* case 1, fall through */
2087 http_set_address_origin(headers
, TO_CONN(conn
));
2088 //log_debug(LD_DIRSERV,"headers %s, body %s.", headers, body);
2090 if (!strncasecmp(headers
,"GET",3))
2091 r
= directory_handle_command_get(conn
, headers
, body
, body_len
);
2092 else if (!strncasecmp(headers
,"POST",4))
2093 r
= directory_handle_command_post(conn
, headers
, body
, body_len
);
2095 log_fn(LOG_PROTOCOL_WARN
, LD_PROTOCOL
,
2096 "Got headers %s with unknown command. Closing.",
2101 tor_free(headers
); tor_free(body
);
2105 /** Write handler for directory connections; called when all data has
2106 * been flushed. Close the connection or wait for a response as
2110 connection_dir_finished_flushing(dir_connection_t
*conn
)
2113 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2115 switch (conn
->_base
.state
) {
2116 case DIR_CONN_STATE_CLIENT_SENDING
:
2117 log_debug(LD_DIR
,"client finished sending command.");
2118 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_READING
;
2119 connection_stop_writing(TO_CONN(conn
));
2121 case DIR_CONN_STATE_SERVER_WRITING
:
2122 log_debug(LD_DIRSERV
,"Finished writing server response. Closing.");
2123 connection_mark_for_close(TO_CONN(conn
));
2126 log_warn(LD_BUG
,"called in unexpected state %d.",
2128 tor_fragile_assert();
2134 /** Connected handler for directory connections: begin sending data to the
2137 connection_dir_finished_connecting(dir_connection_t
*conn
)
2140 tor_assert(conn
->_base
.type
== CONN_TYPE_DIR
);
2141 tor_assert(conn
->_base
.state
== DIR_CONN_STATE_CONNECTING
);
2143 log_debug(LD_HTTP
,"Dir connection to router %s:%u established.",
2144 conn
->_base
.address
,conn
->_base
.port
);
2146 conn
->_base
.state
= DIR_CONN_STATE_CLIENT_SENDING
; /* start flushing conn */
2150 /** Called when one or more networkstatus fetches have failed (with uppercase
2151 * fingerprints listed in <b>failed</b>). Mark those fingerprints as having
2152 * failed once, unless they failed with status code 503. */
2154 dir_networkstatus_download_failed(smartlist_t
*failed
, int status_code
)
2156 if (status_code
== 503)
2158 SMARTLIST_FOREACH(failed
, const char *, fp
,
2160 char digest
[DIGEST_LEN
];
2161 trusted_dir_server_t
*dir
;
2162 base16_decode(digest
, DIGEST_LEN
, fp
, strlen(fp
));
2163 dir
= router_get_trusteddirserver_by_digest(digest
);
2166 ++dir
->n_networkstatus_failures
;
2170 /** Called when one or more routerdesc (or extrainfo, if <b>was_extrainfo</b>)
2171 * fetches have failed (with uppercase fingerprints listed in
2172 * <b>failed</b>). */
2174 dir_routerdesc_download_failed(smartlist_t
*failed
, int status_code
,
2177 char digest
[DIGEST_LEN
];
2178 time_t now
= time(NULL
);
2179 int server
= server_mode(get_options()) && get_options()->DirPort
;
2180 SMARTLIST_FOREACH(failed
, const char *, cp
,
2182 download_status_t
*dls
= NULL
;
2183 base16_decode(digest
, DIGEST_LEN
, cp
, strlen(cp
));
2184 if (was_extrainfo
) {
2185 signed_descriptor_t
*sd
=
2186 router_get_by_extrainfo_digest(digest
);
2188 dls
= &sd
->ei_dl_status
;
2190 local_routerstatus_t
*rs
=
2191 router_get_combined_status_by_descriptor_digest(digest
);
2193 dls
= &rs
->dl_status
;
2195 if (!dls
|| dls
->n_download_failures
>= MAX_ROUTERDESC_DOWNLOAD_FAILURES
)
2197 if (status_code
!= 503 || server
)
2198 ++dls
->n_download_failures
;
2200 switch (dls
->n_download_failures
) {
2201 case 0: dls
->next_attempt_at
= 0; break;
2202 case 1: dls
->next_attempt_at
= 0; break;
2203 case 2: dls
->next_attempt_at
= 0; break;
2204 case 3: dls
->next_attempt_at
= now
+60; break;
2205 case 4: dls
->next_attempt_at
= now
+60; break;
2206 case 5: dls
->next_attempt_at
= now
+60*2; break;
2207 case 6: dls
->next_attempt_at
= now
+60*5; break;
2208 case 7: dls
->next_attempt_at
= now
+60*15; break;
2209 default: dls
->next_attempt_at
= TIME_MAX
; break;
2212 switch (dls
->n_download_failures
) {
2213 case 0: dls
->next_attempt_at
= 0; break;
2214 case 1: dls
->next_attempt_at
= 0; break;
2215 case 2: dls
->next_attempt_at
= now
+60; break;
2216 case 3: dls
->next_attempt_at
= now
+60*5; break;
2217 case 4: dls
->next_attempt_at
= now
+60*10; break;
2218 default: dls
->next_attempt_at
= TIME_MAX
; break;
2221 if (dls
->next_attempt_at
== 0)
2222 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again immediately.",
2223 cp
, (int)dls
->n_download_failures
);
2224 else if (dls
->next_attempt_at
< TIME_MAX
)
2225 log_debug(LD_DIR
, "%s failed %d time(s); I'll try again in %d seconds.",
2226 cp
, (int)dls
->n_download_failures
,
2227 (int)(dls
->next_attempt_at
-now
));
2229 log_debug(LD_DIR
, "%s failed %d time(s); Giving up for a while.",
2230 cp
, (int)dls
->n_download_failures
);
2233 /* No need to relaunch descriptor downloads here: we already do it
2234 * every 10 seconds (DESCRIPTOR_RETRY_INTERVAL) in main.c. */
2237 /** Given a directory <b>resource</b> request, containing zero
2238 * or more strings separated by plus signs, followed optionally by ".z", store
2239 * the strings, in order, into <b>fp_out</b>. If <b>compressed_out</b> is
2240 * non-NULL, set it to 1 if the resource ends in ".z", else set it to 0. If
2241 * decode_hex is true, then delete all elements that aren't hex digests, and
2242 * decode the rest. If sort_uniq is true, then sort the list and remove
2246 dir_split_resource_into_fingerprints(const char *resource
,
2247 smartlist_t
*fp_out
, int *compressed_out
,
2248 int decode_hex
, int sort_uniq
)
2250 smartlist_t
*fp_tmp
= smartlist_create();
2252 smartlist_split_string(fp_tmp
, resource
, "+", 0, 0);
2254 *compressed_out
= 0;
2255 if (smartlist_len(fp_tmp
)) {
2256 char *last
= smartlist_get(fp_tmp
,smartlist_len(fp_tmp
)-1);
2257 size_t last_len
= strlen(last
);
2258 if (last_len
> 2 && !strcmp(last
+last_len
-2, ".z")) {
2259 last
[last_len
-2] = '\0';
2261 *compressed_out
= 1;
2266 char *cp
, *d
= NULL
;
2267 for (i
= 0; i
< smartlist_len(fp_tmp
); ++i
) {
2268 cp
= smartlist_get(fp_tmp
, i
);
2269 if (strlen(cp
) != HEX_DIGEST_LEN
) {
2271 "Skipping digest %s with non-standard length.", escaped(cp
));
2272 smartlist_del_keeporder(fp_tmp
, i
--);
2275 d
= tor_malloc_zero(DIGEST_LEN
);
2276 if (base16_decode(d
, DIGEST_LEN
, cp
, HEX_DIGEST_LEN
)<0) {
2277 log_info(LD_DIR
, "Skipping non-decodable digest %s", escaped(cp
));
2278 smartlist_del_keeporder(fp_tmp
, i
--);
2281 smartlist_set(fp_tmp
, i
, d
);
2289 smartlist_t
*fp_tmp2
= smartlist_create();
2292 smartlist_sort_digests(fp_tmp
);
2294 smartlist_sort_strings(fp_tmp
);
2295 if (smartlist_len(fp_tmp
))
2296 smartlist_add(fp_tmp2
, smartlist_get(fp_tmp
, 0));
2297 for (i
= 1; i
< smartlist_len(fp_tmp
); ++i
) {
2298 char *cp
= smartlist_get(fp_tmp
, i
);
2299 char *last
= smartlist_get(fp_tmp2
, smartlist_len(fp_tmp2
)-1);
2301 if ((decode_hex
&& memcmp(cp
, last
, DIGEST_LEN
))
2302 || (!decode_hex
&& strcasecmp(cp
, last
)))
2303 smartlist_add(fp_tmp2
, cp
);
2307 smartlist_free(fp_tmp
);
2310 smartlist_add_all(fp_out
, fp_tmp
);
2311 smartlist_free(fp_tmp
);