Separated processed_ip_len into processed_ip_in_len and

processed_ip_out_len to avoid corruption, in case we send a packet in
the middle of receiving a fragmented packet.
This commit is contained in:
Ivan Delamer 2012-03-26 15:19:02 -06:00
parent c6b3a9957d
commit 436cbec844

View file

@ -234,7 +234,7 @@ static uip_buf_t sicslowpan_aligned_buf;
* length of the ip packet already sent / received. * length of the ip packet already sent / received.
* It includes IP and transport headers. * It includes IP and transport headers.
*/ */
static uint16_t processed_ip_len; static uint16_t processed_ip_in_len;
/** Datagram tag to be put in the fragments I send. */ /** Datagram tag to be put in the fragments I send. */
static uint16_t my_tag; static uint16_t my_tag;
@ -1353,6 +1353,9 @@ output(uip_lladdr_t *localdest)
/* The MAC address of the destination of the packet */ /* The MAC address of the destination of the packet */
rimeaddr_t dest; rimeaddr_t dest;
/* Number of bytes processed. */
uint16_t processed_ip_out_len;
/* init */ /* init */
uncomp_hdr_len = 0; uncomp_hdr_len = 0;
rime_hdr_len = 0; rime_hdr_len = 0;
@ -1443,6 +1446,7 @@ output(uip_lladdr_t *localdest)
((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len)); ((SICSLOWPAN_DISPATCH_FRAG1 << 8) | uip_len));
/* RIME_FRAG_BUF->tag = uip_htons(my_tag); */ /* RIME_FRAG_BUF->tag = uip_htons(my_tag); */
SET16(RIME_FRAG_PTR, RIME_FRAG_TAG, my_tag); SET16(RIME_FRAG_PTR, RIME_FRAG_TAG, my_tag);
my_tag++;
/* Copy payload and send */ /* Copy payload and send */
rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN; rime_hdr_len += SICSLOWPAN_FRAG1_HDR_LEN;
@ -1461,8 +1465,8 @@ output(uip_lladdr_t *localdest)
queuebuf_free(q); queuebuf_free(q);
q = NULL; q = NULL;
/* set processed_ip_len to what we already sent from the IP payload*/ /* set processed_ip_out_len to what we already sent from the IP payload*/
processed_ip_len = rime_payload_len + uncomp_hdr_len; processed_ip_out_len = rime_payload_len + uncomp_hdr_len;
/* /*
* Create following fragments * Create following fragments
@ -1475,19 +1479,19 @@ output(uip_lladdr_t *localdest)
SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE, SET16(RIME_FRAG_PTR, RIME_FRAG_DISPATCH_SIZE,
((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len)); ((SICSLOWPAN_DISPATCH_FRAGN << 8) | uip_len));
rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8; rime_payload_len = (MAC_MAX_PAYLOAD - rime_hdr_len) & 0xf8;
while(processed_ip_len < uip_len) { while(processed_ip_out_len < uip_len) {
PRINTFO("sicslowpan output: fragment "); PRINTFO("sicslowpan output: fragment ");
RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_len >> 3; RIME_FRAG_PTR[RIME_FRAG_OFFSET] = processed_ip_out_len >> 3;
/* Copy payload and send */ /* Copy payload and send */
if(uip_len - processed_ip_len < rime_payload_len) { if(uip_len - processed_ip_out_len < rime_payload_len) {
/* last fragment */ /* last fragment */
rime_payload_len = uip_len - processed_ip_len; rime_payload_len = uip_len - processed_ip_out_len;
} }
PRINTFO("(offset %d, len %d, tag %d)\n", PRINTFO("(offset %d, len %d, tag %d)\n",
processed_ip_len >> 3, rime_payload_len, my_tag); processed_ip_out_len >> 3, rime_payload_len, my_tag);
memcpy(rime_ptr + rime_hdr_len, memcpy(rime_ptr + rime_hdr_len,
(uint8_t *)UIP_IP_BUF + processed_ip_len, rime_payload_len); (uint8_t *)UIP_IP_BUF + processed_ip_out_len, rime_payload_len);
packetbuf_set_datalen(rime_payload_len + rime_hdr_len); packetbuf_set_datalen(rime_payload_len + rime_hdr_len);
q = queuebuf_new_from_packetbuf(); q = queuebuf_new_from_packetbuf();
if(q == NULL) { if(q == NULL) {
@ -1498,12 +1502,9 @@ output(uip_lladdr_t *localdest)
queuebuf_to_packetbuf(q); queuebuf_to_packetbuf(q);
queuebuf_free(q); queuebuf_free(q);
q = NULL; q = NULL;
processed_ip_len += rime_payload_len; processed_ip_out_len += rime_payload_len;
} }
/* end: reset global variables */
my_tag++;
processed_ip_len = 0;
#else /* SICSLOWPAN_CONF_FRAG */ #else /* SICSLOWPAN_CONF_FRAG */
PRINTFO("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n"); PRINTFO("sicslowpan output: Packet too large to be sent without fragmentation support; dropping packet\n");
return 0; return 0;
@ -1558,7 +1559,7 @@ input(void)
/* if reassembly timed out, cancel it */ /* if reassembly timed out, cancel it */
if(timer_expired(&reass_timer)) { if(timer_expired(&reass_timer)) {
sicslowpan_len = 0; sicslowpan_len = 0;
processed_ip_len = 0; processed_ip_in_len = 0;
} }
/* /*
* Since we don't support the mesh and broadcast header, the first header * Since we don't support the mesh and broadcast header, the first header
@ -1593,10 +1594,10 @@ input(void)
/* If this is the last fragment, we may shave off any extrenous /* If this is the last fragment, we may shave off any extrenous
bytes at the end. We must be liberal in what we accept. */ bytes at the end. We must be liberal in what we accept. */
PRINTFI("last_fragment?: processed_ip_len %d rime_payload_len %d frag_size %d\n", PRINTFI("last_fragment?: processed_ip_in_len %d rime_payload_len %d frag_size %d\n",
processed_ip_len, packetbuf_datalen() - rime_hdr_len, frag_size); processed_ip_in_len, packetbuf_datalen() - rime_hdr_len, frag_size);
if(processed_ip_len + packetbuf_datalen() - rime_hdr_len >= frag_size) { if(processed_ip_in_len + packetbuf_datalen() - rime_hdr_len >= frag_size) {
last_fragment = 1; last_fragment = 1;
} }
break; break;
@ -1604,7 +1605,7 @@ input(void)
break; break;
} }
if(processed_ip_len > 0) { if(processed_ip_in_len > 0) {
/* reassembly is ongoing */ /* reassembly is ongoing */
/* printf("frag %d %d\n", reass_tag, frag_tag);*/ /* printf("frag %d %d\n", reass_tag, frag_tag);*/
if((frag_size > 0 && if((frag_size > 0 &&
@ -1690,22 +1691,22 @@ input(void)
rime_payload_len = packetbuf_datalen() - rime_hdr_len; rime_payload_len = packetbuf_datalen() - rime_hdr_len;
memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len); memcpy((uint8_t *)SICSLOWPAN_IP_BUF + uncomp_hdr_len + (uint16_t)(frag_offset << 3), rime_ptr + rime_hdr_len, rime_payload_len);
/* update processed_ip_len if fragment, sicslowpan_len otherwise */ /* update processed_ip_in_len if fragment, sicslowpan_len otherwise */
#if SICSLOWPAN_CONF_FRAG #if SICSLOWPAN_CONF_FRAG
if(frag_size > 0) { if(frag_size > 0) {
/* Add the size of the header only for the first fragment. */ /* Add the size of the header only for the first fragment. */
if(first_fragment != 0) { if(first_fragment != 0) {
processed_ip_len += uncomp_hdr_len; processed_ip_in_len += uncomp_hdr_len;
} }
/* For the last fragment, we are OK if there is extrenous bytes at /* For the last fragment, we are OK if there is extrenous bytes at
the end of the packet. */ the end of the packet. */
if(last_fragment != 0) { if(last_fragment != 0) {
processed_ip_len = frag_size; processed_ip_in_len = frag_size;
} else { } else {
processed_ip_len += rime_payload_len; processed_ip_in_len += rime_payload_len;
} }
PRINTF("processed_ip_len %d, rime_payload_len %d\n", processed_ip_len, rime_payload_len); PRINTF("processed_ip_in_len %d, rime_payload_len %d\n", processed_ip_in_len, rime_payload_len);
} else { } else {
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
@ -1717,15 +1718,15 @@ input(void)
* If we have a full IP packet in sicslowpan_buf, deliver it to * If we have a full IP packet in sicslowpan_buf, deliver it to
* the IP stack * the IP stack
*/ */
PRINTF("sicslowpan_init processed_ip_len %d, sicslowpan_len %d\n", PRINTF("sicslowpan_init processed_ip_in_len %d, sicslowpan_len %d\n",
processed_ip_len, sicslowpan_len); processed_ip_in_len, sicslowpan_len);
if(processed_ip_len == 0 || (processed_ip_len == sicslowpan_len)) { if(processed_ip_in_len == 0 || (processed_ip_in_len == sicslowpan_len)) {
PRINTFI("sicslowpan input: IP packet ready (length %d)\n", PRINTFI("sicslowpan input: IP packet ready (length %d)\n",
sicslowpan_len); sicslowpan_len);
memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len); memcpy((uint8_t *)UIP_IP_BUF, (uint8_t *)SICSLOWPAN_IP_BUF, sicslowpan_len);
uip_len = sicslowpan_len; uip_len = sicslowpan_len;
sicslowpan_len = 0; sicslowpan_len = 0;
processed_ip_len = 0; processed_ip_in_len = 0;
#endif /* SICSLOWPAN_CONF_FRAG */ #endif /* SICSLOWPAN_CONF_FRAG */
#if DEBUG #if DEBUG