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