Skip to content
Merged
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
51 changes: 51 additions & 0 deletions src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1631,6 +1631,28 @@ impl Socket {
unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_TTL, ttl as c_int) }
}

/// Get the value of the `IP_MINTTL` option for this socket.
///
/// For more information about this option, see [`set_min_ttl_v4`].
///
/// [`set_min_ttl_v4`]: Socket::set_min_ttl_v4
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
pub fn min_ttl_v4(&self) -> io::Result<u32> {
unsafe {
getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_MINTTL)
.map(|ttl| ttl as u32)
}
}

/// Set the value of the `IP_MINTTL` option for this socket.
///
/// If enabled, received IPv4 packets are discarded if the value of the
/// time-to-live field of the IPv4 header is lower than the option value.
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
pub fn set_min_ttl_v4(&self, ttl: u32) -> io::Result<()> {
unsafe { setsockopt(self.as_raw(), sys::IPPROTO_IP, sys::IP_MINTTL, ttl as c_int) }
}

/// Set the value of the `IP_TOS` option for this socket.
///
/// This value sets the type-of-service field that is used in every packet
Expand Down Expand Up @@ -2057,6 +2079,35 @@ impl Socket {
}
}

/// Get the value of the `IPV6_MINHOPCOUNT` option for this socket.
///
/// For more information about this option, see [`set_min_hopcount_v6`].
///
/// [`set_min_hopcount_v6`]: Socket::set_min_hopcount_v6
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
pub fn min_hopcount_v6(&self) -> io::Result<u32> {
unsafe {
getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IPV6_MINHOPCOUNT)
.map(|hops| hops as u32)
}
}

/// Set the value of the `IPV6_MINHOPCOUNT` option for this socket.
///
/// If enabled, received IPv6 packets are discarded if the value of the
/// hop limit field of the IPv6 header is lower than the option value.
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
pub fn set_min_hopcount_v6(&self, hops: u32) -> io::Result<()> {
unsafe {
setsockopt(
self.as_raw(),
sys::IPPROTO_IPV6,
sys::IPV6_MINHOPCOUNT,
hops as c_int,
)
}
}

/// Get the value of the `IPV6_V6ONLY` option for this socket.
///
/// For more information about this option, see [`set_only_v6`].
Expand Down
2 changes: 2 additions & 0 deletions src/sys/unix.rs
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,8 @@ pub(crate) use libc::{IPV6_ADD_MEMBERSHIP, IPV6_DROP_MEMBERSHIP};
pub(crate) use libc::{
IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP, IPV6_LEAVE_GROUP as IPV6_DROP_MEMBERSHIP,
};
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
pub(crate) use libc::{IPV6_MINHOPCOUNT, IP_MINTTL};
#[cfg(not(target_os = "wasi"))]
pub(crate) use libc::{IPV6_MULTICAST_HOPS, IPV6_MULTICAST_IF, IP_MULTICAST_IF, MSG_OOB};
#[cfg(all(
Expand Down
30 changes: 30 additions & 0 deletions tests/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1519,6 +1519,9 @@ test!(IPv6 freebind_v6, set_freebind_v6(true));

test!(IPv4 ttl_v4, set_ttl_v4(40));

#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
test!(IPv4 min_ttl_v4, set_min_ttl_v4(50));

#[cfg(not(any(
target_os = "fuchsia",
target_os = "redox",
Expand Down Expand Up @@ -1552,6 +1555,9 @@ test!(IPv4 broadcast, set_broadcast(true));
#[cfg(not(target_os = "vita"))]
test!(IPv6 unicast_hops_v6, set_unicast_hops_v6(20));

#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
test!(IPv6 min_hopcount_v6, set_min_hopcount_v6(30));

#[cfg(not(any(
windows,
target_os = "dragonfly",
Expand Down Expand Up @@ -1970,3 +1976,27 @@ fn set_busy_poll() {
assert!(socket.busy_poll().unwrap() == i);
}
}

#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
#[test]
fn min_ttl_v4_preserves_outbound_ttl() {
Comment thread
Thomasdezeeuw marked this conversation as resolved.
let socket = Socket::new(Domain::IPV4, Type::STREAM, None).unwrap();

socket.set_ttl_v4(61).unwrap();
socket.set_min_ttl_v4(197).unwrap();

assert_eq!(socket.min_ttl_v4().unwrap(), 197);
assert_eq!(socket.ttl_v4().unwrap(), 61);
}

#[cfg(all(feature = "all", any(target_os = "linux", target_os = "illumos")))]
#[test]
fn min_hopcount_v6_preserves_outbound_hops() {
let socket = Socket::new(Domain::IPV6, Type::STREAM, None).unwrap();

socket.set_unicast_hops_v6(61).unwrap();
socket.set_min_hopcount_v6(197).unwrap();

assert_eq!(socket.min_hopcount_v6().unwrap(), 197);
assert_eq!(socket.unicast_hops_v6().unwrap(), 61);
}
Loading