6lowpan fragmentation bugfix: the 6lowpan code had an unfortunate
interaction with the behavior of the rdc layer. If the first packet of a fragment transmission was lost, the remaining packets would get dropped on reception. Moreover, the reception code contained a bug that sometimes would cause fragments to be misidentified as fragments. Taken together, these problems would result in a pathelogical network breakdown if too many fragmented packets would occur simultaneously.
This commit is contained in:
parent
7987a6dac7
commit
0aa448f190
2 changed files with 73 additions and 12 deletions
|
@ -1590,6 +1590,7 @@ input(void)
|
|||
uint16_t frag_size = 0;
|
||||
/* offset of the fragment in the IP packet */
|
||||
uint8_t frag_offset = 0;
|
||||
uint8_t is_fragment = 0;
|
||||
#if SICSLOWPAN_CONF_FRAG
|
||||
/* tag of the fragment */
|
||||
uint16_t frag_tag = 0;
|
||||
|
@ -1626,6 +1627,7 @@ input(void)
|
|||
rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
|
||||
/* printf("frag1 %d %d\n", reass_tag, frag_tag);*/
|
||||
first_fragment = 1;
|
||||
is_fragment = 1;
|
||||
break;
|
||||
case SICSLOWPAN_DISPATCH_FRAGN:
|
||||
/*
|
||||
|
@ -1648,11 +1650,29 @@ input(void)
|
|||
if(processed_ip_in_len + packetbuf_datalen() - rime_hdr_len >= frag_size) {
|
||||
last_fragment = 1;
|
||||
}
|
||||
is_fragment = 1;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* We are currently reassembling a packet, but have just received the first
|
||||
* fragment of another packet. We can either ignore it and hope to receive
|
||||
* the rest of the under-reassembly packet fragments, or we can discard the
|
||||
* previous packet altogether, and start reassembling the new packet.
|
||||
*
|
||||
* We discard the previous packet, and start reassembling the new packet.
|
||||
* This lessens the negative impacts of too high SICSLOWPAN_REASS_MAXAGE.
|
||||
*/
|
||||
#define PRIORITIZE_NEW_PACKETS 1
|
||||
#if PRIORITIZE_NEW_PACKETS
|
||||
if(processed_ip_in_len > 0 && first_fragment
|
||||
&& !rimeaddr_cmp(&frag_sender, packetbuf_addr(PACKETBUF_ADDR_SENDER))) {
|
||||
sicslowpan_len = 0;
|
||||
processed_ip_in_len = 0;
|
||||
}
|
||||
#endif /* PRIORITIZE_NEW_PACKETS */
|
||||
|
||||
if(processed_ip_in_len > 0) {
|
||||
/* reassembly is ongoing */
|
||||
/* printf("frag %d %d\n", reass_tag, frag_tag);*/
|
||||
|
@ -1674,6 +1694,12 @@ input(void)
|
|||
* start it if we received a fragment
|
||||
*/
|
||||
if((frag_size > 0) && (frag_size <= UIP_BUFSIZE)) {
|
||||
/* We are currently not reassembling a packet, but have received a packet fragment
|
||||
* that is not the first one. */
|
||||
if(is_fragment && !first_fragment) {
|
||||
return;
|
||||
}
|
||||
|
||||
sicslowpan_len = frag_size;
|
||||
reass_tag = frag_tag;
|
||||
timer_set(&reass_timer, SICSLOWPAN_REASS_MAXAGE * CLOCK_SECOND / 16);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue