mirror of
https://gitlab.torproject.org/tpo/core/tor.git
synced 2024-11-24 12:23:32 +01:00
hs-v3: Note client intro circuit failure
Report back to the v3 subsystem any introduction point client circuit failure so they can be noted down in the failure cache. Fixes #32020 Signed-off-by: David Goulet <dgoulet@torproject.org>
This commit is contained in:
parent
1aafe3376e
commit
7f83c43594
@ -20,6 +20,7 @@
|
||||
#include "feature/hs/hs_cell.h"
|
||||
#include "feature/hs/hs_circuit.h"
|
||||
#include "feature/hs/hs_circuitmap.h"
|
||||
#include "feature/hs/hs_client.h"
|
||||
#include "feature/hs/hs_ident.h"
|
||||
#include "feature/hs/hs_service.h"
|
||||
#include "feature/nodelist/describe.h"
|
||||
@ -619,6 +620,22 @@ setup_introduce1_data(const hs_desc_intro_point_t *ip,
|
||||
return ret;
|
||||
}
|
||||
|
||||
/** Helper: cleanup function for client circuit. This is for every HS version.
|
||||
* It is called from hs_circ_cleanup() entry point. */
|
||||
static void
|
||||
cleanup_client_circ(circuit_t *circ)
|
||||
{
|
||||
tor_assert(circ);
|
||||
|
||||
if (circuit_is_hs_v2(circ)) {
|
||||
rend_client_circuit_cleanup(circ);
|
||||
} else if (circuit_is_hs_v3(circ)) {
|
||||
hs_client_circuit_cleanup(circ);
|
||||
}
|
||||
/* It is possible the circuit has an HS purpose but no identifier (rend_data
|
||||
* or hs_ident). Thus possible that this passess through. */
|
||||
}
|
||||
|
||||
/* ========== */
|
||||
/* Public API */
|
||||
/* ========== */
|
||||
@ -1206,21 +1223,12 @@ hs_circ_cleanup(circuit_t *circ)
|
||||
{
|
||||
tor_assert(circ);
|
||||
|
||||
/* v2 specific circuits. */
|
||||
if (circuit_is_hs_v2(circ)) {
|
||||
if (circuit_is_hs_client(circ)) {
|
||||
rend_client_circuit_cleanup(circ);
|
||||
}
|
||||
if (circuit_purpose_is_hs_client(circ->purpose)) {
|
||||
cleanup_client_circ(circ);
|
||||
}
|
||||
|
||||
/* From this point on, it is v3 specific. */
|
||||
|
||||
/* If it's a service-side intro circ, notify the HS subsystem for the intro
|
||||
* point circuit closing so it can be dealt with cleanly. */
|
||||
if (circ->purpose == CIRCUIT_PURPOSE_S_ESTABLISH_INTRO ||
|
||||
circ->purpose == CIRCUIT_PURPOSE_S_INTRO) {
|
||||
hs_service_intro_circ_has_closed(TO_ORIGIN_CIRCUIT(circ));
|
||||
}
|
||||
/* Actions that MUST happen for every circuits regardless of what was done
|
||||
* on it before. */
|
||||
|
||||
/* Clear HS circuitmap token for this circ (if any). Very important to be
|
||||
* done after the HS subsystem has been notified of the close else the
|
||||
|
@ -1522,6 +1522,56 @@ get_hs_client_auths_map(void)
|
||||
/* Public API */
|
||||
/* ========== */
|
||||
|
||||
/** Called when a circuit was just cleaned up. This is done right before the
|
||||
* circuit is freed. */
|
||||
void
|
||||
hs_client_circuit_cleanup(const circuit_t *circ)
|
||||
{
|
||||
bool has_timed_out;
|
||||
rend_intro_point_failure_t failure = INTRO_POINT_FAILURE_GENERIC;
|
||||
const origin_circuit_t *orig_circ = NULL;
|
||||
|
||||
tor_assert(circ);
|
||||
tor_assert(CIRCUIT_IS_ORIGIN(circ));
|
||||
|
||||
orig_circ = CONST_TO_ORIGIN_CIRCUIT(circ);
|
||||
tor_assert(orig_circ->hs_ident);
|
||||
|
||||
has_timed_out =
|
||||
(circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT);
|
||||
if (has_timed_out) {
|
||||
failure = INTRO_POINT_FAILURE_TIMEOUT;
|
||||
}
|
||||
|
||||
switch (circ->purpose) {
|
||||
case CIRCUIT_PURPOSE_C_INTRODUCE_ACK_WAIT:
|
||||
log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
|
||||
"(awaiting ACK). Failure code: %d",
|
||||
safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
|
||||
safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)),
|
||||
failure);
|
||||
hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
|
||||
&orig_circ->hs_ident->intro_auth_pk,
|
||||
failure);
|
||||
break;
|
||||
case CIRCUIT_PURPOSE_C_INTRODUCING:
|
||||
if (has_timed_out || !orig_circ->build_state) {
|
||||
break;
|
||||
}
|
||||
failure = INTRO_POINT_FAILURE_UNREACHABLE;
|
||||
log_info(LD_REND, "Failed v3 intro circ for service %s to intro point %s "
|
||||
"(while building circuit). Marking as unreachable.",
|
||||
safe_str_client(ed25519_fmt(&orig_circ->hs_ident->identity_pk)),
|
||||
safe_str_client(build_state_get_exit_nickname(orig_circ->build_state)));
|
||||
hs_cache_client_intro_state_note(&orig_circ->hs_ident->identity_pk,
|
||||
&orig_circ->hs_ident->intro_auth_pk,
|
||||
failure);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/** A circuit just finished connecting to a hidden service that the stream
|
||||
* <b>conn</b> has been waiting for. Let the HS subsystem know about this. */
|
||||
void
|
||||
|
@ -112,6 +112,7 @@ int hs_client_send_introduce1(origin_circuit_t *intro_circ,
|
||||
origin_circuit_t *rend_circ);
|
||||
|
||||
void hs_client_circuit_has_opened(origin_circuit_t *circ);
|
||||
void hs_client_circuit_cleanup(const circuit_t *circ);
|
||||
|
||||
int hs_client_receive_rendezvous_acked(origin_circuit_t *circ,
|
||||
const uint8_t *payload,
|
||||
|
Loading…
Reference in New Issue
Block a user