Skip to main content

dope_core/backend/uring/platform/
gso.rs

1use crate::io::socket::msg::MsgHdr;
2use libc::CMSG_DATA;
3use libc::CMSG_FIRSTHDR;
4use libc::CMSG_LEN;
5use libc::CMSG_SPACE;
6use libc::SOL_UDP;
7use libc::UDP_SEGMENT;
8use std::ptr::addr_of;
9use std::ptr::copy_nonoverlapping;
10
11pub const MAX_GSO_SEGMENTS: usize = 64;
12pub const MAX_GSO_BYTES: usize = 65535;
13
14#[derive(Default)]
15#[repr(C, align(8))]
16pub struct Gso([u8; 32]);
17
18impl Gso {
19    pub const fn new() -> Self {
20        Self([0; 32])
21    }
22
23    pub fn attach(&mut self, msg: &mut MsgHdr, segment_size: u16) {
24        if segment_size == 0 {
25            return;
26        }
27        const DATA_LEN: u32 = size_of::<u16>() as u32;
28        let (buf, cap) = (self.0.as_mut_ptr(), self.0.len());
29        unsafe {
30            let controllen = CMSG_SPACE(DATA_LEN) as usize;
31            debug_assert!(controllen <= cap);
32            msg.set_control(buf.cast(), controllen);
33            let hdr = CMSG_FIRSTHDR(msg.raw());
34            (*hdr).cmsg_level = SOL_UDP;
35            (*hdr).cmsg_type = UDP_SEGMENT;
36            (*hdr).cmsg_len = CMSG_LEN(DATA_LEN) as _;
37            copy_nonoverlapping(
38                addr_of!(segment_size).cast::<u8>(),
39                CMSG_DATA(hdr),
40                DATA_LEN as usize,
41            );
42        }
43    }
44}