diff --git a/src/relay/tcprelay/redir/sys/unix/linux.rs b/src/relay/tcprelay/redir/sys/unix/linux.rs index 777aadb5e5d4..efbd119420a6 100644 --- a/src/relay/tcprelay/redir/sys/unix/linux.rs +++ b/src/relay/tcprelay/redir/sys/unix/linux.rs @@ -101,7 +101,7 @@ fn create_redir_listener(addr: &SocketAddr) -> io::Result { let socket = Socket::new(domain, Type::stream(), Some(Protocol::tcp()))?; // For Linux 2.4+ TPROXY - // Sockets have to set IP_TRANSPARENT for retrieving original destination by getsockname() + // Sockets have to set IP_TRANSPARENT, IPV6_TRANSPARENT for retrieving original destination by getsockname() unsafe { let fd = socket.as_raw_fd(); diff --git a/src/relay/udprelay/redir/sys/unix/linux.rs b/src/relay/udprelay/redir/sys/unix/linux.rs index ec12e4738002..1cf92210a8cb 100644 --- a/src/relay/udprelay/redir/sys/unix/linux.rs +++ b/src/relay/udprelay/redir/sys/unix/linux.rs @@ -103,14 +103,23 @@ fn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> let enable: libc::c_int = 1; unsafe { - // 1. Set IP_TRANSPARENT to allow binding to non-local addresses - let ret = libc::setsockopt( - fd, - libc::SOL_IP, - libc::IP_TRANSPARENT, - &enable as *const _ as *const _, - mem::size_of_val(&enable) as libc::socklen_t, - ); + // 1. Set IP_TRANSPARENT, IPV6_TRANSPARENT to allow binding to non-local addresses + let ret = match *addr { + SocketAddr::V4(..) => libc::setsockopt( + fd, + libc::SOL_IP, + libc::IP_TRANSPARENT, + &enable as *const _ as *const _, + mem::size_of_val(&enable) as libc::socklen_t, + ), + SocketAddr::V6(..) => libc::setsockopt( + fd, + libc::SOL_IPV6, + libc::IPV6_TRANSPARENT, + &enable as *const _ as *const _, + mem::size_of_val(&enable) as libc::socklen_t, + ), + }; if ret != 0 { return Err(Error::last_os_error()); }