nat: prioritize mapping candidates and label unknown NAT explicitly

This commit is contained in:
evgeny committed 2026-10-17 17:47:18 +02:00
1 parent 6037819269
commit 79d8789410
3 files changed
+21 -7

No files matched your search

+7 -3
View File
@@ -48,6 +48,7 @@ struct nat_wire {
struct nat_pair {
uint64_t group, observer, helper;
uint8_t helper_priority; /* Сначала публичный endpoint C, затем приватный, затем один наблюдатель. */
uint8_t observer_endpoint[ROUTE_ADDR_WIRE_SIZE], helper_endpoint[ROUTE_ADDR_WIRE_SIZE];
};
struct nat_recheck_wire { uint8_t cmd, command, version, socket_id, address[ROUTE_ADDR_WIRE_SIZE]; };
@@ -223,6 +224,8 @@ static int node_udp_endpoint(struct NAT_DETECTION *detector, const struct TOPO_N
}
static int pair_after(struct nat_pair a, struct nat_pair b) {
if (!a.group || !b.group) return a.group != 0;
if (a.helper_priority != b.helper_priority) return a.helper_priority > b.helper_priority;
if (a.group != b.group) return a.group > b.group;
if (a.observer != b.observer) return a.observer > b.observer;
if (a.helper != b.helper) return a.helper > b.helper;
@@ -255,7 +258,7 @@ static int select_pair(struct nat_socket *state) {
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;
observers++;
struct nat_pair observer_only = {.group = group->group_id, .observer = observer};
struct nat_pair observer_only = {.group = group->group_id, .observer = observer, .helper_priority = 2};
memcpy(observer_only.observer_endpoint, previous_b, sizeof(previous_b));
if (!state->socket->is_tcp && pair_after(observer_only, state->cursor) &&
(!single.group || pair_after(single, observer_only))) {
@@ -271,7 +274,8 @@ static int select_pair(struct nat_socket *state) {
for (; more_c; more_c = !state->socket->is_tcp &&
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;
struct nat_pair candidate = {.group = group->group_id, .observer = observer, .helper = helper};
struct nat_pair candidate = {.group = group->group_id, .observer = observer, .helper = helper,
.helper_priority = !public_address(detector, &ca)};
memcpy(candidate.observer_endpoint, previous_b, sizeof(previous_b));
memcpy(candidate.helper_endpoint, previous_c, sizeof(previous_c));
if (state->using_fallback) {
@@ -1286,7 +1290,7 @@ static void owner_start(struct nat_socket *state) {
}
if (!state->cycling) {
state->cycling = 1; state->cursor = (struct nat_pair){0}; state->fallback = (struct nat_pair){0};
state->using_fallback = 0; state->prefer_fresh = 1;
state->using_fallback = 0; state->prefer_fresh = state->measured_profile.mapping != ADDRESS_MAP_UNKNOWN;
state->cycle_deadline = get_time_tb() + NAT_ROUND_TB;
}
history_load(state);