Limit ETCP TCP link MTU to 1500 bytes
This commit is contained in:
1 parent
57168e4a16
commit
c8012d35f1
2 files changed
+34
-5
No files matched your search
@@ -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
@@ -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;
|
||||
|
||||
Reference in new issue
Block a user