From: Davis McPherson -X (davmcphe - XORIANT CORPORATION at Cisco) Date: Mon, 22 Jan 2024 23:56:50 +0000 (+0000) Subject: Pull request #4142: CSCwh95127 - Skip initial seglist holes for midstream flows in... X-Git-Tag: 3.1.79.0~9 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ae6d7ec4621e548d88314718f20acd4b628155aa;p=thirdparty%2Fsnort3.git Pull request #4142: CSCwh95127 - Skip initial seglist holes for midstream flows in IPS mode Merge in SNORT/snort3 from ~DAVMCPHE/snort3:ips_seglist_hole_cscwh95127 to master Squashed commit of the following: commit 24510aba30c9cb8681d8bef03fb9b7d7ba2692f2 Author: davis mcpherson Date: Fri Dec 8 14:46:11 2023 -0500 stream_tcp: on midstream pickup the peer that received the initial midstream packet remains in MID_STREAM_RECV state until a packet with an ACK is sent by that peer. Data packets received are added to the seglist but reassembly is not initiated. When the ACK is seen the seglist is scanned for holes left of the ACK and all packets left of the holes are purged and reassembly started with the first packet to the right of the hole set packet direction flag based on direction saved in reassembly state --- diff --git a/src/stream/paf.h b/src/stream/paf.h index 6d47d33c5..67e6c3677 100644 --- a/src/stream/paf.h +++ b/src/stream/paf.h @@ -65,6 +65,13 @@ SO_PUBLIC inline uint32_t paf_initialized (PAF_State* ps) return ( ps->paf != snort::StreamSplitter::START ); } +SO_PUBLIC inline void paf_initialize(PAF_State* ps, uint32_t seq) +{ + ps->seq = ps->pos = seq; + ps->fpt = ps->tot = 0; + ps->paf = snort::StreamSplitter::SEARCH; +} + inline uint32_t paf_active (PAF_State* ps) { return ( ps->paf != snort::StreamSplitter::ABORT ); diff --git a/src/stream/tcp/tcp_reassembler.cc b/src/stream/tcp/tcp_reassembler.cc index 527cb3c24..b31c79559 100644 --- a/src/stream/tcp/tcp_reassembler.cc +++ b/src/stream/tcp/tcp_reassembler.cc @@ -31,6 +31,7 @@ #include "log/log.h" #include "main/analyzer.h" #include "packet_io/active.h" +#include "packet_tracer/packet_tracer.h" #include "profiler/profiler.h" #include "protocols/packet_manager.h" #include "time/packet_time.h" @@ -38,6 +39,7 @@ #include "tcp_module.h" #include "tcp_normalizers.h" #include "tcp_session.h" +#include "tcp_stream_tracker.h" using namespace snort; @@ -732,7 +734,8 @@ int TcpReassembler::flush_stream( if ( !trs.tracker->is_reassembly_enabled() ) return 0; - if ( trs.sos.session->flow->two_way_traffic() ) + if ( trs.sos.session->flow->two_way_traffic() + or (trs.tracker->get_tcp_state() == TcpStreamTracker::TCP_MID_STREAM_RECV) ) { uint32_t bytes = 0; @@ -822,14 +825,13 @@ void TcpReassembler::flush_queued_segments( { if ( p ) { - finish_and_final_flush(trs, flow, clear, const_cast(p)); + finish_and_final_flush(trs, flow, clear, const_cast(p)); } else { Packet* pdu = get_packet(flow, trs.packet_dir, trs.server_side); bool pending = clear and paf_initialized(&trs.paf_state); - if ( pending ) { DetectionEngine de; @@ -841,38 +843,6 @@ void TcpReassembler::flush_queued_segments( } } -// this is for post-ack flushing -uint32_t TcpReassembler::get_reverse_packet_dir(TcpReassemblerState&, const Packet* p) -{ - /* Remember, one side's packets are stored in the - * other side's queue. So when talker ACKs data, - * we need to check if we're ready to flush. - * - * If we do decide to flush, the flush IP & port info - * is the opposite of the packet -- again because this - * is the ACK from the talker and we're flushing packets - * that actually came from the listener. - */ - if ( p->is_from_server() ) - return PKT_FROM_CLIENT; - - if ( p->is_from_client() ) - return PKT_FROM_SERVER; - - return 0; -} - -uint32_t TcpReassembler::get_forward_packet_dir(TcpReassemblerState&, const Packet* p) -{ - if ( p->is_from_server() ) - return PKT_FROM_SERVER; - - if ( p->is_from_client() ) - return PKT_FROM_CLIENT; - - return 0; -} - // see scan_data_post_ack() for details // the key difference is that we operate on forward moving data // because we don't wait until it is acknowledged @@ -940,8 +910,7 @@ int32_t TcpReassembler::scan_data_pre_ack(TcpReassemblerState& trs, uint32_t* fl } trs.sos.seglist.cur_sseg = tsn; - - if (tsn) + if ( tsn ) update_rcv_nxt(trs, *tsn); return ret_val; @@ -1018,7 +987,8 @@ void TcpReassembler::update_rcv_nxt(TcpReassemblerState& trs, TcpSegmentNode& ts if (!trs.tracker->ooo_packet_seen and SEQ_LT(trs.tracker->rcv_nxt, temp)) trs.tracker->ooo_packet_seen = true; - trs.tracker->rcv_nxt = temp; + if ( SEQ_GT(temp, trs.tracker->rcv_nxt) ) + trs.tracker->rcv_nxt = temp; } bool TcpReassembler::has_seglist_hole(TcpReassemblerState& trs, TcpSegmentNode& tsn, PAF_State& ps, @@ -1042,6 +1012,62 @@ bool TcpReassembler::has_seglist_hole(TcpReassemblerState& trs, TcpSegmentNode& return true; } +void TcpReassembler::purge_segments_left_of_hole(TcpReassemblerState& trs, const TcpSegmentNode* end_tsn) +{ + uint32_t packets_skipped = 0; + + TcpSegmentNode* cur_tsn = trs.sos.seglist.head; + do + { + TcpSegmentNode* drop_tsn = cur_tsn; + cur_tsn = cur_tsn->next; + delete_reassembly_segment(trs, drop_tsn); + ++packets_skipped; + } while( cur_tsn and cur_tsn != end_tsn ); + + if (PacketTracer::is_active()) + PacketTracer::log("Stream: Skipped %u packets before seglist hole)\n", packets_skipped); +} + +void TcpReassembler::skip_midstream_pickup_seglist_hole(TcpReassemblerState& trs, TcpSegmentDescriptor& tsd) +{ + uint32_t ack = tsd.get_ack(); + + TcpSegmentNode* tsn = trs.sos.seglist.head; + while ( tsn ) + { + if ( SEQ_GEQ( tsn->i_seq + tsn->i_len, ack) ) + break; + + if ( tsn->next and SEQ_GT(tsn->next->i_seq, tsn->i_seq + tsn->i_len) ) + { + tsn = tsn->next; + purge_segments_left_of_hole(trs, tsn); + trs.sos.seglist_base_seq = trs.sos.seglist.head->i_seq; + } + else if ( !tsn->next and SEQ_LT(tsn->i_seq + tsn->i_len, ack) ) + { + tsn = tsn->next; + purge_segments_left_of_hole(trs, tsn); + trs.sos.seglist_base_seq = ack; + } + else + tsn = tsn->next; + } + + tsn = trs.sos.seglist.head; + if ( tsn ) + { + paf_initialize(&trs.paf_state, tsn->i_seq); + + while ( next_no_gap(*tsn) ) + tsn = tsn->next; + trs.tracker->rcv_nxt = tsn->i_seq + tsn->i_len; + } + else + trs.tracker->rcv_nxt = ack; +} + // iterate over trs.sos.seglist and scan all new acked bytes // - new means not yet scanned // - must use trs.sos.seglist data (not packet) since this packet may plug a @@ -1155,7 +1181,7 @@ int TcpReassembler::flush_on_data_policy(TcpReassemblerState& trs, Packet* p) int32_t flush_amt; do { - flags = get_forward_packet_dir(trs, p); + flags = trs.packet_dir; flush_amt = scan_data_pre_ack(trs, &flags, p); if ( flush_amt <= 0 ) break; @@ -1251,7 +1277,7 @@ int TcpReassembler::flush_on_ack_policy(TcpReassemblerState& trs, Packet* p) do { - flags = get_reverse_packet_dir(trs, p); + flags = trs.packet_dir; flush_amt = scan_data_post_ack(trs, &flags, p); if ( flush_amt <= 0 or trs.paf_state.paf == StreamSplitter::SKIP ) break; diff --git a/src/stream/tcp/tcp_reassembler.h b/src/stream/tcp/tcp_reassembler.h index e25ca0b39..8dfd0787f 100644 --- a/src/stream/tcp/tcp_reassembler.h +++ b/src/stream/tcp/tcp_reassembler.h @@ -53,6 +53,12 @@ public: uint32_t event_id, uint32_t event_second); virtual void purge_alerts(TcpReassemblerState&); virtual bool segment_within_seglist_window(TcpReassemblerState&, TcpSegmentDescriptor&); + void skip_midstream_pickup_seglist_hole(TcpReassemblerState&, TcpSegmentDescriptor&); + void initialize_paf(TcpReassemblerState& trs) + { + if ( !paf_initialized(&trs.paf_state) or SEQ_GT(trs.paf_state.seq, trs.sos.seglist.head->i_seq) ) + paf_initialize(&trs.paf_state, trs.sos.seglist.head->i_seq); + } uint32_t perform_partial_flush(TcpReassemblerState&, snort::Flow*, snort::Packet*&); @@ -92,6 +98,7 @@ protected: void fallback(TcpStreamTracker&, bool server_side); int32_t scan_data_post_ack(TcpReassemblerState&, uint32_t* flags, snort::Packet*); void purge_to_seq(TcpReassemblerState&, uint32_t flush_seq); + void purge_segments_left_of_hole(TcpReassemblerState&, const TcpSegmentNode*); bool next_no_gap(const TcpSegmentNode&); bool next_no_gap_c(const TcpSegmentNode&); @@ -106,6 +113,7 @@ protected: uint32_t& flags); void skip_seglist_hole(TcpReassemblerState&, snort::Packet*, uint32_t flags, int32_t flush_amt); + uint32_t perform_partial_flush(TcpReassemblerState&, snort::Packet*, uint32_t flushed = 0); }; diff --git a/src/stream/tcp/tcp_reassemblers.h b/src/stream/tcp/tcp_reassemblers.h index 9525a38ca..211454f17 100644 --- a/src/stream/tcp/tcp_reassemblers.h +++ b/src/stream/tcp/tcp_reassemblers.h @@ -79,6 +79,12 @@ public: bool is_segment_pending_flush() const { return reassembler->is_segment_pending_flush(trs); } + void skip_midstream_pickup_seglist_hole(TcpSegmentDescriptor& tsd) + { reassembler->skip_midstream_pickup_seglist_hole(trs, tsd); } + + void initialize_paf() + { reassembler->initialize_paf(trs); } + int flush_on_data_policy(snort::Packet* p) { return reassembler->flush_on_data_policy(trs, p); } diff --git a/src/stream/tcp/tcp_session.cc b/src/stream/tcp/tcp_session.cc index 8ca8cf68d..0c212be91 100644 --- a/src/stream/tcp/tcp_session.cc +++ b/src/stream/tcp/tcp_session.cc @@ -146,6 +146,12 @@ void TcpSession::restart(Packet* p) listener = &server; } + if ( talker->midstream_initial_ack_flush ) + { + talker->midstream_initial_ack_flush = false; + talker->reassembler.flush_on_data_policy(p); + } + if (p->dsize > 0) listener->reassembler.flush_on_data_policy(p); @@ -452,7 +458,6 @@ void TcpSession::update_stream_order(const TcpSegmentDescriptor& tsd, bool align default: if ( aligned ) tsd.set_packet_flags(PKT_STREAM_ORDER_OK); - else { if ( !(flow->get_session_flags() & SSNFLAG_STREAM_ORDER_BAD) ) @@ -830,18 +835,11 @@ void TcpSession::mark_packet_for_drop(TcpSegmentDescriptor& tsd) set_pkt_action_flag(ACTION_BAD_PKT); } -void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd) +void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd, bool flush) { TcpStreamTracker* listener = tsd.get_listener(); TcpStreamTracker* talker = tsd.get_talker(); - // if this session started midstream we may need to init the listener's base seq # - if ( listener->reinit_seg_base ) - { - listener->reassembler.set_seglist_base_seq(tsd.get_seq()); - listener->reinit_seg_base = false; - } - if ( TcpStreamTracker::TCP_CLOSED != talker->get_tcp_state() ) { uint8_t tcp_options_len = tsd.get_tcph()->options_len(); @@ -879,7 +877,10 @@ void TcpSession::handle_data_segment(TcpSegmentDescriptor& tsd) process_tcp_data(tsd); } - listener->reassembler.flush_on_data_policy(tsd.get_pkt()); + if ( flush ) + listener->reassembler.flush_on_data_policy(tsd.get_pkt()); + else + listener->reassembler.initialize_paf(); } TcpStreamTracker::TcpState TcpSession::get_talker_state(TcpSegmentDescriptor& tsd) diff --git a/src/stream/tcp/tcp_session.h b/src/stream/tcp/tcp_session.h index 2a559c9e2..47c70940d 100644 --- a/src/stream/tcp/tcp_session.h +++ b/src/stream/tcp/tcp_session.h @@ -67,7 +67,7 @@ public: void check_for_session_hijack(TcpSegmentDescriptor&) override; bool check_for_window_slam(TcpSegmentDescriptor& tsd) override; void mark_packet_for_drop(TcpSegmentDescriptor&) override; - void handle_data_segment(TcpSegmentDescriptor&) override; + void handle_data_segment(TcpSegmentDescriptor&, bool flush = true); bool validate_packet_established_session(TcpSegmentDescriptor&) override; bool is_midstream_allowed(const TcpSegmentDescriptor& tsd) diff --git a/src/stream/tcp/tcp_state_listen.cc b/src/stream/tcp/tcp_state_listen.cc index f080f247d..0e0488ab3 100644 --- a/src/stream/tcp/tcp_state_listen.cc +++ b/src/stream/tcp/tcp_state_listen.cc @@ -106,7 +106,7 @@ bool TcpStateListen::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& flow->session_state |= STREAM_STATE_MIDSTREAM; trk.init_on_data_seg_recv(tsd); trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); - trk.session->handle_data_segment(tsd); + trk.session->handle_data_segment(tsd, !trk.normalizer.is_tcp_ips_enabled()); } else if ( trk.session->tcp_config->require_3whs() ) { diff --git a/src/stream/tcp/tcp_state_mid_stream_recv.cc b/src/stream/tcp/tcp_state_mid_stream_recv.cc index 2977b224b..37e5cae54 100644 --- a/src/stream/tcp/tcp_state_mid_stream_recv.cc +++ b/src/stream/tcp/tcp_state_mid_stream_recv.cc @@ -51,6 +51,13 @@ bool TcpStateMidStreamRecv::syn_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker bool TcpStateMidStreamRecv::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { + if ( trk.normalizer.is_tcp_ips_enabled() ) + { + trk.reassembler.skip_midstream_pickup_seglist_hole(tsd); + trk.reassembler.flush_on_data_policy(tsd.get_pkt()); + trk.midstream_initial_ack_flush = true; + } + trk.session->check_for_repeated_syn(tsd); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); return true; @@ -58,6 +65,13 @@ bool TcpStateMidStreamRecv::syn_ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTra bool TcpStateMidStreamRecv::ack_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { + if ( trk.normalizer.is_tcp_ips_enabled() ) + { + trk.reassembler.skip_midstream_pickup_seglist_hole(tsd); + trk.reassembler.flush_on_data_policy(tsd.get_pkt()); + trk.midstream_initial_ack_flush = true; + } + trk.update_tracker_ack_sent(tsd); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); return true; @@ -71,6 +85,13 @@ bool TcpStateMidStreamRecv::ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker bool TcpStateMidStreamRecv::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { + if ( trk.normalizer.is_tcp_ips_enabled() ) + { + trk.reassembler.skip_midstream_pickup_seglist_hole(tsd); + trk.reassembler.flush_on_data_policy(tsd.get_pkt()); + trk.midstream_initial_ack_flush = true; + } + trk.update_tracker_ack_sent(tsd); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); if ( trk.session->no_ack_mode_enabled() ) @@ -81,12 +102,19 @@ bool TcpStateMidStreamRecv::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTr bool TcpStateMidStreamRecv::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); - trk.session->handle_data_segment(tsd); + trk.session->handle_data_segment(tsd, !trk.normalizer.is_tcp_ips_enabled()); return true; } bool TcpStateMidStreamRecv::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { + if ( trk.normalizer.is_tcp_ips_enabled() ) + { + trk.reassembler.skip_midstream_pickup_seglist_hole(tsd); + trk.reassembler.flush_on_data_policy(tsd.get_pkt()); + trk.midstream_initial_ack_flush = true; + } + trk.update_on_fin_sent(tsd); trk.session->flow->call_handlers(tsd.get_pkt(), true); TcpStreamTracker::TcpState listener_state = tsd.get_listener()->get_tcp_state(); @@ -132,9 +160,7 @@ bool TcpStateMidStreamRecv::rst_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker bool TcpStateMidStreamRecv::do_post_sm_packet_actions(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { // Always need to check for one sided - bool one_sided = trk.session->check_for_one_sided_session(tsd.get_pkt()); - if ( one_sided && TcpStreamTracker::TCP_MID_STREAM_RECV == trk.get_tcp_state() ) - trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); + trk.session->check_for_one_sided_session(tsd.get_pkt()); return true; } diff --git a/src/stream/tcp/tcp_state_mid_stream_sent.cc b/src/stream/tcp/tcp_state_mid_stream_sent.cc index bc3fa43cd..e7bda4942 100644 --- a/src/stream/tcp/tcp_state_mid_stream_sent.cc +++ b/src/stream/tcp/tcp_state_mid_stream_sent.cc @@ -83,9 +83,10 @@ bool TcpStateMidStreamSent::data_seg_sent(TcpSegmentDescriptor& tsd, TcpStreamTr bool TcpStateMidStreamSent::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk) { trk.update_tracker_ack_recv(tsd); + trk.reassembler.set_seglist_base_seq(tsd.get_seq()); + trk.session->handle_data_segment(tsd); trk.session->set_established(tsd); trk.set_tcp_state(TcpStreamTracker::TCP_ESTABLISHED); - trk.session->handle_data_segment(tsd); return true; } diff --git a/src/stream/tcp/tcp_state_none.cc b/src/stream/tcp/tcp_state_none.cc index d4520cf4f..23bffd828 100644 --- a/src/stream/tcp/tcp_state_none.cc +++ b/src/stream/tcp/tcp_state_none.cc @@ -60,7 +60,7 @@ bool TcpStateNone::syn_ack_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk trk.init_on_synack_recv(tsd); trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); if ( tsd.is_data_segment() ) - trk.session->handle_data_segment(tsd); + trk.session->handle_data_segment(tsd, !trk.normalizer.is_tcp_ips_enabled()); } else if ( trk.session->tcp_config->require_3whs() ) { @@ -111,7 +111,7 @@ bool TcpStateNone::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker& tr flow->session_state |= STREAM_STATE_MIDSTREAM; trk.init_on_data_seg_recv(tsd); trk.normalizer.ecn_tracker(tsd.get_tcph(), trk.session->tcp_config->require_3whs()); - trk.session->handle_data_segment(tsd); + trk.session->handle_data_segment(tsd, !trk.normalizer.is_tcp_ips_enabled()); } else if ( trk.session->tcp_config->require_3whs() ) { diff --git a/src/stream/tcp/tcp_stream_session.h b/src/stream/tcp/tcp_stream_session.h index 96e8a8bf6..3bba9ac90 100644 --- a/src/stream/tcp/tcp_stream_session.h +++ b/src/stream/tcp/tcp_stream_session.h @@ -107,7 +107,6 @@ public: virtual void check_for_session_hijack(TcpSegmentDescriptor&) = 0; virtual bool check_for_window_slam(TcpSegmentDescriptor&) = 0; virtual void mark_packet_for_drop(TcpSegmentDescriptor&) = 0; - virtual void handle_data_segment(TcpSegmentDescriptor&) = 0; virtual bool validate_packet_established_session(TcpSegmentDescriptor&) = 0; TcpStreamTracker client; diff --git a/src/stream/tcp/tcp_stream_tracker.cc b/src/stream/tcp/tcp_stream_tracker.cc index 247940546..e06eec19d 100644 --- a/src/stream/tcp/tcp_stream_tracker.cc +++ b/src/stream/tcp/tcp_stream_tracker.cc @@ -405,7 +405,6 @@ void TcpStreamTracker::init_on_data_seg_sent(TcpSegmentDescriptor& tsd) r_win_base = tsd.get_ack(); rcv_nxt = tsd.get_ack(); reassembler.set_seglist_base_seq(tsd.get_ack()); - reinit_seg_base = true; ts_last_packet = tsd.get_packet_timestamp(); tf_flags |= normalizer.get_tcp_timestamp(tsd, false); @@ -415,10 +414,7 @@ void TcpStreamTracker::init_on_data_seg_sent(TcpSegmentDescriptor& tsd) tf_flags |= tsd.init_wscale(&wscale); cache_mac_address(tsd, tsd.get_direction() ); - if ( TcpStreamTracker::TCP_LISTEN == tcp_state || TcpStreamTracker::TCP_STATE_NONE == tcp_state) - tcp_state = TcpStreamTracker::TCP_MID_STREAM_SENT; - else - tcp_state = TcpStreamTracker::TCP_ESTABLISHED; + tcp_state = TcpStreamTracker::TCP_MID_STREAM_SENT; } void TcpStreamTracker::init_on_data_seg_recv(TcpSegmentDescriptor& tsd) @@ -434,11 +430,8 @@ void TcpStreamTracker::init_on_data_seg_recv(TcpSegmentDescriptor& tsd) reassembler.set_seglist_base_seq(tsd.get_seq()); cache_mac_address(tsd, tsd.get_direction() ); - if ( TcpStreamTracker::TCP_LISTEN == tcp_state || TcpStreamTracker::TCP_STATE_NONE == tcp_state ) - tcp_state = TcpStreamTracker::TCP_MID_STREAM_RECV; - else - tcp_state = TcpStreamTracker::TCP_ESTABLISHED; tcpStats.sessions_on_data++; + tcp_state = TcpStreamTracker::TCP_MID_STREAM_RECV; } void TcpStreamTracker::finish_server_init(TcpSegmentDescriptor& tsd) @@ -481,7 +474,7 @@ void TcpStreamTracker::finish_client_init(TcpSegmentDescriptor& tsd) } else { - reassembler.set_seglist_base_seq(tsd.get_seq() ); + reassembler.set_seglist_base_seq(tsd.get_seq()); r_win_base = tsd.get_seq(); } } diff --git a/src/stream/tcp/tcp_stream_tracker.h b/src/stream/tcp/tcp_stream_tracker.h index cb718f917..0c6dc3d9c 100644 --- a/src/stream/tcp/tcp_stream_tracker.h +++ b/src/stream/tcp/tcp_stream_tracker.h @@ -332,6 +332,7 @@ public: bool require_3whs = false; bool rst_pkt_sent = false; bool ooo_packet_seen = false; + bool midstream_initial_ack_flush = false; // FIXIT-L make these non-public public: @@ -345,7 +346,6 @@ public: uint8_t max_queue_exceeded = MQ_NONE; uint8_t order = 0; FinSeqNumStatus fin_seq_status = TcpStreamTracker::FIN_NOT_SEEN; - bool reinit_seg_base = false; protected: static const std::list::iterator null_iterator;