From 8e926b3ff85acf293f79d1f5af80379fb06a6f7b Mon Sep 17 00:00:00 2001 From: Puasonych Date: Sun, 1 Jul 2018 14:02:26 +0300 Subject: [PATCH 01/10] The first attempt to add protection against lossy traffic --- .gitignore | 1 + include/tins/ip_reassembler.h | 37 +++++++++++ src/ip_reassembler.cpp | 106 ++++++++++++++++++++++++++++-- tests/src/ip_reassembler_test.cpp | 4 ++ 4 files changed, 142 insertions(+), 6 deletions(-) diff --git a/.gitignore b/.gitignore index 6109d958..9b1b3744 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ build/** include/tins/config.h +.vscode/** \ No newline at end of file diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index 3fd0524f..f9127c8e 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -32,6 +32,9 @@ #include #include +#include +#include +#include #include #include #include @@ -70,11 +73,15 @@ class IPv4Fragment { class TINS_API IPv4Stream { public: IPv4Stream(); + + typedef std::chrono::system_clock::time_point time_point; void add_fragment(IP* ip); bool is_complete() const; PDU* allocate_pdu() const; const IP& first_fragment() const; + size_t number_fragments() const; + time_point start_time_point() const; private: typedef std::vector fragments_type; @@ -86,6 +93,7 @@ class TINS_API IPv4Stream { size_t total_size_; IP first_fragment_; bool received_end_; + time_point start_time_point_; }; } // namespace Internals @@ -130,6 +138,8 @@ class TINS_API IPv4Reassembler { TINS_DEPRECATED(typedef PacketStatus packet_status); + typedef std::function StreamCallback; + /** * The type used to represent the overlapped segment reassembly * technique to be used. @@ -183,16 +193,43 @@ class TINS_API IPv4Reassembler { * \sa IP::id */ void remove_stream(uint16_t id, IPv4Address addr1, IPv4Address addr2); + + /** + * \brief + * + * \param max_number + * \param callback + */ + void set_max_number_packets_to_stream(size_t max_number, StreamCallback callback = 0); + + /** + * \brief + * + * \param stream_timeout_ms + * \param time_to_check_s + * \param callback + */ + void set_timeout_to_stream(size_t stream_timeout_ms, size_t time_to_check_s = 60, StreamCallback callback = 0); private: typedef std::pair address_pair; typedef std::pair key_type; typedef std::map streams_type; + typedef std::list> streams_history; key_type make_key(const IP* ip) const; address_pair make_address_pair(IPv4Address addr1, IPv4Address addr2) const; + void removal_expired_streams(); streams_type streams_; OverlappingTechnique technique_; + size_t max_number_packets_to_stream_; + size_t stream_timeout_ms_; + size_t time_to_check_s_; + Internals::IPv4Stream::time_point origin_cycle_time_; + streams_history streams_history_; + + StreamCallback stream_overflow_callback_; + StreamCallback stream_timeout_callback_; }; /** diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 744b4c30..041d3b5d 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -38,7 +38,8 @@ namespace Tins { namespace Internals { IPv4Stream::IPv4Stream() -: received_size_(), total_size_(), received_end_(false) { +: received_size_(), total_size_(), received_end_(false), + start_time_point_(std::chrono::system_clock::now()) { } @@ -100,6 +101,14 @@ const IP& IPv4Stream::first_fragment() const { return first_fragment_; } +size_t IPv4Stream::number_fragments() const { + return fragments_.size(); +} + +IPv4Stream::time_point IPv4Stream::start_time_point() const { + return start_time_point_; +} + uint16_t IPv4Stream::extract_offset(const IP* ip) { return ip->fragment_offset() * 8; } @@ -107,23 +116,36 @@ uint16_t IPv4Stream::extract_offset(const IP* ip) { } // Internals IPv4Reassembler::IPv4Reassembler() -: technique_(NONE) { +: technique_(NONE), max_number_packets_to_stream_(0), + stream_timeout_ms_(0), origin_cycle_time_(std::chrono::system_clock::now()), + stream_overflow_callback_(0), stream_timeout_callback_(0) { } IPv4Reassembler::IPv4Reassembler(OverlappingTechnique technique) -: technique_(technique) { +: technique_(technique), max_number_packets_to_stream_(0), + stream_timeout_ms_(0), origin_cycle_time_(std::chrono::system_clock::now()), + stream_overflow_callback_(0), stream_timeout_callback_(0) { } IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { + // Removal of expired streams + removal_expired_streams(); + IP* ip = pdu.find_pdu(); if (ip && ip->inner_pdu()) { // There's fragmentation if (ip->is_fragmented()) { key_type key = make_key(ip); + // + streams_type::iterator stream_it = streams_.find(key); // Create it or look it up, it's the same - Internals::IPv4Stream& stream = streams_[key]; + Internals::IPv4Stream& stream = (stream_it != streams_.end() ? stream_it->second : streams_[key]); + if (stream_timeout_ms_ && stream_it == streams_.end()) { + streams_history_.emplace_back(key, stream.start_time_point()); + } + stream.add_fragment(ip); if (stream.is_complete()) { PDU* pdu = stream.allocate_pdu(); @@ -132,6 +154,7 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { // Erase this stream, since it's already assembled streams_.erase(key); + // The packet is corrupt if (!pdu) { return FRAGMENTED; @@ -139,11 +162,30 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { ip->inner_pdu(pdu); ip->fragment_offset(0); ip->flags(static_cast(0)); + return REASSEMBLED; } - else { - return FRAGMENTED; + + // Tracking overflow stream + if (max_number_packets_to_stream_ + && stream.number_fragments() >= max_number_packets_to_stream_) + { + if (stream_overflow_callback_) + { + PDU* pdu = stream.allocate_pdu(); + + // The packet is not corrupt + if (pdu) { + stream_overflow_callback_(*pdu); + delete pdu; + } + } + + // Erase this stream + streams_.erase(key); } + + return FRAGMENTED; } } return NOT_FRAGMENTED; @@ -165,6 +207,47 @@ IPv4Reassembler::address_pair IPv4Reassembler::make_address_pair(IPv4Address add } } +void IPv4Reassembler::removal_expired_streams() +{ + if (!stream_timeout_ms_) return; + + Internals::IPv4Stream::time_point now = std::chrono::system_clock::now(); + auto step = std::chrono::duration_cast(now - origin_cycle_time_); + if (std::chrono::seconds(time_to_check_s_) < step) { + return; + } + + while (!streams_history_.empty()) { + streams_history::value_type & history_front = streams_history_.front(); + streams_type::iterator stream_it = streams_.find(history_front.first); + if (stream_it == streams_.end()) { + streams_history_.pop_front(); + continue; + } + Internals::IPv4Stream& stream_tmp = stream_it->second; + if (stream_tmp.start_time_point() != history_front.second) { + streams_history_.pop_front(); + continue; + } + + auto diff = std::chrono::duration_cast(now - history_front.second); + if ((size_t)diff.count() > stream_timeout_ms_) { + if (stream_timeout_callback_) { + PDU* pdu = stream_tmp.allocate_pdu(); + + // The packet is not corrupt + if (pdu) { + stream_timeout_callback_(*pdu); + delete pdu; + } + } + // Erase this stream + streams_.erase(history_front.first); + streams_history_.pop_front(); + } else break; + } +} + void IPv4Reassembler::clear_streams() { streams_.clear(); } @@ -178,4 +261,15 @@ void IPv4Reassembler::remove_stream(uint16_t id, IPv4Address addr1, IPv4Address ); } +void IPv4Reassembler::set_max_number_packets_to_stream(size_t max_number, StreamCallback callback) { + max_number_packets_to_stream_ = max_number; + stream_overflow_callback_ = callback; +} + +void IPv4Reassembler::set_timeout_to_stream(size_t stream_timeout_ms, size_t time_to_check_s, StreamCallback callback) { + stream_timeout_ms_ = stream_timeout_ms; + time_to_check_s_ = time_to_check_s; + stream_timeout_callback_ = callback; +} + } // Tins diff --git a/tests/src/ip_reassembler_test.cpp b/tests/src/ip_reassembler_test.cpp index fb049b48..2697501b 100644 --- a/tests/src/ip_reassembler_test.cpp +++ b/tests/src/ip_reassembler_test.cpp @@ -49,6 +49,8 @@ const size_t IPv4ReassemblerTest::orderings[][11] = { void IPv4ReassemblerTest::test_packets(const vector >& vt) { IPv4Reassembler reassembler; + reassembler.set_max_number_packets_to_stream(500); + reassembler.set_timeout_to_stream(1000); for(size_t i = 0; i < vt.size(); ++i) { EthernetII eth(vt[i].first, (uint32_t)vt[i].second); // Set the TTL for the first fragment to 32 so we can make sure the right "base" @@ -112,6 +114,8 @@ TEST_F(IPv4ReassemblerTest, PacketHasMFAndDF) { EXPECT_TRUE(packet1.rfind_pdu().is_fragmented()); EXPECT_TRUE(packet2.rfind_pdu().is_fragmented()); IPv4Reassembler reassembler; + reassembler.set_max_number_packets_to_stream(500); + reassembler.set_timeout_to_stream(1000); EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet1)); EXPECT_EQ(IPv4Reassembler::REASSEMBLED, reassembler.process(packet2)); } From ee99633622c37302bc098c6999be93dba8295d71 Mon Sep 17 00:00:00 2001 From: Puasonych Date: Mon, 2 Jul 2018 11:35:30 +0300 Subject: [PATCH 02/10] Update IPv4Reassembler --- include/tins/ip_reassembler.h | 37 ++++++++++++++++++++++++------ src/ip_reassembler.cpp | 38 ++++++++++++++++++++++++------- tests/src/ip_reassembler_test.cpp | 8 +++++++ 3 files changed, 68 insertions(+), 15 deletions(-) diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index f9127c8e..d7dadd5e 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -195,21 +195,40 @@ class TINS_API IPv4Reassembler { void remove_stream(uint16_t id, IPv4Address addr1, IPv4Address addr2); /** - * \brief + * \brief A limit is set for each streams. + * If max_number == 0, then there are no restrictions. * - * \param max_number - * \param callback + * \param max_number Maximum number of packets per stream + * \param callback If set, it is called for each overflow stream */ void set_max_number_packets_to_stream(size_t max_number, StreamCallback callback = 0); /** - * \brief + * \brief Set the lifetime for each streams. + * The list of existing streams is checked with a specified time step. + * Attention, the check does not occur in a separate thread, + * but on each incoming package. * - * \param stream_timeout_ms - * \param time_to_check_s - * \param callback + * \param stream_timeout_ms The lifetime of a single stream (milliseconds) + * \param time_to_check_s Time step for verification (seconds) + * \param callback If set, it is called for each expired valid stream */ void set_timeout_to_stream(size_t stream_timeout_ms, size_t time_to_check_s = 60, StreamCallback callback = 0); + + /** + * \brief Return the total number of complete packets + */ + size_t total_number_complete_packages() const; + + /** + * \brief Return the total number of damaged packages + */ + size_t total_number_damaged_packages() const; + + /** + * \brief Return the current number of incomplete packets + */ + size_t current_number_incomplete_packages() const; private: typedef std::pair address_pair; typedef std::pair key_type; @@ -230,6 +249,10 @@ class TINS_API IPv4Reassembler { StreamCallback stream_overflow_callback_; StreamCallback stream_timeout_callback_; + + // Statistic + size_t total_number_complete_packages_; + size_t total_number_damaged_packages_; }; /** diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 041d3b5d..73f0ca5c 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -118,14 +118,16 @@ uint16_t IPv4Stream::extract_offset(const IP* ip) { IPv4Reassembler::IPv4Reassembler() : technique_(NONE), max_number_packets_to_stream_(0), stream_timeout_ms_(0), origin_cycle_time_(std::chrono::system_clock::now()), - stream_overflow_callback_(0), stream_timeout_callback_(0) { + stream_overflow_callback_(0), stream_timeout_callback_(0), + total_number_complete_packages_(0), total_number_damaged_packages_(0) { } IPv4Reassembler::IPv4Reassembler(OverlappingTechnique technique) : technique_(technique), max_number_packets_to_stream_(0), stream_timeout_ms_(0), origin_cycle_time_(std::chrono::system_clock::now()), - stream_overflow_callback_(0), stream_timeout_callback_(0) { + stream_overflow_callback_(0), stream_timeout_callback_(0), + total_number_complete_packages_(0), total_number_damaged_packages_(0) { } @@ -138,16 +140,14 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { // There's fragmentation if (ip->is_fragmented()) { key_type key = make_key(ip); - // - streams_type::iterator stream_it = streams_.find(key); // Create it or look it up, it's the same + streams_type::iterator stream_it = streams_.find(key); Internals::IPv4Stream& stream = (stream_it != streams_.end() ? stream_it->second : streams_[key]); - if (stream_timeout_ms_ && stream_it == streams_.end()) { - streams_history_.emplace_back(key, stream.start_time_point()); - } stream.add_fragment(ip); if (stream.is_complete()) { + ++total_number_complete_packages_; + PDU* pdu = stream.allocate_pdu(); // Use all field values from the first fragment *ip = stream.first_fragment(); @@ -157,6 +157,7 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { // The packet is corrupt if (!pdu) { + ++total_number_damaged_packages_; return FRAGMENTED; } ip->inner_pdu(pdu); @@ -165,6 +166,11 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { return REASSEMBLED; } + + // Only non-complete packages fall into the list + if (stream_timeout_ms_ && stream_it == streams_.end()) { + streams_history_.emplace_back(key, stream.start_time_point()); + } // Tracking overflow stream if (max_number_packets_to_stream_ @@ -178,6 +184,8 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { if (pdu) { stream_overflow_callback_(*pdu); delete pdu; + } else { + ++total_number_damaged_packages_; } } @@ -209,7 +217,7 @@ IPv4Reassembler::address_pair IPv4Reassembler::make_address_pair(IPv4Address add void IPv4Reassembler::removal_expired_streams() { - if (!stream_timeout_ms_) return; + if (!stream_timeout_ms_ || streams_history_.empty()) return; Internals::IPv4Stream::time_point now = std::chrono::system_clock::now(); auto step = std::chrono::duration_cast(now - origin_cycle_time_); @@ -239,6 +247,8 @@ void IPv4Reassembler::removal_expired_streams() if (pdu) { stream_timeout_callback_(*pdu); delete pdu; + } else { + ++total_number_damaged_packages_; } } // Erase this stream @@ -272,4 +282,16 @@ void IPv4Reassembler::set_timeout_to_stream(size_t stream_timeout_ms, size_t tim stream_timeout_callback_ = callback; } +size_t IPv4Reassembler::total_number_complete_packages() const { + return total_number_complete_packages_; +} + +size_t IPv4Reassembler::total_number_damaged_packages() const { + return total_number_damaged_packages_; +} + +size_t IPv4Reassembler::current_number_incomplete_packages() const { + return streams_.size(); +} + } // Tins diff --git a/tests/src/ip_reassembler_test.cpp b/tests/src/ip_reassembler_test.cpp index 2697501b..bf48a174 100644 --- a/tests/src/ip_reassembler_test.cpp +++ b/tests/src/ip_reassembler_test.cpp @@ -116,6 +116,14 @@ TEST_F(IPv4ReassemblerTest, PacketHasMFAndDF) { IPv4Reassembler reassembler; reassembler.set_max_number_packets_to_stream(500); reassembler.set_timeout_to_stream(1000); + EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet1)); + EXPECT_EQ(0, reassembler.total_number_complete_packages()); + EXPECT_EQ(1, reassembler.current_number_incomplete_packages()); + EXPECT_EQ(0, reassembler.total_number_damaged_packages()); + EXPECT_EQ(IPv4Reassembler::REASSEMBLED, reassembler.process(packet2)); + EXPECT_EQ(1, reassembler.total_number_complete_packages()); + EXPECT_EQ(0, reassembler.current_number_incomplete_packages()); + EXPECT_EQ(0, reassembler.total_number_damaged_packages()); } From 5557baffc59a467fbe1d6b7c50505a23e8cd33bd Mon Sep 17 00:00:00 2001 From: Puasonych Date: Mon, 2 Jul 2018 13:25:41 +0300 Subject: [PATCH 03/10] Add new test for IPv4Reassembler --- include/tins/ip_reassembler.h | 7 +++- src/ip_reassembler.cpp | 4 +++ tests/src/ip_reassembler_test.cpp | 60 ++++++++++++++++++++++++++++--- 3 files changed, 65 insertions(+), 6 deletions(-) diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index d7dadd5e..6e5757da 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -229,6 +229,11 @@ class TINS_API IPv4Reassembler { * \brief Return the current number of incomplete packets */ size_t current_number_incomplete_packages() const; + + /** + * \brief Returns the current size of the partial-packet buffer + */ + size_t current_buffer_size_incomplete_packages() const; private: typedef std::pair address_pair; typedef std::pair key_type; @@ -250,7 +255,7 @@ class TINS_API IPv4Reassembler { StreamCallback stream_overflow_callback_; StreamCallback stream_timeout_callback_; - // Statistic + // Statistics size_t total_number_complete_packages_; size_t total_number_damaged_packages_; }; diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 73f0ca5c..cdbf4c78 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -294,4 +294,8 @@ size_t IPv4Reassembler::current_number_incomplete_packages() const { return streams_.size(); } +size_t IPv4Reassembler::current_buffer_size_incomplete_packages() const { + return streams_history_.size(); +} + } // Tins diff --git a/tests/src/ip_reassembler_test.cpp b/tests/src/ip_reassembler_test.cpp index bf48a174..504092e6 100644 --- a/tests/src/ip_reassembler_test.cpp +++ b/tests/src/ip_reassembler_test.cpp @@ -7,6 +7,20 @@ #include #include #include +#ifdef WIN32 + #include +#else + #include +#endif // win32 + +void sleepcp(int milliseconds) // Cross-platform sleep function +{ + #ifdef WIN32 + Sleep(milliseconds); + #else + usleep(milliseconds * 1000); + #endif // win32 +} using std::vector; using std::pair; @@ -50,7 +64,7 @@ const size_t IPv4ReassemblerTest::orderings[][11] = { void IPv4ReassemblerTest::test_packets(const vector >& vt) { IPv4Reassembler reassembler; reassembler.set_max_number_packets_to_stream(500); - reassembler.set_timeout_to_stream(1000); + reassembler.set_timeout_to_stream(100); for(size_t i = 0; i < vt.size(); ++i) { EthernetII eth(vt[i].first, (uint32_t)vt[i].second); // Set the TTL for the first fragment to 32 so we can make sure the right "base" @@ -115,15 +129,51 @@ TEST_F(IPv4ReassemblerTest, PacketHasMFAndDF) { EXPECT_TRUE(packet2.rfind_pdu().is_fragmented()); IPv4Reassembler reassembler; reassembler.set_max_number_packets_to_stream(500); - reassembler.set_timeout_to_stream(1000); + reassembler.set_timeout_to_stream(100); + + EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet1)); + EXPECT_EQ(IPv4Reassembler::REASSEMBLED, reassembler.process(packet2)); +} + + +TEST_F(IPv4ReassemblerTest, PackageWasDeletedByTimeout) { + const uint8_t raw_packet1[] = { + 0, 80, 86, 173, 75, 110, 170, 0, 4, 0, 10, 4, 8, 0, 69, 0, 0, 124, 146, + 205, 96, 0, 64, 6, 107, 153, 7, 7, 7, 7, 7, 7, 7, 1, 152, 191, 0, 80, + 160, 119, 38, 106, 125, 14, 42, 154, 128, 24, 0, 115, 148, 65, 0, 0, 1, + 1, 8, 10, 4, 255, 180, 163, 4, 255, 176, 151, 71, 69, 84, 32, 47, 49, 46, + 104, 116, 109, 108, 63, 32, 72, 84, 84, 80, 47, 49, 46, 49, 13, 10, 85, + 115, 101, 114, 45, 65, 103, 101, 110, 116, 58, 32, 87, 103, 101, 116, + 47, 49, 46, 49, 51, 46, 52, 32, 40, 108, 105, 110, 117, 120, 45, 103, + 110, 117, 41, 13, 10, 65, 99, 99, 101, 112, 116, 58, 32, 42, 47, 42, 13 + }; + const uint8_t raw_packet2[] = { + 0, 80, 86, 173, 75, 110, 170, 0, 4, 0, 10, 4, 8, 0, 69, 0, 0, 62, 146, + 205, 64, 13, 64, 6, 139, 202, 7, 7, 7, 7, 7, 7, 7, 1, 10, 72, 111, 115, + 116, 58, 32, 55, 46, 55, 46, 55, 46, 49, 13, 10, 67, 111, 110, 110, + 101, 99, 116, 105, 111, 110, 58, 32, 75, 101, 101, 112, 45, 65, 108, + 105, 118, 101, 13, 10, 13, 10 + }; + EthernetII packet1(raw_packet1, sizeof(raw_packet1)); + EthernetII packet2(raw_packet2, sizeof(raw_packet2)); + EXPECT_TRUE(packet1.rfind_pdu().is_fragmented()); + EXPECT_TRUE(packet2.rfind_pdu().is_fragmented()); + IPv4Reassembler reassembler; + reassembler.set_max_number_packets_to_stream(500); + reassembler.set_timeout_to_stream(100); EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet1)); EXPECT_EQ(0, reassembler.total_number_complete_packages()); EXPECT_EQ(1, reassembler.current_number_incomplete_packages()); EXPECT_EQ(0, reassembler.total_number_damaged_packages()); + EXPECT_EQ(1, reassembler.current_buffer_size_incomplete_packages()); - EXPECT_EQ(IPv4Reassembler::REASSEMBLED, reassembler.process(packet2)); - EXPECT_EQ(1, reassembler.total_number_complete_packages()); - EXPECT_EQ(0, reassembler.current_number_incomplete_packages()); + sleepcp(1000); + + EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet2)); + + EXPECT_EQ(0, reassembler.total_number_complete_packages()); + EXPECT_EQ(1, reassembler.current_number_incomplete_packages()); EXPECT_EQ(0, reassembler.total_number_damaged_packages()); + EXPECT_EQ(1, reassembler.current_buffer_size_incomplete_packages()); } From 09974385c8a2d56183f0fb6a3e3651e576e0e7e7 Mon Sep 17 00:00:00 2001 From: "e.basargin" Date: Tue, 3 Jul 2018 10:55:29 +0500 Subject: [PATCH 04/10] GNU 4.8.3 compiler support added for IPv4Reasembler --- include/tins/ip_reassembler.h | 29 +++++++++--- src/ip_reassembler.cpp | 73 ++++++++++++++++++++++++------- tests/src/ip_reassembler_test.cpp | 1 + 3 files changed, 81 insertions(+), 22 deletions(-) diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index 6e5757da..46e1b8ac 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -33,8 +33,13 @@ #include #include #include +#if TINS_IS_CXX11 #include #include +#else +#include +#include +#endif #include #include #include @@ -74,7 +79,12 @@ class TINS_API IPv4Stream { public: IPv4Stream(); +#if TINS_IS_CXX11 typedef std::chrono::system_clock::time_point time_point; +#else + typedef uint64_t time_point; + static uint64_t current_time(); +#endif void add_fragment(IP* ip); bool is_complete() const; @@ -138,7 +148,11 @@ class TINS_API IPv4Reassembler { TINS_DEPRECATED(typedef PacketStatus packet_status); +#if TINS_IS_CXX11 typedef std::function StreamCallback; +#else + typedef void (*StreamCallback)(PDU& pdu); +#endif /** * The type used to represent the overlapped segment reassembly @@ -201,7 +215,7 @@ class TINS_API IPv4Reassembler { * \param max_number Maximum number of packets per stream * \param callback If set, it is called for each overflow stream */ - void set_max_number_packets_to_stream(size_t max_number, StreamCallback callback = 0); + void set_max_number_packets_to_stream(uint64_t max_number, StreamCallback callback = 0); /** * \brief Set the lifetime for each streams. @@ -213,7 +227,7 @@ class TINS_API IPv4Reassembler { * \param time_to_check_s Time step for verification (seconds) * \param callback If set, it is called for each expired valid stream */ - void set_timeout_to_stream(size_t stream_timeout_ms, size_t time_to_check_s = 60, StreamCallback callback = 0); + void set_timeout_to_stream(uint64_t stream_timeout_ms, uint64_t time_to_check_s = 60, StreamCallback callback = 0); /** * \brief Return the total number of complete packets @@ -238,7 +252,7 @@ class TINS_API IPv4Reassembler { typedef std::pair address_pair; typedef std::pair key_type; typedef std::map streams_type; - typedef std::list> streams_history; + typedef std::list< std::pair > streams_history; key_type make_key(const IP* ip) const; address_pair make_address_pair(IPv4Address addr1, IPv4Address addr2) const; @@ -246,15 +260,16 @@ class TINS_API IPv4Reassembler { streams_type streams_; OverlappingTechnique technique_; - size_t max_number_packets_to_stream_; - size_t stream_timeout_ms_; - size_t time_to_check_s_; - Internals::IPv4Stream::time_point origin_cycle_time_; + uint64_t max_number_packets_to_stream_; + uint64_t stream_timeout_ms_; + uint64_t time_to_check_s_; streams_history streams_history_; StreamCallback stream_overflow_callback_; StreamCallback stream_timeout_callback_; + Internals::IPv4Stream::time_point origin_cycle_time_; + // Statistics size_t total_number_complete_packages_; size_t total_number_damaged_packages_; diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index cdbf4c78..068224a3 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -38,10 +38,31 @@ namespace Tins { namespace Internals { IPv4Stream::IPv4Stream() -: received_size_(), total_size_(), received_end_(false), - start_time_point_(std::chrono::system_clock::now()) { +: received_size_(), total_size_(), received_end_(false) { +#if TINS_IS_CXX11 + start_time_point_ = std::chrono::system_clock::now(); +#else + start_time_point_ = current_time(); +#endif +} +#if TINS_IS_CXX11 == 0 +uint64_t IPv4Stream::current_time() { + #ifdef _WIN32 + FILETIME file_time; + GetSystemTimeAsFileTime(&file_time); + ULARGE_INTEGER ul; + ul.LowPart = ft.dwLowDateTime; + ul.HighPart = ft.dwHighDateTime; + uint64_t file_time_64 = ul.QuadPart; + return file_time_64; + #else + timespec ts = { 0 }; + clock_gettime(CLOCK_MONOTONIC, &ts); + return ((uint64_t)ts.tv_sec) * 1000 + ((uint64_t)ts.tv_nsec) / 1000000; + #endif } +#endif void IPv4Stream::add_fragment(IP* ip) { const uint16_t offset = extract_offset(ip); @@ -117,18 +138,24 @@ uint16_t IPv4Stream::extract_offset(const IP* ip) { IPv4Reassembler::IPv4Reassembler() : technique_(NONE), max_number_packets_to_stream_(0), - stream_timeout_ms_(0), origin_cycle_time_(std::chrono::system_clock::now()), - stream_overflow_callback_(0), stream_timeout_callback_(0), - total_number_complete_packages_(0), total_number_damaged_packages_(0) { - + stream_timeout_ms_(0), stream_overflow_callback_(0), stream_timeout_callback_(0), + total_number_complete_packages_(0), total_number_damaged_packages_(0) { +#if TINS_IS_CXX11 + origin_cycle_time_ = std::chrono::system_clock::now(); +#else + origin_cycle_time_ = Internals::IPv4Stream::current_time(); +#endif } IPv4Reassembler::IPv4Reassembler(OverlappingTechnique technique) : technique_(technique), max_number_packets_to_stream_(0), - stream_timeout_ms_(0), origin_cycle_time_(std::chrono::system_clock::now()), - stream_overflow_callback_(0), stream_timeout_callback_(0), - total_number_complete_packages_(0), total_number_damaged_packages_(0) { - + stream_timeout_ms_(0), stream_overflow_callback_(0), stream_timeout_callback_(0), + total_number_complete_packages_(0), total_number_damaged_packages_(0) { +#if TINS_IS_CXX11 + origin_cycle_time_ = std::chrono::system_clock::now(); +#else + origin_cycle_time_ = Internals::IPv4Stream::current_time(); +#endif } IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { @@ -169,7 +196,11 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { // Only non-complete packages fall into the list if (stream_timeout_ms_ && stream_it == streams_.end()) { +#if TINS_IS_CXX11 streams_history_.emplace_back(key, stream.start_time_point()); +#else + streams_history_.push_back(std::make_pair(key, stream.start_time_point())); +#endif } // Tracking overflow stream @@ -219,11 +250,19 @@ void IPv4Reassembler::removal_expired_streams() { if (!stream_timeout_ms_ || streams_history_.empty()) return; +#if TINS_IS_CXX11 Internals::IPv4Stream::time_point now = std::chrono::system_clock::now(); auto step = std::chrono::duration_cast(now - origin_cycle_time_); if (std::chrono::seconds(time_to_check_s_) < step) { return; } +#else + uint64_t now = Internals::IPv4Stream::current_time(); + uint64_t step = now - origin_cycle_time_; + if (time_to_check_s_ * 1000 < step) { + return; + } +#endif while (!streams_history_.empty()) { streams_history::value_type & history_front = streams_history_.front(); @@ -231,15 +270,19 @@ void IPv4Reassembler::removal_expired_streams() if (stream_it == streams_.end()) { streams_history_.pop_front(); continue; - } + } Internals::IPv4Stream& stream_tmp = stream_it->second; if (stream_tmp.start_time_point() != history_front.second) { streams_history_.pop_front(); continue; } - +#if TINS_IS_CXX11 auto diff = std::chrono::duration_cast(now - history_front.second); - if ((size_t)diff.count() > stream_timeout_ms_) { + if ((uint64_t)diff.count() > stream_timeout_ms_) { +#else + uint64_t diff = now - history_front.second; + if (diff > stream_timeout_ms_) { +#endif if (stream_timeout_callback_) { PDU* pdu = stream_tmp.allocate_pdu(); @@ -271,12 +314,12 @@ void IPv4Reassembler::remove_stream(uint16_t id, IPv4Address addr1, IPv4Address ); } -void IPv4Reassembler::set_max_number_packets_to_stream(size_t max_number, StreamCallback callback) { +void IPv4Reassembler::set_max_number_packets_to_stream(uint64_t max_number, StreamCallback callback) { max_number_packets_to_stream_ = max_number; stream_overflow_callback_ = callback; } -void IPv4Reassembler::set_timeout_to_stream(size_t stream_timeout_ms, size_t time_to_check_s, StreamCallback callback) { +void IPv4Reassembler::set_timeout_to_stream(uint64_t stream_timeout_ms, uint64_t time_to_check_s, StreamCallback callback) { stream_timeout_ms_ = stream_timeout_ms; time_to_check_s_ = time_to_check_s; stream_timeout_callback_ = callback; diff --git a/tests/src/ip_reassembler_test.cpp b/tests/src/ip_reassembler_test.cpp index 504092e6..63aaf199 100644 --- a/tests/src/ip_reassembler_test.cpp +++ b/tests/src/ip_reassembler_test.cpp @@ -2,6 +2,7 @@ #include #include #include +#include #include #include #include From c6592349035b012f3c74b9b5a60e5b72bb858357 Mon Sep 17 00:00:00 2001 From: Erik Date: Tue, 3 Jul 2018 13:42:54 +0500 Subject: [PATCH 05/10] Update IPv4Reassembler Fix includes for Windows --- include/tins/ip_reassembler.h | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index 46e1b8ac..acd38c42 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -30,16 +30,19 @@ #ifndef TINS_IP_REASSEMBLER_H #define TINS_IP_REASSEMBLER_H -#include -#include -#include #if TINS_IS_CXX11 -#include -#include + #include + #include +#elif defined(_WIN32) + #include + #include #else -#include -#include + #include #endif + +#include +#include +#include #include #include #include From d6958d658337d68ea60133b57f94db01fdada80c Mon Sep 17 00:00:00 2001 From: Puasonych Date: Tue, 3 Jul 2018 14:04:42 +0500 Subject: [PATCH 06/10] Fix IPv4Stream::current_time for Windows --- src/ip_reassembler.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 068224a3..8fdfa65e 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -52,8 +52,8 @@ uint64_t IPv4Stream::current_time() { FILETIME file_time; GetSystemTimeAsFileTime(&file_time); ULARGE_INTEGER ul; - ul.LowPart = ft.dwLowDateTime; - ul.HighPart = ft.dwHighDateTime; + ul.LowPart = file_time.dwLowDateTime; + ul.HighPart = file_time.dwHighDateTime; uint64_t file_time_64 = ul.QuadPart; return file_time_64; #else From f470245a9e8c7bcc38f71137f9a7ae35cbb3f060 Mon Sep 17 00:00:00 2001 From: Puasonych Date: Tue, 3 Jul 2018 16:15:43 +0500 Subject: [PATCH 07/10] Adapted IPv4Reassembler to VS2013 --- include/tins/cxxstd.h | 6 ++++++ include/tins/ip_reassembler.h | 6 +++--- src/ip_reassembler.cpp | 14 +++++++------- 3 files changed, 16 insertions(+), 10 deletions(-) diff --git a/include/tins/cxxstd.h b/include/tins/cxxstd.h index f88f255c..5899f6f3 100644 --- a/include/tins/cxxstd.h +++ b/include/tins/cxxstd.h @@ -44,6 +44,12 @@ #define TINS_IS_CXX11 0 #endif // TINS_IS_CXX11 +#if !(TINS_IS_CXX11 == 0) && defined(_MSC_VER) +#define TINS_WITH_MONOTONIC_CHRONO (_MSC_VER > 1800) +#else +#define TINS_WITH_MONOTONIC_CHRONO TINS_IS_CXX11 +#endif // TINS_WITH_MONOTONIC_CHRONO + namespace Tins{ namespace Internals { template void unused(const T&) { } diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index acd38c42..1ca34c2a 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -30,7 +30,7 @@ #ifndef TINS_IP_REASSEMBLER_H #define TINS_IP_REASSEMBLER_H -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO #include #include #elif defined(_WIN32) @@ -82,7 +82,7 @@ class TINS_API IPv4Stream { public: IPv4Stream(); -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO typedef std::chrono::system_clock::time_point time_point; #else typedef uint64_t time_point; @@ -151,7 +151,7 @@ class TINS_API IPv4Reassembler { TINS_DEPRECATED(typedef PacketStatus packet_status); -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO typedef std::function StreamCallback; #else typedef void (*StreamCallback)(PDU& pdu); diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 8fdfa65e..68975413 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -39,14 +39,14 @@ namespace Internals { IPv4Stream::IPv4Stream() : received_size_(), total_size_(), received_end_(false) { -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO start_time_point_ = std::chrono::system_clock::now(); #else start_time_point_ = current_time(); #endif } -#if TINS_IS_CXX11 == 0 +#if TINS_WITH_MONOTONIC_CHRONO == 0 uint64_t IPv4Stream::current_time() { #ifdef _WIN32 FILETIME file_time; @@ -140,7 +140,7 @@ IPv4Reassembler::IPv4Reassembler() : technique_(NONE), max_number_packets_to_stream_(0), stream_timeout_ms_(0), stream_overflow_callback_(0), stream_timeout_callback_(0), total_number_complete_packages_(0), total_number_damaged_packages_(0) { -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO origin_cycle_time_ = std::chrono::system_clock::now(); #else origin_cycle_time_ = Internals::IPv4Stream::current_time(); @@ -151,7 +151,7 @@ IPv4Reassembler::IPv4Reassembler(OverlappingTechnique technique) : technique_(technique), max_number_packets_to_stream_(0), stream_timeout_ms_(0), stream_overflow_callback_(0), stream_timeout_callback_(0), total_number_complete_packages_(0), total_number_damaged_packages_(0) { -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO origin_cycle_time_ = std::chrono::system_clock::now(); #else origin_cycle_time_ = Internals::IPv4Stream::current_time(); @@ -196,7 +196,7 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { // Only non-complete packages fall into the list if (stream_timeout_ms_ && stream_it == streams_.end()) { -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO streams_history_.emplace_back(key, stream.start_time_point()); #else streams_history_.push_back(std::make_pair(key, stream.start_time_point())); @@ -250,7 +250,7 @@ void IPv4Reassembler::removal_expired_streams() { if (!stream_timeout_ms_ || streams_history_.empty()) return; -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO Internals::IPv4Stream::time_point now = std::chrono::system_clock::now(); auto step = std::chrono::duration_cast(now - origin_cycle_time_); if (std::chrono::seconds(time_to_check_s_) < step) { @@ -276,7 +276,7 @@ void IPv4Reassembler::removal_expired_streams() streams_history_.pop_front(); continue; } -#if TINS_IS_CXX11 +#if TINS_WITH_MONOTONIC_CHRONO auto diff = std::chrono::duration_cast(now - history_front.second); if ((uint64_t)diff.count() > stream_timeout_ms_) { #else From 59571a2154a9846b5f9e7e23074861e7348f4b78 Mon Sep 17 00:00:00 2001 From: Puasonych Date: Tue, 3 Jul 2018 19:19:33 +0500 Subject: [PATCH 08/10] Corrected the current update --- include/tins/ip_reassembler.h | 8 +++++--- src/ip_reassembler.cpp | 10 +++++----- tests/src/ip_reassembler_test.cpp | 6 +++--- 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index 1ca34c2a..0c94882c 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -227,10 +227,12 @@ class TINS_API IPv4Reassembler { * but on each incoming package. * * \param stream_timeout_ms The lifetime of a single stream (milliseconds) - * \param time_to_check_s Time step for verification (seconds) + * If stream_timeout_ms == 0, then there will be no verification + * \param time_to_check_ms Time step for verification (milliseconds) + * If time_to_check_ms == 0 and stream_timeout_ms != 0, then the check will be with each new package * \param callback If set, it is called for each expired valid stream */ - void set_timeout_to_stream(uint64_t stream_timeout_ms, uint64_t time_to_check_s = 60, StreamCallback callback = 0); + void set_timeout_to_stream(uint64_t stream_timeout_ms, uint64_t time_to_check_ms = 1000, StreamCallback callback = 0); /** * \brief Return the total number of complete packets @@ -265,7 +267,7 @@ class TINS_API IPv4Reassembler { OverlappingTechnique technique_; uint64_t max_number_packets_to_stream_; uint64_t stream_timeout_ms_; - uint64_t time_to_check_s_; + uint64_t time_to_check_ms_; streams_history streams_history_; StreamCallback stream_overflow_callback_; diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 68975413..074d02df 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -252,14 +252,14 @@ void IPv4Reassembler::removal_expired_streams() #if TINS_WITH_MONOTONIC_CHRONO Internals::IPv4Stream::time_point now = std::chrono::system_clock::now(); - auto step = std::chrono::duration_cast(now - origin_cycle_time_); - if (std::chrono::seconds(time_to_check_s_) < step) { + auto step = std::chrono::duration_cast(now - origin_cycle_time_); + if (step < std::chrono::milliseconds(time_to_check_ms_)) { return; } #else uint64_t now = Internals::IPv4Stream::current_time(); uint64_t step = now - origin_cycle_time_; - if (time_to_check_s_ * 1000 < step) { + if (step < time_to_check_ms_) { return; } #endif @@ -319,9 +319,9 @@ void IPv4Reassembler::set_max_number_packets_to_stream(uint64_t max_number, Stre stream_overflow_callback_ = callback; } -void IPv4Reassembler::set_timeout_to_stream(uint64_t stream_timeout_ms, uint64_t time_to_check_s, StreamCallback callback) { +void IPv4Reassembler::set_timeout_to_stream(uint64_t stream_timeout_ms, uint64_t time_to_check_ms, StreamCallback callback) { stream_timeout_ms_ = stream_timeout_ms; - time_to_check_s_ = time_to_check_s; + time_to_check_ms_ = time_to_check_ms; stream_timeout_callback_ = callback; } diff --git a/tests/src/ip_reassembler_test.cpp b/tests/src/ip_reassembler_test.cpp index 63aaf199..8032decb 100644 --- a/tests/src/ip_reassembler_test.cpp +++ b/tests/src/ip_reassembler_test.cpp @@ -65,7 +65,7 @@ const size_t IPv4ReassemblerTest::orderings[][11] = { void IPv4ReassemblerTest::test_packets(const vector >& vt) { IPv4Reassembler reassembler; reassembler.set_max_number_packets_to_stream(500); - reassembler.set_timeout_to_stream(100); + reassembler.set_timeout_to_stream(500, 100); for(size_t i = 0; i < vt.size(); ++i) { EthernetII eth(vt[i].first, (uint32_t)vt[i].second); // Set the TTL for the first fragment to 32 so we can make sure the right "base" @@ -130,7 +130,7 @@ TEST_F(IPv4ReassemblerTest, PacketHasMFAndDF) { EXPECT_TRUE(packet2.rfind_pdu().is_fragmented()); IPv4Reassembler reassembler; reassembler.set_max_number_packets_to_stream(500); - reassembler.set_timeout_to_stream(100); + reassembler.set_timeout_to_stream(500, 100); EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet1)); EXPECT_EQ(IPv4Reassembler::REASSEMBLED, reassembler.process(packet2)); @@ -161,7 +161,7 @@ TEST_F(IPv4ReassemblerTest, PackageWasDeletedByTimeout) { EXPECT_TRUE(packet2.rfind_pdu().is_fragmented()); IPv4Reassembler reassembler; reassembler.set_max_number_packets_to_stream(500); - reassembler.set_timeout_to_stream(100); + reassembler.set_timeout_to_stream(500, 100); EXPECT_EQ(IPv4Reassembler::FRAGMENTED, reassembler.process(packet1)); EXPECT_EQ(0, reassembler.total_number_complete_packages()); From f11e2761907339bee3d7021831afc89eac83aadd Mon Sep 17 00:00:00 2001 From: Puasonych Date: Wed, 4 Jul 2018 17:21:29 +0500 Subject: [PATCH 09/10] Checking the monotony of chrono in VS2013 --- include/tins/cxxstd.h | 6 ------ include/tins/ip_reassembler.h | 6 +++--- src/ip_reassembler.cpp | 14 +++++++------- 3 files changed, 10 insertions(+), 16 deletions(-) diff --git a/include/tins/cxxstd.h b/include/tins/cxxstd.h index 5899f6f3..f88f255c 100644 --- a/include/tins/cxxstd.h +++ b/include/tins/cxxstd.h @@ -44,12 +44,6 @@ #define TINS_IS_CXX11 0 #endif // TINS_IS_CXX11 -#if !(TINS_IS_CXX11 == 0) && defined(_MSC_VER) -#define TINS_WITH_MONOTONIC_CHRONO (_MSC_VER > 1800) -#else -#define TINS_WITH_MONOTONIC_CHRONO TINS_IS_CXX11 -#endif // TINS_WITH_MONOTONIC_CHRONO - namespace Tins{ namespace Internals { template void unused(const T&) { } diff --git a/include/tins/ip_reassembler.h b/include/tins/ip_reassembler.h index 0c94882c..af0cf2ea 100644 --- a/include/tins/ip_reassembler.h +++ b/include/tins/ip_reassembler.h @@ -30,7 +30,7 @@ #ifndef TINS_IP_REASSEMBLER_H #define TINS_IP_REASSEMBLER_H -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 #include #include #elif defined(_WIN32) @@ -82,7 +82,7 @@ class TINS_API IPv4Stream { public: IPv4Stream(); -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 typedef std::chrono::system_clock::time_point time_point; #else typedef uint64_t time_point; @@ -151,7 +151,7 @@ class TINS_API IPv4Reassembler { TINS_DEPRECATED(typedef PacketStatus packet_status); -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 typedef std::function StreamCallback; #else typedef void (*StreamCallback)(PDU& pdu); diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 074d02df..6f86b018 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -39,14 +39,14 @@ namespace Internals { IPv4Stream::IPv4Stream() : received_size_(), total_size_(), received_end_(false) { -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 start_time_point_ = std::chrono::system_clock::now(); #else start_time_point_ = current_time(); #endif } -#if TINS_WITH_MONOTONIC_CHRONO == 0 +#if TINS_IS_CXX11 == 0 uint64_t IPv4Stream::current_time() { #ifdef _WIN32 FILETIME file_time; @@ -140,7 +140,7 @@ IPv4Reassembler::IPv4Reassembler() : technique_(NONE), max_number_packets_to_stream_(0), stream_timeout_ms_(0), stream_overflow_callback_(0), stream_timeout_callback_(0), total_number_complete_packages_(0), total_number_damaged_packages_(0) { -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 origin_cycle_time_ = std::chrono::system_clock::now(); #else origin_cycle_time_ = Internals::IPv4Stream::current_time(); @@ -151,7 +151,7 @@ IPv4Reassembler::IPv4Reassembler(OverlappingTechnique technique) : technique_(technique), max_number_packets_to_stream_(0), stream_timeout_ms_(0), stream_overflow_callback_(0), stream_timeout_callback_(0), total_number_complete_packages_(0), total_number_damaged_packages_(0) { -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 origin_cycle_time_ = std::chrono::system_clock::now(); #else origin_cycle_time_ = Internals::IPv4Stream::current_time(); @@ -196,7 +196,7 @@ IPv4Reassembler::PacketStatus IPv4Reassembler::process(PDU& pdu) { // Only non-complete packages fall into the list if (stream_timeout_ms_ && stream_it == streams_.end()) { -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 streams_history_.emplace_back(key, stream.start_time_point()); #else streams_history_.push_back(std::make_pair(key, stream.start_time_point())); @@ -250,7 +250,7 @@ void IPv4Reassembler::removal_expired_streams() { if (!stream_timeout_ms_ || streams_history_.empty()) return; -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 Internals::IPv4Stream::time_point now = std::chrono::system_clock::now(); auto step = std::chrono::duration_cast(now - origin_cycle_time_); if (step < std::chrono::milliseconds(time_to_check_ms_)) { @@ -276,7 +276,7 @@ void IPv4Reassembler::removal_expired_streams() streams_history_.pop_front(); continue; } -#if TINS_WITH_MONOTONIC_CHRONO +#if TINS_IS_CXX11 auto diff = std::chrono::duration_cast(now - history_front.second); if ((uint64_t)diff.count() > stream_timeout_ms_) { #else From 7e453f718a6e8922201961e0cae98cd19159dffc Mon Sep 17 00:00:00 2001 From: Puasonych Date: Thu, 5 Jul 2018 09:56:13 +0500 Subject: [PATCH 10/10] Fix check period of obsolete --- src/ip_reassembler.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/ip_reassembler.cpp b/src/ip_reassembler.cpp index 6f86b018..69dbcf8e 100644 --- a/src/ip_reassembler.cpp +++ b/src/ip_reassembler.cpp @@ -263,6 +263,7 @@ void IPv4Reassembler::removal_expired_streams() return; } #endif + origin_cycle_time_ = now; while (!streams_history_.empty()) { streams_history::value_type & history_front = streams_history_.front();