Skip to content

Commit 0708c1e

Browse files
Merge #648 #649
648: Clarify how to back a PacketAssembler r=Dirbaio a=benbrittain 649: Make the packet fragmentation cache timeout user configurable r=Dirbaio a=benbrittain 60 seconds is a really long time to hold onto these fragments. Since I'm working on a memory constrained microcontroller I can only have so fragmented packets in flight at a given point and it's not uncommon to miss a fragment and then be unable to receive any fragments until this evicts. Co-authored-by: Benjamin Brittain <ben@brittain.org>
3 parents cbe4b6f + 1ec362b + af39d86 commit 0708c1e

File tree

2 files changed

+38
-6
lines changed

2 files changed

+38
-6
lines changed

src/iface/fragmentation.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ use crate::Error;
1010
use crate::Result;
1111

1212
/// Holds different fragments of one packet, used for assembling fragmented packets.
13+
///
14+
/// The buffer used for the `PacketAssembler` should either be dynamically sized (ex: Vec<u8>)
15+
/// or should be statically allocated based upon the MTU of the type of packet being
16+
/// assembled (ex: 1280 for a IPv6 frame).
1317
#[derive(Debug)]
1418
pub struct PacketAssembler<'a> {
1519
buffer: ManagedSlice<'a, u8>,

src/iface/interface.rs

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,8 @@ pub(crate) struct FragmentsBuffer<'a> {
2727
ipv4_fragments: PacketAssemblerSet<'a, Ipv4FragKey>,
2828
#[cfg(feature = "proto-sixlowpan-fragmentation")]
2929
sixlowpan_fragments: PacketAssemblerSet<'a, SixlowpanFragKey>,
30-
30+
#[cfg(feature = "proto-sixlowpan-fragmentation")]
31+
sixlowpan_fragments_cache_timeout: Duration,
3132
#[cfg(not(any(
3233
feature = "proto-ipv4-fragmentation",
3334
feature = "proto-sixlowpan-fragmentation"
@@ -199,6 +200,8 @@ pub struct InterfaceBuilder<'a> {
199200
#[cfg(feature = "proto-sixlowpan-fragmentation")]
200201
sixlowpan_fragments: Option<PacketAssemblerSet<'a, SixlowpanFragKey>>,
201202
#[cfg(feature = "proto-sixlowpan-fragmentation")]
203+
sixlowpan_fragments_cache_timeout: Duration,
204+
#[cfg(feature = "proto-sixlowpan-fragmentation")]
202205
sixlowpan_out_buffer: Option<ManagedSlice<'a, u8>>,
203206
}
204207

@@ -266,6 +269,8 @@ let iface = builder.finalize(&mut device);
266269
#[cfg(feature = "proto-sixlowpan-fragmentation")]
267270
sixlowpan_fragments: None,
268271
#[cfg(feature = "proto-sixlowpan-fragmentation")]
272+
sixlowpan_fragments_cache_timeout: Duration::from_secs(60),
273+
#[cfg(feature = "proto-sixlowpan-fragmentation")]
269274
sixlowpan_out_buffer: None,
270275
}
271276
}
@@ -393,6 +398,15 @@ let iface = builder.finalize(&mut device);
393398
self
394399
}
395400

401+
#[cfg(feature = "proto-sixlowpan-fragmentation")]
402+
pub fn sixlowpan_fragments_cache_timeout(mut self, timeout: Duration) -> Self {
403+
if timeout > Duration::from_secs(60) {
404+
net_debug!("RFC 4944 specifies that the reassembly timeout MUST be set to a maximum of 60 seconds");
405+
}
406+
self.sixlowpan_fragments_cache_timeout = timeout;
407+
self
408+
}
409+
396410
#[cfg(feature = "proto-sixlowpan-fragmentation")]
397411
pub fn sixlowpan_out_packet_cache<T>(mut self, storage: T) -> Self
398412
where
@@ -493,6 +507,8 @@ let iface = builder.finalize(&mut device);
493507
sixlowpan_fragments: self
494508
.sixlowpan_fragments
495509
.expect("Cache for incoming 6LoWPAN fragments is required"),
510+
#[cfg(feature = "proto-sixlowpan-fragmentation")]
511+
sixlowpan_fragments_cache_timeout: self.sixlowpan_fragments_cache_timeout,
496512

497513
#[cfg(not(any(
498514
feature = "proto-ipv4-fragmentation",
@@ -1574,7 +1590,7 @@ impl<'a> InterfaceInner<'a> {
15741590
Some(payload) => {
15751591
cfg_if::cfg_if! {
15761592
if #[cfg(feature = "proto-sixlowpan-fragmentation")] {
1577-
self.process_sixlowpan(sockets, &ieee802154_repr, payload, Some(&mut _fragments.sixlowpan_fragments))
1593+
self.process_sixlowpan(sockets, &ieee802154_repr, payload, Some((&mut _fragments.sixlowpan_fragments, _fragments.sixlowpan_fragments_cache_timeout)))
15781594
} else {
15791595
self.process_sixlowpan(sockets, &ieee802154_repr, payload, None)
15801596
}
@@ -1590,7 +1606,10 @@ impl<'a> InterfaceInner<'a> {
15901606
sockets: &mut SocketSet,
15911607
ieee802154_repr: &Ieee802154Repr,
15921608
payload: &'payload T,
1593-
_fragments: Option<&'output mut PacketAssemblerSet<'a, SixlowpanFragKey>>,
1609+
_fragments: Option<(
1610+
&'output mut PacketAssemblerSet<'a, SixlowpanFragKey>,
1611+
Duration,
1612+
)>,
15941613
) -> Option<IpPacket<'output>> {
15951614
let payload = match check!(SixlowpanPacket::dispatch(payload)) {
15961615
#[cfg(not(feature = "proto-sixlowpan-fragmentation"))]
@@ -1600,7 +1619,7 @@ impl<'a> InterfaceInner<'a> {
16001619
}
16011620
#[cfg(feature = "proto-sixlowpan-fragmentation")]
16021621
SixlowpanPacket::FragmentHeader => {
1603-
let fragments = _fragments.unwrap();
1622+
let (fragments, timeout) = _fragments.unwrap();
16041623

16051624
// We have a fragment header, which means we cannot process the 6LoWPAN packet,
16061625
// unless we have a complete one after processing this fragment.
@@ -1660,12 +1679,21 @@ impl<'a> InterfaceInner<'a> {
16601679
// This information is the total size of the packet when it is fully assmbled.
16611680
// We also pass the header size, since this is needed when other fragments
16621681
// (other than the first one) are added.
1663-
check!(check!(fragments.reserve_with_key(&key)).start(
1682+
let frag_slot = match fragments.reserve_with_key(&key) {
1683+
Ok(frag) => frag,
1684+
Err(Error::PacketAssemblerSetFull) => {
1685+
net_debug!("No available packet assembler for fragmented packet");
1686+
return Default::default();
1687+
}
1688+
e => check!(e),
1689+
};
1690+
1691+
check!(frag_slot.start(
16641692
Some(
16651693
frag.datagram_size() as usize - uncompressed_header_size
16661694
+ compressed_header_size
16671695
),
1668-
self.now + Duration::from_secs(60),
1696+
self.now + timeout,
16691697
-((uncompressed_header_size - compressed_header_size) as isize),
16701698
));
16711699
}

0 commit comments

Comments
 (0)