diff options
author | David Goulet <dgoulet@torproject.org> | 2017-05-10 15:04:40 -0400 |
---|---|---|
committer | Nick Mathewson <nickm@torproject.org> | 2017-08-08 20:29:33 -0400 |
commit | 30b5c6a95ec9932f17f0b171c60229c1d77f829d (patch) | |
tree | f2dd4f04855198ace2bde6fb0a797353604699e3 /src/or/connection_edge.c | |
parent | 7163ce7f62d6c487193fe43828420ba4fe721b9f (diff) | |
download | tor-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.c | 87 |
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); |