Skip to main content

compio_driver/sys/op/socket/
mod.rs

1#[cfg(unix)]
2mod_use![unix];
3
4#[cfg(io_uring)]
5mod_use![iour];
6
7#[cfg(windows)]
8mod_use![iocp];
9
10#[cfg(polling)]
11mod_use![poll];
12
13#[cfg(stub)]
14mod_use![stub];
15
16use compio_buf::IoBufExt;
17use rustix::net::{RecvFlags, ReturnFlags, SendFlags};
18
19use crate::sys::prelude::*;
20
21/// Connect to a remote address.
22pub struct Connect<S> {
23    pub(crate) fd: S,
24    pub(crate) addr: SockAddr,
25}
26
27/// Close socket fd.
28pub struct CloseSocket {
29    pub(crate) fd: ManuallyDrop<OwnedFd>,
30}
31
32/// Send data to remote.
33///
34/// If you want to write to a pipe, use [`Write`].
35///
36/// [`Write`]: crate::op::Write
37pub struct Send<T: IoBuf, S> {
38    pub(crate) fd: S,
39    pub(crate) buffer: T,
40    pub(crate) flags: SendFlags,
41}
42
43/// Send data to remote from vectored buffer.
44pub struct SendVectored<T: IoVectoredBuf, S> {
45    pub(crate) fd: S,
46    pub(crate) buffer: T,
47    pub(crate) flags: SendFlags,
48}
49
50pub(crate) struct SendToHeader<S> {
51    pub(crate) fd: S,
52    pub(crate) addr: SockAddr,
53    pub(crate) flags: SendFlags,
54}
55
56/// Send data to specified address.
57pub struct SendTo<T: IoBuf, S> {
58    pub(crate) header: SendToHeader<S>,
59    pub(crate) buffer: T,
60}
61
62/// Send data to specified address from vectored buffer.
63pub struct SendToVectored<T: IoVectoredBuf, S> {
64    pub(crate) header: SendToHeader<S>,
65    pub(crate) buffer: T,
66}
67
68/// Send data to specified address accompanied by ancillary data from vectored
69/// buffer.
70pub struct SendMsg<T: IoVectoredBuf, C: IoBuf, S> {
71    pub(crate) fd: S,
72    pub(crate) buffer: T,
73    pub(crate) control: C,
74    pub(crate) addr: Option<SockAddr>,
75    pub(crate) flags: SendFlags,
76}
77
78/// Receive data from remote.
79///
80/// If you want to read from a pipe, use [`Read`].
81///
82/// [`Read`]: crate::op::Read
83pub struct Recv<T: IoBufMut, S> {
84    pub(crate) fd: S,
85    pub(crate) buffer: T,
86    pub(crate) flags: RecvFlags,
87}
88
89/// Receive data from remote into vectored buffer.
90pub struct RecvVectored<T: IoVectoredBufMut, S> {
91    pub(crate) fd: S,
92    pub(crate) buffer: T,
93    pub(crate) flags: RecvFlags,
94}
95
96pub(crate) struct RecvFromHeader<S> {
97    pub(crate) fd: S,
98    pub(crate) flags: RecvFlags,
99    pub(crate) addr: SockAddrStorage,
100    pub(crate) addr_len: socklen_t,
101}
102
103/// Receive data and source address.
104pub struct RecvFrom<T: IoBufMut, S> {
105    pub(crate) header: RecvFromHeader<S>,
106    pub(crate) buffer: T,
107}
108
109/// Receive data and source address into vectored buffer.
110pub struct RecvFromVectored<T: IoVectoredBufMut, S> {
111    pub(crate) header: RecvFromHeader<S>,
112    pub(crate) buffer: T,
113}
114
115/// Receive data and source address with ancillary data into vectored
116/// buffer.
117pub struct RecvMsg<T: IoVectoredBufMut, C: IoBufMut, S> {
118    pub(crate) header: RecvFromHeader<S>,
119    pub(crate) buffer: T,
120    pub(crate) control: C,
121    pub(crate) control_len: usize,
122    pub(crate) return_flags: ReturnFlags,
123}
124
125impl<S> Connect<S> {
126    /// Create [`Connect`]. `fd` should be bound.
127    pub fn new(fd: S, addr: SockAddr) -> Self {
128        Self { fd, addr }
129    }
130}
131
132impl CloseSocket {
133    /// Create [`CloseSocket`].
134    pub fn new(fd: OwnedFd) -> Self {
135        Self {
136            fd: ManuallyDrop::new(fd),
137        }
138    }
139}
140
141impl<T: IoBuf, S> Send<T, S> {
142    /// Create [`Send`].
143    pub fn new(fd: S, buffer: T, flags: SendFlags) -> Self {
144        Self { fd, buffer, flags }
145    }
146}
147
148impl<T: IoBuf, S> IntoInner for Send<T, S> {
149    type Inner = T;
150
151    fn into_inner(self) -> Self::Inner {
152        self.buffer
153    }
154}
155
156impl<T: IoVectoredBuf, S> SendVectored<T, S> {
157    /// Create [`SendVectored`].
158    pub fn new(fd: S, buffer: T, flags: SendFlags) -> Self {
159        Self { fd, buffer, flags }
160    }
161}
162
163impl<T: IoVectoredBuf, S> IntoInner for SendVectored<T, S> {
164    type Inner = T;
165
166    fn into_inner(self) -> Self::Inner {
167        self.buffer
168    }
169}
170
171impl<S> SendToHeader<S> {
172    pub fn new(fd: S, addr: SockAddr, flags: SendFlags) -> Self {
173        Self { fd, addr, flags }
174    }
175}
176
177impl<T: IoBuf, S> SendTo<T, S> {
178    /// Create [`SendTo`].
179    pub fn new(fd: S, buffer: T, addr: SockAddr, flags: SendFlags) -> Self {
180        Self {
181            header: SendToHeader::new(fd, addr, flags),
182            buffer,
183        }
184    }
185}
186
187impl<T: IoBuf, S> IntoInner for SendTo<T, S> {
188    type Inner = T;
189
190    fn into_inner(self) -> Self::Inner {
191        self.buffer
192    }
193}
194
195impl<T: IoVectoredBuf, S> SendToVectored<T, S> {
196    /// Create [`SendToVectored`].
197    pub fn new(fd: S, buffer: T, addr: SockAddr, flags: SendFlags) -> Self {
198        Self {
199            header: SendToHeader::new(fd, addr, flags),
200            buffer,
201        }
202    }
203}
204
205impl<T: IoVectoredBuf, S> IntoInner for SendToVectored<T, S> {
206    type Inner = T;
207
208    fn into_inner(self) -> Self::Inner {
209        self.buffer
210    }
211}
212
213impl<T: IoVectoredBuf, C: IoBuf, S> SendMsg<T, C, S> {
214    /// Create [`SendMsg`].
215    ///
216    /// # Panics
217    ///
218    /// This function will panic if the control message buffer is misaligned.
219    pub fn new(fd: S, buffer: T, control: C, addr: Option<SockAddr>, flags: SendFlags) -> Self {
220        assert!(
221            control.buf_len() == 0 || control.buf_ptr().cast::<CmsgHeader>().is_aligned(),
222            "misaligned control message buffer"
223        );
224        Self {
225            fd,
226            buffer,
227            control,
228            addr,
229            flags,
230        }
231    }
232}
233
234impl<T: IoVectoredBuf, C: IoBuf, S> IntoInner for SendMsg<T, C, S> {
235    type Inner = (T, C);
236
237    fn into_inner(self) -> Self::Inner {
238        (self.buffer, self.control)
239    }
240}
241
242impl<T: IoVectoredBufMut, C: IoBufMut, S> RecvMsg<T, C, S> {
243    /// Create [`RecvMsg`].
244    ///
245    /// # Panics
246    ///
247    /// This function will panic if the control message buffer is
248    /// misaligned.
249    pub fn new(fd: S, buffer: T, control: C, flags: RecvFlags) -> Self {
250        assert!(
251            control.buf_ptr().cast::<CmsgHeader>().is_aligned(),
252            "misaligned control message buffer"
253        );
254        Self {
255            header: RecvFromHeader::new(fd, flags),
256            buffer,
257            control,
258            control_len: 0,
259            return_flags: ReturnFlags::empty(),
260        }
261    }
262}
263
264impl<T: IoVectoredBufMut, C: IoBufMut, S> IntoInner for RecvMsg<T, C, S> {
265    type Inner = ((T, C), Option<SockAddr>, usize, ReturnFlags);
266
267    fn into_inner(self) -> Self::Inner {
268        (
269            (self.buffer, self.control),
270            self.header.into_addr(),
271            self.control_len,
272            self.return_flags,
273        )
274    }
275}
276
277impl<T: IoBufMut, S> Recv<T, S> {
278    /// Create [`Recv`].
279    pub fn new(fd: S, buffer: T, flags: RecvFlags) -> Self {
280        Self { fd, buffer, flags }
281    }
282}
283
284impl<T: IoBufMut, S> IntoInner for Recv<T, S> {
285    type Inner = T;
286
287    fn into_inner(self) -> Self::Inner {
288        self.buffer
289    }
290}
291
292impl<T: IoVectoredBufMut, S> RecvVectored<T, S> {
293    /// Create [`RecvVectored`].
294    pub fn new(fd: S, buffer: T, flags: RecvFlags) -> Self {
295        Self { fd, buffer, flags }
296    }
297}
298
299impl<T: IoVectoredBufMut, S> IntoInner for RecvVectored<T, S> {
300    type Inner = T;
301
302    fn into_inner(self) -> Self::Inner {
303        self.buffer
304    }
305}
306
307impl<S> RecvFromHeader<S> {
308    pub fn new(fd: S, flags: RecvFlags) -> Self {
309        let addr = SockAddrStorage::zeroed();
310        let name_len = addr.size_of();
311        Self {
312            fd,
313            addr,
314            flags,
315            addr_len: name_len,
316        }
317    }
318
319    pub fn into_addr(self) -> Option<SockAddr> {
320        (self.addr_len > 0).then(|| unsafe { SockAddr::new(self.addr, self.addr_len) })
321    }
322}
323
324impl<T: IoVectoredBufMut, S> RecvFromVectored<T, S> {
325    /// Create [`RecvFromVectored`].
326    pub fn new(fd: S, buffer: T, flags: RecvFlags) -> Self {
327        Self {
328            header: RecvFromHeader::new(fd, flags),
329            buffer,
330        }
331    }
332}
333
334impl<T: IoVectoredBufMut, S: AsFd> IntoInner for RecvFromVectored<T, S> {
335    type Inner = (T, Option<SockAddr>);
336
337    fn into_inner(self) -> Self::Inner {
338        let addr = self.header.into_addr();
339        (self.buffer, addr)
340    }
341}
342
343impl<T: IoBufMut, S> RecvFrom<T, S> {
344    /// Create [`RecvFrom`].
345    pub fn new(fd: S, buffer: T, flags: RecvFlags) -> Self {
346        Self {
347            header: RecvFromHeader::new(fd, flags),
348            buffer,
349        }
350    }
351}
352
353impl<T: IoBufMut, S> IntoInner for RecvFrom<T, S> {
354    type Inner = (T, Option<SockAddr>);
355
356    fn into_inner(self) -> Self::Inner {
357        (self.buffer, self.header.into_addr())
358    }
359}