[tor-commits] [tor/master] hs-v3: Report rendezvous circuit failure SOCKS ExtendedErrors

asn at torproject.org asn at torproject.org
Wed Apr 8 15:16:38 UTC 2020


commit cf39276f7810c58a1a53bdccf3c3d15001808625
Author: David Goulet <dgoulet at torproject.org>
Date:   Wed Dec 11 10:15:02 2019 -0500

    hs-v3: Report rendezvous circuit failure SOCKS ExtendedErrors
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/feature/hs/hs_circuit.c | 18 ++++++++++++++++
 src/feature/hs/hs_client.c  | 52 +++++++++++++++++++++++++++++++++++++++++++++
 src/feature/hs/hs_client.h  |  1 +
 3 files changed, 71 insertions(+)

diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index dc13c7045..53f574c14 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 4b9c9cb18..ceaba08ff 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 3660bfa96..685b10f95 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,





More information about the tor-commits mailing list