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