summaryrefslogtreecommitdiff
path: root/test/sys/test_socket.rs
diff options
context:
space:
mode:
authorbors[bot] <26634292+bors[bot]@users.noreply.github.com>2021-04-08 03:53:56 +0000
committerGitHub <noreply@github.com>2021-04-08 03:53:56 +0000
commit68d01f0426a82b485b22c31425c0e53b5c372a7d (patch)
tree9417e3a215db1f947ec15363e935dbd4f487056f /test/sys/test_socket.rs
parent2cef18bcf1dffe1662c62424543a348ddbd839ea (diff)
parent830bab64a8615642ea7de69952b5ae122a124285 (diff)
downloadnix-68d01f0426a82b485b22c31425c0e53b5c372a7d.zip
Merge #1402
1402: Support TIMESTAMPNS r=asomers a=WiSaGaN This adds support of linux TIMESTAMPNS. The code is mostly copied paste from https://github.com/nix-rust/nix/pull/663 Co-authored-by: Lu, Wangshan <wisagan@gmail.com>
Diffstat (limited to 'test/sys/test_socket.rs')
-rw-r--r--test/sys/test_socket.rs108
1 files changed, 108 insertions, 0 deletions
diff --git a/test/sys/test_socket.rs b/test/sys/test_socket.rs
index 43f9b5a3..32318ef0 100644
--- a/test/sys/test_socket.rs
+++ b/test/sys/test_socket.rs
@@ -1546,3 +1546,111 @@ pub fn test_vsock() {
close(s1).unwrap();
thr.join().unwrap();
}
+
+// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack of QEMU
+// support is suspected.
+#[cfg_attr(not(any(target_arch = "x86_64")), ignore)]
+#[cfg(all(target_os = "linux"))]
+#[test]
+fn test_recvmsg_timestampns() {
+ use nix::sys::socket::*;
+ use nix::sys::uio::IoVec;
+ use nix::sys::time::*;
+ use std::time::*;
+
+ // Set up
+ let message = "Ohayō!".as_bytes();
+ let in_socket = socket(
+ AddressFamily::Inet,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None).unwrap();
+ setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap();
+ let localhost = InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0);
+ bind(in_socket, &SockAddr::new_inet(localhost)).unwrap();
+ let address = getsockname(in_socket).unwrap();
+ // Get initial time
+ let time0 = SystemTime::now();
+ // Send the message
+ let iov = [IoVec::from_slice(message)];
+ let flags = MsgFlags::empty();
+ let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
+ assert_eq!(message.len(), l);
+ // Receive the message
+ let mut buffer = vec![0u8; message.len()];
+ let mut cmsgspace = nix::cmsg_space!(TimeSpec);
+ let iov = [IoVec::from_mut_slice(&mut buffer)];
+ let r = recvmsg(in_socket, &iov, Some(&mut cmsgspace), flags).unwrap();
+ let rtime = match r.cmsgs().next() {
+ Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
+ Some(_) => panic!("Unexpected control message"),
+ None => panic!("No control message")
+ };
+ // Check the final time
+ let time1 = SystemTime::now();
+ // the packet's received timestamp should lie in-between the two system
+ // times, unless the system clock was adjusted in the meantime.
+ let rduration = Duration::new(rtime.tv_sec() as u64,
+ rtime.tv_nsec() as u32);
+ assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
+ assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
+ // Close socket
+ nix::unistd::close(in_socket).unwrap();
+}
+
+// Disable the test on emulated platforms because it fails in Cirrus-CI. Lack of QEMU
+// support is suspected.
+#[cfg_attr(not(any(target_arch = "x86_64")), ignore)]
+#[cfg(all(target_os = "linux"))]
+#[test]
+fn test_recvmmsg_timestampns() {
+ use nix::sys::socket::*;
+ use nix::sys::uio::IoVec;
+ use nix::sys::time::*;
+ use std::time::*;
+
+ // Set up
+ let message = "Ohayō!".as_bytes();
+ let in_socket = socket(
+ AddressFamily::Inet,
+ SockType::Datagram,
+ SockFlag::empty(),
+ None).unwrap();
+ setsockopt(in_socket, sockopt::ReceiveTimestampns, &true).unwrap();
+ let localhost = InetAddr::new(IpAddr::new_v4(127, 0, 0, 1), 0);
+ bind(in_socket, &SockAddr::new_inet(localhost)).unwrap();
+ let address = getsockname(in_socket).unwrap();
+ // Get initial time
+ let time0 = SystemTime::now();
+ // Send the message
+ let iov = [IoVec::from_slice(message)];
+ let flags = MsgFlags::empty();
+ let l = sendmsg(in_socket, &iov, &[], flags, Some(&address)).unwrap();
+ assert_eq!(message.len(), l);
+ // Receive the message
+ let mut buffer = vec![0u8; message.len()];
+ let mut cmsgspace = nix::cmsg_space!(TimeSpec);
+ let iov = [IoVec::from_mut_slice(&mut buffer)];
+ let mut data = vec![
+ RecvMmsgData {
+ iov,
+ cmsg_buffer: Some(&mut cmsgspace),
+ },
+ ];
+ let r = recvmmsg(in_socket, &mut data, flags, None).unwrap();
+ let rtime = match r[0].cmsgs().next() {
+ Some(ControlMessageOwned::ScmTimestampns(rtime)) => rtime,
+ Some(_) => panic!("Unexpected control message"),
+ None => panic!("No control message")
+ };
+ // Check the final time
+ let time1 = SystemTime::now();
+ // the packet's received timestamp should lie in-between the two system
+ // times, unless the system clock was adjusted in the meantime.
+ let rduration = Duration::new(rtime.tv_sec() as u64,
+ rtime.tv_nsec() as u32);
+ assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
+ assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
+ // Close socket
+ nix::unistd::close(in_socket).unwrap();
+}