]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4142: CSCwh95127 - Skip initial seglist holes for midstream flows in...
authorDavis McPherson -X (davmcphe - XORIANT CORPORATION at Cisco) <davmcphe@cisco.com>
Mon, 22 Jan 2024 23:56:50 +0000 (23:56 +0000)
committerSteven Baigal (sbaigal) <sbaigal@cisco.com>
Mon, 22 Jan 2024 23:56:50 +0000 (23:56 +0000)
Merge in SNORT/snort3 from ~DAVMCPHE/snort3:ips_seglist_hole_cscwh95127 to master

Squashed commit of the following:

commit 24510aba30c9cb8681d8bef03fb9b7d7ba2692f2
Author: davis mcpherson <davmcphe@cisco.com>
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

13 files changed:
src/stream/paf.h
src/stream/tcp/tcp_reassembler.cc
src/stream/tcp/tcp_reassembler.h
src/stream/tcp/tcp_reassemblers.h
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_session.h
src/stream/tcp/tcp_state_listen.cc
src/stream/tcp/tcp_state_mid_stream_recv.cc
src/stream/tcp/tcp_state_mid_stream_sent.cc
src/stream/tcp/tcp_state_none.cc
src/stream/tcp/tcp_stream_session.h
src/stream/tcp/tcp_stream_tracker.cc
src/stream/tcp/tcp_stream_tracker.h

index 6d47d33c5c0009a787656f6e603b0fc2b176d4e4..67e6c367751f07eb42abe806af31d8de075690ff 100644 (file)
@@ -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 );
index 527cb3c24de20c955c6c6ff004b1f849ba43e8c3..b31c79559f73da94e4148fd45af4ac788cf7b9ad 100644 (file)
@@ -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<Packet*>(p));
+       finish_and_final_flush(trs, flow, clear, const_cast<Packet*>(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;
index e25ca0b39c0999db8937e2444e98ba0299ecee7f..8dfd0787f0ddc84fe62e7981f8ed698d193b0022 100644 (file)
@@ -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);
 };
 
index 9525a38caa08eeb53e8dcd0096bd0974adf69dc5..211454f17aab9af8e94179260324adb769031f0f 100644 (file)
@@ -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); }
 
index 8ca8cf68d8958e3d1f64fc6a88a24e4af5a18a07..0c212be911c6c0de9129e92d3e2914d88add7064 100644 (file)
@@ -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)
index 2a559c9e23abd0995df3fed8d51c326306fda29a..47c70940d9ed6f699c879af37cecf7ed459e6ed6 100644 (file)
@@ -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)
index f080f247d6df13791f008dff2ddb5bb0529f0d0f..0e0488ab3f72ca85aa09ec449f266465ff4e10a9 100644 (file)
@@ -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() )
     {
index 2977b224b52ac94945e408bc9b8dc4e336239c88..37e5cae5406a847473a3e3e2f477a33b698a3c47 100644 (file)
@@ -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;
 }
 
index bc3fa43cdbc5d010c27babb9b7cad76e0bfe7757..e7bda4942fecb799be1ee031e09b9afc525aecb8 100644 (file)
@@ -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;
  }
 
index d4520cf4f1e75e8b37022a37babd7d479c03ca8a..23bffd8283c8d9676b664b91a196988b8364bce0 100644 (file)
@@ -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() )
     {
index 96e8a8bf6f7e3eb4045301e18d4b6a61fe4536dc..3bba9ac90de5c12d4b58752bd3ecdd83ab5eaac1 100644 (file)
@@ -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;
index 247940546389d159619860e65356cbaf9cb8ab41..e06eec19d944c1024a4df3149b2a943866216760 100644 (file)
@@ -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();
     }
 }
index cb718f9177ef862978b3f5a303697212bb2323a1..0c6dc3d9c1b4149dc907d38c31b8bad84a5617db 100644 (file)
@@ -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<HeldPacket>::iterator null_iterator;