s2n_quic_platform/message/
mmsg.rs

1// Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
2// SPDX-License-Identifier: Apache-2.0
3
4use crate::message::{msg, Message as MessageTrait};
5use libc::mmsghdr;
6use s2n_quic_core::{io::tx, path};
7
8pub use libc::mmsghdr as Message;
9pub type Handle = msg::Handle;
10
11impl MessageTrait for mmsghdr {
12    type Handle = Handle;
13
14    const SUPPORTS_GSO: bool = libc::msghdr::SUPPORTS_GSO;
15    const SUPPORTS_ECN: bool = libc::msghdr::SUPPORTS_ECN;
16    const SUPPORTS_FLOW_LABELS: bool = libc::msghdr::SUPPORTS_FLOW_LABELS;
17
18    #[inline]
19    fn alloc(entries: u32, payload_len: u32, offset: usize) -> super::Storage {
20        unsafe {
21            msg::alloc(entries, payload_len, offset, |mmsghdr: &mut mmsghdr| {
22                mmsghdr.msg_len = payload_len as _;
23                &mut mmsghdr.msg_hdr
24            })
25        }
26    }
27
28    #[inline]
29    fn payload_len(&self) -> usize {
30        let payload_len = self.msg_len as usize;
31        debug_assert!(payload_len <= u16::MAX as usize);
32        payload_len
33    }
34
35    #[inline]
36    unsafe fn set_payload_len(&mut self, len: usize) {
37        debug_assert!(len <= u16::MAX as usize);
38        self.msg_len = len as _;
39        self.msg_hdr.set_payload_len(len);
40    }
41
42    #[inline]
43    fn set_segment_size(&mut self, size: usize) {
44        self.msg_hdr.set_segment_size(size)
45    }
46
47    #[inline]
48    unsafe fn reset(&mut self, mtu: usize) {
49        self.set_payload_len(mtu);
50        self.msg_hdr.reset(mtu)
51    }
52
53    #[inline]
54    fn payload_ptr_mut(&mut self) -> *mut u8 {
55        self.msg_hdr.payload_ptr_mut()
56    }
57
58    #[inline]
59    fn validate_replication(source: &Self, dest: &Self) {
60        libc::msghdr::validate_replication(&source.msg_hdr, &dest.msg_hdr)
61    }
62
63    #[inline]
64    fn rx_read(
65        &mut self,
66        local_address: &path::LocalAddress,
67    ) -> Option<super::RxMessage<'_, Self::Handle>> {
68        unsafe {
69            // We need to replicate the `msg_len` field to the inner type before delegating
70            // Safety: The `msg_len` is associated with the same buffer as the `msg_hdr`
71            self.msg_hdr.set_payload_len(self.msg_len as _);
72        }
73        self.msg_hdr.rx_read(local_address)
74    }
75
76    #[inline]
77    fn tx_write<M: tx::Message<Handle = Self::Handle>>(
78        &mut self,
79        message: M,
80    ) -> Result<usize, tx::Error> {
81        let len = self.msg_hdr.tx_write(message)?;
82        // We need to replicate the len with the `msg_len` field after delegating to `msg_hdr`
83        debug_assert!(len <= u16::MAX as usize);
84        self.msg_len = len as _;
85        Ok(len)
86    }
87}