]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1257 in SNORT/snort3 from passive_binder to master
authorMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 20 Jun 2018 13:49:18 +0000 (09:49 -0400)
committerMichael Altizer (mialtize) <mialtize@cisco.com>
Wed, 20 Jun 2018 13:49:18 +0000 (09:49 -0400)
Squashed commit of the following:

commit 3b7b3e7d59a842b64e7d338be21225f0d89d2594
Author: Michael Altizer <mialtize@cisco.com>
Date:   Tue Jun 5 19:56:37 2018 -0400

    binder: Refactor binder as a passive, event-driven inspector

src/flow/flow_control.cc
src/framework/data_bus.h
src/framework/inspector.h
src/managers/inspector_manager.cc
src/managers/inspector_manager.h
src/network_inspectors/binder/CMakeLists.txt
src/network_inspectors/binder/binder.cc
src/network_inspectors/binder/binder.h [deleted file]
src/stream/base/stream_ha.cc

index 42753d8df2e19f32217fecdbb53ebf090180394b..c07887d643fb7d0c0582d6cbe3f0ad398b739d80 100644 (file)
@@ -416,13 +416,11 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
     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;
index 127f733b9d10476d61f961e52bb0fcac9bbca0fd..c37a36640520864c1a11522bf9d0738e56f07035 100644 (file)
@@ -59,6 +59,13 @@ protected:
     DataEvent() = default;
 };
 
+class BareDataEvent final : public DataEvent
+{
+public:
+    BareDataEvent() = default;
+    ~BareDataEvent() override = default;
+};
+
 class DataHandler
 {
 public:
@@ -123,15 +130,24 @@ private:
 };
 }
 
-// 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
 
index 75aa7800f82483980834133c59fd99c921d06ef2..ed4509a0ba735df5ac98e26a547173fcff2de179 100644 (file)
@@ -91,7 +91,6 @@ public:
     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]; }
@@ -172,7 +171,6 @@ public:
 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)
index c6b9e6600027d3dea561ff3346b1ccbc3852ca50..1f2242625283f05cbc0ef3b50a4c9ce404e01792 100644 (file)
@@ -27,7 +27,6 @@
 #include <vector>
 
 #include "binder/bind_module.h"
-#include "binder/binder.h"
 #include "detection/detect.h"
 #include "detection/detection_engine.h"
 #include "flow/flow.h"
@@ -248,6 +247,9 @@ void FrameworkPolicy::vectorize()
         {
         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:
@@ -267,10 +269,6 @@ void FrameworkPolicy::vectorize()
             service.add(p);
             break;
 
-        case IT_BINDER:
-            binder = p->handler;
-            break;
-
         case IT_WIZARD:
             wizard = p->handler;
             break;
@@ -415,7 +413,7 @@ static PHInstance* get_instance(
         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(
@@ -502,14 +500,14 @@ void InspectorManager::dispatch_meta(FrameworkPolicy* fp, int type, const uint8_
         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
@@ -555,7 +553,7 @@ bool InspectorManager::delete_inspector(SnortConfig* sc, const char* iname)
         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);
         }
@@ -740,7 +738,7 @@ Inspector* InspectorManager::instantiate(
 #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;
@@ -798,7 +796,7 @@ static bool configure(SnortConfig* sc, FrameworkPolicy* fp, bool cloned)
     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 )
             {
@@ -823,7 +821,7 @@ static bool configure(SnortConfig* sc, FrameworkPolicy* fp, bool cloned)
     // 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;
 }
@@ -918,10 +916,8 @@ static inline void execute(
 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();
 
index d6b57c01688c6b2a818a054da50d23b9d866b54c..6fe1fb26aad69be8e6299ccf0706bab78fef9a9d 100644 (file)
 
 #include "framework/inspector.h"
 
-#ifdef PIGLET
-#include "framework/inspector.h"
-#endif
-
+class Binder;
 struct FrameworkPolicy;
 struct InspectionPolicy;
 
@@ -64,7 +61,7 @@ public:
     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*);
index 3b5a833e68d45a17cca9ee730e78052a80a2ee88..2bb28f3ed0c1450be457dadee1149ba6d9312e2f 100644 (file)
@@ -1,7 +1,6 @@
 
 set(FILE_LIST
     binder.cc
-    binder.h
     binding.h
     bind_module.cc
     bind_module.h
index 8a679300d99465491ce69bf21e9d1459d26d2e1c..8d0b603e3a8fed842d5becdf041f4db392519a3a 100644 (file)
@@ -21,8 +21,6 @@
 #include "config.h"
 #endif
 
-#include "binder.h"
-
 #include "flow/flow.h"
 #include "flow/flow_key.h"
 #include "framework/data_bus.h"
@@ -577,12 +575,15 @@ public:
 
     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*);
 
@@ -590,24 +591,48 @@ private:
     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);
     }
 };
 
@@ -644,7 +669,9 @@ bool Binder::configure(SnortConfig* sc)
             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;
 }
@@ -669,7 +696,7 @@ void Binder::remove_inspector_binding(SnortConfig*, const char* name)
     }
 }
 
-void Binder::eval(Packet* p)
+void Binder::handle_flow_setup(Packet* p)
 {
     Profile profile(bindPerfStats);
     Stuff stuff;
@@ -682,11 +709,12 @@ void Binder::eval(Packet* p)
     ++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 )
@@ -700,7 +728,7 @@ int Binder::exec_handle_gadget( void* pv )
         flow->ssn_state.snort_protocol_id = SnortConfig::get_conf()->proto_ref->find(flow->service);
 
     if ( !flow->is_stream() )
-        return 0;
+        return;
 
     if ( ins )
     {
@@ -712,36 +740,17 @@ int Binder::exec_handle_gadget( void* pv )
         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);
-    }
 }
 
 //-------------------------------------------------------------------------
@@ -825,7 +834,7 @@ void Binder::get_bindings(Flow* flow, Stuff& stuff, Packet* p)
         }
     }
 
-    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 )
@@ -909,7 +918,7 @@ static const InspectApi bind_api =
         mod_ctor,
         mod_dtor
     },
-    IT_BINDER,
+    IT_PASSIVE,
     PROTO_BIT__ANY_TYPE,
     nullptr, // buffers
     nullptr, // service
diff --git a/src/network_inspectors/binder/binder.h b/src/network_inspectors/binder/binder.h
deleted file mode 100644 (file)
index 1a01ccf..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-//--------------------------------------------------------------------------
-// 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
-
index f5f69c19bec34af0717f3e609fa1d1054cb0553a..641125e45e01ea62c3f70086d109196d46024700 100644 (file)
@@ -25,7 +25,6 @@
 
 #include <unordered_map>
 
-#include "binder/binder.h"
 #include "flow/flow_key.h"
 #include "managers/inspector_manager.h"
 #include "stream/stream.h"
@@ -107,9 +106,10 @@ bool StreamHAClient::consume(Flow*& flow, FlowKey* key, HAMessage* msg)
         // 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 )