From 8633b35388cc1b93b352d35041fb4f5be02c44fe Mon Sep 17 00:00:00 2001 From: evgeny Date: Wed, 4 Nov 2026 01:37:54 +0100 Subject: [PATCH] Verify retired invitation packets cannot enter a group API --- src/transport_layer/etcp_api.h | 2 +- tests/test_chat_group_isolation.c | 22 ++++++++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/transport_layer/etcp_api.h b/src/transport_layer/etcp_api.h index 823767485..2a7229bc7 100644 --- a/src/transport_layer/etcp_api.h +++ b/src/transport_layer/etcp_api.h @@ -47,7 +47,7 @@ extern "C" { #define ETCP_ID_STREAM 0x07 // прямой stream INFO/выдачи/DATA #define ETCP_ID_MULTICAST 0x08 // адресный мультикаст с разделением по маршрутам группы #define ETCP_ID_NCD_CONTROL 0x12 // node_conn_direct CLOSE/KEEP_ALIVE -#define ETCP_ID_GROUP_INVITE 0x13 // topo_group_invite +#define ETCP_ID_GROUP_INVITE 0x13 // зарезервирован: старый INVITE_INFO удалён; вступление только через CHAT_SYNC JOIN #define ETCP_ID_DB_SYNC 0x20 // db_sync #define ETCP_ID_CHAT_SYNC 0x30 // chat_sync #define ETCP_ID_MEMBER_SYNC 0x31 // member_sync/merkle_sync diff --git a/tests/test_chat_group_isolation.c b/tests/test_chat_group_isolation.c index 7df3f7e74..63bdee94c 100644 --- a/tests/test_chat_group_isolation.c +++ b/tests/test_chat_group_isolation.c @@ -94,7 +94,8 @@ static void observe(struct ETCP_CONN* conn, struct ll_entry* entry) { DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "isolation wire delivered service=%u peer=%016llx bytes=%u", service, (unsigned long long)conn->peer_node_id, entry->len); } - fixture.receivers[service](conn, entry); + if (fixture.receivers[service]) fixture.receivers[service](conn, entry); + else { queue_dgram_free(entry); queue_entry_free(entry); } } /* Считаем реальную выдачу данных пользовательскому callback группы. */ @@ -1133,6 +1134,22 @@ static int members_isolation(void) { return 0; } +/* Старый INVITE_INFO не обслуживается даже на общем живом ETCP; fallback только фиксирует доставку пакета. */ +static int retired_invite_isolation(void) { + struct UTUN_INSTANCE* server = fixture.nodes[0]; + check("legacy INVITE_INFO has no endpoint on either node", !server->api_bindings.callbacks[ETCP_ID_GROUP_INVITE] + && !fixture.nodes[1]->api_bindings.callbacks[ETCP_ID_GROUP_INVITE]); + REQUIRE(!server->api_bindings.callbacks[ETCP_ID_DATA]); + REQUIRE(!etcp_bind(server, ETCP_ID_DATA, observe)); + for (uint64_t group = 111; group <= 112; group++) { + uint8_t request[10] = {ETCP_ID_GROUP_INVITE, 1}; memcpy(request + 2, &group, 8); + REQUIRE(!inject(request, sizeof(request))); + } + REQUIRE(!etcp_unbind(server, ETCP_ID_DATA)); + check("legacy requests reach the unsupported-command fallback without affecting shared transport", fixture.transport->links_up); + return 0; +} + int main(void) { debug_config_init(); debug_set_level(DEBUG_LEVEL_WARN); debug_set_category_level(DEBUG_CATEGORY_DEBUG, DEBUG_LEVEL_INFO); @@ -1142,7 +1159,8 @@ int main(void) { debug_set_category_level(DEBUG_CATEGORY_BGP, DEBUG_LEVEL_INFO); debug_set_category_level(DEBUG_CATEGORY_MEDIA, DEBUG_LEVEL_DEBUG); } - if (setup() || members_isolation() || run() || invitation_isolation() || join_isolation() || nat_isolation() || multicast_isolation()) fixture.failed++; + if (setup() || retired_invite_isolation() || members_isolation() || run() || invitation_isolation() + || join_isolation() || nat_isolation() || multicast_isolation()) fixture.failed++; else { for (unsigned i = 0; i < 2; i++) if (member_files_init(fixture.nodes[i])) fixture.failed++; if (!fixture.failed) {