Skip to main content

compio_driver/sys/op/socket/
iour.rs

1use std::ffi::c_int;
2
3use io_uring::{opcode, types::Fd};
4
5use crate::{IourOpCode as OpCode, OpEntry, sys::op::*};
6
7unsafe impl OpCode for CreateSocket {
8    type Control = ();
9
10    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
11        opcode::Socket::new(
12            self.domain.as_raw() as _,
13            self.socket_type.as_raw() as c_int | libc::SOCK_CLOEXEC,
14            self.protocol.map(|p| p.as_raw().get()).unwrap_or_default() as _,
15        )
16        .build()
17        .into()
18    }
19
20    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
21        self.call()?;
22        // Return ownership through the result like the kernel does: `set_result`
23        // is the only place that adopts the fd.
24        let fd = self.opened_fd.take().expect("socket not created");
25        Ok(fd.into_raw_fd() as _)
26    }
27
28    unsafe fn set_result(&mut self, _: &mut Self::Control, res: &io::Result<usize>, _: &Extra) {
29        if let Ok(fd) = res {
30            // SAFETY: fd is a valid fd returned from kernel or `call_blocking`
31            let fd = unsafe { Socket2::from_raw_fd(*fd as _) };
32            self.opened_fd = Some(fd);
33        }
34    }
35}
36
37unsafe impl<S: AsFd> OpCode for Bind<S> {
38    type Control = ();
39
40    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
41        opcode::Bind::new(
42            Fd(self.fd.as_fd().as_raw_fd()),
43            self.addr.as_ptr().cast(),
44            self.addr.len(),
45        )
46        .build()
47        .into()
48    }
49
50    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
51        self.call()
52    }
53}
54
55unsafe impl<S: AsFd> OpCode for Listen<S> {
56    type Control = ();
57
58    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
59        opcode::Listen::new(Fd(self.fd.as_fd().as_raw_fd()), self.backlog)
60            .build()
61            .into()
62    }
63
64    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
65        self.call()
66    }
67}
68
69unsafe impl<S: AsFd> OpCode for ShutdownSocket<S> {
70    type Control = ();
71
72    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
73        opcode::Shutdown::new(Fd(self.fd.as_fd().as_raw_fd()), self.how())
74            .build()
75            .into()
76    }
77
78    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
79        self.call()
80    }
81}
82
83unsafe impl OpCode for CloseSocket {
84    type Control = ();
85
86    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
87        opcode::Close::new(Fd(self.fd.as_fd().as_raw_fd()))
88            .build()
89            .into()
90    }
91
92    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
93        self.call()
94    }
95}
96
97unsafe impl<S: AsSocketState> OpCode for Accept<S> {
98    type Control = ();
99
100    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
101        let entry = opcode::Accept::new(
102            Fd(self.fd.as_fd().as_raw_fd()),
103            unsafe { self.buffer.view_as::<libc::sockaddr>() },
104            &raw mut self.addr_len,
105        )
106        .flags(libc::SOCK_CLOEXEC)
107        .build();
108        let entry = set_poll_first(entry, self.fd.accept_poll_first());
109        entry.into()
110    }
111
112    unsafe fn set_result(&mut self, _: &mut Self::Control, res: &io::Result<usize>, _: &Extra) {
113        if let Ok(fd) = res {
114            // SAFETY: fd is a valid fd returned from kernel or `call_blocking`
115            let fd = unsafe { Socket2::from_raw_fd(*fd as _) };
116            self.accepted_fd = Some(fd);
117        }
118    }
119
120    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
121        self.call()?;
122        // See `CreateSocket::call_blocking`.
123        let fd = self.accepted_fd.take().expect("socket not accepted");
124        Ok(fd.into_raw_fd() as _)
125    }
126}
127
128unsafe impl<S: AsFd> OpCode for Connect<S> {
129    type Control = ();
130
131    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
132        opcode::Connect::new(
133            Fd(self.fd.as_fd().as_raw_fd()),
134            self.addr.as_ptr().cast(),
135            self.addr.len(),
136        )
137        .build()
138        .into()
139    }
140
141    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
142        self.call()
143    }
144}
145
146unsafe impl<T: IoBuf, S: AsFd> OpCode for Send<T, S> {
147    type Control = ();
148
149    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
150        let slice = self.buffer.as_init();
151        opcode::Send::new(
152            Fd(self.fd.as_fd().as_raw_fd()),
153            slice.as_ptr(),
154            slice.len().try_into().unwrap_or(u32::MAX),
155        )
156        .flags(self.flags.bits() as _)
157        .build()
158        .into()
159    }
160
161    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
162        self.call()
163    }
164}
165
166unsafe impl<T: IoVectoredBuf, S: AsFd> OpCode for SendVectored<T, S> {
167    type Control = SendVectoredControl;
168
169    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
170        self.init_control(ctrl)
171    }
172
173    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
174        opcode::SendMsg::new(Fd(self.fd.as_fd().as_raw_fd()), &control.msg)
175            .flags(self.flags.bits() as _)
176            .build()
177            .into()
178    }
179
180    fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
181        self.call(control)
182    }
183}
184
185unsafe impl<T: IoBuf, S: AsFd> OpCode for SendTo<T, S> {
186    type Control = SendMsgControl;
187
188    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
189        self.header.create_control(ctrl, [self.buffer.sys_slice()])
190    }
191
192    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
193        opcode::SendMsg::new(Fd(self.header.fd.as_fd().as_raw_fd()), &control.msg)
194            .flags(self.header.flags.bits() as _)
195            .build()
196            .into()
197    }
198
199    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
200        self.call()
201    }
202}
203
204unsafe impl<T: IoVectoredBuf, S: AsFd> OpCode for SendToVectored<T, S> {
205    type Control = SendMsgControl;
206
207    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
208        self.header
209            .create_control(ctrl, self.buffer.sys_slices::<Multi<_>>())
210    }
211
212    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
213        opcode::SendMsg::new(Fd(self.header.fd.as_fd().as_raw_fd()), &control.msg)
214            .flags(self.header.flags.bits() as _)
215            .build()
216            .into()
217    }
218
219    fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
220        self.call(control)
221    }
222}
223
224unsafe impl<T: IoVectoredBuf, C: IoBuf, S: AsFd> OpCode for SendMsg<T, C, S> {
225    type Control = SendMsgControl;
226
227    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
228        self.init_control(ctrl)
229    }
230
231    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
232        opcode::SendMsg::new(Fd(self.fd.as_fd().as_raw_fd()), &control.msg)
233            .flags(self.flags.bits() as _)
234            .build()
235            .into()
236    }
237
238    fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
239        self.call(control)
240    }
241}
242
243unsafe impl<T: IoBufMut, S: AsSocketState> OpCode for Recv<T, S> {
244    type Control = ();
245
246    fn create_entry(&mut self, _: &mut Self::Control) -> OpEntry {
247        let fd = self.fd.as_fd().as_raw_fd();
248        let slice = self.buffer.sys_slice_mut();
249
250        let entry = opcode::Recv::new(
251            Fd(fd),
252            slice.ptr() as _,
253            slice.len().try_into().unwrap_or(u32::MAX),
254        )
255        .flags(self.flags.bits() as _)
256        .build();
257        let entry = set_poll_first(entry, self.fd.recv_poll_first());
258        entry.into()
259    }
260
261    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
262        self.call()
263    }
264}
265
266unsafe impl<T: IoVectoredBufMut, S: AsSocketState> OpCode for RecvVectored<T, S> {
267    type Control = RecvVectoredControl;
268
269    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
270        self.init_control(ctrl)
271    }
272
273    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
274        let entry = opcode::RecvMsg::new(Fd(self.fd.as_fd().as_raw_fd()), &mut control.msg)
275            .flags(self.flags.bits() as _)
276            .build();
277        let entry = set_poll_first(entry, self.fd.recv_poll_first());
278        entry.into()
279    }
280
281    fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
282        self.call(control)
283    }
284}
285
286impl<S: AsSocketState> RecvFromHeader<S> {
287    pub fn create_control(
288        &mut self,
289        ctrl: &mut RecvMsgControl,
290        slices: impl Into<Multi<SysSlice>>,
291    ) {
292        ctrl.msg.msg_name = &raw mut self.addr as _;
293        ctrl.msg.msg_namelen = self.addr.size_of() as _;
294        ctrl.slices = slices.into();
295        ctrl.msg.msg_iov = ctrl.slices.as_mut_ptr().cast();
296        ctrl.msg.msg_iovlen = ctrl.slices.len() as _;
297    }
298
299    pub fn create_entry(&mut self, control: &mut RecvMsgControl) -> OpEntry {
300        let entry = opcode::RecvMsg::new(Fd(self.fd.as_fd().as_raw_fd()), &mut control.msg)
301            .flags(self.flags.bits() as _)
302            .build();
303        let entry = set_poll_first(entry, self.fd.recv_poll_first());
304        entry.into()
305    }
306
307    pub fn set_result(&mut self, control: &mut RecvMsgControl) {
308        self.addr_len = control.msg.msg_namelen;
309    }
310}
311
312unsafe impl<T: IoBufMut, S: AsSocketState> OpCode for RecvFrom<T, S> {
313    type Control = RecvMsgControl;
314
315    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
316        self.header
317            .create_control(ctrl, [self.buffer.sys_slice_mut()])
318    }
319
320    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
321        self.header.create_entry(control)
322    }
323
324    unsafe fn set_result(
325        &mut self,
326        control: &mut Self::Control,
327        _: &io::Result<usize>,
328        _: &crate::Extra,
329    ) {
330        self.header.set_result(control);
331    }
332
333    fn call_blocking(&mut self, _: &mut Self::Control) -> io::Result<usize> {
334        self.call()
335    }
336}
337
338unsafe impl<T: IoVectoredBufMut, S: AsSocketState> OpCode for RecvFromVectored<T, S> {
339    type Control = RecvMsgControl;
340
341    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
342        self.header
343            .create_control(ctrl, self.buffer.sys_slices_mut::<Multi<_>>())
344    }
345
346    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
347        self.header.create_entry(control)
348    }
349
350    unsafe fn set_result(
351        &mut self,
352        control: &mut Self::Control,
353        _: &io::Result<usize>,
354        _: &crate::Extra,
355    ) {
356        self.header.set_result(control);
357    }
358
359    fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
360        self.call(control)
361    }
362}
363
364unsafe impl<T: IoVectoredBufMut, C: IoBufMut, S: AsSocketState> OpCode for RecvMsg<T, C, S> {
365    type Control = RecvMsgControl;
366
367    unsafe fn init(&mut self, ctrl: &mut Self::Control) {
368        self.init_control(ctrl)
369    }
370
371    fn create_entry(&mut self, control: &mut Self::Control) -> OpEntry {
372        let entry = opcode::RecvMsg::new(Fd(self.header.fd.as_fd().as_raw_fd()), &mut control.msg)
373            .flags(self.header.flags.bits() as _)
374            .build();
375        let entry = set_poll_first(entry, self.header.fd.recv_poll_first());
376        entry.into()
377    }
378
379    unsafe fn set_result(
380        &mut self,
381        control: &mut Self::Control,
382        _: &io::Result<usize>,
383        _: &crate::Extra,
384    ) {
385        self.update_control(control);
386    }
387
388    fn call_blocking(&mut self, control: &mut Self::Control) -> io::Result<usize> {
389        self.call(control)
390    }
391}