fix(transport/udp): preserve sin6_scope_id on receive

sockaddr_to_socket_addr dropped the IPv6 scope id when converting an
inbound source address, so a reply to a link-local peer (fe80::/10) had
no interface scope and could not be routed. This stalled the Noise
handshake reply (msg2) over a Wi-Fi Aware NDP interface, where every
address is link-local: msg1 reached the peer (sent to a scoped address)
but msg2 never routed back. Rebuild the SocketAddrV6 with sin6_scope_id;
non-link-local sources carry scope 0 and are unaffected.
This commit is contained in:
Arjen
2026-07-14 13:54:05 +02:00
parent 081855e8e2
commit 3ae4ac725b
+11 -1
View File
@@ -606,7 +606,17 @@ mod platform {
unsafe { &*(storage as *const _ as *const libc::sockaddr_in6) };
let ip = std::net::Ipv6Addr::from(addr.sin6_addr.s6_addr);
let port = u16::from_be(addr.sin6_port);
Ok(SocketAddr::from((ip, port)))
// Preserve sin6_scope_id: a link-local source (fe80::/10) is
// only routable together with its interface scope, so dropping
// it here breaks replies to a link-local peer (e.g. a Wi-Fi
// Aware NDP interface). Non-link-local sources carry scope 0,
// for which SocketAddrV6 is identical to the unscoped form.
Ok(SocketAddr::V6(std::net::SocketAddrV6::new(
ip,
port,
0,
addr.sin6_scope_id,
)))
}
family => Err(std::io::Error::new(
std::io::ErrorKind::InvalidData,