From: Michael Altizer (mialtize) Date: Fri, 6 Dec 2019 16:56:37 +0000 (+0000) Subject: Merge pull request #1875 in SNORT/snort3 from ~DAVMCPHE/snort3:stream_tcp_init_race_c... X-Git-Tag: 3.0.0-267~19 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=95c02f98ef93cdb66f03097c2e10fb8b4041a97c;p=thirdparty%2Fsnort3.git Merge pull request #1875 in SNORT/snort3 from ~DAVMCPHE/snort3:stream_tcp_init_race_condition to master Squashed commit of the following: commit fd95dddf1c1087d8834f3ee04e3a6fb559798f61 Author: davis mcpherson Date: Mon Dec 2 16:40:35 2019 -0500 stream_tcp: refactor stream_tcp initialization to create reassemblers during plugin init stream_tcp: refactor to initialize tcp normalizers during plugin init stream_tcp:: fix TcpState post increment operator to stop increment at max value (and use correct max value) --- diff --git a/src/main/modules.cc b/src/main/modules.cc index 352aec447..4ac3e3b14 100644 --- a/src/main/modules.cc +++ b/src/main/modules.cc @@ -2015,7 +2015,7 @@ bool HostsModule::set(const char*, Value& v, SnortConfig* sc) host->hostInfo.fragPolicy = v.get_uint8() + 1; else if ( host and v.is("tcp_policy") ) - host->hostInfo.streamPolicy = v.get_uint8() + 1; + host->hostInfo.streamPolicy = v.get_uint8(); else if ( app and v.is("name") ) app->snort_protocol_id = sc->proto_ref->add(v.get_string()); diff --git a/src/service_inspectors/http2_inspect/http2_hpack.cc b/src/service_inspectors/http2_inspect/http2_hpack.cc index cc3d213a3..de250421c 100644 --- a/src/service_inspectors/http2_inspect/http2_hpack.cc +++ b/src/service_inspectors/http2_inspect/http2_hpack.cc @@ -134,7 +134,7 @@ bool Http2HpackDecoder::decode_literal_header_line(const uint8_t* encoded_header // Literal field name else { - // Skip over the byte wth the parsed pattern and zeroed index + // Skip over the byte with the parsed pattern and zeroed index bytes_consumed++; if (!decode_string_literal(encoded_header_buffer + bytes_consumed, encoded_header_length - diff --git a/src/stream/stream.h b/src/stream/stream.h index ee68fd387..11e2a105f 100644 --- a/src/stream/stream.h +++ b/src/stream/stream.h @@ -53,7 +53,7 @@ class StreamSplitter; #define IP_POLICIES \ "first | linux | bsd | bsd_right | last | windows | solaris" -// sequence must match STREAM_POLICY_* defines in tcp_session.cc (1-based) +// sequence must match enum StreamPolicy defines in tcp_defs.h #define TCP_POLICIES \ "first | last | linux | old_linux | bsd | macos | solaris | irix | " \ "hpux11 | hpux10 | windows | win_2003 | vista | proxy" diff --git a/src/stream/tcp/segment_overlap_editor.cc b/src/stream/tcp/segment_overlap_editor.cc index 7c89cb56c..1318a9321 100644 --- a/src/stream/tcp/segment_overlap_editor.cc +++ b/src/stream/tcp/segment_overlap_editor.cc @@ -49,9 +49,8 @@ static void set_retransmit_flag(Packet* p) p->packet_flags |= PKT_RETRANSMIT; } -void SegmentOverlapState::init_sos(TcpSession* ssn, ReassemblyPolicy pol) +void SegmentOverlapState::init_sos(TcpSession* ssn, StreamPolicy pol) { - session = ssn; reassembly_policy = pol; @@ -346,7 +345,7 @@ int SegmentOverlapEditor::left_overlap_keep_last(TcpReassemblerState& trs) void SegmentOverlapEditor::right_overlap_truncate_existing(TcpReassemblerState& trs) { if ( SEQ_EQ(trs.sos.right->i_seq, trs.sos.seq) && - ( trs.sos.reassembly_policy != ReassemblyPolicy::OS_LAST ) ) + ( trs.sos.reassembly_policy != StreamPolicy::OS_LAST ) ) { trs.sos.slide = ( trs.sos.right->i_seq + trs.sos.right->i_len - trs.sos.seq ); trs.sos.seq += trs.sos.slide; diff --git a/src/stream/tcp/segment_overlap_editor.h b/src/stream/tcp/segment_overlap_editor.h index 19dc0ac40..2c949292d 100644 --- a/src/stream/tcp/segment_overlap_editor.h +++ b/src/stream/tcp/segment_overlap_editor.h @@ -39,7 +39,7 @@ struct SegmentOverlapState const uint8_t* rdata; TcpSegmentList seglist; - ReassemblyPolicy reassembly_policy; + StreamPolicy reassembly_policy; uint32_t seglist_base_seq; /* seq of first queued segment */ uint32_t seg_count; /* number of current queued segments */ @@ -68,7 +68,7 @@ struct SegmentOverlapState seglist.reset(); } - void init_sos(TcpSession*, ReassemblyPolicy); + void init_sos(TcpSession*, StreamPolicy); void init_soe(TcpSegmentDescriptor& tsd, TcpSegmentNode* left, TcpSegmentNode* right); }; diff --git a/src/stream/tcp/stream_tcp.cc b/src/stream/tcp/stream_tcp.cc index 11d6c7c71..0dc090f1a 100644 --- a/src/stream/tcp/stream_tcp.cc +++ b/src/stream/tcp/stream_tcp.cc @@ -27,6 +27,7 @@ #include "tcp_ha.h" #include "tcp_module.h" #include "tcp_session.h" +#include "tcp_reassemblers.h" #include "tcp_state_machine.h" using namespace snort; @@ -110,10 +111,18 @@ static void tcp_dtor(Inspector* p) { delete p; } static void stream_tcp_pinit() -{ TcpStateMachine::initialize(); } +{ + TcpStateMachine::initialize(); + TcpReassemblerFactory::initialize(); + TcpNormalizerFactory::initialize(); +} static void stream_tcp_pterm() -{ TcpStateMachine::term(); } +{ + TcpStateMachine::term(); + TcpReassemblerFactory::term(); + TcpNormalizerFactory::term(); +} static Session* tcp_ssn(Flow* lws) { return new TcpSession(lws); } diff --git a/src/stream/tcp/tcp_defs.h b/src/stream/tcp/tcp_defs.h index e9ed4392d..fd568192b 100644 --- a/src/stream/tcp/tcp_defs.h +++ b/src/stream/tcp/tcp_defs.h @@ -77,10 +77,9 @@ struct Packet; #define SLAM_MAX 4 // target-based policy types - changes to this enum require changes to stream.h::TCP_POLICIES -enum class StreamPolicy +enum StreamPolicy : uint8_t { - OS_INVALID = 0, - OS_FIRST, + OS_FIRST = 0, OS_LAST, OS_LINUX, OS_OLD_LINUX, @@ -99,7 +98,7 @@ enum class StreamPolicy }; // increment operator... -inline StreamPolicy& operator++(StreamPolicy& c) +inline StreamPolicy& operator++(StreamPolicy& c, int) { if ( c < StreamPolicy::OS_END_OF_LIST ) c = static_cast( static_cast(c) + 1 ); @@ -109,38 +108,6 @@ inline StreamPolicy& operator++(StreamPolicy& c) return c; } -enum class ReassemblyPolicy -{ - OS_INVALID = 0, - OS_FIRST, - OS_LAST, - OS_LINUX, - OS_OLD_LINUX, - OS_BSD, - OS_MACOS, - OS_SOLARIS, - OS_IRIX, - OS_HPUX11, - OS_HPUX10, - OS_WINDOWS, - OS_WINDOWS2K3, - OS_VISTA, - OS_PROXY, - OS_END_OF_LIST, - OS_DEFAULT = OS_BSD -}; - -// increment operator... -inline ReassemblyPolicy& operator++(ReassemblyPolicy& c) -{ - if ( c < ReassemblyPolicy::OS_END_OF_LIST ) - c = static_cast( static_cast(c) + 1 ); - else - c = ReassemblyPolicy::OS_END_OF_LIST; - - return c; -} - enum FlushPolicy { STREAM_FLPOLICY_IGNORE, /* ignore this traffic */ diff --git a/src/stream/tcp/tcp_module.cc b/src/stream/tcp/tcp_module.cc index 1d04d43fa..976473122 100644 --- a/src/stream/tcp/tcp_module.cc +++ b/src/stream/tcp/tcp_module.cc @@ -288,7 +288,7 @@ bool StreamTcpModule::set(const char*, Value& v, SnortConfig*) config->no_ack = v.get_bool(); else if ( v.is("policy") ) - config->policy = static_cast< StreamPolicy >( v.get_uint8() + 1 ); + config->policy = static_cast< StreamPolicy >( v.get_uint8() ); else if ( v.is("overlap_limit") ) config->overlap_limit = v.get_uint32(); diff --git a/src/stream/tcp/tcp_normalizer.h b/src/stream/tcp/tcp_normalizer.h index ab8cc41a0..b906aaa70 100644 --- a/src/stream/tcp/tcp_normalizer.h +++ b/src/stream/tcp/tcp_normalizer.h @@ -53,7 +53,7 @@ struct TcpNormalizerState TcpStreamTracker* tracker = nullptr; TcpStreamTracker* peer_tracker = nullptr; - StreamPolicy os_policy = StreamPolicy::OS_INVALID; + StreamPolicy os_policy = StreamPolicy::OS_DEFAULT; int32_t paws_ts_fudge = 0; int tcp_ts_flags = 0; diff --git a/src/stream/tcp/tcp_normalizers.cc b/src/stream/tcp/tcp_normalizers.cc index da98480b4..a1b6e3918 100644 --- a/src/stream/tcp/tcp_normalizers.cc +++ b/src/stream/tcp/tcp_normalizers.cc @@ -463,48 +463,39 @@ void TcpNormalizerPolicy::init(StreamPolicy os, TcpStreamSession* ssn, TcpStream tns.tcp_block = Normalize_GetMode(NORM_TCP_BLOCK); tns.opt_block = Normalize_GetMode(NORM_TCP_OPT); - norm = TcpNormalizerFactory::create(os); + norm = TcpNormalizerFactory::get_instance(os); norm->init(tns); } -TcpNormalizer* TcpNormalizerFactory::create(StreamPolicy os_policy) -{ - static TcpNormalizerFirst first; - static TcpNormalizerLast last; - static TcpNormalizerLinux new_linux; - static TcpNormalizerOldLinux old_linux; - static TcpNormalizerBSD bsd; - static TcpNormalizerMacOS mac_os; - static TcpNormalizerSolaris solaris; - static TcpNormalizerIrix irix; - static TcpNormalizerHpux11 hpux11; - static TcpNormalizerHpux10 hpux10; - static TcpNormalizerWindows windows; - static TcpNormalizerWindows2K3 windows_2K3; - static TcpNormalizerVista vista; - static TcpNormalizerProxy proxy; +TcpNormalizer* TcpNormalizerFactory::normalizers[StreamPolicy::OS_END_OF_LIST]; - TcpNormalizer* normalizer; +void TcpNormalizerFactory::initialize() +{ + normalizers[StreamPolicy::OS_FIRST] = new TcpNormalizerFirst; + normalizers[StreamPolicy::OS_LAST] = new TcpNormalizerLast; + normalizers[StreamPolicy::OS_LINUX] = new TcpNormalizerLinux; + normalizers[StreamPolicy::OS_OLD_LINUX] = new TcpNormalizerOldLinux; + normalizers[StreamPolicy::OS_BSD] = new TcpNormalizerBSD; + normalizers[StreamPolicy::OS_MACOS] = new TcpNormalizerMacOS; + normalizers[StreamPolicy::OS_SOLARIS] = new TcpNormalizerSolaris; + normalizers[StreamPolicy::OS_IRIX] = new TcpNormalizerIrix; + normalizers[StreamPolicy::OS_HPUX11] = new TcpNormalizerHpux11; + normalizers[StreamPolicy::OS_HPUX10] = new TcpNormalizerHpux10; + normalizers[StreamPolicy::OS_WINDOWS] = new TcpNormalizerWindows; + normalizers[StreamPolicy::OS_WINDOWS2K3] = new TcpNormalizerWindows2K3; + normalizers[StreamPolicy::OS_VISTA] = new TcpNormalizerVista; + normalizers[StreamPolicy::OS_PROXY] = new TcpNormalizerProxy; +} - switch (os_policy) - { - case StreamPolicy::OS_FIRST: normalizer = &first; break; - case StreamPolicy::OS_LAST: normalizer = &last; break; - case StreamPolicy::OS_LINUX: normalizer = &new_linux; break; - case StreamPolicy::OS_OLD_LINUX: normalizer = &old_linux; break; - case StreamPolicy::OS_BSD: normalizer = &bsd; break; - case StreamPolicy::OS_MACOS: normalizer = &mac_os; break; - case StreamPolicy::OS_SOLARIS: normalizer = &solaris; break; - case StreamPolicy::OS_IRIX: normalizer = &irix; break; - case StreamPolicy::OS_HPUX11: normalizer = &hpux11; break; - case StreamPolicy::OS_HPUX10: normalizer = &hpux10; break; - case StreamPolicy::OS_WINDOWS: normalizer = &windows; break; - case StreamPolicy::OS_WINDOWS2K3: normalizer = &windows_2K3; break; - case StreamPolicy::OS_VISTA: normalizer = &vista; break; - case StreamPolicy::OS_PROXY: normalizer = &proxy; break; - default: normalizer = &bsd; break; - } +void TcpNormalizerFactory::term() +{ + for ( auto sp = StreamPolicy::OS_FIRST; sp <= StreamPolicy::OS_PROXY; sp++ ) + delete normalizers[sp]; +} - return normalizer; +TcpNormalizer* TcpNormalizerFactory::get_instance(StreamPolicy sp) +{ + assert( sp <= StreamPolicy::OS_PROXY ); + return normalizers[sp]; } diff --git a/src/stream/tcp/tcp_normalizers.h b/src/stream/tcp/tcp_normalizers.h index 10b369e9b..a28304f09 100644 --- a/src/stream/tcp/tcp_normalizers.h +++ b/src/stream/tcp/tcp_normalizers.h @@ -30,7 +30,14 @@ class TcpStreamSession; class TcpNormalizerFactory { public: - static TcpNormalizer* create(StreamPolicy); + static void initialize(); + static void term(); + static TcpNormalizer* get_instance(StreamPolicy); + +private: + TcpNormalizerFactory() = delete; + + static TcpNormalizer* normalizers[StreamPolicy::OS_END_OF_LIST]; }; class TcpNormalizerPolicy @@ -41,7 +48,7 @@ public: void init(StreamPolicy os, TcpStreamSession* ssn, TcpStreamTracker* trk, TcpStreamTracker* peer); void reset() - { init(StreamPolicy::OS_INVALID, nullptr, nullptr, nullptr); } + { init(StreamPolicy::OS_DEFAULT, nullptr, nullptr, nullptr); } bool packet_dropper(TcpSegmentDescriptor& tsd, NormFlags nflags) { return norm->packet_dropper(tns, tsd, nflags); } diff --git a/src/stream/tcp/tcp_reassemblers.cc b/src/stream/tcp/tcp_reassemblers.cc index 89033d66c..c7e8815d6 100644 --- a/src/stream/tcp/tcp_reassemblers.cc +++ b/src/stream/tcp/tcp_reassemblers.cc @@ -24,6 +24,8 @@ #endif #include "tcp_reassemblers.h" + +#include "tcp_defs.h" #include "tcp_stream_tracker.h" class TcpReassemblerFirst : public TcpReassembler @@ -250,29 +252,9 @@ private: { return full_right_overlap_os5(trs); } }; -static ReassemblyPolicy stream_reassembly_policy_map[] = -{ - ReassemblyPolicy::OS_INVALID, - ReassemblyPolicy::OS_FIRST, - ReassemblyPolicy::OS_LAST, - ReassemblyPolicy::OS_LINUX, - ReassemblyPolicy::OS_OLD_LINUX, - ReassemblyPolicy::OS_BSD, - ReassemblyPolicy::OS_MACOS, - ReassemblyPolicy::OS_SOLARIS, - ReassemblyPolicy::OS_IRIX, - ReassemblyPolicy::OS_HPUX11, - ReassemblyPolicy::OS_HPUX10, - ReassemblyPolicy::OS_WINDOWS, - ReassemblyPolicy::OS_WINDOWS2K3, - ReassemblyPolicy::OS_VISTA, - ReassemblyPolicy::OS_PROXY, - ReassemblyPolicy::OS_DEFAULT -}; - void TcpReassemblerPolicy::init(TcpSession* ssn, TcpStreamTracker* trk, StreamPolicy pol, bool server) { - trs.sos.init_sos(ssn, stream_reassembly_policy_map[ static_cast(pol) ]); + trs.sos.init_sos(ssn, pol); trs.server_side = server; trs.tracker = trk; @@ -290,54 +272,45 @@ void TcpReassemblerPolicy::init(TcpSession* ssn, TcpStreamTracker* trk, StreamPo trs.flush_count = 0; trs.xtradata_mask = 0; - reassembler = TcpReassemblerFactory::create(pol); + reassembler = TcpReassemblerFactory::get_instance(pol); } void TcpReassemblerPolicy::reset() { - init(nullptr, nullptr, StreamPolicy::OS_INVALID, false); + init(nullptr, nullptr, StreamPolicy::OS_DEFAULT, false); } -TcpReassembler* TcpReassemblerFactory::create(StreamPolicy os_policy) +TcpReassembler* TcpReassemblerFactory::reassemblers[StreamPolicy::OS_END_OF_LIST]; + +void TcpReassemblerFactory::initialize() { - static TcpReassemblerFirst first; - static TcpReassemblerLast last; - static TcpReassemblerLinux new_linux; - static TcpReassemblerOldLinux old_linux; - static TcpReassemblerBSD bsd; - static TcpReassemblerMacOS mac_os; - static TcpReassemblerSolaris solaris; - static TcpReassemblerIrix irix; - static TcpReassemblerHpux11 hpux11; - static TcpReassemblerHpux10 hpux10; - static TcpReassemblerWindows windows; - static TcpReassemblerWindows2K3 windows_2K3; - static TcpReassemblerVista vista; - static TcpReassemblerProxy proxy; + reassemblers[StreamPolicy::OS_FIRST] = new TcpReassemblerFirst; + reassemblers[StreamPolicy::OS_LAST] = new TcpReassemblerLast; + reassemblers[StreamPolicy::OS_LINUX] = new TcpReassemblerLinux; + reassemblers[StreamPolicy::OS_OLD_LINUX] = new TcpReassemblerOldLinux; + reassemblers[StreamPolicy::OS_BSD] = new TcpReassemblerBSD; + reassemblers[StreamPolicy::OS_MACOS] = new TcpReassemblerMacOS; + reassemblers[StreamPolicy::OS_SOLARIS] = new TcpReassemblerSolaris; + reassemblers[StreamPolicy::OS_IRIX] = new TcpReassemblerIrix; + reassemblers[StreamPolicy::OS_HPUX11] = new TcpReassemblerHpux11; + reassemblers[StreamPolicy::OS_HPUX10] = new TcpReassemblerHpux10; + reassemblers[StreamPolicy::OS_WINDOWS] = new TcpReassemblerWindows; + reassemblers[StreamPolicy::OS_WINDOWS2K3] = new TcpReassemblerWindows2K3; + reassemblers[StreamPolicy::OS_VISTA] = new TcpReassemblerVista; + reassemblers[StreamPolicy::OS_PROXY] = new TcpReassemblerProxy; +} - NormMode tcp_ips_data = Normalize_GetMode(NORM_TCP_IPS); - StreamPolicy actual = (tcp_ips_data == NORM_MODE_ON) ? StreamPolicy::OS_FIRST : os_policy; - TcpReassembler* reassembler; +void TcpReassemblerFactory::term() +{ + for ( auto sp = StreamPolicy::OS_FIRST; sp <= StreamPolicy::OS_PROXY; sp++ ) + delete reassemblers[sp]; +} - switch (actual) - { - case StreamPolicy::OS_FIRST: reassembler = &first; break; - case StreamPolicy::OS_LAST: reassembler = &last; break; - case StreamPolicy::OS_LINUX: reassembler = &new_linux; break; - case StreamPolicy::OS_OLD_LINUX: reassembler = &old_linux; break; - case StreamPolicy::OS_BSD: reassembler = &bsd; break; - case StreamPolicy::OS_MACOS: reassembler = &mac_os; break; - case StreamPolicy::OS_SOLARIS: reassembler = &solaris; break; - case StreamPolicy::OS_IRIX: reassembler = &irix; break; - case StreamPolicy::OS_HPUX11: reassembler = &hpux11; break; - case StreamPolicy::OS_HPUX10: reassembler = &hpux10; break; - case StreamPolicy::OS_WINDOWS: reassembler = &windows; break; - case StreamPolicy::OS_WINDOWS2K3: reassembler = &windows_2K3; break; - case StreamPolicy::OS_VISTA: reassembler = &vista; break; - case StreamPolicy::OS_PROXY: reassembler = &proxy; break; - default: reassembler = &bsd; break; - } +TcpReassembler* TcpReassemblerFactory::get_instance(StreamPolicy os_policy) +{ + NormMode tcp_ips_data = Normalize_GetMode(NORM_TCP_IPS); + StreamPolicy sp = (tcp_ips_data == NORM_MODE_ON) ? StreamPolicy::OS_FIRST : os_policy; - return reassembler; + assert( sp <= StreamPolicy::OS_PROXY ); + return reassemblers[sp]; } - diff --git a/src/stream/tcp/tcp_reassemblers.h b/src/stream/tcp/tcp_reassemblers.h index cf386e748..6d18c2609 100644 --- a/src/stream/tcp/tcp_reassemblers.h +++ b/src/stream/tcp/tcp_reassemblers.h @@ -16,7 +16,7 @@ // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. //-------------------------------------------------------------------------- -// tcp_reassemblers.h author davis mcpherson +// tcp_reassemblers.h author davis mcpherson // Created on: Oct 9, 2015 #ifndef TCP_REASSEMBLERS_H @@ -27,9 +27,14 @@ class TcpReassemblerFactory { public: - static TcpReassembler* create(StreamPolicy); + static void initialize(); + static void term(); + static TcpReassembler* get_instance(StreamPolicy); + private: TcpReassemblerFactory() = delete; + + static TcpReassembler* reassemblers[StreamPolicy::OS_END_OF_LIST]; }; class TcpReassemblerPolicy @@ -101,7 +106,7 @@ public: uint32_t get_seg_bytes_logical() const { return trs.sos.seg_bytes_logical; } - ReassemblyPolicy get_reassembly_policy() const + StreamPolicy get_reassembly_policy() const { return trs.sos.reassembly_policy; } void set_norm_mode_test() diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index fbf912b63..682a3937e 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -1047,7 +1047,7 @@ int TcpSession::process(Packet* p) } if( !tcp_init ) - set_os_policy( ); + set_os_policy(); TcpSegmentDescriptor tsd(flow, p, tel); diff --git a/src/stream/tcp/tcp_stream_config.cc b/src/stream/tcp/tcp_stream_config.cc index f3383a9cf..2d2e0caa4 100644 --- a/src/stream/tcp/tcp_stream_config.cc +++ b/src/stream/tcp/tcp_stream_config.cc @@ -30,7 +30,7 @@ using namespace snort; static const char* const reassembly_policy_names[] = -{ "no policy", "first", "last", "linux", "old_linux", "bsd", "macos", "solaris", "irix", +{ "first", "last", "linux", "old_linux", "bsd", "macos", "solaris", "irix", "hpux11", "hpux10", "windows", "win_2003", "vista", "proxy" }; TcpStreamConfig::TcpStreamConfig() = default; diff --git a/src/stream/tcp/tcp_stream_config.h b/src/stream/tcp/tcp_stream_config.h index b30dccfec..f97d109c4 100644 --- a/src/stream/tcp/tcp_stream_config.h +++ b/src/stream/tcp/tcp_stream_config.h @@ -54,7 +54,7 @@ public: static void show_config(const TcpStreamConfig*); StreamPolicy policy = StreamPolicy::OS_DEFAULT; - ReassemblyPolicy reassembly_policy = ReassemblyPolicy::OS_DEFAULT; + StreamPolicy reassembly_policy = StreamPolicy::OS_DEFAULT; uint16_t flags = 0; uint16_t flush_factor = 0; diff --git a/src/stream/tcp/tcp_stream_tracker.h b/src/stream/tcp/tcp_stream_tracker.h index fb0f526d7..dbf34d97f 100644 --- a/src/stream/tcp/tcp_stream_tracker.h +++ b/src/stream/tcp/tcp_stream_tracker.h @@ -361,9 +361,11 @@ protected: // <--- note -- the 'state' parameter must be a reference inline TcpStreamTracker::TcpState& operator++(TcpStreamTracker::TcpState& state, int) { - const int i = static_cast(state); - state = static_cast((i + 1) % ( TcpStreamTracker::TCP_MAX_EVENTS + - 1 ) ); + if ( state < TcpStreamTracker::TCP_MAX_STATES ) + state = static_cast( static_cast(state) + 1 ); + else + state = TcpStreamTracker::TCP_MAX_STATES; + return state; }