aboutsummaryrefslogtreecommitdiff
path: root/src/or/hs_circuit.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2017-02-16 15:55:12 -0500
committerNick Mathewson <nickm@torproject.org>2017-08-08 20:29:33 -0400
commit6a21ac7f9809963287dd678c9f2c494b3f9ebba3 (patch)
tree85d989f019ad36b92b8a9d9dabc58e1aa449dcd4 /src/or/hs_circuit.c
parent00a02a3a59f6e44619e6caed150b001acae37231 (diff)
downloadtor-6a21ac7f9809963287dd678c9f2c494b3f9ebba3.tar.gz
tor-6a21ac7f9809963287dd678c9f2c494b3f9ebba3.zip
prop224: Introduction circuit creation
Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/or/hs_circuit.c')
-rw-r--r--src/or/hs_circuit.c99
1 files changed, 99 insertions, 0 deletions
diff --git a/src/or/hs_circuit.c b/src/or/hs_circuit.c
index 2f595d72e5..482ba30f35 100644
--- a/src/or/hs_circuit.c
+++ b/src/or/hs_circuit.c
@@ -10,10 +10,17 @@
#include "circuitlist.h"
#include "circuituse.h"
#include "config.h"
+#include "rephist.h"
+#include "router.h"
#include "hs_circuit.h"
#include "hs_ident.h"
#include "hs_ntor.h"
+#include "hs_service.h"
+
+/* Trunnel. */
+#include "hs/cell_common.h"
+#include "hs/cell_establish_intro.h"
/* A circuit is about to become an e2e rendezvous circuit. Check
* <b>circ_purpose</b> and ensure that it's properly set. Return true iff
@@ -167,6 +174,98 @@ finalize_rend_circuit(origin_circuit_t *circ, crypt_path_t *hop,
}
}
+/* For a given circuit and a service introduction point object, register the
+ * intro circuit to the circuitmap. This supports legacy intro point. */
+static void
+register_intro_circ(const hs_service_intro_point_t *ip,
+ origin_circuit_t *circ)
+{
+ tor_assert(ip);
+ tor_assert(circ);
+
+ if (ip->base.is_only_legacy) {
+ uint8_t digest[DIGEST_LEN];
+ if (BUG(crypto_pk_get_digest(ip->legacy_key, (char *) digest) < 0)) {
+ return;
+ }
+ hs_circuitmap_register_intro_circ_v2_service_side(circ, digest);
+ } else {
+ hs_circuitmap_register_intro_circ_v3_service_side(circ,
+ &ip->auth_key_kp.pubkey);
+ }
+}
+
+/* From a given service and service intro point, create an introduction point
+ * circuit identifier. This can't fail. */
+static hs_ident_circuit_t *
+create_intro_circuit_identifier(const hs_service_t *service,
+ const hs_service_intro_point_t *ip)
+{
+ hs_ident_circuit_t *ident;
+
+ tor_assert(service);
+ tor_assert(ip);
+
+ ident = hs_ident_circuit_new(&service->keys.identity_pk,
+ HS_IDENT_CIRCUIT_INTRO);
+ ed25519_pubkey_copy(&ident->intro_auth_pk, &ip->auth_key_kp.pubkey);
+
+ return ident;
+}
+
+/* For a given service and a service intro point, launch a circuit to the
+ * extend info ei. If the service is a single onion, a one-hop circuit will be
+ * requested. Return 0 if the circuit was successfully launched and tagged
+ * with the correct identifier. On error, a negative value is returned. */
+int
+hs_circ_launch_intro_point(hs_service_t *service,
+ const hs_service_intro_point_t *ip,
+ extend_info_t *ei, time_t now)
+{
+ /* Standard flags for introduction circuit. */
+ int ret = -1, circ_flags = CIRCLAUNCH_NEED_UPTIME | CIRCLAUNCH_IS_INTERNAL;
+ origin_circuit_t *circ;
+
+ tor_assert(service);
+ tor_assert(ip);
+ tor_assert(ei);
+
+ /* Update circuit flags in case of a single onion service that requires a
+ * direct connection. */
+ if (service->config.is_single_onion) {
+ circ_flags |= CIRCLAUNCH_ONEHOP_TUNNEL;
+ }
+
+ log_info(LD_REND, "Launching a circuit to intro point %s for service %s.",
+ safe_str_client(extend_info_describe(ei)),
+ safe_str_client(service->onion_address));
+
+ /* Note down that we are about to use an internal circuit. */
+ rep_hist_note_used_internal(now, circ_flags & CIRCLAUNCH_NEED_UPTIME,
+ circ_flags & CIRCLAUNCH_NEED_CAPACITY);
+
+ /* Note down the launch for the retry period. Even if the circuit fails to
+ * be launched, we still want to respect the retry period to avoid stress on
+ * the circuit subsystem. */
+ service->state.num_intro_circ_launched++;
+ circ = circuit_launch_by_extend_info(CIRCUIT_PURPOSE_S_ESTABLISH_INTRO,
+ ei, circ_flags);
+ if (circ == NULL) {
+ goto end;
+ }
+
+ /* Setup the circuit identifier and attach it to it. */
+ circ->hs_ident = create_intro_circuit_identifier(service, ip);
+ tor_assert(circ->hs_ident);
+ /* Register circuit in the global circuitmap. */
+ register_intro_circ(ip, circ);
+
+ /* Success. */
+ ret = 0;
+ end:
+ return ret;
+}
+
/* Circuit <b>circ</b> just finished the rend ntor key exchange. Use the key
* exchange output material at <b>ntor_key_seed</b> and setup <b>circ</b> to
* serve as a rendezvous end-to-end circuit between the client and the