commit cf75c1af666b983c3a828f13683240153646247b Author: David Goulet dgoulet@torproject.org Date: Tue Sep 26 10:54:46 2017 -0400
hs-v3: Don't fetch descriptor if we have a pending request
If 6 SOCKS requests are opened at once, it would have triggered 6 fetches which ultimately poke all 6 HSDir. We don't want that, if we have multiple SOCKS requests for the same service, do one fetch only.
Signed-off-by: David Goulet dgoulet@torproject.org --- src/or/connection_edge.c | 1 + src/or/hs_client.c | 34 ++++++++++++++++++++++++++++++++++ src/or/hs_client.h | 2 ++ 3 files changed, 37 insertions(+)
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c index 9098cb690..77dac62b0 100644 --- a/src/or/connection_edge.c +++ b/src/or/connection_edge.c @@ -1576,6 +1576,7 @@ connection_ap_handle_onion(entry_connection_t *conn, * connection. */ goto end; case HS_CLIENT_FETCH_LAUNCHED: + case HS_CLIENT_FETCH_PENDING: case HS_CLIENT_FETCH_HAVE_DESC: return 0; case HS_CLIENT_FETCH_ERROR: diff --git a/src/or/hs_client.c b/src/or/hs_client.c index 560ccf849..8ed19529b 100644 --- a/src/or/hs_client.c +++ b/src/or/hs_client.c @@ -108,6 +108,34 @@ purge_hid_serv_request(const ed25519_public_key_t *identity_pk) hs_purge_hid_serv_from_last_hid_serv_requests(base64_blinded_pk); }
+/* Return true iff there is at least one pending directory descriptor request + * for the service identity_pk. */ +static int +directory_request_is_pending(const ed25519_public_key_t *identity_pk) +{ + int ret = 0; + smartlist_t *conns = + connection_list_by_type_purpose(CONN_TYPE_DIR, DIR_PURPOSE_FETCH_HSDESC); + + SMARTLIST_FOREACH_BEGIN(conns, connection_t *, conn) { + const hs_ident_dir_conn_t *ident = TO_DIR_CONN(conn)->hs_ident; + if (BUG(ident == NULL)) { + /* A directory connection fetching a service descriptor can't have an + * empty hidden service identifier. */ + continue; + } + if (!ed25519_pubkey_eq(identity_pk, &ident->identity_pk)) { + continue; + } + ret = 1; + break; + } SMARTLIST_FOREACH_END(conn); + + /* No ownership of the objects in this list. */ + smartlist_free(conns); + return ret; +} + /* A v3 HS circuit successfully connected to the hidden service. Update the * stream state at <b>hs_conn_ident</b> appropriately. */ static void @@ -1046,6 +1074,12 @@ hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk) } }
+ /* Don't try to refetch while we have a pending request for it. */ + if (directory_request_is_pending(identity_pk)) { + log_info(LD_REND, "Already a pending directory request. Waiting on it."); + return HS_CLIENT_FETCH_PENDING; + } + return fetch_v3_desc(identity_pk); }
diff --git a/src/or/hs_client.h b/src/or/hs_client.h index 08ab7736b..1d0201903 100644 --- a/src/or/hs_client.h +++ b/src/or/hs_client.h @@ -27,6 +27,8 @@ typedef enum { HS_CLIENT_FETCH_NOT_ALLOWED = 3, /* We are missing information to be able to launch a request. */ HS_CLIENT_FETCH_MISSING_INFO = 4, + /* There is a pending fetch for the requested service. */ + HS_CLIENT_FETCH_PENDING = 5, } hs_client_fetch_status_t;
void hs_client_note_connection_attempt_succeeded(