From 9e01b910ceb4aba645be1991d272b000bc94d265 Mon Sep 17 00:00:00 2001 From: evgeny Date: Fri, 30 Oct 2026 22:47:14 +0100 Subject: [PATCH] Document socket policy isolation and prepare native handshake regression --- src/transport_layer/etcp.h | 4 ++-- src/transport_layer/etcp_connections.h | 3 ++- tests/test_etcp_init_liveness.c | 10 +++++++++- 3 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/transport_layer/etcp.h b/src/transport_layer/etcp.h index fec5cb359..dbeab354d 100644 --- a/src/transport_layer/etcp.h +++ b/src/transport_layer/etcp.h @@ -139,7 +139,7 @@ struct ETCP_CONN { // Peer info uint64_t peer_node_id; // Peer node ID - uint8_t require_known_node; // 1: при handshake ключ должен принадлежать известному участнику своей CHAT-группы. + uint8_t require_known_node; // Начальная политика пакетных драйверов; сокетные пути UTUN остаются без требования CHAT-членства. uint8_t peer_ed25519_pubkey[SC_PUBKEY_SIZE]; // Ed25519 pubkey пира (из INIT) uint8_t peer_sleep_phase; // 1 = пир в SLEEP-фазе (троттлить), 0 = ACTIVE-окно (обмен) uint16_t peer_active_remaining; // до SLEEP-фазы (x0.1с), из keepalive @@ -268,7 +268,7 @@ struct ETCP_CONN { #define RTT_CB_PERIOD_TB 600000 // 1 минута в 0.1ms /* Создать транспортный объект в instance, name копируется (может быть NULL). - * require_known_node=1 требует точный ключ участника своей CHAT-группы при аутентифицированном handshake; 0 — обычная политика. + * require_known_node=1 задаёт проверку известного ключа новым пакетным драйверам; сокетные пути UTUN не наследуют её. * Жизненным циклом прикладного соединения управляет NCD. Возвращает объект либо NULL при ошибке/отмене из callback. * New-connection/NEW callbacks могут закрыть объект; после отмены конструктор завершает закрытие и не возвращает handle. */ struct ETCP_CONN* etcp_connection_create(struct UTUN_INSTANCE* instance, char* name, int require_known_node); diff --git a/src/transport_layer/etcp_connections.h b/src/transport_layer/etcp_connections.h index feecf2246..3020f4c7b 100644 --- a/src/transport_layer/etcp_connections.h +++ b/src/transport_layer/etcp_connections.h @@ -240,7 +240,7 @@ struct ETCP_LINK { uint32_t recovery_interval; // recovery интервал (x0.1ms) uint8_t is_server; // инициирует подключение клиент uint8_t initialized; // Флаг инициализации (1=подтверждено или получен request) - uint8_t require_known_node; // Политика этого пути; OR с conn->require_known_node для общего ETCP_CONN. + uint8_t require_known_node; // Эффективная политика пути: драйвер наследует conn и может усилить её; сокеты UTUN — 0. uint8_t peer_admitted; // Положительный результат проверки после аутентифицированного handshake; сбрасывается при новом INIT. uint8_t closing; // Close начат: повторный вход из callback игнорируется до окончательного free uint32_t active_users; // Внутренние стеки конструктора/RX/событий; память закрытого линка живёт до выхода последнего @@ -434,6 +434,7 @@ void tcp_server_on_link(struct stcp_link *link, struct ETCP_SOCKET *tcp_sock); * Уведомляет о создании, для исходящего UDP запускает INIT. Ошибка/close из callback — NULL без живого линка. * Конструктор удерживает память до возврата; отмена сразу закрывает ресурсы. */ /* Добавить произвольный пакетный драйвер к conn с настроенным ключом пира. + * require_known_node=1 усиливает политику conn для этого пути; 0 наследует начальную политику conn. * На канале используется защищённый ETCP INIT/DATA без IP-заголовков. OPEN драйвера ещё не UP ETCP. * Успех копирует API и забирает ctx; отказ оставляет ctx непривязанным у вызывающего. * Начальный handshake/callbacks отложены. Все операции — conn->instance->ua. */ diff --git a/tests/test_etcp_init_liveness.c b/tests/test_etcp_init_liveness.c index eb879390d..2edf6e5d0 100644 --- a/tests/test_etcp_init_liveness.c +++ b/tests/test_etcp_init_liveness.c @@ -8,6 +8,7 @@ #include "etcp_keepalive.h" #include "node_conn_direct.h" #include "routing_layer/topo_node.h" +#include "routing_layer/topo_group.h" #include "utun_instance.h" #include "test_clock.h" #include "test_net.h" @@ -23,6 +24,7 @@ struct endpoint { static struct endpoint ep[2]; static struct UASYNC* ua; static unsigned close_action, close_fired, late_handshakes; +static int known_default; static const char* pubkeys[] = { "b3193173def895bd0fcea6f86af077c7d77216f10395275f627ac18242ec0f01", "ce8871f07fa056c636d297115f231b08c29cdf94e0d440fce83a07c34416d36a" @@ -90,7 +92,7 @@ static struct ETCP_LINK* first_link(unsigned side) { static void run_for(unsigned tb) { test_clock_run_for(ua, tb); } static void start_source(unsigned count) { - ep[0].conn = etcp_connection_create(ep[0].inst, "liveness", 0); CHECK(ep[0].conn); + ep[0].conn = etcp_connection_create(ep[0].inst, "liveness", known_default); CHECK(ep[0].conn); ep[0].conn->peer_node_id = ep[1].inst->node_id; CHECK(sc_init_ctx(&ep[0].conn->crypto_ctx, &ep[0].inst->my_keys) == SC_OK); CHECK(sc_set_peer_public_key(&ep[0].conn->crypto_ctx, ep[1].inst->my_keys.public_key, SC_PEER_PUBKEY_BIN) == SC_OK); @@ -119,6 +121,12 @@ static void setup(unsigned swapped, unsigned count) { CHECK(etcp_bind(ep[side].inst, 253, receive) == 0); } if (!count) return; /* Отдельная проверка входящего INIT до создания транспорта. */ + if (known_default) { + /* Общий объект ранее мог быть создан BLE: входящий UDP обязан переиспользовать его без CHAT-проверки. */ + ep[1].conn = etcp_connection_create(ep[1].inst, "shared native", 1); CHECK(ep[1].conn); + CHECK(!etcp_connection_set_peer(ep[1].conn, ep[0].inst->my_keys.public_key)); + CHECK(!etcp_conn_index_peer(ep[1].conn)); + } start_source(count); uint64_t end = get_time_tb() + 30000; while (get_time_tb() < end) {