class LogHandler : public DataHandler
{
public:
- LogHandler(FileLogConfig& conf)
+ LogHandler(FileLogConfig& conf) : DataHandler(s_name)
{ config = conf; }
void handle(DataEvent&, Flow*) override;
{
for ( auto& p : map )
for ( auto* h : p.second )
- delete h;
+ {
+ // If the object is cloned, pass the ownership to the next config.
+ // When the object is no further cloned (e.g., the last config), delete it.
+ if ( h->cloned )
+ h->cloned = false;
+ else
+ delete h;
+ }
+
+ mapped_module.clear();
+}
+
+void DataBus::add_mapped_module(const char* name)
+{
+ if ( name )
+ mapped_module.emplace(name);
+}
+
+void DataBus::clone(DataBus& from)
+{
+ for ( auto& p : from.map )
+ for ( auto* h : p.second )
+ if ( mapped_module.count(h->module_name) == 0 )
+ {
+ h->cloned = true;
+ _subscribe(p.first.c_str(), h);
+ }
}
// add handler to list of handlers to be notified upon
{
DataList& v = map[key];
v.emplace_back(h);
+
+ // Track fresh subscriptions to distinguish during cloning
+ if ( !h->cloned )
+ add_mapped_module(h->module_name);
}
void DataBus::_unsubscribe(const char* key, DataHandler* h)
#include <map>
#include <string>
+#include <unordered_set>
#include <vector>
#include "main/snort_types.h"
virtual ~DataHandler() = default;
virtual void handle(DataEvent&, Flow*) { }
+ const char* module_name;
+ bool cloned;
protected:
- DataHandler() = default;
+ DataHandler(std::nullptr_t) = delete;
+ DataHandler(const char* mod_name) : module_name(mod_name), cloned(false) { }
};
// FIXIT-P evaluate perf; focus is on correctness
typedef std::vector<DataHandler*> DataList;
typedef std::map<std::string, DataList> DataMap;
+typedef std::unordered_set<const char*> DataModule;
class SO_PUBLIC DataBus
{
DataBus();
~DataBus();
+ void clone(DataBus& from);
+ void add_mapped_module(const char*);
+
static void subscribe(const char* key, DataHandler*);
static void subscribe_default(const char* key, DataHandler*);
static void unsubscribe(const char* key, DataHandler*);
private:
DataMap map;
+ DataModule mapped_module;
};
class SO_PUBLIC DaqMetaEvent : public DataEvent
class DaqMetaEventHandler : public DataHandler
{
public:
- DaqMetaEventHandler() = default;
+ DaqMetaEventHandler() : DataHandler(S_NAME) { }
void handle(DataEvent&, Flow*) override;
};
class AltPktHandler : public DataHandler
{
public:
- AltPktHandler() = default;
+ AltPktHandler() : DataHandler("detection") { }
void handle(DataEvent& e, Flow*) override
{ DetectionEngine::detect(const_cast<Packet*>(e.get_packet())); }
dbus.subscribe(PACKET_EVENT, new AltPktHandler);
}
+void InspectionPolicy::clone_dbus(SnortConfig* from, const char* exclude_module)
+{
+ // Clone subscriptions from another config if they are not excluded
+ // (e.g., reloading module) and not already subscribed
+ dbus.add_mapped_module(exclude_module);
+ dbus.clone(from->policy_map->get_inspection_policy()->dbus);
+}
+
//-------------------------------------------------------------------------
// detection policy
//-------------------------------------------------------------------------
namespace snort
{
struct GHash;
+struct SnortConfig;
}
struct PortTable;
~InspectionPolicy();
void configure();
+ void clone_dbus(snort::SnortConfig*, const char*);
public:
PolicyId policy_id;
// FIXIT-L SO_PUBLIC required because SnortConfig::inline_mode(), etc. uses the function
namespace snort
{
-struct SnortConfig;
-
SO_PUBLIC NetworkPolicy* get_network_policy();
SO_PUBLIC InspectionPolicy* get_inspection_policy();
SO_PUBLIC IpsPolicy* get_ips_policy();
}
other_conf->cloned = true;
-
+ sc->policy_map->get_inspection_policy()->clone_dbus(other_conf, iname);
InspectorManager::update_policy(sc);
reloading = false;
return sc;
if ( name )
{
+ ModuleManager::reset_errors();
ModuleManager::reload_module(name, sc);
if ( ModuleManager::get_errors() || !sc->verify() )
{
}
other_conf->cloned = true;
-
+ sc->policy_map->get_inspection_policy()->clone_dbus(other_conf, name);
InspectorManager::update_policy(sc);
reloading = false;
return sc;
{
cout << "Module " << name <<" doesn't exist";
cout << endl;
+ ++s_errors;
}
}
#include "pub_sub/http_events.h"
+#include "appid_module.h"
+
namespace snort
{
class Flow;
RESPONSE_EVENT,
};
- HttpEventHandler(HttpEventType type)
+ HttpEventHandler(HttpEventType type) : DataHandler(MOD_NAME)
{
event_type = type;
}
#include "framework/data_bus.h"
#include "pub_sub/sip_events.h"
+#include "appid_module.h"
+
namespace snort
{
class Flow;
void handle(snort::DataEvent&, snort::Flow*) override;
private:
- SipEventHandler() = default;
+ SipEventHandler() : DataHandler(MOD_NAME) { }
void client_handler(SipEvent&, AppIdSession&, AppidChangeBits&);
void service_handler(SipEvent&, AppIdSession&, AppidChangeBits&);
class FlowStateSetupHandler : public DataHandler
{
public:
- FlowStateSetupHandler() = default;
+ FlowStateSetupHandler() : DataHandler(BIND_NAME) { }
void handle(DataEvent& event, Flow* flow) override
{
class FlowServiceChangeHandler : public DataHandler
{
public:
- FlowServiceChangeHandler() = default;
+ FlowServiceChangeHandler() : DataHandler(BIND_NAME) { }
void handle(DataEvent&, Flow* flow) override
{
class StreamHANewFlowHandler : public DataHandler
{
public:
- StreamHANewFlowHandler() = default;
+ StreamHANewFlowHandler() : DataHandler(BIND_NAME) { }
void handle(DataEvent&, Flow* flow) override
{
class PerfIdleHandler : public DataHandler
{
public:
- PerfIdleHandler(PerfMonitor& p) : perf_monitor(p)
+ PerfIdleHandler(PerfMonitor& p) : DataHandler(PERF_NAME), perf_monitor(p)
{ DataBus::subscribe_default(THREAD_IDLE_EVENT, this); }
void handle(DataEvent&, Flow*) override
class PerfRotateHandler : public DataHandler
{
public:
- PerfRotateHandler(PerfMonitor& p) : perf_monitor(p)
+ PerfRotateHandler(PerfMonitor& p) : DataHandler(PERF_NAME), perf_monitor(p)
{ DataBus::subscribe_default(THREAD_ROTATE_EVENT, this); }
void handle(DataEvent&, Flow*) override
class FlowIPDataHandler : public DataHandler
{
public:
- FlowIPDataHandler(PerfMonitor& p) : perf_monitor(p)
+ FlowIPDataHandler(PerfMonitor& p) : DataHandler(PERF_NAME), perf_monitor(p)
{ DataBus::subscribe_default(FLOW_STATE_EVENT, this); }
void handle(DataEvent&, Flow* flow) override