Confirm new TCP sessions and bound reciprocal challenge retries

Negotiate new TCP sessions even when the peer epoch is known, and let the retry timer send reciprocal challenges to avoid feedback loops when confirmations are lost.

Cover peer restarts, simultaneous connects, REALITY, confirmation loss, second links, stale confirmations and deadlines. Remove forced client resets and count only validated test payloads in the UDP reconnect test.

Validation: 149 tests passed; proxy, burst and load integration tests passed; Android assembleDebug succeeded.
This commit is contained in:
evgeny committed 2026-10-12 21:29:41 +02:00
1 parent d372438b6e
commit 90d3206071
6 files changed
+388 -153

No files matched your search

+2 -1
View File
@@ -1287,7 +1287,8 @@ void etcp_link_enter_ready_tcp(struct ETCP_LINK *link) {
if (!link->mtu_remote) link->mtu_remote = link->mtu;
etcp->tcp_link_count++;
if (link->tcp_link) { const uint8_t* ed = stcp_link_get_peer_ed25519_pubkey(link->tcp_link); if (ed) memcpy(etcp->peer_ed25519_pubkey, ed, SC_PUBKEY_SIZE); }
if (!etcp->peer_reset_id) etcp_session_start(etcp); // сервер создаёт ETCP_CONN после STCP handshake
// Известная эпоха пира не подтверждает новый поток; следующий линк не перезапускает согласование.
if (!etcp->initialized && !etcp->session_required) etcp_session_start(etcp);
if (etcp->initialized == 0) etcp_conn_ready(etcp);
if (etcp->state == 2) { DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "enter_ready_tcp: conn DELETED after conn_ready, link=%p", (void*)link); return; }
etcp_keepalive_link_ready(link);
+2 -4
View File
@@ -93,10 +93,8 @@ int etcp_session_receive(struct ETCP_CONN* c, const uint8_t* data, size_t len) {
DEBUG_DEBUG(DEBUG_CATEGORY_ETCP,"[%s] session: stale target or empty cookie",c->log_name);
} else if (data[0] == ETCP_SESSION_CHALLENGE) {
session_send(c,ETCP_SESSION_CONFIRM,peer,cookie);
if (c->session_required || peer != c->peer_reset_id) {
etcp_session_observe(c,peer);
if (c->session_challenge) session_send(c,ETCP_SESSION_CHALLENGE,peer,c->session_challenge);
}
// Встречный challenge отправляет таймер: немедленный ответ зацикливает обмен при потере CONFIRM.
if (c->session_required || peer != c->peer_reset_id) etcp_session_observe(c,peer);
} else if (peer == c->session_candidate && cookie == c->session_challenge) {
etcp_session_cancel(c);
if (peer != c->peer_reset_id) etcp_conn_reinit_id(c,"confirmed peer epoch",c->reset_id);