From 2ea3541ee6256b9e3fd69aeec22269e3180d12fb Mon Sep 17 00:00:00 2001 From: prudens Date: Wed, 25 Sep 2024 16:07:48 +0800 Subject: [PATCH] TCP reassembly - support closing connection with FIN + RST on one side (#1496) --- Packet++/src/TcpReassembly.cpp | 7 +++++++ .../one_tcp_stream_fin_rst_close_packet.pcap | Bin 0 -> 1307 bytes Tests/Pcap++Test/TestDefinition.h | 1 + Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp | 18 ++++++++++++++++++ Tests/Pcap++Test/main.cpp | 1 + 5 files changed, 27 insertions(+) create mode 100755 Tests/Pcap++Test/PcapExamples/one_tcp_stream_fin_rst_close_packet.pcap diff --git a/Packet++/src/TcpReassembly.cpp b/Packet++/src/TcpReassembly.cpp index 697041c915..7e958aa953 100644 --- a/Packet++/src/TcpReassembly.cpp +++ b/Packet++/src/TcpReassembly.cpp @@ -232,8 +232,15 @@ namespace pcpp // if this side already got FIN or RST packet before, ignore this packet as this side is considered closed if (tcpReassemblyData->twoSides[sideIndex].gotFinOrRst) { + if (!tcpReassemblyData->twoSides[1 - sideIndex].gotFinOrRst && isRst) + { + handleFinOrRst(tcpReassemblyData, 1 - sideIndex, flowKey, isRst); + return FIN_RSTWithNoData; + } + PCPP_LOG_DEBUG("Got a packet after FIN or RST were already seen on this side (" << static_cast(sideIndex) << "). Ignoring this packet"); + return Ignore_PacketOfClosedFlow; } diff --git a/Tests/Pcap++Test/PcapExamples/one_tcp_stream_fin_rst_close_packet.pcap b/Tests/Pcap++Test/PcapExamples/one_tcp_stream_fin_rst_close_packet.pcap new file mode 100755 index 0000000000000000000000000000000000000000..208a6123e4f3a70c1276936ea2c1596bda93db7a GIT binary patch literal 1307 zcmaKrPiWIn9LImF{X45>b%TMIuBzs&7ySBr)wrP_xb(hZJ zz(bFE+`$b*svs71;Ayav1I2?E5AI}L*LAql#2uXPy;4k*;)6$CAn)@&zwhtm%WCnd z4)pME=%EF@ywAJ}`;8VDKx;f9IJ)`O4Av9*^F}iS08Tnfe()RD&a6EDHusW(bYa(8 z>0PM4!ykur5_OOR(CH0tYOG>N!6K9zvBnBG0A`JaKbV7g)=FVFmuEK+Z#it++xhre z$+~w`v}xqZ z*bRH=LXfpH{cf7!e6-um&`jf-$8G0Wcc0Jh@wm7{t@!BSQAHW*NO}U@IFc8jilmGp zsRpUNozfUK#sjnDaSJ>|YdmXBQp7tQaFTdmH)VD1?c}QfLug~Gm+qrIE_h-BxOB(d zW(!RA!2YjOI@o{EfyuQoxh}_$(Rmq?_vK82PeroAbevB|WcjWr#fX!QSJbC% zQ<+3Npo+Gd%X>N8rsP)rI9y-Hgawc!nVL4OJ2x@w!+cW~YSSRPltqA+`DZx{^>@|L zs;4B1S!iE>YkCyDy4IbUT8YetMh+Xr?6KxmMh@_zY`89@IM&KX6GA+dMM)&%=7cao zcIf%E5HoO`i*=d!>}@F?i5a{;mfWZg`MmkJPtM$0b=1QzphmGqjt< zwL?^qqxPO0Z}#hWx!#5CMSM@bhw4TCMy!yaU}<|&Aw4$=}8;v39Dq?RI;>Q zbHr=0@y-#iCFJ$9(Q91E(t2$XuYQ%+67gzBUM{8A#D7_zteEBKRI@N4s0Vm_w9fhq D@;HLg literal 0 HcmV?d00001 diff --git a/Tests/Pcap++Test/TestDefinition.h b/Tests/Pcap++Test/TestDefinition.h index 2ed9ac12b5..57a7cb8e1d 100644 --- a/Tests/Pcap++Test/TestDefinition.h +++ b/Tests/Pcap++Test/TestDefinition.h @@ -78,6 +78,7 @@ PTF_TEST_CASE(TestTcpReassemblyMaxOOOFrags); PTF_TEST_CASE(TestTcpReassemblyMaxSeq); PTF_TEST_CASE(TestTcpReassemblyDisableOOOCleanup); PTF_TEST_CASE(TestTcpReassemblyTimeStamps); +PTF_TEST_CASE(TestTcpReassemblyFinReset); // 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 094f0ebdad..e43ebcd7f6 100644 --- a/Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp +++ b/Tests/Pcap++Test/Tests/TcpReassemblyTests.cpp @@ -1263,3 +1263,21 @@ PTF_TEST_CASE(TestTcpReassemblyTimeStamps) packetStream.clear(); tcpReassemblyResults.clear(); } // TestTcpReassemblyTimeStamps + +PTF_TEST_CASE(TestTcpReassemblyFinReset) +{ + std::string errMsg; + + std::vector packetStream; + PTF_ASSERT_TRUE( + readPcapIntoPacketVec("PcapExamples/one_tcp_stream_fin_rst_close_packet.pcap", packetStream, errMsg)); + + TcpReassemblyMultipleConnStats tcpReassemblyResults; + tcpReassemblyTest(packetStream, tcpReassemblyResults, true, false); + + TcpReassemblyMultipleConnStats::Stats& stats = tcpReassemblyResults.stats; + PTF_ASSERT_EQUAL(stats.size(), 1); + PTF_ASSERT_TRUE(stats.begin()->second.connectionsStarted); + PTF_ASSERT_TRUE(stats.begin()->second.connectionsEnded); + PTF_ASSERT_FALSE(stats.begin()->second.connectionsEndedManually); +} // TestTcpReassemblyFinReset diff --git a/Tests/Pcap++Test/main.cpp b/Tests/Pcap++Test/main.cpp index 3e6479110f..5cd7da0a5b 100644 --- a/Tests/Pcap++Test/main.cpp +++ b/Tests/Pcap++Test/main.cpp @@ -289,6 +289,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(TestTcpReassemblyFinReset, "no_network;tcp_reassembly"); PTF_RUN_TEST(TestIPFragmentationSanity, "no_network;ip_frag"); PTF_RUN_TEST(TestIPFragOutOfOrder, "no_network;ip_frag");