summaryrefslogtreecommitdiff
path: root/src/sys
diff options
context:
space:
mode:
authorJunho Choi <junho@cloudflare.com>2021-06-18 17:39:36 -0700
committerJunho Choi <junho.choi@gmail.com>2021-07-08 16:00:39 -0700
commit0b596a11e08df529d874cfb2ecb461936fda7118 (patch)
tree6a61441bdfd274c6ec10e62091b3fdc83ca43534 /src/sys
parentd9d447db42a16d7f946177e093b5990fba52561e (diff)
downloadnix-0b596a11e08df529d874cfb2ecb461936fda7118.zip
Support SO_RXQ_OVFL socket option (android/fuchsia/linux)
This PR implements support of RXQ_OVFL flag and parsing ControlMessage to get the packet drop counter of UDP socket.
Diffstat (limited to 'src/sys')
-rw-r--r--src/sys/socket/mod.rs38
-rw-r--r--src/sys/socket/sockopt.rs2
2 files changed, 40 insertions, 0 deletions
diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs
index c222bdd7..da5573c4 100644
--- a/src/sys/socket/mod.rs
+++ b/src/sys/socket/mod.rs
@@ -610,6 +610,17 @@ pub enum ControlMessageOwned {
#[cfg(target_os = "linux")]
UdpGroSegments(u16),
+ /// SO_RXQ_OVFL indicates that an unsigned 32 bit value
+ /// ancilliary msg (cmsg) should be attached to recieved
+ /// skbs indicating the number of packets dropped by the
+ /// socket between the last recieved packet and this
+ /// received packet.
+ ///
+ /// `RxqOvfl` socket option should be enabled on a socket
+ /// to allow receiving the drop counter.
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ RxqOvfl(u32),
+
/// Catch-all variant for unimplemented cmsg types.
#[doc(hidden)]
Unknown(UnknownCmsg),
@@ -708,6 +719,11 @@ impl ControlMessageOwned {
let gso_size: u16 = ptr::read_unaligned(p as *const _);
ControlMessageOwned::UdpGroSegments(gso_size)
},
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ (libc::SOL_SOCKET, libc::SO_RXQ_OVFL) => {
+ let drop_counter = ptr::read_unaligned(p as *const u32);
+ ControlMessageOwned::RxqOvfl(drop_counter)
+ },
(_, _) => {
let sl = slice::from_raw_parts(p, len);
let ucmsg = UnknownCmsg(*header, Vec::<u8>::from(sl));
@@ -826,6 +842,14 @@ pub enum ControlMessage<'a> {
target_os = "android",
target_os = "ios",))]
Ipv6PacketInfo(&'a libc::in6_pktinfo),
+
+ /// SO_RXQ_OVFL indicates that an unsigned 32 bit value
+ /// ancilliary msg (cmsg) should be attached to recieved
+ /// skbs indicating the number of packets dropped by the
+ /// socket between the last recieved packet and this
+ /// received packet.
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ RxqOvfl(&'a u32),
}
// An opaque structure used to prevent cmsghdr from being a public type
@@ -916,6 +940,10 @@ impl<'a> ControlMessage<'a> {
target_os = "netbsd", target_os = "freebsd",
target_os = "android", target_os = "ios",))]
ControlMessage::Ipv6PacketInfo(info) => info as *const _ as *const u8,
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ ControlMessage::RxqOvfl(drop_count) => {
+ drop_count as *const _ as *const u8
+ },
};
unsafe {
ptr::copy_nonoverlapping(
@@ -964,6 +992,10 @@ impl<'a> ControlMessage<'a> {
target_os = "netbsd", target_os = "freebsd",
target_os = "android", target_os = "ios",))]
ControlMessage::Ipv6PacketInfo(info) => mem::size_of_val(info),
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ ControlMessage::RxqOvfl(drop_count) => {
+ mem::size_of_val(drop_count)
+ },
}
}
@@ -988,6 +1020,8 @@ impl<'a> ControlMessage<'a> {
target_os = "netbsd", target_os = "freebsd",
target_os = "android", target_os = "ios",))]
ControlMessage::Ipv6PacketInfo(_) => libc::IPPROTO_IPV6,
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ ControlMessage::RxqOvfl(_) => libc::SOL_SOCKET,
}
}
@@ -1023,6 +1057,10 @@ impl<'a> ControlMessage<'a> {
target_os = "netbsd", target_os = "freebsd",
target_os = "android", target_os = "ios",))]
ControlMessage::Ipv6PacketInfo(_) => libc::IPV6_PKTINFO,
+ #[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+ ControlMessage::RxqOvfl(_) => {
+ libc::SO_RXQ_OVFL
+ },
}
}
diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs
index 3397a966..e2f2cafe 100644
--- a/src/sys/socket/sockopt.rs
+++ b/src/sys/socket/sockopt.rs
@@ -328,6 +328,8 @@ sockopt_impl!(Both, Ipv4RecvDstAddr, libc::IPPROTO_IP, libc::IP_RECVDSTADDR, boo
sockopt_impl!(Both, UdpGsoSegment, libc::SOL_UDP, libc::UDP_SEGMENT, libc::c_int);
#[cfg(target_os = "linux")]
sockopt_impl!(Both, UdpGroSegment, libc::IPPROTO_UDP, libc::UDP_GRO, bool);
+#[cfg(any(target_os = "android", target_os = "fuchsia", target_os = "linux"))]
+sockopt_impl!(Both, RxqOvfl, libc::SOL_SOCKET, libc::SO_RXQ_OVFL, libc::c_int);
#[cfg(any(target_os = "android", target_os = "linux"))]
#[derive(Copy, Clone, Debug)]