uds/tokio/
seqpacket.rs

1use crate::{nonblocking, UnixSocketAddr, ConnCredentials};
2
3use std::io::{self, IoSlice, IoSliceMut};
4use std::net::Shutdown;
5use std::os::unix::io::{AsRawFd, FromRawFd, IntoRawFd, RawFd};
6use std::path::Path;
7
8use tokio_crate::io::Interest;
9use tokio_crate::io::unix::AsyncFd;
10
11/// An I/O object representing a Unix Sequenced-packet socket.
12pub struct UnixSeqpacketConn {
13    io: AsyncFd<nonblocking::UnixSeqpacketConn>,
14}
15
16impl UnixSeqpacketConn {
17    /// Connects to the socket named by path.
18    ///
19    /// This function will create a new Unix socket and connects to the path
20    /// specified, associating the returned stream with the default event loop's
21    /// handle.
22    pub fn connect<P: AsRef<Path>>(path: P) -> io::Result<Self> {
23        let conn = nonblocking::UnixSeqpacketConn::connect(path)?;
24        Self::from_nonblocking(conn)
25    }
26    /// Connects to an unix seqpacket server listening at `addr`.
27    pub fn connect_addr(addr: &UnixSocketAddr) -> io::Result<Self> {
28        let conn = nonblocking::UnixSeqpacketConn::connect_unix_addr(addr)?;
29        Self::from_nonblocking(conn)
30    }
31    /// Binds to an address before connecting to a listening seqpacet socket.
32    pub fn connect_from_addr(from: &UnixSocketAddr,  to: &UnixSocketAddr)
33    -> io::Result<Self> {
34        let conn = nonblocking::UnixSeqpacketConn::connect_from_to_unix_addr(from, to)?;
35        Self::from_nonblocking(conn)
36    }
37
38    /// Creates an unnamed pair of connected sockets.
39    ///
40    /// This function will create a pair of interconnected Unix sockets for
41    /// communicating back and forth between one another. Each socket will
42    /// be associated with the default event loop's handle.
43    pub fn pair() -> Result<(UnixSeqpacketConn, UnixSeqpacketConn), io::Error> {
44        let (a, b) = nonblocking::UnixSeqpacketConn::pair()?;
45        let a = Self::from_nonblocking(a)?;
46        let b = Self::from_nonblocking(b)?;
47
48        Ok((a, b))
49    }
50
51    /// Creates a tokio-compatible socket from an existing nonblocking socket.
52    pub fn from_nonblocking(conn: nonblocking::UnixSeqpacketConn) -> Result<Self, io::Error> {
53        match AsyncFd::new(conn) {
54            Ok(io) => Ok(Self { io }),
55            Err(e) => Err(e),
56        }
57    }
58    /// Deregisters the connection and returns the underlying non-blocking type.
59    pub fn into_nonblocking(self) -> nonblocking::UnixSeqpacketConn {
60        self.io.into_inner()
61    }
62    /// Creates a tokio-compatible socket from a raw file descriptor.
63    ///
64    /// This function is provided instead of implementing [`FromRawFd`](std::os::unix::io::FromRawFd)
65    /// because registering with the reactor might fail.
66    ///
67    /// # Safety
68    ///
69    /// The file descriptor must represent a connected seqpacket socket.
70    pub unsafe fn from_raw_fd(fd: RawFd) -> Result<Self, io::Error> {
71        Self::from_nonblocking(nonblocking::UnixSeqpacketConn::from_raw_fd(fd))
72    }
73
74    /// Shuts down the read, write, or both halves of this connection.
75    pub fn shutdown(&self,  how: Shutdown) -> Result<(), io::Error> {
76        self.io.get_ref().shutdown(how)
77    }
78
79    /// Returns the address of this side of the connection.
80    pub fn local_addr(&self) -> Result<UnixSocketAddr, io::Error> {
81        self.io.get_ref().local_unix_addr()
82    }
83    /// Returns the address of the other side of the connection.
84    pub fn peer_addr(&self) -> Result<UnixSocketAddr, io::Error> {
85        self.io.get_ref().peer_unix_addr()
86    }
87
88    /// Returns information about the process of the peer when the connection was established.
89    ///
90    /// See documentation of the returned type for details.
91    pub fn initial_peer_credentials(&self) -> Result<ConnCredentials, io::Error> {
92        self.io.get_ref().initial_peer_credentials()
93    }
94    /// Returns the SELinux security context of the process that created the other
95    /// end of this connection.
96    ///
97    /// Will return an error on other operating systems than Linux or Android,
98    /// and also if running inside kubernetes.
99    /// On success the number of bytes used is returned. (like `Read`)
100    ///
101    /// The default security context is `unconfined`, without any trailing NUL.  
102    /// A buffor of 50 bytes is probably always big enough.
103    pub fn initial_peer_selinux_context(&self,  buffer: &mut[u8]) -> Result<usize, io::Error> {
104        self.io.get_ref().initial_peer_selinux_context(buffer)
105    }
106
107    /// Returns the value of the `SO_ERROR` option.
108    pub fn take_error(&self) -> Result<Option<io::Error>, io::Error> {
109        self.io.get_ref().take_error()
110    }
111}
112
113impl UnixSeqpacketConn {
114    /// Sends a packet to the socket's peer.
115    pub async fn send(&mut self,  packet: &[u8]) -> io::Result<usize> {
116        self.io.async_io(Interest::WRITABLE, |conn| conn.send(packet) ).await
117    }
118    /// Receives a packet from the socket's peer.
119    pub async fn recv(&mut self,  buffer: &mut[u8]) -> io::Result<usize> {
120        self.io.async_io(Interest::READABLE, |conn| conn.recv(buffer) ).await
121    }
122
123    /// Sends a packet assembled from multiple byte slices.
124    pub async fn send_vectored<'a, 'b>
125    (&'a mut self,  slices: &'b [IoSlice<'b>]) -> io::Result<usize> {
126        self.io.async_io(Interest::WRITABLE, |conn| conn.send_vectored(slices) ).await
127    }
128    /// Receives a packet and places the bytes across multiple buffers.
129    pub async fn recv_vectored<'a, 'b>
130    (&'a mut self,  buffers: &'b mut [IoSliceMut<'b>]) -> io::Result<usize> {
131        self.io.async_io(
132                Interest::READABLE,
133                |conn| conn.recv_vectored(buffers).map(|(received, _)| received )
134        ).await
135    }
136
137    /// Receives a packet without removing it from the incoming queue.
138    pub async fn peek(&mut self,  buffer: &mut[u8]) -> io::Result<usize> {
139        self.io.async_io(Interest::READABLE, |conn| conn.peek(buffer) ).await
140    }
141    /// Reads a packet into multiple buffers without removing it from the incoming queue.
142    pub async fn peek_vectored<'a, 'b>
143    (&'a mut self,  buffers: &'b mut [IoSliceMut<'b>]) -> io::Result<usize> {
144        self.io.async_io(
145                Interest::READABLE,
146                |conn| conn.peek_vectored(buffers).map(|(received, _)| received )
147        ).await
148    }
149
150    /// Sends a packet with associated file descriptors.
151    pub async fn send_fds(&mut self,  bytes: &[u8],  fds: &[RawFd]) -> io::Result<usize> {
152        self.io.async_io(Interest::WRITABLE, |conn| conn.send_fds(bytes, fds) ).await
153    }
154    /// Receives a packet and associated file descriptors.
155    pub async fn recv_fds(&mut self,  byte_buffer: &mut[u8],  fd_buffer: &mut[RawFd])
156    -> io::Result<(usize, bool, usize)> {
157        self.io.async_io(Interest::READABLE, |conn| conn.recv_fds(byte_buffer, fd_buffer) ).await
158    }
159}
160
161impl AsRef<nonblocking::UnixSeqpacketConn> for UnixSeqpacketConn {
162    fn as_ref(&self) -> &nonblocking::UnixSeqpacketConn {
163        self.io.get_ref()
164    }
165}
166
167impl AsRawFd for UnixSeqpacketConn {
168    fn as_raw_fd(&self) -> RawFd {
169        self.io.get_ref().as_raw_fd()
170    }
171}
172
173impl IntoRawFd for UnixSeqpacketConn {
174    fn into_raw_fd(self) -> RawFd {
175        self.io.into_inner().into_raw_fd()
176    }
177}
178
179
180
181/// An I/O object representing a Unix Sequenced-packet socket.
182pub struct UnixSeqpacketListener {
183    io: AsyncFd<nonblocking::UnixSeqpacketListener>,
184}
185
186impl UnixSeqpacketListener {
187    /// Creates a socket that listens for seqpacket connections on the specified socket file.
188    pub fn bind<P: AsRef<Path>>(path: P) -> Result<Self, io::Error> {
189        match nonblocking::UnixSeqpacketListener::bind(path.as_ref()) {
190            Ok(listener) => Self::from_nonblocking(listener),
191            Err(e) => Err(e),
192        }
193    }
194    /// Creates a socket that listens for seqpacket connections on the specified address.
195    pub fn bind_addr(addr: &UnixSocketAddr) -> Result<Self, io::Error> {
196        match nonblocking::UnixSeqpacketListener::bind_unix_addr(addr) {
197            Ok(listener) => Self::from_nonblocking(listener),
198            Err(e) => Err(e),
199        }
200    }
201
202    /// Creates a tokio-compatible listener from an existing nonblocking listener.
203    pub fn from_nonblocking(listener: nonblocking::UnixSeqpacketListener)
204    -> Result<Self, io::Error> {
205        match AsyncFd::with_interest(listener, Interest::READABLE) {
206            Ok(io) => Ok(Self { io }),
207            Err(e) => Err(e),
208        }
209    }
210    /// Deregisters the listener and returns the underlying non-blocking type.
211    pub fn into_nonblocking(self) -> nonblocking::UnixSeqpacketListener {
212        self.io.into_inner()
213    }
214    /// Creates a tokio-compatible listener from a raw file descriptor.
215    ///
216    /// This function is provided instead of implementing [`FromRawFd`](std::os::unix::io::FromRawFd)
217    /// because registering with the reactor might fail.
218    ///
219    /// # Safety
220    ///
221    /// The file descriptor must represent a non-blocking seqpacket listener.
222    pub unsafe fn from_raw_fd(fd: RawFd) -> Result<Self, io::Error> {
223        Self::from_nonblocking(nonblocking::UnixSeqpacketListener::from_raw_fd(fd))
224    }
225
226    /// Accepts a new incoming connection to this listener.
227    pub async fn accept(&mut self) -> io::Result<(UnixSeqpacketConn, UnixSocketAddr)> {
228        let (conn, addr) = self.io.async_io(
229                Interest::READABLE,
230                |inner| inner.accept_unix_addr()
231        ).await?;
232        let conn = UnixSeqpacketConn::from_nonblocking(conn)?;
233        Ok((conn, addr))
234    }
235
236    /// Returns the address the socket is listening on.
237    pub fn local_addr(&self) -> Result<UnixSocketAddr, io::Error> {
238        self.io.get_ref().local_unix_addr()
239    }
240
241    /// Returns the value of the `SO_ERROR` option.
242    ///
243    /// This might never produce any errors for listeners. It is therefore
244    /// unlikely to be useful, but is provided for parity with
245    /// `std::unix::net::UnixListener`.
246    pub fn take_error(&self) -> Result<Option<io::Error>, io::Error> {
247        self.io.get_ref().take_error()
248    }
249}
250
251impl AsRef<nonblocking::UnixSeqpacketListener> for UnixSeqpacketListener {
252    fn as_ref(&self) -> &nonblocking::UnixSeqpacketListener {
253        self.io.get_ref()
254    }
255}
256
257impl AsRawFd for UnixSeqpacketListener {
258    fn as_raw_fd(&self) -> RawFd {
259        self.io.get_ref().as_raw_fd()
260    }
261}
262
263impl IntoRawFd for UnixSeqpacketListener {
264    fn into_raw_fd(self) -> RawFd {
265        self.io.into_inner().into_raw_fd()
266    }
267}