diff --git a/src/etcp_connections.c b/src/etcp_connections.c index 1f3cdddb..79641930 100644 --- a/src/etcp_connections.c +++ b/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);