Skip to content

Commit

Permalink
Add: header_included_v6() and set_header_included_v6()
Browse files Browse the repository at this point in the history
Also, deprecate header_included() and set_header_included() in favor of
header_included_v4() and set_header_included_v4().
  • Loading branch information
jjnicola authored and Thomasdezeeuw committed Jun 19, 2024
1 parent 6a13053 commit 7fe1bff
Show file tree
Hide file tree
Showing 2 changed files with 99 additions and 5 deletions.
74 changes: 72 additions & 2 deletions src/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1138,6 +1138,16 @@ const fn into_linger(duration: Option<Duration>) -> sys::linger {
/// * Linux: <https://man7.org/linux/man-pages/man7/ip.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ip-socket-options>
impl Socket {
/// This method is deprecated, use [`crate::Socket::header_included_v4`].
#[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf")))))
)]
#[deprecated = "Use `Socket::header_included_v4` instead"]
pub fn header_included(&self) -> io::Result<bool> {
self.header_included_v4()
}
/// Get the value of the `IP_HDRINCL` option on this socket.
///
/// For more information about this option, see [`set_header_included`].
Expand All @@ -1148,13 +1158,28 @@ impl Socket {
docsrs,
doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf")))))
)]
pub fn header_included(&self) -> io::Result<bool> {
pub fn header_included_v4(&self) -> io::Result<bool> {
unsafe {
getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IP, sys::IP_HDRINCL)
.map(|included| included != 0)
}
}

/// This method is deprecated, use [`crate::Socket::set_header_included_v4`].
#[cfg_attr(
any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"),
allow(rustdoc::broken_intra_doc_links)
)]
#[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf")))))
)]
#[deprecated = "Use `Socket::set_header_included_v4` instead"]
pub fn set_header_included(&self, included: bool) -> io::Result<()> {
self.set_header_included_v4(included)
}

/// Set the value of the `IP_HDRINCL` option on this socket.
///
/// If enabled, the user supplies an IP header in front of the user data.
Expand All @@ -1175,7 +1200,7 @@ impl Socket {
docsrs,
doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf")))))
)]
pub fn set_header_included(&self, included: bool) -> io::Result<()> {
pub fn set_header_included_v4(&self, included: bool) -> io::Result<()> {
unsafe {
setsockopt(
self.as_raw(),
Expand Down Expand Up @@ -1651,6 +1676,51 @@ impl Socket {
/// * Linux: <https://man7.org/linux/man-pages/man7/ipv6.7.html>
/// * Windows: <https://docs.microsoft.com/en-us/windows/win32/winsock/ipproto-ipv6-socket-options>
impl Socket {
/// Get the value of the `IP_HDRINCL` option on this socket.
///
/// For more information about this option, see [`set_header_included`].
///
/// [`set_header_included`]: Socket::set_header_included
#[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf")))))
)]
pub fn header_included_v6(&self) -> io::Result<bool> {
unsafe {
getsockopt::<c_int>(self.as_raw(), sys::IPPROTO_IPV6, sys::IP_HDRINCL)
.map(|included| included != 0)
}
}

/// Set the value of the `IP_HDRINCL` option on this socket.
///
/// If enabled, the user supplies an IP header in front of the user data.
/// Valid only for [`SOCK_RAW`] sockets; see [raw(7)] for more information.
/// When this flag is enabled, the values set by `IP_OPTIONS` are ignored.
///
/// [`SOCK_RAW`]: Type::RAW
/// [raw(7)]: https://man7.org/linux/man-pages/man7/raw.7.html
#[cfg_attr(
any(target_os = "fuchsia", target_os = "illumos", target_os = "solaris"),
allow(rustdoc::broken_intra_doc_links)
)]
#[cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf"))))]
#[cfg_attr(
docsrs,
doc(cfg(all(feature = "all", not(any(target_os = "redox", target_os = "espidf")))))
)]
pub fn set_header_included_v6(&self, included: bool) -> io::Result<()> {
unsafe {
setsockopt(
self.as_raw(),
sys::IPPROTO_IPV6,
sys::IP_HDRINCL,
included as c_int,
)
}
}

/// Join a multicast group using `IPV6_ADD_MEMBERSHIP` option on this socket.
///
/// Some OSs use `IPV6_JOIN_GROUP` for this option.
Expand Down
30 changes: 27 additions & 3 deletions tests/socket.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1539,14 +1539,38 @@ fn header_included() {
};

let initial = socket
.header_included()
.header_included_v4()
.expect("failed to get initial value");
assert_eq!(initial, false, "initial value and argument are the same");

socket
.set_header_included(true)
.set_header_included_v4(true)
.expect("failed to set option");
let got = socket.header_included().expect("failed to get value");
let got = socket.header_included_v4().expect("failed to get value");
assert_eq!(got, true, "set and get values differ");
}

#[test]
#[cfg(all(feature = "all", not(target_os = "redox")))]
fn header_included_ipv6() {
let socket = match Socket::new(Domain::IPV6, Type::RAW, None) {
Ok(socket) => socket,
// Need certain permissions to create a raw sockets.
Err(ref err) if err.kind() == io::ErrorKind::PermissionDenied => return,
#[cfg(unix)]
Err(ref err) if err.raw_os_error() == Some(libc::EPROTONOSUPPORT) => return,
Err(err) => panic!("unexpected error creating socket: {}", err),
};

let initial = socket
.header_included_v6()
.expect("failed to get initial value");
assert_eq!(initial, false, "initial value and argument are the same");

socket
.set_header_included_v6(true)
.expect("failed to set option");
let got = socket.header_included_v6().expect("failed to get value");
assert_eq!(got, true, "set and get values differ");
}

Expand Down

0 comments on commit 7fe1bff

Please sign in to comment.