diff --git a/src/etcp.c b/src/etcp.c index 6cd5c8d4..17ecdf80 100644 --- a/src/etcp.c +++ b/src/etcp.c @@ -215,6 +215,7 @@ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* n etcp->optimal_inflight=100000; etcp->initialized=0; etcp->links_up=0; + etcp->reset_done=0; etcp->last_rr_link=NULL; etcp->name = u_strdup(name); // Initialize log_name with local node_id (peer will be updated later when known) @@ -503,7 +504,7 @@ void etcp_conn_reinit(struct ETCP_CONN* etcp) {// Если сбой в обме etcp->log_name, etcp->initialized, etcp->links_up, etcp->reinit_count, etcp->tx_state); etcp->reinit_count++; - + etcp->reset_done = 0; etcp->initialized = 0;// еще раз придёт conn_ready_callback // Отменяем висящие NAT-ping'и для этого соединения @@ -530,6 +531,7 @@ void etcp_conn_ready(struct ETCP_CONN* conn) { if (!conn) return; conn->initialized = 1; + conn->reset_done = 1; // Если tx_state не установлен (первое подключение без reinit), установим его if (conn->tx_state == 0) { conn->tx_state = ETCP_TX_STATE_DATA_WAIT; diff --git a/src/etcp.h b/src/etcp.h index e9be34f3..de6ca971 100644 --- a/src/etcp.h +++ b/src/etcp.h @@ -225,6 +225,7 @@ struct ETCP_CONN { uint32_t session_id; // случайный ID сессии (генерируется клиентом) для защиты от ложного reinit uint8_t tx_state; // 0 - n/a, 1 - data_wait (queues empty), 2 - link_wait (link busy) uint8_t links_up; // 0 - канал не готов для передачи, 1 - канал готов для передачи (хотя бы один линк не down) + uint8_t reset_done; // 0 - рукопожатие не завершено (реинит разрешён), 1 - соединение стабильно (реинит заблокирован) // Callback chains for ready/up/down notifications struct etcp_cbk_entry* ready_cbks; // цепочка callback'ов при готовности соединения diff --git a/src/etcp_connections.c b/src/etcp_connections.c index 1a28cc27..117ac270 100644 --- a/src/etcp_connections.c +++ b/src/etcp_connections.c @@ -1473,7 +1473,7 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D link->init_timer = NULL; } - if (pkt_code == ETCP_INIT_RESPONSE) { + if (pkt_code == ETCP_INIT_RESPONSE && !link->etcp->reset_done) { DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT from client: INIT_RESPONSE(0x03) received, reinit conn=%p", link->etcp->log_name, link->etcp); etcp_conn_reinit(link->etcp); @@ -1748,10 +1748,11 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) { // Check session_id: if same - no reinit, if different - client restarted, do reinit if (code == ETCP_INIT_REQUEST || conn->session_id != session_id || !conn->got_initial_pkt) { send_reset = 1; // Client explicitly requested reset, or new session, or server waiting for first packet - DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT existing link: code=0x%02x sess=%08x→%08x got_init=%d initialized=%d links_up=%d", - conn->log_name, code, conn->session_id, session_id, conn->got_initial_pkt, conn->initialized, conn->links_up); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT existing link: code=0x%02x sess=%08x→%08x got_init=%d initialized=%d links_up=%d reset_done=%d", + conn->log_name, code, conn->session_id, session_id, conn->got_initial_pkt, conn->initialized, conn->links_up, conn->reset_done); conn->session_id = session_id; - etcp_conn_reinit(conn); + if (!conn->reset_done) etcp_conn_reinit(conn); + else DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT skipped — reset_done=1", conn->log_name); } else { send_reset = 0; // Same session, no reinit needed DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "same session_id, skip reinit"); @@ -1775,10 +1776,11 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) { // For new links: reset if client requested or session changed if (code == ETCP_INIT_REQUEST || conn->session_id != session_id || !conn->got_initial_pkt) { send_reset = 1; - DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT new link: code=0x%02x sess=%08x→%08x got_init=%d initialized=%d links_up=%d", - conn->log_name, code, conn->session_id, session_id, conn->got_initial_pkt, conn->initialized, conn->links_up); + DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT new link: code=0x%02x sess=%08x→%08x got_init=%d initialized=%d links_up=%d reset_done=%d", + conn->log_name, code, conn->session_id, session_id, conn->got_initial_pkt, conn->initialized, conn->links_up, conn->reset_done); conn->session_id = session_id; - etcp_conn_reinit(conn); + if (!conn->reset_done) etcp_conn_reinit(conn); + else DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "[%s] REINIT skipped — reset_done=1", conn->log_name); } link->keepalive_interval=(req->keepalive[0]<<8) | req->keepalive[1]; link->recovery_interval=((req->recovery[0]<<8) | req->recovery[1])*100;// timebase в link, timebase/100 в кодограмме