@@ -27,7 +27,8 @@ pub(crate) struct FragmentsBuffer<'a> {
27
27
ipv4_fragments : PacketAssemblerSet < ' a , Ipv4FragKey > ,
28
28
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
29
29
sixlowpan_fragments : PacketAssemblerSet < ' a , SixlowpanFragKey > ,
30
-
30
+ #[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
31
+ sixlowpan_fragments_cache_timeout : Duration ,
31
32
#[ cfg( not( any(
32
33
feature = "proto-ipv4-fragmentation" ,
33
34
feature = "proto-sixlowpan-fragmentation"
@@ -199,6 +200,8 @@ pub struct InterfaceBuilder<'a> {
199
200
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
200
201
sixlowpan_fragments : Option < PacketAssemblerSet < ' a , SixlowpanFragKey > > ,
201
202
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
203
+ sixlowpan_fragments_cache_timeout : Duration ,
204
+ #[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
202
205
sixlowpan_out_buffer : Option < ManagedSlice < ' a , u8 > > ,
203
206
}
204
207
@@ -266,6 +269,8 @@ let iface = builder.finalize(&mut device);
266
269
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
267
270
sixlowpan_fragments : None ,
268
271
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
272
+ sixlowpan_fragments_cache_timeout : Duration :: from_secs ( 60 ) ,
273
+ #[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
269
274
sixlowpan_out_buffer : None ,
270
275
}
271
276
}
@@ -393,6 +398,15 @@ let iface = builder.finalize(&mut device);
393
398
self
394
399
}
395
400
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
+
396
410
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
397
411
pub fn sixlowpan_out_packet_cache < T > ( mut self , storage : T ) -> Self
398
412
where
@@ -493,6 +507,8 @@ let iface = builder.finalize(&mut device);
493
507
sixlowpan_fragments : self
494
508
. sixlowpan_fragments
495
509
. expect ( "Cache for incoming 6LoWPAN fragments is required" ) ,
510
+ #[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
511
+ sixlowpan_fragments_cache_timeout : self . sixlowpan_fragments_cache_timeout ,
496
512
497
513
#[ cfg( not( any(
498
514
feature = "proto-ipv4-fragmentation" ,
@@ -1574,7 +1590,7 @@ impl<'a> InterfaceInner<'a> {
1574
1590
Some ( payload) => {
1575
1591
cfg_if:: cfg_if! {
1576
1592
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 ) ) )
1578
1594
} else {
1579
1595
self . process_sixlowpan( sockets, & ieee802154_repr, payload, None )
1580
1596
}
@@ -1590,7 +1606,10 @@ impl<'a> InterfaceInner<'a> {
1590
1606
sockets : & mut SocketSet ,
1591
1607
ieee802154_repr : & Ieee802154Repr ,
1592
1608
payload : & ' payload T ,
1593
- _fragments : Option < & ' output mut PacketAssemblerSet < ' a , SixlowpanFragKey > > ,
1609
+ _fragments : Option < (
1610
+ & ' output mut PacketAssemblerSet < ' a , SixlowpanFragKey > ,
1611
+ Duration ,
1612
+ ) > ,
1594
1613
) -> Option < IpPacket < ' output > > {
1595
1614
let payload = match check ! ( SixlowpanPacket :: dispatch( payload) ) {
1596
1615
#[ cfg( not( feature = "proto-sixlowpan-fragmentation" ) ) ]
@@ -1600,7 +1619,7 @@ impl<'a> InterfaceInner<'a> {
1600
1619
}
1601
1620
#[ cfg( feature = "proto-sixlowpan-fragmentation" ) ]
1602
1621
SixlowpanPacket :: FragmentHeader => {
1603
- let fragments = _fragments. unwrap ( ) ;
1622
+ let ( fragments, timeout ) = _fragments. unwrap ( ) ;
1604
1623
1605
1624
// We have a fragment header, which means we cannot process the 6LoWPAN packet,
1606
1625
// unless we have a complete one after processing this fragment.
@@ -1660,12 +1679,21 @@ impl<'a> InterfaceInner<'a> {
1660
1679
// This information is the total size of the packet when it is fully assmbled.
1661
1680
// We also pass the header size, since this is needed when other fragments
1662
1681
// (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(
1664
1692
Some (
1665
1693
frag. datagram_size( ) as usize - uncompressed_header_size
1666
1694
+ compressed_header_size
1667
1695
) ,
1668
- self . now + Duration :: from_secs ( 60 ) ,
1696
+ self . now + timeout ,
1669
1697
-( ( uncompressed_header_size - compressed_header_size) as isize ) ,
1670
1698
) ) ;
1671
1699
}
0 commit comments