Validate UDP handshake MTU and nonzero path IDs before state updates
This commit is contained in:
1 parent
1260884485
commit
b8021efed8
2 files changed
+16
-3
No files matched your search
@@ -2191,12 +2191,18 @@ static int handle_init_response_client(struct ETCP_SOCKET* e_sock, struct ETCP_D
|
||||
if (server_node_id != sc_derive_node_id_from_pubkey(link->etcp->crypto_ctx.peer_public_key)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "INIT_RESPONSE node ID does not match authenticated peer key"); return 46;
|
||||
}
|
||||
uint16_t remote_mtu = wire_read16(resp->mtu);
|
||||
if (!resp->link_id || remote_mtu < ETCP_MIN_UDP_MTU(link->remote_addr.ss_family)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "INIT_RESPONSE invalid path: link_id=%u MTU=%u minimum=%u",
|
||||
resp->link_id, remote_mtu, (unsigned)ETCP_MIN_UDP_MTU(link->remote_addr.ss_family));
|
||||
return 46;
|
||||
}
|
||||
struct ETCP_CONN* conn = link->etcp;
|
||||
int old_state = link->link_state, old_status = etcp_link_record_rx(link, pkt);
|
||||
uint64_t resp_reset_id = wire_read64(resp->reset_id);
|
||||
DEBUG_TRACE(DEBUG_CATEGORY_ETCP, "INIT_RESPONSE rid=%016llx", (unsigned long long)resp_reset_id);
|
||||
etcp_conn_apply_peer_reset_id(link->etcp, resp_reset_id);
|
||||
link->mtu_remote = wire_read16(resp->mtu);
|
||||
link->mtu_remote = remote_mtu;
|
||||
if (link->mtu_remote > PACKET_DATA_MAX_MTU) link->mtu_remote = PACKET_DATA_MAX_MTU;
|
||||
link->mtu = link->mtu_local < link->mtu_remote ? link->mtu_local : link->mtu_remote;
|
||||
etcp_update_mtu(link->etcp);
|
||||
@@ -2472,6 +2478,11 @@ static void etcp_process_packet(struct ETCP_SOCKET* e_sock, uint8_t* data,
|
||||
}
|
||||
uint64_t reset_id = wire_read64(req->reset_id);
|
||||
uint16_t mtu = wire_read16(req->mtu);
|
||||
if (!req->link_id || mtu < ETCP_MIN_UDP_MTU(addr.ss_family)) {
|
||||
DEBUG_WARN(DEBUG_CATEGORY_ETCP, "INIT_REQUEST invalid path: link_id=%u MTU=%u minimum=%u from=%s",
|
||||
req->link_id, mtu, (unsigned)ETCP_MIN_UDP_MTU(addr.ss_family), sockaddr_storage_to_str(&addr).str);
|
||||
errorcode = 7; goto ec_fr;
|
||||
}
|
||||
uint16_t src_port = wire_read16(req->src_port);
|
||||
DEBUG_INFO(DEBUG_CATEGORY_ETCP, "INIT received: peer=0x%016llx mtu=%u link=%u sock=%u rid=%016llx src=%s",
|
||||
(unsigned long long)peer_id, mtu, req->link_id, req->socket_id,
|
||||
|
||||
@@ -38,6 +38,8 @@ extern "C" {
|
||||
// PACKET_DATA_SIZE (2048) — это внутренний буфер аллокации/приёма, а не wire-MTU.
|
||||
#define PACKET_DATA_MAX_MTU 1500
|
||||
#define ETCP_PAYLOAD_HEADER_SIZE 7 // type + seq:u32 + attempt_no:u16 (LE, 1..65535, общий номер для всех линков seq)
|
||||
// Запас normalizer: длина u16 + хотя бы 1 байт кодограммы; меньший MTU даёт нулевой/переполненный frag_size.
|
||||
#define ETCP_MIN_UDP_MTU(fam) (WIRE_OVERHEAD(fam) + ETCP_PAYLOAD_HEADER_SIZE + ACK_REZERV + 3)
|
||||
#define ETCP_ACK_ENTRY_SIZE 10 // seq:u32 + attempt_no:u16 + receiver_delay_us:u32; все числа LE
|
||||
#define ETCP_MAX_PAYLOAD_SIZE (PACKET_DATA_SIZE - ETCP_ACK_BASE_SIZE - ETCP_PAYLOAD_HEADER_SIZE)
|
||||
#define ETCP_RFC791_MIN_MTU 576
|
||||
@@ -102,7 +104,7 @@ struct ETCP_INIT_REQUEST_PKT {
|
||||
uint8_t mtu[2]; // 17: client MTU (big-endian)
|
||||
uint8_t keepalive[2]; // 19: keepalive interval (big-endian)
|
||||
uint8_t recovery[2]; // 21: recovery interval/100 (big-endian)
|
||||
uint8_t link_id; // 23: client's local link id
|
||||
uint8_t link_id; // 23: client's local link id, 1..255
|
||||
uint8_t socket_id; // 24: client's socket id
|
||||
uint8_t only_local; // 25: client only_local flag
|
||||
uint8_t type; // 26: client socket type (CFG_SERVER_TYPE_*)
|
||||
@@ -124,7 +126,7 @@ struct ETCP_INIT_RESPONSE_PKT {
|
||||
uint8_t node_id[8]; // 1: server node_id (big-endian)
|
||||
uint8_t reset_id[8]; // 9: локальная эпоха потока сервера (big-endian), не эхо запроса
|
||||
uint8_t mtu[2]; // 17: server MTU (big-endian)
|
||||
uint8_t link_id; // 19: server's local link id
|
||||
uint8_t link_id; // 19: server's local link id, 1..255
|
||||
uint8_t remote_socket_id; // 20: ID серверного сокета, отправляющего ответ
|
||||
uint8_t only_local; // 21: server only_local flag
|
||||
uint8_t type; // 22: server socket type (CFG_SERVER_TYPE_*)
|
||||
|
||||
Reference in new issue
Block a user