Trait uds::UnixDatagramExt

source ·
pub trait UnixDatagramExt: AsRawFd + FromRawFd {
Show 17 methods // Required method fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, Error> where Self: Sized; // Provided methods fn local_unix_addr(&self) -> Result<UnixSocketAddr, Error> { ... } fn peer_unix_addr(&self) -> Result<UnixSocketAddr, Error> { ... } fn bind_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error> { ... } fn connect_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error> { ... } fn send_to_unix_addr( &self, datagram: &[u8], addr: &UnixSocketAddr ) -> Result<usize, Error> { ... } fn send_vectored_to_unix_addr( &self, datagram: &[IoSlice<'_>], addr: &UnixSocketAddr ) -> Result<usize, Error> { ... } fn recv_from_unix_addr( &self, buf: &mut [u8] ) -> Result<(usize, UnixSocketAddr), Error> { ... } fn recv_vectored_from_unix_addr( &self, bufs: &mut [IoSliceMut<'_>] ) -> Result<(usize, UnixSocketAddr), Error> { ... } fn peek_from_unix_addr( &self, buf: &mut [u8] ) -> Result<(usize, UnixSocketAddr), Error> { ... } fn peek_vectored_from_unix_addr( &self, bufs: &mut [IoSliceMut<'_>] ) -> Result<(usize, UnixSocketAddr), Error> { ... } fn send_fds_to( &self, datagram: &[u8], fds: &[RawFd], addr: &UnixSocketAddr ) -> Result<usize, Error> { ... } fn send_fds(&self, datagram: &[u8], fds: &[RawFd]) -> Result<usize, Error> { ... } fn recv_fds_from( &self, buf: &mut [u8], fd_buf: &mut [RawFd] ) -> Result<(usize, usize, UnixSocketAddr), Error> { ... } fn recv_fds( &self, buf: &mut [u8], fd_buf: &mut [RawFd] ) -> Result<(usize, usize), Error> { ... } fn initial_pair_credentials(&self) -> Result<ConnCredentials, Error> { ... } fn initial_pair_selinux_context( &self, buffer: &mut [u8] ) -> Result<usize, Error> { ... }
}
Expand description

Extension trait for std::os::unix::net::UnixDatagram and nonblocking equivalents.

Required Methods§

source

fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, Error>
where Self: Sized,

Create a socket bound to a path or abstract name.

Examples
let addr = UnixSocketAddr::new("@abstract")?;
let socket = UnixDatagram::bind_unix_addr(&addr)?;

This is equivalent of:

let socket = UnixDatagram::unbound()?;
socket.bind_to_unix_addr(&addr)?;

Provided Methods§

source

fn local_unix_addr(&self) -> Result<UnixSocketAddr, Error>

Returns the address of this socket, as a type that fully supports abstract addresses.

source

fn peer_unix_addr(&self) -> Result<UnixSocketAddr, Error>

Returns the address of the connected socket, as a type that fully supports abstract addresses.

source

fn bind_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error>

Creates a path or abstract name for the socket.

source

fn connect_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error>

Connects the socket to a path-based or abstract named socket.

source

fn send_to_unix_addr( &self, datagram: &[u8], addr: &UnixSocketAddr ) -> Result<usize, Error>

Sends to the specified address, using an address type that supports abstract addresses.

Examples

Send to an abstract address:

let socket = UnixDatagram::unbound().expect("create datagram socket");
let _ = socket.send_to_unix_addr(
    b"Is there anyone there?",
    &UnixSocketAddr::from_abstract("somewhere").expect("OS supports abstract addresses"),
);
source

fn send_vectored_to_unix_addr( &self, datagram: &[IoSlice<'_>], addr: &UnixSocketAddr ) -> Result<usize, Error>

Sends a datagram created from multiple segments to the specified address, using an address type that supports abstract addresses.

Examples

Send a datagram with a fixed header:

let socket = UnixDatagram::unbound().expect("create datagram socket");
let to = UnixSocketAddr::new("/var/run/someone.sock").unwrap();
let msg = [
    IoSlice::new(b"hello "),
    IoSlice::new(to.as_pathname().unwrap().to_str().unwrap().as_bytes()),
];
let _ = socket.send_vectored_to_unix_addr(&msg, &to);
source

fn recv_from_unix_addr( &self, buf: &mut [u8] ) -> Result<(usize, UnixSocketAddr), Error>

Receives from any peer, storing its address in a type that exposes abstract addresses.

Examples

Respond to the received datagram, regardsless of where it was sent from:

use std::os::unix::net::UnixDatagram;
use uds::{UnixSocketAddr, UnixDatagramExt};

let server = UnixDatagram::bind("echo.sock").expect("create server socket");

let client_addr = UnixSocketAddr::new("@echo_client")
    .or(UnixSocketAddr::new("echo_client.sock"))
    .unwrap();
let client = UnixDatagram::unbound().expect("create client ocket");
client.bind_to_unix_addr(&client_addr).expect("create client socket");
client.connect_to_unix_addr(&UnixSocketAddr::new("echo.sock").unwrap())
    .expect("connect to server");
client.send(b"hello").expect("send");

let mut buf = [0; 1024];
let (len, from) = server.recv_from_unix_addr(&mut buf).expect("receive");
server.send_to_unix_addr(&buf[..len], &from).expect("respond");

let len = client.recv(&mut buf).expect("receive response");
assert_eq!(&buf[..len], "hello".as_bytes());

let _ = std::fs::remove_file("echo.sock");
if let Some(client_path) = client_addr.as_pathname() {
    let _ = std::fs::remove_file(client_path);
}
source

fn recv_vectored_from_unix_addr( &self, bufs: &mut [IoSliceMut<'_>] ) -> Result<(usize, UnixSocketAddr), Error>

Uses multiple buffers to receive from any peer, storing its address in a type that exposes abstract addresses.

Examples

Read content into a separate buffer than header:

use mio_08::net::UnixDatagram;
use uds::UnixDatagramExt;
use std::io::IoSliceMut;

let server = UnixDatagram::bind("cat.sock").expect("create cat.sock");
let mut received = Vec::new();

let client = UnixDatagram::unbound().expect("create client socket");
client.send_to(b"cat\x01one", "cat.sock").expect("send");
client.send_to(b"cat\x01two", "cat.sock").expect("send");
client.send_to(b"cat\x01three", "cat.sock").expect("send");

let mut header = [0; 4];
loop {
    let current_len = received.len();
    received.resize(current_len+1024, 0);
    let mut bufs = [
        IoSliceMut::new(&mut header),
        IoSliceMut::new(&mut received[current_len..]),
    ];
    match server.recv_vectored_from_unix_addr(&mut bufs) {
        Ok((len, _addr)) if len > 4  &&  header == *b"cat\x01" => {
            received.truncate(current_len+len-4); // keep it
        },
        Ok((_, _)) => received.truncate(current_len), // discard it
        Err(_) => {
            received.truncate(current_len); // discard it
            break;
        }
    }
}

assert_eq!(&received, &b"onetwothree");
source

fn peek_from_unix_addr( &self, buf: &mut [u8] ) -> Result<(usize, UnixSocketAddr), Error>

Reads the next datagram without removing it from the queue.

Examples

Discard datagram if it’s the wrong protocol:

let checker = UnixDatagram::bind("checker.sock").expect("create receiver socket");

let client = UnixDatagram::unbound().expect("create client ocket");
client.send_to(b"hello", "checker.sock").expect("send");

let mut header = [0; 4];
let (len, _from) = checker.peek_from_unix_addr(&mut header).expect("receive");
if len != 4  ||  header != *b"WTFP" {
    let _ = checker.recv(&mut header); // discard
} else {
    // call function that receives and processes it
}
source

fn peek_vectored_from_unix_addr( &self, bufs: &mut [IoSliceMut<'_>] ) -> Result<(usize, UnixSocketAddr), Error>

Uses multiple buffers to read the next datagram without removing it from the queue.

Examples
use std::os::unix::net::UnixDatagram;
use std::io::IoSliceMut;
use uds::{UnixDatagramExt, UnixSocketAddr};

let server = UnixDatagram::bind("datagram_server.sock").unwrap();

// get a random abstract address on Linux
let client = UnixDatagram::unbound().unwrap();
client.bind_to_unix_addr(&UnixSocketAddr::new_unspecified()).unwrap();
client.connect("datagram_server.sock").unwrap();
client.send(b"headerbodybody").unwrap();

let (mut buf_a, mut buf_b) = ([0; 6], [0; 12]);
let mut vector = [IoSliceMut::new(&mut buf_a), IoSliceMut::new(&mut buf_b)];
let (bytes, addr) = server.peek_vectored_from_unix_addr(&mut vector).unwrap();
assert_eq!(addr, client.local_unix_addr().unwrap());
assert_eq!(bytes, 14);
assert_eq!(&buf_a, b"header");
assert_eq!(&buf_b[..8], b"bodybody");
source

fn send_fds_to( &self, datagram: &[u8], fds: &[RawFd], addr: &UnixSocketAddr ) -> Result<usize, Error>

Sends file descriptors along with the datagram, on an unconnected socket.

source

fn send_fds(&self, datagram: &[u8], fds: &[RawFd]) -> Result<usize, Error>

Sends file descriptors along with the datagram, on a connected socket.

source

fn recv_fds_from( &self, buf: &mut [u8], fd_buf: &mut [RawFd] ) -> Result<(usize, usize, UnixSocketAddr), Error>

Receives file descriptors along with the datagram, on an unconnected socket

source

fn recv_fds( &self, buf: &mut [u8], fd_buf: &mut [RawFd] ) -> Result<(usize, usize), Error>

Receives file descriptors along with the datagram, on a connected socket

source

fn initial_pair_credentials(&self) -> Result<ConnCredentials, Error>

Returns the credentials of the process that created a socket pair.

This information is only available on Linux, and only for sockets that was created with pair() or the underlying socketpair(). For sockets that have merely been “connected” to an address or not connected at all, an error of kind NotConnected or InvalidInput is returned.

The use cases of this function gotta be very narrow:

  • It will return the credentials of the current process unless the side of the socket this method is called on was received via FD-passing or inherited from a parent.
  • If it was created by the direct parent process, one might as well use getppid() and go from there?
  • A returned pid can be repurposed by the OS before the call returns.
  • uids or groups will be those in effect when the pair was created, and will not reflect changes in privileges.

Despite these limitations, the feature is supported by Linux at least (but not macOS or FreeBSD), so might as well expose it.

source

fn initial_pair_selinux_context( &self, buffer: &mut [u8] ) -> Result<usize, Error>

Returns the SELinux security context of the process that created a socket pair.

Has the same limitations and gotchas as initial_pair_credentials(), and will return an error on other OSes than Linux or Android or if running under kubernetes.

The default security context is the string unconfined.

Object Safety§

This trait is not object safe.

Implementations on Foreign Types§

source§

impl UnixDatagramExt for UnixDatagram

source§

impl UnixDatagramExt for UnixDatagram

Implementors§