summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/or/connection_edge.c25
-rw-r--r--src/or/control.c9
-rw-r--r--src/or/or.h4
3 files changed, 23 insertions, 15 deletions
diff --git a/src/or/connection_edge.c b/src/or/connection_edge.c
index b7ac813808..741625c0c9 100644
--- a/src/or/connection_edge.c
+++ b/src/or/connection_edge.c
@@ -930,7 +930,9 @@ addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
}
/* Connection <b>conn</b> just finished its socks handshake, or the
- * controller asked us to take care of it.
+ * controller asked us to take care of it. If <b>circ</b> is defined,
+ * then that's where we'll want to attach it. Otherwise we have to
+ * figure it out ourselves.
*
* First, parse whether it's a .exit address, remap it, and so on. Then
* it's for a general circuit, try to attach it to a circuit (or launch
@@ -939,7 +941,8 @@ addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
* rendezvous descriptor is already here and fresh enough).
*/
int
-connection_ap_handshake_rewrite_and_attach(connection_t *conn)
+connection_ap_handshake_rewrite_and_attach(connection_t *conn,
+ circuit_t *circ)
{
socks_request_t *socks = conn->socks_request;
hostname_type_t addresstype;
@@ -1048,7 +1051,7 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn)
return -1;
}
- if (!conn->chosen_exit_name) {
+ if (!conn->chosen_exit_name && !circ) {
/* see if we can find a suitable enclave exit */
routerinfo_t *r =
router_find_exact_exit_enclave(socks->address, socks->port);
@@ -1067,7 +1070,10 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn)
rep_hist_note_used_port(socks->port, time(NULL));
}
conn->state = AP_CONN_STATE_CIRCUIT_WAIT;
- if (connection_ap_handshake_attach_circuit(conn) < 0) {
+ if ((circ &&
+ connection_ap_handshake_attach_chosen_circuit(conn, circ) < 0) ||
+ (!circ &&
+ connection_ap_handshake_attach_circuit(conn) < 0)) {
connection_mark_unattached_ap(conn, END_STREAM_REASON_CANT_ATTACH);
return -1;
}
@@ -1089,6 +1095,13 @@ connection_ap_handshake_rewrite_and_attach(connection_t *conn)
return -1;
}
+ if (circ) {
+ log_warn(LD_CONTROL, "Attachstream to a circuit is not "
+ "supported for .onion addresses currently. Failing.");
+ connection_mark_unattached_ap(conn, END_STREAM_REASON_TORPROTOCOL);
+ return -1;
+ }
+
strlcpy(conn->rend_query, socks->address, sizeof(conn->rend_query));
log_info(LD_REND,"Got a hidden service request for ID '%s'",
safe_str(conn->rend_query));
@@ -1183,8 +1196,8 @@ connection_ap_handshake_process_socks(connection_t *conn)
if (options->LeaveStreamsUnattached) {
conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
return 0;
- } else
- return connection_ap_handshake_rewrite_and_attach(conn);
+ }
+ return connection_ap_handshake_rewrite_and_attach(conn, NULL);
}
/** Iterate over the two bytes of stream_id until we get one that is not
diff --git a/src/or/control.c b/src/or/control.c
index 9224101f23..8f11e9c304 100644
--- a/src/or/control.c
+++ b/src/or/control.c
@@ -1840,12 +1840,7 @@ handle_control_attachstream(connection_t *conn, uint32_t len,
ap_conn->state = AP_CONN_STATE_CONTROLLER_WAIT;
}
- if (zero_circ) {
- connection_ap_handshake_rewrite_and_attach(ap_conn);
- send_control_done(conn);
- return 0;
- }
- if (circ->state != CIRCUIT_STATE_OPEN) {
+ if (circ && circ->state != CIRCUIT_STATE_OPEN) {
if (STATE_IS_V0(conn->state))
send_control0_error(conn, ERR_INTERNAL,
"Refuse to attach stream to non-open circ.");
@@ -1855,7 +1850,7 @@ handle_control_attachstream(connection_t *conn, uint32_t len,
conn);
return 0;
}
- if (connection_ap_handshake_attach_chosen_circuit(ap_conn, circ) != 1) {
+ if (connection_ap_handshake_rewrite_and_attach(ap_conn, circ) < 0) {
if (STATE_IS_V0(conn->state))
send_control0_error(conn, ERR_INTERNAL, "Unable to attach stream.");
else
diff --git a/src/or/or.h b/src/or/or.h
index ccc0195ae4..bd9bdc013d 100644
--- a/src/or/or.h
+++ b/src/or/or.h
@@ -1758,8 +1758,8 @@ int address_is_in_virtual_range(const char *addr);
const char *addressmap_register_virtual_address(int type, char *new_address);
void addressmap_get_mappings(smartlist_t *sl, time_t min_expires,
time_t max_expires);
-int
-connection_ap_handshake_rewrite_and_attach(connection_t *conn);
+int connection_ap_handshake_rewrite_and_attach(connection_t *conn,
+ circuit_t *circ);
void parse_socks_policy(void);
void free_socks_policy(void);