Skip to content

Commit

Permalink
UDP socket should set different IP_TRANSPARENT and IPV6_TRANSPARENT
Browse files Browse the repository at this point in the history
  • Loading branch information
zonyitoo committed Nov 2, 2020
1 parent a4d684c commit 2a6451f
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 9 deletions.
2 changes: 1 addition & 1 deletion src/relay/tcprelay/redir/sys/unix/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ fn create_redir_listener(addr: &SocketAddr) -> io::Result<TcpListener> {
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();

Expand Down
25 changes: 17 additions & 8 deletions src/relay/udprelay/redir/sys/unix/linux.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
Expand Down

0 comments on commit 2a6451f

Please sign in to comment.