@@ -1535,3 +1535,111 @@ pub fn test_vsock() {
1535
1535
close ( s1) . unwrap ( ) ;
1536
1536
thr. join ( ) . unwrap ( ) ;
1537
1537
}
1538
+
1539
+ // Disable the test on emulated platforms because it fails in Cirrus-CI. Lack of QEMU
1540
+ // support is suspected.
1541
+ #[ cfg_attr( not( any( target_arch = "x86_64" ) ) , ignore) ]
1542
+ #[ cfg( all( target_os = "linux" ) ) ]
1543
+ #[ test]
1544
+ fn test_recvmsg_timestampns ( ) {
1545
+ use nix:: sys:: socket:: * ;
1546
+ use nix:: sys:: uio:: IoVec ;
1547
+ use nix:: sys:: time:: * ;
1548
+ use std:: time:: * ;
1549
+
1550
+ // Set up
1551
+ let message = "Ohayō!" . as_bytes ( ) ;
1552
+ let in_socket = socket (
1553
+ AddressFamily :: Inet ,
1554
+ SockType :: Datagram ,
1555
+ SockFlag :: empty ( ) ,
1556
+ None ) . unwrap ( ) ;
1557
+ setsockopt ( in_socket, sockopt:: ReceiveTimestampns , & true ) . unwrap ( ) ;
1558
+ let localhost = InetAddr :: new ( IpAddr :: new_v4 ( 127 , 0 , 0 , 1 ) , 0 ) ;
1559
+ bind ( in_socket, & SockAddr :: new_inet ( localhost) ) . unwrap ( ) ;
1560
+ let address = getsockname ( in_socket) . unwrap ( ) ;
1561
+ // Get initial time
1562
+ let time0 = SystemTime :: now ( ) ;
1563
+ // Send the message
1564
+ let iov = [ IoVec :: from_slice ( message) ] ;
1565
+ let flags = MsgFlags :: empty ( ) ;
1566
+ let l = sendmsg ( in_socket, & iov, & [ ] , flags, Some ( & address) ) . unwrap ( ) ;
1567
+ assert_eq ! ( message. len( ) , l) ;
1568
+ // Receive the message
1569
+ let mut buffer = vec ! [ 0u8 ; message. len( ) ] ;
1570
+ let mut cmsgspace = nix:: cmsg_space!( TimeSpec ) ;
1571
+ let iov = [ IoVec :: from_mut_slice ( & mut buffer) ] ;
1572
+ let r = recvmsg ( in_socket, & iov, Some ( & mut cmsgspace) , flags) . unwrap ( ) ;
1573
+ let rtime = match r. cmsgs ( ) . next ( ) {
1574
+ Some ( ControlMessageOwned :: ScmTimestampns ( rtime) ) => rtime,
1575
+ Some ( _) => panic ! ( "Unexpected control message" ) ,
1576
+ None => panic ! ( "No control message" )
1577
+ } ;
1578
+ // Check the final time
1579
+ let time1 = SystemTime :: now ( ) ;
1580
+ // the packet's received timestamp should lie in-between the two system
1581
+ // times, unless the system clock was adjusted in the meantime.
1582
+ let rduration = Duration :: new ( rtime. tv_sec ( ) as u64 ,
1583
+ rtime. tv_nsec ( ) as u32 ) ;
1584
+ assert ! ( time0. duration_since( UNIX_EPOCH ) . unwrap( ) <= rduration) ;
1585
+ assert ! ( rduration <= time1. duration_since( UNIX_EPOCH ) . unwrap( ) ) ;
1586
+ // Close socket
1587
+ nix:: unistd:: close ( in_socket) . unwrap ( ) ;
1588
+ }
1589
+
1590
+ // Disable the test on emulated platforms because it fails in Cirrus-CI. Lack of QEMU
1591
+ // support is suspected.
1592
+ #[ cfg_attr( not( any( target_arch = "x86_64" ) ) , ignore) ]
1593
+ #[ cfg( all( target_os = "linux" ) ) ]
1594
+ #[ test]
1595
+ fn test_recvmmsg_timestampns ( ) {
1596
+ use nix:: sys:: socket:: * ;
1597
+ use nix:: sys:: uio:: IoVec ;
1598
+ use nix:: sys:: time:: * ;
1599
+ use std:: time:: * ;
1600
+
1601
+ // Set up
1602
+ let message = "Ohayō!" . as_bytes ( ) ;
1603
+ let in_socket = socket (
1604
+ AddressFamily :: Inet ,
1605
+ SockType :: Datagram ,
1606
+ SockFlag :: empty ( ) ,
1607
+ None ) . unwrap ( ) ;
1608
+ setsockopt ( in_socket, sockopt:: ReceiveTimestampns , & true ) . unwrap ( ) ;
1609
+ let localhost = InetAddr :: new ( IpAddr :: new_v4 ( 127 , 0 , 0 , 1 ) , 0 ) ;
1610
+ bind ( in_socket, & SockAddr :: new_inet ( localhost) ) . unwrap ( ) ;
1611
+ let address = getsockname ( in_socket) . unwrap ( ) ;
1612
+ // Get initial time
1613
+ let time0 = SystemTime :: now ( ) ;
1614
+ // Send the message
1615
+ let iov = [ IoVec :: from_slice ( message) ] ;
1616
+ let flags = MsgFlags :: empty ( ) ;
1617
+ let l = sendmsg ( in_socket, & iov, & [ ] , flags, Some ( & address) ) . unwrap ( ) ;
1618
+ assert_eq ! ( message. len( ) , l) ;
1619
+ // Receive the message
1620
+ let mut buffer = vec ! [ 0u8 ; message. len( ) ] ;
1621
+ let mut cmsgspace = nix:: cmsg_space!( TimeSpec ) ;
1622
+ let iov = [ IoVec :: from_mut_slice ( & mut buffer) ] ;
1623
+ let mut data = vec ! [
1624
+ RecvMmsgData {
1625
+ iov,
1626
+ cmsg_buffer: Some ( & mut cmsgspace) ,
1627
+ } ,
1628
+ ] ;
1629
+ let r = recvmmsg ( in_socket, & mut data, flags, None ) . unwrap ( ) ;
1630
+ let rtime = match r[ 0 ] . cmsgs ( ) . next ( ) {
1631
+ Some ( ControlMessageOwned :: ScmTimestampns ( rtime) ) => rtime,
1632
+ Some ( _) => panic ! ( "Unexpected control message" ) ,
1633
+ None => panic ! ( "No control message" )
1634
+ } ;
1635
+ // Check the final time
1636
+ let time1 = SystemTime :: now ( ) ;
1637
+ // the packet's received timestamp should lie in-between the two system
1638
+ // times, unless the system clock was adjusted in the meantime.
1639
+ let rduration = Duration :: new ( rtime. tv_sec ( ) as u64 ,
1640
+ rtime. tv_nsec ( ) as u32 ) ;
1641
+ assert ! ( time0. duration_since( UNIX_EPOCH ) . unwrap( ) <= rduration) ;
1642
+ assert ! ( rduration <= time1. duration_since( UNIX_EPOCH ) . unwrap( ) ) ;
1643
+ // Close socket
1644
+ nix:: unistd:: close ( in_socket) . unwrap ( ) ;
1645
+ }
0 commit comments