aboutsummaryrefslogtreecommitdiff
path: root/src/core
diff options
context:
space:
mode:
authorNick Mathewson <nickm@torproject.org>2018-09-21 09:40:16 -0400
committerNick Mathewson <nickm@torproject.org>2018-09-21 09:40:16 -0400
commit0e4c42a912d020888e811b748925362e1b3dc67b (patch)
tree90a9e0e682a06bdf1af1ea9b0940dd81e20786e2 /src/core
parenta1b0283040723474377a5746dbd01782a9b7eaa7 (diff)
parent03ef4ec466fd7f1de097a7b0244ca5bc8cc32b18 (diff)
downloadtor-0e4c42a912d020888e811b748925362e1b3dc67b.tar.gz
tor-0e4c42a912d020888e811b748925362e1b3dc67b.zip
Merge remote-tracking branch 'ahf-github/asn/bugs4700_2'
Diffstat (limited to 'src/core')
-rw-r--r--src/core/or/connection_edge.c49
-rw-r--r--src/core/or/connection_edge.h6
-rw-r--r--src/core/or/or.h1
3 files changed, 56 insertions, 0 deletions
diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c
index 40772670ee..d0fad67009 100644
--- a/src/core/or/connection_edge.c
+++ b/src/core/or/connection_edge.c
@@ -839,6 +839,46 @@ connected_cell_format_payload(uint8_t *payload_out,
return connected_payload_len;
}
+/* This is an onion service client connection: Export the client circuit ID
+ * according to the HAProxy proxy protocol. */
+STATIC void
+export_hs_client_circuit_id(edge_connection_t *edge_conn,
+ hs_circuit_id_protocol_t protocol)
+{
+ /* We only support HAProxy right now. */
+ if (protocol != HS_CIRCUIT_ID_PROTOCOL_HAPROXY)
+ return;
+
+ char *buf = NULL;
+ const char dst_ipv6[] = "::1";
+ /* See RFC4193 regarding fc00::/7 */
+ const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:";
+ uint16_t dst_port = 0;
+ uint16_t src_port = 1; /* default value */
+ uint32_t gid = 0; /* default value */
+
+ /* Generate a GID and source port for this client */
+ if (edge_conn->on_circuit != NULL) {
+ gid = TO_ORIGIN_CIRCUIT(edge_conn->on_circuit)->global_identifier;
+ src_port = gid & 0x0000ffff;
+ }
+
+ /* Grab the original dest port from the hs ident */
+ if (edge_conn->hs_ident) {
+ dst_port = edge_conn->hs_ident->orig_virtual_port;
+ }
+
+ /* Build the string */
+ tor_asprintf(&buf, "PROXY TCP6 %s:%x:%x %s %d %d\r\n",
+ src_ipv6_prefix,
+ gid >> 16, gid & 0x0000ffff,
+ dst_ipv6, src_port, dst_port);
+
+ connection_buf_add(buf, strlen(buf), TO_CONN(edge_conn));
+
+ tor_free(buf);
+}
+
/** Connected handler for exit connections: start writing pending
* data, deliver 'CONNECTED' relay cells as appropriate, and check
* any pending data that may have been received. */
@@ -859,6 +899,7 @@ connection_edge_finished_connecting(edge_connection_t *edge_conn)
rep_hist_note_exit_stream_opened(conn->port);
conn->state = EXIT_CONN_STATE_OPEN;
+
connection_watch_events(conn, READ_EVENT); /* stop writing, keep reading */
if (connection_get_outbuf_len(conn)) /* in case there are any queued relay
* cells */
@@ -3652,6 +3693,14 @@ handle_hs_exit_conn(circuit_t *circ, edge_connection_t *conn)
hs_inc_rdv_stream_counter(origin_circ);
+ /* If it's an onion service connection, we might want to include the proxy
+ * protocol header: */
+ if (conn->hs_ident) {
+ hs_circuit_id_protocol_t circuit_id_protocol =
+ hs_service_exports_circuit_id(&conn->hs_ident->identity_pk);
+ export_hs_client_circuit_id(conn, circuit_id_protocol);
+ }
+
/* Connect tor to the hidden service destination. */
connection_exit_connect(conn);
diff --git a/src/core/or/connection_edge.h b/src/core/or/connection_edge.h
index 71ea95d6e5..6dee93f1f9 100644
--- a/src/core/or/connection_edge.h
+++ b/src/core/or/connection_edge.h
@@ -14,6 +14,8 @@
#include "lib/testsupport/testsupport.h"
+#include "feature/hs/hs_service.h"
+
edge_connection_t *TO_EDGE_CONN(connection_t *);
entry_connection_t *TO_ENTRY_CONN(connection_t *);
entry_connection_t *EDGE_TO_ENTRY_CONN(edge_connection_t *);
@@ -260,6 +262,10 @@ STATIC void connection_ap_handshake_rewrite(entry_connection_t *conn,
rewrite_result_t *out);
STATIC int connection_ap_process_http_connect(entry_connection_t *conn);
+STATIC void
+export_hs_client_circuit_id(edge_connection_t *edge_conn,
+ hs_circuit_id_protocol_t protocol);
+
#endif /* defined(CONNECTION_EDGE_PRIVATE) */
#endif /* !defined(TOR_CONNECTION_EDGE_H) */
diff --git a/src/core/or/or.h b/src/core/or/or.h
index 4d8b6d7871..7557c1321e 100644
--- a/src/core/or/or.h
+++ b/src/core/or/or.h
@@ -26,6 +26,7 @@
#include "lib/cc/compat_compiler.h"
#include "lib/cc/torint.h"
#include "lib/container/map.h"
+#include "lib/container/buffers.h"
#include "lib/container/smartlist.h"
#include "lib/crypt_ops/crypto_cipher.h"
#include "lib/crypt_ops/crypto_rsa.h"