]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #4594: flow: change to vector with binary search for flow data and stash
authorRon Dempster (rdempste) <rdempste@cisco.com>
Wed, 28 May 2025 17:18:57 +0000 (17:18 +0000)
committerPriyanka Bangalore Gurudev (prbg) <prbg@cisco.com>
Wed, 28 May 2025 17:18:57 +0000 (17:18 +0000)
Merge in SNORT/snort3 from ~RDEMPSTE/snort3:flow to master

Squashed commit of the following:

commit 0c905b7a6905b54a449a87882ac1e3316bc81c3c
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Tue Dec 10 13:14:09 2024 -0500

    managers, profiler, stream: fix glibc debug and assertion issues

commit 1df7595917fb9f6094733b65c624c80833676422
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Wed Mar 19 13:31:37 2025 -0400

    codec, flow: make mpls layers in flow pointers to save memory

commit e65aafd4add8969db80b353bbd4868d52b65e085
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Wed Nov 27 11:51:19 2024 -0500

    flow: use vector and binary search for flow data and stash

87 files changed:
src/codecs/link/cd_mpls.cc
src/flow/CMakeLists.txt
src/flow/dev_notes.txt
src/flow/expect_cache.cc
src/flow/expect_flow.h
src/flow/flow.cc
src/flow/flow.h
src/flow/flow_data.cc
src/flow/flow_data.h
src/flow/flow_stash.cc
src/flow/flow_stash.h
src/flow/stash_item.h [deleted file]
src/flow/test/flow_cache_test.cc
src/flow/test/flow_control_test.cc
src/flow/test/flow_stash_test.cc
src/flow/test/flow_test.cc
src/flow/test/ha_test.cc
src/framework/base_api.h
src/main/test/distill_verdict_stubs.h
src/managers/event_manager.cc
src/managers/event_manager.h
src/mime/file_mime_log.cc
src/mime/file_mime_process.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.cc
src/network_inspectors/appid/appid_session_api.h
src/network_inspectors/appid/detector_plugins/test/detector_plugins_mock.h
src/network_inspectors/appid/detector_plugins/test/detector_sip_test.cc
src/network_inspectors/appid/detector_plugins/test/http_url_patterns_test.cc
src/network_inspectors/appid/service_plugins/test/service_plugin_mock.h
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_debug_test.cc
src/network_inspectors/appid/test/appid_detector_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_eve_process_event_handler_test.cc
src/network_inspectors/appid/test/appid_http_event_test.cc
src/network_inspectors/appid/test/appid_http_session_test.cc
src/network_inspectors/appid/test/appid_mock_flow.h
src/network_inspectors/appid/test/service_state_test.cc
src/network_inspectors/appid/tp_appid_utils.cc
src/network_inspectors/extractor/extractors.h
src/network_inspectors/packet_capture/packet_capture.cc
src/network_inspectors/perf_monitor/flow_ip_tracker.cc
src/network_inspectors/reputation/reputation_inspect.cc
src/network_inspectors/rna/rna_app_discovery.cc
src/network_inspectors/rna/rna_logger.cc
src/network_inspectors/rna/rna_logger.h
src/network_inspectors/rna/rna_logger_event.h
src/network_inspectors/rna/rna_pnd.cc
src/network_inspectors/rna/rna_pnd.h
src/packet_io/test/active_packet_trace_stubs.h
src/parser/parse_so_rule.cc
src/payload_injector/test/payload_injector_test.cc
src/profiler/memory_profiler.cc
src/profiler/rule_profiler.cc
src/profiler/time_profiler.cc
src/pub_sub/stash_events.h [deleted file]
src/pub_sub/test/pub_sub_http_transaction_end_event_test.cc
src/service_inspectors/cip/cip.cc
src/service_inspectors/cip/cip.h
src/service_inspectors/dns/dns_rr_decoder.cc
src/service_inspectors/gtp/gtp_inspect.cc
src/service_inspectors/gtp/gtp_inspect.h
src/service_inspectors/http_inspect/http_msg_body.cc
src/service_inspectors/http_inspect/http_msg_header.cc
src/service_inspectors/http_inspect/http_msg_request.cc
src/service_inspectors/http_inspect/http_stream_splitter_finish.cc
src/service_inspectors/http_inspect/test/http_transaction_test.cc
src/service_inspectors/imap/imap.cc
src/service_inspectors/imap/imap.h
src/service_inspectors/pop/pop.cc
src/service_inspectors/pop/pop.h
src/service_inspectors/sip/sip.cc
src/service_inspectors/sip/sip.h
src/service_inspectors/smtp/smtp.cc
src/stream/tcp/held_packet_queue.cc
src/stream/tcp/held_packet_queue.h
src/stream/tcp/tcp_overlap_resolver.cc
src/stream/tcp/tcp_session.cc
src/stream/tcp/tcp_state_established.cc
src/stream/tcp/tcp_state_mid_stream_recv.cc
src/stream/tcp/tcp_state_syn_sent.cc
src/stream/tcp/tcp_stream_tracker.cc
src/stream/tcp/tcp_stream_tracker.h
src/stream/test/stream_splitter_test.cc
src/trace/trace_api.cc

index 2585716d7a9303dc9bd5257c7e5d86bdd6d0e837..5ad6a56b850e28a13051f478287cf3124767f549 100644 (file)
@@ -250,12 +250,13 @@ bool MplsCodec::encode(const uint8_t* const raw_in, const uint16_t raw_len,
     const uint8_t* hdr_start = raw_in;
     if (pflow)
     {
-        Layer mpls_lyr = pflow->get_mpls_layer_per_dir(enc.forward());
+        Layer* mpls_lyr = pflow->get_mpls_layer_per_dir(enc.forward());
 
-        if (mpls_lyr.length)
+        if (mpls_lyr && mpls_lyr->length)
         {
-            hdr_len = mpls_lyr.length;
-            hdr_start = mpls_lyr.start;
+            hdr_len = mpls_lyr->length;
+            hdr_start = mpls_lyr->start;
+            assert(hdr_start);
         }
 
     }
index a1de6ff1c53a6033f44e1f45424f1d21ded89d8d..5ea36dac145f925874621287687edfac582b17db 100644 (file)
@@ -7,7 +7,6 @@ set (FLOW_INCLUDES
     flow_stash.h
     ha.h
     session.h
-    stash_item.h
     stream_flow.h
 )
 
@@ -31,7 +30,6 @@ add_library (flow OBJECT
     ha_module.cc
     ha_module.h
     prune_stats.h
-    stash_item.h
     filter_flow_critera.h
 )
 
index 9c8725719facb513fecd15919846d801cd7e06d6..ad431372d542c87c15bb80c64804e4df84853a10 100644 (file)
@@ -61,7 +61,7 @@ The HA subsystem implements these classes:
     information.
   - FlowHAClient - All HA coordination is managed via a set of FlowHAClient's.
     Every function that desires to use HA capabilities defines one FlowHAClient
-    object within the packet processing thread.  Each client is provided a 
+    object within the packet processing thread.  Each client is provided a
     handle bit-mask as part of the pending logic.  The client may set the
     pending bit to indicate the desire to add content to the HA message.
     A maximum of 17 clients may existing (numbers 1-16, corresponding to the
@@ -71,36 +71,46 @@ The HA subsystem implements these classes:
 
 
 09/25/2023
-In response to the need for more nuanced management of different protocol 
-types within the `flow_cache`, we've leveraged the newly added feature in 
-xhash. This enhancement includes the introduction of Protocol-Based 
-Least Recently Used (LRU) caches, which substantially improves the handling 
+In response to the need for more nuanced management of different protocol
+types within the `flow_cache`, we've leveraged the newly added feature in
+xhash. This enhancement includes the introduction of Protocol-Based
+Least Recently Used (LRU) caches, which substantially improves the handling
 of multiple protocol types in the cache.
-With this implementation, during various pruning sessions (idle, 
-excess, and timeout etc), we've adopted a round-robin method to cycle through 
-the LRU lists designated for each protocol type. This methodology ensures 
-that every protocol, irrespective of its inherent timeout characteristics, 
+With this implementation, during various pruning sessions (idle,
+excess, and timeout etc), we've adopted a round-robin method to cycle through
+the LRU lists designated for each protocol type. This methodology ensures
+that every protocol, irrespective of its inherent timeout characteristics,
 is given an equal opportunity for pruning and retirement from the cache.
-This adjustment to `flow_cache` not only addresses the previously observed 
-bias during pruning sessions, especially concerning UDP flows, 
-but lays down a framework for more advanced and controlled data management 
+This adjustment to `flow_cache` not only addresses the previously observed
+bias during pruning sessions, especially concerning UDP flows,
+but lays down a framework for more advanced and controlled data management
 within the cache moving forward.
 
 10/25/2024
 Allowlist LRU
-To address the need for preserving flows that have been allowlisted and are 
-at risk of timing out, we've introduced a configurable Allowlist LRU cache 
-within the flow_cache. This enhancement enables the retention of flows marked 
-with a whitelist verdict, preventing them from being prematurely pruned due 
-to inactivity timeouts. This is particularly beneficial in scenarios where 
-Snort ceases to observe traffic for a flow after the whitelist decision, 
-especially if that flow is long-lived. Without this adjustment, 
-such flows may be pruned by the cache upon timeout, potentially impacting 
-event logging at the flow’s end-of-life (EOF) due to missing 
+To address the need for preserving flows that have been allowlisted and are
+at risk of timing out, we've introduced a configurable Allowlist LRU cache
+within the flow_cache. This enhancement enables the retention of flows marked
+with a whitelist verdict, preventing them from being prematurely pruned due
+to inactivity timeouts. This is particularly beneficial in scenarios where
+Snort ceases to observe traffic for a flow after the whitelist decision,
+especially if that flow is long-lived. Without this adjustment,
+such flows may be pruned by the cache upon timeout, potentially impacting
+event logging at the flow’s end-of-life (EOF) due to missing
 pruned flow information.
 
 The Allowlist LRU cache is disabled by default but can be enabled by adding
-allowlist_cache = { enable = true } in the stream configuration. 
-Like the protocol-based LRUs, this allowlist functionality is an 
-additional LRU rather than a new hash_table, thereby maintaining 
-consistent performance with previous configurations.
\ No newline at end of file
+allowlist_cache = { enable = true } in the stream configuration.
+Like the protocol-based LRUs, this allowlist functionality is an
+additional LRU rather than a new hash_table, thereby maintaining
+consistent performance with previous configurations.
+
+04/07/2025
+Changed the flow data hash to start with 7 hash buckets. This is trying to balance
+between memory usage and speed.
+The flow data hash load factor controls the when a hash table rebalance happens. We
+don't ever want a hash rebalance to happen for flow data as that would mean allocating
+a new bigger bucket array and rehashing all of the elements in the hash. So, a max
+load factor of 5.0 was chosen. This means that the average depth for all buckets in
+the hash would need to be 5 or more before a rebalance would happen. This is very
+unlikely to happen.
index ae31ae959e8f0be724587856482e21ceaed79497..2aebcee60ecb3fa78d858f540b9d3360bd60d4fe 100644 (file)
@@ -24,6 +24,8 @@
 #include "expect_cache.h"
 #include "expect_flow.h"
 
+#include <algorithm>
+
 #include "detection/ips_context.h"
 #include "hash/zhash.h"
 #include "packet_io/packet_tracer.h"
@@ -47,33 +49,38 @@ using namespace snort;
 static THREAD_LOCAL std::vector<ExpectFlow*>* packet_expect_flows = nullptr;
 
 ExpectFlow::~ExpectFlow()
-{
-    clear();
-}
+{ clear(); }
 
 void ExpectFlow::clear()
 {
-    while (data)
-    {
-        FlowData* fd = data;
-        data = data->next;
-        delete fd;
-    }
-    data = nullptr;
+    std::for_each(std::begin(data), std::end(data),
+        [](FlowData* f)
+        { delete f; }
+        );
+    data.clear();
 }
 
-int ExpectFlow::add_flow_data(FlowData* fd)
+void ExpectFlow::add_flow_data(FlowData* fd)
 {
-    if (data)
+    unsigned id = fd->get_id();
+    if (data.size() == data.capacity())
+        data.reserve(data.size() + FlowDataStore::FLOW_DATA_INCREMENTS);
+    auto lower = std::lower_bound(data.begin(), data.end(), id,
+        [](const FlowData* the_fd, unsigned id)
+        { return the_fd->get_id() < id; });
+    if (lower == data.end())
+        data.emplace_back(fd);
+    else
     {
-        FlowData* prev_fd;
-        for (prev_fd = data; prev_fd && prev_fd->next; prev_fd = prev_fd->next);
-
-        prev_fd->next = fd;
+        FlowData* lower_fd = *lower;
+        if (lower_fd->get_id() == id)
+        {
+            delete lower_fd;
+            *lower = fd;
+        }
+        else
+            data.emplace(lower, fd);
     }
-    else
-        data = fd;
-    return 0;
 }
 
 std::vector<ExpectFlow*>* ExpectFlow::get_expect_flows()
@@ -98,12 +105,13 @@ void ExpectFlow::handle_expected_flows(const Packet* p)
 
 FlowData* ExpectFlow::get_flow_data(unsigned id)
 {
-    for (FlowData* p = data; p; p = p->next)
-    {
-        if (p->get_id() == id)
-            return p;
-    }
-    return nullptr;
+    auto lower = std::lower_bound(data.begin(), data.end(), id,
+        [](const FlowData* the_fd, unsigned id)
+        { return the_fd->get_id() < id; });
+    if (lower == data.end())
+        return nullptr;
+    FlowData* fd = *lower;
+    return (fd->get_id() == id) ? fd : nullptr;
 }
 
 struct ExpectNode
@@ -229,30 +237,29 @@ ExpectNode* ExpectCache::find_node_by_packet(Packet* p, FlowKey &key)
 
 bool ExpectCache::process_expected(ExpectNode* node, FlowKey& key, Packet* p, Flow* lws)
 {
-    ExpectFlow* head;
-    FlowData* fd;
-    bool ignoring = false;
-
     assert(node->count && node->head);
 
     /* Pull the first set of expected flow data off of the Expect node and apply it
         in its entirety to the target flow.  Discard the set (and potentially the
         entire node, it empty) after this is done. */
     node->count--;
-    head = node->head;
+    ExpectFlow* head = node->head;
     node->head = head->next;
 
-    while ((fd = head->data))
-    {
-        head->data = fd->next;
-        lws->set_flow_data(fd);
-        ++realized;
-        fd->handle_expected(p);
-    }
+    std::for_each(std::begin(head->data), std::end(head->data),
+        [this, p, lws](FlowData* fd)
+        {
+            lws->set_flow_data(fd);
+            ++realized;
+            fd->handle_expected(p);
+        }
+        );
+    head->data.clear();
     head->next = free_list;
     free_list = head;
 
     /* If this is 0, we're ignoring, otherwise setting id of new session */
+    bool ignoring = false;
     if (!node->snort_protocol_id)
         ignoring = node->direction != 0;
     else
@@ -289,7 +296,6 @@ ExpectCache::ExpectCache(uint32_t max)
     for (unsigned i = 0; i < max; ++i)
     {
         ExpectFlow* p = pool + i;
-        p->data = nullptr;
         p->next = free_list;
         free_list = p;
     }
@@ -341,7 +347,7 @@ int ExpectCache::add_flow(const Packet *ctrlPkt, PktType type, IpProtocol ip_pro
     int16_t expected_ingress_group = ctrlPkt->pkth->egress_group;
     int16_t expected_egress_group = ctrlPkt->pkth->ingress_group;
     bool reversed_key = key.init(ctrlPkt->context->conf, type, ip_proto, cliIP, cliPort,
-        srvIP, srvPort, vlanId, mplsId, ctrlPkt->pkth->address_space_id, 
+        srvIP, srvPort, vlanId, mplsId, ctrlPkt->pkth->address_space_id,
 #ifndef DISABLE_TENANT_ID
         ctrlPkt->pkth->tenant_id,
 #endif
@@ -378,16 +384,8 @@ int ExpectCache::add_flow(const Packet *ctrlPkt, PktType type, IpProtocol ip_pro
         last = node->tail;
         if ( last )
         {
-            FlowData* lfd = last->data;
-            while ( lfd )
-            {
-                if ( lfd->get_id() == fd->get_id() )
-                {
-                    last = nullptr;
-                    break;
-                }
-                lfd = lfd->next;
-            }
+            if ( last->get_flow_data(fd->get_id()) )
+                last = nullptr;
         }
     }
     else
index 2fafe1a019528c88c2698045aa79b5e7cfaa07cb..26a458d49daf8c2df1bbb0fb9c13de4c4eafd64d 100644 (file)
 //    a la FlowCache)
 //-------------------------------------------------------------------------
 
+#include <memory>
+#include <unordered_map>
 #include <vector>
 
+#include "flow/flow_data.h"
 #include "main/snort_types.h"
 
 struct ExpectNode;
 
 namespace snort
 {
-class FlowData;
 struct Packet;
 
 struct SO_PUBLIC ExpectFlow
 {
-    struct ExpectFlow* next;
-    snort::FlowData* data;
+    ExpectFlow* next = nullptr;
+    // This cannot use a unique_ptr because we need to move to a real flow during realization
+    std::vector<FlowData*> data;
 
+    ExpectFlow() = default;
     ~ExpectFlow();
     void clear();
-    int add_flow_data(snort::FlowData*);
-    snort::FlowData* get_flow_data(unsigned);
+    void add_flow_data(FlowData*);
+    FlowData* get_flow_data(unsigned);
     static std::vector<ExpectFlow*>* get_expect_flows();
     static void reset_expect_flows();
-    static void handle_expected_flows(const snort::Packet*);
+    static void handle_expected_flows(const Packet*);
 };
 }
 
index 06f17b2cbe1355d447687c19593616c7406c3e86..9221ea2ef0be2a17438554212f7f27927d353804 100644 (file)
@@ -54,10 +54,8 @@ Flow::~Flow()
     free_flow_data();
     delete session;
 
-    if ( mpls_client.length )
-        delete[] mpls_client.start;
-    if ( mpls_server.length )
-        delete[] mpls_server.start;
+    delete_mpls_layer(mpls_client);
+    delete_mpls_layer(mpls_server);
     delete bitop;
 
     if ( ssn_client )
@@ -79,7 +77,6 @@ Flow::~Flow()
         clear_data();
 
     delete ha_state;
-    delete stash;
     delete ips_cont;
 }
 
@@ -93,24 +90,16 @@ void Flow::init(PktType type)
         ha_state = new FlowHAState;
         previous_ssn_state = ssn_state;
     }
-    mpls_client.length = 0;
-    mpls_server.length = 0;
-
-    stash = new FlowStash;
+    assert(!mpls_client);
+    assert(!mpls_server);
 }
 
 inline void Flow::clean()
 {
-    if ( mpls_client.length )
-    {
-        delete[] mpls_client.start;
-        mpls_client.length = 0;
-    }
-    if ( mpls_server.length )
-    {
-        delete[] mpls_server.start;
-        mpls_server.length = 0;
-    }
+    delete_mpls_layer(mpls_client);
+    mpls_client = nullptr;
+    delete_mpls_layer(mpls_server);
+    mpls_server = nullptr;
     delete bitop;
     bitop = nullptr;
     filtering_state.clear();
@@ -229,45 +218,11 @@ uint64_t Flow::fetch_add_inspection_duration()
     return get_inspection_duration();
 }
 
-int Flow::set_flow_data(FlowData* fd)
-{
-    if ( !fd ) return -1;
-
-    current_flow_data = fd;
-    uint32_t id = fd->get_id();
-    // operator[] will create a new entry if it does not exist
-    // or replace the existing one if it does
-    // when replacing, the old entry is deleted
-    flow_data[id] = std::unique_ptr<FlowData>(fd);
-    return 0;
-}
-
-
-FlowData* Flow::get_flow_data(unsigned id) const
-{
-    auto it = flow_data.find(id);
-    if ( it != flow_data.end() )
-        return it->second.get();
-    return nullptr;
-}
-
-void Flow::free_flow_data(FlowData* fd)
-{
-    if ( fd )
-        flow_data.erase(fd->get_id());
-}
-
-void Flow::free_flow_data(uint32_t proto)
-{
-    flow_data.erase(proto);
-}
-
 void Flow::free_flow_data()
 {
     if ( flow_data.empty() )
     {
-        if (stash)
-            stash->reset();
+        stash.reset();
         return;
     }
     const SnortConfig* sc = SnortConfig::get_conf();
@@ -302,8 +257,7 @@ void Flow::free_flow_data()
     }
 
     flow_data.clear();
-    if (stash)
-        stash->reset();
+    stash.reset();
 
     if (ps)
     {
@@ -313,18 +267,6 @@ void Flow::free_flow_data()
     }
 }
 
-void Flow::call_handlers(Packet* p, bool eof)
-{
-    for (auto& fd_pair : flow_data)
-    {
-        FlowData* fd = fd_pair.second.get();
-        if ( eof )
-            fd->handle_eof(p);
-        else
-            fd->handle_retransmit(p);
-    }
-}
-
 void Flow::markup_packet_flags(Packet* p)
 {
     if ( (ssn_state.session_flags & SSNFLAG_ESTABLISHED) != SSNFLAG_ESTABLISHED )
@@ -479,29 +421,18 @@ void Flow::set_mpls_layer_per_dir(Packet* p)
     if ( !mpls_lyr || !(mpls_lyr->start) )
         return;
 
-    if ( p->packet_flags & PKT_FROM_CLIENT )
+    Layer*& mpls_layer = ( p->packet_flags & PKT_FROM_CLIENT ) ? mpls_client : mpls_server;
+    if ( !mpls_layer )
     {
-        if ( !mpls_client.length )
-        {
-            mpls_client.length = mpls_lyr->length;
-            mpls_client.prot_id = mpls_lyr->prot_id;
-            mpls_client.start = new uint8_t[mpls_lyr->length];
-            memcpy((void *)mpls_client.start, mpls_lyr->start, mpls_lyr->length);
-        }
-    }
-    else
-    {
-        if ( !mpls_server.length )
-        {
-            mpls_server.length = mpls_lyr->length;
-            mpls_server.prot_id = mpls_lyr->prot_id;
-            mpls_server.start = new uint8_t[mpls_lyr->length];
-            memcpy((void *)mpls_server.start, mpls_lyr->start, mpls_lyr->length);
-        }
+        mpls_layer = new Layer;
+        mpls_layer->length = mpls_lyr->length;
+        mpls_layer->prot_id = mpls_lyr->prot_id;
+        mpls_layer->start = new uint8_t[mpls_lyr->length];
+        memcpy((void *)mpls_layer->start, mpls_lyr->start, mpls_lyr->length);
     }
 }
 
-Layer Flow::get_mpls_layer_per_dir(bool client)
+Layer* Flow::get_mpls_layer_per_dir(bool client)
 {
     if ( client )
         return mpls_client;
index c65d569c990cbb0f87ff8caa29a11448791eb14a..87d3d1e17f49a8bfa68de3156cd5505d369cd804 100644 (file)
 // state.  Inspector state is stored in FlowData, and Flow manages a list
 // of FlowData items.
 
+#include <atomic>
 #include <bitset>
+#include <list>
+#include <memory>
 #include <string>
 #include <sys/time.h>
+#include <unordered_map>
 
 #include <daq_common.h>
 
@@ -184,13 +188,27 @@ public:
     void restart(bool dump_flow_data = true);
     void clear(bool dump_flow_data = true);
 
-    int set_flow_data(FlowData*);
-    FlowData* get_flow_data(uint32_t proto) const;
-    void free_flow_data(uint32_t proto);
-    void free_flow_data(FlowData*);
+    void set_flow_data(FlowData* fd)
+    {
+        assert(fd);
+        flow_data.set(fd);
+    }
+    FlowData* get_flow_data(unsigned id) const
+    { return flow_data.get(id); }
+    void free_flow_data(unsigned id)
+    { flow_data.erase(id); }
+    void free_flow_data(FlowData* fd)
+    {
+        if ( fd )
+            flow_data.erase(fd->get_id());
+    }
     void free_flow_data();
+    void call_handlers(Packet* p,
+        FlowDataStore::FlowDataHandlerType handler_type = FlowDataStore::HANDLER_RETRANSMIT) const
+    {
+        flow_data.call_handlers(p, handler_type);
+    }
 
-    void call_handlers(Packet* p, bool eof = false);
     void markup_packet_flags(Packet*);
     void set_client_initiate(Packet*);
     void set_direction(Packet*);
@@ -198,34 +216,24 @@ public:
     bool expired(const Packet*) const;
     void set_ttl(Packet*, bool client);
     void set_mpls_layer_per_dir(Packet*);
-    Layer get_mpls_layer_per_dir(bool);
+    Layer* get_mpls_layer_per_dir(bool);
     void swap_roles();
     void set_service(Packet*, const char* new_service);
-    bool get_attr(const std::string& key, int32_t& val) const;
-    bool get_attr(const std::string& key, std::string& val) const;
-    void set_attr(const std::string& key, const int32_t& val);
-    void set_attr(const std::string& key, const std::string& val);
-    // Use this API when the publisher of the attribute allocated memory for it and can give up its
-    // ownership after the call.
-    void set_attr(const std::string& key, std::string* val)
-    {
-        assert(stash);
-        stash->store(key, val);
-    }
 
     template<typename T>
     bool get_attr(const std::string& key, T& val) const
-    {
-        assert(stash);
-        return stash->get(key, val);
-    }
-
+    { return stash.get(key, val); }
     template<typename T>
-    void set_attr(const std::string& key, const T& val)
-    {
-        assert(stash);
-        stash->store(key, val);
-    }
+    void set_attr(const std::string& key, T& val)
+    { stash.store(key, val); }
+    void set_attr(const std::string& key, const std::string& val)
+    { stash.store(key, val); }
+    void set_attr(const std::string& key, StashGenericObject* val)
+    { stash.store(key, val); }
+    bool set_attr(const snort::SfIp& ip, const SnortConfig* sc = nullptr)
+    { return stash.store(ip, sc); }
+    const std::list<SfIp>* get_aux_ip_list() const
+    { return stash.get_aux_ip_list(); }
 
     uint32_t update_session_flags(uint32_t ssn_flags)
     { return ssn_state.session_flags = ssn_flags; }
@@ -280,7 +288,7 @@ public:
     { return (flow_state <= FlowState::INSPECT) and !is_inspection_disabled(); }
 
     void set_state(FlowState fs)
-    { 
+    {
         flow_state = fs;
         if (fs > FlowState::INSPECT)
         {
@@ -308,6 +316,8 @@ public:
 
     void set_clouseau(Inspector* ins)
     {
+        if (clouseau)
+            clouseau->rem_ref();
         clouseau = ins;
         clouseau->add_ref();
     }
@@ -325,6 +335,8 @@ public:
 
     void set_gadget(Inspector* ins)
     {
+        if (gadget)
+            gadget->rem_ref();
         gadget = ins;
         gadget->add_ref();
     }
@@ -339,6 +351,8 @@ public:
 
     void set_assistant_gadget(Inspector* ins)
     {
+        if (assistant_gadget)
+            assistant_gadget->rem_ref();
         assistant_gadget = ins;
         assistant_gadget->add_ref();
     }
@@ -351,6 +365,8 @@ public:
 
     void set_data(Inspector* pd)
     {
+        if (data)
+            data->rem_ref();
         data = pd;
         data->add_ref();
     }
@@ -431,21 +447,27 @@ public:
 
     bool handle_allowlist();
 
+protected:
+    static void delete_mpls_layer(Layer* mpls_layer)
+    {
+        if ( mpls_layer )
+        {
+            if ( mpls_layer->length )
+                delete[] mpls_layer->start;
+            delete mpls_layer;
+        }
+    }
+    DeferredTrust deferred_trust;
+    FlowStash stash;
+    FlowDataStore flow_data;
+
 public:  // FIXIT-M privatize if possible
     // fields are organized by initialization and size to minimize
     // void space
 
-    std::unordered_map<uint32_t, std::unique_ptr<FlowData>> flow_data;
-
-    DeferredTrust deferred_trust;
-
     const FlowKey* key = nullptr;
     BitOp* bitop = nullptr;
     FlowHAState* ha_state = nullptr;
-    FlowStash* stash = nullptr;
-
-    uint8_t ip_proto = 0;
-    PktType pkt_type = PktType::NONE; // ^^
 
     // these fields are always set; not zeroed
     Flow* prev = nullptr;
@@ -456,11 +478,10 @@ public:  // FIXIT-M privatize if possible
     Continuation* ips_cont = nullptr;
 
     long last_data_seen = 0;
-    Layer mpls_client = {};
-    Layer mpls_server = {};
+    Layer* mpls_client = nullptr;
+    Layer* mpls_server = nullptr;
 
     IpsContextChain context_chain;
-    FlowData* current_flow_data = nullptr;
     FlowStats flowstats = {};
     class StreamFlowIntf* stream_intf = nullptr;
 
@@ -478,6 +499,12 @@ public:  // FIXIT-M privatize if possible
 
     uint64_t expire_time = 0;
 
+    std::bitset<64> data_log_filtering_state;
+
+    FilteringState filtering_state;
+
+    DAQ_Verdict last_verdict = MAX_DAQ_VERDICT;
+
     unsigned network_policy_id = 0;
     struct timeval prev_packet_time = {0, 0};
     
@@ -486,25 +513,6 @@ public:  // FIXIT-M privatize if possible
     unsigned reload_id = 0;
     uint32_t default_session_timeout = 0;
     uint32_t idle_timeout = 0;
-    int32_t client_intf = 0;
-    int32_t server_intf = 0;
-
-    int16_t client_group = 0;
-    int16_t server_group = 0;
-
-    uint16_t client_port = 0;
-    uint16_t server_port = 0;
-
-    uint16_t ssn_policy = 0;
-    uint16_t session_state = 0;
-
-    uint8_t inner_client_ttl = 0;
-    uint8_t inner_server_ttl = 0;
-    uint8_t outer_client_ttl = 0;
-    uint8_t outer_server_ttl = 0;
-
-    uint8_t response_count = 0;
-    uint8_t dump_code = 0;
 
     struct
     {
@@ -532,13 +540,30 @@ public:  // FIXIT-M privatize if possible
         bool allowed_on_excess : 1; // Set if the flow is allowed on excess
     } flags = {};
 
-    FlowState flow_state = FlowState::SETUP;
+    int32_t client_intf = 0;
+    int32_t server_intf = 0;
 
-    FilteringState filtering_state;
+    int16_t client_group = 0;
+    int16_t server_group = 0;
 
-    DAQ_Verdict last_verdict = MAX_DAQ_VERDICT;
+    uint16_t client_port = 0;
+    uint16_t server_port = 0;
 
-    std::bitset<64> data_log_filtering_state;
+    uint16_t ssn_policy = 0;
+    uint16_t session_state = 0;
+
+    uint8_t ip_proto = 0;
+    PktType pkt_type = PktType::NONE; // ^^
+
+    uint8_t inner_client_ttl = 0;
+    uint8_t inner_server_ttl = 0;
+    uint8_t outer_client_ttl = 0;
+    uint8_t outer_server_ttl = 0;
+
+    uint8_t response_count = 0;
+    uint8_t dump_code = 0;
+
+    FlowState flow_state = FlowState::SETUP;
 
 private:
     void clean();
index 0ef4090b4ec39b9533999294da471fd73fb62f82..123a0717a1bffb4b16d74812a5955ed4bcc2f693 100644 (file)
@@ -23,6 +23,7 @@
 
 #include "flow_data.h"
 
+#include <algorithm>
 #include <cassert>
 
 #include "framework/inspector.h"
@@ -33,12 +34,104 @@ using namespace snort;
 
 unsigned FlowData::flow_data_id = 0;
 
+FlowDataStore::~FlowDataStore()
+{ clear(); }
+
+void FlowDataStore::set(FlowData* fd)
+{
+    assert(fd);
+    unsigned id = fd->get_id();
+    if (flow_data.size() == flow_data.capacity())
+        flow_data.reserve(flow_data.size() + FLOW_DATA_INCREMENTS);
+    const auto lower = std::lower_bound(flow_data.begin(), flow_data.end(), id,
+        [](const FlowData* the_fd, unsigned id)
+        { return the_fd->get_id() < id; });
+    if (lower == flow_data.end())
+        flow_data.emplace_back(fd);
+    else
+    {
+        FlowData* lower_fd = *lower;
+        if (lower_fd->get_id() == id)
+        {
+            delete lower_fd;
+            *lower = fd;
+        }
+        else
+            flow_data.emplace(lower, fd);
+    }
+}
+
+void FlowDataStore::erase(unsigned id)
+{
+    const auto lower = std::lower_bound(flow_data.begin(), flow_data.end(), id,
+        [](const FlowData* the_fd, unsigned id)
+        { return the_fd->get_id() < id; });
+    if (lower != flow_data.end() && (*lower)->get_id() == id)
+    {
+        FlowData* lower_fd = *lower;
+        flow_data.erase(lower);
+        delete lower_fd;
+    }
+}
+
+void FlowDataStore::clear()
+{
+    // Cannot use unique_ptr because resize and pop_back leave the flow_data element in
+    // the vector. This can lead to crashes if the vector is used during the flow data destruction.
+    while (!flow_data.empty())
+    {
+        FlowData* fd = flow_data.back();
+        flow_data.pop_back();
+        delete fd;
+    }
+}
+
+FlowData* FlowDataStore::get(unsigned id) const
+{
+    const auto lower = std::lower_bound(flow_data.begin(), flow_data.end(), id,
+        [](const FlowData* the_fd, unsigned id)
+        { return the_fd->get_id() < id; });
+    if (lower == flow_data.end())
+        return nullptr;
+    FlowData* lower_fd = *lower;
+    return (lower_fd->get_id() == id) ? lower_fd : nullptr;
+}
+
+bool FlowDataStore::empty() const
+{ return flow_data.empty(); }
+
+void FlowDataStore::call_handlers(Packet* p, FlowDataHandlerType handler_type) const
+{
+    // handle_eof modifies flow_data, so we must make a temporary vector to be walked
+    std::vector<FlowData*> fd_ptrs;
+    fd_ptrs.reserve(flow_data.size());
+    for (FlowData* fd : flow_data)
+    {
+        assert(fd);
+        fd_ptrs.push_back(fd);
+    }
+
+    for (FlowData* fd : fd_ptrs)
+    {
+        switch (handler_type)
+        {
+            case HANDLER_RETRANSMIT:
+                fd->handle_retransmit(p);
+                break;
+            case HANDLER_EOF:
+                fd->handle_eof(p);
+                break;
+            default:
+                assert(!"Invalid handler type");
+        }
+    }
+}
+
 FlowData::FlowData(unsigned u, Inspector* ph)
 {
     assert(u > 0);
     id = u;
     handler = ph;
-    prev = next = nullptr;
     if ( handler )
         handler->add_ref();
 }
@@ -49,7 +142,18 @@ FlowData::~FlowData()
         handler->rem_ref();
 }
 
+void FlowData::set_handler(Inspector* h)
+{
+    if (handler != h)
+    {
+        if (handler)
+            handler->rem_ref();
+        handler = h;
+        if (handler)
+            handler->add_ref();
+    }
+}
+
 RuleFlowData::RuleFlowData(unsigned u) :
     FlowData(u, SnortConfig::get_conf()->so_rules->proxy)
 { }
-
index 11aed4b4e6f99cd9dbe57384009b8316075ac82d..d43d320fdb1c17a70c80343e924c716df7dc45a6 100644 (file)
@@ -20,6 +20,8 @@
 #ifndef FLOW_DATA_H
 #define FLOW_DATA_H
 
+#include <vector>
+
 // FlowData is how inspectors maintain flow state
 // use Flow::set/get_flow_data() to attach to a flow
 
@@ -35,25 +37,27 @@ class SO_PUBLIC FlowData
 public:
     virtual ~FlowData();
 
-    unsigned get_id()
+    unsigned get_id() const
     { return id; }
 
     static unsigned create_flow_data_id()
     { return ++flow_data_id; }
 
-    Inspector* get_handler() { return handler; }
+    Inspector* get_handler() const
+    { return handler; }
+
+    void set_handler(Inspector*);
 
-    virtual void handle_expected(Packet*) { }
-    virtual void handle_retransmit(Packet*) { }
-    virtual void handle_eof(Packet*) { }
+    virtual void handle_expected(Packet*)
+    { }
+    virtual void handle_retransmit(Packet*)
+    { }
+    virtual void handle_eof(Packet*)
+    { }
 
 protected:
     FlowData(unsigned u, Inspector* = nullptr);
 
-public:  // FIXIT-L privatize
-    FlowData* next;
-    FlowData* prev;
-
 private:
     static unsigned flow_data_id;
     Inspector* handler;
@@ -70,5 +74,34 @@ public:
     ~RuleFlowData() override = default;
 };
 
+class SO_PUBLIC FlowDataStore
+{
+public:
+    FlowDataStore() = default;
+    ~FlowDataStore();
+
+    void set(FlowData*);
+    FlowData* get(unsigned) const;
+
+    void erase(unsigned);
+    void erase(FlowData*);
+    void clear();
+
+    bool empty() const;
+
+    enum FlowDataHandlerType
+    {
+        HANDLER_RETRANSMIT,
+        HANDLER_EOF,
+    };
+
+    void call_handlers(Packet*, FlowDataHandlerType) const;
+
+    static constexpr unsigned FLOW_DATA_INCREMENTS = 7;
+
+private:
+    std::vector<FlowData*> flow_data;
+};
+
 }
 #endif
index e93531a14637eba24eaeac7914c50d597e0edbed..c0b2247564cd201cd2b287c90c6415866e66d0f2 100644 (file)
 
 #include <cassert>
 
+#include "framework/data_bus.h"
 #include "main/snort_config.h"
 #include "pub_sub/auxiliary_ip_event.h"
-#include "pub_sub/stash_events.h"
 
 using namespace snort;
 using namespace std;
 
-FlowStash::~FlowStash()
-{
-    reset();
-}
-
-void FlowStash::reset()
-{
-    for(auto it = container.begin(); it != container.end(); ++it)
-    {
-        delete it->second;
-    }
-    container.clear();
-}
-
-bool FlowStash::get(const string& key, int32_t& val)
+bool FlowStash::get(const string& key, int32_t& val) const
 {
     return get(key, val, STASH_ITEM_TYPE_INT32);
 }
 
-bool FlowStash::get(const string& key, uint32_t& val)
+bool FlowStash::get(const string& key, uint32_t& val) const
 {
     return get(key, val, STASH_ITEM_TYPE_UINT32);
 }
 
-bool FlowStash::get(const string& key, string& val)
+bool FlowStash::get(const string& key, string& val) const
 {
     return get(key, val, STASH_ITEM_TYPE_STRING);
 }
 
-bool FlowStash::get(const string& key, StashGenericObject* &val)
+bool FlowStash::get(const string& key, StashGenericObject* &val) const
 {
     return get(key, val, STASH_ITEM_TYPE_GENERIC_OBJECT);
 }
 
-void FlowStash::store(const string& key, int32_t val, unsigned pubid, unsigned evid)
+void FlowStash::store(const string& key, int32_t val)
 {
-    store(key, val, STASH_ITEM_TYPE_INT32, pubid, evid);
+    internal_store(key, val);
 }
 
-void FlowStash::store(const string& key, uint32_t val, unsigned pubid, unsigned evid)
+void FlowStash::store(const string& key, uint32_t val)
 {
-    store(key, val, STASH_ITEM_TYPE_UINT32, pubid, evid);
+    internal_store(key, val);
 }
 
-void FlowStash::store(const string& key, const string& val, unsigned pubid, unsigned evid)
+void FlowStash::store(const string& key, const string& val)
 {
-    store(key, val, STASH_ITEM_TYPE_STRING, pubid, evid);
+    internal_store(key, val);
 }
 
-void FlowStash::store(const string& key, string* val, unsigned pubid, unsigned evid)
+void FlowStash::store(const string& key, string* val)
 {
-    store(key, val, STASH_ITEM_TYPE_STRING, pubid, evid);
+    internal_store(key, val);
 }
 
-void FlowStash::store(const string& key, StashGenericObject* val, unsigned pubid, unsigned evid)
+void FlowStash::store(const string& key, StashGenericObject* val)
 {
-    store(key, val, STASH_ITEM_TYPE_GENERIC_OBJECT, pubid, evid);
+    internal_store(key, val);
 }
 
-void FlowStash::store(const string& key, StashGenericObject* &val, StashItemType type, unsigned pubid, unsigned evid)
+template<typename T>
+bool FlowStash::get(const string& key, T& val, StashItemType type) const
 {
-#ifdef NDEBUG
-    UNUSED(type);
-#endif
-    auto item = new StashItem(val);
-    auto it_and_status = container.emplace(key, item);
-
-    if (!it_and_status.second)
-    {
-        StashGenericObject* stored_object;
-        assert(it_and_status.first->second->get_type() == type);
-        it_and_status.first->second->get_val(stored_object);
-        assert(stored_object->get_object_type() == val->get_object_type());
-        delete it_and_status.first->second;
-        it_and_status.first->second = item;
-    }
-
-    if (DataBus::valid(pubid))
+    auto lower = lower_bound(container.begin(), container.end(), key,
+        [](const unique_ptr<StashItem>& item, const string& key)
+        { return 0 > item->get_key().compare(key); });
+    if (lower == container.end())
+        return false;
+    StashItem* item = lower->get();
+    if (item->get_key() == key)
     {
-        StashEvent e(item);
-        DataBus::publish(pubid, evid, e);
+        if (item->get_type() == type)
+        {
+            item->get_val(val);
+            return true;
+        }
+        assert(item->get_type() == type);
     }
+    return false;
 }
 
 template<typename T>
-bool FlowStash::get(const string& key, T& val, StashItemType type)
+void FlowStash::internal_store(const string& key, T& val)
 {
-#ifdef NDEBUG
-    UNUSED(type);
-#endif
-    auto it = container.find(key);
-
-    if (it != container.end())
+    if (container.size() == container.capacity())
+        container.reserve(container.size() + FLOW_STASH_INCREMENTS);
+    StashItem* new_item = new StashItem(key, val);
+    auto lower = lower_bound(container.begin(), container.end(), key,
+        [](const unique_ptr<StashItem>& item, const string& key)
+        { return 0 > item->get_key().compare(key); });
+    if (lower == container.end())
+        container.emplace_back(new_item);
+    else
     {
-        assert(it->second->get_type() == type);
-        it->second->get_val(val);
-        return true;
+        unique_ptr<StashItem>& lower_item = *lower;
+        if (lower_item->get_key() == key)
+            lower_item.reset(new_item);
+        else
+            container.emplace(lower, new_item);
     }
-    return false;
 }
 
-template<typename T>
-void FlowStash::store(const string& key, T& val, StashItemType type, unsigned pubid, unsigned evid)
-{
-#ifdef NDEBUG
-    UNUSED(type);
-#endif
-    auto item = new StashItem(val);
-    auto it_and_status = container.emplace(key, item);
+#define STASH_AUX_IP "aux_ip"
 
-    if (!it_and_status.second)
+class AuxIPStashItem : public StashGenericObject
+{
+public:
+    AuxIPStashItem() = default;
+    ~AuxIPStashItem() override = default;
+    bool update(const SfIp& ip, const SnortConfig* sc)
     {
-        assert(it_and_status.first->second->get_type() == type);
-        delete it_and_status.first->second;
-        it_and_status.first->second = item;
+        if ( any_of(aux_ip_fifo.cbegin(), aux_ip_fifo.cend(),
+            [ip](const snort::SfIp& aip)
+            { return aip == ip; }) )
+            return false;
+
+        while ( aux_ip_fifo.size() >= (unsigned)sc->max_aux_ip )
+            aux_ip_fifo.pop_back();
+
+        aux_ip_fifo.emplace_front(ip);
+        return true;
     }
 
-    StashEvent e(item);
-    DataBus::publish(pubid, evid, e);
-}
+    const list<snort::SfIp>& get_aux_ip_list() const
+    { return aux_ip_fifo; }
+
+protected:
+    list<snort::SfIp> aux_ip_fifo;
+};
 
 bool FlowStash::store(const SfIp& ip, const SnortConfig* sc)
 {
@@ -164,17 +158,30 @@ bool FlowStash::store(const SfIp& ip, const SnortConfig* sc)
 
     if ( sc->max_aux_ip > 0 )
     {
-        if ( std::any_of(aux_ip_fifo.cbegin(), aux_ip_fifo.cend(),
-            [ip](const snort::SfIp& aip){ return aip == ip; }) )
+        AuxIPStashItem* item;
+        StashGenericObject* stash_value;
+        if (!get(STASH_AUX_IP, stash_value))
+        {
+            item = new AuxIPStashItem;
+            store(STASH_AUX_IP, item);
+        }
+        else
+            item = static_cast<AuxIPStashItem*>(stash_value);
+
+        if (!item->update(ip, sc))
             return false;
-
-        if ( aux_ip_fifo.size() == (unsigned)sc->max_aux_ip )
-            aux_ip_fifo.pop_back();
-
-        aux_ip_fifo.emplace_front(ip);
     }
 
     AuxiliaryIpEvent event(ip);
     DataBus::publish(intrinsic_pub_id, IntrinsicEventIds::AUXILIARY_IP, event);
     return true;
 }
+
+const list<snort::SfIp>* FlowStash::get_aux_ip_list() const
+{
+    StashGenericObject* stash_value;
+    if (!get(STASH_AUX_IP, stash_value))
+        return nullptr;
+    AuxIPStashItem* item = static_cast<AuxIPStashItem*>(stash_value);
+    return &item->get_aux_ip_list();
+}
index e89d82a3bb8a7d6a43a8f9b0b0aba3a92441ce89..af926c233f19a91c09afff0689a3c438401ebb10 100644 (file)
 
 // a generic store for shared flow data
 
+#include <algorithm>
 #include <list>
-#include <map>
+#include <memory>
 #include <string>
-#include <unordered_map>
+#include <vector>
 
 #include "main/snort_types.h"
 #include "sfip/sf_ip.h"
 
-#include "stash_item.h"
-
 namespace snort
 {
+class StashItem;
+struct SnortConfig;
+
+class StashGenericObject
+{
+public:
+    StashGenericObject() = default;
+    virtual ~StashGenericObject() = default;
+};
+
+enum StashItemType
+{
+    STASH_ITEM_TYPE_INT32,
+    STASH_ITEM_TYPE_UINT32,
+    STASH_ITEM_TYPE_STRING,
+    STASH_ITEM_TYPE_GENERIC_OBJECT
+};
+
+union StashItemVal
+{
+    int32_t int32_val;
+    uint32_t uint32_val;
+    std::string* str_val;
+    StashGenericObject* generic_obj_val;
+};
+
+class StashItem
+{
+public:
+    StashItem(const std::string& the_key, int32_t int32_val) : key(the_key)
+    {
+        type = STASH_ITEM_TYPE_INT32;
+        val.int32_val = int32_val;
+    }
+
+    StashItem(const std::string& the_key, uint32_t uint32_val) : key(the_key)
+    {
+        type = STASH_ITEM_TYPE_UINT32;
+        val.uint32_val = uint32_val;
+    }
+
+    StashItem(const std::string& the_key, const std::string& str_val) : key(the_key)
+    {
+        type = STASH_ITEM_TYPE_STRING;
+        val.str_val = new std::string(str_val);
+    }
+
+    StashItem(const std::string& the_key, std::string* str_val) : key(the_key)
+    {
+        type = STASH_ITEM_TYPE_STRING;
+        val.str_val = str_val;
+    }
+
+    StashItem(const std::string& the_key, StashGenericObject* obj) : key(the_key)
+    {
+        type = STASH_ITEM_TYPE_GENERIC_OBJECT;
+        val.generic_obj_val = obj;
+    }
+
+    ~StashItem()
+    {
+        switch (type)
+        {
+        case STASH_ITEM_TYPE_STRING:
+            delete val.str_val;
+            break;
+        case STASH_ITEM_TYPE_GENERIC_OBJECT:
+            delete val.generic_obj_val;
+        default:
+            break;
+        }
+    }
+
+    const std::string& get_key() const
+    { return key; }
+
+    StashItemType get_type() const
+    { return type; }
+
+    void get_val(int32_t& int32_val) const
+    { int32_val = val.int32_val; }
+
+    void get_val(uint32_t& uint32_val) const
+    { uint32_val = val.uint32_val; }
+
+    void get_val(std::string& str_val) const
+    { str_val = *(val.str_val); }
+
+    void get_val(StashGenericObject* &obj_val) const
+    { obj_val = val.generic_obj_val; }
+
+private:
+    std::string key;
+    StashItemType type;
+    StashItemVal val;
+};
 
 class SO_PUBLIC FlowStash
 {
 public:
-    ~FlowStash();
-    void reset();
+    FlowStash() = default;
+    ~FlowStash()
+    { reset(); }
 
-    bool get(const std::string& key, int32_t& val);
-    bool get(const std::string& key, uint32_t& val);
-    bool get(const std::string& key, std::string& val);
-    bool get(const std::string& key, StashGenericObject* &val);
+    void reset()
+    { container.clear(); }
 
-    void store(const std::string& key, int32_t val, unsigned pubid = 0, unsigned evid = 0);
-    void store(const std::string& key, uint32_t val, unsigned pubid = 0, unsigned evid = 0);
-    void store(const std::string& key, const std::string& val, unsigned pubid = 0, unsigned evid = 0);
-    void store(const std::string& key, std::string* val, unsigned pubid = 0, unsigned evid = 0);
-    void store(const std::string& key, StashGenericObject* val, unsigned pubid = 0, unsigned evid = 0);
+    bool get(const std::string& key, int32_t& val) const;
+    bool get(const std::string& key, uint32_t& val) const;
+    bool get(const std::string& key, std::string& val) const;
+    bool get(const std::string& key, StashGenericObject* &val) const;
 
-    bool store(const snort::SfIp&, const struct SnortConfig* = nullptr);
+    void store(const std::string& key, int32_t val);
+    void store(const std::string& key, uint32_t val);
+    void store(const std::string& key, const std::string& val);
+    void store(const std::string& key, std::string* val);
+    void store(const std::string& key, StashGenericObject* val);
 
-    std::list<snort::SfIp>& get_aux_ip_list()
-    { return aux_ip_fifo; }
+    bool store(const snort::SfIp&, const SnortConfig*);
+
+    const std::list<snort::SfIp>* get_aux_ip_list() const;
 
 private:
-    std::list<snort::SfIp> aux_ip_fifo;
-    std::unordered_map<std::string, StashItem*> container;
+    static constexpr unsigned FLOW_STASH_INCREMENTS = 7;
+
+    std::vector<std::unique_ptr<StashItem>> container;
 
     template<typename T>
-    bool get(const std::string& key, T& val, StashItemType type);
+    bool get(const std::string& key, T& val, StashItemType type) const;
     template<typename T>
-    void store(const std::string& key, T& val, StashItemType type, unsigned = 0, unsigned = 0);
-    void store(const std::string& key, StashGenericObject* &val, StashItemType type, unsigned, unsigned);
+    void internal_store(const std::string& key, T& val);
 };
 
 }
diff --git a/src/flow/stash_item.h b/src/flow/stash_item.h
deleted file mode 100644 (file)
index 6efcd64..0000000
+++ /dev/null
@@ -1,137 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2019-2025 Cisco and/or its affiliates. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation.  You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//--------------------------------------------------------------------------
-
-// stash_item.h author Shravan Rangaraju <shrarang@cisco.com>
-
-#ifndef STASH_ITEM_H
-#define STASH_ITEM_H
-
-// stored in the FlowStash
-
-#include <cstdint>
-#include <string>
-
-#define STASH_APPID_DATA "appid_data"
-
-#define STASH_GENERIC_OBJECT_APPID 1
-#define STASH_GENERIC_OBJECT_MIME 2
-
-namespace snort
-{
-
-class StashGenericObject
-{
-public:
-    StashGenericObject(int type) : object_type(type)
-    { }
-
-    virtual ~StashGenericObject() = default;
-
-    int get_object_type() const
-    { return object_type; }
-
-private:
-    int object_type;
-};
-
-enum StashItemType
-{
-    STASH_ITEM_TYPE_INT32,
-    STASH_ITEM_TYPE_UINT32,
-    STASH_ITEM_TYPE_STRING,
-    STASH_ITEM_TYPE_GENERIC_OBJECT
-};
-
-union StashItemVal
-{
-    int32_t int32_val;
-    uint32_t uint32_val;
-    std::string* str_val;
-    StashGenericObject* generic_obj_val;
-};
-
-class StashItem
-{
-public:
-    StashItem(int32_t int32_val)
-    {
-        type = STASH_ITEM_TYPE_INT32;
-        val.int32_val = int32_val;
-    }
-
-    StashItem(uint32_t uint32_val)
-    {
-        type = STASH_ITEM_TYPE_UINT32;
-        val.uint32_val = uint32_val;
-    }
-
-    StashItem(const std::string& str_val)
-    {
-        type = STASH_ITEM_TYPE_STRING;
-        val.str_val = new std::string(str_val);
-    }
-
-    StashItem(std::string* str_val)
-    {
-        type = STASH_ITEM_TYPE_STRING;
-        val.str_val = str_val;
-    }
-
-    StashItem(StashGenericObject* obj)
-    {
-        type = STASH_ITEM_TYPE_GENERIC_OBJECT;
-        val.generic_obj_val = obj;
-    }
-
-    ~StashItem()
-    {
-        switch (type)
-        {
-        case STASH_ITEM_TYPE_STRING:
-            delete val.str_val;
-            break;
-        case STASH_ITEM_TYPE_GENERIC_OBJECT:
-            delete val.generic_obj_val;
-        default:
-            break;
-        }
-    }
-
-    StashItemType get_type() const
-    { return type; }
-
-    void get_val(int32_t& int32_val) const
-    { int32_val = val.int32_val; }
-
-    void get_val(uint32_t& uint32_val) const
-    { uint32_val = val.uint32_val; }
-
-    void get_val(std::string& str_val) const
-    { str_val = *(val.str_val); }
-
-    void get_val(StashGenericObject* &obj_val) const
-    { obj_val = val.generic_obj_val; }
-
-private:
-    StashItemType type;
-    StashItemVal val;
-};
-
-}
-
-#endif
index f4b3af56375ae38afeea28bdb1f4b4afae19127e..f6057b839f82e061f524de5940e94e9c9f7d9d22 100644 (file)
@@ -105,6 +105,7 @@ void Flow::free_flow_data() { }
 void Flow::set_client_initiate(Packet*) { }
 void Flow::set_direction(Packet*) { }
 void Flow::set_mpls_layer_per_dir(Packet*) { }
+FlowDataStore::~FlowDataStore() = default;
 void packet_gettimeofday(struct timeval* ) { }
 SO_PUBLIC void ts_print(const struct timeval*, char*, bool) { }
 
@@ -422,7 +423,7 @@ TEST(allowlist_test, move_to_allowlist)
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::UDP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         CHECK(cache->move_to_allowlist(flow) == true);  // Move flow to allow list
 
@@ -451,7 +452,7 @@ TEST(allowlist_test, allowlist_timeout_prune_fail)
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::TCP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         CHECK(cache->move_to_allowlist(flow) == true);
     }
@@ -462,7 +463,7 @@ TEST(allowlist_test, allowlist_timeout_prune_fail)
     // Ensure pruning doesn't occur because all flows are allow listed
     for (uint8_t i = 0; i < total_lru_count; ++i)
         CHECK(cache->prune_one(PruneReason::IDLE_PROTOCOL_TIMEOUT, true, i) == false);
-    
+
     CHECK_EQUAL(2, cache->get_count());
     CHECK_EQUAL(2, cache->get_lru_flow_count(allowlist_lru_index));
 
@@ -484,7 +485,7 @@ TEST(allowlist_test, allowlist_memcap_prune_pass)
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::TCP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         CHECK(cache->move_to_allowlist(flow) == true);
     }
@@ -508,18 +509,18 @@ TEST(allowlist_test, allowlist_timeout_with_other_protos)
     fcg.max_flows = 10;
     fcg.prune_flows = 10;
 
-    for (uint8_t i = to_utype(PktType::NONE); i <= to_utype(PktType::MAX); ++i) 
+    for (uint8_t i = to_utype(PktType::NONE); i <= to_utype(PktType::MAX); ++i)
         fcg.proto[i].nominal_timeout = 5;
-    
+
     FlowCache* cache = new FlowCache(fcg);
     int port = 1;
 
-    for (unsigned i = 0; i < 2; ++i) 
+    for (unsigned i = 0; i < 2; ++i)
     {
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::UDP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         CHECK(cache->move_to_allowlist(flow) == true);  // Move flow to allow list
 
@@ -531,9 +532,9 @@ TEST(allowlist_test, allowlist_timeout_with_other_protos)
     CHECK_EQUAL(2, cache->get_count());
 
     // Ensure pruning doesn't occur because all flows are allow listed
-    for (uint8_t i = 0; i < to_utype(PktType::MAX) - 1; ++i) 
+    for (uint8_t i = 0; i < to_utype(PktType::MAX) - 1; ++i)
         CHECK(cache->prune_one(PruneReason::NONE, true, i) == false);
-    
+
     CHECK_EQUAL(2, cache->get_count());  // Ensure no flows were pruned
 
     // Add a new ICMP flow
@@ -551,16 +552,16 @@ TEST(allowlist_test, allowlist_timeout_with_other_protos)
     // we can't prune to 0 so 1 flow will be pruned
     CHECK_EQUAL(1, cache->prune_multiple(PruneReason::MEMCAP, true));
 
-    CHECK_EQUAL(1, cache->get_count()); 
+    CHECK_EQUAL(1, cache->get_count());
     CHECK_EQUAL(1, cache->get_lru_flow_count(allowlist_lru_index));
 
     // Adding five UDP flows, these will become the LRU flows
-    for (unsigned i = 0; i < 5; ++i) 
+    for (unsigned i = 0; i < 5; ++i)
     {
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::UDP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         flow->last_data_seen = 2 + i;
     }
@@ -568,16 +569,16 @@ TEST(allowlist_test, allowlist_timeout_with_other_protos)
     CHECK_EQUAL(6, cache->get_count());
 
     // Adding three TCP flows, move two to allow list, making them MRU
-    for (unsigned i = 0; i < 3; ++i) 
+    for (unsigned i = 0; i < 3; ++i)
     {
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::TCP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         flow->last_data_seen = 4 + i;  // Set TCP flows to have later timeout
 
-        if (i > 0) 
+        if (i > 0)
         {
             CHECK(cache->move_to_allowlist(flow) == true);
 
@@ -626,7 +627,7 @@ TEST(allowlist_test, excess_prune)
         FlowKey flow_key;
         flow_key.port_l = port++;
         flow_key.pkt_type = PktType::TCP;
-        
+
         Flow* flow = cache->allocate(&flow_key);
         CHECK(cache->move_to_allowlist(flow) == true);
     }
@@ -804,7 +805,7 @@ TEST(dump_flows, dump_flows_no_flows_to_dump)
     DummyCache* cache = new DummyCache(fcg);
     CHECK(cache->dump_flows(dump_stream, 100, ffc, true, 1) == true);
 
-    delete cache;   
+    delete cache;
 }
 
 TEST_GROUP(dump_flows_summary) { };
@@ -867,7 +868,7 @@ TEST(dump_flows_summary, dump_flows_summary_with_5_of_each_flow)
 
     std::vector<PktType> types = {PktType::IP, PktType::ICMP, PktType::TCP, PktType::UDP};
 
-    for (const auto& type : types) 
+    for (const auto& type : types)
     {
         for (unsigned i = 0; i < 5; i++)
         {
@@ -881,7 +882,7 @@ TEST(dump_flows_summary, dump_flows_summary_with_5_of_each_flow)
     CHECK(cache->dump_flows_summary(flows_summary, ffc) == true);
 
     FlowsTypeSummary expected_type{};
-    for (const auto& type : types) 
+    for (const auto& type : types)
         expected_type[to_utype(type)] = 5;
     CHECK(expected_type == flows_summary.type_summary);
 
@@ -907,7 +908,7 @@ TEST(dump_flows_summary, dump_flows_summary_with_different_flow_states)
 
     std::vector<snort::Flow::FlowState> types = {snort::Flow::FlowState::BLOCK, snort::Flow::FlowState::ALLOW, snort::Flow::FlowState::SETUP};
 
-    for (const auto& type : types) 
+    for (const auto& type : types)
     {
         for (unsigned i = 0; i < 5; i++)
         {
@@ -928,7 +929,7 @@ TEST(dump_flows_summary, dump_flows_summary_with_different_flow_states)
     CHECK(expected_type == flows_summary.type_summary);
 
     FlowsStateSummary expected_state{};
-    for (const auto& type : types) 
+    for (const auto& type : types)
     {
         expected_state[to_utype(type)] = flows_number;
     }
@@ -1006,7 +1007,7 @@ TEST(dump_flows_summary, dump_flows_summary_with_filter)
 
     std::vector<PktType> types = {PktType::IP, PktType::ICMP, PktType::TCP, PktType::UDP};
 
-    for (const auto& type : types) 
+    for (const auto& type : types)
     {
         int port = 1;
         for (unsigned i = 0; i < 5; i++)
@@ -1042,7 +1043,7 @@ TEST(dump_flows_summary, dump_flows_summary_with_filter)
     CHECK(cache->dump_flows_summary(flows_summary, ffc) == true);
 
     expected_type = {};
-    for (const auto& type : types) 
+    for (const auto& type : types)
         expected_type[to_utype(type)] = 1;
     CHECK(expected_type == flows_summary.type_summary);
 
@@ -1072,8 +1073,8 @@ TEST(dump_flows_summary, dump_flows_summary_with_filter)
 
 
 
-TEST_GROUP(flow_cache_lrus) 
-{ 
+TEST_GROUP(flow_cache_lrus)
+{
     FlowCacheConfig fcg;
     DummyCache* cache;
 
@@ -1115,7 +1116,7 @@ TEST(flow_cache_lrus, count_flows_in_lru_test)
         CHECK(flow != nullptr);
     }
 
-    CHECK_EQUAL(10, cache->get_count());  // Verify 10 flows in 
+    CHECK_EQUAL(10, cache->get_count());  // Verify 10 flows in
     CHECK_EQUAL(4, cache->count_flows_in_lru(to_utype(PktType::TCP)));  // 4 TCP flows
     CHECK_EQUAL(1, cache->count_flows_in_lru(to_utype(PktType::UDP)));  // 1 UDP flow
     CHECK_EQUAL(1, cache->count_flows_in_lru(to_utype(PktType::USER)));  // 1 USER flow
index db361d13497d16fe45a171747df858f58ca89ef4..4a88e0fc3ecdbadee53ba4f0518e3483138979ee 100644 (file)
@@ -57,6 +57,7 @@ void Active::set_drop_reason(char const*) { }
 FlowCache::FlowCache(const FlowCacheConfig& cfg) : config(cfg) { }
 FlowCache::~FlowCache() = default;
 Flow::~Flow() = default;
+FlowDataStore::~FlowDataStore() = default;
 DetectionEngine::DetectionEngine() { context = nullptr; }
 DetectionEngine::~DetectionEngine() = default;
 unsigned FlowCache::purge() { return 1; }
index 2d2bab043e1cb52e2a53d49d7fb9c2800f437bad..f05b34bc8890273d995038ac391e40096222736e 100644 (file)
@@ -26,7 +26,6 @@
 
 #include "flow/flow_stash.h"
 #include "main/snort_config.h"
-#include "pub_sub/stash_events.h"
 #include "utils/util.h"
 
 #include <CppUTest/CommandLineTestRunner.h>
 using namespace snort;
 using namespace std;
 
-template<class Type>
-class DBConsumer : public DataHandler
-{
-public:
-
-    static const char* STASH_EVENT;
-
-    DBConsumer(const char* mod_name) : DataHandler(mod_name) {}
-
-    void handle(DataEvent& e, Flow*) override
-    {
-        const StashEvent* se = static_cast<const StashEvent*>(&e);
-        se->get_item()->get_val(value);
-    }
-
-    Type get_from_stash(FlowStash& stash)
-    {
-        stash.get(STASH_EVENT, value);
-        return value;
-    }
-
-    Type get_value() const { return value; }
-
-private:
-    Type value;
-};
-
-template<class Type>
-const char* DBConsumer<Type>::STASH_EVENT = "foo.stash.event";
-
 static DataHandler* s_handler = nullptr;
 
 void DataBus::subscribe(const PubKey&, unsigned, snort::DataHandler* h)
@@ -101,42 +70,6 @@ char* snort_strdup(const char* str)
 TEST_GROUP(stash_tests)
 { };
 
-// DataBus tests
-TEST(stash_tests, data_bus_publish_test)
-{
-    typedef int32_t value_t;
-
-    DBConsumer<value_t> c("foo");
-    PubKey pub_key { };
-
-    DataBus::subscribe(pub_key, 0, &c);
-
-    FlowStash stash;
-    value_t vin, vout;
-
-    // stash/publish 10
-    vin = 10;
-    stash.store(DBConsumer<value_t>::STASH_EVENT, vin, 1, 1);
-    vout = c.get_value();
-    CHECK_EQUAL(vin, vout);
-
-    // stash/publish 20, with the same key as before
-    vin = 20;
-    stash.store(DBConsumer<value_t>::STASH_EVENT, vin, 1, 1);
-    vout = c.get_value();
-    CHECK_EQUAL(vin, vout);
-
-    // do we get some event that we're not listening to?
-    value_t before = c.get_value();
-    stash.store("bar.stash.event", 30);
-    value_t after = c.get_value();
-    CHECK_EQUAL(before, after);
-
-    // do we still get our own STASH_EVENT from the stash, at a later time?
-    vout = c.get_from_stash(stash);
-    CHECK_EQUAL(vin, vout);
-}
-
 // Stash tests
 TEST(stash_tests, new_int32_item)
 {
@@ -239,23 +172,22 @@ TEST(stash_tests, non_existent_item)
 TEST(stash_tests, new_generic_object)
 {
     FlowStash stash;
-    StashGenericObject *test_object = new StashGenericObject(111);
+    StashGenericObject *test_object = new StashGenericObject;
 
     stash.store("item_1", test_object);
 
     StashGenericObject *retrieved_object;
     CHECK(stash.get("item_1", retrieved_object));
     POINTERS_EQUAL(test_object, retrieved_object);
-    CHECK_EQUAL(test_object->get_object_type(), ((StashGenericObject*)retrieved_object)->get_object_type());
 }
 
 TEST(stash_tests, update_generic_object)
 {
     FlowStash stash;
-    StashGenericObject *test_object = new StashGenericObject(111);
+    StashGenericObject *test_object = new StashGenericObject;
     stash.store("item_1", test_object);
 
-    StashGenericObject *new_test_object = new StashGenericObject(111);
+    StashGenericObject *new_test_object = new StashGenericObject;
     stash.store("item_1", new_test_object);
 
     StashGenericObject *retrieved_object;
@@ -273,7 +205,7 @@ TEST(stash_tests, non_existent_generic_object)
 TEST(stash_tests, mixed_items)
 {
     FlowStash stash;
-    StashGenericObject *test_object = new StashGenericObject(111);
+    StashGenericObject *test_object = new StashGenericObject;
 
     stash.store("item_1", 10);
     stash.store("item_2", "value_2");
@@ -293,7 +225,6 @@ TEST(stash_tests, mixed_items)
     StashGenericObject *retrieved_object;
     CHECK(stash.get("item_4", retrieved_object));
     POINTERS_EQUAL(test_object, retrieved_object);
-    CHECK_EQUAL(test_object->get_object_type(), ((StashGenericObject*)retrieved_object)->get_object_type());
 }
 
 TEST(stash_tests, store_ip)
@@ -304,31 +235,31 @@ TEST(stash_tests, store_ip)
 
     // Disabled
     snort_conf.max_aux_ip = -1;
-    CHECK_FALSE(stash.store(ip));
+    CHECK_FALSE(stash.store(ip, nullptr));
 
     // Enabled without stashing, no duplicate IP checking
     snort_conf.max_aux_ip = 0;
-    CHECK_TRUE(stash.store(ip));
-    CHECK_TRUE(stash.store(ip));
+    CHECK_TRUE(stash.store(ip, nullptr));
+    CHECK_TRUE(stash.store(ip, nullptr));
 
     // Enabled with FIFO stashing, duplicate IP checking
     snort_conf.max_aux_ip = 2;
-    CHECK_TRUE(stash.store(ip));
-    CHECK_FALSE(stash.store(ip));
+    CHECK_TRUE(stash.store(ip, nullptr));
+    CHECK_FALSE(stash.store(ip, nullptr));
 
     SfIp ip2;
     CHECK(ip2.set("1.1.1.2") == SFIP_SUCCESS);
-    CHECK_TRUE(stash.store(ip2));
-    CHECK_FALSE(stash.store(ip2));
+    CHECK_TRUE(stash.store(ip2, nullptr));
+    CHECK_FALSE(stash.store(ip2, nullptr));
 
     SfIp ip3;
     CHECK(ip3.set("1111::8888") == SFIP_SUCCESS);
-    CHECK_TRUE(stash.store(ip3));
-    CHECK_FALSE(stash.store(ip3));
-    CHECK_FALSE(stash.store(ip2));
-    CHECK_TRUE(stash.store(ip));
-    CHECK_FALSE(stash.store(ip));
-    CHECK_FALSE(stash.store(ip3));
+    CHECK_TRUE(stash.store(ip3, nullptr));
+    CHECK_FALSE(stash.store(ip3, nullptr));
+    CHECK_FALSE(stash.store(ip2, nullptr));
+    CHECK_TRUE(stash.store(ip, nullptr));
+    CHECK_FALSE(stash.store(ip, nullptr));
+    CHECK_FALSE(stash.store(ip3, nullptr));
 }
 
 int main(int argc, char** argv)
index 5126e60f11b8c9b437908329f36d08d2944976be..c7cf26a3cf9e8001bb303f1ebb552e0616155619 100644 (file)
@@ -67,10 +67,6 @@ FlowHAState::FlowHAState() = default;
 
 void FlowHAState::reset() {}
 
-FlowStash::~FlowStash() = default;
-
-void FlowStash::reset() {}
-
 void DetectionEngine::onload(Flow*) {}
 
 Packet* DetectionEngine::set_next_packet(const Packet*, Flow*) { return nullptr; }
@@ -149,6 +145,118 @@ TEST(inspection_time_presence, inspection_time_addition)
     delete flow;
 }
 
+class TestFlowData : public FlowData
+{
+public:
+    explicit TestFlowData(unsigned v) : FlowData(module_id), version(v)
+    { }
+    ~TestFlowData() override = default;
+
+    unsigned get_version() const
+    { return version; }
+
+    static unsigned module_id;
+
+    static void init()
+    { module_id = FlowData::create_flow_data_id(); }
+
+protected:
+    unsigned version;
+};
+
+unsigned TestFlowData::module_id = 0;
+
+class HigherIdFlowData : public FlowData
+{
+public:
+    HigherIdFlowData() : FlowData(module_id)
+    { }
+    ~HigherIdFlowData() override = default;
+
+    static unsigned module_id;
+
+    static void init()
+    { module_id = FlowData::create_flow_data_id(); }
+};
+
+unsigned HigherIdFlowData::module_id = 0;
+
+TEST_GROUP(flow_data_test)
+{
+};
+
+TEST(flow_data_test, flow_data_access)
+{
+    unsigned lower_module_id = FlowData::create_flow_data_id();
+    TestFlowData::init();
+    HigherIdFlowData::init();
+    unsigned higher_module_id = FlowData::create_flow_data_id();
+
+    Flow *flow = new Flow;
+
+    TestFlowData* existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(!existing_fd, "FlowData should not exist");
+
+    // new
+    TestFlowData* fd = new TestFlowData(1);
+    flow->set_flow_data(fd);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(existing_fd, "FlowData should exist");
+    UNSIGNED_LONGS_EQUAL_TEXT(1, existing_fd->get_version(), "FlowData version should be 1");
+
+    // overwrite
+    fd = new TestFlowData(2);
+    flow->set_flow_data(fd);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(existing_fd, "FlowData should exist");
+    UNSIGNED_LONGS_EQUAL_TEXT(2, existing_fd->get_version(), "FlowData version should be 2");
+
+    // free by object
+    flow->free_flow_data(fd);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(!existing_fd, "FlowData should not exist");
+
+    HigherIdFlowData* hid_fd = new HigherIdFlowData;
+    flow->set_flow_data(hid_fd);
+    HigherIdFlowData* hid_existing_fd =
+        static_cast<HigherIdFlowData*>(flow->get_flow_data(HigherIdFlowData::module_id));
+    CHECK_TEXT(hid_existing_fd, "HigherIdFlowData should exist");
+
+    fd = new TestFlowData(3);
+    flow->set_flow_data(fd);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(existing_fd, "FlowData should exist");
+    UNSIGNED_LONGS_EQUAL_TEXT(3, existing_fd->get_version(), "FlowData version should be 3");
+
+    // free by id not found lower
+    flow->free_flow_data(lower_module_id);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(existing_fd, "FlowData should exist");
+    UNSIGNED_LONGS_EQUAL_TEXT(3, existing_fd->get_version(), "FlowData version should be 3");
+    hid_existing_fd = static_cast<HigherIdFlowData*>(flow->get_flow_data(HigherIdFlowData::module_id));
+    CHECK_TEXT(hid_existing_fd, "HigherIdFlowData should exist");
+
+    // free by id not found higher
+    flow->free_flow_data(higher_module_id);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(existing_fd, "FlowData should exist");
+    UNSIGNED_LONGS_EQUAL_TEXT(3, existing_fd->get_version(), "FlowData version should be 3");
+    hid_existing_fd = static_cast<HigherIdFlowData*>(flow->get_flow_data(HigherIdFlowData::module_id));
+    CHECK_TEXT(hid_existing_fd, "HigherIdFlowData should exist");
+
+    // free by id
+    flow->free_flow_data(TestFlowData::module_id);
+    existing_fd = static_cast<TestFlowData*>(flow->get_flow_data(TestFlowData::module_id));
+    CHECK_TEXT(!existing_fd, "FlowData should not exist");
+    hid_existing_fd = static_cast<HigherIdFlowData*>(flow->get_flow_data(HigherIdFlowData::module_id));
+    CHECK_TEXT(hid_existing_fd, "HigherIdFlowData should exist");
+    flow->free_flow_data(hid_existing_fd);
+    hid_existing_fd = static_cast<HigherIdFlowData*>(flow->get_flow_data(HigherIdFlowData::module_id));
+    CHECK_TEXT(!hid_existing_fd, "HigherIdFlowData should not exist");
+
+    delete flow;
+}
+
 int main(int argc, char** argv)
 {
     int return_value = CommandLineTestRunner::RunAllTests(argc, argv);
index a7e1955ffcc2f87b6ae9311f66f9a2e5445f538c..39327aae6b88192b827f7459b47f22ba121a807f 100644 (file)
@@ -206,6 +206,7 @@ namespace snort
 Flow::~Flow() = default;
 void Flow::set_client_initiate(Packet*) { }
 void Flow::set_direction(Packet*) { }
+FlowDataStore::~FlowDataStore() = default;
 
 void packet_gettimeofday(struct timeval* tv)
 {
@@ -215,9 +216,6 @@ void packet_gettimeofday(struct timeval* tv)
 
 int SFDAQInstance::ioctl(DAQ_IoctlCmd, void*, size_t) { return DAQ_SUCCESS; }
 
-FlowStash::~FlowStash() = default;
-
-
 SideChannel::SideChannel(ScMsgFormat)
 { }
 
index 4306687da2920273a6ac46eef99261a0c5498439..c2d0b94c8151ac866dcda1bb4f73a61bf5c299e4 100644 (file)
@@ -38,7 +38,7 @@
 // depends on includes installed in framework/snort_api.h
 // see framework/plugins.h
 
-#define BASE_API_VERSION 21
+#define BASE_API_VERSION 22
 
 // set the reserved field to this to be future proof
 #define API_RESERVED 0
index ed1a4e5f71fed43354f922057b484460d737f649..a29a9f534a9bf240e00808a47b3ceb8448650a0a 100644 (file)
@@ -236,6 +236,7 @@ NetworkPolicy* get_network_policy() { return nullptr; }
 InspectionPolicy* get_inspection_policy() { return nullptr; }
 Flow::~Flow() = default;
 bool Flow::handle_allowlist() { return true; }
+FlowDataStore::~FlowDataStore() = default;
 void ThreadConfig::implement_thread_affinity(SThreadType, unsigned) { }
 void ThreadConfig::apply_thread_policy(SThreadType , unsigned ) { }
 void ThreadConfig::set_instance_tid(int) { }
index f548e8e94519f4fac73a874d0e49f8a7417fabf8..e5df02447790a7cce513545e3abd2f1435650d8a 100644 (file)
@@ -146,9 +146,10 @@ void EventManager::add_output(OutputSet** ofn, Logger* eh)
     (*ofn)->outputs.emplace_back(eh);
 }
 
-void EventManager::copy_outputs(OutputSet* dst, OutputSet* src)
+void EventManager::copy_outputs(OutputSet* dst, const OutputSet* src)
 {
-    dst->outputs = src->outputs;
+    if (dst && src && src->outputs.size())
+        dst->outputs = src->outputs;
 }
 
 //-------------------------------------------------------------------------
index 8f815f6ede52dd7059ab89372867b7cf5305c3a5..83c65023882ea7fcc337b5abbab6491567d18fc0 100644 (file)
@@ -55,7 +55,7 @@ public:
     static unsigned get_output_type_flags(char*);
 
     static void add_output(OutputSet**, snort::Logger*);
-    static void copy_outputs(OutputSet* dst, OutputSet* src);
+    static void copy_outputs(OutputSet* dst, const OutputSet* src);
     static void release_outputs(OutputSet*);
 
     static void open_outputs();
index 870e1a9ecd69dd6b3c72a4ea30fc9790e4dae45c..faeb3324675d6fb1b84e7aebd874b20e89aa2cbb 100644 (file)
@@ -223,7 +223,7 @@ bool MailLogState::is_email_to_present() const
     return log_flags & MIME_FLAG_RCPT_TO_PRESENT;
 }
 
-MailLogState::MailLogState(MailLogConfig* conf) : StashGenericObject(STASH_GENERIC_OBJECT_MIME)
+MailLogState::MailLogState(MailLogConfig* conf)
 {
     if (conf && (conf->log_email_hdrs || conf->log_filename
             || conf->log_mailfrom || conf->log_rcptto))
index b555ecd4c8c4c9e7f145ca9830100c75506ac01c..c2f0d7ef8496203adff5747034d9587f3ad993a3 100644 (file)
@@ -893,7 +893,7 @@ MimeSession::MimeSession(Packet* p, const DecodeConfig* dconf, MailLogConfig* lc
     uri(uri),
     uri_length(uri_length)
 {
-    p->flow->stash->store(STASH_EXTRADATA_MIME, log_state);
+    p->flow->set_attr(STASH_EXTRADATA_MIME, log_state);
     reset_mime_paf_state(&mime_boundary);
 }
 
index be52d3349f9b12ba4023e1759bb30704b5eedd42..a211a736cc8548a2520d340e187c5ecb713f5d07 100644 (file)
@@ -248,9 +248,10 @@ AppIdSession* AppIdSession::create_future_session(const Packet* ctrlPkt, const S
     char src_ip[INET6_ADDRSTRLEN];
     char dst_ip[INET6_ADDRSTRLEN];
 
-    AppIdInspector* inspector = (AppIdInspector*)ctrlPkt->flow->current_flow_data->get_handler();
-    if ((inspector == nullptr) or strcmp(inspector->get_name(), MOD_NAME))
-        inspector = (AppIdInspector*)InspectorManager::get_inspector(MOD_NAME, true);
+    AppIdInspector* inspector =
+        static_cast<AppIdInspector*>(
+            InspectorManager::get_inspector(MOD_NAME, MOD_USAGE, appid_inspector_api.type));
+    assert(inspector);
 
     // FIXIT-RC - port parameter passed in as 0 since we may not know client port, verify
 
@@ -1260,8 +1261,8 @@ void AppIdSession::publish_appid_event(AppidChangeBits& change_bits, const Packe
 {
     if (!api.flags.stored_in_stash)
     {
-        assert(p.flow and p.flow->stash);
-        p.flow->stash->store(STASH_APPID_DATA, &api, false);
+        assert(p.flow);
+        p.flow->set_attr(STASH_APPID_DATA, &api);
         api.flags.stored_in_stash = true;
     }
 
index 45c93c0400bb0cc1bad2c8806e139ad1a9ab1772..edf21a040fa8ca9e1e1cf13ed0b2967174aaaa49 100644 (file)
@@ -29,6 +29,7 @@
 #include <unordered_map>
 
 #include <daq_common.h>
+#include "flow/flow_data.h"
 #include "pub_sub/appid_events.h"
 
 #include "app_info_table.h"
@@ -44,6 +45,8 @@
 #include "pub_sub/shadowtraffic_aggregator.h"
 #include "service_state.h"
 
+#define STASH_APPID_DATA "appid_data"
+
 namespace snort
 {
     class AppIdSessionApi;
@@ -340,7 +343,7 @@ public:
     static unsigned inspector_id;
     static std::mutex inferred_svcs_lock;
 
-    static void init() { inspector_id = FlowData::create_flow_data_id(); }
+    static void init() { inspector_id = snort::FlowData::create_flow_data_id(); }
 
     void set_session_flags(uint64_t set_flags) { flags |= set_flags; }
     void clear_session_flags(uint64_t clear_flags) { flags &= ~clear_flags; }
@@ -756,16 +759,16 @@ public:
 
     void set_shadow_traffic_publishing_appid(AppId id)
     {
-       shadow_traffic_appid = id; 
+       shadow_traffic_appid = id;
     }
 
     AppId get_shadow_traffic_publishing_appid() const
     {
         return shadow_traffic_appid;
     }
-    
-    inline void change_shadow_traffic_bits_to_string (const uint32_t& st_bits,std::string& str) const 
-    {  
+
+    inline void change_shadow_traffic_bits_to_string (const uint32_t& st_bits,std::string& str) const
+    {
         std::string tempStr;
 
         if (st_bits & ShadowTraffic_Type_Encrypted_DNS) {
@@ -783,10 +786,10 @@ public:
         if (!tempStr.empty()) {
             tempStr.pop_back();
         }
-        
-        str.append(tempStr);     
-    } 
-    
+
+        str.append(tempStr);
+    }
+
     void set_cert_key (const std::string& key)
     {
         ssl_cert_key = key;
index 0fe45de1e29841aada4ac8485ed48dd90d725f9c..10b97d7b140f8276e84bacfe972ce2f1494a59ed 100644 (file)
@@ -40,7 +40,7 @@ using namespace snort;
 static THREAD_LOCAL uint32_t appid_flow_data_id = 0;
 
 AppIdSessionApi::AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID), asd(asd), initiator_ip(ip),
+    asd(asd), initiator_ip(ip),
     session_id(std::to_string(get_instance_id()) + "." + std::to_string(++appid_flow_data_id))
 { }
 
index c5e2e127dcc59ac095cc91287807b994fafac89a..6444f25d2e9dc2f81753e747e55354eb34513dcc 100644 (file)
@@ -23,7 +23,6 @@
 #define APPID_SESSION_API_H
 
 #include "flow/flow.h"
-#include "flow/stash_item.h"
 #include "main/snort_types.h"
 #include "pub_sub/appid_events.h"
 #include "sfip/sf_ip.h"
index 88c307e2bce24c1e9fe87ce8d32860b0e3c8bba7..6b0442b6ca2ab7267763237fdbbff32b28c15412 100644 (file)
@@ -39,9 +39,10 @@ void ParseWarning(WarningGroup, const char*, ...) { }
 // LCOV_EXCL_STOP
 
 // Stubs for appid sessions
-FlowData::FlowData(unsigned, Inspector*) : next(nullptr), prev(nullptr), handler(nullptr), id(0)
+FlowData::FlowData(unsigned, Inspector*) : handler(nullptr), id(0)
 { }
 FlowData::~FlowData() = default;
+FlowDataStore::~FlowDataStore() = default;
 
 // Stubs for packet
 Packet::Packet(bool) { }
index 3b8c230010b7446cb3f6d10b9bf464e50e3f5a94..d428bc231007c0cd7c1a33a5550fad50262d6848 100644 (file)
@@ -61,8 +61,8 @@ static bool prep_patterns = true;
 namespace snort
 {
 AppIdApi appid_api;
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) { }
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+{ }
 Flow::~Flow() = default;
 AppIdSession* AppIdApi::get_appid_session(snort::Flow const&) { return nullptr; }
 
index 4ded4112333a1ac7285a29ad87d6ddf318909190..71674abd222f70334aded7204f6a9d514a4e0384 100644 (file)
@@ -63,8 +63,8 @@ static DetectorHTTPPattern mpattern;
 
 namespace snort
 {
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 SearchTool::SearchTool(bool, const char*) { }
 void SearchTool::reload() { }
 static bool test_find_all_done = false;
index 17b9950611959d90056a74c72f716c103aa32ca6..58439af14e35fcbad3a4200cc0ed91d1ba9d1932 100644 (file)
@@ -35,7 +35,7 @@ namespace snort
 void ParseWarning(WarningGroup, const char*, ...) { }
 
 // Stubs for appid sessions
-FlowData::FlowData(unsigned, Inspector*) : next(nullptr), prev(nullptr), handler(nullptr), id(0)
+FlowData::FlowData(unsigned, Inspector*) : handler(nullptr), id(0)
 { }
 FlowData::~FlowData() = default;
 
@@ -78,8 +78,8 @@ void Module::sum_stats(bool){}
 void Module::main_accumulate_stats(){}
 void Module::reset_stats() {}
 
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 }
 
 AlpnPatternMatchers::~AlpnPatternMatchers() {}
index da27f3221145950dcd518ade66d82b00cd86855d..7b1d892e800c426e703bb8049efc4046c2ccfb24 100644 (file)
@@ -70,8 +70,8 @@ Packet* DetectionEngine::get_current_packet()
     return &p;
 }
 
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 }
 
 void appid_log(const snort::Packet*, unsigned char, char const*, ...) { }
@@ -274,7 +274,7 @@ TEST(appid_api, set_ssl_certificate_key)
     appid_api.set_ssl_certificate_key(*flow, cert_key);
     asd.set_cert_key(cert_key);
     CHECK_EQUAL(asd.get_cert_key(), cert_key);
-    delete &asd.get_api(); 
+    delete &asd.get_api();
 }
 
 TEST(appid_api, ssl_app_group_id_lookup)
@@ -386,7 +386,8 @@ TEST(appid_api, ssl_app_group_id_lookup)
     // When appid session is not existing
     // 1. Match based on server name
     Flow* f = new Flow;
-    flow->set_flow_data(nullptr);
+    // This call just sets mock_flow_data pointer to nullptr, so mocks work correctly for the test.
+    flow->free_flow_data(1);
     service = APP_ID_NONE;
     client = APP_ID_NONE;
     payload = APP_ID_NONE;
index ae96ec5daa3521e8cf00ef6023e8c55ad4c9e9df..564113bca8154034b6f903a8238cf463ec5eddaa 100644 (file)
@@ -47,8 +47,7 @@ Packet::Packet(bool) {}
 Packet::~Packet() = default;
 FlowData::FlowData(unsigned, Inspector*) { }
 FlowData::~FlowData() = default;
-AppIdSessionApi::AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID), asd(asd), initiator_ip(ip) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession* asd, const SfIp& ip) : asd(asd), initiator_ip(ip) { }
 [[noreturn]] void FatalError(const char*,...) {  exit(-1); }
 void ErrorMessage(const char*, va_list&) { }
 void WarningMessage(const char*, va_list&) { }
index afe84a26c69b4922f5edb52c9bcbc318d71b9af9..5189cd9c347ddd7c5a332c39f4300057c6b13a84 100644 (file)
@@ -38,8 +38,8 @@
 
 namespace snort
 {
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 }
 
 void ApplicationDescriptor::set_id(
index 7ef0115119cd99c7593c7f8c39edf5c5aea5bc68..94a2af541d65689b39a327c2c6214a948decab8a 100644 (file)
@@ -124,8 +124,8 @@ void IpApi::set(const SfIp& sip, const SfIp& dip)
 }
 } // namespace ip
 
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 void AppIdSessionApi::get_first_stream_app_ids(AppId&, AppId&, AppId&, AppId&) const { }
 
 // Mocks for publish
@@ -221,7 +221,7 @@ const char* AppInfoManager::get_app_name(int32_t)
 uint32_t AppInfoManager::getAttributeBits(AppId)
 {
     return 0;
-} 
+}
 
 // Stubs for AppIdSession
 void AppIdSession::sync_with_snort_protocol_id(AppId, Packet*) {}
index 4ecace80a83de17a17c6f89a1dadd6c33e6aafe5..786f72403a139e9f9ee0aa798f315da8ab5374db 100644 (file)
@@ -46,8 +46,8 @@ using namespace std;
 namespace snort
 {
 AppIdApi appid_api;
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-        StashGenericObject(STASH_GENERIC_OBJECT_APPID) { }
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+{ }
 AppIdSession* AppIdApi::get_appid_session(Flow const&) { return session; }
 
 Packet::Packet(bool) { }
index caa11deea19b44e1efd93969673347014b150ecd..c29259bb3986f9cf53c0e103bc3b4c1673b27c47 100644 (file)
@@ -62,8 +62,8 @@ Packet* DetectionEngine::get_current_packet()
     return &p;
 }
 
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 }
 
 void appid_log(const snort::Packet*, unsigned char, char const*, ...) { }
index 7263de8469c430551825c73dbe8fc4be3a39e48d..9afe95b54c19eebe87cc42e61a26def5925ca55e 100644 (file)
@@ -54,8 +54,8 @@ namespace snort
 Packet::Packet(bool) {}
 Packet::~Packet() = default;
 Packet* DetectionEngine::get_current_packet() { return nullptr; }
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 }
 
 void FlowHAState::add(uint8_t) { }
index be3b12d2b1fc9949b8f92c1711c83f268e8f3469..e35a85e2c254858acf6803cbfb90ad6007c69e33 100644 (file)
@@ -23,7 +23,6 @@
 
 FlowData::FlowData(unsigned, Inspector*)
 {
-    next = prev = nullptr;
     handler = nullptr;
     id = 222;
 }
@@ -34,23 +33,29 @@ FlowData* mock_flow_data = nullptr;
 
 typedef int32_t AppId;
 Flow::~Flow() = default;
+FlowDataStore::~FlowDataStore() = default;
 
 class FakeFlow : public Flow
 {
 };
 
-FlowData* Flow::get_flow_data(unsigned) const
+FlowData* FlowDataStore::get(unsigned) const
 {
     return mock_flow_data;
 }
 
-int Flow::set_flow_data(FlowData* fd)
+void FlowDataStore::set(FlowData* fd)
 {
     mock_flow_data = fd;
-    return 0;
 }
 
-bool FlowStash::get(const std::string &, StashGenericObject*&) { return false; }
+void FlowDataStore::erase(unsigned)
+{
+    mock_flow_data = nullptr;
+}
+
+bool FlowStash::get(const std::string &, StashGenericObject*&) const
+{ return false; }
 
 #endif
 
index 0ee30f24ac58313b3ed3cd8cbc292abcc99202fd..b7762342f65fb8b3af0f517cc3350d8e51454eec 100644 (file)
@@ -74,8 +74,8 @@ char* snort_strdup(const char* str)
 }
 time_t packet_time() { return std::time(nullptr); }
 
-AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
-    StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&)
+}
 }
 
 DiscoveryFilter::~DiscoveryFilter(){}
@@ -87,7 +87,7 @@ AppInfoTableEntry* AppInfoManager::get_app_info_entry(AppId)
 
 // Stubs for appid classes
 class AppIdInspector{};
-FlowData::FlowData(unsigned, Inspector*) : next(nullptr), prev(nullptr), handler(nullptr), id(0)
+FlowData::FlowData(unsigned, Inspector*) : handler(nullptr), id(0)
 { }
 FlowData::~FlowData() = default;
 
index e5f3590f9939a6c177a96aec14abea330124f81b..e4730e271da791c757a2f9701a2d2614e1a9c628 100644 (file)
@@ -285,7 +285,7 @@ static inline void process_http_session(const Packet& p, AppIdSession& asd,
         {
             SfIp aux_ip;
             if (parse_ip_from_uri(*uri, aux_ip))
-                p.flow->stash->store(aux_ip);
+                p.flow->set_attr(aux_ip);
         }
     }
 }
index d47de5c7d1b69a8100401e708c62299a0c752f7e..1e14c4c6d232af873539fc01691f4dff272f6b65 100644 (file)
@@ -20,6 +20,7 @@
 #ifndef EXTRACTORS_H
 #define EXTRACTORS_H
 
+#include <map>
 #include <sys/time.h>
 #include <vector>
 
index 5f9fe9928ded1b101a2ff1ccb4ef33e982f0fb99..0a1c3fcc6d45cbc04e2919c902a19765b7cfeeb3 100644 (file)
@@ -120,7 +120,7 @@ static bool bpf_compile_and_validate()
 static bool open_pcap_dumper()
 {
     string fname;
-    if ( config.capture_path.empty() ) 
+    if ( config.capture_path.empty() )
         get_instance_file(fname, FILE_NAME);
     else
     {
@@ -143,7 +143,7 @@ static bool open_pcap_dumper()
 }
 
 // for unit test
-static void _packet_capture_enable(const string& f, const int16_t g = -1, const string& t = "", 
+static void _packet_capture_enable(const string& f, const int16_t g = -1, const string& t = "",
                                    const bool ci = true, const string& path = "", const unsigned max = 0)
 {
     if ( !config.enabled )
@@ -174,7 +174,7 @@ static void _packet_capture_disable()
 // non-static functions
 // -----------------------------------------------------------------------------
 
-void packet_capture_enable(const string& f, const int16_t g, const string& t, const bool ci, 
+void packet_capture_enable(const string& f, const int16_t g, const string& t, const bool ci,
                            const string& p, const unsigned max)
 {
 
@@ -247,7 +247,7 @@ bool PacketCapture::capture_init()
 void PacketCapture::show(const SnortConfig*) const
 {
     ConfigLogger::log_flag("enable", config.enabled);
-    if (config.enabled) 
+    if (config.enabled)
     {
         ConfigLogger::log_value("filter", config.filter.c_str());
         ConfigLogger::log_value("tenants", int_vector_to_str(config.tenants).c_str());
@@ -275,9 +275,12 @@ void PacketCapture::eval(Packet* p)
 
         if (!config.tenants.empty())
         {
-            if (!std::any_of(config.tenants.begin(), config.tenants.end(),[&p](uint32_t tenant_id){
-            return p->pkth->tenant_id == tenant_id;
-            }))
+            uint32_t packet_tenant_id = p->pkth->tenant_id;
+            if (std::none_of(config.tenants.cbegin(), config.tenants.cend(),
+                [packet_tenant_id](uint32_t tenant_id)
+                {
+                    return packet_tenant_id == tenant_id;
+                }))
             {
                 cap_count_stats.checked++;
                 return;
@@ -642,7 +645,7 @@ TEST_CASE("bpf filter", "[PacketCapture]")
         "\x0a\x96";
 
     Packet p_match(false), p_non_match(false);
-    DAQ_PktHdr_t daq_hdr;
+    DAQ_PktHdr_t daq_hdr = {};
 
     p_match.pkth = &daq_hdr;
     p_non_match.pkth = &daq_hdr;
index 29407b2e2d049234e8f0b80e93a82d85cf9b5ace..2c91d27ea697a84474111fe34636eef03ee96fbc 100644 (file)
@@ -152,7 +152,7 @@ FlowIPTracker::FlowIPTracker(PerfConfig* perf) : PerfTracker(perf, TRACKER_NAME)
         &stats.state_changes[SFS_STATE_TCP_CLOSED]);
     formatter->register_field("udp_created", (PegCount*)
         &stats.state_changes[SFS_STATE_UDP_CREATED]);
-    formatter->register_field("app_id", appid_name); 
+    formatter->register_field("app_id", appid_name);
     formatter->register_field("port_a", port_a);
     formatter->register_field("port_b", port_b);
     formatter->register_field("protocol", protocol);
index cd57a3438c60b9247c8819e27d5a72242bfb1df0..31f2bf56a1352062988532d0bad4addfc44d4d3a 100644 (file)
@@ -387,11 +387,14 @@ static void snort_reputation(const ReputationConfig& config, ReputationData& dat
 
     if ( p->flow and p->flow->reload_id > 0 )
     {
-        const auto& aux_ip_list =  p->flow->stash->get_aux_ip_list();
-        for ( const auto& ip : aux_ip_list )
+        const auto* aux_ip_list = p->flow->get_aux_ip_list();
+        if (aux_ip_list)
         {
-            if ( BLOCKED == snort_reputation_aux_ip(config, data, p, &ip) )
-                return;
+            for ( const auto& ip : *aux_ip_list )
+            {
+                if ( BLOCKED == snort_reputation_aux_ip(config, data, p, &ip) )
+                    return;
+            }
         }
     }
 
index e2d9aa3ec805876d12298af5a3cedae2ad49e8dd..f7b94a44cf8568862c869039d5119ec0a16ce232 100644 (file)
@@ -207,10 +207,10 @@ bool RnaAppDiscovery::discover_service(const Packet* p, DiscoveryFilter& filter,
     if ( is_new )
     {
         if ( proto == IpProtocol::TCP )
-            logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &htp,
+            logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, htp,
                 (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
         else
-            logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &htp,
+            logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, htp,
                 (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
 
         ha.hits = 0; // hit count is reset after logs are written
@@ -252,11 +252,11 @@ void RnaAppDiscovery::discover_payload(const Packet* p, DiscoveryFilter& filter,
         if ( new_pld )
         {
             if ( proto == IpProtocol::TCP )
-                logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &srt,
+                logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, srt,
                     (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
                     srt->get_last_seen_mac(mac_addr), &local_ha);
             else
-                logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &srt,
+                logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, srt,
                     (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
                     srt->get_last_seen_mac(mac_addr), &local_ha);
         }
@@ -277,7 +277,7 @@ void RnaAppDiscovery::discover_payload(const Packet* p, DiscoveryFilter& filter,
     new_client_payload = crt->add_client_payload(hc, payload, max_payloads);
 
     if ( new_client_payload )
-        logger.log(RNA_EVENT_CHANGE, CHANGE_CLIENT_APP_UPDATE, p, &crt,
+        logger.log(RNA_EVENT_CHANGE, CHANGE_CLIENT_APP_UPDATE, p, crt,
             (const struct in6_addr*) p->flow->client_ip.get_ip6_ptr(),
             crt->get_last_seen_mac(mac_addr), &hc);
 }
@@ -316,10 +316,10 @@ void RnaAppDiscovery::update_service_info(const Packet* p, DiscoveryFilter& filt
     ha.last_seen = (uint32_t) packet_time();
 
     if ( proto == IpProtocol::TCP )
-        logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, &htp,
+        logger.log(RNA_EVENT_CHANGE, CHANGE_TCP_SERVICE_INFO, p, htp,
             (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
     else
-        logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, &htp,
+        logger.log(RNA_EVENT_CHANGE, CHANGE_UDP_SERVICE_INFO, p, htp,
             (const struct in6_addr*) ip.get_ip6_ptr(), htp->get_last_seen_mac(mac_addr), &ha);
 
     ha.hits = 0;
@@ -343,7 +343,7 @@ void RnaAppDiscovery::discover_banner(const Packet* p, DiscoveryFilter& filter,
     HostApplication ha(p->flow->server_port, proto, service, false);
     //coverity[y2k38_safety]
     ha.last_seen = (uint32_t) packet_time();
-    logger.log(RNA_EVENT_CHANGE, CHANGE_BANNER_UPDATE, p, &rt,
+    logger.log(RNA_EVENT_CHANGE, CHANGE_BANNER_UPDATE, p, rt,
         (const struct in6_addr*) p->flow->server_ip.get_ip6_ptr(),
         rt->get_last_seen_mac(mac_addr), &ha);
 }
@@ -382,7 +382,7 @@ void RnaAppDiscovery::discover_client(const Packet* p, DiscoveryFilter& filter,
     bool is_new = false;
     auto hc = rt->find_or_add_client(client, version, service, is_new);
     if ( is_new )
-        logger.log(RNA_EVENT_NEW, NEW_CLIENT_APP, p, &rt,
+        logger.log(RNA_EVENT_NEW, NEW_CLIENT_APP, p, rt,
             (const struct in6_addr*) p->flow->client_ip.get_ip6_ptr(), mac, &hc);
 }
 
@@ -400,7 +400,7 @@ void RnaAppDiscovery::discover_user(const Packet* p, DiscoveryFilter& filter, RN
             conf ? conf->max_host_services : 0, login_success) )
     {
         logger.log(RUA_EVENT, login_success ? CHANGE_USER_LOGIN : FAILED_USER_LOGIN,
-            p, &rt, (const struct in6_addr*) p->ptrs.ip_api.get_dst()->get_ip6_ptr(),
+            p, rt, (const struct in6_addr*) p->ptrs.ip_api.get_dst()->get_ip6_ptr(),
             username, service, packet_time());
     }
 }
@@ -419,7 +419,7 @@ void RnaAppDiscovery::discover_netbios_name(const snort::Packet* p, DiscoveryFil
         const uint8_t* src_mac = layer::get_eth_layer(p)->ether_src;
 
         logger.log(RNA_EVENT_CHANGE, CHANGE_NETBIOS_NAME, src_ip_ptr, src_mac,
-            &rt, p, packet_time(), 0, nullptr, nullptr, nullptr, nullptr, nullptr,
+            rt, p, packet_time(), 0, nullptr, nullptr, nullptr, nullptr, nullptr,
             nullptr, APP_ID_NONE, nullptr, false, 0, 0, nullptr, nb_name);
     }
 }
@@ -445,7 +445,7 @@ void RnaAppDiscovery::analyze_user_agent_fingerprint(const Packet* p, DiscoveryF
     if ( uafp and rt->add_ua_fingerprint(uafp->fpid, uafp->fp_type, jail_broken,
         device_info, MAX_USER_AGENT_DEVICES) )
     {
-        logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt,
+        logger.log(RNA_EVENT_NEW, NEW_OS, p, rt,
             (const struct in6_addr*)p->flow->client_ip.get_ip6_ptr(),
             rt->get_last_seen_mac(mac_addr), (FpFingerprint*)uafp, packet_time(),
             device_info, jail_broken);
index c1a4876f80cd175a562cf8cd15caedd4151aaba0..2671b393f1a21298a6e39b0dedf431be08fa4509 100644 (file)
@@ -151,28 +151,28 @@ static inline void rna_logger_message(const RnaLoggerEvent& rle, const Packet* p
 }
 #endif
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
    const struct in6_addr* src_ip, const uint8_t* src_mac, const HostApplication* ha)
 {
     log(type, subtype, src_ip, src_mac, ht, p, 0, 0,
         nullptr, ha);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
    const struct in6_addr* ip, const char* user, AppId appid, time_t event_time)
 {
     log(type, subtype, ip, nullptr, ht, p, event_time, 0,
         nullptr, nullptr, nullptr, nullptr, nullptr, user, appid);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
        const struct in6_addr* src_ip, const uint8_t* src_mac, const HostClient* hc)
 {
     log(type, subtype, src_ip, src_mac, ht, p, 0, 0,
         nullptr, nullptr, nullptr, nullptr, hc);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
     const struct in6_addr* src_ip, const uint8_t* src_mac, const FpFingerprint* fp,
     time_t event_time, const char* device_info, bool jail_broken)
 {
@@ -180,32 +180,32 @@ void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker
         fp, nullptr, nullptr, nullptr, APP_ID_NONE, device_info, jail_broken);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
     const struct in6_addr* src_ip, const uint8_t* src_mac, time_t event_time)
 {
     log(type, subtype, src_ip, src_mac, ht, p, event_time);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
     const struct in6_addr* src_ip, const uint8_t* src_mac, const HostMac* hm, time_t event_time)
 {
     log(type, subtype, src_ip, src_mac, ht, p, event_time, 0, hm);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, RnaTracker& ht,
     uint16_t proto, const uint8_t* src_mac, const struct in6_addr* src_ip, time_t event_time)
 {
     log(type, subtype, src_ip, src_mac, ht, p, event_time, proto);
 }
 
 void RnaLogger::log(uint16_t type, uint16_t subtype, const Packet* p, const uint8_t* src_mac,
-    const struct in6_addr* src_ip, RnaTracker* ht, time_t event_time, void* cond_var)
+    const struct in6_addr* src_ip, RnaTracker& ht, time_t event_time, void* cond_var)
 {
     log(type, subtype, src_ip, src_mac, ht, p, event_time, 0,
         nullptr, nullptr, nullptr, cond_var);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
     const struct in6_addr* src_ip, const uint8_t* src_mac, uint32_t lease, uint32_t netmask,
     const struct in6_addr* router)
 {
@@ -213,7 +213,7 @@ void RnaLogger::log(uint16_t type, uint16_t subtype, const snort::Packet* p, Rna
         nullptr, nullptr, APP_ID_NONE, nullptr, false, lease, netmask, router);
 }
 
-void RnaLogger::log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+void RnaLogger::log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
     const struct in6_addr* src_ip, const uint8_t* src_mac, const FpFingerprint* fp,
     const vector<const char*>* cpeos, time_t event_time)
 {
@@ -223,7 +223,7 @@ void RnaLogger::log(uint16_t type, uint16_t subtype, const snort::Packet* p, Rna
 }
 
 bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_ip,
-    const uint8_t* src_mac, RnaTracker* ht, const Packet* p, time_t event_time,
+    const uint8_t* src_mac, RnaTracker& ht, const Packet* p, time_t event_time,
     uint16_t proto, const HostMac* hm, const HostApplication* ha,
     const FpFingerprint* fp, void* cond_var, const HostClient* hc,
     const char* user, AppId appid, const char* di, bool jb, uint32_t lease,
@@ -233,8 +233,6 @@ bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_
     if ( !enabled )
         return false;
 
-    assert(ht);
-
     RnaLoggerEvent rle(type, subtype, src_mac, ht, hm, proto, cond_var,
         ha, fp, hc, user, appid, di, jb, lease, netmask, router, p, nb_name, cpeos);
     if ( src_ip and (!IN6_IS_ADDR_V4MAPPED(src_ip) or src_ip->s6_addr32[3]) )
@@ -247,7 +245,7 @@ bool RnaLogger::log(uint16_t type, uint16_t subtype, const struct in6_addr* src_
         //coverity[y2k38_safety]
         rle.event_time = (uint32_t)event_time;
         //coverity[y2k38_safety]
-        (*ht)->update_last_event(event_time);
+        ht->update_last_event(event_time);
     }
 
     EventManager::call_loggers(nullptr, const_cast<Packet*>(p), "RNA", &rle);
@@ -267,11 +265,11 @@ TEST_CASE("RNA logger", "[rna_logger]")
         RnaTracker ht;
         uint8_t mac[6] = {0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6};
         RnaLogger logger1(false);
-        CHECK(false == logger1.log(0, 0, nullptr, mac, &ht, nullptr, 0, 0,
+        CHECK(false == logger1.log(0, 0, nullptr, mac, ht, nullptr, 0, 0,
             nullptr, nullptr, nullptr, nullptr, nullptr));
 
         RnaLogger logger2(true);
-        CHECK(true == logger2.log(0, 0, nullptr, mac, &ht, nullptr, 0, 0,
+        CHECK(true == logger2.log(0, 0, nullptr, mac, ht, nullptr, 0, 0,
             nullptr, nullptr, nullptr, nullptr, nullptr));
     }
 }
index 57e8390c86b5296282077b4d0cc68e9d7c8ed067..5bb6939630cdde005cd34d253206617f0296750a 100644 (file)
@@ -37,53 +37,53 @@ public:
     RnaLogger(const bool enable) : enabled(enable) { }
 
     // for host application
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::HostApplication* ha);
 
     // for host client
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::HostClient* hcp);
 
     // for host user
-    void log(uint16_t type, uint16_t subtype, const snort::Packet*, RnaTracker*,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet*, RnaTracker&,
         const struct in6_addr*, const char* user, AppId appid, time_t event_time);
 
     // for cpe os info event
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::FpFingerprint* fp,
         const std::vector<const char*>* cpeos, time_t event_time);
 
     // for fingerprint
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac, const snort::FpFingerprint* fp,
         time_t event_time, const char* device_info = nullptr, bool jail_broken = false);
 
     // for event time
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac, time_t event_time);
 
     // for mac event
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac,
         const snort::HostMac* hm = nullptr, time_t event_time = 0);
 
     // for protocol event
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         uint16_t proto, const uint8_t* mac, const struct in6_addr* ip = nullptr,
         time_t event_time = 0);
 
     // for timeout update
     void log(uint16_t type, uint16_t subtype, const snort::Packet* p, const uint8_t* src_mac,
-        const struct in6_addr* src_ip, RnaTracker* ht, time_t event_time, void* cond_var);
+        const struct in6_addr* src_ip, RnaTracker& ht, time_t event_time, void* cond_var);
 
     // for dhcp info event
-    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker* ht,
+    void log(uint16_t type, uint16_t subtype, const snort::Packet* p, RnaTracker& ht,
         const struct in6_addr* src_ip, const uint8_t* src_mac, uint32_t lease, uint32_t netmask,
         const struct in6_addr* router);
 
     // for all
     bool log(uint16_t type, uint16_t subtype, const struct in6_addr* src_ip,
-        const uint8_t* src_mac, RnaTracker* ht, const snort::Packet* p = nullptr,
+        const uint8_t* src_mac, RnaTracker& ht, const snort::Packet* p = nullptr,
         time_t event_time = 0, uint16_t proto = 0, const snort::HostMac* hm = nullptr,
         const snort::HostApplication* ha = nullptr, const snort::FpFingerprint* fp = nullptr,
         void* cond_var = nullptr, const snort::HostClient* hc = nullptr,
index 237c3392bbe9d460eb66ce303108be8d08285315..c70d67d4f0b1f5f465832c459fa967270b50d4a6 100644 (file)
@@ -34,7 +34,7 @@ class FpFingerprint;
 
 struct RnaLoggerEvent : public Event
 {
-    RnaLoggerEvent (uint16_t t, uint16_t st, const uint8_t* mc, const RnaTracker* rt,
+    RnaLoggerEvent (uint16_t t, uint16_t st, const uint8_t* mc, const RnaTracker& rt,
         const snort::HostMac* hmp, uint16_t pr, void* cv, const snort::HostApplication* hap,
         const snort::FpFingerprint* fpr, const snort::HostClient* hcp, const char* u,
         int32_t app, const char* di, bool jb, uint32_t ls, uint32_t nm,
@@ -50,7 +50,7 @@ struct RnaLoggerEvent : public Event
     uint16_t subtype;
     const struct in6_addr* ip = nullptr;
     const uint8_t* mac;
-    const RnaTracker* ht;
+    const RnaTracker& ht;
     const snort::HostMac* hm;
     uint16_t proto;
     void* cond_var;
index 3abb936a2cd3a5e3cedbb26159f2ed8f2a041a6a..8274bbd3ba7af08e4a15a40d2dd517dc89bb9219 100644 (file)
@@ -169,7 +169,7 @@ bool RnaPnd::analyze_cpe_os_info(snort::DataEvent& event)
     rt->update_last_seen();
     FpFingerprint fp = FpFingerprint();
     fp.fp_type = FpFingerprint::FpType::FP_TYPE_CPE;
-    logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt, src_ip_ptr, src_mac, &fp,
+    logger.log(RNA_EVENT_NEW, NEW_OS, p, rt, src_ip_ptr, src_mac, &fp,
         cpeos_event.get_os_names(), packet_time());
 
     return true;
@@ -222,7 +222,7 @@ void RnaPnd::analyze_netflow_host(NetFlowEvent* nfe)
     if ( new_host )
     {
         if ( nfe->get_create_host() )
-            logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht, src_ip_ptr, src_mac);
+            logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht, src_ip_ptr, src_mac);
         else
             return;
     }
@@ -232,17 +232,17 @@ void RnaPnd::analyze_netflow_host(NetFlowEvent* nfe)
     if ( ptype > to_utype(ProtocolId::ETHERTYPE_MINIMUM) )
     {
         if ( ht->add_network_proto(ptype) )
-            logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ptype, src_mac, src_ip_ptr,
+            logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, ht, ptype, src_mac, src_ip_ptr,
                 packet_time());
     }
 
     // Remaining fields (port, proto, etc.) are parsed from the NetFlow record
     ptype = nfe->get_record()->proto;
     if ( ht->add_xport_proto(ptype) )
-        logger.log(RNA_EVENT_NEW, NEW_XPORT_PROTOCOL, p, &ht, ptype, src_mac, src_ip_ptr,
+        logger.log(RNA_EVENT_NEW, NEW_XPORT_PROTOCOL, p, ht, ptype, src_mac, src_ip_ptr,
             packet_time());
     if ( !new_host )
-        generate_change_host_update(&ht, p, &src_ip, src_mac, packet_time());
+        generate_change_host_update(ht, p, &src_ip, src_mac, packet_time());
 }
 
 void RnaPnd::analyze_netflow_service(NetFlowEvent* nfe)
@@ -276,10 +276,10 @@ void RnaPnd::analyze_netflow_service(NetFlowEvent* nfe)
     if ( is_new )
     {
         if ( proto == IpProtocol::TCP )
-            logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, &ht,
+            logger.log(RNA_EVENT_NEW, NEW_TCP_SERVICE, p, ht,
                 (const struct in6_addr*) src_ip.get_ip6_ptr(), mac_addr, &ha);
         else if ( proto == IpProtocol::UDP )
-            logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, &ht,
+            logger.log(RNA_EVENT_NEW, NEW_UDP_SERVICE, p, ht,
                 (const struct in6_addr*) src_ip.get_ip6_ptr(), mac_addr, &ha);
 
         ha.hits = 0;
@@ -353,23 +353,23 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl)
     }
 
     if ( new_host )
-        logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht, src_ip_ptr, src_mac);
+        logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht, src_ip_ptr, src_mac);
 
     if ( new_mac and !new_host )
     {
         HostMac hm;
-        logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_ADD, p, &ht, src_ip_ptr, src_mac,
+        logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_ADD, p, ht, src_ip_ptr, src_mac,
             ht->get_hostmac(src_mac, hm) ? &hm : nullptr, packet_time());
     }
 
     if ( ht->update_mac_ttl(src_mac, ttl) )
     {
         HostMac hm;
-        logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, &ht, src_ip_ptr, src_mac,
+        logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, ht, src_ip_ptr, src_mac,
             ht->get_hostmac(src_mac, hm) ? &hm : nullptr, packet_time());
 
         if ( ht->reset_hops_if_primary() )
-            logger.log(RNA_EVENT_CHANGE, CHANGE_HOPS, p, &ht, src_ip_ptr, src_mac, packet_time());
+            logger.log(RNA_EVENT_CHANGE, CHANGE_HOPS, p, ht, src_ip_ptr, src_mac, packet_time());
     }
 
     if ( p->is_tcp() and ht->get_host_type() == HOST_TYPE_HOST )
@@ -379,17 +379,17 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl)
     if ( ptype > to_utype(ProtocolId::ETHERTYPE_MINIMUM) )
     {
         if ( ht->add_network_proto(ptype) )
-            logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ptype, src_mac, src_ip_ptr,
+            logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, ht, ptype, src_mac, src_ip_ptr,
                 packet_time());
     }
 
     ptype = to_utype(p->get_ip_proto_next());
     if ( ht->add_xport_proto(ptype) )
-        logger.log(RNA_EVENT_NEW, NEW_XPORT_PROTOCOL, p, &ht, ptype, src_mac, src_ip_ptr,
+        logger.log(RNA_EVENT_NEW, NEW_XPORT_PROTOCOL, p, ht, ptype, src_mac, src_ip_ptr,
             packet_time());
 
     if ( !new_host )
-        generate_change_host_update(&ht, p, src_ip, src_mac, packet_time());
+        generate_change_host_update(ht, p, src_ip, src_mac, packet_time());
 
     discover_host_types_icmpv6_ndp(ht, p, last_seen, src_ip_ptr, src_mac);
 
@@ -402,7 +402,7 @@ void RnaPnd::discover_network(const Packet* p, uint8_t ttl)
         const TcpFingerprint* tfp = processor->get(p, rna_flow);
 
         if ( tfp and ht->add_tcp_fingerprint(tfp->fpid) )
-            logger.log(RNA_EVENT_NEW, NEW_OS, p, &ht, src_ip_ptr, src_mac, tfp, packet_time());
+            logger.log(RNA_EVENT_NEW, NEW_OS, p, ht, src_ip_ptr, src_mac, tfp, packet_time());
     }
 }
 
@@ -426,7 +426,7 @@ void RnaPnd::analyze_dhcp_fingerprint(DataEvent& event)
     if (new_mac)
     {
         ht->add_mac(mk.mac_addr, p->ptrs.ip_api.ttl(), 0);
-        logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht, nullptr, mk.mac_addr);
+        logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht, nullptr, mk.mac_addr);
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
     }
     else
@@ -446,7 +446,7 @@ void RnaPnd::analyze_dhcp_fingerprint(DataEvent& event)
     if (dhcp_fp and ht->add_udp_fingerprint(dhcp_fp->fpid))
     {
         const auto& src_ip_ptr = (const struct in6_addr*) src_ip->get_ip6_ptr();
-        logger.log(RNA_EVENT_NEW, NEW_OS, p, &ht, src_ip_ptr, src_mac, dhcp_fp, packet_time());
+        logger.log(RNA_EVENT_NEW, NEW_OS, p, ht, src_ip_ptr, src_mac, dhcp_fp, packet_time());
     }
 }
 
@@ -478,13 +478,13 @@ void RnaPnd::add_dhcp_info(DataEvent& event)
     if (new_mac)
     {
         ht->add_mac(mk.mac_addr, p->ptrs.ip_api.ttl(), 0);
-        logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht, nullptr, mk.mac_addr);
+        logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht, nullptr, mk.mac_addr);
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
     }
     else
         hm_ptr->update_last_seen(p->pkth->ts.tv_sec);
 
-    logger.log(RNA_EVENT_CHANGE, CHANGE_FULL_DHCP_INFO, p, &ht,
+    logger.log(RNA_EVENT_CHANGE, CHANGE_FULL_DHCP_INFO, p, ht,
         (const struct in6_addr*) leased_ip.get_ip6_ptr(), src_mac,
         lease, net_mask, (const struct in6_addr*) router_ip.get_ip6_ptr());
 }
@@ -517,7 +517,7 @@ void RnaPnd::analyze_smb_fingerprint(DataEvent& event)
         const auto& src_ip_ptr = (const struct in6_addr*) src_ip->get_ip6_ptr();
         const auto& src_mac = layer::get_eth_layer(p)->ether_src;
 
-        logger.log(RNA_EVENT_NEW, NEW_OS, p, &rt, src_ip_ptr, src_mac, fp, packet_time());
+        logger.log(RNA_EVENT_NEW, NEW_OS, p, rt, src_ip_ptr, src_mac, fp, packet_time());
     }
 }
 
@@ -532,7 +532,7 @@ inline void RnaPnd::update_vlan(const Packet* p, HostTrackerMac& hm)
         hm.update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto);
 }
 
-void RnaPnd::generate_change_vlan_update(RnaTracker *rt, const Packet* p,
+void RnaPnd::generate_change_vlan_update(RnaTrackerrt, const Packet* p,
     const uint8_t* src_mac, HostTrackerMac& hm, bool isnew)
 {
     if ( !(p->proto_bits & PROTO_BIT__VLAN) )
@@ -548,12 +548,12 @@ void RnaPnd::generate_change_vlan_update(RnaTracker *rt, const Packet* p,
         if ( !isnew )
             update_vlan(p, hm);
 
-        rt->get()->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto);
+        rt->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto);
         logger.log(RNA_EVENT_CHANGE, CHANGE_VLAN_TAG, p, rt, nullptr, src_mac, packet_time());
     }
 }
 
-void RnaPnd::generate_change_vlan_update(RnaTracker *rt, const Packet* p,
+void RnaPnd::generate_change_vlan_update(RnaTrackerrt, const Packet* p,
     const uint8_t* src_mac, const SfIp* src_ip, bool isnew)
 {
     if ( !(p->proto_bits & PROTO_BIT__VLAN) )
@@ -563,22 +563,22 @@ void RnaPnd::generate_change_vlan_update(RnaTracker *rt, const Packet* p,
     if ( !vh )
         return;
 
-    if ( isnew or !rt->get()->has_same_vlan(vh->vth_pri_cfi_vlan) )
+    if ( isnew or !rt->has_same_vlan(vh->vth_pri_cfi_vlan) )
     {
-        rt->get()->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto);
+        rt->update_vlan(vh->vth_pri_cfi_vlan, vh->vth_proto);
         logger.log(RNA_EVENT_CHANGE, CHANGE_VLAN_TAG, p, rt,
             (const struct in6_addr*) src_ip->get_ip6_ptr(), src_mac, packet_time());
     }
 }
 
-void RnaPnd::generate_change_host_update(RnaTracker* ht, const Packet* p,
+void RnaPnd::generate_change_host_update(RnaTracker& ht, const Packet* p,
     const SfIp* src_ip, const uint8_t* src_mac, const time_t& sec)
 {
     if ( !ht or !update_timeout )
         return;
 
-    uint32_t last_seen = (*ht)->get_last_seen();
-    uint32_t last_event = (*ht)->get_last_event();
+    uint32_t last_seen = ht->get_last_seen();
+    uint32_t last_event = ht->get_last_event();
     time_t timestamp = sec - update_timeout;
     if ( last_seen > last_event and (time_t) last_event + update_timeout <= sec )
         logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_UPDATE, p, src_mac,
@@ -610,7 +610,8 @@ void RnaPnd::generate_change_host_update_eth(HostTrackerMac* mt, const Packet* p
     if ( last_seen > last_event and (time_t) last_event + update_timeout <= sec )
     {
         logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_UPDATE, p, src_mac, nullptr,
-            &rt, last_seen, (void*) &timestamp);
+            rt, last_seen, (void*) &timestamp);
+
         //coverity[y2k38_safety]
         mt->update_last_event(sec);
     }
@@ -627,7 +628,7 @@ void RnaPnd::generate_change_host_update()
     auto sec = time(nullptr);
 
     for ( auto & h : hosts )
-        generate_change_host_update(&h.second, nullptr, &h.first, nullptr, sec);
+        generate_change_host_update(h.second, nullptr, &h.first, nullptr, sec);
 
     for ( auto & m : mac_hosts)
         generate_change_host_update_eth(m.second.get(), nullptr,
@@ -652,15 +653,15 @@ void RnaPnd::generate_new_host_mac(const Packet* p, RnaTracker ht, bool discover
         ht.get()->update_last_seen();
         ht.get()->add_mac(mk.mac_addr, 0, 0);
 
-        logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht, nullptr, mk.mac_addr);
+        logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht, nullptr, mk.mac_addr);
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
-        generate_change_vlan_update(&ht, p, mk.mac_addr, *hm_ptr, true);
+        generate_change_vlan_update(ht, p, mk.mac_addr, *hm_ptr, true);
     }
     else
     {
         generate_change_host_update_eth(hm_ptr.get(), p, mk.mac_addr, packet_time());
         hm_ptr->update_last_seen(p->pkth->ts.tv_sec);
-        generate_change_vlan_update(&ht, p, mk.mac_addr, *hm_ptr, false);
+        generate_change_vlan_update(ht, p, mk.mac_addr, *hm_ptr, false);
     }
 
     if ( discover_proto )
@@ -670,7 +671,7 @@ void RnaPnd::generate_new_host_mac(const Packet* p, RnaTracker ht, bool discover
         {
             if ( hm_ptr->add_network_proto(ntype) )
             {
-                logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ntype, mk.mac_addr);
+                logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, ht, ntype, mk.mac_addr);
                 hm_ptr->update_last_event(p->pkth->ts.tv_sec);
             }
         }
@@ -682,7 +683,7 @@ void RnaPnd::generate_new_host_mac(const Packet* p, RnaTracker ht, bool discover
                 ntype = ((const RNA_LLC*) lyr.start)->s.proto;
                 if ( hm_ptr->add_network_proto(ntype) )
                 {
-                    logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ntype, mk.mac_addr);
+                    logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, ht, ntype, mk.mac_addr);
                     hm_ptr->update_last_event(p->pkth->ts.tv_sec);
                 }
             }
@@ -703,7 +704,7 @@ void RnaPnd::discover_network_ethernet(const Packet* p)
     RnaTracker rt = std::make_shared<snort::HostTracker>();
 
     if ( layer::get_arp_layer(p) )
-        retval = discover_network_arp(p, &rt);
+        retval = discover_network_arp(p, rt);
     else
     {
         // If we have an inner LLC layer, grab it
@@ -749,7 +750,7 @@ void RnaPnd::discover_network_ethernet(const Packet* p)
     return;
 }
 
-int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref)
+int RnaPnd::discover_network_arp(const Packet* p, RnaTracker& ht_ref)
 {
     MacKey mk(layer::get_eth_layer(p)->ether_src);
     const auto& src_mac = mk.mac_addr;
@@ -784,13 +785,13 @@ int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref)
     if ( !new_host_mac )
         hm_ptr->update_last_seen(p->pkth->ts.tv_sec);
 
-    *ht_ref = ht;
+    ht_ref = ht;
 
     if( new_host )
     {
         ht->update_hops(255);
         ht->add_mac(src_mac, 0, 0);
-        logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht,
+        logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht,
             (const struct in6_addr*) spa.get_ip6_ptr(), src_mac);
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
     }
@@ -815,12 +816,12 @@ int RnaPnd::discover_network_arp(const Packet* p, RnaTracker* ht_ref)
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
     }
 
-    generate_change_vlan_update(&ht, p, src_mac, &spa, true);
+    generate_change_vlan_update(ht, p, src_mac, &spa, true);
     auto ntype = to_utype(ProtocolId::ETHERTYPE_ARP);
 
     if ( hm_ptr->add_network_proto(ntype) )
     {
-        logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, &ht, ntype, src_mac);
+        logger.log(RNA_EVENT_NEW, NEW_NET_PROTOCOL, p, ht, ntype, src_mac);
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
     }
 
@@ -871,19 +872,19 @@ int RnaPnd::discover_switch(const Packet* p, RnaTracker& ht_ref)
 
         hm_ptr->update_last_event(p->pkth->ts.tv_sec);
 
-        ht_ref.get()->update_last_seen();
-        ht_ref.get()->add_mac(mk.mac_addr, 0, 1);
+        ht_ref->update_last_seen();
+        ht_ref->add_mac(mk.mac_addr, 0, 1);
 
-        logger.log(RNA_EVENT_NEW, NEW_HOST, p, &ht_ref,
+        logger.log(RNA_EVENT_NEW, NEW_HOST, p, ht_ref,
             (const struct in6_addr*) nullptr, mk.mac_addr);
 
-        generate_change_vlan_update(&ht_ref, p, mk.mac_addr, *hm_ptr, true);
+        generate_change_vlan_update(ht_ref, p, mk.mac_addr, *hm_ptr, true);
     }
     else
     {
         hm_ptr->update_last_seen(p->pkth->ts.tv_sec);
         generate_change_host_update_eth(hm_ptr.get(), p, mk.mac_addr, packet_time());
-        generate_change_vlan_update(&ht_ref, p, mk.mac_addr, *hm_ptr, false);
+        generate_change_vlan_update(ht_ref, p, mk.mac_addr, *hm_ptr, false);
     }
 
     return 0;
@@ -907,7 +908,7 @@ void RnaPnd::discover_host_types_ttl(RnaTracker& ht, const Packet *p, uint8_t pk
                     if ( ht_last_seen - ht->get_nat_count_start() <= RNA_NAT_TIMEOUT_THRESHOLD )
                     {
                         ht->set_host_type(p->is_from_application_client() ? HOST_TYPE_NAT : HOST_TYPE_LB);
-                        logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_TYPE, p, &ht, src_ip, src_mac);
+                        logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_TYPE, p, ht, src_ip, src_mac);
                     }
 
                     ht->set_nat_count_start(ht_last_seen);
@@ -1021,7 +1022,7 @@ int RnaPnd::discover_network_cdp(const Packet* p, const uint8_t* data, uint16_t
             else
                 ht->set_host_type(HOST_TYPE_BRIDGE);
 
-            logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_TYPE, p, &ht,
+            logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_TYPE, p, ht,
                 (const struct in6_addr*)cdp_ip.get_ip6_ptr(), layer::get_eth_layer(p)->ether_src);
         }
     }
@@ -1105,14 +1106,14 @@ int RnaPnd::discover_host_types_icmpv6_ndp(RnaTracker& ht, const Packet* p, uint
         if ( host_type != HOST_TYPE_ROUTER and host_type != HOST_TYPE_BRIDGE )
         {
             ht->set_host_type(HOST_TYPE_ROUTER);
-            logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_TYPE, p, &ht, src_ip, neighbor_src_mac);
+            logger.log(RNA_EVENT_CHANGE, CHANGE_HOST_TYPE, p, ht, src_ip, neighbor_src_mac);
         }
     }
 
     if ( ht->make_primary(src_mac) )
     {
         HostMac hm;
-        logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, &ht,
+        logger.log(RNA_EVENT_CHANGE, CHANGE_MAC_INFO, p, ht,
             src_ip, src_mac, ht->get_hostmac(src_mac, hm) ? &hm : nullptr, last_seen);
     }
 
index 17c3b3cd9131ef13b00f25e865274a636981b683..c7c152dcf9c46dab201a3358b2e746556a27931d 100644 (file)
@@ -143,7 +143,7 @@ public:
 
 private:
     // generate change event for single host
-    void generate_change_host_update(RnaTracker*, const snort::Packet*,
+    void generate_change_host_update(RnaTracker&, const snort::Packet*,
         const snort::SfIp*, const uint8_t* src_mac, const time_t&);
     void generate_change_host_update_eth(HostTrackerMac*, const snort::Packet*,
         const uint8_t* src_mac, const time_t&);
@@ -155,9 +155,9 @@ private:
 
     // Change vlan event related utilities
     inline void update_vlan(const snort::Packet*, HostTrackerMac&);
-    void generate_change_vlan_update(RnaTracker*, const snort::Packet*,
+    void generate_change_vlan_update(RnaTracker&, const snort::Packet*,
         const uint8_t* src_mac, HostTrackerMac&, bool isnew);
-    void generate_change_vlan_update(RnaTracker*, const snort::Packet*,
+    void generate_change_vlan_update(RnaTracker&, const snort::Packet*,
         const uint8_t* src_mac, const snort::SfIp*, bool isnew);
 
     void generate_new_host_mac(const snort::Packet*, RnaTracker, bool discover_proto = false);
@@ -172,7 +172,7 @@ private:
 
     // RNA utilities for non-IP packets
     void discover_network_ethernet(const snort::Packet*);
-    int discover_network_arp(const snort::Packet*, RnaTracker*);
+    int discover_network_arp(const snort::Packet*, RnaTracker&);
     int discover_network_bpdu(const snort::Packet*, const uint8_t* data, RnaTracker&);
     int discover_network_cdp(const snort::Packet*, const uint8_t* data, uint16_t rlen,
         RnaTracker&);
index 3b0c55826e8b05739943f8f5b3be9c6740cee41a..d9992e852ba32f06bd455f318297c923ec89df25 100644 (file)
@@ -230,6 +230,7 @@ IpsContext::IpsContext(unsigned) { }
 NetworkPolicy* get_network_policy() { return nullptr; }
 InspectionPolicy* get_inspection_policy() { return nullptr; }
 Flow::~Flow() = default;
+FlowDataStore::~FlowDataStore() = default;
 bool Flow::handle_allowlist() { return true; }
 void ThreadConfig::implement_thread_affinity(SThreadType, unsigned) { }
 void ThreadConfig::apply_thread_policy(SThreadType , unsigned ) { }
index 3054ae0272242e77ddd95a315f6ec6f5ec9ef7c7..9e33422d75d00794f91c2999b83268b943eb9d8b 100644 (file)
@@ -247,14 +247,14 @@ bool get_so_stub(const char* in, std::string& stub)
 //--------------------------------------------------------------------------
 
 #ifdef UNIT_TEST
-struct TestCase
+struct ParseSOTestCase
 {
     const char* rule;
     const char* expect;
     bool result;
 };
 
-static const TestCase syntax_tests[] =
+static const ParseSOTestCase syntax_tests[] =
 {
     { "alert()", "alert()", true },
     { " alert() ", "alert()", true },
@@ -287,7 +287,7 @@ static const TestCase syntax_tests[] =
     { nullptr, nullptr, false }
 };
 
-static const TestCase basic_tests[] =
+static const ParseSOTestCase basic_tests[] =
 {
     { "alert( sid:1; )", "alert( sid:1; )", true },
 
@@ -306,7 +306,7 @@ static const TestCase basic_tests[] =
 };
 
 // __STRDUMP_DISABLE__
-static const TestCase stub_tests[] =
+static const ParseSOTestCase stub_tests[] =
 {
     { "alert( id:0; )", "alert( )", true },
     { "alert( sid:1; id:0; )", "alert( sid:1; )", true },
@@ -337,7 +337,7 @@ static const TestCase stub_tests[] =
 
 TEST_CASE("parse_so_rule.syntax", "[parser]")
 {
-    const TestCase* tc = syntax_tests;
+    const ParseSOTestCase* tc = syntax_tests;
 
     while ( tc->rule )
     {
@@ -353,7 +353,7 @@ TEST_CASE("parse_so_rule.syntax", "[parser]")
 
 TEST_CASE("parse_so_rule.basic", "[parser]")
 {
-    const TestCase* tc = basic_tests;
+    const ParseSOTestCase* tc = basic_tests;
 
     while ( tc->rule )
     {
@@ -369,7 +369,7 @@ TEST_CASE("parse_so_rule.basic", "[parser]")
 
 TEST_CASE("get_so_stub", "[parser]")
 {
-    const TestCase* tc = stub_tests;
+    const ParseSOTestCase* tc = stub_tests;
 
     while ( tc->rule )
     {
index 0aa68424e7905dfc95209bc4f0caa0ccbc78895b..2fc5f51ee930fba10bc3111759d7ae7e26dc96e8 100644 (file)
@@ -89,6 +89,7 @@ Packet::~Packet() = default;
 int DetectionEngine::queue_event(unsigned int, unsigned int) { return 0; }
 FlowData::~FlowData() = default;
 FlowData::FlowData(unsigned int, snort::Inspector*) { }
+FlowDataStore::~FlowDataStore() = default;
 
 // Inspector mocks, used by MockInspector class
 InspectApi mock_api;
@@ -133,7 +134,7 @@ InjectionReturnStatus PayloadInjector::get_http2_payload(InjectionControl,
     return translation_status;
 }
 
-// Mocks for snort::Flow::get_flow_data
+// Mocks for snort::FlowDataStore::get
 
 unsigned Http2FlowData::inspector_id = 0;
 Http2Stream::~Http2Stream() = default;
@@ -155,7 +156,8 @@ Http2FlowData::~Http2FlowData() = default;
 Http2FlowData http2_flow_data(nullptr);
 void Http2FlowData::set_mid_frame(bool val) { continuation_expected[SRC_SERVER] = val; }
 bool Http2FlowData::is_mid_frame() const { return continuation_expected[SRC_SERVER]; }
-FlowData* snort::Flow::get_flow_data(unsigned int) const { return &http2_flow_data; }
+FlowData* FlowDataStore::get(unsigned) const
+{ return &http2_flow_data; }
 
 TEST_GROUP(payload_injector_test)
 {
index 0a602ca3d9a4dd28382e7205b785b75a69c776b8..cc81933a4cf897b94846f2e17c68b6d483b958d5 100644 (file)
@@ -120,17 +120,17 @@ static const ProfilerSorter<View> sorters[] =
     {
         "allocations",
         [](const View& lhs, const View& rhs)
-        { return lhs.allocs() >= rhs.allocs(); }
+        { return lhs.allocs() > rhs.allocs(); }
     },
     {
         "total_used",
         [](const View& lhs, const View& rhs)
-        { return lhs.total() >= rhs.total(); }
+        { return lhs.total() > rhs.total(); }
     },
     {
         "avg_allocation",
         [](const View& lhs, const View& rhs)
-        { return lhs.avg_alloc() >= rhs.avg_alloc(); }
+        { return lhs.avg_alloc() > rhs.avg_alloc(); }
     },
 };
 
index c9ecd87a6384f6386a4f07e214fe97def7cf50ae..3ca8f3c9c1a0b91c608242b5fa194d7ee43d67d8 100644 (file)
@@ -74,37 +74,37 @@ static const ProfilerSorter<View> sorters[] =
     {
         "checks",
         [](const View& lhs, const View& rhs)
-        { return lhs.checks() >= rhs.checks(); }
+        { return lhs.checks() > rhs.checks(); }
     },
     {
         "avg_check",
         [](const View& lhs, const View& rhs)
-        { return lhs.avg_check() >= rhs.avg_check(); }
+        { return lhs.avg_check() > rhs.avg_check(); }
     },
     {
         "total_time",
         [](const View& lhs, const View& rhs)
-        { return TO_TICKS(lhs.elapsed()) >= TO_TICKS(rhs.elapsed()); }
+        { return TO_TICKS(lhs.elapsed()) > TO_TICKS(rhs.elapsed()); }
     },
     {
         "matches",
         [](const View& lhs, const View& rhs)
-        { return lhs.matches() >= rhs.matches(); }
+        { return lhs.matches() > rhs.matches(); }
     },
     {
         "no_matches",
         [](const View& lhs, const View& rhs)
-        { return lhs.no_matches() >= rhs.no_matches(); }
+        { return lhs.no_matches() > rhs.no_matches(); }
     },
     {
         "avg_match",
         [](const View& lhs, const View& rhs)
-        { return lhs.avg_match() >= rhs.avg_match(); }
+        { return lhs.avg_match() > rhs.avg_match(); }
     },
     {
         "avg_no_match",
         [](const View& lhs, const View& rhs)
-        { return lhs.avg_no_match() >= rhs.avg_no_match(); }
+        { return lhs.avg_no_match() > rhs.avg_no_match(); }
     }
 };
 
index 2d6de68c02ed1b554dfc84a1cfd0fc4996808cf2..bc45ffff4d408e939bcae15004b0176b6c0b7e11 100644 (file)
@@ -119,17 +119,17 @@ static const ProfilerSorter<View> sorters[] =
     {
         "checks",
         [](const View& lhs, const View& rhs)
-        { return lhs.checks() >= rhs.checks(); }
+        { return lhs.checks() > rhs.checks(); }
     },
     {
         "avg_check",
         [](const View& lhs, const View& rhs)
-        { return lhs.avg_check() >= rhs.avg_check(); }
+        { return lhs.avg_check() > rhs.avg_check(); }
     },
     {
         "total_time",
         [](const View& lhs, const View& rhs)
-        { return lhs.elapsed() >= rhs.elapsed(); }
+        { return lhs.elapsed() > rhs.elapsed(); }
     }
 };
 
diff --git a/src/pub_sub/stash_events.h b/src/pub_sub/stash_events.h
deleted file mode 100644 (file)
index d3ddb56..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2019-2025 Cisco and/or its affiliates. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation.  You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
-//--------------------------------------------------------------------------
-// stash_events.h author Silviu Minut <sminut@cisco.com>
-
-#ifndef STASH_EVENTS_H
-#define STASH_EVENTS_H
-
-#include "framework/data_bus.h"
-
-using snort::StashItem;
-
-class StashEvent : public snort::DataEvent
-{
-public:
-    StashEvent(const StashItem* it = nullptr) : item(it) {}
-    const StashItem* get_item() const { return item; }
-private:
-    const StashItem* item;
-};
-
-#endif
index 25b7ad9eafb545a1306e4237505ccf360e4f5a63..fe54bbc5c1602db2f287e72c44e80e8f4f26d089 100644 (file)
@@ -44,12 +44,13 @@ using namespace HttpEnums;
 namespace snort
 {
 unsigned FlowData::flow_data_id = 0;
-FlowData::FlowData(unsigned, Inspector*) : next(nullptr), prev(nullptr), handler(nullptr), id(0)
+FlowData::FlowData(unsigned, Inspector*) : handler(nullptr), id(0)
 { }
 FlowData::~FlowData() = default;
-FlowData* Flow::get_flow_data(uint32_t) const { return nullptr; }
-int Flow::set_flow_data(FlowData*) { return 0; }
+FlowData* FlowDataStore::get(uint32_t) const { return nullptr; }
+void FlowDataStore::set(FlowData*) { }
 Flow::~Flow() = default;
+FlowDataStore::~FlowDataStore() = default;
 unsigned DataBus::get_id(PubKey const&) { return 0; }
 void DataBus::publish(unsigned int, unsigned int, DataEvent&, Flow*) { }
 int DetectionEngine::queue_event(unsigned int, unsigned int) { return 0; }
index 9e7e422d1e41a5e06115a50e0dafb4977e3cccc4..031d0b55c82c4bcedfe1e70c715638e2dcd6fae1 100644 (file)
@@ -49,7 +49,6 @@ static void free_cip_data(void* data);
 
 CipFlowData::CipFlowData() : FlowData(inspector_id)
 {
-    memset(&session, 0, sizeof(session));
     cip_stats.sessions++;
     cip_stats.concurrent_sessions++;
     if (cip_stats.max_concurrent_sessions < cip_stats.concurrent_sessions)
index cdb3d5645c98f8decfee2be142e0810060aa2375..53c98fda281f66e7ea7cc098d638275af57e5362 100644 (file)
@@ -95,7 +95,7 @@ public:
 
 public:
     static unsigned inspector_id;
-    CipSessionData session;
+    CipSessionData session = {};
 };
 
 CipSessionData* get_cip_session_data(const snort::Flow*);
index 1d029206ec58d188e854c9140797cc2619b65fca..28adbdf0a60e4da15421ec6f0b2390fd3896bdc0 100644 (file)
@@ -24,6 +24,7 @@
 #include "dns.h"
 
 #include <iomanip>
+#include <map>
 #include <sstream>
 #include <string>
 #include "sfip/sf_ip.h"
index e20be2174f328d66e92a3748891a7845b63cf95d..de672559df7a00b859355ed97ea73a07500b7417 100644 (file)
@@ -48,7 +48,6 @@ void GtpFlowData::init()
 
 GtpFlowData::GtpFlowData() : FlowData(inspector_id)
 {
-    memset(&ropts, 0, sizeof(ropts));
     gtp_stats.concurrent_sessions++;
     if(gtp_stats.max_concurrent_sessions < gtp_stats.concurrent_sessions)
         gtp_stats.max_concurrent_sessions = gtp_stats.concurrent_sessions;
index e668b756200ec489d157c61ce19e87907186350c..62bd1a425a9762519f5f2a1ea33c2b51699cdc8d 100644 (file)
@@ -45,7 +45,7 @@ public:
 
 public:
     static unsigned inspector_id;
-    GTP_Roptions ropts;
+    GTP_Roptions ropts = {};
 };
 
 namespace snort
index 4033673f18ac815be75d82f779e79f63262579b2..2f6ac57b5de9c72fe24d33ddd2f5e0c7057ba970 100644 (file)
@@ -89,9 +89,9 @@ void HttpMsgBody::publish(unsigned pub_id)
     // Publish entire request/response body limited dynamically
     int32_t should_publish_body = 0;
     if (is_request)
-        flow->stash->get(STASH_PUBLISH_REQUEST_BODY, should_publish_body);
+        flow->get_attr(STASH_PUBLISH_REQUEST_BODY, should_publish_body);
     else
-        flow->stash->get(STASH_PUBLISH_RESPONSE_BODY, should_publish_body);
+        flow->get_attr(STASH_PUBLISH_RESPONSE_BODY, should_publish_body);
 
     if (should_publish_body)
     {
@@ -103,7 +103,7 @@ void HttpMsgBody::publish(unsigned pub_id)
         {
             fprintf(HttpTestManager::get_output_file(),
                 "Published %" PRId32 " bytes of body. Originated from %s. last: %s\n",
-                publish_length, (is_request ? "client" : "server"), 
+                publish_length, (is_request ? "client" : "server"),
                 (last_piece ? "true" : "false"));
             fflush(HttpTestManager::get_output_file());
         }
@@ -122,8 +122,8 @@ void HttpMsgBody::publish(unsigned pub_id)
 
         // If it is not the last piece of the request, it should be marked as such because of REQUEST_PUBLISH_DEPTH limit:
         // if sum of already published octets (publish_octets) and current publishing length (request_publish_length)
-        // is greater than the request publish depth. 
-        auto request_last_piece = last_piece ? 
+        // is greater than the request publish depth.
+        auto request_last_piece = last_piece ?
             true : (publish_octets + request_publish_length >= REQUEST_PUBLISH_DEPTH);
 
         HttpRequestBodyEvent http_request_body_event(this, request_publish_length, publish_octets, request_last_piece, session_data);
index ef3d3afcfb7099ef299dd287bd9db7bc3a293343..162e232cf35b8935d58db8d699317d9db5edf26d 100755 (executable)
@@ -517,10 +517,11 @@ void HttpMsgHeader::prepare_body()
     DataBus::publish(DataBus::get_id(http_pub_key), HttpEventIds::HTTP_PUBLISH_LENGTH, http_publish_length_event, flow);
     int32_t new_depth = http_publish_length_event.get_publish_length();
 
+    int32_t should_publish = (int32_t)http_publish_length_event.should_publish_body();
     if (is_request)
-        flow->stash->store(STASH_PUBLISH_REQUEST_BODY, http_publish_length_event.should_publish_body());
+        flow->set_attr(STASH_PUBLISH_REQUEST_BODY, should_publish);
     else
-        flow->stash->store(STASH_PUBLISH_RESPONSE_BODY, http_publish_length_event.should_publish_body());
+        flow->set_attr(STASH_PUBLISH_RESPONSE_BODY, should_publish);
 
     if (new_depth > session_data->publish_depth_remaining[source_id])
     {
index f5cea92c2d073cd87ab1ebeae6c6e51c55a40cac..223fd97be605b14a97b8710aed032d28daef5f49 100644 (file)
@@ -360,7 +360,7 @@ void HttpMsgRequest::publish(unsigned)
         {
             SfIp aux_ip;
             if (parse_ip_from_uri(aux_ip_str, aux_ip))
-                flow->stash->store(aux_ip);
+                flow->set_attr(aux_ip);
         }
     }
 }
index 70337abc9cfec8989e0344836a11d20c866b7395..1be14e162a405926db3a10957f581a34c42005e7 100644 (file)
@@ -201,9 +201,9 @@ bool HttpStreamSplitter::finish(Flow* flow)
         {
             int32_t should_publish_body = 0;
             if (source_id == SRC_CLIENT)
-                flow->stash->get(STASH_PUBLISH_REQUEST_BODY, should_publish_body);
+                flow->get_attr(STASH_PUBLISH_REQUEST_BODY, should_publish_body);
             else
-                flow->stash->get(STASH_PUBLISH_RESPONSE_BODY, should_publish_body);
+                flow->get_attr(STASH_PUBLISH_RESPONSE_BODY, should_publish_body);
 
             if (should_publish_body)
             {
index 82e2b3039a9d1ad358afe887a75401fe3fcba409..58f560593a00da21e96992cacb13e549f309cd3d 100644 (file)
@@ -46,14 +46,15 @@ namespace snort
 {
 // Stubs whose sole purpose is to make the test code link
 unsigned FlowData::flow_data_id = 0;
-FlowData::FlowData(unsigned, Inspector*) : next(nullptr), prev(nullptr), handler(nullptr), id(0)
+FlowData::FlowData(unsigned, Inspector*) : handler(nullptr), id(0)
 {}
 FlowData::~FlowData() = default;
+FlowDataStore::~FlowDataStore() = default;
 int DetectionEngine::queue_event(unsigned int, unsigned int) { return 0; }
 fd_status_t File_Decomp_StopFree(fd_session_t*) { return File_Decomp_OK; }
 uint32_t str_to_hash(const uint8_t *, size_t) { return 0; }
-FlowData* Flow::get_flow_data(uint32_t) const { return nullptr; }
-int Flow::set_flow_data(FlowData*) { return 0;}
+FlowData* FlowDataStore::get(unsigned) const { return nullptr; }
+void FlowDataStore::set(FlowData*) { }
 Flow::~Flow() = default;
 unsigned DataBus::get_id(PubKey const&) { return 0; }
 void DataBus::publish(unsigned int, unsigned int, DataEvent&, Flow*) {}
index 7b30d9640d177df4162b5023400282bb9d1e283f..df9a21d5b5d428d2a5cd4d2768a593ff24ba40a9 100644 (file)
@@ -155,7 +155,6 @@ const PegInfo imap_peg_names[] =
 
 ImapFlowData::ImapFlowData() : FlowData(inspector_id)
 {
-    memset(&session, 0, sizeof(session));
     imapstats.concurrent_sessions++;
     if(imapstats.max_concurrent_sessions < imapstats.concurrent_sessions)
         imapstats.max_concurrent_sessions = imapstats.concurrent_sessions;
index 91039c15b6f656f463a0fa093a82c92b8696ac67..2aa599bb3fb7129689724f7687fb3ec397a32042 100644 (file)
@@ -183,7 +183,7 @@ public:
 
 public:
     static unsigned inspector_id;
-    IMAPData session;
+    IMAPData session = {};
 };
 
 #endif
index b575461e544c6b7e5663e57b2a6bf7046e0bcbc0..9e3e813f6a9900bed0ada1d38181b6723c3ae9d2 100644 (file)
@@ -112,7 +112,6 @@ const PegInfo pop_peg_names[] =
 
 PopFlowData::PopFlowData() : FlowData(inspector_id)
 {
-    memset(&session, 0, sizeof(session));
     popstats.concurrent_sessions++;
     if(popstats.max_concurrent_sessions < popstats.concurrent_sessions)
         popstats.max_concurrent_sessions = popstats.concurrent_sessions;
index f00ce2d52a418a46c19166c68d6e24a9c795d859..2201cbdd2c414746fb6428b57b098cc49c70674e 100644 (file)
@@ -137,7 +137,7 @@ public:
 
 public:
     static unsigned inspector_id;
-    POPData session;
+    POPData session = {};
 };
 
 #endif
index 17960d814b2d2ce825952b21d182f5542e688e8e..ae397ecf050ab9d928bdd666b9b64186bd929e25 100644 (file)
@@ -73,7 +73,6 @@ bool get_buf_sip(unsigned id, snort::Packet* p, snort::InspectionBuffer& b)
 
 SipFlowData::SipFlowData() : FlowData(inspector_id)
 {
-    memset(&session, 0, sizeof(session));
     sip_stats.sessions++;
     sip_stats.concurrent_sessions++;
     if(sip_stats.max_concurrent_sessions < sip_stats.concurrent_sessions)
index e64878014e9bc90c9f0119b1447a20cbd719f7f5..a6af048efa26c73ce9027b23f95357436dd61a3c 100644 (file)
@@ -52,7 +52,7 @@ public:
 
 public:
     static unsigned inspector_id;
-    SIPData session;
+    SIPData session = {};
 };
 
 SIPData* get_sip_session_data(const snort::Flow*);
index 099a240f725f61e8b79573c2789c319f96305c8f..86ee0ad1452024bf00f3164d293fbaa78fc6933f 100644 (file)
@@ -1793,8 +1793,6 @@ TEST_CASE("handle_header_line", "[smtp]")
     Packet p;
     Flow flow;
     p.flow = &flow;
-    FlowStash stash;
-    p.flow->stash = &stash;
     p.context = new IpsContext(1);
     SmtpMime mime_ssn(&p, &decode_conf, &log_config);
     smtp_normalizing = true;
@@ -1812,7 +1810,6 @@ TEST_CASE("handle_header_line", "[smtp]")
 
     // Cleanup
     delete p.context;
-    p.flow->stash = nullptr;
 }
 
 TEST_CASE("normalize_data", "[smtp]")
@@ -1825,8 +1822,6 @@ TEST_CASE("normalize_data", "[smtp]")
     Packet p;
     Flow flow;
     p.flow =& flow;
-    FlowStash stash;
-    p.flow->stash = &stash;
     p.context = new IpsContext(1);
     SmtpMime mime_ssn(&p, &decode_conf, &log_config);
     smtp_normalizing = true;
@@ -1844,6 +1839,5 @@ TEST_CASE("normalize_data", "[smtp]")
 
     // Cleanup
     delete p.context;
-    p.flow->stash = nullptr;
 }
 #endif
index ba7a43066b267da495afee9d186d787624907fa6..f3f407b97d41dbcd57df39390388038a5141d130 100644 (file)
@@ -45,7 +45,7 @@ HeldPacket::HeldPacket(DAQ_Msg_h msg, uint32_t seq, const timeval& exp, TcpStrea
     : daq_msg(msg), seq_num(seq), expiration(exp), tracker(trk), expired(false)
 { }
 
-HeldPacketQueue::iter_t HeldPacketQueue::append(DAQ_Msg_h msg, uint32_t seq,
+const HeldPacketQueue::iter_t HeldPacketQueue::append(DAQ_Msg_h msg, uint32_t seq,
     TcpStreamTracker& trk)
 {
     timeval now, expiration;
@@ -56,7 +56,7 @@ HeldPacketQueue::iter_t HeldPacketQueue::append(DAQ_Msg_h msg, uint32_t seq,
     return --q.end();
 }
 
-void HeldPacketQueue::erase(iter_t it)
+void HeldPacketQueue::erase(const iter_t it)
 {
     q.erase(it);
 }
index afa66d9258c1a05c62a336bc3f4f4491abb31eb1..f0bc8acbdcbbb9a627e1dc2de78195de1c1dae29 100644 (file)
@@ -40,7 +40,7 @@ public:
         return expired;
     }
 
-    bool has_expired()
+    bool has_expired() const
     { return expired; }
 
     TcpStreamTracker& get_tracker() const { return tracker; }
@@ -61,10 +61,10 @@ class HeldPacketQueue
 public:
 
     using list_t = std::list<HeldPacket>;
-    using iter_t = list_t::iterator;
+    using iter_t = list_t::const_iterator;
 
-    iter_t append(DAQ_Msg_h msg, uint32_t seq, TcpStreamTracker& trk);
-    void erase(iter_t it);
+    const iter_t append(DAQ_Msg_h msg, uint32_t seq, TcpStreamTracker& trk);
+    void erase(const iter_t it);
 
     // Return whether there still are expired packets in the queue.
     bool execute(const timeval& cur_time, int max_remove);
@@ -81,6 +81,9 @@ public:
     bool empty() const
     { return q.empty(); }
 
+    auto end() const
+    { return q.end(); }
+
     // This must be called at reload time only, with now = reload time.
     // Return true if, upon exit, there are expired packets in the queue.
     bool adjust_expiration(uint32_t new_timeout_ms, const timeval& now);
index 8d7531f01cd6252c63044b72c41aee23df459291..d8d1d4137db0b3db67f5fda0a9a4f62b3e604dfc 100644 (file)
@@ -147,7 +147,7 @@ void TcpOverlapResolver::eval_right(TcpOverlapState& tos)
 
         // Treat sequence number overlap as a retransmission,
         // only check right side since left side happens rarely
-        tos.seglist.session->flow->call_handlers(tos.tsd->get_pkt(), false);
+        tos.seglist.session->flow->call_handlers(tos.tsd->get_pkt());
         if ( tos.overlap < tos.right->length )
         {
             if ( tos.right->is_retransmit(tos.rdata, tos.rsize,
index 3ea775ceb40403b7d755e93fb6a5a3209a39a405..5c5915b85a04f059a5a0b417fa7a8d52ca9c5f6c 100644 (file)
@@ -926,7 +926,7 @@ bool TcpSession::ignore_this_packet(Packet* p)
         // Don't need to process a retry packet through stream again,
         // just make sure the retransmit handler is called so that
         // we do things like update file inspection.
-        flow->call_handlers(p, false);
+        flow->call_handlers(p);
         return true;
     }
 
index 601e9e5151c33b5be9999e431264a6f8ebf7d938..fef43f46e9286340d2187c2e43638658ddf6bab1 100644 (file)
@@ -100,7 +100,7 @@ bool TcpStateEstablished::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTrac
 bool TcpStateEstablished::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
 {
     trk.update_on_fin_sent(tsd);
-    trk.session->flow->call_handlers(tsd.get_pkt(), true);
+    trk.session->flow->call_handlers(tsd.get_pkt(), FlowDataStore::HANDLER_EOF);
     trk.set_tcp_state(TcpStreamTracker::TCP_FIN_WAIT1);
     return true;
 }
index a7f7531e7d502c7bcf8472327295668b9631bada..89231b6b1302773e9d746ec86100b80ebadba711 100644 (file)
@@ -115,7 +115,7 @@ bool TcpStateMidStreamRecv::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker
     }
 
     trk.update_on_fin_sent(tsd);
-    trk.session->flow->call_handlers(tsd.get_pkt(), true);
+    trk.session->flow->call_handlers(tsd.get_pkt(), FlowDataStore::HANDLER_EOF);
     TcpStreamTracker::TcpState listener_state = tsd.get_listener()->get_tcp_state();
     // If one sided has sent a FIN
     if ( TcpStreamTracker::TCP_FIN_WAIT1 == listener_state )
index 1914d514e7e5056d9bf44c7e4205d9c434d79c8a..a3d635b640f919ae3cf351c860b5c38d52d97014 100644 (file)
@@ -138,7 +138,7 @@ bool TcpStateSynSent::data_seg_recv(TcpSegmentDescriptor& tsd, TcpStreamTracker&
 bool TcpStateSynSent::fin_sent(TcpSegmentDescriptor& tsd, TcpStreamTracker& trk)
 {
     trk.update_on_fin_sent(tsd);
-    trk.session->flow->call_handlers(tsd.get_pkt(), true);
+    trk.session->flow->call_handlers(tsd.get_pkt(), FlowDataStore::HANDLER_EOF);
     trk.session->update_timestamp_tracking(tsd);
     if ( trk.session->flow->two_way_traffic() )
     {
index c45425548434f017f4923d19ad6613d7b182c736..38c66f7889b92bf24cf9e1d7771f66a23fec9840 100644 (file)
@@ -48,8 +48,6 @@ using namespace snort;
 
 THREAD_LOCAL HeldPacketQueue* hpq = nullptr;
 
-const std::list<HeldPacket>::iterator TcpStreamTracker::null_iterator { };
-
 const char* tcp_state_names[] =
 {
     "TCP_LISTEN", "TCP_SYN_SENT", "TCP_SYN_RECV",
@@ -69,11 +67,12 @@ const char* tcp_event_names[] = {
 };
 
 TcpStreamTracker::TcpStreamTracker(bool client) :
-    client_tracker(client), tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN),
-    held_packet(null_iterator)
+    client_tracker(client), tcp_state(client ? TCP_STATE_NONE : TCP_LISTEN)
 { 
     flush_policy = STREAM_FLPOLICY_IGNORE;
     update_flush_policy(nullptr);
+    if (hpq)
+        held_packet = hpq->end();
 }
 
 TcpStreamTracker::~TcpStreamTracker()
@@ -291,7 +290,10 @@ void TcpStreamTracker::init_tcp_state(TcpSession* s)
     fin_seq_set = false;
     rst_pkt_sent = false;
     order = TcpStreamTracker::IN_SEQUENCE;
-    held_packet = null_iterator;
+    if (hpq)
+        held_packet = hpq->end();
+    else
+        held_packet = {};
 
     flush_policy = STREAM_FLPOLICY_IGNORE;
     update_flush_policy(nullptr);
@@ -814,9 +816,15 @@ bool TcpStreamTracker::is_segment_seq_valid(TcpSegmentDescriptor& tsd)
     return valid_seq;
 }
 
+bool TcpStreamTracker::is_holding_packet() const
+{
+    assert(hpq);
+    return held_packet != hpq->end();
+}
+
 bool TcpStreamTracker::set_held_packet(Packet* p)
 {
-    if ( held_packet != null_iterator )
+    if ( is_holding_packet() )
         return false;
 
     held_packet = hpq->append(p->daq_msg, p->ptrs.tcph->seq(), *this);
@@ -875,7 +883,7 @@ void TcpStreamTracker::perform_fin_recv_flush(TcpSegmentDescriptor& tsd)
 uint32_t TcpStreamTracker::perform_partial_flush()
 {
     uint32_t flushed = 0;
-    if ( held_packet != null_iterator )
+    if ( is_holding_packet() )
     {
         Packet* p;
         flushed = reassembler->perform_partial_flush(session->flow, p);
@@ -897,7 +905,10 @@ uint32_t TcpStreamTracker::perform_partial_flush()
 
 bool TcpStreamTracker::is_retransmit_of_held_packet(Packet* cp)
 {
-    if ( (held_packet == null_iterator) or ( cp->daq_msg == held_packet->get_daq_msg() ) )
+    if ( !is_holding_packet() )
+        return false;
+
+    if ( cp->daq_msg == held_packet->get_daq_msg() )
         return false;
 
     uint32_t next_send_seq = cp->ptrs.tcph->seq() + (uint32_t)cp->dsize;
@@ -912,7 +923,7 @@ bool TcpStreamTracker::is_retransmit_of_held_packet(Packet* cp)
 
 void TcpStreamTracker::finalize_held_packet(Packet* cp)
 {
-    if ( held_packet != null_iterator )
+    if ( is_holding_packet() )
     {
         DAQ_Msg_h msg = held_packet->get_daq_msg();
 
@@ -940,7 +951,7 @@ void TcpStreamTracker::finalize_held_packet(Packet* cp)
         }
 
         hpq->erase(held_packet);
-        held_packet = null_iterator;
+        held_packet = hpq->end();
         tcpStats.current_packets_held--;
     }
 
@@ -950,7 +961,7 @@ void TcpStreamTracker::finalize_held_packet(Packet* cp)
 
 void TcpStreamTracker::finalize_held_packet(Flow* flow)
 {
-    if ( held_packet != null_iterator )
+    if ( is_holding_packet() )
     {
         DAQ_Msg_h msg = held_packet->get_daq_msg();
 
@@ -970,7 +981,7 @@ void TcpStreamTracker::finalize_held_packet(Flow* flow)
         }
 
         hpq->erase(held_packet);
-        held_packet = null_iterator;
+        held_packet = hpq->end();
         tcpStats.current_packets_held--;
     }
 }
index c30c01f189b213a332a735fcda28c90b5754e178..5f7d23bbc8f692fdd006a6e5ac6069eb499f52da 100644 (file)
@@ -304,8 +304,7 @@ public:
     void perform_fin_recv_flush(TcpSegmentDescriptor&);
     int32_t kickstart_asymmetric_flow(const TcpSegmentDescriptor& tsd, uint32_t max_queued_bytes);
     uint32_t perform_partial_flush();
-    bool is_holding_packet() const
-    { return held_packet != null_iterator; }
+    bool is_holding_packet() const;
 
     // max_remove < 0 means time out all eligible packets.
     // Return whether there are more packets that need to be released.
@@ -343,8 +342,7 @@ private:
     TcpEvent tcp_event = TCP_MAX_EVENTS;
 
     snort::StreamSplitter* splitter = nullptr;
-    static const std::list<HeldPacket>::iterator null_iterator;
-    std::list<HeldPacket>::iterator held_packet;
+    std::list<HeldPacket>::const_iterator held_packet;
     uint32_t ts_last_packet = 0;
     uint32_t ts_last = 0;       // last timestamp (for PAWS)
     uint32_t fin_final_seq = 0;
index 2e4ed761516d02282df5ea8c4dbfecc5218c1328..bc669379d6353473b0b14cb136a5777d5874cde9 100644 (file)
@@ -46,6 +46,7 @@ const SnortConfig* SnortConfig::get_conf()
 static StreamSplitter* next_splitter = nullptr;
 
 Flow::~Flow() = default;
+FlowDataStore::~FlowDataStore() = default;
 Packet::Packet(bool) { }
 Packet::~Packet() = default;
 
index e526a71900da2da56cd3e3f6800804ea976c5362..f3a13f60e5d82af8a4b29c730b3458574057a857 100644 (file)
@@ -226,7 +226,7 @@ using namespace snort;
 //stringify the macro
 #define sm(code) #code
 
-struct TestCase
+struct TraceTestCase
 {
     const char* test;
     const char* expected;
@@ -243,7 +243,7 @@ static void test_log(const char* log_msg, const char* name,
 
 TEST_CASE("macros", "[trace]")
 {
-    TestCase cases[] =
+    TraceTestCase cases[] =
     {
         {
             sx(debug_log(1, test_trace, "my message")),