[tor-commits] [tor/master] hs-v3: Note client intro circuit failure

asn at torproject.org asn at torproject.org
Wed Nov 27 13:36:50 UTC 2019


commit 7f83c43594dcf13fb04352f5faa8db2cd86354c1
Author: David Goulet <dgoulet at torproject.org>
Date:   Wed Oct 30 15:56:17 2019 -0400

    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 at torproject.org>
---
 src/feature/hs/hs_circuit.c | 34 ++++++++++++++++++------------
 src/feature/hs/hs_client.c  | 50 +++++++++++++++++++++++++++++++++++++++++++++
 src/feature/hs/hs_client.h  |  1 +
 3 files changed, 72 insertions(+), 13 deletions(-)

diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c
index 1a3767ce6..8640129f3 100644
--- a/src/feature/hs/hs_circuit.c
+++ b/src/feature/hs/hs_circuit.c
@@ -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
diff --git a/src/feature/hs/hs_client.c b/src/feature/hs/hs_client.c
index 787b29b57..716b6a26a 100644
--- a/src/feature/hs/hs_client.c
+++ b/src/feature/hs/hs_client.c
@@ -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
diff --git a/src/feature/hs/hs_client.h b/src/feature/hs/hs_client.h
index 04827ea92..a0f1c7758 100644
--- a/src/feature/hs/hs_client.h
+++ b/src/feature/hs/hs_client.h
@@ -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,





More information about the tor-commits mailing list