mirror of
https://github.com/n0-computer/noq.git
synced 2026-09-23 11:45:25 +00:00
fix(proto): canonicalize off-path probe destinations to IPv4
Off-path NAT traversal probes had IPv4-mapped IPv6 destinations (e.g. [::ffff:10.0.0.4]) because map_to_local_socket_family maps to IPv6 when the connection has any IPv6 path. The transport layer routes V6 addresses to the IPv6 socket, which has a different port than the IPv4 socket. This breaks NAT hole punching because the probe arrives from the wrong source port. Canonicalize the destination in the Transmit so IPv4-mapped IPv6 addresses become plain IPv4, routing to the correct socket.
This commit is contained in:
@@ -2034,7 +2034,10 @@ impl Connection {
|
||||
.udp_tx
|
||||
.on_sent(1, size);
|
||||
Some(Transmit {
|
||||
destination: network_path.remote,
|
||||
destination: SocketAddr::new(
|
||||
network_path.remote.ip().to_canonical(),
|
||||
network_path.remote.port(),
|
||||
),
|
||||
size,
|
||||
ecn: None,
|
||||
segment_size: None,
|
||||
@@ -2117,8 +2120,14 @@ impl Connection {
|
||||
.udp_tx
|
||||
.on_sent(1, size);
|
||||
|
||||
// Canonicalize the destination: IPv4-mapped IPv6 addresses (e.g.
|
||||
// [::ffff:10.0.0.4]) must be converted to plain IPv4 so the transport
|
||||
// layer routes them to the IPv4 socket. Without this, the packet goes
|
||||
// out from the IPv6 socket with a different source port, breaking NAT
|
||||
// mappings needed for hole punching.
|
||||
let destination = SocketAddr::new(remote.ip().to_canonical(), remote.port());
|
||||
Some(Transmit {
|
||||
destination: remote,
|
||||
destination,
|
||||
size,
|
||||
ecn: None,
|
||||
segment_size: None,
|
||||
|
||||
Reference in New Issue
Block a user