Skip to content

Commit 14a2969

Browse files
authored
2075: Add ControlMessage::Ipv6HopLimit (#2074)
When sending IPv6 packets with `sendmsg`, Linux does not use the hop limit set on the socket. Instead, the hop limit has to be specified for each individual message with ancillary data in a cmsg. This commit adds the enum variant `ControlMessage::Ipv6HopLimit` to specify the limit. The variant is available on the `net` feature flag for Linux, MacOs, FreeBSD, DragonflyBSD, Android, iOS and Haiku. Co-authored-by: Simon B. Gasse <[email protected]>
1 parent 2f4861f commit 14a2969

File tree

2 files changed

+56
-14
lines changed

2 files changed

+56
-14
lines changed

CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,10 @@ This project adheres to [Semantic Versioning](https://semver.org/).
4949
- Added `Icmp` and `IcmpV6` to `SockProtocol`.
5050
(#[2103](https://github.com/nix-rust/nix/pull/2103))
5151

52+
- Added `Ipv6HopLimit` to `::nix::sys::socket::ControlMessage` for Linux,
53+
MacOS, FreeBSD, DragonflyBSD, Android, iOS and Haiku.
54+
([#2074](https://github.com/nix-rust/nix/pull/2074))
55+
5256
## [0.27.1] - 2023-08-28
5357

5458
### Fixed

src/sys/socket/mod.rs

+52-14
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ use libc::{
1818
use std::io::{IoSlice, IoSliceMut};
1919
#[cfg(feature = "net")]
2020
use std::net;
21-
use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, RawFd, OwnedFd};
21+
use std::os::unix::io::{AsFd, AsRawFd, FromRawFd, OwnedFd, RawFd};
2222
use std::{mem, ptr};
2323

2424
#[deny(missing_docs)]
@@ -62,7 +62,11 @@ pub use crate::sys::socket::addr::netlink::NetlinkAddr;
6262
#[cfg(any(target_os = "ios", target_os = "macos"))]
6363
#[cfg(feature = "ioctl")]
6464
pub use crate::sys::socket::addr::sys_control::SysControlAddr;
65-
#[cfg(any(target_os = "android", target_os = "linux", target_os = "macos"))]
65+
#[cfg(any(
66+
target_os = "android",
67+
target_os = "linux",
68+
target_os = "macos"
69+
))]
6670
pub use crate::sys::socket::addr::vsock::VsockAddr;
6771

6872
#[cfg(all(feature = "uio", not(target_os = "redox")))]
@@ -1147,7 +1151,7 @@ pub enum ControlMessage<'a> {
11471151
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
11481152
UdpGsoSegments(&'a u16),
11491153

1150-
/// Configure the sending addressing and interface for v4
1154+
/// Configure the sending addressing and interface for v4.
11511155
///
11521156
/// For further information, please refer to the
11531157
/// [`ip(7)`](https://man7.org/linux/man-pages/man7/ip.7.html) man page.
@@ -1160,7 +1164,7 @@ pub enum ControlMessage<'a> {
11601164
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
11611165
Ipv4PacketInfo(&'a libc::in_pktinfo),
11621166

1163-
/// Configure the sending addressing and interface for v6
1167+
/// Configure the sending addressing and interface for v6.
11641168
///
11651169
/// For further information, please refer to the
11661170
/// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page.
@@ -1185,6 +1189,22 @@ pub enum ControlMessage<'a> {
11851189
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
11861190
Ipv4SendSrcAddr(&'a libc::in_addr),
11871191

1192+
/// Configure the hop limit for v6 multicast traffic.
1193+
///
1194+
/// Set the IPv6 hop limit for this message. The argument is an integer
1195+
/// between 0 and 255. A value of -1 will set the hop limit to the route
1196+
/// default if possible on the interface. Without this cmsg, packets sent
1197+
/// with sendmsg have a hop limit of 1 and will not leave the local network.
1198+
/// For further information, please refer to the
1199+
/// [`ipv6(7)`](https://man7.org/linux/man-pages/man7/ipv6.7.html) man page.
1200+
#[cfg(any(target_os = "linux", target_os = "macos",
1201+
target_os = "freebsd", target_os = "dragonfly",
1202+
target_os = "android", target_os = "ios",
1203+
target_os = "haiku"))]
1204+
#[cfg(feature = "net")]
1205+
#[cfg_attr(docsrs, doc(cfg(feature = "net")))]
1206+
Ipv6HopLimit(&'a libc::c_int),
1207+
11881208
/// SO_RXQ_OVFL indicates that an unsigned 32 bit value
11891209
/// ancilliary msg (cmsg) should be attached to recieved
11901210
/// skbs indicating the number of packets dropped by the
@@ -1298,6 +1318,12 @@ impl<'a> ControlMessage<'a> {
12981318
target_os = "openbsd", target_os = "dragonfly"))]
12991319
#[cfg(feature = "net")]
13001320
ControlMessage::Ipv4SendSrcAddr(addr) => addr as *const _ as *const u8,
1321+
#[cfg(any(target_os = "linux", target_os = "macos",
1322+
target_os = "freebsd", target_os = "dragonfly",
1323+
target_os = "android", target_os = "ios",
1324+
target_os = "haiku"))]
1325+
#[cfg(feature = "net")]
1326+
ControlMessage::Ipv6HopLimit(limit) => limit as *const _ as *const u8,
13011327
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13021328
ControlMessage::RxqOvfl(drop_count) => {
13031329
drop_count as *const _ as *const u8
@@ -1361,6 +1387,14 @@ impl<'a> ControlMessage<'a> {
13611387
target_os = "openbsd", target_os = "dragonfly"))]
13621388
#[cfg(feature = "net")]
13631389
ControlMessage::Ipv4SendSrcAddr(addr) => mem::size_of_val(addr),
1390+
#[cfg(any(target_os = "linux", target_os = "macos",
1391+
target_os = "freebsd", target_os = "dragonfly",
1392+
target_os = "android", target_os = "ios",
1393+
target_os = "haiku"))]
1394+
#[cfg(feature = "net")]
1395+
ControlMessage::Ipv6HopLimit(limit) => {
1396+
mem::size_of_val(limit)
1397+
},
13641398
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
13651399
ControlMessage::RxqOvfl(drop_count) => {
13661400
mem::size_of_val(drop_count)
@@ -1400,6 +1434,12 @@ impl<'a> ControlMessage<'a> {
14001434
target_os = "openbsd", target_os = "dragonfly"))]
14011435
#[cfg(feature = "net")]
14021436
ControlMessage::Ipv4SendSrcAddr(_) => libc::IPPROTO_IP,
1437+
#[cfg(any(target_os = "linux", target_os = "macos",
1438+
target_os = "freebsd", target_os = "dragonfly",
1439+
target_os = "android", target_os = "ios",
1440+
target_os = "haiku"))]
1441+
#[cfg(feature = "net")]
1442+
ControlMessage::Ipv6HopLimit(_) => libc::IPPROTO_IPV6,
14031443
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
14041444
ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET,
14051445
#[cfg(target_os = "linux")]
@@ -1446,6 +1486,12 @@ impl<'a> ControlMessage<'a> {
14461486
target_os = "openbsd", target_os = "dragonfly"))]
14471487
#[cfg(feature = "net")]
14481488
ControlMessage::Ipv4SendSrcAddr(_) => libc::IP_SENDSRCADDR,
1489+
#[cfg(any(target_os = "linux", target_os = "macos",
1490+
target_os = "freebsd", target_os = "dragonfly",
1491+
target_os = "android", target_os = "ios",
1492+
target_os = "haiku"))]
1493+
#[cfg(feature = "net")]
1494+
ControlMessage::Ipv6HopLimit(_) => libc::IPV6_HOPLIMIT,
14491495
#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
14501496
ControlMessage::RxqOvfl(_) => {
14511497
libc::SO_RXQ_OVFL
@@ -2186,9 +2232,7 @@ pub fn socketpair<T: Into<Option<SockProtocol>>>(
21862232
Errno::result(res)?;
21872233

21882234
// Safe because socketpair returned success.
2189-
unsafe {
2190-
Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1])))
2191-
}
2235+
unsafe { Ok((OwnedFd::from_raw_fd(fds[0]), OwnedFd::from_raw_fd(fds[1]))) }
21922236
}
21932237

21942238
/// Listen for connections on a socket
@@ -2296,13 +2340,7 @@ pub fn recvfrom<T: SockaddrLike>(
22962340
&mut len as *mut socklen_t,
22972341
))? as usize;
22982342

2299-
Ok((
2300-
ret,
2301-
T::from_raw(
2302-
addr.assume_init().as_ptr(),
2303-
Some(len),
2304-
),
2305-
))
2343+
Ok((ret, T::from_raw(addr.assume_init().as_ptr(), Some(len))))
23062344
}
23072345
}
23082346

0 commit comments

Comments
 (0)