diff --git a/ChangeLog b/ChangeLog index 8b54721688..7901f2c6a3 100644 --- a/ChangeLog +++ b/ChangeLog @@ -37,9 +37,18 @@ Changes in version 0.2.1.2-alpha - 2008-06-?? from cannibalized circuits are completely ignored and not included in rendezvous service descriptors. This might be another reason for delay in making a hidden service available. Bugfix on 0.2.0.14-alpha. + + o Bootstrapping bugfixes: - Directory authorities shouldn't complain about bootstrapping problems just because they do a lot of reachability testing and some of the connection attempts fail. + - Start sending "count" and "recommendation" key/value pairs in + bootstrap problem status events, so the controller can hear about + problems even before Tor decides they're worth reporting for sure. + - If you're using bridges, generate "bootstrap problem" warnings + as soon as you run out of working bridges, rather than waiting + for ten failures -- which will never happen if you have less than + ten bridges. Changes in version 0.2.1.1-alpha - 2008-06-13 diff --git a/doc/TODO b/doc/TODO index bb729af13e..2ea0afe37b 100644 --- a/doc/TODO +++ b/doc/TODO @@ -340,7 +340,7 @@ R - investigate: it looks like if the bridge authority is unreachable, o directory authorities shouldn't complain about bootstrapping problems just because they do a lot of reachability testing and some of it fails. -R * if your bridge is unreachable, it won't generate enough connection + o if your bridge is unreachable, it won't generate enough connection failures to generate a bootstrap problem event. R - if "no running bridges known", an application request should make us retry all our bridges. diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c index da96974623..8e89daf40f 100644 --- a/src/or/circuitbuild.c +++ b/src/or/circuitbuild.c @@ -3068,6 +3068,27 @@ any_bridge_descriptors_known(void) return choose_random_entry(NULL)!=NULL ? 1 : 0; } +/** Return 1 if there are any directory conns fetching bridge descriptors + * that aren't marked for close. We use this to guess if we should tell + * the controller that we have a problem. */ +int +any_pending_bridge_descriptor_fetches(void) +{ + smartlist_t *conns = get_connection_array(); + SMARTLIST_FOREACH(conns, connection_t *, conn, + { + if (conn->type == CONN_TYPE_DIR && + conn->purpose == DIR_PURPOSE_FETCH_SERVERDESC && + TO_DIR_CONN(conn)->router_purpose == ROUTER_PURPOSE_BRIDGE && + !conn->marked_for_close && + conn->linked && !conn->linked_conn->marked_for_close) { + log_debug(LD_DIR, "found one: %s", conn->address); + return 1; + } + }); + return 0; +} + /** Return 1 if we have at least one descriptor for a bridge and * all descriptors we know are down. Else return 0. If act is * 1, then mark the down bridges up; else just observe and report. */ diff --git a/src/or/connection.c b/src/or/connection.c index f83ea9d7ff..690cc02774 100644 --- a/src/or/connection.c +++ b/src/or/connection.c @@ -494,6 +494,10 @@ connection_about_to_close_connection(connection_t *conn) or_conn = TO_OR_CONN(conn); /* Remember why we're closing this connection. */ if (conn->state != OR_CONN_STATE_OPEN) { + /* Inform any pending (not attached) circs that they should + * give up. */ + circuit_n_conn_done(TO_OR_CONN(conn), 0); + /* now mark things down as needed */ if (connection_or_nonopen_was_started_here(or_conn)) { or_options_t *options = get_options(); rep_hist_note_connect_failed(or_conn->identity_digest, now); @@ -517,9 +521,6 @@ connection_about_to_close_connection(connection_t *conn) orconn_end_reason_to_control_string(reason), reason); } } - /* Inform any pending (not attached) circs that they should - * give up. */ - circuit_n_conn_done(TO_OR_CONN(conn), 0); } else if (conn->hold_open_until_flushed) { /* We only set hold_open_until_flushed when we're intentionally * closing a connection. */ diff --git a/src/or/control.c b/src/or/control.c index bef6028c75..db7540bf0f 100644 --- a/src/or/control.c +++ b/src/or/control.c @@ -3868,12 +3868,19 @@ control_event_bootstrap_problem(const char *warn, int reason) if (bootstrap_problems >= BOOTSTRAP_PROBLEM_THRESHOLD) recommendation = "warn"; + if (get_options()->UseBridges && + !any_bridge_descriptors_known() && + !any_pending_bridge_descriptor_fetches()) + recommendation = "warn"; + while (status>=0 && bootstrap_status_to_string(status, &tag, &summary) < 0) status--; /* find a recognized status string based on current progress */ - log_warn(LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s)", + log_warn(LD_CONTROL, "Problem bootstrapping. Stuck at %d%%: %s. (%s; %s; " + "count %d; recommendation %s)", status, summary, warn, - orconn_end_reason_to_control_string(reason)); + orconn_end_reason_to_control_string(reason), + bootstrap_problems, recommendation); tor_snprintf(buf, sizeof(buf), "BOOTSTRAP PROGRESS=%d TAG=%s SUMMARY=\"%s\" WARNING=\"%s\" REASON=%s " "COUNT=%d RECOMMENDATION=%s", diff --git a/src/or/or.h b/src/or/or.h index ad675ce02f..43a882ca84 100644 --- a/src/or/or.h +++ b/src/or/or.h @@ -2600,6 +2600,7 @@ void retry_bridge_descriptor_fetch_directly(char *digest); void fetch_bridge_descriptors(time_t now); void learned_bridge_descriptor(routerinfo_t *ri, int from_cache); int any_bridge_descriptors_known(void); +int any_pending_bridge_descriptor_fetches(void); int bridges_known_but_down(void); void bridges_retry_all(void);