else
{
init_roles(p, flow);
- Inspector* b = InspectorManager::get_binder();
+ DataBus::publish(FLOW_STATE_SETUP_EVENT, p);
- if ( b )
- b->eval(p);
-
- if ( !b || (flow->flow_state == Flow::FlowState::INSPECT &&
- (!flow->ssn_client || !flow->session->setup(p))) )
+ if ( flow->flow_state == Flow::FlowState::SETUP ||
+ (flow->flow_state == Flow::FlowState::INSPECT &&
+ (!flow->ssn_client || !flow->session->setup(p))) )
flow->set_state(Flow::FlowState::ALLOW);
++news;
DataEvent() = default;
};
+class BareDataEvent final : public DataEvent
+{
+public:
+ BareDataEvent() = default;
+ ~BareDataEvent() override = default;
+};
+
class DataHandler
{
public:
};
}
-// common data events
+//
+// Common core functionality 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"
-// An event that indicates that the service on a flow has been updated.
-#define FLOW_SERVICE_CHANGE_EVENT "flow_service_change_event"
+// A flow changed its service
+#define FLOW_SERVICE_CHANGE_EVENT "flow.service_change_event"
+
+// A flow has entered the setup state
+#define FLOW_STATE_SETUP_EVENT "flow.state_setup"
+
+// A new standby flow was generated by stream high availability
+#define STREAM_HA_NEW_FLOW_EVENT "stream.ha.new_flow"
#endif
virtual void clear(Packet*) { }
virtual void meta(int, const uint8_t*) { }
- virtual int exec(int, void*) { return 0; }
// framework support
unsigned get_ref(unsigned i) { return ref_count[i]; }
enum InspectorType
{
IT_PASSIVE, // config only, or data consumer (eg file_log, binder, ftp_client)
- IT_BINDER, // maps config to traffic
IT_WIZARD, // guesses service inspector
IT_PACKET, // processes raw packets only (eg normalize, capture)
IT_STREAM, // flow tracking and reassembly (eg ip, tcp, udp)
#include <vector>
#include "binder/bind_module.h"
-#include "binder/binder.h"
#include "detection/detect.h"
#include "detection/detection_engine.h"
#include "flow/flow.h"
{
case IT_PASSIVE :
passive.add(p);
+ // FIXIT-L Ugly special case for noticing a binder
+ if ( !strcmp(p->pp_class.api.base.name, bind_id) )
+ binder = p->handler;
break;
case IT_PACKET:
service.add(p);
break;
- case IT_BINDER:
- binder = p->handler;
- break;
-
case IT_WIZARD:
wizard = p->handler;
break;
FrameworkPolicy* fp, const char* keyword, bool dflt_only = false)
{
std::vector<PHInstance*>::iterator it;
- return get_instance(fp, keyword, dflt_only, it)? *it : nullptr;
+ return get_instance(fp, keyword, dflt_only, it) ? *it : nullptr;
}
static PHInstance* get_new(
p->handler->meta(type, data);
}
-Inspector* InspectorManager::get_binder()
+Binder* InspectorManager::get_binder()
{
InspectionPolicy* pi = snort::get_inspection_policy();
if ( !pi || !pi->framework_policy )
return nullptr;
- return pi->framework_policy->binder;
+ return (Binder*) pi->framework_policy->binder;
}
// FIXIT-P cache get_inspector() returns or provide indexed lookup
fp->ilist.erase(old_it);
ok = true;
std::vector<PHInstance*>::iterator bind_it;
- if ( get_instance(fp, "binder", false, bind_it) )
+ if ( get_instance(fp, bind_id, false, bind_it) )
{
(*bind_it)->handler->remove_inspector_binding(sc, iname);
}
#endif
// create default binding for wizard and configured services
-static void instantiate_binder(SnortConfig* sc, FrameworkPolicy* fp)
+static void instantiate_default_binder(SnortConfig* sc, FrameworkPolicy* fp)
{
BinderModule* m = (BinderModule*)ModuleManager::get_module(bind_id);
bool tcp = false, udp = false, pdu = false;
if ( new_ins or reenabled_ins )
{
std::vector<PHInstance*>::iterator old_binder;
- if ( get_instance(fp, "binder", false, old_binder) )
+ if ( get_instance(fp, bind_id, false, old_binder) )
{
if ( new_ins and fp->default_binder )
{
// can't bind wizard but this exposes other issues that must
// be fixed first.
if ( fp->session.num and !fp->binder /*and fp->wizard*/ )
- instantiate_binder(sc, fp);
+ instantiate_default_binder(sc, fp);
return ok;
}
void InspectorManager::bumble(Packet* p)
{
Flow* flow = p->flow;
- Inspector* ins = get_binder();
- if ( ins )
- ins->exec(BinderSpace::ExecOperation::HANDLE_GADGET, flow);
+ DataBus::publish(FLOW_SERVICE_CHANGE_EVENT, p);
flow->clear_clouseau();
#include "framework/inspector.h"
-#ifdef PIGLET
-#include "framework/inspector.h"
-#endif
-
+class Binder;
struct FrameworkPolicy;
struct InspectionPolicy;
static InspectorType get_type(const char* key);
SO_PUBLIC static Inspector* get_inspector(const char* key, bool dflt_only = false);
- SO_PUBLIC static Inspector* get_binder();
+ SO_PUBLIC static Binder* get_binder();
SO_PUBLIC static Inspector* acquire(const char* key, bool dflt_only = false);
SO_PUBLIC static void release(Inspector*);
set(FILE_LIST
binder.cc
- binder.h
binding.h
bind_module.cc
bind_module.h
#include "config.h"
#endif
-#include "binder.h"
-
#include "flow/flow.h"
#include "flow/flow_key.h"
#include "framework/data_bus.h"
bool configure(SnortConfig*) override;
- void eval(Packet*) override;
- int exec(int, void*) override;
+ void eval(Packet*) override { }
void add(Binding* b)
{ bindings.push_back(b); }
+ void handle_flow_setup(Packet*);
+ void handle_flow_service_change(Flow*);
+ void handle_new_standby_flow(Flow*);
+
private:
void apply(const Stuff&, Flow*);
void get_bindings(Flow*, Stuff&, Packet* = nullptr); // may be null when dealing with HA flows
void apply(Flow*, Stuff&);
Inspector* find_gadget(Flow*);
- int exec_handle_gadget(void*);
- int exec_eval_standby_flow(void*);
private:
vector<Binding*> bindings;
};
+class FlowStateSetupHandler : public DataHandler
+{
+public:
+ FlowStateSetupHandler() = default;
+
+ void handle(DataEvent& event, Flow* flow) override
+ {
+ Binder* binder = InspectorManager::get_binder();
+ if (binder && flow)
+ binder->handle_flow_setup(const_cast<Packet*>(event.get_packet()));
+ }
+};
+
// When a flow's service changes, re-evaluate service to inspector mapping.
class FlowServiceChangeHandler : public DataHandler
{
public:
- FlowServiceChangeHandler() { }
+ FlowServiceChangeHandler() = default;
+
+ void handle(DataEvent&, Flow* flow) override
+ {
+ Binder* binder = InspectorManager::get_binder();
+ if (binder && flow)
+ binder->handle_flow_service_change(flow);
+ }
+};
+
+class StreamHANewFlowHandler : public DataHandler
+{
+public:
+ StreamHANewFlowHandler() = default;
void handle(DataEvent&, Flow* flow) override
{
- Binder* binder = (Binder*)InspectorManager::get_binder();
- if(binder and flow)
- binder->exec(BinderSpace::ExecOperation::HANDLE_GADGET, flow);
+ Binder* binder = InspectorManager::get_binder();
+ if (binder && flow)
+ binder->handle_new_standby_flow(flow);
}
};
set_binding(sc, pb);
}
- DataBus::subscribe(FLOW_SERVICE_CHANGE_EVENT, new FlowServiceChangeHandler);
+ DataBus::subscribe(FLOW_STATE_SETUP_EVENT, new FlowStateSetupHandler());
+ DataBus::subscribe(FLOW_SERVICE_CHANGE_EVENT, new FlowServiceChangeHandler());
+ DataBus::subscribe(STREAM_HA_NEW_FLOW_EVENT, new StreamHANewFlowHandler());
return true;
}
}
}
-void Binder::eval(Packet* p)
+void Binder::handle_flow_setup(Packet* p)
{
Profile profile(bindPerfStats);
Stuff stuff;
++bstats.packets;
}
-int Binder::exec_handle_gadget( void* pv )
+void Binder::handle_flow_service_change( Flow* flow )
{
- assert(pv);
+ Profile profile(bindPerfStats);
+
+ assert(flow);
- Flow* flow = (Flow*)pv;
Inspector* ins = find_gadget(flow);
if ( ins )
flow->ssn_state.snort_protocol_id = SnortConfig::get_conf()->proto_ref->find(flow->service);
if ( !flow->is_stream() )
- return 0;
+ return;
if ( ins )
{
Stream::set_splitter(flow, true, new AtomSplitter(true));
Stream::set_splitter(flow, false, new AtomSplitter(false));
}
-
- return 0;
}
-// similar to eval(), but working on a Flow in HA Standby mode
-int Binder::exec_eval_standby_flow( void* pv )
+void Binder::handle_new_standby_flow( Flow* flow )
{
- Flow* flow = (Flow*)pv;
+ Profile profile(bindPerfStats);
Stuff stuff;
get_bindings(flow, stuff);
apply(flow, stuff);
++bstats.verdicts[stuff.action];
- return 0;
-}
-
-int Binder::exec(int operation, void* pv)
-{
- Profile profile(bindPerfStats);
-
- switch( operation )
- {
- case BinderSpace::ExecOperation::HANDLE_GADGET:
- return exec_handle_gadget( pv );
- case BinderSpace::ExecOperation::EVAL_STANDBY_FLOW:
- return exec_eval_standby_flow( pv );
- default:
- return (-1);
- }
}
//-------------------------------------------------------------------------
}
}
- Binder* sub = (Binder*)InspectorManager::get_binder();
+ Binder* sub = InspectorManager::get_binder();
// If policy selection produced a new binder to use, use that instead.
if ( sub && sub != this )
mod_ctor,
mod_dtor
},
- IT_BINDER,
+ IT_PASSIVE,
PROTO_BIT__ANY_TYPE,
nullptr, // buffers
nullptr, // service
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2016-2018 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.
-//--------------------------------------------------------------------------
-
-// binder.h author Ed Borgoyn <eborgoyn@cisco.com>
-
-#ifndef BINDER_H
-#define BINDER_H
-
-namespace BinderSpace
-{
- enum ExecOperation : int { HANDLE_GADGET, EVAL_STANDBY_FLOW };
-}
-
-#endif
-
#include <unordered_map>
-#include "binder/binder.h"
#include "flow/flow_key.h"
#include "managers/inspector_manager.h"
#include "stream/stream.h"
// A nullptr indicates that the protocol has no handler
if ( (flow = protocol_create_session(key)) == nullptr )
return false;
- Inspector* b = InspectorManager::get_binder();
- if ( b != nullptr )
- b->exec(BinderSpace::ExecOperation::EVAL_STANDBY_FLOW,(void*)flow);
+
+ BareDataEvent event;
+ DataBus::publish(STREAM_HA_NEW_FLOW_EVENT, event, flow);
+
flow->ha_state->clear(FlowHAState::NEW);
int family = (hac->flags & SessionHAContent::FLAG_IP6) ? AF_INET6 : AF_INET;
if ( hac->flags & SessionHAContent::FLAG_LOW )