Skip to content

Commit 3a75bfa

Browse files
committed
Add support for SO_TIMESTAMP
1 parent 46e77b5 commit 3a75bfa

File tree

3 files changed

+31
-0
lines changed

3 files changed

+31
-0
lines changed

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 = SO_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 = SO_TIMESTAMP;
238240
}
239241

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

src/sys/socket/mod.rs

Lines changed: 28 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,7 @@ 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+
ScmTimestamp(&'a TimeVal),
185191
#[doc(hidden)]
186192
Unknown(UnknownCmsg<'a>),
187193
}
@@ -207,6 +213,9 @@ impl<'a> ControlMessage<'a> {
207213
ControlMessage::ScmRights(fds) => {
208214
mem::size_of_val(fds)
209215
},
216+
ControlMessage::ScmTimestamp(t) => {
217+
mem::size_of_val(t)
218+
},
210219
ControlMessage::Unknown(UnknownCmsg(_, bytes)) => {
211220
mem::size_of_val(bytes)
212221
}
@@ -237,6 +246,25 @@ impl<'a> ControlMessage<'a> {
237246

238247
copy_bytes(fds, buf);
239248
},
249+
ControlMessage::ScmTimestamp(t) => {
250+
let cmsg = cmsghdr {
251+
cmsg_len: self.len() as type_of_cmsg_len,
252+
cmsg_level: SOL_SOCKET,
253+
cmsg_type: SCM_TIMESTAMP,
254+
cmsg_data: [],
255+
};
256+
copy_bytes(&cmsg, buf);
257+
258+
let padlen = cmsg_align(mem::size_of_val(&cmsg)) -
259+
mem::size_of_val(&cmsg);
260+
261+
let mut tmpbuf = &mut [][..];
262+
mem::swap(&mut tmpbuf, buf);
263+
let (_padding, mut remainder) = tmpbuf.split_at_mut(padlen);
264+
mem::swap(buf, &mut remainder);
265+
266+
copy_bytes(t, buf);
267+
},
240268
ControlMessage::Unknown(UnknownCmsg(orig_cmsg, bytes)) => {
241269
copy_bytes(orig_cmsg, buf);
242270
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)