Skip to content

Commit 3025b85

Browse files
authored
Support setting IP_TRANSPARENT on sockets
1 parent eaa5f8f commit 3025b85

File tree

2 files changed

+47
-0
lines changed

2 files changed

+47
-0
lines changed

src/socket.rs

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -955,6 +955,47 @@ fn into_linger(duration: Option<Duration>) -> sys::linger {
955955
/// * Linux: <https://man7.org/linux/man-pages/man7/ip.7.html>
956956
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
957957
impl Socket {
958+
/// Get the value of the `IP_TRANSPARENT` option on this socket.
959+
///
960+
/// For more information about this option, see [`set_ip_transparent`].
961+
///
962+
/// [`ip_transparent`]: Socket::set_ip_transparent
963+
#[cfg(all(feature = "all", target_os = "linux"))]
964+
pub fn ip_transparent(&self) -> io::Result<bool> {
965+
unsafe {
966+
getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, libc::IP_TRANSPARENT)
967+
.map(|transparent| transparent != 0)
968+
}
969+
}
970+
971+
/// Set the value of the `IP_TRANSPARENT` option on this socket.
972+
///
973+
/// Setting this boolean option enables transparent proxying
974+
/// on this socket. This socket option allows the calling
975+
/// application to bind to a nonlocal IP address and operate
976+
/// both as a client and a server with the foreign address as
977+
/// the local endpoint. NOTE: this requires that routing be
978+
/// set up in a way that packets going to the foreign address
979+
/// are routed through the TProxy box (i.e., the system
980+
/// hosting the application that employs the IP_TRANSPARENT
981+
/// socket option). Enabling this socket option requires
982+
/// superuser privileges (the CAP_NET_ADMIN capability).
983+
///
984+
/// TProxy redirection with the iptables TPROXY target also
985+
/// requires that this option be set on the redirected socket.
986+
/// this feature is only available on linux
987+
#[cfg(all(feature = "all", target_os = "linux"))]
988+
pub fn set_ip_transparent(&self, transparent: bool) -> io::Result<()> {
989+
unsafe {
990+
setsockopt(
991+
self.as_raw(),
992+
sys::IPPROTO_IP,
993+
libc::IP_TRANSPARENT,
994+
transparent as c_int,
995+
)
996+
}
997+
}
998+
958999
/// Join a multicast group using `IP_ADD_MEMBERSHIP` option on this socket.
9591000
///
9601001
/// This function specifies a new multicast group for this socket to join.

tests/socket.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1047,6 +1047,12 @@ test!(
10471047
mss,
10481048
set_mss(256)
10491049
);
1050+
#[cfg(all(feature = "all", target_os = "linux"))]
1051+
test!(
1052+
#[ignore = "setting `IP_TRANSPARENT` requires the `CAP_NET_ADMIN` capability (works when running as root)"]
1053+
ip_transparent,
1054+
set_ip_transparent(true)
1055+
);
10501056
#[cfg(all(feature = "all", any(target_os = "fuchsia", target_os = "linux")))]
10511057
test!(
10521058
#[ignore = "setting `SO_MARK` requires the `CAP_NET_ADMIN` capability (works when running as root)"]

0 commit comments

Comments
 (0)