Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TPROXY-related Linux things #1025

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions src/sys/socket/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -463,6 +463,19 @@ pub enum ControlMessageOwned {
target_os = "openbsd",
))]
Ipv4RecvDstAddr(libc::in_addr),
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV4(libc::sockaddr_in),
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV6(libc::sockaddr_in6),

/// Catch-all variant for unimplemented cmsg types.
#[doc(hidden)]
Unknown(UnknownCmsg),
Expand Down Expand Up @@ -546,6 +559,16 @@ impl ControlMessageOwned {
let dl = ptr::read_unaligned(p as *const libc::in_addr);
ControlMessageOwned::Ipv4RecvDstAddr(dl)
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
(libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {
let dl = ptr::read_unaligned(p as *const libc::sockaddr_in);
ControlMessageOwned::OrigDstAddrV4(dl)
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
(libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {
let dl = ptr::read_unaligned(p as *const libc::sockaddr_in6);
ControlMessageOwned::OrigDstAddrV6(dl)
},
(_, _) => {
let sl = slice::from_raw_parts(p, len);
let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(&sl[..]));
Expand Down Expand Up @@ -587,6 +610,34 @@ pub enum ControlMessage<'a> {
#[cfg(any(target_os = "android", target_os = "linux"))]
ScmCredentials(&'a UnixCredentials),

/// A message of type `IP_ORIGDSTADDR` which is triggered by setting
/// `RecvOrigDstAddrV4` socket option and is used to get original IPv4
/// UDP or TCP destination address when actual destination address
/// is overwritten by [`TPROXY`][1], which in turn may be used to
/// make a transparent proxy server.
///
/// [1]:https://www.kernel.org/doc/Documentation/networking/tproxy.txt
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV4(&'a libc::sockaddr_in),

/// A message of type `IPV6_ORIGDSTADDR` which is triggered by setting
/// `RecvOrigDstAddrV6` socket option and is used to get original IPv6
/// UDP or TCP destination address when actual destination address
/// is overwritten by [`TPROXY`][1], which in turn may be used to
/// make a transparent proxy server.
///
/// [1]:https://www.kernel.org/doc/Documentation/networking/tproxy.txt
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
OrigDstAddrV6(&'a libc::sockaddr_in6),

/// Set IV for `AF_ALG` crypto API.
///
/// For further information, please refer to the
Expand Down Expand Up @@ -655,6 +706,22 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmCredentials(creds) => {
&creds.0 as *const libc::ucred as *const u8
}
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV4(origaddr) => {
origaddr as *const libc::sockaddr_in as *const u8
},
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV6(origaddr) => {
origaddr as *const libc::sockaddr_in6 as *const u8
},
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetIv(iv) => {
unsafe {
Expand Down Expand Up @@ -696,6 +763,22 @@ impl<'a> ControlMessage<'a> {
ControlMessage::ScmCredentials(creds) => {
mem::size_of_val(creds)
}
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV4(origaddr) => {
mem::size_of_val(origaddr)
},
#[cfg(any(
target_os = "linux",
target_os = "android",
target_os = "freebsd",
))]
ControlMessage::OrigDstAddrV6(origaddr) => {
mem::size_of_val(origaddr)
},
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetIv(iv) => {
mem::size_of::<libc::af_alg_iv>() + iv.len()
Expand All @@ -720,6 +803,10 @@ impl<'a> ControlMessage<'a> {
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetIv(_) | ControlMessage::AlgSetOp(_) |
ControlMessage::AlgSetAeadAssoclen(_) => libc::SOL_ALG ,
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV4(_) => libc::IPPROTO_IP,
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV6(_) => libc::IPPROTO_IPV6,
}
}

Expand All @@ -733,6 +820,14 @@ impl<'a> ControlMessage<'a> {
ControlMessage::AlgSetIv(_) => {
libc::ALG_SET_IV
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV4(_) => {
libc::IP_ORIGDSTADDR
},
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
ControlMessage::OrigDstAddrV6(_) => {
libc::IPV6_ORIGDSTADDR
},
#[cfg(any(target_os = "android", target_os = "linux"))]
ControlMessage::AlgSetOp(_) => {
libc::ALG_SET_OP
Expand Down
4 changes: 4 additions & 0 deletions src/sys/socket/sockopt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -261,6 +261,10 @@ sockopt_impl!(GetOnly, OriginalDst, libc::SOL_IP, libc::SO_ORIGINAL_DST, libc::s
sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
#[cfg(any(target_os = "android", target_os = "linux"))]
sockopt_impl!(Both, IpTransparent, libc::SOL_IP, libc::IP_TRANSPARENT, bool);
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
sockopt_impl!(Both, RecvOrigDstAddrV4, libc::SOL_IP, libc::IP_RECVORIGDSTADDR, bool);
#[cfg(any(target_os = "android", target_os = "linux", target_os = "freebsd"))]
sockopt_impl!(Both, RecvOrigDstAddrV6, libc::SOL_IPV6, libc::IPV6_RECVORIGDSTADDR, bool);
#[cfg(target_os = "openbsd")]
sockopt_impl!(Both, BindAny, libc::SOL_SOCKET, libc::SO_BINDANY, bool);
#[cfg(target_os = "freebsd")]
Expand Down