diff --git a/src/core/or/connection_edge.c b/src/core/or/connection_edge.c index 9af03f7f23..891e922171 100644 --- a/src/core/or/connection_edge.c +++ b/src/core/or/connection_edge.c @@ -607,8 +607,7 @@ export_hs_client_circuit_id_haproxy(const edge_connection_t *edge_conn, const char dst_ipv6[] = "::1"; /* See RFC4193 regarding fc00::/7 */ const char src_ipv6_prefix[] = "fc00:dead:beef:4dad:"; - /* TODO: retain virtual port and use as destination port */ - uint16_t dst_port = 443; + uint16_t dst_port = 0; uint16_t src_port = 1; /* default value */ uint32_t gid = 0; /* default value */ @@ -618,6 +617,11 @@ export_hs_client_circuit_id_haproxy(const edge_connection_t *edge_conn, 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 %s %d %d\r\n", src_ipv6_prefix, gid, dst_ipv6, src_port, dst_port); diff --git a/src/feature/hs/hs_common.c b/src/feature/hs/hs_common.c index 12405a79cb..c36892e0f8 100644 --- a/src/feature/hs/hs_common.c +++ b/src/feature/hs/hs_common.c @@ -882,6 +882,11 @@ hs_set_conn_addr_port(const smartlist_t *ports, edge_connection_t *conn) smartlist_free(matching_ports); if (chosen_port) { if (!(chosen_port->is_unix_addr)) { + /* save the original destination before we overwrite it */ + if (conn->hs_ident) { + conn->hs_ident->orig_virtual_port = TO_CONN(conn)->port; + } + /* Get a non-AF_UNIX connection ready for connection_exit_connect() */ tor_addr_copy(&TO_CONN(conn)->addr, &chosen_port->real_addr); TO_CONN(conn)->port = chosen_port->real_port; diff --git a/src/feature/hs/hs_ident.h b/src/feature/hs/hs_ident.h index 92d15b0523..ab87d16d17 100644 --- a/src/feature/hs/hs_ident.h +++ b/src/feature/hs/hs_ident.h @@ -111,6 +111,10 @@ typedef struct hs_ident_edge_conn_t { * in the onion address. */ ed25519_public_key_t identity_pk; + /* The original virtual port that was used by the client to access the onion + * service, regardless of the internal port forwarding that might have + * happened on the service-side. */ + uint16_t orig_virtual_port; /* XXX: Client authorization. */ } hs_ident_edge_conn_t;