[][src]Enum nix::sys::socket::ControlMessage

pub enum ControlMessage<'a> {
    ScmRights(&'a [RawFd]),
    ScmTimestamp(&'a TimeVal),
    Ipv4PacketInfo(&'a in_pktinfo),
    Ipv6PacketInfo(&'a in6_pktinfo),
    // some variants omitted
}

A type-safe wrapper around a single control message. More types may be added to this enum; do not exhaustively pattern-match it. Further reading

Variants

ScmRights(&'a [RawFd])

A message of type SCM_RIGHTS, containing an array of file descriptors passed between processes.

See the description in the "Ancillary messages" section of the unix(7) man page.

Using multiple ScmRights messages for a single sendmsg call isn't recommended since it causes platform-dependent behaviour: It might swallow all but the first ScmRights message or fail with EINVAL. Instead, you can put all fds to be passed into a single ScmRights message.

ScmTimestamp(&'a TimeVal)

A message of type SCM_TIMESTAMP, containing the time the packet was received by the kernel.

See the kernel's explanation in "SO_TIMESTAMP" of networking/timestamping.

Examples

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::ReceiveTimestamp, &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: CmsgSpace<TimeVal> = CmsgSpace::new();
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(ControlMessage::ScmTimestamp(&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_usec() as u32 * 1000);
assert!(time0.duration_since(UNIX_EPOCH).unwrap() <= rduration);
assert!(rduration <= time1.duration_since(UNIX_EPOCH).unwrap());
// Close socket
nix::unistd::close(in_socket).unwrap();
Ipv4PacketInfo(&'a in_pktinfo)Ipv6PacketInfo(&'a in6_pktinfo)

Auto Trait Implementations

impl<'a> Send for ControlMessage<'a>

impl<'a> Sync for ControlMessage<'a>

Blanket Implementations

impl<T> From<T> for T[src]

impl<T, U> Into<U> for T where
    U: From<T>, 
[src]

impl<T, U> TryFrom<U> for T where
    U: Into<T>, 
[src]

type Error = Infallible

The type returned in the event of a conversion error.

impl<T, U> TryInto<U> for T where
    U: TryFrom<T>, 
[src]

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.

impl<T> BorrowMut<T> for T where
    T: ?Sized
[src]

impl<T> Borrow<T> for T where
    T: ?Sized
[src]

impl<T> Any for T where
    T: 'static + ?Sized
[src]