Skip to content

Commit

Permalink
fix(local-redir): set IPV6_V6ONLY for IPv4-mapped IPv6 bind() call
Browse files Browse the repository at this point in the history
- ref #1543
  • Loading branch information
zonyitoo committed Jun 16, 2024
1 parent bedfe34 commit a27410c
Show file tree
Hide file tree
Showing 2 changed files with 4 additions and 24 deletions.
3 changes: 2 additions & 1 deletion crates/shadowsocks/src/net/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,8 @@ impl From<SocketAddr> for AddrFamily {
/// Check if `SocketAddr` could be used for creating dual-stack sockets
pub fn is_dual_stack_addr(addr: &SocketAddr) -> bool {
if let SocketAddr::V6(ref v6) = *addr {
v6.ip().is_unspecified()
let ip = v6.ip();
ip.is_unspecified() || ip.to_ipv4_mapped().is_some()
} else {
false
}
Expand Down
25 changes: 2 additions & 23 deletions crates/shadowsocks/src/net/sys/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -176,32 +176,11 @@ static IP_STACK_CAPABILITIES: Lazy<IpStackCapabilities> = Lazy::new(|| {
});

fn check_ipv4_mapped_ipv6_capability() -> io::Result<()> {
// https://stackoverflow.com/questions/30184377/how-to-detect-if-dual-stack-socket-is-supported
let socket = Socket::new(Domain::IPV6, Type::STREAM, Some(Protocol::TCP))?;
socket.set_only_v6(false)?;

let local_host = SockAddr::from(SocketAddr::new(Ipv4Addr::LOCALHOST.to_ipv6_mapped().into(), 0));
let local_host_53 = SockAddr::from(SocketAddr::new(Ipv4Addr::LOCALHOST.to_ipv6_mapped().into(), 53));

let socket = Socket::new(Domain::IPV6, Type::DGRAM, Some(Protocol::UDP))?;
socket.set_only_v6(false)?;
socket.bind(&local_host)?;
socket.connect(&local_host_53)?;

// getsockname()
let local_addr = socket.local_addr()?;
match local_addr.as_socket() {
None => return Err(io::Error::new(ErrorKind::Other, "invalid local_addr")),
Some(addr) => match addr {
SocketAddr::V4(..) => return Err(io::Error::new(ErrorKind::Other, "local_addr returned an IPv4 address")),
SocketAddr::V6(v6) => {
if v6.ip().to_ipv4_mapped().is_none() {
return Err(io::Error::new(
ErrorKind::Other,
"local_addr returned a non IPv4-mapped-IPv6 address",
));
}
}
},
}

Ok(())
}
Expand Down

0 comments on commit a27410c

Please sign in to comment.