]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2885 in SNORT/snort3 from ~MDAGON/snort3:res_depth to master
authorTom Peters (thopeter) <thopeter@cisco.com>
Tue, 18 May 2021 21:05:04 +0000 (21:05 +0000)
committerTom Peters (thopeter) <thopeter@cisco.com>
Tue, 18 May 2021 21:05:04 +0000 (21:05 +0000)
Squashed commit of the following:

commit 94b659b9e667930660a9434d0c9a514d3b187617
Author: Maya Dagon <mdagon@cisco.com>
Date:   Fri Apr 23 11:03:32 2021 -0400

    http2_inspect: optimize processing after reaching flow depth

src/service_inspectors/http2_inspect/http2_stream.h
src/service_inspectors/http2_inspect/http2_stream_splitter.h
src/service_inspectors/http2_inspect/http2_stream_splitter_impl.cc

index ec0209f288eabda23c3d3a8afc1d25c38b07286c..e9e4e65bb7d1d24c697abd4760f1b56cc4696a17 100644 (file)
@@ -58,6 +58,10 @@ public:
         { return end_stream_on_data_flush[source_id]; }
     void finish_msg_body(HttpCommon::SourceId source_id, bool expect_trailers,
         bool clear_partial_buffer);
+    void set_discard(HttpCommon::SourceId source_id)
+    { discard[source_id] = true; }
+    bool is_discard_set(HttpCommon::SourceId source_id)
+    { return discard[source_id]; }
 
 #ifdef REG_TEST
     void print_frame(FILE* output);
@@ -71,6 +75,7 @@ private:
     bool end_stream_on_data_flush[2] = { false, false };
     Http2Enums::StreamState state[2] =
         { Http2Enums::STREAM_EXPECT_HEADERS, Http2Enums::STREAM_EXPECT_HEADERS };
+    bool discard[2] = { false, false };
 };
 
 #endif
index 38248e4eeb02d7709ca375f71ce0135ef4bf6286..624aa70daad6ed8e2338a8d82b1a387861e3f20b 100644 (file)
@@ -60,7 +60,7 @@ private:
         HttpCommon::SourceId source_id);
     static bool read_frame_hdr(Http2FlowData* session_data, const uint8_t* data,
         uint32_t length, HttpCommon::SourceId source_id, uint32_t& data_offset);
-    static void discarded_data_frame_cleanup(Http2FlowData* session_data, HttpCommon::SourceId source_id);
+    static void discarded_data_frame_cleanup(Http2FlowData* session_data, HttpCommon::SourceId source_id, Http2Stream* stream);
 };
 
 
index 98ab536db3e0e1f516e1a69cd1ccbe224f5a08b9..964fdd59661025774e26c4b0f6f40c1b6d1ab1fa 100644 (file)
@@ -331,14 +331,14 @@ StreamSplitter::Status Http2StreamSplitter::implement_scan(Http2FlowData* sessio
                 {
                     Http2Stream* const stream =
                         session_data->find_stream(session_data->current_stream[source_id]);
-                    if (stream && stream->is_open(source_id))
+                    if (stream && stream->is_open(source_id) && !stream->is_discard_set(source_id))
                     {
                         status = session_data->data_cutter[source_id].scan(
                             data, length, flush_offset, data_offset, frame_flags);
                     }
                     else
                     {
-                        // Need to skip past Data frame in a bad stream
+                        // Need to skip past Data frame in a bad stream or if passed flow depth
                         uint32_t& remaining = session_data->scan_remaining_frame_octets[source_id];
                         if (length - data_offset < remaining)
                         {
@@ -351,9 +351,18 @@ StreamSplitter::Status Http2StreamSplitter::implement_scan(Http2FlowData* sessio
                             remaining = 0;
                             session_data->header_octets_seen[source_id] = 0;
                             session_data->scan_state[source_id] = SCAN_FRAME_HEADER;
-                            assert(!session_data->frame_lengths[source_id].empty());
-                            session_data->frame_lengths[source_id].pop();
-                            assert(session_data->frame_lengths[source_id].empty());
+
+                            if (!session_data->frame_lengths[source_id].empty())
+                            {
+                                session_data->frame_lengths[source_id].pop();
+                                assert(session_data->frame_lengths[source_id].empty());
+                            }
+
+                            if (stream && ((frame_flags & FLAG_END_STREAM) != 0))
+                            {
+                                stream->set_end_stream_on_data_flush(source_id);
+                                discarded_data_frame_cleanup(session_data, source_id, stream);
+                            }
                         }
 
                         session_data->payload_discard[source_id] = true;
@@ -501,38 +510,42 @@ const StreamBuffer Http2StreamSplitter::implement_reassemble(Http2FlowData* sess
             session_data->frame_reassemble[source_id] = nullptr;
         }
 
-        if (session_data->frame_type[source_id] != FT_DATA ||
-            session_data->frame_data[source_id] != nullptr)
+        if (session_data->frame_type[source_id] == FT_DATA &&
+            session_data->frame_data[source_id] == nullptr)
+        {
+            Http2Stream* const stream =
+                session_data->find_stream(session_data->current_stream[source_id]);
+            if (stream)
+            {
+                stream->set_discard(source_id);
+                discarded_data_frame_cleanup(session_data, source_id, stream);
+            }
+        }
+        else
         {
             // Return 0-length non-null buffer to stream which signals detection required,
             // but don't create pkt_data buffer
             frame_buf.data = (const uint8_t*)"";
         }
-        else
-            discarded_data_frame_cleanup(session_data, source_id);
     }
 
     return frame_buf;
 }
 
-void Http2StreamSplitter::discarded_data_frame_cleanup(Http2FlowData* session_data, HttpCommon::SourceId source_id)
+void Http2StreamSplitter::discarded_data_frame_cleanup(Http2FlowData* session_data, HttpCommon::SourceId source_id, Http2Stream* stream)
 {
-    Http2Stream* const stream = session_data->find_current_stream(source_id);
-
-    if (!stream || stream->get_state(source_id) == STREAM_ERROR)
+    if (stream->get_state(source_id) == STREAM_ERROR ||
+        !stream->is_end_stream_on_data_flush(source_id))
         return;
 
-    if (stream->is_end_stream_on_data_flush(source_id))
+    if (session_data->concurrent_files > 0)
+        session_data->concurrent_files -= 1;
+    stream->set_state(source_id, STREAM_COMPLETE);
+    stream->check_and_cleanup_completed();
+    if (session_data->delete_stream)
     {
-        if (session_data->concurrent_files > 0)
-            session_data->concurrent_files -= 1;
-        stream->set_state(source_id, STREAM_COMPLETE);
-        stream->check_and_cleanup_completed();
-        if (session_data->delete_stream)
-        {
-            session_data->processing_stream_id = session_data->get_current_stream_id(source_id);
-            session_data->delete_processing_stream();
-            session_data->processing_stream_id = NO_STREAM_ID;
-        }
+        session_data->processing_stream_id = session_data->get_current_stream_id(source_id);
+        session_data->delete_processing_stream();
+        session_data->processing_stream_id = NO_STREAM_ID;
     }
 }