s2n_quic_platform/message/
simple.rs1use crate::message::Message as MessageTrait;
5use core::alloc::Layout;
6use s2n_quic_core::{
7 inet::{datagram, SocketAddress},
8 io::tx,
9 path,
10};
11
12#[derive(Clone, Copy, Debug)]
16pub struct Message {
17 address: SocketAddress,
18 payload_ptr: *mut u8,
19 payload_len: usize,
20}
21
22impl Message {
23 #[inline]
24 pub fn remote_address(&self) -> &SocketAddress {
25 &self.address
26 }
27
28 #[inline]
29 pub fn set_remote_address(&mut self, remote_address: &SocketAddress) {
30 let remote_address = *remote_address;
31
32 self.address = remote_address;
33 }
34}
35
36pub type Handle = path::Tuple;
37
38impl MessageTrait for Message {
39 type Handle = Handle;
40
41 const SUPPORTS_GSO: bool = false;
42 const SUPPORTS_ECN: bool = false;
43 const SUPPORTS_FLOW_LABELS: bool = false;
44
45 #[inline]
46 fn alloc(entries: u32, payload_len: u32, offset: usize) -> super::Storage {
47 unsafe { alloc(entries, payload_len, offset) }
48 }
49
50 #[inline]
51 fn payload_len(&self) -> usize {
52 self.payload_len
53 }
54
55 #[inline]
56 unsafe fn set_payload_len(&mut self, len: usize) {
57 self.payload_len = len;
58 }
59
60 #[inline]
61 unsafe fn reset(&mut self, mtu: usize) {
62 self.set_payload_len(mtu)
63 }
64
65 #[inline]
66 fn payload_ptr_mut(&mut self) -> *mut u8 {
67 self.payload_ptr
68 }
69
70 #[inline]
71 fn validate_replication(source: &Self, dest: &Self) {
72 assert_eq!(source.payload_ptr, dest.payload_ptr);
73 }
74
75 #[inline]
76 fn rx_read(
77 &mut self,
78 local_address: &path::LocalAddress,
79 ) -> Option<super::RxMessage<'_, Self::Handle>> {
80 let path = path::Tuple {
81 remote_address: self.address.into(),
82 local_address: *local_address,
83 };
84 let header = datagram::Header {
85 path,
86 ecn: Default::default(),
87 };
88 let payload = self.payload_mut();
89
90 let message = super::RxMessage {
91 header,
92 segment_size: payload.len(),
93 payload,
94 };
95
96 Some(message)
97 }
98
99 #[inline]
100 fn tx_write<M: tx::Message<Handle = Self::Handle>>(
101 &mut self,
102 mut message: M,
103 ) -> Result<usize, tx::Error> {
104 let payload = self.payload_mut();
105
106 let len = message.write_payload(tx::PayloadBuffer::new(payload), 0)?;
107
108 unsafe {
109 debug_assert!(len <= payload.len());
110 let len = len.min(payload.len());
111 self.set_payload_len(len);
112 }
113
114 let remote_address = message.path_handle().remote_address;
115 self.address = remote_address.0;
116
117 Ok(len)
118 }
119}
120
121#[inline]
122unsafe fn alloc(entries: u32, payload_len: u32, offset: usize) -> super::Storage {
123 let (layout, entry_offset, payload_offset) = layout(entries, payload_len, offset);
124
125 let storage = super::Storage::new(layout);
126
127 {
128 let ptr = storage.as_ptr();
129
130 let mut entry_ptr = ptr.add(entry_offset) as *mut Message;
131 let mut payload_ptr = ptr.add(payload_offset);
132 for _ in 0..entries {
133 let entry = &mut *entry_ptr;
134 entry.payload_ptr = payload_ptr;
135 entry.payload_len = payload_len as _;
136
137 entry_ptr = entry_ptr.add(1);
138 payload_ptr = payload_ptr.add(payload_len as _);
139 storage.check_bounds(entry_ptr);
140 storage.check_bounds(payload_ptr);
141 }
142
143 let primary = ptr.add(entry_offset) as *mut Message;
144 let secondary = primary.add(entries as _);
145 storage.check_bounds(secondary.add(entries as _));
146 core::ptr::copy_nonoverlapping(primary, secondary, entries as _);
147 }
148
149 storage
150}
151
152fn layout(entries: u32, payload_len: u32, offset: usize) -> (Layout, usize, usize) {
153 let cursor = Layout::array::<u8>(offset).unwrap();
154 let payloads = Layout::array::<u8>(entries as usize * payload_len as usize).unwrap();
155 let entries = Layout::array::<Message>((entries * 2) as usize).unwrap();
156 let (layout, entry_offset) = cursor.extend(entries).unwrap();
157 let (layout, payload_offset) = layout.extend(payloads).unwrap();
158 (layout, entry_offset, payload_offset)
159}