From c42d75c2f5226ca3f6fd2a920edfd84cce329d98 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 17 Oct 2026 19:49:42 +0200 Subject: [PATCH] nat: limit helper selection and topology retries to UDP --- src/routing_layer/nat_detection.c | 37 ++++++++++++++----------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/routing_layer/nat_detection.c b/src/routing_layer/nat_detection.c index 2e83b47d..46c336e1 100644 --- a/src/routing_layer/nat_detection.c +++ b/src/routing_layer/nat_detection.c @@ -252,29 +252,29 @@ static int select_pair(struct nat_socket *state) { const struct TOPO_NODE *bn = group_node(detector, group->group_id, observer); uint8_t previous_b[ROUTE_ADDR_WIRE_SIZE] = {0}; struct sockaddr_storage ba = {0}; uint8_t bs = 0; - int more_b = state->socket->is_tcp || node_udp_endpoint(detector, bn, state->local.ss_family, 0, previous_b, &ba, &bs); - for (; more_b; more_b = !state->socket->is_tcp && + int more_b = node_udp_endpoint(detector, bn, state->local.ss_family, 0, previous_b, &ba, &bs); + for (; more_b; more_b = node_udp_endpoint(detector, bn, state->local.ss_family, 0, previous_b, &ba, &bs)) { - if (!state->socket->is_tcp && route_ping_addr_encode(previous_b, &ba)) break; + if (route_ping_addr_encode(previous_b, &ba)) break; observers++; struct nat_pair observer_only = {.group = group->group_id, .observer = observer, .helper_priority = 4}; memcpy(observer_only.observer_endpoint, previous_b, sizeof(previous_b)); - if (!state->socket->is_tcp && pair_after(observer_only, state->cursor) && + if (pair_after(observer_only, state->cursor) && (!single.group || pair_after(single, observer_only))) { single = observer_only; single_address = ba; memcpy(single_key, bn->public_key, 32); } - for (struct ll_entry *c = state->socket->is_tcp ? b : group->nodes->head; c; c = state->socket->is_tcp ? NULL : c->next) { + for (struct ll_entry *c = group->nodes->head; c; c = c->next) { uint64_t helper = ((struct TOPO_GROUP_NODE *)c)->node_id; - if (helper == detector->instance->node_id || (!state->socket->is_tcp && helper == observer) || + if (helper == detector->instance->node_id || helper == observer || !control_route(detector, group->group_id, helper)) continue; const struct TOPO_NODE *cn = group_node(detector, group->group_id, helper); struct sockaddr_storage ca = {0}; uint8_t cs = 0, previous_c[ROUTE_ADDR_WIRE_SIZE] = {0}; - int more_c = state->socket->is_tcp || node_udp_endpoint(detector, cn, state->local.ss_family, 1, previous_c, &ca, &cs); - for (; more_c; more_c = !state->socket->is_tcp && + int more_c = node_udp_endpoint(detector, cn, state->local.ss_family, 1, previous_c, &ca, &cs); + for (; more_c; more_c = node_udp_endpoint(detector, cn, state->local.ss_family, 1, previous_c, &ca, &cs)) { - if (!state->socket->is_tcp && route_ping_addr_encode(previous_c, &ca)) break; + if (route_ping_addr_encode(previous_c, &ca)) break; struct nat_pair candidate = {.group = group->group_id, .observer = observer, .helper = helper, - .helper_priority = state->socket->is_tcp ? 0 : 2 * !public_address(detector, &ca) + contacted(state, &ca)}; + .helper_priority = 2 * !public_address(detector, &ca) + contacted(state, &ca)}; memcpy(candidate.observer_endpoint, previous_b, sizeof(previous_b)); memcpy(candidate.helper_endpoint, previous_c, sizeof(previous_c)); if (!pair_after(candidate, state->cursor)) continue; @@ -1347,19 +1347,15 @@ static uint64_t candidate_fingerprint(struct nat_socket *state, int ready) { struct sockaddr_storage endpoint = {0}; uint8_t socket_id = 0; uint8_t bytes[16 + ROUTE_ADDR_WIRE_SIZE + 1] = {0}; write64(bytes, group->group_id); write64(bytes + 8, id); - if (!state->socket->is_tcp) { - struct sockaddr_storage observer_address = {0}; uint8_t observer_socket = 0; - observers += node_udp_endpoint(detector, node, state->local.ss_family, 0, NULL, &observer_address, &observer_socket); - } + struct sockaddr_storage observer_address = {0}; uint8_t observer_socket = 0; + observers += node_udp_endpoint(detector, node, state->local.ss_family, 0, NULL, &observer_address, &observer_socket); candidates++; uint8_t previous[ROUTE_ADDR_WIRE_SIZE] = {0}; - int more = state->socket->is_tcp || node_udp_endpoint(detector, node, state->local.ss_family, 1, previous, &endpoint, &socket_id); - for (; more; more = !state->socket->is_tcp && + int more = node_udp_endpoint(detector, node, state->local.ss_family, 1, previous, &endpoint, &socket_id); + for (; more; more = node_udp_endpoint(detector, node, state->local.ss_family, 1, previous, &endpoint, &socket_id)) { - if (!state->socket->is_tcp) { - if (route_ping_addr_encode(previous, &endpoint)) break; - memcpy(bytes + 16, previous, sizeof(previous)); bytes[16 + ROUTE_ADDR_WIRE_SIZE] = socket_id; - } + if (route_ping_addr_encode(previous, &endpoint)) break; + memcpy(bytes + 16, previous, sizeof(previous)); bytes[16 + ROUTE_ADDR_WIRE_SIZE] = socket_id; uint64_t hash = UINT64_C(14695981039346656037); for (unsigned i = 0; i < sizeof(bytes); i++) { hash ^= bytes[i]; hash *= UINT64_C(1099511628211); } group_total += hash; @@ -1442,6 +1438,7 @@ int nat_detection_ping_allowed(struct NAT_DETECTION *detector, struct ETCP_SOCKE static void topology_wake(void *arg) { struct NAT_DETECTION *detector = arg; detector->topology_wake = NULL; for (struct nat_socket *state = detector->sockets; state; state = state->next) { + if (state->socket->is_tcp) continue; uint64_t fingerprint = candidate_fingerprint(state, 1); int changed = fingerprint != state->available_fingerprint; state->available_fingerprint = fingerprint; if (state->phase) {