From 56d092863242f1ae4b1d0d35e46f1fe2f0bc0401 Mon Sep 17 00:00:00 2001 From: evgeny Date: Sat, 12 Sep 2026 13:53:55 +0300 Subject: [PATCH] =?UTF-8?q?etcp:=20wire-MTU=20=D0=BA=D0=B0=D0=BF=202048?= =?UTF-8?q?=E2=86=921500=20(=D1=81=D0=BE=D0=B3=D0=BB=D0=B0=D1=81=D0=BE?= =?UTF-8?q?=D0=B2=D0=B0=D0=BD=D0=BE=20=D1=81=20TUN=5FMAX=5FPACKET=5FSIZE),?= =?UTF-8?q?=20enc=5Fbuf=20=D0=BF=D1=80=D0=B8=D0=B2=D1=8F=D0=B7=D0=B0=D0=BD?= =?UTF-8?q?=20=D0=BA=20MTU;=20=D1=82=D0=B5=D1=81=D1=82=20multilink:=20per-?= =?UTF-8?q?link=20=D0=BF=D1=80=D0=BE=D0=B2=D0=B5=D1=80=D0=BA=D0=B0=20?= =?UTF-8?q?=D1=82=D1=80=D0=B0=D1=84=D0=B8=D0=BA=D0=B0=20=D1=81=20=D1=80?= =?UTF-8?q?=D0=B5=D1=82=D1=80=D0=B0=D0=B5=D0=BC=20=D1=87=D0=B5=D1=80=D0=B5?= =?UTF-8?q?=D0=B7=20keepalive-=D1=82=D0=B8=D0=BA=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/transport_layer/etcp_connections.c | 2 +- src/transport_layer/etcp_connections.h | 4 +++- tests/test_etcp_link_stress.c | 26 +++++++++++++++++--------- 3 files changed, 21 insertions(+), 11 deletions(-) diff --git a/src/transport_layer/etcp_connections.c b/src/transport_layer/etcp_connections.c index d2223564..49ce37d8 100644 --- a/src/transport_layer/etcp_connections.c +++ b/src/transport_layer/etcp_connections.c @@ -1255,7 +1255,7 @@ int etcp_encrypt_send(struct ETCP_DGRAM* dgram) { int udp_ov = (dgram->link->remote_addr.ss_family == AF_INET6) ? IP_UDP_OVERHEAD_V6 : IP_UDP_OVERHEAD_V4; int wire_ov = udp_ov + SC_ENCRYPT_OVERHEAD; if (len<0 || len + (int)dgram->noencrypt_len > (int)(dgram->link->mtu - wire_ov)) { dgram->link->send_errors++; errcode=1; goto es_err; } - uint8_t enc_buf[PACKET_DATA_MAX_MTU];// должно вмещать mtu - udp_ov (до 2020 байт) + uint8_t enc_buf[PACKET_DATA_MAX_MTU];// макс запись = data_len + 32 <= mtu - wire_ov + 32 = 1468 size_t enc_buf_len=0; dgram->timestamp=get_current_timestamp(); diff --git a/src/transport_layer/etcp_connections.h b/src/transport_layer/etcp_connections.h index a860af19..cbcbbaba 100644 --- a/src/transport_layer/etcp_connections.h +++ b/src/transport_layer/etcp_connections.h @@ -28,7 +28,9 @@ extern "C" { #define INFLIGHT_LIM_MAX 1048576 // 1M #define PACKET_DATA_SIZE 2048 -#define PACKET_DATA_MAX_MTU 2048 +// Wire-MTU кап: пакет на проводе не должен превышать 1500 (согласовано с TUN_MAX_PACKET_SIZE). +// PACKET_DATA_SIZE (2048) — это внутренний буфер аллокации/приёма, а не wire-MTU. +#define PACKET_DATA_MAX_MTU 1500 #define ETCP_MAX_PAYLOAD_SIZE (PACKET_DATA_SIZE - ETCP_ACK_BASE_SIZE - 5) /* 2035 */ #define ETCP_RFC791_MIN_MTU 576 diff --git a/tests/test_etcp_link_stress.c b/tests/test_etcp_link_stress.c index 3e00e6c5..6f6934ff 100644 --- a/tests/test_etcp_link_stress.c +++ b/tests/test_etcp_link_stress.c @@ -256,6 +256,20 @@ static int run_traffic(int n, uint64_t timeout_ms) { } } +// Проверяет, что конкретный линк (по серверному порту) реально перенёс данные. +// Линк может пропустить короткий burst из-за keepalive-стабилизации link_status, +// поэтому повторяем до нескольких keepalive-тиков. Возвращает 0 если линк нёс трафик. +static int check_link_traffic(uint16_t srv_port, const char* label) { + for (int attempt = 0; attempt < 6; attempt++) { + uint64_t before = client_link_acked(srv_port); + if (run_traffic(TRAFFIC_PACKETS, TRAFFIC_TIMEOUT_MS) != 0) return -1; + if (client_link_acked(srv_port) > before) return 0; + uasync_poll(ua, 50); + } + printf(" [%s] link never carried traffic\n", label); + return -1; +} + // ===== instance lifecycle ===== static int start_instances(void) { @@ -306,9 +320,7 @@ static int session_a(void) { // -- per-link трафик на исходном линке -- printf("[A] traffic on initial link...\n"); - uint64_t ack0 = client_link_acked(server_port); - CHECK(run_traffic(TRAFFIC_PACKETS, TRAFFIC_TIMEOUT_MS) == 0, "initial traffic failed"); - CHECK(client_link_acked(server_port) > ack0, "initial link carried no traffic"); + CHECK(check_link_traffic(server_port, "initial") == 0, "initial link carried no traffic"); CHECK(sc->reinit_count == srv_reinit0 && cc->reinit_count == cli_reinit0, "reinit during initial traffic"); // -- V1: клиент дозванивается до нового серверного сокета S1 -- @@ -324,9 +336,7 @@ static int session_a(void) { g_sock = s1; CHECK(poll_until(c_socket_link_up, LINK_UP_TIMEOUT_MS, "V1 link up (server)") == 0, "V1 server link did not come up"); CHECK(sc->reinit_count == srv_reinit0 && cc->reinit_count == cli_reinit0, "reinit during V1"); - ack0 = client_link_acked(sp1); - CHECK(run_traffic(TRAFFIC_PACKETS, TRAFFIC_TIMEOUT_MS) == 0, "V1 traffic failed"); - CHECK(client_link_acked(sp1) > ack0, "V1 link carried no traffic"); + CHECK(check_link_traffic(sp1, "V1") == 0, "V1 link carried no traffic"); // -- V2: сервер дозванивается до клиента -- int sp2 = alloc_port(); @@ -341,9 +351,7 @@ static int session_a(void) { g_conn = cc; g_port = sp2; CHECK(poll_until(c_link_on_port_up, LINK_UP_TIMEOUT_MS, "V2 link up (client)") == 0, "V2 client link did not come up"); CHECK(sc->reinit_count == srv_reinit0 && cc->reinit_count == cli_reinit0, "reinit during V2"); - ack0 = client_link_acked(sp2); - CHECK(run_traffic(TRAFFIC_PACKETS, TRAFFIC_TIMEOUT_MS) == 0, "V2 traffic failed"); - CHECK(client_link_acked(sp2) > ack0, "V2 link carried no traffic"); + CHECK(check_link_traffic(sp2, "V2") == 0, "V2 link carried no traffic"); printf("[A] after adds: server links_up=%d/%d client links_up=%d/%d\n", count_links_up(sc), count_links(sc), count_links_up(cc), count_links(cc));