[tor-commits] [tor/master] prop224: Client function to pick intro point
nickm at torproject.org
nickm at torproject.org
Thu Aug 24 19:13:52 UTC 2017
commit abb840bf6431cfeb4f5e32ae2774fcde29e7724d
Author: David Goulet <dgoulet at torproject.org>
Date: Fri Jul 21 15:19:32 2017 -0400
prop224: Client function to pick intro point
From an edge connection object, add a function that randomly pick an
introduction point for the requested service.
This follows the code design of rend_client_get_random_intro() and returns an
extend_info_t object ready to be used to extend to.
At this commit, it is not used yet.
Signed-off-by: David Goulet <dgoulet at torproject.org>
---
src/or/hs_client.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++++++++
src/or/hs_client.h | 4 +-
2 files changed, 120 insertions(+), 1 deletion(-)
diff --git a/src/or/hs_client.c b/src/or/hs_client.c
index cf9bdba5a..a593999f2 100644
--- a/src/or/hs_client.c
+++ b/src/or/hs_client.c
@@ -20,6 +20,7 @@
#include "directory.h"
#include "hs_client.h"
#include "router.h"
+#include "routerset.h"
#include "circuitlist.h"
#include "circuituse.h"
#include "connection.h"
@@ -387,6 +388,109 @@ client_rendezvous_circ_has_opened(origin_circuit_t *circ)
hs_circ_send_establish_rendezvous(circ);
}
+/* This is an helper function that convert a descriptor intro point object ip
+ * to a newly allocated extend_info_t object fully initialized. Return NULL if
+ * we can't convert it for which chances are that we are missing or malformed
+ * link specifiers. */
+static extend_info_t *
+desc_intro_point_to_extend_info(const hs_desc_intro_point_t *ip)
+{
+ extend_info_t *ei;
+ smartlist_t *lspecs = smartlist_new();
+
+ tor_assert(ip);
+
+ /* We first encode the descriptor link specifiers into the binary
+ * representation which is a trunnel object. */
+ SMARTLIST_FOREACH_BEGIN(ip->link_specifiers,
+ const hs_desc_link_specifier_t *, desc_lspec) {
+ link_specifier_t *lspec = hs_desc_encode_lspec(desc_lspec);
+ smartlist_add(lspecs, lspec);
+ } SMARTLIST_FOREACH_END(desc_lspec);
+
+ /* Explicitely put the direct connection option to 0 because this is client
+ * side and there is no such thing as a non anonymous client. */
+ ei = hs_get_extend_info_from_lspecs(lspecs, &ip->onion_key, 0);
+
+ SMARTLIST_FOREACH(lspecs, link_specifier_t *, ls, link_specifier_free(ls));
+ smartlist_free(lspecs);
+ return ei;
+}
+
+/* Using a descriptor desc, return a newly allocated extend_info_t object of a
+ * randomly picked introduction point from its list. Return NULL if none are
+ * usable. */
+static extend_info_t *
+client_get_random_intro(const ed25519_public_key_t *service_pk)
+{
+ extend_info_t *ei = NULL, *ei_excluded = NULL;
+ smartlist_t *usable_ips = NULL;
+ const hs_descriptor_t *desc;
+ const hs_desc_encrypted_data_t *enc_data;
+ const or_options_t *options = get_options();
+
+ tor_assert(service_pk);
+
+ desc = hs_cache_lookup_as_client(service_pk);
+ if (desc == NULL || !hs_client_any_intro_points_usable(desc)) {
+ log_info(LD_REND, "Unable to randomly select an introduction point "
+ "because descriptor %s.",
+ (desc) ? "doesn't have usable intro point" : "is missing");
+ goto end;
+ }
+
+ enc_data = &desc->encrypted_data;
+ usable_ips = smartlist_new();
+ smartlist_add_all(usable_ips, enc_data->intro_points);
+ while (smartlist_len(usable_ips) != 0) {
+ int idx;
+ const hs_desc_intro_point_t *ip;
+
+ /* Pick a random intro point and immediately remove it from the usable
+ * list so we don't pick it again if we have to iterate more. */
+ idx = crypto_rand_int(smartlist_len(usable_ips));
+ ip = smartlist_get(usable_ips, idx);
+ smartlist_del(usable_ips, idx);
+
+ /* Generate an extend info object from the intro point object. */
+ ei = desc_intro_point_to_extend_info(ip);
+ if (ei == NULL) {
+ /* We can get here for instance if the intro point is a private address
+ * and we aren't allowed to extend to those. */
+ continue;
+ }
+
+ /* Test the pick against ExcludeNodes. */
+ if (routerset_contains_extendinfo(options->ExcludeNodes, ei)) {
+ /* If this pick is in the ExcludeNodes list, we keep its reference so if
+ * we ever end up not being able to pick anything else and StrictNodes is
+ * unset, we'll use it. */
+ ei_excluded = ei;
+ continue;
+ }
+ /* XXX: Intro point can time out or just be unsuable, we need to keep
+ * track of this and check against such cache. */
+
+ /* Good pick! Let's go with this. */
+ goto end;
+ }
+
+ /* Reaching this point means a couple of things. Either we can't use any of
+ * the intro point listed because the IP address can't be extended to or it
+ * is listed in the ExcludeNodes list. In the later case, if StrictNodes is
+ * set, we are forced to not use anything. */
+ ei = ei_excluded;
+ if (options->StrictNodes) {
+ log_warn(LD_REND, "Every introduction points are in the ExcludeNodes set "
+ "and StrictNodes is set. We can't connect.");
+ ei = NULL;
+ }
+
+ end:
+ smartlist_free(usable_ips);
+ return ei;
+}
+
/* ========== */
/* Public API */
/* ========== */
@@ -643,3 +747,16 @@ hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident)
smartlist_free(conns);
}
+/* Return a newly allocated extend_info_t for a randomly chosen introduction
+ * point for the given edge connection identifier ident. Return NULL if we
+ * can't pick any usable introduction points. */
+extend_info_t *
+hs_client_get_random_intro_from_edge(const edge_connection_t *edge_conn)
+{
+ tor_assert(edge_conn);
+
+ return (edge_conn->hs_ident) ?
+ client_get_random_intro(&edge_conn->hs_ident->identity_pk) :
+ rend_client_get_random_intro(edge_conn->rend_data);
+}
+
diff --git a/src/or/hs_client.h b/src/or/hs_client.h
index 50d0ad760..c41baa2ce 100644
--- a/src/or/hs_client.h
+++ b/src/or/hs_client.h
@@ -31,8 +31,10 @@ void hs_client_circuit_has_opened(origin_circuit_t *circ);
int hs_client_receive_rendezvous_acked(origin_circuit_t *circ,
const uint8_t *payload,
size_t payload_len);
-
void hs_client_desc_has_arrived(const hs_ident_dir_conn_t *ident);
+extend_info_t *hs_client_get_random_intro_from_edge(
+ const edge_connection_t *edge_conn);
+
#endif /* TOR_HS_CLIENT_H */
More information about the tor-commits
mailing list