Skip to content

Commit

Permalink
Defrag engine
Browse files Browse the repository at this point in the history
Big rewrite of defrag engine to make it more scalable and fix some
locking logic flaws.

Now uses a hash of trackers similar to Flow and Host hashes.
  • Loading branch information
victorjulien committed Sep 19, 2012
1 parent c91c359 commit 7a044a9
Show file tree
Hide file tree
Showing 15 changed files with 1,434 additions and 544 deletions.
3 changes: 3 additions & 0 deletions src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -301,6 +301,9 @@ app-layer-ssh.c app-layer-ssh.h \
app-layer-tls-handshake.c app-layer-tls-handshake.h \
app-layer-smtp.c app-layer-smtp.h \
defrag.c defrag.h \
defrag-hash.c defrag-hash.h \
defrag-queue.c defrag-queue.h \
defrag-timeout.c defrag-timeout.h \
output.c output.h \
win32-misc.c win32-misc.h \
win32-service.c win32-service.h \
Expand Down
25 changes: 12 additions & 13 deletions src/decode-ipv4.c
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ void DecodeIPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,

/* If a fragment, pass off for re-assembly. */
if (unlikely(IPV4_GET_IPOFFSET(p) > 0 || IPV4_GET_MF(p) == 1)) {
Packet *rp = Defrag(tv, dtv, NULL, p);
Packet *rp = Defrag(tv, dtv, p);
if (rp != NULL) {
/* Got re-assembled packet, re-run through decoder. */
DecodeIPV4(tv, dtv, rp, (void *)rp->ip4h, IPV4_GET_IPLEN(rp), pq);
Expand Down Expand Up @@ -1558,6 +1558,7 @@ int DecodeIPV4DefragTest01(void)

PACKET_INITIALIZE(p);
FlowInitConfig(FLOW_QUIET);
DefragInit();

PacketCopyData(p, pkt1, sizeof(pkt1));
DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
Expand Down Expand Up @@ -1622,6 +1623,7 @@ int DecodeIPV4DefragTest01(void)
SCFree(tp);

end:
DefragDestroy();
FlowShutdown();
PACKET_CLEANUP(p);
SCFree(p);
Expand Down Expand Up @@ -1686,21 +1688,21 @@ int DecodeIPV4DefragTest02(void)
ThreadVars tv;
DecodeThreadVars dtv;
PacketQueue pq;
int result = 1;
int result = 0;

memset(&tv, 0, sizeof(ThreadVars));
memset(&dtv, 0, sizeof(DecodeThreadVars));
memset(&pq, 0, sizeof(PacketQueue));

PACKET_INITIALIZE(p);
FlowInitConfig(FLOW_QUIET);
DefragInit();

PacketCopyData(p, pkt1, sizeof(pkt1));
DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
if (p->tcph != NULL) {
printf("tcp header should be NULL for ip fragment, but it isn't\n");
result = 0;
goto end;
}
PACKET_DO_RECYCLE(p);
Expand All @@ -1710,7 +1712,6 @@ int DecodeIPV4DefragTest02(void)
GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
if (p->tcph != NULL) {
printf("tcp header should be NULL for ip fragment, but it isn't\n");
result = 0;
goto end;
}
PACKET_DO_RECYCLE(p);
Expand All @@ -1721,45 +1722,41 @@ int DecodeIPV4DefragTest02(void)
GET_PKT_LEN(p) - ETHERNET_HEADER_LEN, &pq);
if (p->tcph != NULL) {
printf("tcp header should be NULL for ip fragment, but it isn't\n");
result = 0;
goto end;
}
Packet *tp = PacketDequeue(&pq);
if (tp == NULL) {
printf("Failed to get defragged pseudo packet\n");
result = 0;
goto end;
}
if (tp->recursion_level != p->recursion_level) {
printf("defragged pseudo packet's and parent packet's recursion "
"level don't match\n %d != %d",
"level don't match %d != %d: ",
tp->recursion_level, p->recursion_level);
result = 0;
goto end;
}
if (tp->ip4h == NULL || tp->tcph == NULL) {
printf("pseudo packet's ip header and tcp header shouldn't be NULL, "
"but it is\n");
result = 0;
goto end;
}
if (GET_PKT_LEN(tp) != sizeof(tunnel_pkt)) {
printf("defragged pseudo packet's and parent packet's pkt lens "
"don't match\n %u != %"PRIuMAX,
"don't match %u != %"PRIuMAX": ",
GET_PKT_LEN(tp), (uintmax_t)sizeof(tunnel_pkt));
result = 0;
goto end;
}

if (memcmp(GET_PKT_DATA(tp), tunnel_pkt, sizeof(tunnel_pkt)) != 0) {
result = 0;
goto end;
goto end;
}

result = 1;
PACKET_CLEANUP(p);
SCFree(tp);

end:
DefragDestroy();
FlowShutdown();
PACKET_CLEANUP(p);
SCFree(p);
Expand Down Expand Up @@ -1828,6 +1825,7 @@ int DecodeIPV4DefragTest03(void)

PACKET_INITIALIZE(p);
FlowInitConfig(FLOW_QUIET);
DefragInit();

PacketCopyData(p, pkt, sizeof(pkt));
DecodeIPV4(&tv, &dtv, p, GET_PKT_DATA(p) + ETHERNET_HEADER_LEN,
Expand Down Expand Up @@ -1918,6 +1916,7 @@ int DecodeIPV4DefragTest03(void)
SCFree(tp);

end:
DefragDestroy();
FlowShutdown();
PACKET_CLEANUP(p);
SCFree(p);
Expand Down
4 changes: 3 additions & 1 deletion src/decode-ipv6.c
Original file line number Diff line number Diff line change
Expand Up @@ -564,7 +564,7 @@ void DecodeIPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,

/* Pass to defragger if a fragment. */
if (IPV6_EXTHDR_ISSET_FH(p)) {
Packet *rp = Defrag(tv, dtv, NULL, p);
Packet *rp = Defrag(tv, dtv, p);
if (rp != NULL) {
DecodeIPV6(tv, dtv, rp, (uint8_t *)rp->ip6h, IPV6_GET_PLEN(rp) + IPV6_HEADER_LEN, pq);
PacketEnqueue(pq, rp);
Expand Down Expand Up @@ -725,6 +725,7 @@ static int DecodeIPV6FragTest01 (void) {
PacketQueue pq;

FlowInitConfig(FLOW_QUIET);
DefragInit();

memset(&pq, 0, sizeof(PacketQueue));
memset(&tv, 0, sizeof(ThreadVars));
Expand Down Expand Up @@ -765,6 +766,7 @@ static int DecodeIPV6FragTest01 (void) {
PACKET_CLEANUP(p2);
SCFree(p1);
SCFree(p2);
DefragDestroy();
FlowShutdown();
return result;
}
Expand Down
Loading

0 comments on commit 7a044a9

Please sign in to comment.