]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4497: stream_tcp: fix core cause by seglist with nullptr value in TcpRe...
authorDavis McPherson -X (davmcphe - XORIANT CORPORATION at Cisco) <davmcphe@cisco.com>
Thu, 31 Oct 2024 16:13:32 +0000 (16:13 +0000)
committerSteven Baigal (sbaigal) <sbaigal@cisco.com>
Thu, 31 Oct 2024 16:13:32 +0000 (16:13 +0000)
Merge in SNORT/snort3 from ~DAVMCPHE/snort3:tcp_reassembly_core_fix2 to master

Squashed commit of the following:

commit 136be196a094fb3b909b5a5e79b0ae2ba70f8556
Author: davis mcpherson <davmcphe@cisco.com>
Date:   Tue Oct 29 17:09:49 2024 -0400

    stream_tcp: pass tracker and seglist to TcpReassembler* as refs, define dummy tracker & seglist for use by TcpReassemblerIgnore

src/stream/tcp/tcp_reassembler.cc
src/stream/tcp/tcp_reassembler.h
src/stream/tcp/tcp_reassembler_ids.cc
src/stream/tcp/tcp_reassembler_ids.h
src/stream/tcp/tcp_reassembler_ips.cc
src/stream/tcp/tcp_reassembler_ips.h
src/stream/tcp/tcp_session.h
src/stream/tcp/tcp_stream_tracker.cc

index df49f076369566e3119ec343081e25008c050560..ab9975719380845dee1725736f493dc9dd8060ec 100644 (file)
@@ -47,10 +47,10 @@ void TcpReassembler::init(bool server, StreamSplitter* ss)
 {
     splitter = ss;
     paf.paf_setup(ss);
-    if ( seglist->cur_rseg )
-        seglist->cur_sseg = seglist->cur_rseg;
+    if ( seglist.cur_rseg )
+        seglist.cur_sseg = seglist.cur_rseg;
     else
-        seglist->cur_sseg = seglist->head;
+        seglist.cur_sseg = seglist.head;
 
     server_side = server;
 
@@ -68,14 +68,14 @@ void TcpReassembler::init(bool server, StreamSplitter* ss)
 
 bool TcpReassembler::fin_no_gap(const TcpSegmentNode& tsn)
 {
-    return tracker->fin_seq_status >= FIN_WITH_SEQ_SEEN
-        and SEQ_GEQ(tsn.next_seq(), tracker->get_fin_i_seq());
+    return tracker.fin_seq_status >= FIN_WITH_SEQ_SEEN
+        and SEQ_GEQ(tsn.next_seq(), tracker.get_fin_i_seq());
 }
 
 bool TcpReassembler::fin_acked_no_gap(const TcpSegmentNode& tsn)
 {
-    return tracker->fin_seq_status >= FIN_WITH_SEQ_ACKED
-        and SEQ_GEQ(tsn.next_seq(), tracker->get_fin_i_seq());
+    return tracker.fin_seq_status >= FIN_WITH_SEQ_ACKED
+        and SEQ_GEQ(tsn.next_seq(), tracker.get_fin_i_seq());
 }
 
 // If we are skipping seglist hole, update tsn so that we can purge
@@ -83,7 +83,7 @@ void TcpReassembler::update_skipped_bytes(uint32_t remaining_bytes)
 {
     TcpSegmentNode* tsn;
 
-    while ( remaining_bytes and (tsn = seglist->cur_rseg) )
+    while ( remaining_bytes and (tsn = seglist.cur_rseg) )
     {
         auto bytes_skipped = ( tsn->unscanned() <= remaining_bytes ) ? tsn->unscanned() : remaining_bytes;
 
@@ -92,23 +92,23 @@ void TcpReassembler::update_skipped_bytes(uint32_t remaining_bytes)
 
         if ( !tsn->unscanned() )
         {
-            seglist->flush_count++;
-            seglist->update_next(tsn);
+            seglist.flush_count++;
+            seglist.update_next(tsn);
         }
     }
 }
 
 void TcpReassembler::purge_to_seq(uint32_t flush_seq)
 {
-    seglist->purge_flushed_segments(flush_seq);
+    seglist.purge_flushed_segments(flush_seq);
 
     if ( last_pdu )
     {
-        tracker->tcp_alerts.purge_alerts(*last_pdu, tracker->normalizer.is_tcp_ips_enabled());
+        tracker.tcp_alerts.purge_alerts(*last_pdu, tracker.normalizer.is_tcp_ips_enabled());
         last_pdu = nullptr;
     }
     else
-        tracker->tcp_alerts.purge_alerts(seglist->session->flow);
+        tracker.tcp_alerts.purge_alerts(seglist.session->flow);
 }
 
 // must only purge flushed and acked bytes we may flush partial segments
@@ -118,29 +118,29 @@ void TcpReassembler::purge_to_seq(uint32_t flush_seq)
 //   (if we reassemble such)
 void TcpReassembler::purge_flushed_ackd()
 {
-    if ( !seglist->head )
+    if ( !seglist.head )
         return;
 
-    uint32_t seq = seglist->head->start_seq();
-    TcpSegmentNode* tsn = seglist->head;
+    uint32_t seq = seglist.head->start_seq();
+    TcpSegmentNode* tsn = seglist.head;
     while ( tsn && !tsn->unscanned() )
     {
         uint32_t end = tsn->next_seq();
 
-        if ( SEQ_GT(end, tracker->r_win_base) )
+        if ( SEQ_GT(end, tracker.r_win_base) )
             break;
 
         seq = end;
         tsn = tsn->next;
     }
 
-    if ( !SEQ_EQ(seq, seglist->head->start_seq()) )
+    if ( !SEQ_EQ(seq, seglist.head->start_seq()) )
         purge_to_seq(seq);
 }
 
 void TcpReassembler::show_rebuilt_packet(Packet* pkt)
 {
-    if ( seglist->session->tcp_config->flags & STREAM_CONFIG_SHOW_PACKETS )
+    if ( seglist.session->tcp_config->flags & STREAM_CONFIG_SHOW_PACKETS )
     {
         // FIXIT-L setting conf here is required because this is called before context start
         pkt->context->conf = SnortConfig::get_conf();
@@ -153,13 +153,13 @@ int TcpReassembler::flush_data_segments(uint32_t flush_len, Packet* pdu)
 {
     uint32_t flags = PKT_PDU_HEAD;
 
-    uint32_t to_seq = seglist->cur_rseg->scan_seq() + flush_len;
+    uint32_t to_seq = seglist.cur_rseg->scan_seq() + flush_len;
     uint32_t remaining_bytes = flush_len;
     uint32_t total_flushed = 0;
 
     while ( remaining_bytes )
     {
-        TcpSegmentNode* tsn = seglist->cur_rseg;
+        TcpSegmentNode* tsn = seglist.cur_rseg;
         unsigned bytes_to_copy = ( tsn->unscanned() <= remaining_bytes ) ? tsn->unscanned() : remaining_bytes;
 
         remaining_bytes -= bytes_to_copy;
@@ -169,7 +169,7 @@ int TcpReassembler::flush_data_segments(uint32_t flush_len, Packet* pdu)
             assert( bytes_to_copy >= tsn->unscanned() );
 
         unsigned bytes_copied = 0;
-        const StreamBuffer sb = splitter->reassemble(seglist->session->flow, flush_len, total_flushed,
+        const StreamBuffer sb = splitter->reassemble(seglist.session->flow, flush_len, total_flushed,
             tsn->paf_data(), bytes_to_copy, flags, bytes_copied);
 
         if ( sb.data )
@@ -184,8 +184,8 @@ int TcpReassembler::flush_data_segments(uint32_t flush_len, Packet* pdu)
 
         if ( !tsn->unscanned() )
         {
-            seglist->flush_count++;
-            seglist->update_next(tsn);
+            seglist.flush_count++;
+            seglist.update_next(tsn);
         }
 
         /* Check for a gap/missing packet */
@@ -194,15 +194,15 @@ int TcpReassembler::flush_data_segments(uint32_t flush_len, Packet* pdu)
         {
             // FIXIT-H // assert(false); find when this scenario happens
             // FIXIT-L this is suboptimal - better to exclude fin from to_seq
-            if ( !tracker->is_fin_seq_set() or
-                SEQ_LEQ(to_seq, tracker->get_fin_final_seq()) )
+            if ( !tracker.is_fin_seq_set() or
+                SEQ_LEQ(to_seq, tracker.get_fin_final_seq()) )
             {
-                tracker->set_tf_flags(TF_MISSING_PKT);
+                tracker.set_tf_flags(TF_MISSING_PKT);
             }
             break;
         }
 
-        if ( sb.data || !seglist->cur_rseg )
+        if ( sb.data || !seglist.cur_rseg )
             break;
     }
 
@@ -267,9 +267,9 @@ Packet* TcpReassembler::initialize_pdu(Packet* p, uint32_t pkt_flags, struct tim
 
     EncodeFlags enc_flags = 0;
     DAQ_PktHdr_t pkth;
-    seglist->session->get_packet_header_foo(&pkth, p->pkth, pkt_flags);
+    seglist.session->get_packet_header_foo(&pkth, p->pkth, pkt_flags);
     PacketManager::format_tcp(enc_flags, p, pdu, PSEUDO_PKT_TCP, &pkth, pkth.opaque);
-    prep_pdu(seglist->session->flow, p, pkt_flags, pdu);
+    prep_pdu(seglist.session->flow, p, pkt_flags, pdu);
     assert(pdu->pkth == pdu->context->pkth);
     pdu->context->pkth->ts = tv;
     pdu->dsize = 0;
@@ -291,18 +291,18 @@ Packet* TcpReassembler::initialize_pdu(Packet* p, uint32_t pkt_flags, struct tim
 // flush a seglist up to the given point, generate a pseudopacket, and fire it thru the system.
 int TcpReassembler::flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags)
 {
-    assert( p && seglist->cur_rseg);
+    assert( p && seglist.cur_rseg);
 
-    tracker->clear_tf_flags(TF_MISSING_PKT | TF_MISSING_PREV_PKT);
+    tracker.clear_tf_flags(TF_MISSING_PKT | TF_MISSING_PREV_PKT);
 
-    TcpSegmentNode* tsn = seglist->cur_rseg;
-    assert( seglist->seglist_base_seq == tsn->scan_seq());
+    TcpSegmentNode* tsn = seglist.cur_rseg;
+    assert( seglist.seglist_base_seq == tsn->scan_seq());
 
     Packet* pdu = initialize_pdu(p, pkt_flags, tsn->tv);
     int32_t flushed_bytes = flush_data_segments(bytes, pdu);
     assert( flushed_bytes );
 
-    seglist->seglist_base_seq += flushed_bytes;
+    seglist.seglist_base_seq += flushed_bytes;
 
     if ( pdu->data )
     {
@@ -322,7 +322,7 @@ int TcpReassembler::flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags)
         else
             last_pdu = nullptr;
 
-        tracker->finalize_held_packet(p);
+        tracker.finalize_held_packet(p);
     }
     else
     {
@@ -331,14 +331,14 @@ int TcpReassembler::flush_to_seq(uint32_t bytes, Packet* p, uint32_t pkt_flags)
     }
 
     // FIXIT-L abort should be by PAF callback only since recovery may be possible
-    if ( tracker->get_tf_flags() & TF_MISSING_PKT )
+    if ( tracker.get_tf_flags() & TF_MISSING_PKT )
     {
-        tracker->set_tf_flags(TF_MISSING_PREV_PKT | TF_PKT_MISSED);
-        tracker->clear_tf_flags(TF_MISSING_PKT);
+        tracker.set_tf_flags(TF_MISSING_PREV_PKT | TF_PKT_MISSED);
+        tracker.clear_tf_flags(TF_MISSING_PKT);
         tcpStats.gaps++;
     }
     else
-        tracker->clear_tf_flags(TF_MISSING_PREV_PKT);
+        tracker.clear_tf_flags(TF_MISSING_PREV_PKT);
 
     return flushed_bytes;
 }
@@ -347,7 +347,7 @@ int TcpReassembler::do_zero_byte_flush(Packet* p, uint32_t pkt_flags)
 {
     unsigned bytes_copied = 0;
 
-    const StreamBuffer sb = splitter->reassemble(seglist->session->flow, 0, 0,
+    const StreamBuffer sb = splitter->reassemble(seglist.session->flow, 0, 0,
         nullptr, 0, (PKT_PDU_HEAD | PKT_PDU_TAIL), bytes_copied);
 
      if ( sb.data )
@@ -375,8 +375,8 @@ uint32_t TcpReassembler::get_q_footprint()
     int32_t footprint = 0;
     int32_t sequenced = 0;
 
-    if ( SEQ_GT(tracker->r_win_base, seglist->seglist_base_seq) )
-        footprint = tracker->r_win_base - seglist->seglist_base_seq;
+    if ( SEQ_GT(tracker.r_win_base, seglist.seglist_base_seq) )
+        footprint = tracker.r_win_base - seglist.seglist_base_seq;
 
     if ( footprint )
         sequenced = get_q_sequenced();
@@ -390,16 +390,16 @@ uint32_t TcpReassembler::get_q_footprint()
 
 uint32_t TcpReassembler::get_q_sequenced()
 {
-    TcpSegmentNode* tsn = seglist->cur_rseg;
+    TcpSegmentNode* tsn = seglist.cur_rseg;
 
     if ( !tsn )
     {
-        tsn = seglist->head;
+        tsn = seglist.head;
 
-        if ( !tsn || SEQ_LT(tracker->r_win_base, tsn->scan_seq()) )
+        if ( !tsn || SEQ_LT(tracker.r_win_base, tsn->scan_seq()) )
             return 0;
 
-        seglist->cur_rseg = tsn;
+        seglist.cur_rseg = tsn;
     }
 
     uint32_t len = 0;
@@ -408,7 +408,7 @@ uint32_t TcpReassembler::get_q_sequenced()
     {
 
         if ( !tsn->unscanned() )
-            seglist->cur_rseg = tsn->next;
+            seglist.cur_rseg = tsn->next;
         else
             len += tsn->unscanned();
 
@@ -417,22 +417,22 @@ uint32_t TcpReassembler::get_q_sequenced()
     if ( tsn->unscanned() )
         len += tsn->unscanned();
 
-    seglist->seglist_base_seq = seglist->cur_rseg->scan_seq();
+    seglist.seglist_base_seq = seglist.cur_rseg->scan_seq();
 
     return len;
 }
 
 bool TcpReassembler::is_q_sequenced()
 {
-    TcpSegmentNode* tsn = seglist->cur_rseg;
+    TcpSegmentNode* tsn = seglist.cur_rseg;
 
     if ( !tsn )
     {
-        tsn = seglist->head;
-        if ( !tsn || SEQ_LT(tracker->r_win_base, tsn->scan_seq()) )
+        tsn = seglist.head;
+        if ( !tsn || SEQ_LT(tracker.r_win_base, tsn->scan_seq()) )
             return false;
 
-        seglist->cur_rseg = tsn;
+        seglist.cur_rseg = tsn;
     }
 
     while ( tsn->next_no_gap() )
@@ -440,17 +440,17 @@ bool TcpReassembler::is_q_sequenced()
         if ( tsn->unscanned() )
             break;
 
-        tsn = seglist->cur_rseg = tsn->next;
+        tsn = seglist.cur_rseg = tsn->next;
     }
 
-    seglist->seglist_base_seq = tsn->scan_seq();
+    seglist.seglist_base_seq = tsn->scan_seq();
 
     return (tsn->unscanned() != 0);
 }
 
 void TcpReassembler::final_flush(Packet* p, uint32_t dir)
 {
-    tracker->set_tf_flags(TF_FORCE_FLUSH);
+    tracker.set_tf_flags(TF_FORCE_FLUSH);
 
     if ( flush_stream(p, dir, true) )
     {
@@ -461,7 +461,7 @@ void TcpReassembler::final_flush(Packet* p, uint32_t dir)
 
         purge_flushed_ackd();
     }
-    tracker->clear_tf_flags(TF_FORCE_FLUSH);
+    tracker.clear_tf_flags(TF_FORCE_FLUSH);
 }
 
 static Packet* get_packet(Flow* flow, uint32_t flags, bool c2s)
@@ -552,10 +552,10 @@ void TcpReassembler::flush_queued_segments(Flow* flow, bool clear, Packet* p)
 
 void TcpReassembler::check_first_segment_hole()
 {
-    if ( SEQ_LT(seglist->seglist_base_seq, seglist->head->start_seq()) )
+    if ( SEQ_LT(seglist.seglist_base_seq, seglist.head->start_seq()) )
     {
-        seglist->seglist_base_seq = seglist->head->start_seq();
-        seglist->advance_rcv_nxt();
+        seglist.seglist_base_seq = seglist.head->start_seq();
+        seglist.advance_rcv_nxt();
         paf.state = StreamSplitter::START;
     }
 }
@@ -576,10 +576,10 @@ uint32_t TcpReassembler::perform_partial_flush(Packet* p)
         paf.paf_jump(flushed);
         tcpStats.partial_flushes++;
         tcpStats.partial_flush_bytes += flushed;
-        if ( seglist->seg_count )
+        if ( seglist.seg_count )
         {
-            purge_to_seq(seglist->head->start_seq() + flushed);
-            tracker->r_win_base = seglist->seglist_base_seq;
+            purge_to_seq(seglist.head->start_seq() + flushed);
+            tracker.r_win_base = seglist.seglist_base_seq;
         }
     }
 
@@ -591,7 +591,7 @@ uint32_t TcpReassembler::perform_partial_flush(Packet* p)
 // FIXIT-M this convoluted expression needs some refactoring to simplify
 bool TcpReassembler::final_flush_on_fin(int32_t flush_amt, Packet *p, FinSeqNumStatus fin_status)
 {
-    return tracker->fin_seq_status >= fin_status
+    return tracker.fin_seq_status >= fin_status
         && -1 <= flush_amt && flush_amt <= 0
         && paf.state == StreamSplitter::SEARCH
         && !p->flow->searching_for_service();
@@ -599,10 +599,10 @@ bool TcpReassembler::final_flush_on_fin(int32_t flush_amt, Packet *p, FinSeqNumS
 
 bool TcpReassembler::asymmetric_flow_flushed(uint32_t flushed, snort::Packet *p)
 {
-    bool asymmetric = flushed && seglist->seg_count && !p->flow->two_way_traffic() && !p->ptrs.tcph->is_syn();
+    bool asymmetric = flushed && seglist.seg_count && !p->flow->two_way_traffic() && !p->ptrs.tcph->is_syn();
     if ( asymmetric )
     {
-        TcpStreamTracker::TcpState peer = tracker->session->get_peer_state(tracker);
+        TcpStreamTracker::TcpState peer = tracker.session->get_peer_state(tracker);
         asymmetric = ( peer == TcpStreamTracker::TCP_SYN_SENT || peer == TcpStreamTracker::TCP_SYN_RECV
             || peer == TcpStreamTracker::TCP_MID_STREAM_SENT );
     }
@@ -610,6 +610,24 @@ bool TcpReassembler::asymmetric_flow_flushed(uint32_t flushed, snort::Packet *p)
     return asymmetric;
 }
 
+// define a tracker to assign to the Ignore Flush Policy reassembler and
+// create an instance of the Ignore reassembler.  When reassembly is ignored
+// all operations are no-ops so a single instance is created and shared by
+// all TCP sessions with a flush policy of ignore.  Minimal initialization
+// is performed as no state or processing is done by this reassembler.
+// The ignore tracker reassembler member variable is set to the ignore
+// reassembler as it is referenced in the dtor of the tracker.  The ignore
+// tracker is never assigned or used by a Flow, it's only purpose is to
+// be passed into the ignore reassembler (along with the tracker's seglist)
+TcpStreamTracker ignore_tracker(false);
+TcpReassemblerIgnore* tcp_ignore_reassembler = new TcpReassemblerIgnore();
+
+TcpReassemblerIgnore::TcpReassemblerIgnore()
+    : TcpReassembler(ignore_tracker, ignore_tracker.seglist)
+{
+    tracker.reassembler = this;
+}
+
 uint32_t TcpReassemblerIgnore::perform_partial_flush(snort::Flow* flow, snort::Packet*& p)
 {
     p = get_packet(flow, packet_dir, server_side);
index a966241828acd83d7dfc96c81cb49cd85431006b..bb85b128b80c9042e4a1100f5377ae7399ef0676 100644 (file)
@@ -52,7 +52,7 @@ public:
         FINAL_FLUSH_OK = -1
     };
 
-    TcpReassembler(TcpStreamTracker* trk, TcpReassemblySegments* seglist)
+    TcpReassembler(TcpStreamTracker& trk, TcpReassemblySegments& seglist)
         : tracker(trk), seglist(seglist)
     { }
 
@@ -84,16 +84,16 @@ public:
             return false;
     }
 
-    void initialize_paf()
+    virtual void initialize_paf()
     {
         assert( get_flush_policy() != STREAM_FLPOLICY_IGNORE );
 
         // only initialize if we have a data segment queued
-        if ( !seglist->head )
+        if ( !seglist.head )
             return;
 
-       if ( !paf.paf_initialized() or !SEQ_EQ(paf.seq_num, seglist->head->start_seq()) )
-            paf.paf_initialize(seglist->head->start_seq());
+       if ( !paf.paf_initialized() or !SEQ_EQ(paf.seq_num, seglist.head->start_seq()) )
+            paf.paf_initialize(seglist.head->start_seq());
     }
 
     void reset_paf()
@@ -125,8 +125,8 @@ protected:
     bool asymmetric_flow_flushed(uint32_t flushed, snort::Packet *p);
 
     ProtocolAwareFlusher paf;
-    TcpStreamTracker* tracker = nullptr;
-    TcpReassemblySegments* seglist = nullptr;
+    TcpStreamTracker& tracker;
+    TcpReassemblySegments& seglist;
     snort::StreamSplitter* splitter = nullptr;
 
     snort::Packet* last_pdu = nullptr;
@@ -139,8 +139,8 @@ protected:
 class TcpReassemblerIgnore : public TcpReassembler
 {
 public:
-       TcpReassemblerIgnore(TcpStreamTracker* trk, TcpReassemblySegments* sl)
-        : TcpReassembler(trk, sl)
+    TcpReassemblerIgnore();
+    ~TcpReassemblerIgnore() override
     { }
 
     void init(bool, snort::StreamSplitter*) override
@@ -169,9 +169,14 @@ public:
     void purge_flushed_ackd() override
     { }
 
+    virtual void initialize_paf() override
+    { }
+
     FlushPolicy get_flush_policy() const override
     { return STREAM_FLPOLICY_IGNORE; }
 };
 
+extern TcpReassemblerIgnore* tcp_ignore_reassembler;
+
 #endif
 
index 54518aef488df36f4d8b901989790f2564780eb7..77cb9de9d4a6d7dfdede493ecb66b197c27962f1 100644 (file)
@@ -47,7 +47,7 @@ using namespace snort;
 bool TcpReassemblerIds::has_seglist_hole(TcpSegmentNode& tsn, uint32_t& total, uint32_t& flags)
 {
     if ( !tsn.prev or SEQ_GEQ(tsn.prev->scan_seq() + tsn.prev->unscanned(), tsn.scan_seq())
-       or SEQ_GEQ(tsn.scan_seq(), tracker->r_win_base) )
+       or SEQ_GEQ(tsn.scan_seq(), tracker.r_win_base) )
     {
        check_first_segment_hole();
        return false;
@@ -70,7 +70,7 @@ void TcpReassemblerIds::skip_seglist_hole(Packet* p, uint32_t flags, int32_t flu
     {
         if ( flush_amt > 0 )
             update_skipped_bytes(flush_amt);
-        tracker->fallback();
+        tracker.fallback();
     }
     else
     {
@@ -79,17 +79,17 @@ void TcpReassemblerIds::skip_seglist_hole(Packet* p, uint32_t flags, int32_t flu
         paf.state = StreamSplitter::START;
     }
 
-    if ( seglist->head )
+    if ( seglist.head )
     {
         if ( flush_amt > 0 )
-            purge_to_seq(seglist->seglist_base_seq + flush_amt);
-        seglist->seglist_base_seq = seglist->head->scan_seq();
+            purge_to_seq(seglist.seglist_base_seq + flush_amt);
+        seglist.seglist_base_seq = seglist.head->scan_seq();
     }
     else
-        seglist->seglist_base_seq = tracker->r_win_base;  // FIXIT-H - do we need to set rcv_nxt here?
+        seglist.seglist_base_seq = tracker.r_win_base;  // FIXIT-H - do we need to set rcv_nxt here?
 
-    seglist->cur_rseg = seglist->head;
-    tracker->set_order(TcpStreamTracker::OUT_OF_SEQUENCE);
+    seglist.cur_rseg = seglist.head;
+    tracker.set_order(TcpStreamTracker::OUT_OF_SEQUENCE);
 }
 
 // iterate over seglist and scan all new acked bytes
@@ -108,44 +108,44 @@ void TcpReassemblerIds::skip_seglist_hole(Packet* p, uint32_t flags, int32_t flu
 //   know where we left off and can resume scanning the remainder
 int32_t TcpReassemblerIds::scan_data_post_ack(uint32_t* flags, Packet* p)
 {
-    assert(seglist->session->flow == p->flow);
+    assert(seglist.session->flow == p->flow);
 
     int32_t ret_val = FINAL_FLUSH_HOLD;
 
-    if ( !seglist->cur_sseg || SEQ_GEQ(seglist->seglist_base_seq, tracker->r_win_base) )
+    if ( !seglist.cur_sseg || SEQ_GEQ(seglist.seglist_base_seq, tracker.r_win_base) )
         return ret_val ;
 
-    if ( !seglist->cur_rseg )
-        seglist->cur_rseg = seglist->cur_sseg;
+    if ( !seglist.cur_rseg )
+        seglist.cur_rseg = seglist.cur_sseg;
 
     uint32_t total = 0;
-    TcpSegmentNode* tsn = seglist->cur_sseg;
+    TcpSegmentNode* tsn = seglist.cur_sseg;
     if ( paf.paf_initialized() )
     {
         uint32_t end_seq = tsn->scan_seq() + tsn->unscanned();
         if ( SEQ_EQ(end_seq, paf.paf_position()) )
         {
-            total = end_seq - seglist->seglist_base_seq;
+            total = end_seq - seglist.seglist_base_seq;
             tsn = tsn->next;
         }
         else
-            total = tsn->scan_seq() - seglist->cur_rseg->scan_seq();
+            total = tsn->scan_seq() - seglist.cur_rseg->scan_seq();
     }
 
     ret_val = FINAL_FLUSH_OK;
-    while (tsn && *flags && SEQ_LT(tsn->scan_seq(), tracker->r_win_base))
+    while (tsn && *flags && SEQ_LT(tsn->scan_seq(), tracker.r_win_base))
     {
         // only flush acked data that fits in pdu reassembly buffer...
         uint32_t end = tsn->scan_seq() + tsn->unscanned();
         uint32_t flush_len;
         int32_t flush_pt;
 
-        if ( SEQ_GT(end, tracker->r_win_base))
-            flush_len = tracker->r_win_base - tsn->scan_seq();
+        if ( SEQ_GT(end, tracker.r_win_base))
+            flush_len = tracker.r_win_base - tsn->scan_seq();
         else
             flush_len = tsn->unscanned();
 
-        if ( tsn->next_acked_no_gap(tracker->r_win_base) )
+        if ( tsn->next_acked_no_gap(tracker.r_win_base) )
             *flags |= PKT_MORE_TO_FLUSH;
         else
             *flags &= ~PKT_MORE_TO_FLUSH;
@@ -159,11 +159,11 @@ int32_t TcpReassemblerIds::scan_data_post_ack(uint32_t* flags, Packet* p)
         }
 
         // Get splitter from tracker as paf check may change it.
-        seglist->cur_sseg = tsn;
+        seglist.cur_sseg = tsn;
 
         if ( flush_pt >= 0 )
         {
-            seglist->seglist_base_seq = seglist->cur_rseg->scan_seq();
+            seglist.seglist_base_seq = seglist.cur_rseg->scan_seq();
             return flush_pt;
         }
 
@@ -201,13 +201,13 @@ int TcpReassemblerIds::eval_flush_policy_on_ack(Packet* p)
         assert( flushed );
 
         // ideally we would purge just once after this loop but that throws off base
-        if ( seglist->head )
-            purge_to_seq(seglist->seglist_base_seq);
-    } while ( seglist->head and !p->flow->is_inspection_disabled() );
+        if ( seglist.head )
+            purge_to_seq(seglist.seglist_base_seq);
+    } while ( seglist.head and !p->flow->is_inspection_disabled() );
 
     if ( (paf.state == StreamSplitter::ABORT) && is_splitter_paf() )
     {
-        tracker->fallback();
+        tracker.fallback();
         return eval_flush_policy_on_ack(p);
     }
     else if ( paf.state == StreamSplitter::SKIP )
@@ -225,16 +225,16 @@ int TcpReassemblerIds::eval_flush_policy_on_data(Packet* p)
 {
     uint32_t flushed = 0;
 
-    if ( !seglist->head )
+    if ( !seglist.head )
         return flushed;
 
-    if ( tracker->is_retransmit_of_held_packet(p) )
+    if ( tracker.is_retransmit_of_held_packet(p) )
         flushed += perform_partial_flush(p);
 
     if ( !p->flow->two_way_traffic() and
-        seglist->get_seg_bytes_total() > seglist->session->tcp_config->asymmetric_ids_flush_threshold )
+        seglist.get_seg_bytes_total() > seglist.session->tcp_config->asymmetric_ids_flush_threshold )
     {
-        seglist->skip_hole_at_beginning(seglist->head);
+        seglist.skip_hole_at_beginning(seglist.head);
         flushed += eval_asymmetric_flush(p);
     }
 
@@ -244,7 +244,7 @@ int TcpReassemblerIds::eval_flush_policy_on_data(Packet* p)
 int TcpReassemblerIds::eval_asymmetric_flush(snort::Packet* p)
 {
     // asymmetric flush in IDS mode.. advance r_win_base to end of in-order data
-    tracker->r_win_base = tracker->rcv_nxt;
+    tracker.r_win_base = tracker.rcv_nxt;
 
     uint32_t flushed = eval_flush_policy_on_ack(p);
     if ( flushed )
@@ -261,7 +261,7 @@ int TcpReassemblerIds::flush_stream(Packet* p, uint32_t dir, bool final_flush)
 {
     uint32_t bytes = 0;
 
-    if ( seglist->session->flow->two_way_traffic() )
+    if ( seglist.session->flow->two_way_traffic() )
         bytes = get_q_footprint();
     else
         bytes = get_q_sequenced();
index 131b92de8d0f9deed77861e86b2e6eb51461c58b..099d5c33bb708621c1a96106a7fa7e358098c690 100644 (file)
@@ -36,9 +36,7 @@ class TcpSegmentNode;
 class TcpReassemblerIds : public TcpReassembler
 {
 public:
-
-
-    TcpReassemblerIds(TcpStreamTracker* trk, TcpReassemblySegments* sl)
+    TcpReassemblerIds(TcpStreamTracker& trk, TcpReassemblySegments& sl)
         : TcpReassembler(trk, sl)
     { }
 
index 3795f5c90c99a2cc799bdfb51550df159c69d2ca..21dc7d7afe54d09721a7c564965e22ab356436bc 100644 (file)
@@ -49,21 +49,21 @@ using namespace snort;
 // because we don't wait until it is acknowledged
 int32_t TcpReassemblerIps::scan_data_pre_ack(uint32_t* flags, Packet* p)
 {
-    assert(seglist->session->flow == p->flow);
+    assert(seglist.session->flow == p->flow);
 
     int32_t ret_val = FINAL_FLUSH_HOLD;
 
-    if ( SEQ_GT(seglist->head->scan_seq(), seglist->seglist_base_seq) )
+    if ( SEQ_GT(seglist.head->scan_seq(), seglist.seglist_base_seq) )
         return ret_val;
 
-    if ( !seglist->cur_rseg )
-        seglist->cur_rseg = seglist->cur_sseg;
+    if ( !seglist.cur_rseg )
+        seglist.cur_rseg = seglist.cur_sseg;
 
     if ( !is_q_sequenced() )
         return ret_val;
 
-    TcpSegmentNode* tsn = seglist->cur_sseg;
-    uint32_t total = tsn->scan_seq() - seglist->seglist_base_seq;
+    TcpSegmentNode* tsn = seglist.cur_sseg;
+    uint32_t total = tsn->scan_seq() - seglist.seglist_base_seq;
 
     ret_val = FINAL_FLUSH_OK;
     while ( tsn && *flags )
@@ -94,7 +94,7 @@ int32_t TcpReassemblerIps::scan_data_pre_ack(uint32_t* flags, Packet* p)
 
         if (flush_pt >= 0)
         {
-            seglist->cur_sseg = tsn;
+            seglist.cur_sseg = tsn;
             return flush_pt;
         }
 
@@ -108,7 +108,7 @@ int32_t TcpReassemblerIps::scan_data_pre_ack(uint32_t* flags, Packet* p)
         tsn = tsn->next;
     }
 
-    seglist->cur_sseg = tsn;
+    seglist.cur_sseg = tsn;
     
     return ret_val;
 }
@@ -122,7 +122,7 @@ int TcpReassemblerIps::eval_flush_policy_on_ack(Packet*)
 
 int TcpReassemblerIps::eval_flush_policy_on_data(Packet* p)
 {
-    if ( !seglist->head )
+    if ( !seglist.head )
         return 0;
 
     last_pdu = nullptr;
@@ -138,20 +138,20 @@ int TcpReassemblerIps::eval_flush_policy_on_data(Packet* p)
             break;
 
         flushed += flush_to_seq(flush_amt, p, flags);
-    } while ( seglist->head and !p->flow->is_inspection_disabled() );
+    } while ( seglist.head and !p->flow->is_inspection_disabled() );
 
     if ( (paf.state == StreamSplitter::ABORT) && is_splitter_paf() )
     {
-        tracker->fallback();
+        tracker.fallback();
         return eval_flush_policy_on_data(p);
     }
     else if ( final_flush_on_fin(flush_amt, p, FIN_WITH_SEQ_SEEN) )
         finish_and_final_flush(p->flow, true, p);
 
-    if ( !seglist->head )
+    if ( !seglist.head )
         return flushed;
 
-    if ( tracker->is_retransmit_of_held_packet(p) )
+    if ( tracker.is_retransmit_of_held_packet(p) )
         flushed += perform_partial_flush(p);
 
     if ( asymmetric_flow_flushed(flushed, p) )
@@ -159,8 +159,8 @@ int TcpReassemblerIps::eval_flush_policy_on_data(Packet* p)
         if (PacketTracer::is_active())
             PacketTracer::log("stream_tcp: IPS mode - %u bytes flushed on asymmetric flow\n", flushed);
 
-        purge_to_seq(seglist->head->start_seq() + flushed);
-        tracker->r_win_base = seglist->seglist_base_seq;
+        purge_to_seq(seglist.head->start_seq() + flushed);
+        tracker.r_win_base = seglist.seglist_base_seq;
         tcpStats.flush_on_asymmetric_flow++;
     }
 
@@ -174,8 +174,8 @@ int TcpReassemblerIps::eval_asymmetric_flush(snort::Packet* p)
 
 int TcpReassemblerIps::flush_stream(Packet* p, uint32_t dir, bool final_flush)
 {
-    if ( seglist->session->flow->two_way_traffic()
-        or (tracker->get_tcp_state() == TcpStreamTracker::TCP_MID_STREAM_RECV) )
+    if ( seglist.session->flow->two_way_traffic()
+        or (tracker.get_tcp_state() == TcpStreamTracker::TCP_MID_STREAM_RECV) )
     {
         uint32_t bytes = get_q_sequenced();  // num bytes in pre-ack mode
         if ( bytes )
index 328cfbbd3bf21af1558ba3a30f072bdc7f05ea78..3a81efd1ee10138ddd013d123170218cd6f4a5e9 100644 (file)
@@ -37,7 +37,7 @@ class TcpSegmentNode;
 class TcpReassemblerIps : public TcpReassembler
 {
 public:
-    TcpReassemblerIps(TcpStreamTracker* trk, TcpReassemblySegments* sl)
+    TcpReassemblerIps(TcpStreamTracker& trk, TcpReassemblySegments& sl)
         : TcpReassembler(trk, sl)
     { }
 
index f66b72e55472272b1dca9fe2933b93c866ea06cc..5c496e3f375baf77210c2c42302d18577a70cd1b 100644 (file)
@@ -83,8 +83,8 @@ public:
     void clear_session(bool free_flow_data, bool flush_segments, bool restart, snort::Packet* p = nullptr);
     TcpStreamTracker::TcpState get_talker_state(const TcpSegmentDescriptor& tsd);
     TcpStreamTracker::TcpState get_listener_state(const TcpSegmentDescriptor& tsd);
-    TcpStreamTracker::TcpState get_peer_state(const TcpStreamTracker* me)
-    { return me == &client ? server.get_tcp_state() : client.get_tcp_state(); }
+    TcpStreamTracker::TcpState get_peer_state(const TcpStreamTracker& me)
+    { return me.client_tracker ? server.get_tcp_state() : client.get_tcp_state(); }
 
     void init_new_tcp_session(TcpSegmentDescriptor&);
     void update_perf_base_state(char new_state);
index 1f5f4b66b72a25dc7a01ee72f0e48bc64b1016c8..a0f0e12a9c6f7f7c194992f7ae99847ff76f359e 100644 (file)
@@ -47,7 +47,6 @@
 using namespace snort;
 
 THREAD_LOCAL HeldPacketQueue* hpq = nullptr;
-TcpReassemblerIgnore* tcp_ignore_reassembler = new TcpReassemblerIgnore(nullptr, nullptr);
 
 const std::list<HeldPacket>::iterator TcpStreamTracker::null_iterator { };
 
@@ -380,7 +379,7 @@ void TcpStreamTracker::update_flush_policy(StreamSplitter* splitter)
             assert( reassembler->get_flush_policy() != STREAM_FLPOLICY_ON_ACK );
         }
 
-        reassembler = new  TcpReassemblerIps(this, &seglist);
+        reassembler = new TcpReassemblerIps(*this, seglist);
         reassembler->init(!client_tracker, splitter);
     }
     else
@@ -391,7 +390,7 @@ void TcpStreamTracker::update_flush_policy(StreamSplitter* splitter)
             assert( reassembler->get_flush_policy() != STREAM_FLPOLICY_ON_DATA );
         }
 
-        reassembler = new  TcpReassemblerIds(this, &seglist);
+        reassembler = new TcpReassemblerIds(*this, seglist);
         reassembler->init(!client_tracker, splitter);
     }
 }