summaryrefslogtreecommitdiff
path: root/src/feature/rend/rendclient.c
diff options
context:
space:
mode:
authorNeel Chauhan <neel@neelc.org>2019-07-28 16:34:39 -0400
committerDavid Goulet <dgoulet@torproject.org>2019-10-30 08:47:21 -0400
commitf81e4aa831c51e47954c2d52b72066e796253d80 (patch)
tree980f71ca968c9857d5cb5dff86b3c3eb8f0a48c2 /src/feature/rend/rendclient.c
parentdce1f63d4407da0530111ebe049f286a38110f17 (diff)
downloadtor-f81e4aa831c51e47954c2d52b72066e796253d80.tar.gz
tor-f81e4aa831c51e47954c2d52b72066e796253d80.zip
hs-v2: Lookup intro failure cache when picking an intro from descriptor
When picking an intro point from the service descriptor, the client failed to lookup the failure cache. It made an HS v2 client re-pick bad intro points for which we already know it won't work in the first place. Based on Neel Chauhan original patch. Fixes #25568 Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/feature/rend/rendclient.c')
-rw-r--r--src/feature/rend/rendclient.c19
1 files changed, 15 insertions, 4 deletions
diff --git a/src/feature/rend/rendclient.c b/src/feature/rend/rendclient.c
index 2540066dfc..bc94c88efb 100644
--- a/src/feature/rend/rendclient.c
+++ b/src/feature/rend/rendclient.c
@@ -1048,18 +1048,29 @@ rend_client_get_random_intro_impl(const rend_cache_entry_t *entry,
const or_options_t *options = get_options();
smartlist_t *usable_nodes;
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,
* no nodes are usable. */
usable_nodes = smartlist_new();
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
* connection attempt from our list of usable nodes. */
- SMARTLIST_FOREACH(usable_nodes, rend_intro_point_t *, ip,
- if (ip->timed_out) {
- SMARTLIST_DEL_CURRENT(usable_nodes, ip);
- });
+ SMARTLIST_FOREACH_BEGIN(usable_nodes, const rend_intro_point_t *, ip) {
+ 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_FOREACH_END(ip);
again:
if (smartlist_len(usable_nodes) == 0) {