]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2236 in SNORT/snort3 from ~KATHARVE/snort3:h2i_hi_memory to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 2 Jun 2020 14:31:05 +0000 (14:31 +0000)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 2 Jun 2020 14:31:05 +0000 (14:31 +0000)
Squashed commit of the following:

commit a3742b47d9b0437fde14014241e933e3bc1908af
Author: Katura Harvey <katharve@cisco.com>
Date:   Mon Jun 1 13:27:50 2020 -0400

    http2_inspect: track memory usage for http_inspect flows in http2_inspect

src/service_inspectors/http2_inspect/http2_flow_data.cc
src/service_inspectors/http2_inspect/http2_flow_data.h
src/service_inspectors/http2_inspect/http2_stream.cc
src/service_inspectors/http2_inspect/http2_stream.h
src/service_inspectors/http_inspect/http_flow_data.cc
src/service_inspectors/http_inspect/http_flow_data.h

index 9627846ebbbdbfe300b8807a708c77a2124d227c..0a559b58a603af2db2b47b76482509006c85c4b0 100644 (file)
@@ -158,3 +158,12 @@ uint32_t Http2FlowData::get_current_stream_id(const HttpCommon::SourceId source_
     return current_stream[source_id];
 }
 
+void Http2FlowData::allocate_hi_memory()
+{
+    update_allocations(HttpFlowData::get_memory_usage_estimate());
+}
+
+void Http2FlowData::deallocate_hi_memory()
+{
+    update_deallocations(HttpFlowData::get_memory_usage_estimate());
+}
index 46dd2b1fdb0d092a967331b9af4a72aceec253c8..974f2d050c15a573ecc2159a67fbe1b23626ffea 100644 (file)
@@ -165,6 +165,11 @@ private:
     class Http2Stream* get_stream(uint32_t key);
     class Http2Stream* get_hi_stream() const;
     class Http2Stream* find_stream(uint32_t key) const;
+
+    // When H2I allocates http_inspect flows, it bypasses the usual FlowData memory allocation
+    // bookkeeping. So H2I needs to update memory allocations and deallocations itself.
+    void allocate_hi_memory();
+    void deallocate_hi_memory();
 };
 
 #endif
index 3e6c453786f8f8e92fa06ad9de1b7d3679ffeed5..2ea72a070a863577a7368b2e11088d38a8749692 100644 (file)
@@ -40,6 +40,8 @@ Http2Stream::Http2Stream(uint32_t stream_id_, Http2FlowData* session_data_) :
 Http2Stream::~Http2Stream()
 {
     delete current_frame;
+    if (hi_flow_data)
+        session_data->deallocate_hi_memory();
     delete hi_flow_data;
     delete data_cutter[SRC_CLIENT];
     delete data_cutter[SRC_SERVER];
@@ -62,6 +64,13 @@ void Http2Stream::clear_frame()
     current_frame = nullptr;
 }
 
+void Http2Stream::set_hi_flow_data(HttpFlowData* flow_data)
+{
+    assert(hi_flow_data == nullptr);
+    hi_flow_data = flow_data;
+    session_data->allocate_hi_memory();
+}
+
 const Field& Http2Stream::get_buf(unsigned id)
 {
     if (current_frame != nullptr)
index bbbf7f0cca889e2057c6a6f1a73ffb2a9133b313..ca77104b4b876bd53990ad4271c8fceb2c2d398c 100644 (file)
@@ -42,8 +42,7 @@ public:
     void clear_frame();
     const Field& get_buf(unsigned id);
     HttpFlowData* get_hi_flow_data() const { return hi_flow_data; }
-    void set_hi_flow_data(HttpFlowData* flow_data)
-        { assert(hi_flow_data == nullptr); hi_flow_data = flow_data; }
+    void set_hi_flow_data(HttpFlowData* flow_data);
     HttpMsgSection* get_hi_msg_section() const { return hi_msg_section; }
     void set_hi_msg_section(HttpMsgSection* section) { hi_msg_section = section; }
     uint32_t get_xtradata_mask() { return (current_frame != nullptr) ?
index 04f4fb31d5a7665ab09bcce3de864e31d56458d1..23ed128a77a00da7ef71fde5729bd51e54698620 100644 (file)
 #include "http_common.h"
 #include "http_enum.h"
 #include "http_module.h"
+#include "http_msg_header.h"
+#include "http_msg_request.h"
+#include "http_msg_status.h"
 #include "http_test_manager.h"
 #include "http_transaction.h"
+#include "http_uri.h"
 
 using namespace snort;
 using namespace HttpCommon;
@@ -42,6 +46,10 @@ unsigned HttpFlowData::inspector_id = 0;
 uint64_t HttpFlowData::instance_count = 0;
 #endif
 
+const uint16_t HttpFlowData::memory_usage_estimate = sizeof(HttpFlowData) + sizeof(HttpTransaction)
+    + sizeof(HttpMsgRequest) + sizeof(HttpMsgStatus) + (2 * sizeof(HttpMsgHeader)) + sizeof(HttpUri)
+    + header_size_estimate + small_things;
+
 HttpFlowData::HttpFlowData() : FlowData(inspector_id)
 {
 #ifdef REG_TEST
@@ -235,6 +243,11 @@ HttpInfractions* HttpFlowData::get_infractions(SourceId source_id)
     return transaction[source_id]->get_infractions(source_id);
 }
 
+uint16_t HttpFlowData::get_memory_usage_estimate()
+{
+    return memory_usage_estimate;
+}
+
 #ifdef REG_TEST
 void HttpFlowData::show(FILE* out_file) const
 {
index d057ae2800fea8fdbcc0f7cc0ca2a9dfc5661a01..2a9be9d1ac423f198b129964ddb7e19d46ab4835 100644 (file)
@@ -77,6 +77,8 @@ public:
     void reset_partial_flush(HttpCommon::SourceId source_id)
     { partial_flush[source_id] = false; }
 
+    static uint16_t get_memory_usage_estimate();
+
 private:
     // HTTP/2 handling
     bool for_http2 = false;
@@ -182,6 +184,12 @@ private:
     // Transactions with uncleared sections awaiting deletion
     HttpTransaction* discard_list = nullptr;
 
+    // Estimates of how much memory http_inspect uses to process a stream for H2I
+    static const uint16_t header_size_estimate = 3000;  // combined raw size of request and
+                                                        //response message headers
+    static const uint16_t small_things = 400; // minor memory costs not otherwise accounted for
+    static const uint16_t memory_usage_estimate;
+
 #ifdef REG_TEST
     static uint64_t instance_count;
     uint64_t seq_num;