fragmentation.rs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362
  1. #![allow(unused)]
  2. use core::fmt;
  3. use managed::{ManagedMap, ManagedSlice};
  4. use crate::storage::Assembler;
  5. use crate::time::{Duration, Instant};
  6. // TODO: make configurable.
  7. const BUFFER_SIZE: usize = 1500;
  8. #[cfg(feature = "alloc")]
  9. type Buffer = alloc::vec::Vec<u8>;
  10. #[cfg(not(feature = "alloc"))]
  11. type Buffer = [u8; BUFFER_SIZE];
  12. const PACKET_ASSEMBLER_COUNT: usize = 4;
  13. /// Problem when assembling: something was out of bounds.
  14. #[derive(Copy, Clone, PartialEq, Eq, Debug)]
  15. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  16. pub struct AssemblerError;
  17. /// Packet assembler is full
  18. #[derive(Copy, Clone, PartialEq, Eq, Debug)]
  19. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  20. pub struct AssemblerFullError;
  21. /// Holds different fragments of one packet, used for assembling fragmented packets.
  22. ///
  23. /// The buffer used for the `PacketAssembler` should either be dynamically sized (ex: Vec<u8>)
  24. /// or should be statically allocated based upon the MTU of the type of packet being
  25. /// assembled (ex: 1280 for a IPv6 frame).
  26. #[derive(Debug)]
  27. pub struct PacketAssembler<K> {
  28. key: Option<K>,
  29. buffer: Buffer,
  30. assembler: Assembler,
  31. total_size: Option<usize>,
  32. expires_at: Instant,
  33. offset_correction: isize,
  34. }
  35. impl<K> PacketAssembler<K> {
  36. /// Create a new empty buffer for fragments.
  37. pub fn new() -> Self {
  38. Self {
  39. key: None,
  40. #[cfg(feature = "alloc")]
  41. buffer: Buffer::new(),
  42. #[cfg(not(feature = "alloc"))]
  43. buffer: [0u8; BUFFER_SIZE],
  44. assembler: Assembler::new(),
  45. total_size: None,
  46. expires_at: Instant::ZERO,
  47. offset_correction: 0,
  48. }
  49. }
  50. pub(crate) fn reset(&mut self) {
  51. self.key = None;
  52. self.assembler.clear();
  53. self.total_size = None;
  54. self.expires_at = Instant::ZERO;
  55. self.offset_correction = 0;
  56. }
  57. pub(crate) fn set_offset_correction(&mut self, correction: isize) {
  58. self.offset_correction = correction;
  59. }
  60. /// Set the total size of the packet assembler.
  61. pub(crate) fn set_total_size(&mut self, size: usize) -> Result<(), AssemblerError> {
  62. if let Some(old_size) = self.total_size {
  63. if old_size != size {
  64. return Err(AssemblerError);
  65. }
  66. }
  67. #[cfg(not(feature = "alloc"))]
  68. if self.buffer.len() < size {
  69. return Err(AssemblerError);
  70. }
  71. #[cfg(feature = "alloc")]
  72. if self.buffer.len() < size {
  73. self.buffer.resize(size, 0);
  74. }
  75. self.total_size = Some(size);
  76. Ok(())
  77. }
  78. /// Return the instant when the assembler expires.
  79. pub(crate) fn expires_at(&self) -> Instant {
  80. self.expires_at
  81. }
  82. pub(crate) fn add_with(
  83. &mut self,
  84. offset: usize,
  85. f: impl Fn(&mut [u8]) -> Result<usize, AssemblerError>,
  86. ) -> Result<(), AssemblerError> {
  87. if self.buffer.len() < offset {
  88. return Err(AssemblerError);
  89. }
  90. let len = f(&mut self.buffer[offset..])?;
  91. assert!(offset + len <= self.buffer.len());
  92. net_debug!(
  93. "frag assembler: receiving {} octets at offset {}",
  94. len,
  95. offset
  96. );
  97. match self.assembler.add(offset, len) {
  98. Ok(()) => {
  99. net_debug!("assembler: {}", self.assembler);
  100. Ok(())
  101. }
  102. Err(_) => {
  103. net_debug!("packet assembler: too many holes, dropping.");
  104. Err(AssemblerError)
  105. }
  106. }
  107. }
  108. /// Add a fragment into the packet that is being reassembled.
  109. ///
  110. /// # Errors
  111. ///
  112. /// - Returns [`Error::PacketAssemblerBufferTooSmall`] when trying to add data into the buffer at a non-existing
  113. /// place.
  114. pub(crate) fn add(&mut self, data: &[u8], offset: usize) -> Result<(), AssemblerError> {
  115. let offset = offset as isize + self.offset_correction;
  116. let offset = if offset <= 0 { 0 } else { offset as usize };
  117. #[cfg(not(feature = "alloc"))]
  118. if self.buffer.len() < offset + data.len() {
  119. return Err(AssemblerError);
  120. }
  121. #[cfg(feature = "alloc")]
  122. if self.buffer.len() < offset + data.len() {
  123. self.buffer.resize(offset + data.len(), 0);
  124. }
  125. let len = data.len();
  126. self.buffer[offset..][..len].copy_from_slice(data);
  127. net_debug!(
  128. "frag assembler: receiving {} octets at offset {}",
  129. len,
  130. offset
  131. );
  132. match self.assembler.add(offset, data.len()) {
  133. Ok(()) => {
  134. net_debug!("assembler: {}", self.assembler);
  135. Ok(())
  136. }
  137. Err(_) => {
  138. net_debug!("packet assembler: too many holes, dropping.");
  139. Err(AssemblerError)
  140. }
  141. }
  142. }
  143. /// Get an immutable slice of the underlying packet data, if reassembly complete.
  144. /// This will mark the assembler as empty, so that it can be reused.
  145. pub(crate) fn assemble(&mut self) -> Option<&'_ [u8]> {
  146. if !self.is_complete() {
  147. return None;
  148. }
  149. // NOTE: we can unwrap because `is_complete` already checks this.
  150. let total_size = self.total_size.unwrap();
  151. self.reset();
  152. Some(&self.buffer[..total_size])
  153. }
  154. /// Returns `true` when all fragments have been received, otherwise `false`.
  155. pub(crate) fn is_complete(&self) -> bool {
  156. self.total_size == Some(self.assembler.peek_front())
  157. }
  158. /// Returns `true` when the packet assembler is free to use.
  159. fn is_free(&self) -> bool {
  160. self.key.is_none()
  161. }
  162. }
  163. /// Set holding multiple [`PacketAssembler`].
  164. #[derive(Debug)]
  165. pub struct PacketAssemblerSet<K: Eq + Copy> {
  166. assemblers: [PacketAssembler<K>; PACKET_ASSEMBLER_COUNT],
  167. }
  168. impl<K: Eq + Copy> PacketAssemblerSet<K> {
  169. /// Create a new set of packet assemblers.
  170. pub fn new() -> Self {
  171. Self {
  172. // TODO: support any PACKET_ASSEMBLER_COUNT
  173. assemblers: [
  174. PacketAssembler::new(),
  175. PacketAssembler::new(),
  176. PacketAssembler::new(),
  177. PacketAssembler::new(),
  178. ],
  179. }
  180. }
  181. /// Get a [`PacketAssembler`] for a specific key.
  182. ///
  183. /// If it doesn't exist, it is created, with the `expires_at` timestamp.
  184. ///
  185. /// If the assembler set is full, in which case an error is returned.
  186. pub(crate) fn get(
  187. &mut self,
  188. key: &K,
  189. expires_at: Instant,
  190. ) -> Result<&mut PacketAssembler<K>, AssemblerFullError> {
  191. let mut empty_slot = None;
  192. for slot in &mut self.assemblers {
  193. if slot.key.as_ref() == Some(key) {
  194. return Ok(slot);
  195. }
  196. if slot.is_free() {
  197. empty_slot = Some(slot)
  198. }
  199. }
  200. let slot = empty_slot.ok_or(AssemblerFullError)?;
  201. slot.key = Some(*key);
  202. slot.expires_at = expires_at;
  203. Ok(slot)
  204. }
  205. /// Remove all [`PacketAssembler`]s that are expired.
  206. pub fn remove_expired(&mut self, timestamp: Instant) {
  207. for frag in &mut self.assemblers {
  208. if !frag.is_free() && frag.expires_at < timestamp {
  209. frag.reset();
  210. }
  211. }
  212. }
  213. }
  214. #[cfg(test)]
  215. mod tests {
  216. use super::*;
  217. #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  218. struct Key {
  219. id: usize,
  220. }
  221. #[test]
  222. fn packet_assembler_overlap() {
  223. let mut p_assembler = PacketAssembler::<Key>::new();
  224. p_assembler.set_total_size(5).unwrap();
  225. let data = b"Rust";
  226. p_assembler.add(&data[..], 0);
  227. p_assembler.add(&data[..], 1);
  228. assert_eq!(p_assembler.assemble(), Some(&b"RRust"[..]))
  229. }
  230. #[test]
  231. fn packet_assembler_assemble() {
  232. let mut p_assembler = PacketAssembler::<Key>::new();
  233. let data = b"Hello World!";
  234. p_assembler.set_total_size(data.len()).unwrap();
  235. p_assembler.add(b"Hello ", 0).unwrap();
  236. assert_eq!(p_assembler.assemble(), None);
  237. p_assembler.add(b"World!", b"Hello ".len()).unwrap();
  238. assert_eq!(p_assembler.assemble(), Some(&b"Hello World!"[..]));
  239. }
  240. #[test]
  241. fn packet_assembler_out_of_order_assemble() {
  242. let mut p_assembler = PacketAssembler::<Key>::new();
  243. let data = b"Hello World!";
  244. p_assembler.set_total_size(data.len()).unwrap();
  245. p_assembler.add(b"World!", b"Hello ".len()).unwrap();
  246. assert_eq!(p_assembler.assemble(), None);
  247. p_assembler.add(b"Hello ", 0).unwrap();
  248. assert_eq!(p_assembler.assemble(), Some(&b"Hello World!"[..]));
  249. }
  250. #[test]
  251. fn packet_assembler_set() {
  252. let key = Key { id: 1 };
  253. let mut set = PacketAssemblerSet::new();
  254. assert!(set.get(&key, Instant::ZERO).is_ok());
  255. }
  256. #[test]
  257. fn packet_assembler_set_full() {
  258. let mut set = PacketAssemblerSet::new();
  259. set.get(&Key { id: 0 }, Instant::ZERO).unwrap();
  260. set.get(&Key { id: 1 }, Instant::ZERO).unwrap();
  261. set.get(&Key { id: 2 }, Instant::ZERO).unwrap();
  262. set.get(&Key { id: 3 }, Instant::ZERO).unwrap();
  263. assert!(set.get(&Key { id: 4 }, Instant::ZERO).is_err());
  264. }
  265. #[test]
  266. fn packet_assembler_set_assembling_many() {
  267. let mut set = PacketAssemblerSet::new();
  268. let key = Key { id: 0 };
  269. let assr = set.get(&key, Instant::ZERO).unwrap();
  270. assert_eq!(assr.assemble(), None);
  271. assr.set_total_size(0).unwrap();
  272. assr.assemble().unwrap();
  273. // Test that `.assemble()` effectively deletes it.
  274. let assr = set.get(&key, Instant::ZERO).unwrap();
  275. assert_eq!(assr.assemble(), None);
  276. assr.set_total_size(0).unwrap();
  277. assr.assemble().unwrap();
  278. let key = Key { id: 1 };
  279. let assr = set.get(&key, Instant::ZERO).unwrap();
  280. assr.set_total_size(0).unwrap();
  281. assr.assemble().unwrap();
  282. let key = Key { id: 2 };
  283. let assr = set.get(&key, Instant::ZERO).unwrap();
  284. assr.set_total_size(0).unwrap();
  285. assr.assemble().unwrap();
  286. let key = Key { id: 2 };
  287. let assr = set.get(&key, Instant::ZERO).unwrap();
  288. assr.set_total_size(2).unwrap();
  289. assr.add(&[0x00], 0).unwrap();
  290. assert_eq!(assr.assemble(), None);
  291. let assr = set.get(&key, Instant::ZERO).unwrap();
  292. assr.add(&[0x01], 1).unwrap();
  293. assert_eq!(assr.assemble(), Some(&[0x00, 0x01][..]));
  294. }
  295. }