Trait uds::UnixDatagramExt
source · [−]pub trait UnixDatagramExt: AsRawFd + FromRawFd + Sized {
Show 17 methods
fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, Error> { ... }
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.
Provided Methods
sourcefn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, Error>
fn bind_unix_addr(addr: &UnixSocketAddr) -> Result<Self, Error>
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)?;
sourcefn local_unix_addr(&self) -> Result<UnixSocketAddr, Error>
fn local_unix_addr(&self) -> Result<UnixSocketAddr, Error>
Returns the address of this socket, as a type that fully supports abstract addresses.
sourcefn peer_unix_addr(&self) -> Result<UnixSocketAddr, Error>
fn peer_unix_addr(&self) -> Result<UnixSocketAddr, Error>
Returns the address of the connected socket, as a type that fully supports abstract addresses.
sourcefn bind_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error>
fn bind_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error>
Creates a path or abstract name for the socket.
sourcefn connect_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error>
fn connect_to_unix_addr(&self, addr: &UnixSocketAddr) -> Result<(), Error>
Connects the socket to a path-based or abstract named socket.
sourcefn send_to_unix_addr(
&self,
datagram: &[u8],
addr: &UnixSocketAddr
) -> Result<usize, Error>
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"),
);
sourcefn send_vectored_to_unix_addr(
&self,
datagram: &[IoSlice<'_>],
addr: &UnixSocketAddr
) -> Result<usize, Error>
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);
sourcefn recv_from_unix_addr(
&self,
buf: &mut [u8]
) -> Result<(usize, UnixSocketAddr), Error>
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);
}
sourcefn recv_vectored_from_unix_addr(
&self,
bufs: &mut [IoSliceMut<'_>]
) -> Result<(usize, UnixSocketAddr), Error>
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_07::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");
# let _ = std::fs::remove_file("cat.sock");
sourcefn peek_from_unix_addr(
&self,
buf: &mut [u8]
) -> Result<(usize, UnixSocketAddr), Error>
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
}
sourcefn peek_vectored_from_unix_addr(
&self,
bufs: &mut [IoSliceMut<'_>]
) -> Result<(usize, UnixSocketAddr), Error>
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");
sourcefn send_fds_to(
&self,
datagram: &[u8],
fds: &[RawFd],
addr: &UnixSocketAddr
) -> Result<usize, Error>
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.
sourcefn send_fds(&self, datagram: &[u8], fds: &[RawFd]) -> Result<usize, Error>
fn send_fds(&self, datagram: &[u8], fds: &[RawFd]) -> Result<usize, Error>
Sends file descriptors along with the datagram, on a connected socket.
sourcefn recv_fds_from(
&self,
buf: &mut [u8],
fd_buf: &mut [RawFd]
) -> Result<(usize, usize, UnixSocketAddr), Error>
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
sourcefn recv_fds(
&self,
buf: &mut [u8],
fd_buf: &mut [RawFd]
) -> Result<(usize, usize), Error>
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
sourcefn initial_pair_credentials(&self) -> Result<ConnCredentials, Error>
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.
sourcefn initial_pair_selinux_context(&self, buffer: &mut [u8]) -> Result<usize, Error>
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
.