From 903c6cf1ab5ba115bbfd33385e0acd5f88ad2ba3 Mon Sep 17 00:00:00 2001 From: Micah Elizabeth Scott Date: Fri, 31 Mar 2023 13:36:58 -0700 Subject: hs_pow: client side effort adjustment The goal of this patch is to add an additional mechanism for adjusting PoW effort upwards, where clients rather than services can choose to solve their puzzles at a higher effort than what was suggested in the descriptor. I wanted to use hs_cache's existing unreachability stats to drive this effort bump, but this revealed some cases where a circuit (intro or rend) closed early on can end up in hs_cache with an all zero intro point key, where nobody will find it. This moves intro_auth_pk initialization earlier in a couple places and adds nonfatal asserts to catch the problem if it shows up elsewhere. The actual effort adjustment method I chose is to multiply the suggested effort by (1 + unresponsive_count), then ensure the result is at least 1. If a service has suggested effort of 0 but we fail to connect, retries will all use an effort of 1. If the suggestion was 50, we'll try 50, 100, 150, 200, etc. This is bounded both by our client effort limit and by the limit on unresponsive_count (currently 5). Signed-off-by: Micah Elizabeth Scott --- src/core/or/circuituse.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'src/core/or/circuituse.c') diff --git a/src/core/or/circuituse.c b/src/core/or/circuituse.c index b78f72e835..ac9005e1d4 100644 --- a/src/core/or/circuituse.c +++ b/src/core/or/circuituse.c @@ -564,14 +564,6 @@ 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; @@ -2560,6 +2552,11 @@ circuit_get_open_circ_or_launch(entry_connection_t *conn, circ->hs_ident = hs_ident_circuit_new(&edge_conn->hs_ident->identity_pk); } + if (desired_circuit_purpose == CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT) { + if (hs_client_setup_intro_circ_auth_key(circ) < 0) { + return 0; + } + } if (circ->base_.purpose == CIRCUIT_PURPOSE_C_ESTABLISH_REND && circ->base_.state == CIRCUIT_STATE_OPEN) circuit_has_opened(circ); @@ -3012,6 +3009,16 @@ connection_ap_handshake_attach_circuit(entry_connection_t *conn) conn, CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT, &introcirc); if (retval < 0) return -1; /* failed */ + if (rendcirc && introcirc) { + /* Let's fill out the hs_ident fully as soon as possible, so that + * unreachability counts can be updated properly even if circuits close + * early. */ + tor_assert_nonfatal(!ed25519_public_key_is_zero( + &introcirc->hs_ident->intro_auth_pk)); + ed25519_pubkey_copy(&rendcirc->hs_ident->intro_auth_pk, + &introcirc->hs_ident->intro_auth_pk); + } + if (retval > 0) { /* one has already sent the intro. keep waiting. */ tor_assert(introcirc); -- cgit v1.2.3-54-g00ecf