diff options
author | David Goulet <dgoulet@torproject.org> | 2019-12-11 10:15:02 -0500 |
---|---|---|
committer | David Goulet <dgoulet@torproject.org> | 2020-04-08 07:56:54 -0400 |
commit | cf39276f7810c58a1a53bdccf3c3d15001808625 (patch) | |
tree | c8bdbdb4cdf8a410546e9295531b0d82671919d1 | |
parent | fdd6352506ccf3d085238d970bef962b592da35d (diff) | |
download | tor-cf39276f7810c58a1a53bdccf3c3d15001808625.tar.gz tor-cf39276f7810c58a1a53bdccf3c3d15001808625.zip |
hs-v3: Report rendezvous circuit failure SOCKS ExtendedErrors
Signed-off-by: David Goulet <dgoulet@torproject.org>
-rw-r--r-- | src/feature/hs/hs_circuit.c | 18 | ||||
-rw-r--r-- | src/feature/hs/hs_client.c | 52 | ||||
-rw-r--r-- | src/feature/hs/hs_client.h | 1 |
3 files changed, 71 insertions, 0 deletions
diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c index dc13c7045e..53f574c14a 100644 --- a/src/feature/hs/hs_circuit.c +++ b/src/feature/hs/hs_circuit.c @@ -622,6 +622,20 @@ setup_introduce1_data(const hs_desc_intro_point_t *ip, } /** Helper: cleanup function for client circuit. This is for every HS version. + * It is called from hs_circ_cleanup_on_close() entry point. */ +static void +cleanup_on_close_client_circ(circuit_t *circ) +{ + tor_assert(circ); + + if (circuit_is_hs_v3(circ)) { + hs_client_circuit_cleanup_on_close(circ); + } + /* It is possible the circuit has an HS purpose but no identifier (rend_data + * or hs_ident). Thus possible that this passess through. */ +} + +/** Helper: cleanup function for client circuit. This is for every HS version. * It is called from hs_circ_cleanup_on_free() entry point. */ static void cleanup_on_free_client_circ(circuit_t *circ) @@ -1293,6 +1307,10 @@ hs_circ_cleanup_on_close(circuit_t *circ) { tor_assert(circ); + if (circuit_purpose_is_hs_client(circ->purpose)) { + cleanup_on_close_client_circ(circ); + } + /* On close, we simply remove it from the circuit map. It can not be used * anymore. We keep this code path fast and lean. */ diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c index 4b9c9cb186..ceaba08ff9 100644 --- a/src/feature/hs/hs_client.c +++ b/src/feature/hs/hs_client.c @@ -961,6 +961,27 @@ client_get_random_intro(const ed25519_public_key_t *service_pk) return ei; } +/** Called when a rendezvous circuit has timed out. Every streams attached to + * the circuit will get set with the SOCKS5_HS_REND_FAILED (0xF3) extended + * error code so if the connection to the rendezvous point ends up not + * working, this code could be sent back as a reason. */ +static void +socks_report_rend_circuit_timed_out(const origin_circuit_t *rend_circ) +{ + tor_assert(rend_circ); + + /* For each entry connections attached to this rendezvous circuit, report + * the error. */ + for (edge_connection_t *edge = rend_circ->p_streams; edge; + edge = edge->next_stream) { + entry_connection_t *entry = EDGE_TO_ENTRY_CONN(edge); + if (entry->socks_request) { + entry->socks_request->socks_extended_error_code = + SOCKS5_HS_REND_FAILED; + } + } +} + /** Called when introduction has failed meaning there is no more usable * introduction points to be used (either NACKed or failed) for the given * entry connection. @@ -1780,6 +1801,37 @@ get_hs_client_auths_map(void) /* ========== */ /** Called when a circuit was just cleaned up. This is done right before the + * circuit is marked for close. */ +void +hs_client_circuit_cleanup_on_close(const circuit_t *circ) +{ + bool has_timed_out; + + tor_assert(circ); + tor_assert(CIRCUIT_IS_ORIGIN(circ)); + + has_timed_out = + (circ->marked_for_close_orig_reason == END_CIRC_REASON_TIMEOUT); + + switch (circ->purpose) { + case CIRCUIT_PURPOSE_C_ESTABLISH_REND: + case CIRCUIT_PURPOSE_C_REND_READY: + case CIRCUIT_PURPOSE_C_REND_READY_INTRO_ACKED: + case CIRCUIT_PURPOSE_C_REND_JOINED: + /* Report extended SOCKS error code when a rendezvous circuit timeouts. + * This MUST be done on_close() because it is possible the entry + * connection would get closed before the circuit is freed and thus + * failing to report the error code. */ + if (has_timed_out) { + socks_report_rend_circuit_timed_out(CONST_TO_ORIGIN_CIRCUIT(circ)); + } + break; + default: + break; + } +} + +/** Called when a circuit was just cleaned up. This is done right before the * circuit is freed. */ void hs_client_circuit_cleanup_on_free(const circuit_t *circ) diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h index 3660bfa96c..685b10f955 100644 --- a/src/feature/hs/hs_client.h +++ b/src/feature/hs/hs_client.h @@ -110,6 +110,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_on_close(const circuit_t *circ); void hs_client_circuit_cleanup_on_free(const circuit_t *circ); int hs_client_receive_rendezvous_acked(origin_circuit_t *circ, |