monoio/net/unix/seq_packet/
mod.rs

1//! UnixSeqpacket related.
2//! Only available on linux.
3
4use std::{
5    io,
6    os::unix::prelude::{AsRawFd, RawFd},
7    path::Path,
8};
9
10use super::{
11    socket_addr::{local_addr, pair, peer_addr, socket_addr},
12    SocketAddr,
13};
14use crate::{
15    buf::{IoBuf, IoBufMut},
16    driver::{op::Op, shared_fd::SharedFd},
17    net::new_socket,
18};
19
20mod listener;
21pub use listener::UnixSeqpacketListener;
22
23/// UnixSeqpacket
24pub struct UnixSeqpacket {
25    fd: SharedFd,
26}
27
28impl UnixSeqpacket {
29    pub(crate) fn from_shared_fd(fd: SharedFd) -> Self {
30        Self { fd }
31    }
32
33    /// Creates an unnamed pair of connected sockets.
34    pub fn pair() -> io::Result<(Self, Self)> {
35        let (a, b) = pair(libc::SOCK_SEQPACKET)?;
36        Ok((
37            Self::from_shared_fd(SharedFd::new::<false>(a)?),
38            Self::from_shared_fd(SharedFd::new::<false>(b)?),
39        ))
40    }
41
42    /// Connects the socket to the specified address.
43    pub async fn connect<P: AsRef<Path>>(path: P) -> io::Result<Self> {
44        let (addr, addr_len) = socket_addr(path.as_ref())?;
45        Self::inner_connect(addr, addr_len).await
46    }
47
48    /// Connects the socket to an address.
49    pub async fn connect_addr(addr: SocketAddr) -> io::Result<Self> {
50        let (addr, addr_len) = addr.into_parts();
51        Self::inner_connect(addr, addr_len).await
52    }
53
54    #[inline(always)]
55    async fn inner_connect(
56        sockaddr: libc::sockaddr_un,
57        socklen: libc::socklen_t,
58    ) -> io::Result<Self> {
59        let socket = new_socket(libc::AF_UNIX, libc::SOCK_SEQPACKET)?;
60        let op = Op::connect_unix(SharedFd::new::<false>(socket)?, sockaddr, socklen)?;
61        let completion = op.await;
62        completion.meta.result?;
63
64        Ok(Self::from_shared_fd(completion.data.fd))
65    }
66
67    /// Returns the socket address of the local half of this connection.
68    pub fn local_addr(&self) -> io::Result<SocketAddr> {
69        local_addr(self.as_raw_fd())
70    }
71
72    /// Returns the socket address of the remote half of this connection.
73    pub fn peer_addr(&self) -> io::Result<SocketAddr> {
74        peer_addr(self.as_raw_fd())
75    }
76
77    /// Wait for read readiness.
78    /// Note: Do not use it before every io. It is different from other runtimes!
79    ///
80    /// Everytime call to this method may pay a syscall cost.
81    /// In uring impl, it will push a PollAdd op; in epoll impl, it will use use
82    /// inner readiness state; if !relaxed, it will call syscall poll after that.
83    ///
84    /// If relaxed, on legacy driver it may return false positive result.
85    /// If you want to do io by your own, you must maintain io readiness and wait
86    /// for io ready with relaxed=false.
87    pub async fn readable(&self, relaxed: bool) -> io::Result<()> {
88        let op = Op::poll_read(&self.fd, relaxed).unwrap();
89        op.wait().await
90    }
91
92    /// Wait for write readiness.
93    /// Note: Do not use it before every io. It is different from other runtimes!
94    ///
95    /// Everytime call to this method may pay a syscall cost.
96    /// In uring impl, it will push a PollAdd op; in epoll impl, it will use use
97    /// inner readiness state; if !relaxed, it will call syscall poll after that.
98    ///
99    /// If relaxed, on legacy driver it may return false positive result.
100    /// If you want to do io by your own, you must maintain io readiness and wait
101    /// for io ready with relaxed=false.
102    pub async fn writable(&self, relaxed: bool) -> io::Result<()> {
103        let op = Op::poll_write(&self.fd, relaxed).unwrap();
104        op.wait().await
105    }
106
107    /// Sends data on the socket to the given address. On success, returns the
108    /// number of bytes written.
109    pub async fn send_to<T: IoBuf, P: AsRef<Path>>(
110        &self,
111        buf: T,
112        path: P,
113    ) -> crate::BufResult<usize, T> {
114        let addr = match crate::net::unix::socket_addr::socket_addr(path.as_ref()) {
115            Ok(addr) => addr,
116            Err(e) => return (Err(e), buf),
117        };
118        let op = Op::send_msg_unix(
119            self.fd.clone(),
120            buf,
121            Some(SocketAddr::from_parts(addr.0, addr.1)),
122        )
123        .unwrap();
124        op.wait().await
125    }
126
127    /// Receives a single datagram message on the socket. On success, returns the number
128    /// of bytes read and the origin.
129    pub async fn recv_from<T: IoBufMut>(&self, buf: T) -> crate::BufResult<(usize, SocketAddr), T> {
130        let op = Op::recv_msg_unix(self.fd.clone(), buf).unwrap();
131        op.wait().await
132    }
133
134    /// Sends data on the socket to the remote address to which it is connected.
135    pub async fn send<T: IoBuf>(&self, buf: T) -> crate::BufResult<usize, T> {
136        let op = Op::send_msg_unix(self.fd.clone(), buf, None).unwrap();
137        op.wait().await
138    }
139
140    /// Receives a single datagram message on the socket from the remote address to
141    /// which it is connected. On success, returns the number of bytes read.
142    pub async fn recv<T: IoBufMut>(&self, buf: T) -> crate::BufResult<usize, T> {
143        let op = Op::recv(self.fd.clone(), buf).unwrap();
144        op.result().await
145    }
146}
147
148impl AsRawFd for UnixSeqpacket {
149    #[inline]
150    fn as_raw_fd(&self) -> RawFd {
151        self.fd.raw_fd()
152    }
153}
154
155impl std::fmt::Debug for UnixSeqpacket {
156    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
157        f.debug_struct("UnixSeqpacket")
158            .field("fd", &self.fd)
159            .finish()
160    }
161}