Skip to content

Commit

Permalink
Implemented a comprehensive socket API.
Browse files Browse the repository at this point in the history
  • Loading branch information
davidv1992 committed Sep 29, 2023
1 parent 459cd7d commit 87e917b
Show file tree
Hide file tree
Showing 9 changed files with 1,416 additions and 736 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ jobs:
# os: [ubuntu-latest, macos-latest]
os: [ubuntu-latest]
rust:
- 1.65.0
- 1.66.0
target:
- ""
features:
Expand Down
6 changes: 3 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,18 @@
name = "timestamped-socket"
version = "0.1.0"
edition = "2021"
rust-version = "1.66"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
libc = "0.2.145"
tokio = { version = "1.29.1", features = ["net", "time"] }
tracing = { version = "0.1.37", default-features = false, features = ["std"] }
clock-steering = { git = "https://github.com/pendulum-project/clock-steering.git", rev = "3ab6721" }
tracing = { version = "0.1.37", default-features = false, features = ["std", "log"] }
serde = { version = "1.0.145", features = ["derive"], optional = true }

[dev-dependencies]
tokio = { version = "1.29.1", features = ["full"] }
tokio = { version = "1.29.1", features = ["rt", "macros"] }

[features]
default = ["std", "serde"]
Expand Down
46 changes: 31 additions & 15 deletions src/control_message.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
use std::marker::PhantomData;

use crate::timestamped_udp_socket::LibcTimestamp;
use crate::socket::Timestamp;

pub const fn control_message_space<T>() -> usize {
pub(crate) const fn control_message_space<T>() -> usize {
// Safety: CMSG_SPACE is safe to call
(unsafe { libc::CMSG_SPACE((std::mem::size_of::<T>()) as _) }) as usize
}

pub enum MessageQueue {
pub(crate) enum MessageQueue {
Normal,
Error,
}

// these invariants and that the fields of ControlMessageIterator
// are not modified outside these two functions.
pub struct ControlMessageIterator<'a> {
pub(crate) struct ControlMessageIterator<'a> {
mhdr: libc::msghdr,
next_msg: *const libc::cmsghdr,
phantom: PhantomData<&'a [u8]>,
Expand Down Expand Up @@ -46,8 +46,11 @@ impl<'a> ControlMessageIterator<'a> {
}
}

pub enum ControlMessage {
Timestamping(LibcTimestamp),
pub(crate) enum ControlMessage {
Timestamping {
software: Option<Timestamp>,
hardware: Option<Timestamp>,
},
ReceiveError(libc::sock_extended_err),
Other(libc::cmsghdr),
}
Expand Down Expand Up @@ -88,14 +91,21 @@ impl<'a> Iterator for ControlMessageIterator<'a> {

let [software, _, hardware] = unsafe { std::ptr::read_unaligned(cmsg_data) };

// if defined, we prefer the hardware over the software timestamp
let timespec = if hardware.tv_sec != 0 && hardware.tv_nsec != 0 {
hardware
// Both 0 indicates it is not present
let hardware = if hardware.tv_sec != 0 || hardware.tv_nsec != 0 {
Some(Timestamp::from_timespec(hardware))
} else {
software
None
};

ControlMessage::Timestamping(LibcTimestamp::from_timespec(timespec))
// Both 0 indicates it is not present
let software = if software.tv_sec != 0 || software.tv_nsec != 0 {
Some(Timestamp::from_timespec(software))
} else {
None
};

ControlMessage::Timestamping { software, hardware }
}

#[cfg(any(target_os = "linux", target_os = "freebsd"))]
Expand All @@ -107,7 +117,10 @@ impl<'a> Iterator for ControlMessageIterator<'a> {

let timespec = unsafe { std::ptr::read_unaligned(cmsg_data) };

ControlMessage::Timestamping(LibcTimestamp::from_timespec(timespec))
ControlMessage::Timestamping {
software: Some(Timestamp::from_timespec(timespec)),
hardware: None,
}
}

(libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => {
Expand All @@ -116,7 +129,10 @@ impl<'a> Iterator for ControlMessageIterator<'a> {
// SO_TIMESTAMP always has a timeval in the data
let cmsg_data = unsafe { libc::CMSG_DATA(current_msg) } as *const libc::timeval;
let timeval = unsafe { std::ptr::read_unaligned(cmsg_data) };
ControlMessage::Timestamping(LibcTimestamp::from_timeval(timeval))
ControlMessage::Timestamping {
software: Some(Timestamp::from_timeval(timeval)),
hardware: None,
}
}

#[cfg(target_os = "linux")]
Expand All @@ -138,15 +154,15 @@ impl<'a> Iterator for ControlMessageIterator<'a> {
}
}

pub fn zeroed_sockaddr_storage() -> libc::sockaddr_storage {
pub(crate) fn zeroed_sockaddr_storage() -> libc::sockaddr_storage {
// a zeroed-out sockaddr storage is semantically valid, because a ss_family with
// value 0 is libc::AF_UNSPEC. Hence the rest of the data does not come with
// any constraints Safety:
// the MaybeUninit is zeroed before assumed to be initialized
unsafe { std::mem::MaybeUninit::zeroed().assume_init() }
}

pub fn empty_msghdr() -> libc::msghdr {
pub(crate) fn empty_msghdr() -> libc::msghdr {
// On `target_env = "musl"`, there are several private padding fields.
// the position of these padding fields depends on the system endianness,
// so keeping making them public does not really help.
Expand Down
5 changes: 3 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
mod control_message;
pub mod interface;
pub mod raw_udp_socket;
pub mod timestamped_udp_socket;
pub mod networkaddress;
mod raw_socket;
pub mod socket;

/// Turn a C failure (-1 is returned) into a rust Result
pub(crate) fn cerr(t: libc::c_int) -> std::io::Result<libc::c_int> {
Expand Down
Loading

0 comments on commit 87e917b

Please sign in to comment.