fix(nat): advance after an unfinished pair uses its full retry budget

This commit is contained in:
evgeny committed 2026-10-17 23:43:21 +02:00
1 parent 1d1f5d081f
commit 305b61ccab
3 files changed
+15 -3

No files matched your search

+8 -1
View File
@@ -70,7 +70,7 @@ struct nat_socket {
uint8_t contacts[NAT_MAX_CONTACTS][17];
unsigned contact_count, contact_cutoff, cycle_contact_cutoff, phase, reason, retries;
uint8_t history_loaded, history_complete, history_incomplete, filter_clean, pre_received, post_received, pre_healthy;
uint8_t cycle_history_complete, cycle_mapping_seen;
uint8_t cycle_history_complete, cycle_mapping_seen, pair_full_budget;
uint8_t helper_socket, active_ping, heartbeat_active, forced, cycling;
uint32_t rounds, helper_reselections;
};
@@ -641,6 +641,11 @@ static void remember_address(struct nat_socket *state, const struct sockaddr_sto
}
static void owner_finish(struct nat_socket *state, uint8_t reason) {
if (reason == NAT_REASON_BUDGET && state->pair_full_budget) {
reason = NAT_REASON_TIMEOUT;
DEBUG_WARN(DEBUG_CATEGORY_NAT, "NAT pair full budget exhausted socket=%s round=%016llx; advancing candidate",
state->socket->name, (unsigned long long)state->round);
}
/* Неудача входящего испытания не мешает сравнить mapping через уже известный публичный endpoint C. */
if ((reason == NAT_REASON_TIMEOUT || reason == NAT_REASON_CONTROL_LOST || reason == NAT_REASON_SEND_ERROR ||
reason == NAT_REASON_CONTACT_HISTORY) &&
@@ -1279,6 +1284,7 @@ static void owner_start(struct nat_socket *state) {
}
uint64_t now = get_time_tb();
history_load(state);
int full_budget = !state->cycling || now >= state->cycle_deadline;
if (!state->cycling) {
state->cycling = 1; state->cursor = (struct nat_pair){0};
state->cycle_contact_cutoff = state->contact_count; state->cycle_history_complete = state->history_complete;
@@ -1290,6 +1296,7 @@ static void owner_start(struct nat_socket *state) {
state->socket->name, state->cycle_contact_cutoff, state->contact_count);
}
if (select_pair(state)) { owner_finish(state, state->reason); return; }
state->pair_full_budget = full_budget;
if (random_id(&state->round)) { owner_finish(state, NAT_REASON_SEND_ERROR); return; }
state->rounds++;
memset(&state->helper_seen, 0, sizeof(state->helper_seen)); memset(&state->baseline, 0, sizeof(state->baseline));