Skip to content

Commit 3ab1a3a

Browse files
committed
handle FIN flag in order of the sequence numbers
Signed-off-by: Matthias Klein <matthias@extraklein.de>
1 parent 6387499 commit 3ab1a3a

File tree

4 files changed

+39
-119
lines changed

4 files changed

+39
-119
lines changed

Packet++/header/TcpReassembly.h

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -404,9 +404,11 @@ namespace pcpp
404404
uint32_t sequence;
405405
size_t dataLength;
406406
uint8_t* data;
407+
uint32_t flowKey;
408+
bool isFin;
407409
std::chrono::time_point<std::chrono::high_resolution_clock> timestamp;
408410

409-
TcpFragment() : sequence(0), dataLength(0), data(nullptr)
411+
TcpFragment() : sequence(0), dataLength(0), data(nullptr), flowKey(0), isFin(false)
410412
{}
411413
~TcpFragment()
412414
{

Packet++/src/TcpReassembly.cpp

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -268,10 +268,10 @@ namespace pcpp
268268
return Ignore_PacketOfClosedFlow;
269269
}
270270

271-
// handle FIN/RST packets that don't contain additional TCP data
272-
if (isFinOrRst && tcpPayloadSize == 0)
271+
// handle RST packets that don't contain additional TCP data
272+
if (isRst && tcpPayloadSize == 0)
273273
{
274-
PCPP_LOG_DEBUG("Got FIN or RST packet without data on side " << sideIndex);
274+
PCPP_LOG_DEBUG("Got RST packet without data on side " << sideIndex);
275275

276276
handleFinOrRst(tcpReassemblyData, sideIndex, flowKey, isRst);
277277
return FIN_RSTWithNoData;
@@ -441,27 +441,36 @@ namespace pcpp
441441
{
442442
PCPP_LOG_DEBUG("Payload length is 0, doing nothing");
443443

444-
// handle case where this packet is FIN or RST
445-
if (isFinOrRst)
444+
// handle case where this packet is RST
445+
if (isRst)
446446
{
447447
handleFinOrRst(tcpReassemblyData, sideIndex, flowKey, isRst);
448448
status = FIN_RSTWithNoData;
449+
return status;
449450
}
450-
else
451+
452+
if(!isFin)
451453
{
452454
status = Ignore_PacketWithNoData;
453-
}
454-
455-
return status;
455+
return status;
456+
}
456457
}
457458

458459
// create a new TcpFragment, copy the TCP data to it and add this packet to the the out-of-order packet list
459460
TcpFragment* newTcpFrag = new TcpFragment();
460-
newTcpFrag->data = new uint8_t[tcpPayloadSize];
461+
462+
if(tcpPayloadSize)
463+
{
464+
newTcpFrag->data = new uint8_t[tcpPayloadSize];
465+
memcpy(newTcpFrag->data, tcpLayer->getLayerPayload(), tcpPayloadSize);
466+
}
467+
461468
newTcpFrag->dataLength = tcpPayloadSize;
462469
newTcpFrag->sequence = sequence;
463470
newTcpFrag->timestamp = currTime;
464-
memcpy(newTcpFrag->data, tcpLayer->getLayerPayload(), tcpPayloadSize);
471+
newTcpFrag->isFin = isFin;
472+
newTcpFrag->flowKey = flowKey;
473+
465474
tcpReassemblyData->twoSides[sideIndex].tcpFragmentList.pushBack(newTcpFrag);
466475

467476
PCPP_LOG_DEBUG("Found out-of-order packet and added a new TCP fragment with size "
@@ -476,8 +485,8 @@ namespace pcpp
476485
checkOutOfOrderFragments(tcpReassemblyData, sideIndex, false);
477486
}
478487

479-
// handle case where this packet is FIN or RST
480-
if (isFinOrRst)
488+
// handle case where this packet is RST
489+
if (isRst)
481490
{
482491
handleFinOrRst(tcpReassemblyData, sideIndex, flowKey, isRst);
483492
}
@@ -580,6 +589,12 @@ namespace pcpp
580589

581590
foundSomething = true;
582591

592+
if(curTcpFrag->isFin)
593+
{
594+
PCPP_LOG_DEBUG("handle saved FIN flag on sequence match");
595+
handleFinOrRst(tcpReassemblyData, sideIndex, curTcpFrag->flowKey, false);
596+
}
597+
583598
continue;
584599
}
585600

@@ -616,6 +631,12 @@ namespace pcpp
616631
}
617632

618633
foundSomething = true;
634+
635+
if(curTcpFrag->isFin)
636+
{
637+
PCPP_LOG_DEBUG("handle saved FIN flag on lower sequence");
638+
handleFinOrRst(tcpReassemblyData, sideIndex, curTcpFrag->flowKey, false);
639+
}
619640
}
620641
else
621642
{

Tests/Pcap++Test/PcapExamples/one_http_stream_fin2_output2.txt

Lines changed: 0 additions & 103 deletions
This file was deleted.

Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -721,13 +721,13 @@ PTF_TEST_CASE(TestTcpReassemblyWithFIN_RST)
721721
tcpReassemblyTest(packetStream, tcpReassemblyResults, true, false);
722722

723723
PTF_ASSERT_EQUAL(stats.size(), 1);
724-
PTF_ASSERT_EQUAL(stats.begin()->second.numOfDataPackets, 5);
724+
PTF_ASSERT_EQUAL(stats.begin()->second.numOfDataPackets, 6);
725725
PTF_ASSERT_EQUAL(stats.begin()->second.numOfMessagesFromSide[0], 1);
726726
PTF_ASSERT_EQUAL(stats.begin()->second.numOfMessagesFromSide[1], 1);
727727
PTF_ASSERT_TRUE(stats.begin()->second.connectionsStarted);
728728
PTF_ASSERT_TRUE(stats.begin()->second.connectionsEnded);
729729
PTF_ASSERT_FALSE(stats.begin()->second.connectionsEndedManually);
730-
expectedReassemblyData = readFileIntoString(std::string("PcapExamples/one_http_stream_fin2_output2.txt"));
730+
expectedReassemblyData = readFileIntoString(std::string("PcapExamples/one_http_stream_fin2_output.txt"));
731731
PTF_ASSERT_EQUAL(expectedReassemblyData, stats.begin()->second.reassembledData);
732732
} // TestTcpReassemblyWithFIN_RST
733733

0 commit comments

Comments
 (0)