Bug #53 » 0001-don-t-create-a-new-tracker-when-frags-are-received-i.patch
src/defrag.c | ||
---|---|---|
}
|
||
if (rp == NULL) {
|
||
SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for fragmentation re-assembly, dumping fragments.");
|
||
goto done;
|
||
goto remove_tracker;
|
||
}
|
||
int payload_len = 0;
|
||
... | ... | |
rp->pktlen = pktlen + payload_len;
|
||
done:
|
||
remove_tracker:
|
||
/* Remove the frag tracker. */
|
||
SCMutexLock(&dc->frag_table_lock);
|
||
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
|
||
... | ... | |
PoolReturn(dc->tracker_pool, tracker);
|
||
SCMutexUnlock(&dc->tracker_pool_lock);
|
||
done:
|
||
SCMutexUnlock(&tracker->lock);
|
||
return rp;
|
||
}
|
||
... | ... | |
}
|
||
if (rp == NULL) {
|
||
SCLogError(SC_ERR_MEM_ALLOC, "Failed to allocate packet for fragmentation re-assembly, dumping fragments.");
|
||
goto done;
|
||
goto remove_tracker;
|
||
}
|
||
int payload_len = 0;
|
||
... | ... | |
rp->ip6h->s_ip6_plen = htons(payload_len);
|
||
rp->pktlen = pktlen + payload_len;
|
||
done:
|
||
remove_tracker:
|
||
/* Remove the frag tracker. */
|
||
SCMutexLock(&dc->frag_table_lock);
|
||
HashListTableRemove(dc->frag_table, tracker, sizeof(tracker));
|
||
... | ... | |
PoolReturn(dc->tracker_pool, tracker);
|
||
SCMutexUnlock(&dc->tracker_pool_lock);
|
||
done:
|
||
SCMutexUnlock(&tracker->lock);
|
||
return rp;
|
||
}
|
||
... | ... | |
}
|
||
/**
|
||
* Simple fragmented packet in reverse order.
|
||
*/
|
||
static int
|
||
DefragReverseSimpleTest(void)
|
||
{
|
||
DefragContext *dc = NULL;
|
||
Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
|
||
Packet *reassembled = NULL;
|
||
int id = 12;
|
||
int i;
|
||
int ret = 0;
|
||
DefragInit();
|
||
dc = DefragContextNew();
|
||
if (dc == NULL)
|
||
goto end;
|
||
p1 = BuildTestPacket(id, 0, 1, 'A', 8);
|
||
if (p1 == NULL)
|
||
goto end;
|
||
p2 = BuildTestPacket(id, 1, 1, 'B', 8);
|
||
if (p2 == NULL)
|
||
goto end;
|
||
p3 = BuildTestPacket(id, 2, 0, 'C', 3);
|
||
if (p3 == NULL)
|
||
goto end;
|
||
if (Defrag(NULL, dc, p3) != NULL)
|
||
goto end;
|
||
if (Defrag(NULL, dc, p2) != NULL)
|
||
goto end;
|
||
reassembled = Defrag(NULL, dc, p1);
|
||
if (reassembled == NULL)
|
||
goto end;
|
||
/* 20 bytes in we should find 8 bytes of A. */
|
||
for (i = 20; i < 20 + 8; i++) {
|
||
if (reassembled->pkt[i] != 'A')
|
||
goto end;
|
||
}
|
||
/* 28 bytes in we should find 8 bytes of B. */
|
||
for (i = 28; i < 28 + 8; i++) {
|
||
if (reassembled->pkt[i] != 'B')
|
||
goto end;
|
||
}
|
||
/* And 36 bytes in we should find 3 bytes of C. */
|
||
for (i = 36; i < 36 + 3; i++) {
|
||
if (reassembled->pkt[i] != 'C')
|
||
goto end;
|
||
}
|
||
ret = 1;
|
||
end:
|
||
if (dc != NULL)
|
||
DefragContextDestroy(dc);
|
||
if (p1 != NULL)
|
||
free(p1);
|
||
if (p2 != NULL)
|
||
free(p2);
|
||
if (p3 != NULL)
|
||
free(p3);
|
||
if (reassembled != NULL)
|
||
free(reassembled);
|
||
DefragDestroy();
|
||
return ret;
|
||
}
|
||
/**
|
||
* Test the simplest possible re-assembly scenario. All packet in
|
||
* order and no overlaps.
|
||
*/
|
||
... | ... | |
}
|
||
static int
|
||
IPV6DefragReverseSimpleTest(void)
|
||
{
|
||
DefragContext *dc = NULL;
|
||
Packet *p1 = NULL, *p2 = NULL, *p3 = NULL;
|
||
Packet *reassembled = NULL;
|
||
int id = 12;
|
||
int i;
|
||
int ret = 0;
|
||
DefragInit();
|
||
dc = DefragContextNew();
|
||
if (dc == NULL)
|
||
goto end;
|
||
p1 = IPV6BuildTestPacket(id, 0, 1, 'A', 8);
|
||
if (p1 == NULL)
|
||
goto end;
|
||
p2 = IPV6BuildTestPacket(id, 1, 1, 'B', 8);
|
||
if (p2 == NULL)
|
||
goto end;
|
||
p3 = IPV6BuildTestPacket(id, 2, 0, 'C', 3);
|
||
if (p3 == NULL)
|
||
goto end;
|
||
if (Defrag(NULL, dc, p3) != NULL)
|
||
goto end;
|
||
if (Defrag(NULL, dc, p2) != NULL)
|
||
goto end;
|
||
reassembled = Defrag(NULL, dc, p1);
|
||
if (reassembled == NULL)
|
||
goto end;
|
||
/* 40 bytes in we should find 8 bytes of A. */
|
||
for (i = 40; i < 40 + 8; i++) {
|
||
if (reassembled->pkt[i] != 'A')
|
||
goto end;
|
||
}
|
||
/* 28 bytes in we should find 8 bytes of B. */
|
||
for (i = 48; i < 48 + 8; i++) {
|
||
if (reassembled->pkt[i] != 'B')
|
||
goto end;
|
||
}
|
||
/* And 36 bytes in we should find 3 bytes of C. */
|
||
for (i = 56; i < 56 + 3; i++) {
|
||
if (reassembled->pkt[i] != 'C')
|
||
goto end;
|
||
}
|
||
ret = 1;
|
||
end:
|
||
if (dc != NULL)
|
||
DefragContextDestroy(dc);
|
||
if (p1 != NULL)
|
||
free(p1);
|
||
if (p2 != NULL)
|
||
free(p2);
|
||
if (p3 != NULL)
|
||
free(p3);
|
||
if (reassembled != NULL)
|
||
free(reassembled);
|
||
DefragDestroy();
|
||
return ret;
|
||
}
|
||
static int
|
||
DefragDoSturgesNovakTest(int policy, u_char *expected, size_t expected_len)
|
||
{
|
||
int i;
|
||
... | ... | |
#ifdef UNITTESTS
|
||
UtRegisterTest("DefragInOrderSimpleTest",
|
||
DefragInOrderSimpleTest, 1);
|
||
UtRegisterTest("DefragReverseSimpleTest",
|
||
DefragReverseSimpleTest, 1);
|
||
UtRegisterTest("DefragSturgesNovakBsdTest",
|
||
DefragSturgesNovakBsdTest, 1);
|
||
UtRegisterTest("DefragSturgesNovakLinuxTest",
|
||
... | ... | |
UtRegisterTest("IPV6DefragInOrderSimpleTest",
|
||
IPV6DefragInOrderSimpleTest, 1);
|
||
UtRegisterTest("IPV6DefragReverseSimpleTest",
|
||
IPV6DefragReverseSimpleTest, 1);
|
||
UtRegisterTest("IPV6DefragSturgesNovakBsdTest",
|
||
IPV6DefragSturgesNovakBsdTest, 1);
|
||
UtRegisterTest("IPV6DefragSturgesNovakLinuxTest",
|