Skip to content

Commit 3c1811a

Browse files
committed
Add support for SO_TIMESTAMP
1 parent e08a430 commit 3c1811a

File tree

3 files changed

+39
-0
lines changed

3 files changed

+39
-0
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ This project adheres to [Semantic Versioning](http://semver.org/).
55

66
## [Unreleased]
77

8+
### Added
9+
- Added `nix::sys::socket::ControlMessage::ScmTimestamp`
10+
([#663](https://github.com/nix-rust/nix/pull/663))
11+
812
### Changed
913
- Renamed existing `ptrace` wrappers to encourage namespacing ([#692](https://github.com/nix-rust/nix/pull/692))
1014

src/sys/socket/mod.rs

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@ 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;
13+
use libc;
1214

1315
mod addr;
1416
mod consts;
@@ -162,6 +164,10 @@ impl<'a> Iterator for CmsgIterator<'a> {
162164
slice::from_raw_parts(
163165
&cmsg.cmsg_data as *const _ as *const _, 1)))
164166
},
167+
(libc::SOL_SOCKET, libc::SCM_TIMESTAMP) => unsafe {
168+
Some(ControlMessage::ScmTimestamp(
169+
&*(&cmsg.cmsg_data as *const _ as *const _)))
170+
},
165171
(_, _) => unsafe {
166172
Some(ControlMessage::Unknown(UnknownCmsg(
167173
&cmsg,
@@ -182,6 +188,11 @@ pub enum ControlMessage<'a> {
182188
/// "Ancillary messages" section of the
183189
/// [unix(7) man page](http://man7.org/linux/man-pages/man7/unix.7.html).
184190
ScmRights(&'a [RawFd]),
191+
/// A message of type SCM_TIMESTAMP, containing the time the packet
192+
/// was received by the kernel. See the kernel's explanation in
193+
/// "SO_TIMESTAMP" of
194+
/// [networking/timestamping](https://www.kernel.org/doc/Documentation/networking/timestamping.txt).
195+
ScmTimestamp(&'a TimeVal),
185196
#[doc(hidden)]
186197
Unknown(UnknownCmsg<'a>),
187198
}
@@ -207,6 +218,9 @@ impl<'a> ControlMessage<'a> {
207218
ControlMessage::ScmRights(fds) => {
208219
mem::size_of_val(fds)
209220
},
221+
ControlMessage::ScmTimestamp(t) => {
222+
mem::size_of_val(t)
223+
},
210224
ControlMessage::Unknown(UnknownCmsg(_, bytes)) => {
211225
mem::size_of_val(bytes)
212226
}
@@ -237,6 +251,25 @@ impl<'a> ControlMessage<'a> {
237251

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

src/sys/socket/sockopt.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use super::{ffi, consts, GetSockOpt, SetSockOpt};
2+
use libc;
23
use {Errno, Result};
34
use sys::time::TimeVal;
45
use libc::{c_int, uint8_t, c_void, socklen_t};
@@ -176,6 +177,7 @@ sockopt_impl!(GetOnly, SockType, consts::SOL_SOCKET, consts::SO_TYPE, super::Soc
176177
sockopt_impl!(GetOnly, AcceptConn, consts::SOL_SOCKET, consts::SO_ACCEPTCONN, bool);
177178
#[cfg(target_os = "linux")]
178179
sockopt_impl!(GetOnly, OriginalDst, consts::SOL_IP, consts::SO_ORIGINAL_DST, sockaddr_in);
180+
sockopt_impl!(Both, ReceiveTimestamp, libc::SOL_SOCKET, libc::SO_TIMESTAMP, bool);
179181

180182
/*
181183
*

0 commit comments

Comments
 (0)