Limit ETCP TCP link MTU to 1500 bytes

This commit is contained in:
evgeny committed 2026-10-31 21:35:10 +01:00
1 parent 57168e4a16
commit c8012d35f1
2 files changed
+34 -5

No files matched your search

+4 -4
View File
@@ -1117,10 +1117,10 @@ static struct ETCP_LINK* link_create(struct ETCP_CONN* etcp, struct ETCP_SOCKET*
link->etcp = etcp;
link->is_server = is_server;
link->is_tcp = (uint8_t)is_tcp;
int mtu;
mtu = conn ? conn->mtu : STCP_MAX_MSG_SIZE;
if (is_tcp) mtu = STCP_MAX_MSG_SIZE;
else { if (mtu == 0) mtu = 1280; if (mtu > PACKET_DATA_MAX_MTU) mtu = PACKET_DATA_MAX_MTU; }
// Предел кадра STCP не задаёт MTU ETCP: фрагмент со служебными секциями должен вмещаться в 1500 байт.
int mtu = is_tcp || !conn ? PACKET_DATA_MAX_MTU : conn->mtu;
if (mtu == 0) mtu = 1280;
if (mtu > PACKET_DATA_MAX_MTU) mtu = PACKET_DATA_MAX_MTU;
if (driver) {
size_t maximum = driver->get_state(driver->ctx).max_packet;
mtu = maximum < PACKET_DATA_MAX_MTU ? (int)maximum : PACKET_DATA_MAX_MTU;
+30 -1
View File
@@ -5,6 +5,7 @@
#include "etcp.h"
#include "etcp_api.h"
#include "etcp_connections.h"
#include "etcp_loadbalancer.h"
#include "etcp_session.h"
#include "etcp_bbr.h"
#include "stcp_link.h"
@@ -210,6 +211,34 @@ static void exchange_messages(void) {
for (int i = 0; i < 2; i++) CHECK(!endpoints[i].conn->input_wait_ack->count && !endpoints[i].conn->input_send_q->count);
}
// Накопленные ACK должны разбиваться на пакеты до 1500 байт и успешно уходить через настоящий STCP.
static void check_tcp_ack_mtu(void) {
for (int i = 0; i < 2; i++) {
struct ETCP_CONN* conn = endpoints[i].conn;
for (struct ETCP_LINK* l = conn->links; l; l = l->next)
CHECK(l->is_tcp && l->mtu == PACKET_DATA_MAX_MTU && l->mtu_local == PACKET_DATA_MAX_MTU);
struct ETCP_LINK* link = conn->links; CHECK(link && link->initialized && link->link_status);
for (unsigned attempt = 1; attempt <= 202; attempt++)
CHECK(etcp_tx_queue_ack(link, conn->last_delivered_id, etcp_tx_attempt_id(conn->last_delivered_id, attempt)) == 0);
unsigned packets = 0, max_size = 0;
while (link->ack_q->count) {
unsigned before = link->ack_q->count;
link->ack_reply_pending = 1;
struct ETCP_DGRAM* packet = etcp_request_pkt(conn); CHECK(packet && packet->link == link && packet->ack_count);
unsigned size = packet->data_len + ETCP_ENCRYPTED_HDR_SIZE + ETCP_SESSION_HEADER_SIZE;
CHECK(size <= link->mtu && size <= PACKET_DATA_MAX_MTU);
if (size > max_size) max_size = size;
unsigned count = packet->ack_count;
CHECK(etcp_loadbalancer_send(packet) >= 0);
CHECK(link->ack_q->count == (int)(before - count));
packets++;
}
CHECK(packets >= 2);
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "PASS TCP ACK MTU: side=%d mtu=%u packets=%u max_packet=%u ACK_queue=0",
i, link->mtu, packets, max_size);
}
}
static void run_case(int reality, int simultaneous, int restarted) {
DEBUG_INFO(DEBUG_CATEGORY_DEBUG, "Transport case: reality=%d simultaneous=%d restart=%d", reality, simultaneous, restarted);
memset(endpoints, 0, sizeof(endpoints)); phase = 0; failed = 0; stream_packets = session_packets = 0;
@@ -229,7 +258,7 @@ static void run_case(int reality, int simultaneous, int restarted) {
CHECK(node_conn_direct_update_node(endpoints[0].inst, peers[0]->node_id) == 0);
unsigned updated = 0; for (struct ETCP_LINK* l = endpoints[0].conn->links; l; l = l->next) updated++;
CHECK(updated == links); node_conn_direct_close(extra);
exchange_messages();
exchange_messages(); check_tcp_ack_mtu();
if (restarted < 2) {
int survivor = 1 - restarted;