]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1131 in SNORT/snort3 from perf_files to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Tue, 13 Mar 2018 22:30:44 +0000 (18:30 -0400)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Tue, 13 Mar 2018 22:30:44 +0000 (18:30 -0400)
Squashed commit of the following:

commit e6f3785c7af8aa67856fce0c9618165352fbda01
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Tue Mar 13 10:26:08 2018 -0400

    PluginManager: enforce all IT_PROBE Inspectors present GLOBAL Modules

commit e7470a81c44ecb506f8cb89cc77a72e95d3b65ba
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Tue Mar 13 09:50:15 2018 -0400

    ModuleManager: globals only load on default policy

commit 50edf8306b1127f1ff150ee9fb699ddbe65a4b6a
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Fri Mar 9 08:24:31 2018 -0500

    DataBus: added ability to unsubscribe to prevent dangling references

commit d60232178001c911176ed0272181f80a913bbe62
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Thu Mar 8 12:05:21 2018 -0500

    perf_monitor: fixed flow_ip outputting erroneous values

commit e003750bf325ed99a6b1186b839f1f40e569d21c
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Mon Feb 19 16:08:54 2018 -0500

    InspectorManager: probes run regardless of active policy

commit 3749d1380583fb2d3b475b76c741fd63bb28f061
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Mon Feb 19 15:30:12 2018 -0500

    perf_monitor: query modules for stats only after they have all loaded

commit dddb7fdd814513d4f195f501d6cff2f6b6dd6760
Author: Carter Waxman <cwaxman@cisco.com>
Date:   Wed Feb 14 16:17:08 2018 -0500

    perf_monitor: decoupled from other modules. now builds dynamically.

28 files changed:
src/framework/data_bus.cc
src/framework/data_bus.h
src/main/policy.cc
src/main/policy.h
src/main/snort.cc
src/managers/inspector_manager.cc
src/managers/module_manager.cc
src/managers/plugin_manager.cc
src/network_inspectors/CMakeLists.txt
src/network_inspectors/network_inspectors.cc
src/network_inspectors/packet_capture/capture_module.h
src/network_inspectors/packet_capture/packet_capture.cc
src/network_inspectors/perf_monitor/CMakeLists.txt
src/network_inspectors/perf_monitor/base_tracker.cc
src/network_inspectors/perf_monitor/cpu_tracker.cc
src/network_inspectors/perf_monitor/flow_ip_tracker.cc
src/network_inspectors/perf_monitor/flow_ip_tracker.h
src/network_inspectors/perf_monitor/flow_tracker.cc
src/network_inspectors/perf_monitor/perf_module.cc
src/network_inspectors/perf_monitor/perf_module.h
src/network_inspectors/perf_monitor/perf_monitor.cc
src/network_inspectors/perf_monitor/perf_monitor.h [deleted file]
src/network_inspectors/perf_monitor/perf_tracker.cc
src/network_inspectors/perf_monitor/perf_tracker.h
src/network_inspectors/port_scan/ps_module.h
src/stream/tcp/tcp_debug_trace.h
src/stream/tcp/tcp_session.cc
src/stream/udp/udp_session.cc

index 22b009a63f0d870ba80ef1d2a253f802b6965ed9..4a07ad06bbcbacd01851d608940cd0de9bfa1719 100644 (file)
@@ -79,6 +79,22 @@ void DataBus::subscribe(const char* key, DataHandler* h)
     get_data_bus()._subscribe(key, h);
 }
 
+// for subscribers that need to receive events regardless of active inspection policy
+void DataBus::subscribe_default(const char* key, DataHandler* h)
+{
+    get_default_inspection_policy(SnortConfig::get_conf())->dbus._subscribe(key, h);
+}
+
+void DataBus::unsubscribe(const char* key, DataHandler* h)
+{
+    get_data_bus()._unsubscribe(key, h);
+}
+
+void DataBus::unsubscribe_default(const char* key, DataHandler* h)
+{
+    get_default_inspection_policy(SnortConfig::get_conf())->dbus._unsubscribe(key, h);
+}
+
 // notify subscribers of event
 void DataBus::publish(const char* key, DataEvent& e, Flow* f)
 {
@@ -102,7 +118,7 @@ void DataBus::publish(const char* key, const uint8_t* buf, unsigned len, Flow* f
 void DataBus::publish(const char* key, Packet* p, Flow* f)
 {
     PacketEvent e(p);
-    if ( !f )
+    if ( p && !f )
         f = p->flow;
     publish(key, e, f);
 }
@@ -123,6 +139,18 @@ void DataBus::_subscribe(const char* key, DataHandler* h)
     v.push_back(h);
 }
 
+void DataBus::_unsubscribe(const char* key, DataHandler* h)
+{
+    DataList& v = map[key];
+
+    for ( unsigned i = 0; i < v.size(); i++ )
+        if ( v[i] == h )
+            v.erase(v.begin() + i--);
+
+    if ( v.empty() )
+        map.erase(key);
+}
+
 // notify subscribers of event
 void DataBus::_publish(const char* key, DataEvent& e, Flow* f)
 {
index 6228cf82e3e8ad7e54855564881ce0515b5e2a68..64e109ed5cc81ae0d579d47588edbb2ac3f9b739 100644 (file)
@@ -81,6 +81,9 @@ public:
     ~DataBus();
 
     static void subscribe(const char* key, DataHandler*);
+    static void subscribe_default(const char* key, DataHandler*);
+    static void unsubscribe(const char* key, DataHandler*);
+    static void unsubscribe_default(const char* key, DataHandler*);
     static void publish(const char* key, DataEvent&, Flow* = nullptr);
 
     // convenience methods
@@ -90,6 +93,7 @@ public:
 
 private:
     void _subscribe(const char* key, DataHandler*);
+    void _unsubscribe(const char* key, DataHandler*);
     void _publish(const char* key, DataEvent&, Flow*);
 
 private:
@@ -122,6 +126,9 @@ private:
 // common data events
 #define PACKET_EVENT "detection.packet"
 #define DAQ_META_EVENT "daq.metapacket"
+#define FLOW_STATE_EVENT "flow.state_change"
+#define THREAD_IDLE_EVENT "thread.idle"
+#define THREAD_ROTATE_EVENT "thread.rotate"
 
 #endif
 
index fc1e57beafaed817551ac6ace56aba3dfb5be8f5..aa152d17c4b16d1e0021ead3ebf712c607d4dab1 100644 (file)
@@ -332,6 +332,17 @@ void set_default_policy(SnortConfig* sc)
 void set_default_policy()
 { set_default_policy(SnortConfig::get_conf()); }
 
+bool default_inspection_policy()
+{
+    if ( !get_inspection_policy() )
+        return false;
+    
+    if ( get_inspection_policy()->policy_id != 0 )
+        return false;
+
+    return true;
+}
+
 bool only_inspection_policy()
 { return get_inspection_policy() && !get_ips_policy() && !get_network_policy(); }
 
index 1ba1f132b6155a9029f1ffb6d2788f235db15e02..ab6897e07407d5f89169c75b463d759a830d24a9 100644 (file)
@@ -259,6 +259,7 @@ void set_policies(snort::SnortConfig*, Shell*);
 void set_default_policy();
 void set_default_policy(snort::SnortConfig*);
 
+bool default_inspection_policy();
 bool only_inspection_policy();
 bool only_ips_policy();
 bool only_network_policy();
index bc371f41dd2b1030e3bfc0ebce23b3d4a2782266..4a5fcfb3d90f959812aa6b1d6a8f71a565c92ab7 100644 (file)
@@ -75,7 +75,6 @@
 #include "packet_io/trough.h"
 #include "parser/cmd_line.h"
 #include "parser/parser.h"
-#include "perf_monitor/perf_monitor.h"
 #include "profiler/profiler.h"
 #include "search_engines/search_engines.h"
 #include "service_inspectors/service_inspectors.h"
@@ -701,15 +700,16 @@ void Snort::capture_packet()
 
 void Snort::thread_idle()
 {
+    // FIXIT-L this whole thing could be pub-sub
+    DataBus::publish(THREAD_IDLE_EVENT, nullptr);
     Stream::timeout_flows(time(nullptr));
-    perf_monitor_idle_process();
     aux_counts.idle++;
     HighAvailabilityManager::process_receive();
 }
 
 void Snort::thread_rotate()
 {
-    SetRotatePerfFileFlag();
+    DataBus::publish(THREAD_ROTATE_EVENT, nullptr);
 }
 
 /*
index 4cabe59455ec510d1b6af5694c3c466563f7eb30..b0bfab1a7ac2b57890485342afcfce8f12d96f19 100644 (file)
@@ -280,8 +280,13 @@ void FrameworkPolicy::vectorize()
             break;
 
         case IT_PROBE:
-            probe.add(p);
+        {
+            // probes always run
+            // add them to default so they can be found on InspectorManager::probe
+            SnortConfig* sc = SnortConfig::get_conf();
+            sc->policy_map->get_inspection_policy(0)->framework_policy->probe.add(p);
             break;
+        }
 
         case IT_MAX:
             break;
@@ -1001,7 +1006,8 @@ void InspectorManager::execute(Packet* p)
 
 void InspectorManager::probe(Packet* p)
 {
-    FrameworkPolicy* fp = snort::get_inspection_policy()->framework_policy;
+    InspectionPolicy* policy = snort::SnortConfig::get_conf()->policy_map->get_inspection_policy(0);
+    FrameworkPolicy* fp = policy->framework_policy;
     ::execute(p, fp->probe.vec, fp->probe.num);
 }
 
index 412a18abebb810d515b758beef251e9405ce053b..cf57a0b49d08297189371d32a4bddf751177c251 100644 (file)
@@ -468,14 +468,18 @@ static bool set_value(const char* fqn, Value& v)
         return found;
     }
 
+    if ( mod->get_usage() == Module::GLOBAL &&
+         only_inspection_policy() && !default_inspection_policy() )
+        return true;
+
     if ( mod->get_usage() != Module::INSPECT && only_inspection_policy() )
-            return true;
+        return true;
 
     if ( mod->get_usage() != Module::DETECT && only_ips_policy() )
-            return true;
+        return true;
 
     if ( mod->get_usage() != Module::CONTEXT && only_network_policy() )
-            return true;
+        return true;
 
     // now we must traverse the mod params to get the leaf
     string s = fqn;
@@ -688,6 +692,10 @@ SO_PUBLIC bool open_table(const char* s, int idx)
     Module* m = h->mod;
     const Parameter* p = nullptr;
 
+    if ( m->get_usage() == Module::GLOBAL &&
+         only_inspection_policy() && !default_inspection_policy() )
+        return true;
+
     if ( m->get_usage() != Module::INSPECT && only_inspection_policy() )
         return true;
 
@@ -747,6 +755,10 @@ SO_PUBLIC void close_table(const char* s, int idx)
 
     if ( ModHook* h = get_hook(key.c_str()) )
     {
+        if ( h->mod->get_usage() == Module::GLOBAL &&
+             only_inspection_policy() && !default_inspection_policy() )
+            return;
+
         if ( h->mod->get_usage() != Module::INSPECT && only_inspection_policy() )
             return;
 
index e1c085ded7df13c33d708d9530c830358f09f807..d98a26f7ca074bc0f0651eb32680ea14fa0d7608 100644 (file)
@@ -278,10 +278,11 @@ static bool load_lib(const char* file)
 
 static void add_plugin(Plugin& p)
 {
+    Module* m = nullptr;
     if ( p.api->mod_ctor )
     {
         current_plugin = p.api->name;
-        Module* m = p.api->mod_ctor();
+        m = p.api->mod_ctor();
         ModuleManager::add_module(m, p.api);
     }
 
@@ -292,6 +293,11 @@ static void add_plugin(Plugin& p)
         break;
 
     case PT_INSPECTOR:
+        // probes must always be global. they run regardless of selected policy.
+        assert( (m && ((const InspectApi*)p.api)->type == IT_PROBE) ? 
+                m->get_usage() == Module::GLOBAL :
+                true );
+
         InspectorManager::add_plugin((const InspectApi*)p.api);
         break;
 
index d3b9cff6c4b6b217bb2aea62bed955e27ee96da7..95b846878c702065067aa6df0ca32f100391cf8f 100644 (file)
@@ -12,6 +12,7 @@ if(STATIC_INSPECTORS)
     set(STATIC_INSPECTOR_OBJS
         $<TARGET_OBJECTS:arp_spoof>
         $<TARGET_OBJECTS:packet_capture>
+        $<TARGET_OBJECTS:perf_monitor>
     )
 endif()
 
@@ -19,7 +20,6 @@ set(STATIC_NETWORK_INSPECTOR_PLUGINS
     $<TARGET_OBJECTS:appid>
     $<TARGET_OBJECTS:binder>
     $<TARGET_OBJECTS:normalize>
-    $<TARGET_OBJECTS:perf_monitor>
     $<TARGET_OBJECTS:port_scan>
     $<TARGET_OBJECTS:reputation>
     ${STATIC_INSPECTOR_OBJS}
@@ -30,4 +30,3 @@ add_library( network_inspectors OBJECT
     network_inspectors.cc
     network_inspectors.h
 )
-
index 6717982cd32bee52aca7b0b46974b968abc3532e..73e8c274edf86593a8a582caf1c6842d6032d593 100644 (file)
@@ -28,7 +28,6 @@ using namespace snort;
 
 extern const BaseApi* nin_binder;
 extern const BaseApi* nin_normalize;
-extern const BaseApi* nin_perf_monitor;
 extern const BaseApi* nin_reputation;
 
 extern const BaseApi* nin_appid[];
@@ -37,13 +36,13 @@ extern const BaseApi* nin_port_scan[];
 #ifdef STATIC_INSPECTORS
 extern const BaseApi* nin_arp_spoof[];
 extern const BaseApi* nin_packet_capture[];
+extern const BaseApi* nin_perf_monitor[];
 #endif
 
 static const BaseApi* network_inspectors[] =
 {
     nin_binder,
     nin_normalize,
-    nin_perf_monitor,
     nin_reputation,
     nullptr
 };
@@ -57,6 +56,7 @@ void load_network_inspectors()
 #ifdef STATIC_INSPECTORS
     PluginManager::load_plugins(nin_arp_spoof);
     PluginManager::load_plugins(nin_packet_capture);
+    PluginManager::load_plugins(nin_perf_monitor);
 #endif
 }
 
index c48c263fc1a92ae65ad01895e3eadb71bae2da19..8e4bdc051cd09998301889e9c9d5a45511dccf6e 100644 (file)
@@ -52,7 +52,7 @@ public:
     void get_config(CaptureConfig&);
 
     Usage get_usage() const override
-    { return CONTEXT; }
+    { return GLOBAL; }
 
 private:
     CaptureConfig config;
index 96cc0acd0ef58f7ad0b04ef75dbe445da80058b1..84731629d96e1db61d9ecc0c89a19c1b24824075 100644 (file)
@@ -196,7 +196,7 @@ static const InspectApi pc_api =
         mod_ctor,
         mod_dtor
     },
-    IT_PACKET,
+    IT_PROBE,
     (uint16_t)PktType::ANY,
     nullptr, // buffers
     nullptr, // service
index 5179a623782f39535eb2ea43abab83dc2a7e15cb..edfc1de089df0acb5254e8fee174795c1b974577 100644 (file)
@@ -21,7 +21,6 @@ add_library ( perf_monitor OBJECT
     perf_module.cc
     perf_module.h
     perf_monitor.cc
-    perf_monitor.h
     perf_tracker.cc
     perf_tracker.h
     text_formatter.cc
index ce735d7a502ca2a2d189a2313ff4434338e6bbc4..68421fc00ce24a22d68dab9397d19c64b7f2e632 100644 (file)
 using namespace snort;
 using namespace std;
 
-BaseTracker::BaseTracker(PerfConfig* perf)
-    : PerfTracker(perf, perf->output == PERF_FILE, PERF_NAME "_base")
+BaseTracker::BaseTracker(PerfConfig* perf) : PerfTracker(perf, PERF_NAME "_base")
 {
-    for (unsigned i = 0; i < config->modules.size(); i++)
+    for ( ModuleConfig& mod : config->modules )
     {
-        Module *m = config->modules.at(i);
-        IndexVec peg_map = config->mod_peg_idxs.at(i);
+        formatter->register_section(mod.ptr->get_name());
 
-        formatter->register_section(m->get_name());
-
-        for (auto const& peg : peg_map)
-            formatter->register_field(m->get_pegs()[peg].name, &(m->get_counts()[peg]));
+        for ( auto const& idx : mod.pegs )
+            formatter->register_field(mod.ptr->get_pegs()[idx].name, &(mod.ptr->get_counts()[idx]));
     }
     formatter->finalize_fields();
 }
@@ -52,9 +48,9 @@ void BaseTracker::process(bool summary)
 {
     write();
 
-    for ( auto const& m : config->modules )
-        if (!summary)
-            m->sum_stats(false);
+    for ( auto const& mod : config->modules )
+        if ( !summary )
+            mod.ptr->sum_stats(false);
 }
 
 #ifdef UNIT_TEST
@@ -114,14 +110,13 @@ TEST_CASE("module stats", "[BaseTracker]")
         {0, 0, 0}};
 
     PerfConfig config;
-    config.format = PERF_MOCK;
+    config.format = PerfFormat::MOCK;
 
     MockModule mod;
-    config.modules.push_back(&mod);
-    config.mod_peg_idxs.push_back(IndexVec());
-    config.mod_peg_idxs[0].push_back(0);
-    config.mod_peg_idxs[0].push_back(2);
-    config.mod_peg_idxs[0].push_back(4);
+    ModuleConfig mod_cfg;
+    mod_cfg.ptr = &mod;
+    mod_cfg.pegs = {0, 2, 4};
+    config.modules.push_back(mod_cfg);
 
     MockBaseTracker tracker(&config);
     MockFormatter *formatter = (MockFormatter*)tracker.output;
index 40751f94eaaf9df797235361da4092163aa6e359..55b908168074a30ff2a5fdd37c7aed97c06a79cb 100644 (file)
@@ -45,8 +45,7 @@ static inline uint64_t get_microseconds(struct timeval t)
     return (uint64_t)t.tv_sec * 1000000 + t.tv_usec;
 }
 
-CPUTracker::CPUTracker(PerfConfig *perf) :
-    PerfTracker(perf, perf->output == PERF_FILE, TRACKER_NAME)
+CPUTracker::CPUTracker(PerfConfig *perf) : PerfTracker(perf, TRACKER_NAME)
 {
     formatter->register_section("thread_" + to_string(get_instance_id()));
     formatter->register_field("cpu_user", &user_stat);
@@ -177,7 +176,7 @@ TEST_CASE("process and output", "[cpu_tracker]")
         {2100000, 3200000, 8500000}};
 
     PerfConfig config;
-    config.format = PERF_MOCK;
+    config.format = PerfFormat::MOCK;
     TestCPUTracker tracker(&config);
     MockFormatter *formatter = (MockFormatter*)tracker.output;
 
index 65455c619675b832bf77f212041c7549cb2f3f3d..b61cec4dc0d75f7a21a49c052ad6929e763b2a6c 100644 (file)
@@ -24,6 +24,7 @@
 
 #include "flow_ip_tracker.h"
 
+#include "framework/data_bus.h"
 #include "log/messages.h"
 #include "protocols/packet.h"
 
@@ -37,13 +38,43 @@ struct FlowStateKey
     SfIp ipB;
 };
 
-THREAD_LOCAL FlowIPTracker* perf_flow_ip;
+class FlowIPDataHandler : public DataHandler
+{
+public:
+    FlowIPDataHandler(FlowIPTracker& t) : tracker(t)
+    { DataBus::subscribe_default(FLOW_STATE_EVENT, this); }
+    
+    virtual void handle(DataEvent&, Flow* flow) override
+    {
+        FlowState state = SFS_STATE_MAX;
+
+        if ( flow->pkt_type == PktType::UDP )
+            state = SFS_STATE_UDP_CREATED;
+
+        if ( flow->pkt_type == PktType::TCP )
+        {
+            if ( flow->get_session_flags() & SSNFLAG_COUNTED_ESTABLISH )
+                state = SFS_STATE_TCP_ESTABLISHED;
+
+            if ( flow->get_session_flags() & SSNFLAG_COUNTED_CLOSED )
+                state = SFS_STATE_TCP_CLOSED;
+        }
+        
+        if ( state == SFS_STATE_MAX )
+            return;
+
+        tracker.update_state(&flow->client_ip, &flow->server_ip, state);
+    }
+
+private:
+    FlowIPTracker& tracker;
+};
 
 FlowStateValue* FlowIPTracker::find_stats(const SfIp* src_addr, const SfIp* dst_addr,
     int* swapped)
 {
     FlowStateKey key;
-    FlowStateValue* value;
+    FlowStateValue* value = nullptr;
 
     if (src_addr->less_than(*dst_addr))
     {
@@ -77,9 +108,10 @@ FlowStateValue* FlowIPTracker::find_stats(const SfIp* src_addr, const SfIp* dst_
     return value;
 }
 
-FlowIPTracker::FlowIPTracker(PerfConfig* perf) :
-    PerfTracker(perf, perf->output == PERF_FILE, TRACKER_NAME)
+FlowIPTracker::FlowIPTracker(PerfConfig* perf) : PerfTracker(perf, TRACKER_NAME)
 {
+    handler = new FlowIPDataHandler(*this);
+
     formatter->register_section("flow_ip");
     formatter->register_field("ip_a", ip_a);
     formatter->register_field("ip_b", ip_b);
@@ -116,7 +148,7 @@ FlowIPTracker::FlowIPTracker(PerfConfig* perf) :
     formatter->finalize_fields();
 
     ip_map = xhash_new(1021, sizeof(FlowStateKey), sizeof(FlowStateValue),
-        perfmon_config->flowip_memcap, 1, nullptr, nullptr, 1);
+        perf->flowip_memcap, 1, nullptr, nullptr, 1);
 
     if (!ip_map)
         FatalError("Unable to allocate memory for FlowIP stats\n");
@@ -124,7 +156,10 @@ FlowIPTracker::FlowIPTracker(PerfConfig* perf) :
 
 FlowIPTracker::~FlowIPTracker()
 {
-    if (ip_map)
+    DataBus::unsubscribe_default(FLOW_STATE_EVENT, handler);
+    delete handler;
+
+    if ( ip_map )
         xhash_delete(ip_map);
 }
 
index a993aad2bd822763c92472d6244589fca53939c1..707cd79caab459a797363d16c091c86ac702f54f 100644 (file)
@@ -22,6 +22,7 @@
 #define FLOW_IP_TRACKER_H
 
 #include "perf_tracker.h"
+
 #include "hash/xhash.h"
 
 enum FlowState
@@ -51,11 +52,12 @@ struct TrafficStats
 struct FlowStateValue
 {
     TrafficStats traffic_stats[SFS_TYPE_MAX];
-    uint64_t total_packets;
-    uint64_t total_bytes;
-    uint32_t state_changes[SFS_STATE_MAX];
+    PegCount total_packets;
+    PegCount total_bytes;
+    PegCount state_changes[SFS_STATE_MAX];
 };
 
+class FlowIPDataHandler;
 class FlowIPTracker : public PerfTracker
 {
 public:
@@ -69,6 +71,7 @@ public:
     int update_state(const snort::SfIp* src_addr, const snort::SfIp* dst_addr, FlowState);
 
 private:
+    FlowIPDataHandler* handler;
     FlowStateValue stats;
     XHash* ip_map;
     char ip_a[41], ip_b[41];
@@ -77,7 +80,5 @@ private:
     void write_stats();
     void display_stats();
 };
-
-extern THREAD_LOCAL FlowIPTracker* perf_flow_ip;
 #endif
 
index eb7331f76ef6b86934072e94ce6476b8459fcc49..d5484b949b5c6d569927205ff558b2fab6044679 100644 (file)
@@ -39,8 +39,7 @@ using namespace snort;
 
 #define MAX_PKT_LEN  9000
 
-FlowTracker::FlowTracker(PerfConfig* perf) : PerfTracker(perf,
-        perf->output == PERF_FILE, TRACKER_NAME)
+FlowTracker::FlowTracker(PerfConfig* perf) : PerfTracker(perf, TRACKER_NAME)
 {
     pkt_len_cnt.resize( MAX_PKT_LEN + 1 );
     tcp.src.resize( config->flow_max_port_to_track + 1, 0 );
@@ -166,7 +165,7 @@ TEST_CASE("no protocol", "[FlowTracker]")
     uint32_t* len_ptr = &const_cast<DAQ_PktHdr_t*>(p.pkth)->caplen;
 
     PerfConfig config;
-    config.format = PERF_MOCK;
+    config.format = PerfFormat::MOCK;
     config.flow_max_port_to_track = 1024;
 
     MockFlowTracker tracker(&config);
@@ -212,7 +211,7 @@ TEST_CASE("icmp", "[FlowTracker]")
     uint8_t* type_ptr = (uint8_t*) &icmp.type;
 
     PerfConfig config;
-    config.format = PERF_MOCK;
+    config.format = PerfFormat::MOCK;
     config.flow_max_port_to_track = 1024;
 
     MockFlowTracker tracker(&config);
@@ -256,7 +255,7 @@ TEST_CASE("tcp", "[FlowTracker]")
     uint32_t* len_ptr = &const_cast<DAQ_PktHdr_t*>(p.pkth)->caplen;
 
     PerfConfig config;
-    config.format = PERF_MOCK;
+    config.format = PerfFormat::MOCK;
     config.flow_max_port_to_track = 1024;
 
     MockFlowTracker tracker(&config);
@@ -310,7 +309,7 @@ TEST_CASE("udp", "[FlowTracker]")
     uint32_t* len_ptr = &const_cast<DAQ_PktHdr_t*>(p.pkth)->caplen;
 
     PerfConfig config;
-    config.format = PERF_MOCK;
+    config.format = PerfFormat::MOCK;
     config.flow_max_port_to_track = 1024;
 
     MockFlowTracker tracker(&config);
index bb20bdbf01d99685016df439ea4e23144e3aa03f..b12276b727076ec8bf027c2d32e3fff757746f4b 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "perf_module.h"
 
+#include "log/messages.h"
 #include "managers/module_manager.h"
 
 using namespace snort;
@@ -160,11 +161,11 @@ bool PerfMonModule::set(const char*, Value& v, SnortConfig*)
     }
     else if ( v.is("name") )
     {
-        mod_name = v.get_string();
+        config.modules.back().set_name(v.get_string());
     }
     else if ( v.is("pegs") )
     {
-        mod_pegs = v.get_string();
+        config.modules.back().set_peg_names(v);
     }
     else if ( v.is("summary") )
     {
@@ -181,88 +182,112 @@ bool PerfMonModule::set(const char*, Value& v, SnortConfig*)
     return true;
 }
 
-bool PerfMonModule::begin(const char* fqn, int, SnortConfig*)
+bool PerfMonModule::begin(const char* fqn, int idx, SnortConfig*)
 {
-    if ( !strcmp(fqn, "perf_monitor.modules") )
-    {
-        mod_name.clear();
-        mod_pegs.clear();
-    }
-    else
-        memset(static_cast<PerfConfigBase*>(&config), 0, sizeof(config));
+    if ( idx != 0 && strcmp(fqn, "perf_monitor.modules") == 0 )
+        config.modules.push_back(ModuleConfig());
 
     return true;
 }
 
-static bool add_module(PerfConfig& config, Module *mod, std::string& pegs)
+bool PerfMonModule::end(const char* fqn, int idx, SnortConfig*)
+{
+    if ( idx != 0 && strcmp(fqn, "perf_monitor.modules") == 0 )
+        return config.modules.back().confirm_parse();
+
+    return true;
+}
+
+PerfConfig& PerfMonModule::get_config()
+{ return config; }
+
+const PegInfo* PerfMonModule::get_pegs() const
+{ return simple_pegs; }
+
+PegCount* PerfMonModule::get_counts() const
+{ return (PegCount*)&pmstats; }
+
+void ModuleConfig::set_name(std::string name)
+{ this->name = name; }
+
+void ModuleConfig::set_peg_names(Value& peg_names)
 {
-    const PegInfo* peg_info;
     std::string tok;
-    Value v(pegs.c_str());
-    unsigned t_count = 0;
+    peg_names.set_first_token();
 
-    if ( !mod )
+    while ( peg_names.get_next_token(tok) )
+        this->peg_names[tok] = false;
+}
+
+bool ModuleConfig::confirm_parse()
+{
+    // asking for pegs without specifying the module name doesn't make sense
+    if ( name.empty() && !peg_names.empty() )
         return false;
 
-    config.modules.push_back(mod);
-    config.mod_peg_idxs.push_back(std::vector<unsigned>());
+    return true;
+}
+bool ModuleConfig::resolve()
+{
+    ptr = ModuleManager::get_module(name.c_str());
+    if ( ptr == nullptr )
+    {
+        ParseWarning(WARN_CONF, "Perf monitor is unable to find the %s module.\n", name.c_str());
+        return false;
+    }
 
-    peg_info = mod->get_pegs();
+    const PegInfo* peg_info = ptr->get_pegs();
+    if ( !peg_info )
+        return true; // classifications does this. it's valid.
 
-    for ( v.set_first_token(); v.get_next_token(tok); t_count++ )
+    if ( peg_names.empty() )
     {
-        bool found = false;
+        for ( unsigned i = 0; peg_info[i].name != nullptr; i++ )
+            pegs.push_back(i);
+    }
+    else
+    {
+        for ( unsigned i = 0; peg_info[i].name != nullptr; i++ )
+        {
+            auto peg_ittr = peg_names.find(peg_info[i].name);
 
-        for ( int i = 0; peg_info[i].name; i++ )
+            if ( peg_ittr != peg_names.end() )
+            {
+                peg_ittr->second = true;
+                pegs.push_back(i);
+            }
+        }
+
+        for ( auto &i : peg_names )
         {
-            if ( !strcmp(tok.c_str(), peg_info[i].name) )
+            if ( !i.second )
             {
-                config.mod_peg_idxs.back().push_back(i);
-                found = true;
-                break;
+                ParseWarning(WARN_CONF, "Perf monitor is unable to find %s.%s count", name.c_str(), i.first.c_str());
+                return false;
             }
         }
-        if ( !found )
-            return false;
     }
-    if ( !t_count && peg_info )
-        for ( int i = 0; peg_info[i].name; i++ )
-            config.mod_peg_idxs.back().push_back(i);
+    name.clear();
+    peg_names.clear();
     return true;
 }
 
-bool PerfMonModule::end(const char* fqn, int idx, SnortConfig*)
+bool PerfConfig::resolve()
 {
-    if ( !idx )
+    if ( modules.empty() )
     {
-        if ( config.modules.empty() )
+        auto all_modules = ModuleManager::get_all_modules();       
+        for ( auto& mod : all_modules )
         {
-            auto modules = ModuleManager::get_all_modules();
-            std::string empty;
-
-            for ( auto& mod : modules )
-            {
-                if ( !add_module(config, mod, empty) )
-                    return false;
-            }
+            ModuleConfig cfg;
+            cfg.set_name(mod->get_name());
+            modules.push_back(cfg);
         }
-        return true;
     }
 
-    if ( !strcmp(fqn, "perf_monitor.modules") && !mod_name.empty() )
-        return add_module(config, ModuleManager::get_module(mod_name.c_str()), mod_pegs);
+    for ( auto& mod : modules )
+        if ( !mod.resolve() )
+            return false;
 
     return true;
 }
-
-void PerfMonModule::get_config(PerfConfig& cfg)
-{
-    cfg = config;
-}
-
-const PegInfo* PerfMonModule::get_pegs() const
-{ return simple_pegs; }
-
-PegCount* PerfMonModule::get_counts() const
-{ return (PegCount*)&pmstats; }
-
index 20a173d6ef6410b0a056b11e39b3bdda4a0651ea..397bb39b83b7802277e4aa55c63151830363fdf4 100644 (file)
@@ -21,6 +21,8 @@
 #ifndef PERF_MODULE_H
 #define PERF_MODULE_H
 
+#include <unordered_map>
+
 #include "framework/module.h"
 
 #define PERF_NAME "perf_monitor"
 #define MAX_PERF_FILE_SIZE  UINT64_MAX
 #define MIN_PERF_FILE_SIZE  4096
 
-enum PerfFormat
+enum class PerfFormat
 {
-    PERF_CSV,
-    PERF_TEXT,
-    PERF_JSON,
-    PERF_FBS,
-    PERF_MOCK
+    CSV,
+    TEXT,
+    JSON,
+    FBS,
+    MOCK
 };
 
-enum PerfOutput
+enum class PerfOutput
 {
-    PERF_FILE,
-    PERF_CONSOLE
+    TO_FILE,
+    TO_CONSOLE
 };
 
-struct PerfConfigBase
+struct ModuleConfig
 {
+    // state optimized for run time using indicies
+    // can't be determined until all modules have loaded (PerfMonitor::configure)
+    snort::Module* ptr;
+    IndexVec pegs;
+
+    void set_name(std::string name);
+    void set_peg_names(snort::Value& peg_names);
+    bool confirm_parse();
+    bool resolve();
 
-    int perf_flags;
-    uint32_t pkt_cnt;
-    int sample_interval;
-    uint64_t max_file_size;
-    int flow_max_port_to_track;
-    uint32_t flowip_memcap;
-    PerfFormat format;
-    PerfOutput output;
+private:
+    std::string name;
+    std::unordered_map<std::string, bool> peg_names;
 };
 
-struct PerfConfig:public PerfConfigBase
+struct PerfConfig
 {
-    std::vector<snort::Module*> modules;
-    std::vector<IndexVec> mod_peg_idxs;
+    int perf_flags = 0;
+    uint32_t pkt_cnt = 0;
+    int sample_interval = 0;
+    uint64_t max_file_size = 0;
+    int flow_max_port_to_track = 0;
+    uint32_t flowip_memcap = 0;
+    PerfFormat format = PerfFormat::CSV;
+    PerfOutput output = PerfOutput::TO_FILE;
+    std::vector<ModuleConfig> modules;
+
+    bool resolve();
 };
 
 /* The Module Class for incorporation into Snort++ */
@@ -87,16 +102,13 @@ public:
     PegCount* get_counts() const override;
     snort::ProfileStats* get_profile() const override;
 
-    void get_config(PerfConfig&);
+    PerfConfig& get_config();
 
     Usage get_usage() const override
-    { return CONTEXT; }
+    { return GLOBAL; }
 
 private:
     PerfConfig config;
-
-    std::string mod_pegs;
-    std::string mod_name;
 };
 
 extern THREAD_LOCAL SimpleStats pmstats;
index 367f9c0ee04c84aa40b11b008c4eeb78b01beb74..a7ce724f86f12b92072201910f484443188a9f5d 100644 (file)
@@ -28,8 +28,7 @@
 #include "config.h"
 #endif
 
-#include "perf_monitor.h"
-
+#include "framework/data_bus.h"
 #include "log/messages.h"
 #include "managers/inspector_manager.h"
 #include "profiler/profiler.h"
@@ -39,6 +38,7 @@
 #include "cpu_tracker.h"
 #include "flow_ip_tracker.h"
 #include "flow_tracker.h"
+#include "perf_module.h"
 
 #ifdef UNIT_TEST
 #include "catch/snort_catch.h"
@@ -49,17 +49,14 @@ using namespace snort;
 THREAD_LOCAL SimpleStats pmstats;
 THREAD_LOCAL ProfileStats perfmonStats;
 
-THREAD_LOCAL bool perfmon_rotate_perf_file = false;
-static PerfConfig config;
-PerfConfig* perfmon_config = &config;   // FIXIT-M remove this after flowip can be decoupled.
 static THREAD_LOCAL std::vector<PerfTracker*>* trackers;
 
-static bool ready_to_process(Packet* p);
-
 //-------------------------------------------------------------------------
 // class stuff
 //-------------------------------------------------------------------------
 
+class PerfIdleHandler;
+class PerfRotateHandler;
 class PerfMonitor : public Inspector
 {
 public:
@@ -69,15 +66,48 @@ public:
     void show(SnortConfig*) override;
 
     void eval(Packet*) override;
+    bool ready_to_process(Packet* p);
 
     void tinit() override;
     void tterm() override;
+
+    void rotate();
+private:
+    PerfConfig& config;
+    PerfIdleHandler* idle_handler = nullptr;
+    PerfRotateHandler* rotate_handler = nullptr;
+};
+
+class PerfIdleHandler : public DataHandler
+{
+public:
+    PerfIdleHandler(PerfMonitor& p) : perf_monitor(p)
+    { DataBus::subscribe_default(THREAD_IDLE_EVENT, this); }
+
+    virtual void handle(DataEvent&, Flow*) override
+    { perf_monitor.eval(nullptr); }
+
+private:
+    PerfMonitor& perf_monitor;
 };
 
-PerfMonitor::PerfMonitor(PerfMonModule* mod)
+class PerfRotateHandler : public DataHandler
 {
-    mod->get_config(config);
-    perfmon_config = &config;
+public:
+    PerfRotateHandler(PerfMonitor& p) : perf_monitor(p)
+    { DataBus::subscribe_default(THREAD_ROTATE_EVENT, this); }
+
+    virtual void handle(DataEvent&, Flow*) override
+    { perf_monitor.rotate(); }
+
+private:
+    PerfMonitor& perf_monitor;
+};
+
+PerfMonitor::PerfMonitor(PerfMonModule* mod) : config(mod->get_config())
+{
+    idle_handler = new PerfIdleHandler(*this);
+    rotate_handler = new PerfRotateHandler(*this);
 }
 
 void PerfMonitor::show(SnortConfig*)
@@ -106,28 +136,28 @@ void PerfMonitor::show(SnortConfig*)
     }
     LogMessage("  CPU Stats:    %s\n",
         (config.perf_flags & PERF_CPU) ? "ACTIVE" : "INACTIVE");
-    switch(config.output)
+    switch ( config.output )
     {
-        case PERF_CONSOLE:
+        case PerfOutput::TO_CONSOLE:
             LogMessage("    Output Location:  console\n");
             break;
-        case PERF_FILE:
+        case PerfOutput::TO_FILE:
             LogMessage("    Output Location:  file\n");
             break;
     }
     switch(config.format)
     {
-        case PERF_TEXT:
+        case PerfFormat::TEXT:
             LogMessage("    Output Format:  text\n");
             break;
-        case PERF_CSV:
+        case PerfFormat::CSV:
             LogMessage("    Output Format:  csv\n");
             break;
-        case PERF_JSON:
+        case PerfFormat::JSON:
             LogMessage("    Output Format:  json\n");
             break;
 #ifdef HAVE_FLATBUFFERS
-        case PERF_FBS:
+        case PerfFormat::FBS:
             LogMessage("    Output Format:  flatbuffers\n");
             break;
 #endif
@@ -150,7 +180,10 @@ static void disable_tracker(size_t i)
 
 bool PerfMonitor::configure(SnortConfig*)
 {
-    return true;
+    idle_handler = new PerfIdleHandler(*this);
+    rotate_handler = new PerfRotateHandler(*this);
+
+    return config.resolve();
 }
 
 void PerfMonitor::tinit()
@@ -164,7 +197,7 @@ void PerfMonitor::tinit()
         trackers->push_back(new FlowTracker(&config));
 
     if (config.perf_flags & PERF_FLOWIP)
-        trackers->push_back(perf_flow_ip = new FlowIPTracker(&config));
+        trackers->push_back(new FlowIPTracker(&config));
 
     if (config.perf_flags & PERF_CPU )
         trackers->push_back(new CPUTracker(&config));
@@ -181,8 +214,6 @@ void PerfMonitor::tinit()
 
 void PerfMonitor::tterm()
 {
-    perf_flow_ip = nullptr;
-
     if (trackers)
     {
         while (!trackers->empty())
@@ -197,21 +228,17 @@ void PerfMonitor::tterm()
     }
 }
 
+void PerfMonitor::rotate()
+{
+    for ( unsigned i = 0; i < trackers->size(); i++ )
+        if ( !(*trackers)[i]->rotate() )
+            disable_tracker(i--);
+}
+
 void PerfMonitor::eval(Packet* p)
 {
     Profile profile(perfmonStats);
 
-    if (IsSetRotatePerfFileFlag())
-    {
-        for (unsigned i = 0; i < trackers->size(); i++)
-        {
-            if (!(*trackers)[i]->rotate())
-                disable_tracker(i--);
-        }
-
-        ClearRotatePerfFileFlag();
-    }
-
     if (p)
     {
         for (auto& tracker : *trackers)
@@ -238,17 +265,7 @@ void PerfMonitor::eval(Packet* p)
         ++pmstats.total_packets;
 }
 
-//FIXIT-M uncouple from Snort class when framework permits
-void perf_monitor_idle_process()
-{
-    PerfMonitor* pm =
-    (PerfMonitor*)InspectorManager::get_inspector("perf_monitor", true);
-
-    if ( pm )
-        pm->eval(nullptr);
-}
-
-static bool ready_to_process(Packet* p)
+bool PerfMonitor::ready_to_process(Packet* p)
 {
     static THREAD_LOCAL time_t sample_time = 0;
     static THREAD_LOCAL time_t cur_time = 0;
@@ -326,11 +343,23 @@ static const InspectApi pm_api =
     nullptr  // reset
 };
 
-const BaseApi* nin_perf_monitor = &pm_api.base;
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+#else
+const BaseApi* nin_perf_monitor[] =
+#endif
+{
+    &pm_api.base,
+    nullptr
+};
 
 #ifdef UNIT_TEST
 TEST_CASE("Process timing logic", "[perfmon]")
 {
+    PerfMonModule mod;
+    PerfConfig& config = mod.get_config();
+    PerfMonitor perfmon(&mod);
+
     Packet p(false);
     DAQ_PktHdr_t pkth;
     p.pkth = &pkth;
@@ -338,34 +367,34 @@ TEST_CASE("Process timing logic", "[perfmon]")
     config.pkt_cnt = 0;
     config.sample_interval = 0;
     pkth.ts.tv_sec = 0;
-    REQUIRE((ready_to_process(&p) == true));
+    REQUIRE((perfmon.ready_to_process(&p) == true));
     pkth.ts.tv_sec = 1;
-    REQUIRE((ready_to_process(&p) == true));
+    REQUIRE((perfmon.ready_to_process(&p) == true));
 
     config.pkt_cnt = 2;
     config.sample_interval = 0;
     pkth.ts.tv_sec = 2;
-    REQUIRE((ready_to_process(&p) == false));
+    REQUIRE((perfmon.ready_to_process(&p) == false));
     pkth.ts.tv_sec = 3;
-    REQUIRE((ready_to_process(&p) == true));
+    REQUIRE((perfmon.ready_to_process(&p) == true));
 
     config.pkt_cnt = 0;
     config.sample_interval = 2;
     pkth.ts.tv_sec = 4;
-    REQUIRE((ready_to_process(&p) == false));
+    REQUIRE((perfmon.ready_to_process(&p) == false));
     pkth.ts.tv_sec = 8;
-    REQUIRE((ready_to_process(&p) == true));
+    REQUIRE((perfmon.ready_to_process(&p) == true));
     pkth.ts.tv_sec = 10;
-    REQUIRE((ready_to_process(&p) == true));
+    REQUIRE((perfmon.ready_to_process(&p) == true));
 
     config.pkt_cnt = 5;
     config.sample_interval = 4;
     pkth.ts.tv_sec = 11;
-    REQUIRE((ready_to_process(&p) == false));
+    REQUIRE((perfmon.ready_to_process(&p) == false));
     pkth.ts.tv_sec = 14;
-    REQUIRE((ready_to_process(&p) == false));
-    REQUIRE((ready_to_process(&p) == false));
-    REQUIRE((ready_to_process(&p) == false));
-    REQUIRE((ready_to_process(&p) == true));
+    REQUIRE((perfmon.ready_to_process(&p) == false));
+    REQUIRE((perfmon.ready_to_process(&p) == false));
+    REQUIRE((perfmon.ready_to_process(&p) == false));
+    REQUIRE((perfmon.ready_to_process(&p) == true));
 }
 #endif
diff --git a/src/network_inspectors/perf_monitor/perf_monitor.h b/src/network_inspectors/perf_monitor/perf_monitor.h
deleted file mode 100644 (file)
index 3d44881..0000000
+++ /dev/null
@@ -1,56 +0,0 @@
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2002-2013 Sourcefire, Inc.
-//
-// 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.
-//--------------------------------------------------------------------------
-// perf_monitor.h author Carter Waxman <cwaxman@cisco.com>
-
-#ifndef PERF_MONITOR_H
-#define PERF_MONITOR_H
-
-// These are the basic functions and structures that are needed to call
-// performance functions.
-
-#include "perf_module.h"
-
-namespace snort
-{
-struct Packet;
-}
-
-extern PerfConfig* perfmon_config;  // FIXIT-M shouldn't be needed externally
-extern THREAD_LOCAL bool perfmon_rotate_perf_file;
-
-void perf_monitor_idle_process();
-
-/* functions to set & get the RotatePerfFileFlag */
-inline void SetRotatePerfFileFlag()
-{
-    perfmon_rotate_perf_file = true;
-}
-
-inline bool IsSetRotatePerfFileFlag()
-{
-    return perfmon_rotate_perf_file;
-}
-
-inline void ClearRotatePerfFileFlag()
-{
-    perfmon_rotate_perf_file = false;
-}
-
-#endif
-
index b751fcef4c3e9e06a9c3110b8e7fd1ef1ce28671..eeda5d17cc83e87fe16262089576e8049ab9924f 100644 (file)
@@ -59,25 +59,25 @@ static inline bool check_file_size(FILE* fh, uint64_t max_file_size)
     return false;
 }
 
-PerfTracker::PerfTracker(PerfConfig* config, bool file, const char* tracker_name)
+PerfTracker::PerfTracker(PerfConfig* config, const char* tracker_name)
 {
     this->config = config;
 
     switch (config->format)
     {
-        case PERF_CSV: formatter = new CSVFormatter(tracker_name); break;
-        case PERF_TEXT: formatter = new TextFormatter(tracker_name); break;
-        case PERF_JSON: formatter = new JSONFormatter(tracker_name); break;
+        case PerfFormat::CSV: formatter = new CSVFormatter(tracker_name); break;
+        case PerfFormat::TEXT: formatter = new TextFormatter(tracker_name); break;
+        case PerfFormat::JSON: formatter = new JSONFormatter(tracker_name); break;
 #ifdef HAVE_FLATBUFFERS
-        case PERF_FBS: formatter = new FbsFormatter(tracker_name); break;
+        case PerfFormat::FBS: formatter = new FbsFormatter(tracker_name); break;
 #endif
 #ifdef UNIT_TEST
-        case PERF_MOCK: formatter = new MockFormatter(tracker_name); break;
+        case PerfFormat::MOCK: formatter = new MockFormatter(tracker_name); break;
 #endif
         default: break;
     }
 
-    if (file)
+    if ( config->output == PerfOutput::TO_FILE )
     {
         string tracker_fname = tracker_name;
         tracker_fname += formatter->get_extension();
index f0e700ee528994f3247b5e35d90db31fd9878db4..b92a8dbdaa4f4357f4be62c0206791e4a3d0cd75 100644 (file)
 #include <ctime>
 
 #include "perf_formatter.h"
-#include "perf_monitor.h"
+#include "perf_module.h"
 
+namespace snort
+{
+    class Packet;
+}
 class PerfTracker
 {
 public:
@@ -67,7 +71,7 @@ protected:
     PerfConfig* config;
     PerfFormatter* formatter;
 
-    PerfTracker(PerfConfig*, bool file, const char* tracker_name);
+    PerfTracker(PerfConfig*, const char* tracker_name);
     virtual void write() final;
 
 private:
index b86a6f2d9a9e45e1304a8650ed08a5ac8691564c..a826688665b882ba87aff045915457007f8efa7f 100644 (file)
@@ -155,7 +155,8 @@ public:
     PortscanConfig* get_data();
 
     Usage get_usage() const override
-    { return CONTEXT; }
+    { return GLOBAL; } // FIXIT-M this should eventually be CONTEXT.
+                       // Set to GLOBAL so this isn't selected away when inspection policy switches
 
 private:
     PS_ALERT_CONF* get_alert_conf(const char* fqn);
index 7bb89a763082a5b85fff641f84f38f4a280a74eb..203d810f5be28738212ac8e54003433d4aacea08 100644 (file)
@@ -22,7 +22,9 @@
 #ifndef TCP_DEBUG_TRACE_H
 #define TCP_DEBUG_TRACE_H
 
-#include "stream/tcp/tcp_reassembler.h"
+#include "utils/stats.h"
+
+#include "tcp_reassembler.h"
 
 #ifndef REG_TEST
 #define S5TraceTCP(pkt, flow, tsd, evt)
@@ -67,7 +69,7 @@ inline void TraceEvent(const snort::Packet* p, TcpSegmentDescriptor*, uint32_t t
     uint32_t rack = ( rxd ) ? h->ack() - rxd : h->ack();
     fprintf(stdout, "\n" FMTu64("-3") " %s=0x%02x Seq=%-4u Ack=%-4u Win=%-4hu Len=%-4hu%s\n",
         //"\n" FMTu64("-3") " %s=0x%02x Seq=%-4u Ack=%-4u Win=%-4u Len=%-4u End=%-4u%s\n",
-        pc.total_from_daq, flags, h->th_flags, rseq, rack, h->win(), p->dsize, order);
+        get_packet_number(), flags, h->th_flags, rseq, rack, h->win(), p->dsize, order);
 }
 
 inline void TraceSession(const snort::Flow* lws)
index 86fee3a568cf5707f611cd8d5cdf25c73d9f8b57..1ddc0decf3b8c522f66386af9b6213f0341d8aa8 100644 (file)
@@ -51,7 +51,6 @@
 #include "detection/detection_engine.h"
 #include "detection/rules.h"
 #include "log/log.h"
-#include "perf_monitor/flow_ip_tracker.h"
 #include "profiler/profiler.h"
 #include "protocols/eth.h"
 
@@ -196,6 +195,8 @@ void TcpSession::clear_session(bool free_flow_data, bool flush_segments, bool re
 void TcpSession::update_perf_base_state(char newState)
 {
     uint32_t session_flags = flow->get_session_flags();
+    bool fire_event = false;
+
     switch ( newState )
     {
     case TcpStreamTracker::TCP_SYN_SENT:
@@ -210,11 +211,9 @@ void TcpSession::update_perf_base_state(char newState)
         if ( !( session_flags & SSNFLAG_COUNTED_ESTABLISH ) )
         {
             tcpStats.sessions_established++;
-            if ( perfmon_config && ( perfmon_config->perf_flags & PERF_FLOWIP ) )
-                perf_flow_ip->update_state(&flow->client_ip,
-                    &flow->server_ip, SFS_STATE_TCP_ESTABLISHED);
-
             session_flags |= SSNFLAG_COUNTED_ESTABLISH;
+            fire_event = true;
+
             tel.log_internal_event(INTERNAL_EVENT_SESSION_ADD);
             if ( ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
                 && !( session_flags & SSNFLAG_COUNTED_CLOSING ) )
@@ -235,10 +234,6 @@ void TcpSession::update_perf_base_state(char newState)
             {
                 assert(tcpStats.sessions_established);
                 tcpStats.sessions_established--;
-
-                if (perfmon_config  && (perfmon_config->perf_flags & PERF_FLOWIP))
-                    perf_flow_ip->update_state(&flow->client_ip, &flow->server_ip,
-                        SFS_STATE_TCP_CLOSED);
             }
             else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
             {
@@ -252,6 +247,7 @@ void TcpSession::update_perf_base_state(char newState)
         if ( !( session_flags & SSNFLAG_COUNTED_CLOSED ) )
         {
             session_flags |= SSNFLAG_COUNTED_CLOSED;
+            fire_event = true;
 
             if ( session_flags & SSNFLAG_COUNTED_CLOSING )
             {
@@ -262,10 +258,6 @@ void TcpSession::update_perf_base_state(char newState)
             {
                 assert(tcpStats.sessions_established);
                 tcpStats.sessions_established--;
-
-                if ( perfmon_config && ( perfmon_config->perf_flags & PERF_FLOWIP ) )
-                    perf_flow_ip->update_state(&flow->client_ip,
-                        &flow->server_ip, SFS_STATE_TCP_CLOSED);
             }
             else if ( session_flags & SSNFLAG_COUNTED_INITIALIZE )
             {
@@ -280,6 +272,9 @@ void TcpSession::update_perf_base_state(char newState)
     }
 
     flow->update_session_flags(session_flags);
+
+    if ( fire_event )
+        DataBus::publish(FLOW_STATE_EVENT, nullptr, flow);
 }
 
 bool TcpSession::flow_exceeds_config_thresholds(TcpSegmentDescriptor& tsd)
index 743e201b2cd13a5dfb81c80341c4dc99383d2549..147000dcdfb36c3190c563c5c7d86383d6d646c9 100644 (file)
@@ -24,7 +24,8 @@
 #include "udp_session.h"
 
 #include "flow/session.h"
-#include "perf_monitor/flow_ip_tracker.h"
+#include "framework/data_bus.h"
+#include "hash/xhash.h"
 #include "profiler/profiler_defs.h"
 #include "protocols/packet.h"
 
@@ -123,11 +124,7 @@ bool UdpSession::setup(Packet* p)
 
     SESSION_STATS_ADD(udpStats);
 
-    if (perfmon_config && (perfmon_config->perf_flags & PERF_FLOWIP))
-    {
-        perf_flow_ip->update_state(&flow->client_ip,
-            &flow->server_ip, SFS_STATE_UDP_CREATED);
-    }
+    DataBus::publish(FLOW_STATE_EVENT, p);
 
     if ( Stream::expected_flow(flow, p) )
     {