tor

The Tor anonymity network
git clone https://git.dasho.dev/tor.git
Log | Files | Refs | README | LICENSE

commit 63366a427be39fffeaa1dafff32ba76983656d0a
parent 958c46b8caa3479dfaa85acedacb5c7c4ac3c286
Author: David Goulet <dgoulet@torproject.org>
Date:   Tue, 11 Mar 2025 12:00:22 -0400

hs: Never pick a MiddleOnly node for HS circuit purposes

Related to #41023

Signed-off-by: David Goulet <dgoulet@torproject.org>

Diffstat:
Msrc/core/or/circuitbuild.c | 19+++----------------
Msrc/feature/hs/hs_circuit.c | 1+
Msrc/feature/hs/hs_service.c | 2+-
Msrc/feature/nodelist/node_select.h | 3+++
Msrc/feature/nodelist/routerlist.c | 5+++++
5 files changed, 13 insertions(+), 17 deletions(-)

diff --git a/src/core/or/circuitbuild.c b/src/core/or/circuitbuild.c @@ -1847,14 +1847,6 @@ choose_good_exit_server_general(router_crn_flags_t flags) return NULL; } -/* Pick a Rendezvous Point for our HS circuits according to <b>flags</b>. */ -static const node_t * -pick_rendezvous_node(router_crn_flags_t flags) -{ - const or_options_t *options = get_options(); - return router_choose_random_node(NULL, options->ExcludeNodes, flags); -} - /* * Helper function to pick a configured restricted middle node * (either HSLayer2Nodes or HSLayer3Nodes). @@ -1962,9 +1954,12 @@ choose_good_exit_server(origin_circuit_t *circ, case CIRCUIT_PURPOSE_C_HSDIR_GET: case CIRCUIT_PURPOSE_S_HSDIR_POST: case CIRCUIT_PURPOSE_HS_VANGUARDS: + case CIRCUIT_PURPOSE_C_ESTABLISH_REND: /* For these three, we want to pick the exit like a middle hop, * since it should be random. */ tor_assert_nonfatal(is_internal); + /* We want to avoid picking certain nodes for HS purposes. */ + flags |= CRN_FOR_HS; FALLTHROUGH; case CIRCUIT_PURPOSE_CONFLUX_UNLINKED: case CIRCUIT_PURPOSE_C_GENERAL: @@ -1972,14 +1967,6 @@ choose_good_exit_server(origin_circuit_t *circ, return router_choose_random_node(NULL, options->ExcludeNodes, flags); else return choose_good_exit_server_general(flags); - case CIRCUIT_PURPOSE_C_ESTABLISH_REND: - { - /* Pick a new RP */ - const node_t *rendezvous_node = pick_rendezvous_node(flags); - log_info(LD_REND, "Picked new RP: %s", - safe_str_client(node_describe(rendezvous_node))); - return rendezvous_node; - } } log_warn(LD_BUG,"Unhandled purpose %d", TO_CIRCUIT(circ)->purpose); tor_fragile_assert(); diff --git a/src/feature/hs/hs_circuit.c b/src/feature/hs/hs_circuit.c @@ -44,6 +44,7 @@ #include "core/or/congestion_control_st.h" #include "core/or/cpath_build_state_st.h" #include "core/or/crypt_path_st.h" +#include "core/or/extend_info_st.h" #include "feature/nodelist/node_st.h" #include "core/or/origin_circuit_st.h" diff --git a/src/feature/hs/hs_service.c b/src/feature/hs/hs_service.c @@ -2203,7 +2203,7 @@ pick_intro_point(unsigned int direct_conn, smartlist_t *exclude_nodes) const node_t *node; hs_service_intro_point_t *ip = NULL; /* Normal 3-hop introduction point flags. */ - router_crn_flags_t flags = CRN_NEED_UPTIME | CRN_NEED_DESC; + router_crn_flags_t flags = CRN_NEED_UPTIME | CRN_NEED_DESC | CRN_FOR_HS; /* Single onion flags. */ router_crn_flags_t direct_flags = flags | CRN_PREF_ADDR | CRN_DIRECT_CONN; diff --git a/src/feature/nodelist/node_select.h b/src/feature/nodelist/node_select.h @@ -29,6 +29,9 @@ typedef enum router_crn_flags_t { /* On clients, if choosing a node for a direct connection, only provide * nodes that satisfy ClientPreferIPv6OR. */ CRN_PREF_ADDR = 1<<5, + /* On clients, indiate that we need a HS related circuit (IP, HSDir or RP). + * This is used in order to avoid certain nodes for these purposes. */ + CRN_FOR_HS = 1<<6, /* On clients, only provide nodes that can initiate IPv6 extends. */ CRN_INITIATE_IPV6_EXTEND = 1<<7, /* On clients, only provide nodes that support Conflux (Relay=5). */ diff --git a/src/feature/nodelist/routerlist.c b/src/feature/nodelist/routerlist.c @@ -558,6 +558,7 @@ router_can_choose_node(const node_t *node, int flags) const bool direct_conn = (flags & CRN_DIRECT_CONN) != 0; const bool initiate_ipv6_extend = (flags & CRN_INITIATE_IPV6_EXTEND) != 0; const bool need_conflux = (flags & CRN_CONFLUX) != 0; + const bool for_hs = (flags & CRN_FOR_HS) != 0; const or_options_t *options = get_options(); const bool check_reach = @@ -599,6 +600,10 @@ router_can_choose_node(const node_t *node, int flags) return false; if (initiate_ipv6_extend && !node_supports_initiating_ipv6_extends(node)) return false; + /* MiddleOnly node should never be used for HS ndpoints (IP, RP, HSDir). */ + if (for_hs && node->is_middle_only) { + return false; + } return true; }