From b2a14e737395bc74b6024e201b219746653eb13d Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Wed, 29 Sep 2021 11:32:03 +0800 Subject: [PATCH] feat: Add glibc::SOF_TIMESTAMPING_* support --- src/sys/socket/mod.rs | 29 +++++++++++++++++++++++++++++ src/sys/socket/sockopt.rs | 18 +++++++++++++++--- 2 files changed, 44 insertions(+), 3 deletions(-) diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index 97eea3dcb1..f8f9d9b442 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -591,6 +591,14 @@ pub enum ControlMessageOwned { /// # } /// ``` ScmTimestamp(TimeVal), + /// A set of nanosecond resolution timestamps + /// + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + #[cfg(all(target_os = "linux"))] + ScmTimestampsns(Timestamping), + #[cfg(any( + target_os = "linux", + ))] /// Nanoseconds resolution timestamp /// /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) @@ -666,6 +674,14 @@ pub enum ControlMessageOwned { Unknown(UnknownCmsg), } +#[cfg(all(target_os = "linux"))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Timestamping { + pub system: TimeSpec, + pub hw_trans: TimeSpec, + pub hw_raw: TimeSpec, +} + impl ControlMessageOwned { /// Decodes a `ControlMessageOwned` from raw bytes. /// @@ -710,6 +726,19 @@ impl ControlMessageOwned { let ts: libc::timespec = ptr::read_unaligned(p as *const _); ControlMessageOwned::ScmTimestampns(TimeSpec::from(ts)) } + #[cfg(all(target_os = "linux"))] + (libc::SOL_SOCKET, libc::SCM_TIMESTAMPING) => { + let ts: libc::timespec = ptr::read_unaligned(p as *const _); + let system = TimeSpec::from(ts); + let tsp = (p as *const libc::timespec).add(1); + let ts: libc::timespec = ptr::read_unaligned(tsp as *const _); + let hw_trans = TimeSpec::from(ts); + let tsp = (p as *const libc::timespec).add(2); + let ts: libc::timespec = ptr::read_unaligned(tsp as *const _); + let hw_raw = TimeSpec::from(ts); + let timestamping = Timestamping { system, hw_trans, hw_raw }; + ControlMessageOwned::ScmTimestampsns(timestamping) + } #[cfg(any( target_os = "android", target_os = "freebsd", diff --git a/src/sys/socket/sockopt.rs b/src/sys/socket/sockopt.rs index efa43517ef..38c106256e 100644 --- a/src/sys/socket/sockopt.rs +++ b/src/sys/socket/sockopt.rs @@ -16,7 +16,7 @@ use std::os::unix::ffi::OsStrExt; // Constants // TCP_CA_NAME_MAX isn't defined in user space include files -#[cfg(any(target_os = "freebsd", target_os = "linux"))] +#[cfg(any(target_os = "freebsd", target_os = "linux"))] const TCP_CA_NAME_MAX: usize = 16; /// Helper for implementing `SetSockOpt` for a given socket option. See @@ -432,7 +432,19 @@ sockopt_impl!( #[allow(missing_docs)] // Not documented by Linux! Ip6tOriginalDst, GetOnly, libc::SOL_IPV6, libc::IP6T_SO_ORIGINAL_DST, libc::sockaddr_in6); -sockopt_impl!( +#[cfg(any(target_os = "linux"))] +sockopt_impl!( + /// Specifies exact type of timestamping information collected by the kernel + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + /// Takes a bitwise `or` of libc timestamping options: + /// - [SOF_TIMESTAMPING_TX_HARDWARE][::libc::SOF_TIMESTAMPING_TX_HARDWARE]: + /// - [SOF_TIMESTAMPING_TX_SOFTWARE][::libc::SOF_TIMESTAMPING_TX_SOFTWARE]: + /// - [SOF_TIMESTAMPING_RX_HARDWARE][::libc::SOF_TIMESTAMPING_RX_HARDWARE]: + /// - [SOF_TIMESTAMPING_RX_SOFTWARE][::libc::SOF_TIMESTAMPING_RX_SOFTWARE]: + /// - [SOF_TIMESTAMPING_RAW_HARDWARE][::libc::SOF_TIMESTAMPING_RAW_HARDWARE]: + /// - [SOF_TIMESTAMPING_SOFTWARE][::libc::SOF_TIMESTAMPING_SOFTWARE] + Timestamping, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPING, u32); +sockopt_impl!( /// Enable or disable the receiving of the `SO_TIMESTAMP` control message. ReceiveTimestamp, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool); #[cfg(all(target_os = "linux"))] @@ -463,7 +475,7 @@ sockopt_impl!( /// Enable or disable the receiving of the `SCM_CREDENTIALS` control /// message. PassCred, Both, libc::SOL_SOCKET, libc::SO_PASSCRED, bool); -#[cfg(any(target_os = "freebsd", target_os = "linux"))] +#[cfg(any(target_os = "freebsd", target_os = "linux"))] sockopt_impl!( /// This option allows the caller to set the TCP congestion control /// algorithm to be used, on a per-socket basis.