[tor-commits] [tor/master] hs-v3: Stall SOCKS connection when no live consensus available

nickm at torproject.org nickm at torproject.org
Tue Sep 12 19:05:57 UTC 2017


commit 6b4eace248272f4defae0f6cc9933588b1b498b3
Author: David Goulet <dgoulet at torproject.org>
Date:   Tue Sep 12 12:24:26 2017 -0400

    hs-v3: Stall SOCKS connection when no live consensus available
    
    Fixes #23481
    
    Signed-off-by: David Goulet <dgoulet at torproject.org>
---
 src/or/connection_edge.c  | 26 +++++++++++++++++++++++---
 src/or/hs_client.c        | 31 +++++++++++++++++++++++--------
 src/or/hs_client.h        | 16 ++++++++++++++++
 src/test/test_entryconn.c |  2 +-
 4 files changed, 63 insertions(+), 12 deletions(-)

diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index dfa89bc2c..d1b8abda8 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -80,6 +80,7 @@
 #include "hs_client.h"
 #include "hs_circuit.h"
 #include "main.h"
+#include "networkstatus.h"
 #include "nodelist.h"
 #include "policies.h"
 #include "proto_http.h"
@@ -1561,18 +1562,37 @@ connection_ap_handle_onion(entry_connection_t *conn,
     if (addresstype == ONION_V2_HOSTNAME) {
       tor_assert(edge_conn->rend_data);
       rend_client_refetch_v2_renddesc(edge_conn->rend_data);
+      /* Whatever the result of the refetch, we don't go further. */
+      return 0;
     } else {
       tor_assert(addresstype == ONION_V3_HOSTNAME);
       tor_assert(edge_conn->hs_ident);
-      hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
+      /* Attempt to fetch the hsv3 descriptor. Check the retval to see how it
+       * went and act accordingly. */
+      int ret = hs_client_refetch_hsdesc(&edge_conn->hs_ident->identity_pk);
+      switch (ret) {
+      case HS_CLIENT_FETCH_MISSING_INFO:
+        /* By going to the end, the connection is put in waiting for a circuit
+         * state which means that it will be retried and consider as a pending
+         * connection. */
+        goto end;
+      case HS_CLIENT_FETCH_LAUNCHED:
+      case HS_CLIENT_FETCH_HAVE_DESC:
+        return 0;
+      case HS_CLIENT_FETCH_ERROR:
+      case HS_CLIENT_FETCH_NO_HSDIRS:
+      case HS_CLIENT_FETCH_NOT_ALLOWED:
+        /* Can't proceed further and better close the SOCKS request. */
+        return -1;
+      }
     }
-    return 0;
   }
 
   /* We have the descriptor!  So launch a connection to the HS. */
-  base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
   log_info(LD_REND, "Descriptor is here. Great.");
 
+ end:
+  base_conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
   /* We'll try to attach it at the next event loop, or whenever
    * we call connection_ap_attach_pending() */
   connection_ap_mark_as_pending_circuit(conn);
diff --git a/src/or/hs_client.c b/src/or/hs_client.c
index 620ef3a10..be5ece068 100644
--- a/src/or/hs_client.c
+++ b/src/or/hs_client.c
@@ -152,7 +152,7 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
   /* ...and base64 it. */
   retval = ed25519_public_to_base64(base64_blinded_pubkey, &blinded_pubkey);
   if (BUG(retval < 0)) {
-    return -1;
+    return HS_CLIENT_FETCH_ERROR;
   }
 
   /* Copy onion pk to a dir_ident so that we attach it to the dir conn */
@@ -180,7 +180,7 @@ directory_launch_v3_desc_fetch(const ed25519_public_key_t *onion_identity_pk,
   memwipe(base64_blinded_pubkey, 0, sizeof(base64_blinded_pubkey));
   memwipe(&hs_conn_dir_ident, 0, sizeof(hs_conn_dir_ident));
 
-  return 1;
+  return HS_CLIENT_FETCH_LAUNCHED;
 }
 
 /** Return the HSDir we should use to fetch the descriptor of the hidden
@@ -236,7 +236,7 @@ fetch_v3_desc(const ed25519_public_key_t *onion_identity_pk)
   hsdir_rs = pick_hsdir_v3(onion_identity_pk);
   if (!hsdir_rs) {
     log_info(LD_REND, "Couldn't pick a v3 hsdir.");
-    return 0;
+    return HS_CLIENT_FETCH_NO_HSDIRS;
   }
 
   return directory_launch_v3_desc_fetch(onion_identity_pk, hsdir_rs);
@@ -998,8 +998,7 @@ hs_client_any_intro_points_usable(const ed25519_public_key_t *service_pk,
 /** Launch a connection to a hidden service directory to fetch a hidden
  * service descriptor using <b>identity_pk</b> to get the necessary keys.
  *
- * On success, 1 is returned. If no hidden service is left to ask, return 0.
- * On error, -1 is returned. (retval is only used by unittests right now) */
+ * A hs_client_fetch_status_t code is returned. */
 int
 hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
 {
@@ -1009,7 +1008,23 @@ hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
   if (!get_options()->FetchHidServDescriptors) {
     log_warn(LD_REND, "We received an onion address for a hidden service "
                       "descriptor but we are configured to not fetch.");
-    return 0;
+    return HS_CLIENT_FETCH_NOT_ALLOWED;
+  }
+
+  /* Without a live consensus we can't do any client actions. It is needed to
+   * compute the hashring for a service. */
+  if (!networkstatus_get_live_consensus(approx_time())) {
+    log_info(LD_REND, "Can't fetch descriptor for service %s because we "
+                      "are missing a live consensus. Stalling connection.",
+               safe_str_client(ed25519_fmt(identity_pk)));
+    return HS_CLIENT_FETCH_MISSING_INFO;
+  }
+
+  if (!router_have_minimum_dir_info()) {
+    log_info(LD_REND, "Can't fetch descriptor for service %s because we "
+                      "dont have enough descriptors. Stalling connection.",
+               safe_str_client(ed25519_fmt(identity_pk)));
+    return HS_CLIENT_FETCH_MISSING_INFO;
   }
 
   /* Check if fetching a desc for this HS is useful to us right now */
@@ -1019,8 +1034,8 @@ hs_client_refetch_hsdesc(const ed25519_public_key_t *identity_pk)
     if (cached_desc && hs_client_any_intro_points_usable(identity_pk,
                                                          cached_desc)) {
       log_info(LD_GENERAL, "We would fetch a v3 hidden service descriptor "
-                            "but we already have a usable descriptor.");
-      return 0;
+                           "but we already have a usable descriptor.");
+      return HS_CLIENT_FETCH_HAVE_DESC;
     }
   }
 
diff --git a/src/or/hs_client.h b/src/or/hs_client.h
index 522770450..3ea2b8cdf 100644
--- a/src/or/hs_client.h
+++ b/src/or/hs_client.h
@@ -13,6 +13,22 @@
 #include "hs_descriptor.h"
 #include "hs_ident.h"
 
+/* Status code of a descriptor fetch request. */
+typedef enum {
+  /* Something internally went wrong. */
+  HS_CLIENT_FETCH_ERROR        = -1,
+  /* The fetch request has been launched successfully. */
+  HS_CLIENT_FETCH_LAUNCHED     = 0,
+  /* We already have a usable descriptor. No fetch. */
+  HS_CLIENT_FETCH_HAVE_DESC    = 1,
+  /* No more HSDir available to query. */
+  HS_CLIENT_FETCH_NO_HSDIRS    = 2,
+  /* The fetch request is not allowed. */
+  HS_CLIENT_FETCH_NOT_ALLOWED  = 3,
+  /* We are missing information to be able to launch a request. */
+  HS_CLIENT_FETCH_MISSING_INFO = 4,
+} hs_client_fetch_status_t;
+
 void hs_client_note_connection_attempt_succeeded(
                                        const edge_connection_t *conn);
 
diff --git a/src/test/test_entryconn.c b/src/test/test_entryconn.c
index 9fe3db26f..2d28f1d42 100644
--- a/src/test/test_entryconn.c
+++ b/src/test/test_entryconn.c
@@ -815,7 +815,7 @@ test_entryconn_rewrite_onion_v3(void *arg)
   tt_int_op(retval, OP_EQ, 0);
 
   /* Check connection state after rewrite */
-  tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_RENDDESC_WAIT);
+  tt_int_op(ENTRY_TO_CONN(conn)->state, OP_EQ, AP_CONN_STATE_CIRCUIT_WAIT);
   /* check that the address got rewritten */
   tt_str_op(conn->socks_request->address, OP_EQ,
             "p3xnclpu4mu22dwaurjtsybyqk4xfjmcfz6z62yl24uwmhjatiwnlnad");



More information about the tor-commits mailing list