From c2f6b057b88ea3ee4d3a4a86ec198775d50c6d4c Mon Sep 17 00:00:00 2001 From: David Goulet Date: Wed, 29 Jun 2022 15:00:59 -0400 Subject: hs: Don't expire RP circuits to HS with PoW Signed-off-by: David Goulet --- src/core/or/circuituse.c | 14 ++++++++++++-- src/core/or/connection_edge.c | 18 +++++++++++++++++- src/core/or/entry_connection_st.h | 4 ++++ 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index 6956cf9849..d5879a21eb 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -564,6 +564,14 @@ circuit_expire_building(void) continue; } + /* Ignore circuits that are waiting for an introduction to a service with + * PoW enabled, it can take an arbitrary amount of time. They will get + * cleaned up if the SOCKS connection is closed. */ + if (TO_ORIGIN_CIRCUIT(victim)->hs_with_pow_circ && + victim->purpose == CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED) { + continue; + } + build_state = TO_ORIGIN_CIRCUIT(victim)->build_state; if (build_state && build_state->onehop_tunnel) cutoff = begindir_cutoff; @@ -2841,8 +2849,10 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) conn_age = (int)(time(NULL) - base_conn->timestamp_created); - /* Is this connection so old that we should give up on it? */ - if (conn_age >= get_options()->SocksTimeout) { + /* Is this connection so old that we should give up on it? Don't timeout if + * this is a connection to an HS with PoW enabled because it can take an + * arbitrary amount of time. */ + if (conn_age >= get_options()->SocksTimeout && !conn->hs_with_pow_conn) { int severity = (tor_addr_is_null(&base_conn->addr) && !base_conn->port) ? LOG_INFO : LOG_NOTICE; log_fn(severity, LD_APP, diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index e1eeb2f64f..f21779a80c 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -1213,7 +1213,10 @@ connection_ap_expire_beginning(void) * it here too because controllers that put streams in controller_wait * state never ask Tor to attach the circuit. */ if (AP_CONN_STATE_IS_UNATTACHED(base_conn->state)) { - if (seconds_since_born >= options->SocksTimeout) { + /* If this is a connection to an HS with PoW defenses enabled, we need to + * wait longer than the usual Socks timeout. */ + if (seconds_since_born >= options->SocksTimeout && + !entry_conn->hs_with_pow_conn) { log_fn(severity, LD_APP, "Tried for %d seconds to get a connection to %s:%d. " "Giving up. (%s)", @@ -2051,6 +2054,19 @@ connection_ap_handle_onion(entry_connection_t *conn, descriptor_is_usable = hs_client_any_intro_points_usable(&hs_conn_ident->identity_pk, cached_desc); + /* Check if PoW parameters have expired. If yes, the descriptor is + * unusable. */ + if (cached_desc->encrypted_data.pow_params) { + if (cached_desc->encrypted_data.pow_params->expiration_time < + approx_time()) { + log_info(LD_REND, "Descriptor PoW parameters have expired."); + descriptor_is_usable = 0; + } else { + /* Mark that the connection is to an HS with PoW defenses on. */ + conn->hs_with_pow_conn = 1; + } + } + log_info(LD_GENERAL, "Found %s descriptor in cache for %s. %s.", (descriptor_is_usable) ? "usable" : "unusable", safe_str_client(socks->address), diff --git a/src/core/or/entry_connection_st.h b/src/core/or/entry_connection_st.h index 500de7521b..a9484bece2 100644 --- a/src/core/or/entry_connection_st.h +++ b/src/core/or/entry_connection_st.h @@ -96,6 +96,10 @@ struct entry_connection_t { * the exit has sent a CONNECTED cell) and we have chosen to use it. */ unsigned int may_use_optimistic_data : 1; + + /** True iff this is a connection to a HS that has PoW defenses enabled, + * so we know not to apply the usual SOCKS timeout. */ + unsigned int hs_with_pow_conn : 1; }; /** Cast a entry_connection_t subtype pointer to a edge_connection_t **/ -- cgit v1.2.3-54-g00ecf