fragmentation.rs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506
  1. #![allow(unused)]
  2. use core::fmt;
  3. use managed::{ManagedMap, ManagedSlice};
  4. use crate::config::{FRAGMENTATION_BUFFER_SIZE, REASSEMBLY_BUFFER_COUNT, REASSEMBLY_BUFFER_SIZE};
  5. use crate::storage::Assembler;
  6. use crate::time::{Duration, Instant};
  7. use crate::wire::*;
  8. use core::result::Result;
  9. #[cfg(feature = "alloc")]
  10. type Buffer = alloc::vec::Vec<u8>;
  11. #[cfg(not(feature = "alloc"))]
  12. type Buffer = [u8; REASSEMBLY_BUFFER_SIZE];
  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. impl fmt::Display for AssemblerError {
  18. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  19. write!(f, "AssemblerError")
  20. }
  21. }
  22. #[cfg(feature = "std")]
  23. impl std::error::Error for AssemblerError {}
  24. /// Packet assembler is full
  25. #[derive(Copy, Clone, PartialEq, Eq, Debug)]
  26. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  27. pub struct AssemblerFullError;
  28. impl fmt::Display for AssemblerFullError {
  29. fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
  30. write!(f, "AssemblerFullError")
  31. }
  32. }
  33. #[cfg(feature = "std")]
  34. impl std::error::Error for AssemblerFullError {}
  35. /// Holds different fragments of one packet, used for assembling fragmented packets.
  36. ///
  37. /// The buffer used for the `PacketAssembler` should either be dynamically sized (ex: Vec<u8>)
  38. /// or should be statically allocated based upon the MTU of the type of packet being
  39. /// assembled (ex: 1280 for a IPv6 frame).
  40. #[derive(Debug)]
  41. pub struct PacketAssembler<K> {
  42. key: Option<K>,
  43. buffer: Buffer,
  44. assembler: Assembler,
  45. total_size: Option<usize>,
  46. expires_at: Instant,
  47. }
  48. impl<K> PacketAssembler<K> {
  49. /// Create a new empty buffer for fragments.
  50. pub const fn new() -> Self {
  51. Self {
  52. key: None,
  53. #[cfg(feature = "alloc")]
  54. buffer: Buffer::new(),
  55. #[cfg(not(feature = "alloc"))]
  56. buffer: [0u8; REASSEMBLY_BUFFER_SIZE],
  57. assembler: Assembler::new(),
  58. total_size: None,
  59. expires_at: Instant::ZERO,
  60. }
  61. }
  62. pub(crate) fn reset(&mut self) {
  63. self.key = None;
  64. self.assembler.clear();
  65. self.total_size = None;
  66. self.expires_at = Instant::ZERO;
  67. }
  68. /// Set the total size of the packet assembler.
  69. pub(crate) fn set_total_size(&mut self, size: usize) -> Result<(), AssemblerError> {
  70. if let Some(old_size) = self.total_size {
  71. if old_size != size {
  72. return Err(AssemblerError);
  73. }
  74. }
  75. #[cfg(not(feature = "alloc"))]
  76. if self.buffer.len() < size {
  77. return Err(AssemblerError);
  78. }
  79. #[cfg(feature = "alloc")]
  80. if self.buffer.len() < size {
  81. self.buffer.resize(size, 0);
  82. }
  83. self.total_size = Some(size);
  84. Ok(())
  85. }
  86. /// Return the instant when the assembler expires.
  87. pub(crate) fn expires_at(&self) -> Instant {
  88. self.expires_at
  89. }
  90. pub(crate) fn add_with(
  91. &mut self,
  92. offset: usize,
  93. f: impl Fn(&mut [u8]) -> Result<usize, AssemblerError>,
  94. ) -> Result<(), AssemblerError> {
  95. if self.buffer.len() < offset {
  96. return Err(AssemblerError);
  97. }
  98. let len = f(&mut self.buffer[offset..])?;
  99. assert!(offset + len <= self.buffer.len());
  100. net_debug!(
  101. "frag assembler: receiving {} octets at offset {}",
  102. len,
  103. offset
  104. );
  105. self.assembler.add(offset, len);
  106. Ok(())
  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. #[cfg(not(feature = "alloc"))]
  116. if self.buffer.len() < offset + data.len() {
  117. return Err(AssemblerError);
  118. }
  119. #[cfg(feature = "alloc")]
  120. if self.buffer.len() < offset + data.len() {
  121. self.buffer.resize(offset + data.len(), 0);
  122. }
  123. let len = data.len();
  124. self.buffer[offset..][..len].copy_from_slice(data);
  125. net_debug!(
  126. "frag assembler: receiving {} octets at offset {}",
  127. len,
  128. offset
  129. );
  130. self.assembler.add(offset, data.len());
  131. Ok(())
  132. }
  133. /// Get an immutable slice of the underlying packet data, if reassembly complete.
  134. /// This will mark the assembler as empty, so that it can be reused.
  135. pub(crate) fn assemble(&mut self) -> Option<&'_ [u8]> {
  136. if !self.is_complete() {
  137. return None;
  138. }
  139. // NOTE: we can unwrap because `is_complete` already checks this.
  140. let total_size = self.total_size.unwrap();
  141. self.reset();
  142. Some(&self.buffer[..total_size])
  143. }
  144. /// Returns `true` when all fragments have been received, otherwise `false`.
  145. pub(crate) fn is_complete(&self) -> bool {
  146. self.total_size == Some(self.assembler.peek_front())
  147. }
  148. /// Returns `true` when the packet assembler is free to use.
  149. fn is_free(&self) -> bool {
  150. self.key.is_none()
  151. }
  152. }
  153. /// Set holding multiple [`PacketAssembler`].
  154. #[derive(Debug)]
  155. pub struct PacketAssemblerSet<K: Eq + Copy> {
  156. assemblers: [PacketAssembler<K>; REASSEMBLY_BUFFER_COUNT],
  157. }
  158. impl<K: Eq + Copy> PacketAssemblerSet<K> {
  159. const NEW_PA: PacketAssembler<K> = PacketAssembler::new();
  160. /// Create a new set of packet assemblers.
  161. pub fn new() -> Self {
  162. Self {
  163. assemblers: [Self::NEW_PA; REASSEMBLY_BUFFER_COUNT],
  164. }
  165. }
  166. /// Get a [`PacketAssembler`] for a specific key.
  167. ///
  168. /// If it doesn't exist, it is created, with the `expires_at` timestamp.
  169. ///
  170. /// If the assembler set is full, in which case an error is returned.
  171. pub(crate) fn get(
  172. &mut self,
  173. key: &K,
  174. expires_at: Instant,
  175. ) -> Result<&mut PacketAssembler<K>, AssemblerFullError> {
  176. let mut empty_slot = None;
  177. for slot in &mut self.assemblers {
  178. if slot.key.as_ref() == Some(key) {
  179. return Ok(slot);
  180. }
  181. if slot.is_free() {
  182. empty_slot = Some(slot)
  183. }
  184. }
  185. let slot = empty_slot.ok_or(AssemblerFullError)?;
  186. slot.key = Some(*key);
  187. slot.expires_at = expires_at;
  188. Ok(slot)
  189. }
  190. /// Remove all [`PacketAssembler`]s that are expired.
  191. pub fn remove_expired(&mut self, timestamp: Instant) {
  192. for frag in &mut self.assemblers {
  193. if !frag.is_free() && frag.expires_at < timestamp {
  194. frag.reset();
  195. }
  196. }
  197. }
  198. }
  199. // Max len of non-fragmented packets after decompression (including ipv6 header and payload)
  200. // TODO: lower. Should be (6lowpan mtu) - (min 6lowpan header size) + (max ipv6 header size)
  201. pub(crate) const MAX_DECOMPRESSED_LEN: usize = 1500;
  202. #[cfg(feature = "_proto-fragmentation")]
  203. #[derive(Debug, Eq, PartialEq, Ord, PartialOrd, Clone, Copy)]
  204. #[cfg_attr(feature = "defmt", derive(defmt::Format))]
  205. pub(crate) enum FragKey {
  206. #[cfg(feature = "proto-ipv4-fragmentation")]
  207. Ipv4(Ipv4FragKey),
  208. #[cfg(feature = "proto-sixlowpan-fragmentation")]
  209. Sixlowpan(SixlowpanFragKey),
  210. }
  211. pub(crate) struct FragmentsBuffer {
  212. #[cfg(feature = "proto-sixlowpan")]
  213. pub decompress_buf: [u8; MAX_DECOMPRESSED_LEN],
  214. #[cfg(feature = "_proto-fragmentation")]
  215. pub assembler: PacketAssemblerSet<FragKey>,
  216. #[cfg(feature = "_proto-fragmentation")]
  217. pub reassembly_timeout: Duration,
  218. }
  219. #[cfg(not(feature = "_proto-fragmentation"))]
  220. pub(crate) struct Fragmenter {}
  221. #[cfg(not(feature = "_proto-fragmentation"))]
  222. impl Fragmenter {
  223. pub(crate) fn new() -> Self {
  224. Self {}
  225. }
  226. }
  227. #[cfg(feature = "_proto-fragmentation")]
  228. pub(crate) struct Fragmenter {
  229. /// The buffer that holds the unfragmented 6LoWPAN packet.
  230. pub buffer: [u8; FRAGMENTATION_BUFFER_SIZE],
  231. /// The size of the packet without the IEEE802.15.4 header and the fragmentation headers.
  232. pub packet_len: usize,
  233. /// The amount of bytes that already have been transmitted.
  234. pub sent_bytes: usize,
  235. #[cfg(feature = "proto-ipv4-fragmentation")]
  236. pub ipv4: Ipv4Fragmenter,
  237. #[cfg(feature = "proto-sixlowpan-fragmentation")]
  238. pub sixlowpan: SixlowpanFragmenter,
  239. }
  240. #[cfg(feature = "proto-ipv4-fragmentation")]
  241. pub(crate) struct Ipv4Fragmenter {
  242. /// The IPv4 representation.
  243. pub repr: Ipv4Repr,
  244. /// The destination hardware address.
  245. #[cfg(feature = "medium-ethernet")]
  246. pub dst_hardware_addr: EthernetAddress,
  247. /// The offset of the next fragment.
  248. pub frag_offset: u16,
  249. /// The identifier of the stream.
  250. pub ident: u16,
  251. }
  252. #[cfg(feature = "proto-sixlowpan-fragmentation")]
  253. pub(crate) struct SixlowpanFragmenter {
  254. /// The datagram size that is used for the fragmentation headers.
  255. pub datagram_size: u16,
  256. /// The datagram tag that is used for the fragmentation headers.
  257. pub datagram_tag: u16,
  258. pub datagram_offset: usize,
  259. /// The size of the FRAG_N packets.
  260. pub fragn_size: usize,
  261. /// The link layer IEEE802.15.4 source address.
  262. pub ll_dst_addr: Ieee802154Address,
  263. /// The link layer IEEE802.15.4 source address.
  264. pub ll_src_addr: Ieee802154Address,
  265. }
  266. #[cfg(feature = "_proto-fragmentation")]
  267. impl Fragmenter {
  268. pub(crate) fn new() -> Self {
  269. Self {
  270. buffer: [0u8; FRAGMENTATION_BUFFER_SIZE],
  271. packet_len: 0,
  272. sent_bytes: 0,
  273. #[cfg(feature = "proto-ipv4-fragmentation")]
  274. ipv4: Ipv4Fragmenter {
  275. repr: Ipv4Repr {
  276. src_addr: Ipv4Address::new(0, 0, 0, 0),
  277. dst_addr: Ipv4Address::new(0, 0, 0, 0),
  278. next_header: IpProtocol::Unknown(0),
  279. payload_len: 0,
  280. hop_limit: 0,
  281. },
  282. #[cfg(feature = "medium-ethernet")]
  283. dst_hardware_addr: EthernetAddress::default(),
  284. frag_offset: 0,
  285. ident: 0,
  286. },
  287. #[cfg(feature = "proto-sixlowpan-fragmentation")]
  288. sixlowpan: SixlowpanFragmenter {
  289. datagram_size: 0,
  290. datagram_tag: 0,
  291. datagram_offset: 0,
  292. fragn_size: 0,
  293. ll_dst_addr: Ieee802154Address::Absent,
  294. ll_src_addr: Ieee802154Address::Absent,
  295. },
  296. }
  297. }
  298. /// Return `true` when everything is transmitted.
  299. #[inline]
  300. pub(crate) fn finished(&self) -> bool {
  301. self.packet_len == self.sent_bytes
  302. }
  303. /// Returns `true` when there is nothing to transmit.
  304. #[inline]
  305. pub(crate) fn is_empty(&self) -> bool {
  306. self.packet_len == 0
  307. }
  308. // Reset the buffer.
  309. pub(crate) fn reset(&mut self) {
  310. self.packet_len = 0;
  311. self.sent_bytes = 0;
  312. #[cfg(feature = "proto-ipv4-fragmentation")]
  313. {
  314. self.ipv4.repr = Ipv4Repr {
  315. src_addr: Ipv4Address::new(0, 0, 0, 0),
  316. dst_addr: Ipv4Address::new(0, 0, 0, 0),
  317. next_header: IpProtocol::Unknown(0),
  318. payload_len: 0,
  319. hop_limit: 0,
  320. };
  321. #[cfg(feature = "medium-ethernet")]
  322. {
  323. self.ipv4.dst_hardware_addr = EthernetAddress::default();
  324. }
  325. }
  326. #[cfg(feature = "proto-sixlowpan-fragmentation")]
  327. {
  328. self.sixlowpan.datagram_size = 0;
  329. self.sixlowpan.datagram_tag = 0;
  330. self.sixlowpan.fragn_size = 0;
  331. self.sixlowpan.ll_dst_addr = Ieee802154Address::Absent;
  332. self.sixlowpan.ll_src_addr = Ieee802154Address::Absent;
  333. }
  334. }
  335. }
  336. #[cfg(test)]
  337. mod tests {
  338. use super::*;
  339. #[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy)]
  340. struct Key {
  341. id: usize,
  342. }
  343. #[test]
  344. fn packet_assembler_overlap() {
  345. let mut p_assembler = PacketAssembler::<Key>::new();
  346. p_assembler.set_total_size(5).unwrap();
  347. let data = b"Rust";
  348. p_assembler.add(&data[..], 0);
  349. p_assembler.add(&data[..], 1);
  350. assert_eq!(p_assembler.assemble(), Some(&b"RRust"[..]))
  351. }
  352. #[test]
  353. fn packet_assembler_assemble() {
  354. let mut p_assembler = PacketAssembler::<Key>::new();
  355. let data = b"Hello World!";
  356. p_assembler.set_total_size(data.len()).unwrap();
  357. p_assembler.add(b"Hello ", 0).unwrap();
  358. assert_eq!(p_assembler.assemble(), None);
  359. p_assembler.add(b"World!", b"Hello ".len()).unwrap();
  360. assert_eq!(p_assembler.assemble(), Some(&b"Hello World!"[..]));
  361. }
  362. #[test]
  363. fn packet_assembler_out_of_order_assemble() {
  364. let mut p_assembler = PacketAssembler::<Key>::new();
  365. let data = b"Hello World!";
  366. p_assembler.set_total_size(data.len()).unwrap();
  367. p_assembler.add(b"World!", b"Hello ".len()).unwrap();
  368. assert_eq!(p_assembler.assemble(), None);
  369. p_assembler.add(b"Hello ", 0).unwrap();
  370. assert_eq!(p_assembler.assemble(), Some(&b"Hello World!"[..]));
  371. }
  372. #[test]
  373. fn packet_assembler_set() {
  374. let key = Key { id: 1 };
  375. let mut set = PacketAssemblerSet::new();
  376. assert!(set.get(&key, Instant::ZERO).is_ok());
  377. }
  378. #[test]
  379. fn packet_assembler_set_full() {
  380. let mut set = PacketAssemblerSet::new();
  381. for i in 0..REASSEMBLY_BUFFER_COUNT {
  382. set.get(&Key { id: i }, Instant::ZERO).unwrap();
  383. }
  384. assert!(set.get(&Key { id: 4 }, Instant::ZERO).is_err());
  385. }
  386. #[test]
  387. fn packet_assembler_set_assembling_many() {
  388. let mut set = PacketAssemblerSet::new();
  389. let key = Key { id: 0 };
  390. let assr = set.get(&key, Instant::ZERO).unwrap();
  391. assert_eq!(assr.assemble(), None);
  392. assr.set_total_size(0).unwrap();
  393. assr.assemble().unwrap();
  394. // Test that `.assemble()` effectively deletes it.
  395. let assr = set.get(&key, Instant::ZERO).unwrap();
  396. assert_eq!(assr.assemble(), None);
  397. assr.set_total_size(0).unwrap();
  398. assr.assemble().unwrap();
  399. let key = Key { id: 1 };
  400. let assr = set.get(&key, Instant::ZERO).unwrap();
  401. assr.set_total_size(0).unwrap();
  402. assr.assemble().unwrap();
  403. let key = Key { id: 2 };
  404. let assr = set.get(&key, Instant::ZERO).unwrap();
  405. assr.set_total_size(0).unwrap();
  406. assr.assemble().unwrap();
  407. let key = Key { id: 2 };
  408. let assr = set.get(&key, Instant::ZERO).unwrap();
  409. assr.set_total_size(2).unwrap();
  410. assr.add(&[0x00], 0).unwrap();
  411. assert_eq!(assr.assemble(), None);
  412. let assr = set.get(&key, Instant::ZERO).unwrap();
  413. assr.add(&[0x01], 1).unwrap();
  414. assert_eq!(assr.assemble(), Some(&[0x00, 0x01][..]));
  415. }
  416. }