diff --git a/Packet++/src/TcpReassembly.cpp b/Packet++/src/TcpReassembly.cpp index 3a696abf43..a415a8e4fa 100644 --- a/Packet++/src/TcpReassembly.cpp +++ b/Packet++/src/TcpReassembly.cpp @@ -227,6 +227,11 @@ TcpReassembly::ReassemblyStatus TcpReassembly::reassemblePacket(Packet& tcpData) if (tcpReassemblyData->twoSides[sideIndex].gotFinOrRst) { PCPP_LOG_DEBUG("Got a packet after FIN or RST were already seen on this side (" << static_cast(sideIndex) << "). Ignoring this packet"); + if (!tcpReassemblyData->twoSides[1 - sideIndex].gotFinOrRst && isRst) + { + handleFinOrRst(tcpReassemblyData, 1 - sideIndex, flowKey, isRst); + return FIN_RSTWithNoData; + } return Ignore_PacketOfClosedFlow; } diff --git a/Tests/Pcap++Test/TestDefinition.h b/Tests/Pcap++Test/TestDefinition.h index 29dbb1298f..32ab9978a6 100644 --- a/Tests/Pcap++Test/TestDefinition.h +++ b/Tests/Pcap++Test/TestDefinition.h @@ -77,6 +77,7 @@ PTF_TEST_CASE(TestTcpReassemblyMaxOOOFrags); PTF_TEST_CASE(TestTcpReassemblyMaxSeq); PTF_TEST_CASE(TestTcpReassemblyDisableOOOCleanup); PTF_TEST_CASE(TestTcpReassemblyTimeStamps); +PTF_TEST_CASE(TestTcpReassemblyFinishReset); // Implemented in IPFragmentationTests.cpp PTF_TEST_CASE(TestIPFragmentationSanity); diff --git a/Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp b/Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp index be663e0084..f266ef3701 100644 --- a/Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp +++ b/Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp @@ -1264,3 +1264,36 @@ PTF_TEST_CASE(TestTcpReassemblyTimeStamps) packetStream.clear(); tcpReassemblyResults.clear(); } // TestTcpReassemblyTimeStamps + +PTF_TEST_CASE(TestTcpReassemblyFinishReset) +{ + TcpReassemblyMultipleConnStats results; + std::string errMsg; + + pcpp::TcpReassemblyConfiguration config(true, 2, 1); + pcpp::TcpReassembly tcpReassembly(tcpReassemblyMsgReadyCallback, &results, tcpReassemblyConnectionStartCallback, + tcpReassemblyConnectionEndCallback, config); + + std::vector packetStream; + PTF_ASSERT_TRUE( + readPcapIntoPacketVec("PcapExamples/one_tcp_stream_fin_rst_close_packet.pcap", packetStream, errMsg)); + + pcpp::RawPacket lastPacket = packetStream.back(); + + packetStream.pop_back(); + + for (auto iter : packetStream) + { + pcpp::Packet packet(&iter); + tcpReassembly.reassemblePacket(packet); + } + + pcpp::TcpReassembly::ConnectionInfoList managedConnections = + tcpReassembly.getConnectionInformation(); // make a copy of list + PTF_ASSERT_EQUAL(managedConnections.size(), 1); + bool isOpen = tcpReassembly.isConnectionOpen(managedConnections.begin()->second); + PTF_ASSERT_FALSE(isOpen); + + packetStream.clear(); + +} // TestTcpReassemblyFinishReset diff --git a/Tests/Pcap++Test/main.cpp b/Tests/Pcap++Test/main.cpp index 4c38c16223..bc65ecd6ac 100644 --- a/Tests/Pcap++Test/main.cpp +++ b/Tests/Pcap++Test/main.cpp @@ -285,6 +285,7 @@ int main(int argc, char* argv[]) PTF_RUN_TEST(TestTcpReassemblyMaxSeq, "no_network;tcp_reassembly"); PTF_RUN_TEST(TestTcpReassemblyDisableOOOCleanup, "no_network;tcp_reassembly"); PTF_RUN_TEST(TestTcpReassemblyTimeStamps, "no_network;tcp_reassembly"); + PTF_RUN_TEST(TestTcpReassemblyFinishReset, "no_network;tcp_reassembly"); PTF_RUN_TEST(TestIPFragmentationSanity, "no_network;ip_frag"); PTF_RUN_TEST(TestIPFragOutOfOrder, "no_network;ip_frag");