[tor-commits] [tor/master] Implement Tor2webRendezvousPoints functionality.

nickm at torproject.org nickm at torproject.org
Wed Feb 11 20:06:13 UTC 2015


commit 24a7726955f415564412582602271de9de3164de
Author: George Kadianakis <desnacked at riseup.net>
Date:   Mon Sep 15 15:28:11 2014 +0300

    Implement Tor2webRendezvousPoints functionality.
---
 src/or/circuitbuild.c |   82 +++++++++++++++++++++++++++++++++++++++++++++++--
 src/or/circuitbuild.h |    3 ++
 src/or/routerlist.c   |    2 +-
 src/or/routerlist.h   |    4 +++
 4 files changed, 87 insertions(+), 4 deletions(-)

diff --git a/src/or/circuitbuild.c b/src/or/circuitbuild.c
index edf7d28..5de6f3c 100644
--- a/src/or/circuitbuild.c
+++ b/src/or/circuitbuild.c
@@ -1735,6 +1735,79 @@ choose_good_exit_server_general(int need_uptime, int need_capacity)
   return NULL;
 }
 
+/* The config option Tor2webRendezvousPoints has been set and we need
+ * to pick an RP out of that set. Make sure that the RP we choose is
+ * alive, and return it. Return NULL if no usable RP could be found in
+ * Tor2webRendezvousPoints. */
+STATIC const node_t *
+pick_tor2web_rendezvous_node(router_crn_flags_t flags,
+                             const or_options_t *options)
+{
+  const node_t *rp_node = NULL;
+  const int allow_invalid = (flags & CRN_ALLOW_INVALID) != 0;
+  const int need_desc = (flags & CRN_NEED_DESC) != 0;
+
+  smartlist_t *whitelisted_live_rps = smartlist_new();
+  smartlist_t *all_live_nodes = smartlist_new();
+
+  tor_assert(options->Tor2webRendezvousPoints);
+
+  /* Add all running nodes to all_live_nodes */
+  router_add_running_nodes_to_smartlist(all_live_nodes,
+                                        allow_invalid,
+                                        0, 0, 0,
+                                        need_desc);
+
+  /* Filter all_live_nodes to only add live *and* whitelisted RPs to
+   * the list whitelisted_live_rps. */
+  SMARTLIST_FOREACH_BEGIN(all_live_nodes, node_t *, live_node) {
+    if (routerset_contains_node(options->Tor2webRendezvousPoints, live_node)) {
+      smartlist_add(whitelisted_live_rps, live_node);
+    }
+  } SMARTLIST_FOREACH_END(live_node);
+
+  /* Honor ExcludeNodes */
+  if (options->ExcludeNodes) {
+    routerset_subtract_nodes(whitelisted_live_rps, options->ExcludeNodes);
+  }
+
+  /* Now pick randomly amongst the whitelisted RPs. No need to waste time
+     doing bandwidth load balancing, for most use cases
+     'whitelisted_live_rps' contains a single OR anyway. */
+  rp_node = smartlist_choose(whitelisted_live_rps);
+
+  if (!rp_node) {
+    log_warn(LD_REND, "Could not find a Rendezvous Point that suits "
+             "the purposes of Tor2webRendezvousPoints. Choosing random one.");
+  }
+
+  smartlist_free(whitelisted_live_rps);
+  smartlist_free(all_live_nodes);
+
+  return rp_node;
+}
+
+/* Pick a Rendezvous Point for our HS circuits according to <b>flags</b>. */
+static const node_t *
+pick_rendezvous_node(router_crn_flags_t flags)
+{
+  const or_options_t *options = get_options();
+
+  if (options->AllowInvalid_ & ALLOW_INVALID_RENDEZVOUS)
+    flags |= CRN_ALLOW_INVALID;
+
+  /* The user wants us to pick specific RPs. */
+  if (options->Tor2webRendezvousPoints) {
+    const node_t *tor2web_rp = pick_tor2web_rendezvous_node(flags, options);
+    if (tor2web_rp) {
+      return tor2web_rp;
+    }
+    /* Else, if no tor2web RP was found, fall back to choosing a random node */
+  }
+
+  return router_choose_random_node(NULL, options->ExcludeNodes, flags);
+}
+
 /** Return a pointer to a suitable router to be the exit node for the
  * circuit of purpose <b>purpose</b> that we're about to build (or NULL
  * if no router is suitable).
@@ -1765,9 +1838,12 @@ choose_good_exit_server(uint8_t purpose,
       else
         return choose_good_exit_server_general(need_uptime,need_capacity);
     case CIRCUIT_PURPOSE_C_ESTABLISH_REND:
-      if (options->AllowInvalid_ & ALLOW_INVALID_RENDEZVOUS)
-        flags |= CRN_ALLOW_INVALID;
-      return router_choose_random_node(NULL, options->ExcludeNodes, flags);
+      {
+        /* Pick a new RP */
+        const node_t *rendezvous_node = pick_rendezvous_node(flags);
+        log_info(LD_REND, "Picked new RP: %s", node_describe(rendezvous_node));
+        return rendezvous_node;
+      }
   }
   log_warn(LD_BUG,"Unhandled purpose %d", purpose);
   tor_fragile_assert();
diff --git a/src/or/circuitbuild.h b/src/or/circuitbuild.h
index 71caea9..99411c0 100644
--- a/src/or/circuitbuild.h
+++ b/src/or/circuitbuild.h
@@ -60,6 +60,9 @@ const node_t *choose_good_entry_server(uint8_t purpose,
 
 #ifdef CIRCUITBUILD_PRIVATE
 STATIC circid_t get_unique_circ_id_by_chan(channel_t *chan);
+STATIC const node_t *pick_tor2web_rendezvous_node(router_crn_flags_t flags,
+                                                  const or_options_t *options);
+
 #endif
 
 #endif
diff --git a/src/or/routerlist.c b/src/or/routerlist.c
index 1faa05f..5fc30f1 100644
--- a/src/or/routerlist.c
+++ b/src/or/routerlist.c
@@ -1732,7 +1732,7 @@ routerlist_add_node_and_family(smartlist_t *sl, const routerinfo_t *router)
 /** Add every suitable node from our nodelist to <b>sl</b>, so that
  * we can pick a node for a circuit.
  */
-static void
+void
 router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
                                       int need_uptime, int need_capacity,
                                       int need_guard, int need_desc)
diff --git a/src/or/routerlist.h b/src/or/routerlist.h
index 52f2303..83fea78 100644
--- a/src/or/routerlist.h
+++ b/src/or/routerlist.h
@@ -58,6 +58,10 @@ const routerstatus_t *router_pick_fallback_dirserver(dirinfo_type_t type,
 int router_get_my_share_of_directory_requests(double *v3_share_out);
 void router_reset_status_download_failures(void);
 int routers_have_same_or_addrs(const routerinfo_t *r1, const routerinfo_t *r2);
+void router_add_running_nodes_to_smartlist(smartlist_t *sl, int allow_invalid,
+                                           int need_uptime, int need_capacity,
+                                           int need_guard, int need_desc);
+
 const routerinfo_t *routerlist_find_my_routerinfo(void);
 uint32_t router_get_advertised_bandwidth(const routerinfo_t *router);
 uint32_t router_get_advertised_bandwidth_capped(const routerinfo_t *router);





More information about the tor-commits mailing list