]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #3023 in SNORT/snort3 from ~RUCOMBS/snort3:pub_order to master
authorRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 25 Aug 2021 22:08:24 +0000 (22:08 +0000)
committerRuss Combs (rucombs) <rucombs@cisco.com>
Wed, 25 Aug 2021 22:08:24 +0000 (22:08 +0000)
Squashed commit of the following:

commit e1f7f82009202b4dd5f3f2f8a72b82b95decc0e6
Author: russ <rucombs@cisco.com>
Date:   Wed Aug 25 16:29:47 2021 -0400

    framework: update base API version to 7

commit f465cfcbfeace58569b37b00b62db54daa766ca2
Author: russ <rucombs@cisco.com>
Date:   Fri Aug 6 11:40:46 2021 -0400

    policy: reorganize for sanity

commit 86df6f2bf31b78cc5251c42df5dbfaa6943b8cc7
Author: russ <rucombs@cisco.com>
Date:   Fri Aug 6 11:32:37 2021 -0400

    policy: put inspection policy accessors in public space

commit 56a76559b84bff6437f5e412f807ba27c8e3bf98
Author: russ <rucombs@cisco.com>
Date:   Sat Jul 31 09:51:31 2021 -0400

    data_bus: support ordered call of handlers

    Each handler can set a desired order which defaults to zero meaning
    last. One would be first, and so on. The sequence in which handlers with
    the same order are called is unspecified.

    binder sets order 100 for flow setup events to apply policy. (That makes
    it effectively first since by default everything else is zero / last.)
    plugins which want to predictably set policy on flow setup can run
    before or after binder by setting an appropriate order.

src/framework/base_api.h
src/framework/data_bus.cc
src/framework/data_bus.h
src/framework/test/data_bus_test.cc
src/main/policy.cc
src/main/policy.h
src/managers/inspector_manager.cc
src/network_inspectors/binder/binder.cc

index e416771bedce148d4fe3eaa22cd4efb816f49a14..6de163f5c8ab3bff5aa275dd795d39558e92f89e 100644 (file)
@@ -29,7 +29,7 @@
 
 // this is the current version of the base api
 // must be prefixed to subtype version
-#define BASE_API_VERSION 6
+#define BASE_API_VERSION 7
 
 // set options to API_OPTIONS to ensure compatibility
 #ifndef API_OPTIONS
index d85d5ccfb5319a853877ec17b41aec12c0e83fac..3e41b90332daf4099ef9898d7fb182cc7a0d07e4 100644 (file)
@@ -21,6 +21,8 @@
 #include "config.h"
 #endif
 
+#include <algorithm>
+
 #include "data_bus.h"
 
 #include "main/policy.h"
@@ -142,10 +144,22 @@ void DataBus::publish(const char* key, Packet* p, Flow* f)
 // private methods
 //--------------------------------------------------------------------------
 
+static bool compare(DataHandler* a, DataHandler* b)
+{
+    if ( a->order and b->order )
+        return a->order < b->order;
+
+    if ( a->order )
+        return true;
+
+    return false;
+}
+
 void DataBus::_subscribe(const char* key, DataHandler* h)
 {
     DataList& v = map[key];
     v.emplace_back(h);
+    std::sort(v.begin(), v.end(), compare);
 }
 
 void DataBus::_unsubscribe(const char* key, DataHandler* h)
index 109ebc70374c2eed2078c196f31ed8a50c505723..2593244056fa71ffbf7bc79ad6f7b643ca0a4286 100644 (file)
@@ -77,6 +77,10 @@ public:
     const char* module_name;
     bool cloned;
 
+    // order is desired position in the call sequence of handlers: 1 = first, 0 = last
+    // the sequence among subscribers with the same order is not specified
+    unsigned order = 0;
+
 protected:
     DataHandler(std::nullptr_t) = delete;
     DataHandler(const char* mod_name) : module_name(mod_name), cloned(false) { }
index 752f2e16b52d2d36560693594360219054356283..fb97af2c9d36ebed7963a4f33f5efa5f360d728a 100644 (file)
@@ -72,19 +72,24 @@ private:
 class UTestHandler : public DataHandler
 {
 public:
-    UTestHandler() : DataHandler("unit_test")
-    { }
+    UTestHandler(unsigned u = 0) : DataHandler("unit_test")
+    { if ( u ) order = u; }
 
     void handle(DataEvent&, Flow*) override;
 
     int evt_msg = 0;
+    unsigned seq = 99;
 };
 
+static unsigned s_next = 0;
+
 void UTestHandler::handle(DataEvent& event, Flow*)
 {
     UTestEvent* evt = (UTestEvent*)&event;
     evt_msg = evt->get_message();
+    seq = ++s_next;
 }
+
 #define DB_UTEST_EVENT "unit.test.event"
 
 //--------------------------------------------------------------------------
@@ -151,6 +156,62 @@ TEST(data_bus, subscribe)
     delete h;
 }
 
+TEST(data_bus, order1)
+{
+    UTestHandler* h0 = new UTestHandler();
+    DataBus::subscribe(DB_UTEST_EVENT, h0);
+
+    UTestHandler* h1 = new UTestHandler(1);
+    DataBus::subscribe(DB_UTEST_EVENT, h1);
+
+    UTestHandler* h9 = new UTestHandler(9);
+    DataBus::subscribe(DB_UTEST_EVENT, h9);
+
+    s_next = 0;
+    UTestEvent event(100);
+    DataBus::publish(DB_UTEST_EVENT, event);
+
+    CHECK(1 == h1->seq);
+    CHECK(2 == h9->seq);
+    CHECK(3 == h0->seq);
+
+    DataBus::unsubscribe(DB_UTEST_EVENT, h0);
+    DataBus::unsubscribe(DB_UTEST_EVENT, h1);
+    DataBus::unsubscribe(DB_UTEST_EVENT, h9);
+
+    delete h0;
+    delete h1;
+    delete h9;
+}
+
+TEST(data_bus, order2)
+{
+    UTestHandler* h0 = new UTestHandler(0);
+    DataBus::subscribe(DB_UTEST_EVENT, h0);
+
+    UTestHandler* h9 = new UTestHandler(9);
+    DataBus::subscribe(DB_UTEST_EVENT, h9);
+
+    UTestHandler* h1 = new UTestHandler(1);
+    DataBus::subscribe(DB_UTEST_EVENT, h1);
+
+    s_next = 0;
+    UTestEvent event(100);
+    DataBus::publish(DB_UTEST_EVENT, event);
+
+    CHECK(1 == h1->seq);
+    CHECK(2 == h9->seq);
+    CHECK(3 == h0->seq);
+
+    DataBus::unsubscribe(DB_UTEST_EVENT, h0);
+    DataBus::unsubscribe(DB_UTEST_EVENT, h1);
+    DataBus::unsubscribe(DB_UTEST_EVENT, h9);
+
+    delete h0;
+    delete h1;
+    delete h9;
+}
+
 //-------------------------------------------------------------------------
 // main
 //-------------------------------------------------------------------------
index 6667225878b84382c60e9f4b8277cfe0e2e6499a..1c0a30864ab4c2a965c6ba48d37fff739f8f7d03 100644 (file)
@@ -293,20 +293,33 @@ InspectionPolicy* get_inspection_policy()
 IpsPolicy* get_ips_policy()
 { return s_detection_policy; }
 
-IpsPolicy* get_ips_policy(const SnortConfig* sc, unsigned i)
+void set_network_policy(NetworkPolicy* p)
+{ s_traffic_policy = p; }
+
+void set_inspection_policy(InspectionPolicy* p)
+{ s_inspection_policy = p; }
+
+void set_ips_policy(IpsPolicy* p)
+{ s_detection_policy = p; }
+
+NetworkPolicy* get_user_network_policy(const SnortConfig* sc, unsigned policy_id)
 {
-    return sc && i < sc->policy_map->ips_policy_count() ?
-        sc->policy_map->get_ips_policy(i) : nullptr;
+    return sc->policy_map->get_user_network(policy_id);
+}
+
+InspectionPolicy* get_user_inspection_policy(const SnortConfig* sc, unsigned policy_id)
+{
+    return sc->policy_map->get_user_inspection(policy_id);
 }
 
 InspectionPolicy* get_default_inspection_policy(const SnortConfig* sc)
 { return sc->policy_map->get_inspection_policy(0); }
 
-void set_ips_policy(IpsPolicy* p)
-{ s_detection_policy = p; }
-
-void set_network_policy(NetworkPolicy* p)
-{ s_traffic_policy = p; }
+IpsPolicy* get_ips_policy(const SnortConfig* sc, unsigned i)
+{
+    return sc && i < sc->policy_map->ips_policy_count() ?
+        sc->policy_map->get_ips_policy(i) : nullptr;
+}
 
 IpsPolicy* get_user_ips_policy(const SnortConfig* sc, unsigned policy_id)
 {
@@ -317,11 +330,6 @@ IpsPolicy* get_empty_ips_policy(const SnortConfig* sc)
 {
     return sc->policy_map->get_empty_ips();
 }
-
-NetworkPolicy* get_user_network_policy(const SnortConfig* sc, unsigned policy_id)
-{
-    return sc->policy_map->get_user_network(policy_id);
-}
 } // namespace snort
 
 void set_network_policy(const SnortConfig* sc, unsigned i)
@@ -332,9 +340,6 @@ void set_network_policy(const SnortConfig* sc, unsigned i)
         set_network_policy(pm->get_network_policy(i));
 }
 
-void set_inspection_policy(InspectionPolicy* p)
-{ s_inspection_policy = p; }
-
 void set_inspection_policy(const SnortConfig* sc, unsigned i)
 {
     PolicyMap* pm = sc->policy_map;
@@ -372,6 +377,15 @@ void set_default_policy(const SnortConfig* sc)
     set_ips_policy(sc->policy_map->get_ips_policy(0));
 }
 
+bool only_network_policy()
+{ return get_network_policy() && !get_ips_policy() && !get_inspection_policy(); }
+
+bool only_inspection_policy()
+{ return get_inspection_policy() && !get_ips_policy() && !get_network_policy(); }
+
+bool only_ips_policy()
+{ return get_ips_policy() && !get_inspection_policy() && !get_network_policy(); }
+
 bool default_inspection_policy()
 {
     if ( !get_inspection_policy() )
@@ -383,12 +397,3 @@ bool default_inspection_policy()
     return true;
 }
 
-bool only_inspection_policy()
-{ return get_inspection_policy() && !get_ips_policy() && !get_network_policy(); }
-
-bool only_ips_policy()
-{ return get_ips_policy() && !get_inspection_policy() && !get_network_policy(); }
-
-bool only_network_policy()
-{ return get_network_policy() && !get_ips_policy() && !get_inspection_policy(); }
-
index 5cc7025fe47644576a6a33735006726b92a56ae9..bb32a061400638491eda9cd87802f177ede5abb3 100644 (file)
@@ -219,14 +219,26 @@ public:
     Shell* get_shell(unsigned i = 0)
     { return i < shells.size() ? shells[i] : nullptr; }
 
+    void set_user_network(NetworkPolicy* p)
+    { user_network[p->user_policy_id] = p; }
+
     void set_user_inspection(InspectionPolicy* p)
     { user_inspection[p->user_policy_id] = p; }
 
     void set_user_ips(IpsPolicy* p)
     { user_ips[p->user_policy_id] = p; }
 
-    void set_user_network(NetworkPolicy* p)
-    { user_network[p->user_policy_id] = p; }
+    NetworkPolicy* get_user_network(unsigned user_id)
+    {
+        auto it = user_network.find(user_id);
+        return it == user_network.end() ? nullptr : it->second;
+    }
+
+    InspectionPolicy* get_user_inspection(unsigned user_id)
+    {
+        auto it = user_inspection.find(user_id);
+        return it == user_inspection.end() ? nullptr : it->second;
+    }
 
     IpsPolicy* get_user_ips(unsigned user_id)
     {
@@ -234,11 +246,8 @@ public:
         return it == user_ips.end() ? nullptr : it->second;
     }
 
-    NetworkPolicy* get_user_network(unsigned user_id)
-    {
-        auto it = user_network.find(user_id);
-        return it == user_network.end() ? nullptr : it->second;
-    }
+    NetworkPolicy* get_network_policy(unsigned i = 0)
+    { return i < network_policy.size() ? network_policy[i] : nullptr; }
 
     InspectionPolicy* get_inspection_policy(unsigned i = 0)
     { return i < inspection_policy.size() ? inspection_policy[i] : nullptr; }
@@ -249,8 +258,8 @@ public:
     IpsPolicy* get_empty_ips()
     { return empty_ips_policy; }
 
-    NetworkPolicy* get_network_policy(unsigned i = 0)
-    { return i < network_policy.size() ? network_policy[i] : nullptr; }
+    unsigned network_policy_count()
+    { return network_policy.size(); }
 
     unsigned inspection_policy_count()
     { return inspection_policy.size(); }
@@ -258,9 +267,6 @@ public:
     unsigned ips_policy_count()
     { return ips_policy.size(); }
 
-    unsigned network_policy_count()
-    { return network_policy.size(); }
-
     unsigned shells_count()
     { return shells.size(); }
 
@@ -280,21 +286,21 @@ private:
     std::vector<InspectionPolicy*> inspection_policy;
     std::vector<IpsPolicy*> ips_policy;
     std::vector<NetworkPolicy*> network_policy;
+
     IpsPolicy* empty_ips_policy;
+
     std::unordered_map<Shell*, std::shared_ptr<PolicyTuple>> shell_map;
+    std::unordered_map<unsigned, NetworkPolicy*> user_network;
     std::unordered_map<unsigned, InspectionPolicy*> user_inspection;
     std::unordered_map<unsigned, IpsPolicy*> user_ips;
-    std::unordered_map<unsigned, NetworkPolicy*> user_network;
 
     bool cloned = false;
-
 };
 
 //-------------------------------------------------------------------------
 // navigator stuff
 //-------------------------------------------------------------------------
 
-
 // FIXIT-L may be inlined at some point; on lockdown for now
 // FIXIT-L SO_PUBLIC required because SnortConfig::inline_mode(), etc. uses the function
 namespace snort
@@ -302,29 +308,31 @@ namespace snort
 SO_PUBLIC NetworkPolicy* get_network_policy();
 SO_PUBLIC InspectionPolicy* get_inspection_policy();
 SO_PUBLIC IpsPolicy* get_ips_policy();
-SO_PUBLIC IpsPolicy* get_ips_policy(const snort::SnortConfig*, unsigned i = 0);
-SO_PUBLIC InspectionPolicy* get_default_inspection_policy(const snort::SnortConfig*);
-SO_PUBLIC void set_ips_policy(IpsPolicy*);
+
 SO_PUBLIC void set_network_policy(NetworkPolicy*);
+SO_PUBLIC void set_inspection_policy(InspectionPolicy*);
+SO_PUBLIC void set_ips_policy(IpsPolicy*);
+
+SO_PUBLIC NetworkPolicy* get_user_network_policy(const snort::SnortConfig*, unsigned policy_id);
+SO_PUBLIC InspectionPolicy* get_user_inspection_policy(const snort::SnortConfig*, unsigned policy_id);
+SO_PUBLIC InspectionPolicy* get_default_inspection_policy(const snort::SnortConfig*);
+
+SO_PUBLIC IpsPolicy* get_ips_policy(const snort::SnortConfig*, unsigned i = 0);
 SO_PUBLIC IpsPolicy* get_user_ips_policy(const snort::SnortConfig*, unsigned policy_id);
 SO_PUBLIC IpsPolicy* get_empty_ips_policy(const snort::SnortConfig*);
-SO_PUBLIC NetworkPolicy* get_user_network_policy(const snort::SnortConfig*, unsigned policy_id);
 }
 
 void set_network_policy(const snort::SnortConfig*, unsigned = 0);
-
-void set_inspection_policy(InspectionPolicy*);
 void set_inspection_policy(const snort::SnortConfig*, unsigned = 0);
-
 void set_ips_policy(const snort::SnortConfig*, unsigned = 0);
 
 void set_policies(const snort::SnortConfig*, Shell*);
 void set_default_policy(const snort::SnortConfig*);
 
-bool default_inspection_policy();
+bool only_network_policy();
 bool only_inspection_policy();
 bool only_ips_policy();
-bool only_network_policy();
 
+bool default_inspection_policy();
 #endif
 
index 44c0cd90da86ed595dce09a91450f2a1140619f2..c02a2586ef15520412f4f34f2fc2654e1a22cd53 100644 (file)
@@ -1036,13 +1036,13 @@ bool InspectorManager::configure(SnortConfig* sc, bool cloned)
         if ( cloned and idx )
             break;
 
-        set_inspection_policy(sc, idx);
+        ::set_inspection_policy(sc, idx);
         InspectionPolicy* p = sc->policy_map->get_inspection_policy(idx);
         p->configure();
         ok = ::configure(sc, p->framework_policy, cloned) && ok;
     }
 
-    set_inspection_policy(sc);
+    ::set_inspection_policy(sc);
     SearchTool::set_conf(nullptr);
 
     return ok;
index 7cdb1219736929e68ff9a19fb1b5e98f50f073d5..c66569c122134620f58327c35fd5f04fb402df9b 100644 (file)
@@ -468,7 +468,8 @@ private:
 class FlowStateSetupHandler : public DataHandler
 {
 public:
-    FlowStateSetupHandler() : DataHandler(BIND_NAME) { }
+    FlowStateSetupHandler() : DataHandler(BIND_NAME)
+    { order = 100; }
 
     void handle(DataEvent&, Flow* flow) override
     {