Merge branch 'tor-github/pr/1484'

This commit is contained in:
George Kadianakis 2019-10-31 15:31:14 +08:00
commit fa0257eda0
4 changed files with 33 additions and 4 deletions

5
changes/bug25568 Normal file
View File

@ -0,0 +1,5 @@
o Minor bugfixes (onion service v2):
- When sending the INTRO cell for a v2 Onion Service, look at the failure
cache alongside timeout values to check if the intro point is marked
as failed. Previously, we only looked at if the relay timeout values.
Fixes bug 25568; bugfix on 0.2.7.3-rc. Patch by Neel Chauhan.

View File

@ -228,6 +228,17 @@ rend_cache_entry_free_void(void *p)
rend_cache_entry_free_(p); rend_cache_entry_free_(p);
} }
/** Check if a failure cache entry exists for the given intro point. */
bool
rend_cache_intro_failure_exists(const char *service_id,
const uint8_t *intro_identity)
{
tor_assert(service_id);
tor_assert(intro_identity);
return cache_failure_intro_lookup(intro_identity, service_id, NULL);
}
/** Free all storage held by the service descriptor cache. */ /** Free all storage held by the service descriptor cache. */
void void
rend_cache_free_all(void) rend_cache_free_all(void)

View File

@ -80,6 +80,8 @@ int rend_cache_store_v2_desc_as_client(const char *desc,
rend_cache_entry_t **entry); rend_cache_entry_t **entry);
size_t rend_cache_get_total_allocation(void); size_t rend_cache_get_total_allocation(void);
bool rend_cache_intro_failure_exists(const char *service_id,
const uint8_t *intro_identity);
void rend_cache_intro_failure_note(rend_intro_point_failure_t failure, void rend_cache_intro_failure_note(rend_intro_point_failure_t failure,
const uint8_t *identity, const uint8_t *identity,
const char *service_id); const char *service_id);

View File

@ -1048,18 +1048,29 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry,
const or_options_t *options = get_options(); const or_options_t *options = get_options();
smartlist_t *usable_nodes; smartlist_t *usable_nodes;
int n_excluded = 0; int n_excluded = 0;
char service_id[REND_SERVICE_ID_LEN_BASE32 + 1];
/* We'll keep a separate list of the usable nodes. If this becomes empty, /* We'll keep a separate list of the usable nodes. If this becomes empty,
* no nodes are usable. */ * no nodes are usable. */
usable_nodes = smartlist_new(); usable_nodes = smartlist_new();
smartlist_add_all(usable_nodes, entry->parsed->intro_nodes); smartlist_add_all(usable_nodes, entry->parsed->intro_nodes);
/* Get service ID so we can use it to query the failure cache. If we fail to
* parse it, this cache entry is no good. */
if (BUG(rend_get_service_id(entry->parsed->pk, service_id) < 0)) {
return NULL;
}
/* Remove the intro points that have timed out during this HS /* Remove the intro points that have timed out during this HS
* connection attempt from our list of usable nodes. */ * connection attempt from our list of usable nodes. */
SMARTLIST_FOREACH(usable_nodes, rend_intro_point_t *, ip, SMARTLIST_FOREACH_BEGIN(usable_nodes, const rend_intro_point_t *, ip) {
if (ip->timed_out) { bool failed_intro =
rend_cache_intro_failure_exists(service_id,
(const uint8_t *) ip->extend_info->identity_digest);
if (ip->timed_out || failed_intro) {
SMARTLIST_DEL_CURRENT(usable_nodes, ip); SMARTLIST_DEL_CURRENT(usable_nodes, ip);
}); };
} SMARTLIST_FOREACH_END(ip);
again: again:
if (smartlist_len(usable_nodes) == 0) { if (smartlist_len(usable_nodes) == 0) {