Browse Source

fix: DIRECT detection read srс_ipv4/src_port before INIT RESPONSE overwrites the buffer

Both req (INIT_REQUEST) and resp (INIT_RESPONSE) point to pkt->data.
resp->peer_port at offset 23-24 overwrites req->src_ipv4[0..1] at same offset.
Save src_ipv4/src_port before building the response.
feature/x25519-migration
Evgeny 3 months ago
parent
commit
5420e414ce
  1. 16
      src/etcp_connections.c

16
src/etcp_connections.c

@ -1485,6 +1485,9 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
link->mtu = link->mtu_local < link->mtu_remote ? link->mtu_local : link->mtu_remote;
etcp_update_mtu(link->etcp);
uint32_t req_src_ip; memcpy(&req_src_ip, req->src_ipv4, 4);
uint16_t req_src_port = be16toh(*(uint16_t*)req->src_port);
struct ETCP_INIT_RESPONSE_PKT* resp = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data;
// Set response code: 0x03 (with reset) or 0x05 (without reset)
@ -1523,11 +1526,8 @@ void etcp_connections_read_callback_socket(socket_t sock, void* arg) {
}
// DIRECT detection: if client reports its own address and it matches observed source → real public IP
if (pkt_len >= ETCP_INIT_REQ_V2_SIZE && addr.ss_family == AF_INET && link->nat_ip != 0) {
uint32_t reported_ip;
memcpy(&reported_ip, req->src_ipv4, 4);
uint16_t reported_port = be16toh(*(uint16_t*)req->src_port);
if (reported_ip != 0 && reported_ip == link->nat_ip
&& reported_port == link->nat_port
if (req_src_ip != 0 && req_src_ip == link->nat_ip
&& req_src_port == link->nat_port
&& !is_local_subnet(link->nat_ip))
{
link->nat_type = NAT_TYPE_DIRECT;
@ -1630,7 +1630,11 @@ process_decrypted:
if (pkt_len < ETCP_INIT_RESP_V1_SIZE) { errorcode = 46; DEBUG_ERROR(DEBUG_CATEGORY_ETCP, "INIT_RESPONSE too short: pkt_len=%zu", pkt_len); goto ec_fr; }
// ETCP_INIT_RESPONSE (0x03) - reset entire ETCP_CONN
// ETCP_INIT_RESPONSE_NOINIT (0x05) - no reset
struct ETCP_INIT_RESPONSE_PKT* resp = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data;
// Save src_ipv4/src_port from INIT REQUEST before we overwrite the buffer with INIT RESPONSE
uint32_t req_src_ip; memcpy(&req_src_ip, req->src_ipv4, 4);
uint16_t req_src_port = be16toh(*(uint16_t*)req->src_port);
struct ETCP_INIT_RESPONSE_PKT* resp = (struct ETCP_INIT_RESPONSE_PKT*)pkt->data;
uint64_t server_node_id = be64toh(*(uint64_t*)resp->node_id);
uint32_t resp_session_id = be32toh(*(uint32_t*)resp->session_id);
DEBUG_TRACE(DEBUG_CATEGORY_CONNECTION, "INIT_RESPONSE session_id=%08x", resp_session_id);

Loading…
Cancel
Save