From 9aa61ef9758474b886b82999e4dfe8cc9a0b03ac Mon Sep 17 00:00:00 2001 From: Michael Baikov Date: Wed, 29 Sep 2021 11:32:03 +0800 Subject: feat: Add glibc::SOF_TIMESTAMPING_* support --- src/sys/socket/mod.rs | 51 +++++++++++++++++++++++++++++++++++++++++++++++ src/sys/socket/sockopt.rs | 11 +++++++--- 2 files changed, 59 insertions(+), 3 deletions(-) (limited to 'src/sys/socket') diff --git a/src/sys/socket/mod.rs b/src/sys/socket/mod.rs index dcac2818..9df5ed4a 100644 --- a/src/sys/socket/mod.rs +++ b/src/sys/socket/mod.rs @@ -198,6 +198,28 @@ pub enum SockProtocol { NetlinkCrypto = libc::NETLINK_CRYPTO, } +#[cfg(any(target_os = "linux"))] +libc_bitflags! { + /// Configuration flags for `SO_TIMESTAMPING` interface + /// + /// For use with [`Timestamping`][sockopt::Timestamping]. + /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) + pub struct TimestampingFlag: c_uint { + /// Report any software timestamps when available. + SOF_TIMESTAMPING_SOFTWARE; + /// Report hardware timestamps as generated by SOF_TIMESTAMPING_TX_HARDWARE when available. + SOF_TIMESTAMPING_RAW_HARDWARE; + /// Collect transmiting timestamps as reported by hardware + SOF_TIMESTAMPING_TX_HARDWARE; + /// Collect transmiting timestamps as reported by software + SOF_TIMESTAMPING_TX_SOFTWARE; + /// Collect receiving timestamps as reported by hardware + SOF_TIMESTAMPING_RX_HARDWARE; + /// Collect receiving timestamps as reported by software + SOF_TIMESTAMPING_RX_SOFTWARE; + } +} + libc_bitflags!{ /// Additional socket options pub struct SockFlag: c_int { @@ -641,6 +663,11 @@ 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(Timestamps), /// Nanoseconds resolution timestamp /// /// [Further reading](https://www.kernel.org/doc/html/latest/networking/timestamping.html) @@ -732,6 +759,18 @@ pub enum ControlMessageOwned { Unknown(UnknownCmsg), } +/// For representing packet timestamps via `SO_TIMESTAMPING` interface +#[cfg(all(target_os = "linux"))] +#[derive(Copy, Clone, Debug, Eq, PartialEq)] +pub struct Timestamps { + /// software based timestamp, usually one containing data + pub system: TimeSpec, + /// legacy timestamp, usually empty + pub hw_trans: TimeSpec, + /// hardware based timestamp + pub hw_raw: TimeSpec, +} + impl ControlMessageOwned { /// Decodes a `ControlMessageOwned` from raw bytes. /// @@ -776,6 +815,18 @@ 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 tp = p as *const libc::timespec; + let ts: libc::timespec = ptr::read_unaligned(tp); + let system = TimeSpec::from(ts); + let ts: libc::timespec = ptr::read_unaligned(tp.add(1)); + let hw_trans = TimeSpec::from(ts); + let ts: libc::timespec = ptr::read_unaligned(tp.add(2)); + let hw_raw = TimeSpec::from(ts); + let timestamping = Timestamps { 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 3ad139ad..056ded42 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"))] #[cfg(feature = "net")] const TCP_CA_NAME_MAX: usize = 16; @@ -465,7 +465,12 @@ 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) + Timestamping, Both, libc::SOL_SOCKET, libc::SO_TIMESTAMPING, super::TimestampingFlag); +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"))] @@ -502,7 +507,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"))] #[cfg(feature = "net")] sockopt_impl!( #[cfg_attr(docsrs, doc(cfg(feature = "net")))] -- cgit v1.2.3