aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2019-12-11 10:15:02 -0500
committerDavid Goulet <dgoulet@torproject.org>2020-04-08 07:56:54 -0400
commitcf39276f7810c58a1a53bdccf3c3d15001808625 (patch)
treec8bdbdb4cdf8a410546e9295531b0d82671919d1
parentfdd6352506ccf3d085238d970bef962b592da35d (diff)
downloadtor-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.c18
-rw-r--r--src/feature/hs/hs_client.c52
-rw-r--r--src/feature/hs/hs_client.h1
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,