ng_sixlowpan_frag: fixes
This commit is contained in:
parent
03b7c7349a
commit
dc2113d67a
@ -191,7 +191,7 @@ static uint16_t _send_nth_fragment(ng_sixlowpan_netif_t *iface, ng_pktsnip_t *pk
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG("6lo frag: send first fragment (datagram size: %u, "
|
||||
DEBUG("6lo frag: send subsequent fragment (datagram size: %u, "
|
||||
"datagram tag: %" PRIu16 ", offset: %" PRIu8 " (%u bytes), "
|
||||
"fragment size: %" PRIu16 ")\n",
|
||||
(unsigned int)datagram_size, _tag, hdr->offset, hdr->offset << 3,
|
||||
@ -217,6 +217,7 @@ void ng_sixlowpan_frag_send(kernel_pid_t pid, ng_pktsnip_t *pkt,
|
||||
|
||||
if ((res = _send_1st_fragment(iface, pkt, payload_len, datagram_size)) == 0) {
|
||||
/* error sending first fragment */
|
||||
DEBUG("6lo frag: error sending 1st fragment\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
@ -226,7 +227,9 @@ void ng_sixlowpan_frag_send(kernel_pid_t pid, ng_pktsnip_t *pkt,
|
||||
while (offset < datagram_size) {
|
||||
if ((res = _send_nth_fragment(iface, pkt, payload_len, datagram_size,
|
||||
offset)) == 0) {
|
||||
/* error sending first fragment */
|
||||
/* error sending subsequent fragment */
|
||||
DEBUG("6lo frag: error sending subsequent fragment (offset = %" PRIu16
|
||||
")\n", offset);
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -16,10 +16,7 @@
|
||||
#include <stdbool.h>
|
||||
|
||||
#include "rbuf.h"
|
||||
#include "net/ng_netapi.h"
|
||||
#include "net/ng_netif.h"
|
||||
#include "net/ng_netif/hdr.h"
|
||||
#include "net/ng_pktbuf.h"
|
||||
#include "net/ng_netbase.h"
|
||||
#include "net/ng_ipv6/netif.h"
|
||||
#include "net/ng_sixlowpan.h"
|
||||
#include "net/ng_sixlowpan/frag.h"
|
||||
@ -67,7 +64,6 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
rbuf_t *entry;
|
||||
rbuf_int_t *ptr;
|
||||
uint8_t *data = ((uint8_t *)frag) + sizeof(ng_sixlowpan_frag_t);
|
||||
uint16_t dg_frag_size = frag_size; /* may differ on first fragment */
|
||||
|
||||
_rbuf_gc();
|
||||
entry = _rbuf_get(ng_netif_hdr_get_src_addr(netif_hdr), netif_hdr->src_l2addr_len,
|
||||
@ -83,23 +79,12 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
ptr = entry->ints;
|
||||
|
||||
/* dispatches in the first fragment are ignored */
|
||||
if (offset != 0) {
|
||||
switch (((uint8_t *)(entry->pkt->data))[0]) {
|
||||
case NG_SIXLOWPAN_UNCOMPRESSED:
|
||||
offset++;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
data++; /* also don't take offset field */
|
||||
}
|
||||
else {
|
||||
if (offset == 0) {
|
||||
switch (data[0]) {
|
||||
case NG_SIXLOWPAN_UNCOMPRESSED:
|
||||
dg_frag_size--;
|
||||
data++; /* skip 6LoWPAN dispatch */
|
||||
frag_size--;
|
||||
entry->compressed = 0; /* datagram is not compressed */
|
||||
|
||||
break;
|
||||
|
||||
@ -108,6 +93,9 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
data++; /* FRAGN header is one byte longer (offset) */
|
||||
}
|
||||
|
||||
if ((offset + frag_size) > entry->pkt->size) {
|
||||
DEBUG("6lo rfrag: fragment too big for resulting datagram, discarding datagram\n");
|
||||
@ -117,7 +105,7 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
}
|
||||
|
||||
while (ptr != NULL) {
|
||||
if (_rbuf_int_in(ptr, offset, offset + dg_frag_size - 1)) {
|
||||
if (_rbuf_int_in(ptr, offset, offset + frag_size - 1)) {
|
||||
DEBUG("6lo rfrag: overlapping or same intervals, discarding datagram\n");
|
||||
ng_pktbuf_release(entry->pkt);
|
||||
_rbuf_rem(entry);
|
||||
@ -127,31 +115,13 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
ptr = ptr->next;
|
||||
}
|
||||
|
||||
if (_rbuf_update_ints(entry, offset, dg_frag_size)) {
|
||||
if (dg_frag_size < frag_size) {
|
||||
/* some dispatches do not count to datagram size and we need
|
||||
* more space because of that */
|
||||
if (ng_pktbuf_realloc_data(entry->pkt, entry->pkt->size +
|
||||
(frag_size - dg_frag_size)) < 0) {
|
||||
DEBUG("6lo rbuf: could not reallocate packet data.\n");
|
||||
return;
|
||||
}
|
||||
|
||||
/* move already inserted fragments (frag_size - dg_frag_size) to the right */
|
||||
if (entry->cur_size > 0) {
|
||||
for (int i = entry->pkt->size - (frag_size - dg_frag_size); i > 0; i--) {
|
||||
uint8_t *d = ((uint8_t *)(entry->pkt->data)) + i;
|
||||
*d = *(d - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_rbuf_update_ints(entry, offset, frag_size)) {
|
||||
DEBUG("6lo rbuf: add fragment data\n");
|
||||
entry->cur_size += (uint16_t)dg_frag_size;
|
||||
entry->cur_size += (uint16_t)frag_size;
|
||||
memcpy(((uint8_t *)entry->pkt->data) + offset, data, frag_size);
|
||||
}
|
||||
|
||||
if (entry->cur_size == entry->datagram_size) {
|
||||
if (entry->cur_size == entry->pkt->size) {
|
||||
kernel_pid_t iface = netif_hdr->if_pid;
|
||||
ng_pktsnip_t *netif = ng_netif_hdr_build(entry->src, entry->src_len,
|
||||
entry->dst, entry->dst_len);
|
||||
@ -159,6 +129,7 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
if (netif == NULL) {
|
||||
DEBUG("6lo rbuf: error allocating netif header\n");
|
||||
ng_pktbuf_release(entry->pkt);
|
||||
_rbuf_rem(entry);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -166,8 +137,18 @@ void rbuf_add(ng_netif_hdr_t *netif_hdr, ng_sixlowpan_frag_t *frag,
|
||||
netif_hdr->if_pid = iface;
|
||||
LL_APPEND(entry->pkt, netif);
|
||||
|
||||
DEBUG("6lo rbuf: datagram complete, send to self\n");
|
||||
ng_netapi_receive(thread_getpid(), entry->pkt);
|
||||
if (entry->compressed) {
|
||||
DEBUG("6lo rbuf: datagram complete, send to self for decompression\n");
|
||||
ng_netapi_receive(thread_getpid(), entry->pkt);
|
||||
}
|
||||
else {
|
||||
DEBUG("6lo rbuf: datagram complete, send to IPv6 listeners\n");
|
||||
if (!ng_netapi_dispatch_receive(NG_NETTYPE_IPV6, NG_NETREG_DEMUX_CTX_ALL,
|
||||
entry->pkt)) {
|
||||
DEBUG("6lo rbuf: No receivers for this packet found\n");
|
||||
ng_pktbuf_release(entry->pkt);
|
||||
}
|
||||
}
|
||||
_rbuf_rem(entry);
|
||||
}
|
||||
}
|
||||
@ -222,9 +203,9 @@ static bool _rbuf_update_ints(rbuf_t *entry, uint16_t offset, size_t frag_size)
|
||||
DEBUG("6lo rfrag: add interval (%" PRIu16 ", %" PRIu16 ") to entry (%s, ",
|
||||
new->start, new->end, ng_netif_addr_to_str(l2addr_str,
|
||||
sizeof(l2addr_str), entry->src, entry->src_len));
|
||||
DEBUG("%s, %u, %" PRIu16 ")\n", ng_netif_addr_to_str(l2addr_str,
|
||||
sizeof(l2addr_str), entry->dst, entry->dst_len), entry->datagram_size,
|
||||
entry->tag);
|
||||
DEBUG("%s, %u, %u)\n", ng_netif_addr_to_str(l2addr_str,
|
||||
sizeof(l2addr_str), entry->dst, entry->dst_len),
|
||||
(unsigned)entry->pkt->size, entry->tag);
|
||||
|
||||
LL_PREPEND(entry->ints, new);
|
||||
|
||||
@ -247,10 +228,10 @@ static void _rbuf_gc(void)
|
||||
((now.seconds - rbuf[i].arrival) > RBUF_TIMEOUT)) {
|
||||
DEBUG("6lo rfrag: entry (%s, ", ng_netif_addr_to_str(l2addr_str,
|
||||
sizeof(l2addr_str), rbuf[i].src, rbuf[i].src_len));
|
||||
DEBUG("%s, %u, %" PRIu16 ") timed out\n",
|
||||
DEBUG("%s, %u, %u) timed out\n",
|
||||
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), rbuf[i].dst,
|
||||
rbuf[i].dst_len),
|
||||
rbuf[i].datagram_size, rbuf[i].tag);
|
||||
(unsigned)rbuf[i].pkt->size, rbuf[i].tag);
|
||||
|
||||
ng_pktbuf_release(rbuf[i].pkt);
|
||||
_rbuf_rem(&(rbuf[i]));
|
||||
@ -278,7 +259,7 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
||||
|
||||
for (unsigned int i = 0; i < RBUF_SIZE; i++) {
|
||||
/* check first if entry already available */
|
||||
if ((rbuf[i].pkt != NULL) && (rbuf[i].datagram_size == size) &&
|
||||
if ((rbuf[i].pkt != NULL) && (rbuf[i].pkt->size == size) &&
|
||||
(rbuf[i].tag == tag) && (rbuf[i].src_len == src_len) &&
|
||||
(rbuf[i].dst_len == dst_len) &&
|
||||
(memcmp(rbuf[i].src, src, src_len) == 0) &&
|
||||
@ -286,10 +267,10 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
||||
DEBUG("6lo rfrag: entry %p (%s, ", (void *)(&rbuf[i]),
|
||||
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str),
|
||||
rbuf[i].src, rbuf[i].src_len));
|
||||
DEBUG("%s, %u, %" PRIu16 ") found\n",
|
||||
DEBUG("%s, %u, %u) found\n",
|
||||
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str),
|
||||
rbuf[i].dst, rbuf[i].dst_len),
|
||||
rbuf[i].datagram_size, rbuf[i].tag);
|
||||
(unsigned)rbuf[i].pkt->size, rbuf[i].tag);
|
||||
rbuf[i].arrival = now.seconds;
|
||||
return &(rbuf[i]);
|
||||
}
|
||||
@ -315,15 +296,16 @@ static rbuf_t *_rbuf_get(const void *src, size_t src_len,
|
||||
res->src_len = src_len;
|
||||
res->dst_len = dst_len;
|
||||
res->tag = tag;
|
||||
res->datagram_size = size;
|
||||
res->cur_size = 0;
|
||||
res->compressed = 1;
|
||||
|
||||
DEBUG("6lo rfrag: entry %p (%s, ", (void *)res,
|
||||
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), res->src,
|
||||
res->src_len));
|
||||
DEBUG("%s, %u, %" PRIu16 ") created\n",
|
||||
DEBUG("%s, %u, %u) created\n",
|
||||
ng_netif_addr_to_str(l2addr_str, sizeof(l2addr_str), res->dst,
|
||||
res->dst_len), res->datagram_size, res->tag);
|
||||
res->dst_len), (unsigned)res->pkt->size,
|
||||
res->tag);
|
||||
}
|
||||
|
||||
return res;
|
||||
|
||||
@ -77,8 +77,8 @@ typedef struct {
|
||||
uint8_t src_len; /**< length of source address */
|
||||
uint8_t dst_len; /**< length of destination address */
|
||||
uint16_t tag; /**< the datagram's tag */
|
||||
uint16_t datagram_size; /**< the datagram's size (without 6lo dispatches) */
|
||||
uint16_t cur_size; /**< the datagram's current size */
|
||||
uint16_t compressed; /**< the datagram has a compressed header */
|
||||
} rbuf_t;
|
||||
|
||||
/**
|
||||
|
||||
@ -146,18 +146,31 @@ static void _receive(ng_pktsnip_t *pkt)
|
||||
}
|
||||
}
|
||||
|
||||
static inline bool _add_uncompr_disp(ng_pktsnip_t *pkt)
|
||||
{
|
||||
ng_pktsnip_t *sixlowpan;
|
||||
uint8_t *disp;
|
||||
|
||||
DEBUG("6lo: Send uncompressed\n");
|
||||
|
||||
sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t), NG_NETTYPE_SIXLOWPAN);
|
||||
|
||||
if (sixlowpan == NULL) {
|
||||
return false;
|
||||
}
|
||||
sixlowpan->next = pkt->next;
|
||||
pkt->next = sixlowpan;
|
||||
disp = sixlowpan->data;
|
||||
disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
|
||||
return true;
|
||||
}
|
||||
|
||||
static void _send(ng_pktsnip_t *pkt)
|
||||
{
|
||||
ng_netif_hdr_t *hdr;
|
||||
ng_pktsnip_t *ipv6, *sixlowpan;
|
||||
ng_pktsnip_t *pkt2;
|
||||
ng_sixlowpan_netif_t *iface;
|
||||
/* cppcheck: datagram_size will be read by frag */
|
||||
/* cppcheck-suppress unreadVariable */
|
||||
size_t payload_len, datagram_size;
|
||||
uint16_t max_frag_size;
|
||||
/* cppcheck: disp is needed in other build paths on this level already */
|
||||
/* cppcheck-suppress variableScope */
|
||||
uint8_t *disp;
|
||||
size_t datagram_size, dispatch_len = 0;
|
||||
|
||||
if ((pkt == NULL) || (pkt->size < sizeof(ng_netif_hdr_t))) {
|
||||
DEBUG("6lo: Sending packet has no netif header\n");
|
||||
@ -165,33 +178,21 @@ static void _send(ng_pktsnip_t *pkt)
|
||||
return;
|
||||
}
|
||||
|
||||
hdr = pkt->data;
|
||||
ipv6 = pkt->next;
|
||||
|
||||
if ((ipv6 == NULL) || (ipv6->type != NG_NETTYPE_IPV6)) {
|
||||
if ((pkt->next == NULL) || (pkt->next->type != NG_NETTYPE_IPV6)) {
|
||||
DEBUG("6lo: Sending packet has no IPv6 header\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
/* payload length and datagram size are different in that the payload
|
||||
* length is the length of the IPv6 datagram + 6LoWPAN dispatches,
|
||||
* while the datagram size is the size of only the IPv6 datagram */
|
||||
payload_len = ng_pkt_len(ipv6);
|
||||
/* cppcheck: datagram_size will be read by ng_sixlowpan_frag implementation */
|
||||
/* cppcheck-suppress unreadVariable */
|
||||
datagram_size = (uint16_t)payload_len;
|
||||
pkt2 = ng_pktbuf_start_write(pkt);
|
||||
|
||||
/* use sixlowpan packet snip as temporary one */
|
||||
sixlowpan = ng_pktbuf_start_write(pkt);
|
||||
|
||||
if (sixlowpan == NULL) {
|
||||
if (pkt2 == NULL) {
|
||||
DEBUG("6lo: no space left in packet buffer\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
return;
|
||||
}
|
||||
|
||||
pkt = sixlowpan;
|
||||
hdr = pkt2->data;
|
||||
iface = ng_sixlowpan_netif_get(hdr->if_pid);
|
||||
|
||||
if (iface == NULL) {
|
||||
@ -212,73 +213,59 @@ static void _send(ng_pktsnip_t *pkt)
|
||||
|
||||
#ifdef MODULE_NG_SIXLOWPAN_IPHC
|
||||
if (iface->iphc_enabled) {
|
||||
if (!ng_sixlowpan_iphc_encode(pkt)) {
|
||||
if (!ng_sixlowpan_iphc_encode(pkt2)) {
|
||||
DEBUG("6lo: error on IPHC encoding\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
ng_pktbuf_release(pkt2);
|
||||
return;
|
||||
}
|
||||
/* IPHC dispatch does not count on dispatch length since it _shortens_
|
||||
* the datagram */
|
||||
}
|
||||
else {
|
||||
DEBUG("6lo: Send uncompressed\n");
|
||||
|
||||
sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t),
|
||||
NG_NETTYPE_SIXLOWPAN);
|
||||
|
||||
if (sixlowpan == NULL) {
|
||||
if (!_add_uncompr_disp(pkt2)) {
|
||||
/* adding uncompressed dispatch failed */
|
||||
DEBUG("6lo: no space left in packet buffer\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
ng_pktbuf_release(pkt2);
|
||||
return;
|
||||
}
|
||||
|
||||
sixlowpan->next = ipv6;
|
||||
pkt->next = sixlowpan;
|
||||
disp = sixlowpan->data;
|
||||
disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
|
||||
payload_len++;
|
||||
dispatch_len += 1;
|
||||
}
|
||||
#else
|
||||
/* suppress clang-analyzer report about iface being not read */
|
||||
(void) iface;
|
||||
|
||||
DEBUG("6lo: Send uncompressed\n");
|
||||
|
||||
sixlowpan = ng_pktbuf_add(NULL, NULL, sizeof(uint8_t), NG_NETTYPE_SIXLOWPAN);
|
||||
|
||||
if (sixlowpan == NULL) {
|
||||
if (!_add_uncompr_disp(pkt2)) {
|
||||
/* adding uncompressed dispatch failed */
|
||||
DEBUG("6lo: no space left in packet buffer\n");
|
||||
ng_pktbuf_release(pkt);
|
||||
ng_pktbuf_release(pkt2);
|
||||
return;
|
||||
}
|
||||
|
||||
sixlowpan->next = ipv6;
|
||||
pkt->next = sixlowpan;
|
||||
disp = sixlowpan->data;
|
||||
disp[0] = NG_SIXLOWPAN_UNCOMPRESSED;
|
||||
payload_len++;
|
||||
dispatch_len += 1;
|
||||
#endif
|
||||
datagram_size = ng_pkt_len(pkt2->next);
|
||||
|
||||
DEBUG("6lo: max_frag_size = %" PRIu16 " for interface %"
|
||||
PRIkernel_pid "\n", max_frag_size, hdr->if_pid);
|
||||
DEBUG("6lo: iface->max_frag_size = %" PRIu16 " for interface %"
|
||||
PRIkernel_pid "\n", iface->max_frag_size, hdr->if_pid);
|
||||
|
||||
/* IP should not send anything here if it is not a 6LoWPAN interface,
|
||||
* so we don't need to check for NULL pointers */
|
||||
if (payload_len <= max_frag_size) {
|
||||
if ((datagram_size + dispatch_len) <= iface->max_frag_size) {
|
||||
DEBUG("6lo: Send SND command for %p to %" PRIu16 "\n",
|
||||
(void *)pkt, hdr->if_pid);
|
||||
ng_netapi_send(hdr->if_pid, pkt);
|
||||
(void *)pkt2, hdr->if_pid);
|
||||
ng_netapi_send(hdr->if_pid, pkt2);
|
||||
|
||||
return;
|
||||
}
|
||||
#ifdef MODULE_NG_SIXLOWPAN_FRAG
|
||||
else {
|
||||
DEBUG("6lo: Send fragmented (%u > %" PRIu16 ")\n",
|
||||
(unsigned int)payload_len, max_frag_size);
|
||||
ng_sixlowpan_frag_send(hdr->if_pid, pkt, payload_len, datagram_size);
|
||||
(unsigned int)datagram_size + dispatch_len, iface->max_frag_size);
|
||||
ng_sixlowpan_frag_send(hdr->if_pid, pkt2, datagram_size + dispatch_len,
|
||||
datagram_size);
|
||||
}
|
||||
#else
|
||||
(void)datagram_size;
|
||||
DEBUG("6lo: packet too big (%u> %" PRIu16 ")\n",
|
||||
(unsigned int)payload_len, max_frag_size);
|
||||
(unsigned int)(datagram_size + dispatch_len), iface->max_frag_size);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user