summaryrefslogtreecommitdiff
path: root/src/or/connection_edge.c
diff options
context:
space:
mode:
authorDavid Goulet <dgoulet@torproject.org>2017-05-10 15:04:40 -0400
committerNick Mathewson <nickm@torproject.org>2017-08-08 20:29:33 -0400
commit30b5c6a95ec9932f17f0b171c60229c1d77f829d (patch)
treef2dd4f04855198ace2bde6fb0a797353604699e3 /src/or/connection_edge.c
parent7163ce7f62d6c487193fe43828420ba4fe721b9f (diff)
downloadtor-30b5c6a95ec9932f17f0b171c60229c1d77f829d.tar.gz
tor-30b5c6a95ec9932f17f0b171c60229c1d77f829d.zip
prop224: Link rendezvous circuit to edge connection
This commit refactors the handle_hs_exit_conn() function introduced at a prior commit that connects the rendezvous circuit to the edge connection used to connect to the service virtual port requested in a BEGIN cell. The refactor adds the support for prop224 adding the hs_service_set_conn_addr_port() function that has the same purpose has rend_service_set_connection_addr_port() from the legacy code. The rend_service_set_connection_addr_port() has also been a bit refactored so the common code can be shared between the two HS subsystems (legacy and prop224). In terms of functionallity, nothing has changed, we still close the circuits in case of failure for the same reasons as the legacy system currently does. Signed-off-by: David Goulet <dgoulet@torproject.org>
Diffstat (limited to 'src/or/connection_edge.c')
-rw-r--r--src/or/connection_edge.c87
1 files changed, 59 insertions, 28 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index 8e447131fd..41e5f88ab8 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -76,6 +76,7 @@
#include "dirserv.h"
#include "hibernate.h"
#include "hs_common.h"
+#include "hs_circuit.h"
#include "main.h"
#include "nodelist.h"
#include "policies.h"
@@ -3066,58 +3067,88 @@ begin_cell_parse(const cell_t *cell, begin_cell_t *bcell,
return 0;
}
-/** For the given <b>circ</b> and the edge connection <b>n_stream</b>, setup
- * the the connection, attach it to the circ and connect it. Return 0 on
- * success or END_CIRC_AT_ORIGIN if we can't find the requested hidden
- * service port where the caller should close the circuit. */
+/** For the given <b>circ</b> and the edge connection <b>conn</b>, setup the
+ * connection, attach it to the circ and connect it. Return 0 on success
+ * or END_CIRC_AT_ORIGIN if we can't find the requested hidden service port
+ * where the caller should close the circuit. */
static int
-handle_hs_exit_conn(circuit_t *circ, edge_connection_t *n_stream)
+handle_hs_exit_conn(circuit_t *circ, edge_connection_t *conn)
{
- origin_circuit_t *origin_circ = TO_ORIGIN_CIRCUIT(circ);
- log_info(LD_REND,"begin is for rendezvous. configuring stream.");
- n_stream->base_.address = tor_strdup("(rendezvous)");
- n_stream->base_.state = EXIT_CONN_STATE_CONNECTING;
- n_stream->rend_data = rend_data_dup(origin_circ->rend_data);
- tor_assert(connection_edge_is_rendezvous_stream(n_stream));
+ int ret;
+ origin_circuit_t *origin_circ;
+
assert_circuit_ok(circ);
+ tor_assert(circ->purpose == CIRCUIT_PURPOSE_S_REND_JOINED);
+ tor_assert(conn);
- const int r = rend_service_set_connection_addr_port(n_stream, origin_circ);
- if (r < 0) {
- log_info(LD_REND,"Didn't find rendezvous service (port %d)",
- n_stream->base_.port);
+ log_debug(LD_REND, "Connecting the hidden service rendezvous circuit "
+ "to the service destination.");
+
+ origin_circ = TO_ORIGIN_CIRCUIT(circ);
+ conn->base_.address = tor_strdup("(rendezvous)");
+ conn->base_.state = EXIT_CONN_STATE_CONNECTING;
+
+ /* The circuit either has an hs identifier for v3+ or a rend_data for legacy
+ * service. */
+ if (origin_circ->rend_data) {
+ conn->rend_data = rend_data_dup(origin_circ->rend_data);
+ tor_assert(connection_edge_is_rendezvous_stream(conn));
+ ret = rend_service_set_connection_addr_port(conn, origin_circ);
+ } else if (origin_circ->hs_ident) {
+ /* Setup the identifier to be the one for the circuit service. */
+ conn->hs_ident =
+ hs_ident_edge_conn_new(&origin_circ->hs_ident->identity_pk);
+ ret = hs_service_set_conn_addr_port(origin_circ, conn);
+ } else {
+ /* We should never get here if the circuit's purpose is rendezvous. */
+ tor_assert(0);
+ }
+ if (ret < 0) {
+ log_info(LD_REND, "Didn't find rendezvous service (addr%s, port %d)",
+ fmt_addr(&TO_CONN(conn)->addr), TO_CONN(conn)->port);
/* Send back reason DONE because we want to make hidden service port
* scanning harder thus instead of returning that the exit policy
* didn't match, which makes it obvious that the port is closed,
* return DONE and kill the circuit. That way, a user (malicious or
* not) needs one circuit per bad port unless it matches the policy of
* the hidden service. */
- relay_send_end_cell_from_edge(n_stream->stream_id, circ,
+ relay_send_end_cell_from_edge(conn->stream_id, circ,
END_STREAM_REASON_DONE,
origin_circ->cpath->prev);
- connection_free(TO_CONN(n_stream));
+ connection_free(TO_CONN(conn));
/* Drop the circuit here since it might be someone deliberately
* scanning the hidden service ports. Note that this mitigates port
* scanning by adding more work on the attacker side to successfully
* scan but does not fully solve it. */
- if (r < -1)
+ if (ret < -1) {
return END_CIRC_AT_ORIGIN;
- else
+ } else {
return 0;
+ }
}
- assert_circuit_ok(circ);
- log_debug(LD_REND,"Finished assigning addr/port");
- n_stream->cpath_layer = origin_circ->cpath->prev; /* link it */
- /* add it into the linked list of p_streams on this circuit */
- n_stream->next_stream = origin_circ->p_streams;
- n_stream->on_circuit = circ;
- origin_circ->p_streams = n_stream;
+ /* Link the circuit and the connection crypt path. */
+ conn->cpath_layer = origin_circ->cpath->prev;
+
+ /* Add it into the linked list of p_streams on this circuit */
+ conn->next_stream = origin_circ->p_streams;
+ origin_circ->p_streams = conn;
+ conn->on_circuit = circ;
assert_circuit_ok(circ);
- origin_circ->rend_data->nr_streams++;
+ if (origin_circ->rend_data) {
+ origin_circ->rend_data->nr_streams++;
+ } else if (origin_circ->hs_ident) {
+ origin_circ->hs_ident->num_rdv_streams++;
+ } else {
+ /* The previous if/else at the start of the function guarantee that we'll
+ * never end up in a else situation unless it's freed in between. */
+ tor_assert(0);
+ }
- connection_exit_connect(n_stream);
+ /* Connect tor to the hidden service destination. */
+ connection_exit_connect(conn);
/* For path bias: This circuit was used successfully */
pathbias_mark_use_success(origin_circ);