-
Notifications
You must be signed in to change notification settings - Fork 228
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added options to support socket timestamping #504
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -23,6 +23,11 @@ use std::time::Duration; | |
use crate::sys::{self, c_int, getsockopt, setsockopt, Bool}; | ||
#[cfg(all(unix, not(target_os = "redox")))] | ||
use crate::MsgHdrMut; | ||
#[cfg(all( | ||
feature = "all", | ||
any(target_os = "linux", target_os = "android", target_os = "windows") | ||
))] | ||
use crate::TimestampingFlags; | ||
use crate::{Domain, Protocol, SockAddr, TcpKeepalive, Type}; | ||
#[cfg(not(target_os = "redox"))] | ||
use crate::{MaybeUninitSlice, MsgHdr, RecvFlags}; | ||
|
@@ -1109,6 +1114,141 @@ impl Socket { | |
pub fn set_write_timeout(&self, duration: Option<Duration>) -> io::Result<()> { | ||
sys::set_timeout_opt(self.as_raw(), sys::SOL_SOCKET, sys::SO_SNDTIMEO, duration) | ||
} | ||
|
||
/// Get value for `SO_TIMESTAMP` option on this socket. | ||
/// | ||
/// For more information about this option, see [`set_timestamp`]. | ||
/// | ||
/// [`set_timestamp`]: Socket::set_timestamp | ||
#[cfg(not(any(target_os = "redox", target_os = "hurd", target_os = "windows")))] | ||
#[cfg_attr( | ||
docsrs, | ||
doc(cfg(not(any(target_os = "redox", target_os = "hurd", target_os = "windows")))) | ||
)] | ||
pub fn timestamp(&self) -> io::Result<bool> { | ||
unsafe { | ||
getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_TIMESTAMP) | ||
.map(|active| active != 0) | ||
} | ||
} | ||
|
||
/// Set value for the `SO_TIMESTAMP` option on this socket. | ||
/// | ||
/// This indicates that timestamps should be generated for each incoming | ||
/// packet in system time. The timestamp is reported via `recvmsg`. The | ||
/// timestamp is represented by a `timeval`. | ||
/// | ||
/// Additional documentation can be found in documentation of the OS. | ||
/// * Linux: <https://docs.kernel.org/networking/timestamping.html> | ||
#[cfg(all( | ||
feature = "all", | ||
not(any(target_os = "redox", target_os = "hurd", target_os = "windows")) | ||
))] | ||
#[cfg_attr( | ||
docsrs, | ||
doc(cfg(all( | ||
feature = "all", | ||
not(any(target_os = "redox", target_os = "hurd", target_os = "windows")) | ||
))) | ||
)] | ||
pub fn set_timestamp(&self, active: bool) -> io::Result<()> { | ||
unsafe { | ||
setsockopt( | ||
self.as_raw(), | ||
sys::SOL_SOCKET, | ||
sys::SO_TIMESTAMP, | ||
active as c_int, | ||
) | ||
} | ||
} | ||
|
||
/// Get value for `SO_TIMESTAMPNS` option on this socket. | ||
/// | ||
/// For more information about this option, see [`set_timestamp_ns`]. | ||
/// | ||
/// [`set_timestamp_ns`]: Socket::set_timestamp_ns | ||
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "android")))] | ||
#[cfg_attr( | ||
docsrs, | ||
doc(cfg(all(feature = "all", any(target_os = "linux", target_os = "android")))) | ||
)] | ||
pub fn timestamp_ns(&self) -> io::Result<bool> { | ||
unsafe { | ||
getsockopt::<c_int>(self.as_raw(), sys::SOL_SOCKET, sys::SO_TIMESTAMPNS) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Is there any value in having both There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure if I understand what you are proposing here. This API should not allow the user to set timestamps or some duration. The timestamping API allows the user to receive query timestamps for when packets were send or received (depending on the flags). With |
||
.map(|active| active != 0) | ||
} | ||
} | ||
|
||
/// Set value for the `SO_TIMESTAMPNS` option on this socket. | ||
/// | ||
/// This indicates that timestamps should be generated for each incoming | ||
/// packet in system time. The timestamp is reported via `recvmsg`. The | ||
/// timestamp is represented by a `timespec` with nsec resolution. | ||
/// | ||
/// Additional documentation can be found in documentation of the OS. | ||
/// * Linux: <https://docs.kernel.org/networking/timestamping.html> | ||
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "android")))] | ||
#[cfg_attr( | ||
docsrs, | ||
doc(cfg(all(feature = "all", any(target_os = "linux", target_os = "android")))) | ||
)] | ||
pub fn set_timestamp_ns(&self, active: bool) -> io::Result<()> { | ||
unsafe { | ||
setsockopt( | ||
self.as_raw(), | ||
sys::SOL_SOCKET, | ||
sys::SO_TIMESTAMPNS, | ||
active as c_int, | ||
) | ||
} | ||
} | ||
|
||
/// On Unix this gets the value for the `SO_TIMESTAMPING` options and on | ||
/// Windows this gets the value for the `SOI_TIMESTAMPING` option on this | ||
/// socket. | ||
/// | ||
/// For more information about this option, see [`set_timestamping`]. | ||
/// | ||
/// [`set_timestamping`]: Socket::set_timestamping | ||
#[cfg(all(feature = "all", any(target_os = "linux", target_os = "android")))] | ||
#[cfg_attr( | ||
docsrs, | ||
doc(cfg(all(feature = "all", any(target_os = "linux", target_os = "android")))) | ||
)] | ||
pub fn timestamping(&self) -> io::Result<TimestampingFlags> { | ||
unsafe { | ||
getsockopt::<sys::c_uint>(self.as_raw(), sys::SOL_SOCKET, sys::SO_TIMESTAMPING) | ||
.map(TimestampingFlags) | ||
} | ||
} | ||
|
||
/// On Unix this sets the value for the `SO_TIMESTAMPING` options and on | ||
/// Windows this sets the value for the `SOI_TIMESTAMPING` option on this | ||
/// socket. | ||
/// | ||
/// With this timestamps can be configured to be generated on reception, | ||
/// transmission or both. It supports hardware and software sources for | ||
/// timestamp generation and it also allows generating timestamps for | ||
/// stream sockets. The configuration depends on the flags that are set on | ||
/// the input parameter of type [`TimestampingFlags`]. | ||
/// | ||
/// Additional documentation can be found in documentation of the OS. | ||
/// * Linux: <https://docs.kernel.org/networking/timestamping.html> | ||
/// * Windows: <https://learn.microsoft.com/en-us/windows/win32/winsock/winsock-timestamping> | ||
#[cfg(all( | ||
feature = "all", | ||
any(target_os = "linux", target_os = "android", target_os = "windows") | ||
))] | ||
#[cfg_attr( | ||
docsrs, | ||
doc(cfg(all( | ||
feature = "all", | ||
any(target_os = "linux", target_os = "android", target_os = "windows") | ||
))) | ||
)] | ||
pub fn set_timestamping(&self, flags: TimestampingFlags) -> io::Result<()> { | ||
sys::set_timestamping_opt(self.as_raw(), flags) | ||
} | ||
} | ||
|
||
const fn from_linger(linger: sys::linger) -> Option<Duration> { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since these lists are so long, can we make it "opt-in" instead of excluding basically everything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Also, since it's not available on all OS, we need to use the
all
feature.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you are right. I will change that to reduce the overall noise in the code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In 08e843b I changed the
cfg
attributes to be opt-in. Thanks for this remark, its so much cleaner now.