Skip to content

Commit 107d8af

Browse files
committed
Add support for SO_TIMESTAMP
1 parent 46e77b5 commit 107d8af

File tree

4 files changed

+37
-0
lines changed

4 files changed

+37
-0
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ This project adheres to [Semantic Versioning](http://semver.org/).
66
## [Unreleased]
77

88
### Added
9+
- Added `nix::sys::socket::ControlMessage::ScmTimestamp`
10+
([#663](https://github.com/nix-rust/nix/pull/663))
911
- Added `sys::signal::SigAction::{ flags, mask, handler}`
1012
([#611](https://github.com/nix-rust/nix/pull/609)
1113
- Added `nix::sys::pthread::pthread_self`

src/sys/socket/consts.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,7 @@ mod os {
109109

110110
// Ancillary message types
111111
pub const SCM_RIGHTS: c_int = libc::SCM_RIGHTS;
112+
pub const SCM_TIMESTAMP: c_int = libc::SCM_TIMESTAMP;
112113
}
113114

114115
// Not all of these constants exist on freebsd
@@ -235,6 +236,7 @@ mod os {
235236

236237
// Ancillary message types
237238
pub const SCM_RIGHTS: c_int = 1;
239+
pub const SCM_TIMESTAMP: c_int = libc::SCM_TIMESTAMP;
238240
}
239241

240242
#[cfg(target_os = "dragonfly")]

src/sys/socket/mod.rs

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use libc::{c_void, c_int, socklen_t, size_t, pid_t, uid_t, gid_t};
99
use std::{mem, ptr, slice};
1010
use std::os::unix::io::RawFd;
1111
use sys::uio::IoVec;
12+
use sys::time::TimeVal;
1213

1314
mod addr;
1415
mod consts;
@@ -162,6 +163,10 @@ impl<'a> Iterator for CmsgIterator<'a> {
162163
slice::from_raw_parts(
163164
&cmsg.cmsg_data as *const _ as *const _, 1)))
164165
},
166+
(SOL_SOCKET, SCM_TIMESTAMP) => unsafe {
167+
Some(ControlMessage::ScmTimestamp(
168+
&*(&cmsg.cmsg_data as *const _ as *const _)))
169+
},
165170
(_, _) => unsafe {
166171
Some(ControlMessage::Unknown(UnknownCmsg(
167172
&cmsg,
@@ -182,6 +187,11 @@ pub enum ControlMessage<'a> {
182187
/// "Ancillary messages" section of the
183188
/// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
184189
ScmRights(&'a [RawFd]),
190+
/// A message of type SCM_TIMESTAMP, containing the time the packet
191+
/// was received by the kernel. See the kernel's explanation in
192+
/// "SO_TIMESTAMP" of
193+
/// [networking/timestamping](https://www.kernel.org/doc/Documentation/networking/timestamping.txt).
194+
ScmTimestamp(&'a TimeVal),
185195
#[doc(hidden)]
186196
Unknown(UnknownCmsg<'a>),
187197
}
@@ -207,6 +217,9 @@ impl<'a> ControlMessage<'a> {
207217
ControlMessage::ScmRights(fds) => {
208218
mem::size_of_val(fds)
209219
},
220+
ControlMessage::ScmTimestamp(t) => {
221+
mem::size_of_val(t)
222+
},
210223
ControlMessage::Unknown(UnknownCmsg(_, bytes)) => {
211224
mem::size_of_val(bytes)
212225
}
@@ -237,6 +250,25 @@ impl<'a> ControlMessage<'a> {
237250

238251
copy_bytes(fds, buf);
239252
},
253+
ControlMessage::ScmTimestamp(t) => {
254+
let cmsg = cmsghdr {
255+
cmsg_len: self.len() as type_of_cmsg_len,
256+
cmsg_level: SOL_SOCKET,
257+
cmsg_type: SCM_TIMESTAMP,
258+
cmsg_data: [],
259+
};
260+
copy_bytes(&cmsg, buf);
261+
262+
let padlen = cmsg_align(mem::size_of_val(&cmsg)) -
263+
mem::size_of_val(&cmsg);
264+
265+
let mut tmpbuf = &mut [][..];
266+
mem::swap(&mut tmpbuf, buf);
267+
let (_padding, mut remainder) = tmpbuf.split_at_mut(padlen);
268+
mem::swap(buf, &mut remainder);
269+
270+
copy_bytes(t, buf);
271+
},
240272
ControlMessage::Unknown(UnknownCmsg(orig_cmsg, bytes)) => {
241273
copy_bytes(orig_cmsg, buf);
242274
copy_bytes(bytes, buf);

src/sys/socket/sockopt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ sockopt_impl!(GetOnly, SockType, consts::SOL_SOCKET, consts::SO_TYPE, super::Soc
176176
sockopt_impl!(GetOnly, AcceptConn, consts::SOL_SOCKET, consts::SO_ACCEPTCONN, bool);
177177
#[cfg(target_os = "linux")]
178178
sockopt_impl!(GetOnly, OriginalDst, consts::SOL_IP, consts::SO_ORIGINAL_DST, sockaddr_in);
179+
sockopt_impl!(Both, ReceiveTimestamp, consts::SOL_SOCKET, consts::SO_TIMESTAMP, bool);
179180

180181
/*
181182
*

0 commit comments

Comments
 (0)