diff --git a/src/or/rendclient.c b/src/or/rendclient.c index 90304c33c3..d444611019 100644 --- a/src/or/rendclient.c +++ b/src/or/rendclient.c @@ -23,7 +23,8 @@ #include "routerlist.h" static extend_info_t *rend_client_get_random_intro_impl( - const rend_data_t *rend_query, const int strict); + const rend_cache_entry_t *rend_query, + const int strict, const int warnings); /** Called when we've established a circuit to an introduction point: * send the introduction request. */ @@ -562,7 +563,7 @@ rend_client_remove_intro_point(extend_info_t *failed_intro, } } - if (smartlist_len(ent->parsed->intro_nodes) == 0) { + if (! rend_client_any_intro_points_usable(ent)) { log_info(LD_REND, "No more intro points remain for %s. Re-fetching descriptor.", escaped_safe_str_client(rend_query->onion_address)); @@ -708,7 +709,7 @@ rend_client_desc_trynow(const char *query) assert_connection_ok(TO_CONN(conn), now); if (rend_cache_lookup_entry(conn->rend_data->onion_address, -1, &entry) == 1 && - smartlist_len(entry->parsed->intro_nodes) > 0) { + rend_client_any_intro_points_usable(entry)) { /* either this fetch worked, or it failed but there was a * valid entry from before which we should reuse */ log_info(LD_REND,"Rend desc is usable. Launching circuits."); @@ -743,13 +744,22 @@ extend_info_t * rend_client_get_random_intro(const rend_data_t *rend_query) { extend_info_t *result; + rend_cache_entry_t *entry; + + if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) { + log_warn(LD_REND, + "Query '%s' didn't have valid rend desc in cache. Failing.", + safe_str_client(rend_query->onion_address)); + return NULL; + } + /* See if we can get a node that complies with ExcludeNodes */ - if ((result = rend_client_get_random_intro_impl(rend_query, 1))) + if ((result = rend_client_get_random_intro_impl(entry, 1, 1))) return result; /* If not, and StrictNodes is not set, see if we can return any old node */ if (!get_options()->StrictNodes) - return rend_client_get_random_intro_impl(rend_query, 0); + return rend_client_get_random_intro_impl(entry, 0, 1); return NULL; } @@ -757,23 +767,18 @@ rend_client_get_random_intro(const rend_data_t *rend_query) * iff strict is true. */ static extend_info_t * -rend_client_get_random_intro_impl(const rend_data_t *rend_query, - const int strict) +rend_client_get_random_intro_impl(const rend_cache_entry_t *entry, + const int strict, + const int warnings) { int i; - rend_cache_entry_t *entry; + rend_intro_point_t *intro; routerinfo_t *router; or_options_t *options = get_options(); smartlist_t *usable_nodes; int n_excluded = 0; - if (rend_cache_lookup_entry(rend_query->onion_address, -1, &entry) < 1) { - log_warn(LD_REND, - "Query '%s' didn't have valid rend desc in cache. Failing.", - safe_str_client(rend_query->onion_address)); - return NULL; - } /* We'll keep a separate list of the usable nodes. If this becomes empty, * no nodes are usable. */ usable_nodes = smartlist_create(); @@ -781,7 +786,7 @@ rend_client_get_random_intro_impl(const rend_data_t *rend_query, again: if (smartlist_len(usable_nodes) == 0) { - if (n_excluded && get_options()->StrictNodes) { + if (n_excluded && get_options()->StrictNodes && warnings) { /* We only want to warn if StrictNodes is really set. Otherwise * we're just about to retry anyways. */ @@ -822,6 +827,15 @@ rend_client_get_random_intro_impl(const rend_data_t *rend_query, return extend_info_dup(intro->extend_info); } +/** Return true iff any introduction points still listed in entry are + * usable. */ +int +rend_client_any_intro_points_usable(const rend_cache_entry_t *entry) +{ + return rend_client_get_random_intro_impl( + entry, get_options()->StrictNodes, 0) != NULL; +} + /** Client-side authorizations for hidden services; map of onion address to * rend_service_authorization_t*. */ static strmap_t *auth_hid_servs = NULL; diff --git a/src/or/rendclient.h b/src/or/rendclient.h index 56ccde1464..3f2e58e30b 100644 --- a/src/or/rendclient.h +++ b/src/or/rendclient.h @@ -29,6 +29,7 @@ int rend_client_receive_rendezvous(origin_circuit_t *circ, void rend_client_desc_trynow(const char *query); extend_info_t *rend_client_get_random_intro(const rend_data_t *rend_query); +int rend_client_any_intro_points_usable(const rend_cache_entry_t *entry); int rend_client_send_introduction(origin_circuit_t *introcirc, origin_circuit_t *rendcirc); diff --git a/src/or/rendcommon.c b/src/or/rendcommon.c index f4c8888c04..9d6a89ef1f 100644 --- a/src/or/rendcommon.c +++ b/src/or/rendcommon.c @@ -934,7 +934,7 @@ rend_cache_lookup_entry(const char *query, int version, rend_cache_entry_t **e) tor_assert((*e)->parsed && (*e)->parsed->intro_nodes); /* XXX023 hack for now, to return "not found" if there are no intro * points remaining. See bug 997. */ - if (smartlist_len((*e)->parsed->intro_nodes) == 0) + if (! rend_client_any_intro_points_usable(*e)) return 0; return 1; }