]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Pull request #3371: Fix most of the perf drop from multi-tenant code
authorRon Dempster (rdempste) <rdempste@cisco.com>
Fri, 15 Apr 2022 15:26:44 +0000 (15:26 +0000)
committerRon Dempster (rdempste) <rdempste@cisco.com>
Fri, 15 Apr 2022 15:26:44 +0000 (15:26 +0000)
Merge in SNORT/snort3 from ~RDEMPSTE/snort3:perf to master

Squashed commit of the following:

commit c14d36a3e41f083d4a80199b22b40b601166419f
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Mon Apr 11 09:58:36 2022 -0400

    flow: only select policies when deleting flow data if there is a policy selector

commit c38b0b61f1a9b8a7e359ff81a5468a59567a5260
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Sun Apr 10 16:26:12 2022 -0400

    flow, snort_config: change service back to a pointer and add a method to return a non-volatile pointer for service

commit a9b120ee80a12c64e59f475f56db4477ffc88c08
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Thu Apr 7 11:14:26 2022 -0400

    flow: use a flag instead off shared pointer use count for has service check

commit 429fa43a6346f6e67e2ddb98238e2fc1f340aaa3
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Fri Apr 1 12:32:23 2022 -0400

    flow, managers, binder: only publish flow state reloaded event from internal execute

commit 4f2429b5140895ea377a49029e387f5b509de5ca
Author: Ron Dempster (rdempste) <rdempste@cisco.com>
Date:   Thu Mar 31 14:09:29 2022 -0400

    main: check policy exists instead of index when setting network policy
    by id

30 files changed:
src/flow/flow.cc
src/flow/flow.h
src/flow/flow_control.cc
src/loggers/alert_csv.cc
src/loggers/alert_json.cc
src/main/policy.cc
src/main/snort_config.cc
src/main/snort_config.h
src/managers/inspector_manager.cc
src/network_inspectors/binder/binder.cc
src/network_inspectors/binder/binding.cc
src/pub_sub/opportunistic_tls_event.h
src/service_inspectors/dce_rpc/dce_common.cc
src/service_inspectors/dce_rpc/dce_common.h
src/service_inspectors/dce_rpc/dce_http_proxy.cc
src/service_inspectors/dce_rpc/dce_http_server.cc
src/service_inspectors/ftp_telnet/ftp_data.cc
src/service_inspectors/http_inspect/http_inspect.cc
src/service_inspectors/smtp/smtp.cc
src/service_inspectors/ssl/ssl_inspector.cc
src/service_inspectors/wizard/curses.cc
src/service_inspectors/wizard/curses.h
src/service_inspectors/wizard/hexes.cc
src/service_inspectors/wizard/magic.cc
src/service_inspectors/wizard/magic.h
src/service_inspectors/wizard/spells.cc
src/service_inspectors/wizard/wizard.cc
src/target_based/snort_protocols.cc
src/target_based/snort_protocols.h
src/target_based/test/proto_ref_test.cc

index 916a5b0d9b497ea492705f4be0573a2245781399..0b945ab8302275d7c83e1396aa58add5f9e09293 100644 (file)
@@ -120,7 +120,7 @@ void Flow::term()
         stash = nullptr;
     }
 
-    service.reset();
+    service = nullptr;
 }
 
 inline void Flow::clean()
@@ -214,7 +214,6 @@ void Flow::reset(bool do_cleanup)
         stash->reset();
 
     deferred_trust.clear();
-    service.reset();
 
     constexpr size_t offset = offsetof(Flow, context_chain);
     // FIXIT-L need a struct to zero here to make future proof
@@ -330,23 +329,32 @@ void Flow::free_flow_data(uint32_t proto)
 
 void Flow::free_flow_data()
 {
-    NetworkPolicy* np = get_network_policy();
-    InspectionPolicy* ip = get_inspection_policy();
-    IpsPolicy* ipsp = get_ips_policy();
-
-    unsigned t_reload_id = SnortConfig::get_thread_reload_id();
-    if (reload_id == t_reload_id)
+    const SnortConfig* sc = SnortConfig::get_conf();
+    PolicySelector* ps = sc->policy_map->get_policy_selector();
+    NetworkPolicy* np = nullptr;
+    InspectionPolicy* ip = nullptr;
+    IpsPolicy* ipsp = nullptr;
+    if (ps)
     {
-        ::set_network_policy(network_policy_id);
-        ::set_inspection_policy(inspection_policy_id);
-        ::set_ips_policy(SnortConfig::get_conf(), ips_policy_id);
-    }
-    else
-    {
-        _daq_pkt_hdr pkthdr = {};
-        pkthdr.address_space_id = key->addressSpaceId;
-        select_default_policy(pkthdr, SnortConfig::get_conf());
+        np = get_network_policy();
+        ip = get_inspection_policy();
+        ipsp = get_ips_policy();
+
+        unsigned t_reload_id = SnortConfig::get_thread_reload_id();
+        if (reload_id == t_reload_id)
+        {
+            ::set_network_policy(network_policy_id);
+            ::set_inspection_policy(inspection_policy_id);
+            ::set_ips_policy(sc, ips_policy_id);
+        }
+        else
+        {
+            _daq_pkt_hdr pkthdr = {};
+            pkthdr.address_space_id = key->addressSpaceId;
+            select_default_policy(pkthdr, sc);
+        }
     }
+
     while (flow_data)
     {
         FlowData* tmp = flow_data;
@@ -354,9 +362,12 @@ void Flow::free_flow_data()
         delete tmp;
     }
 
-    set_network_policy(np);
-    set_inspection_policy(ip);
-    set_ips_policy(ipsp);
+    if (ps)
+    {
+        set_network_policy(np);
+        set_inspection_policy(ip);
+        set_ips_policy(ipsp);
+    }
 }
 
 void Flow::call_handlers(Packet* p, bool eof)
@@ -571,21 +582,12 @@ bool Flow::is_direction_aborted(bool from_client) const
     return (session_flags & SSNFLAG_ABORT_CLIENT);
 }
 
-void Flow::set_service(Packet* pkt, std::shared_ptr<std::string> new_service)
+void Flow::set_service(Packet* pkt, const char* new_service)
 {
-    if (!new_service.use_count())
-        return clear_service(pkt);
-
     service = new_service;
     DataBus::publish(FLOW_SERVICE_CHANGE_EVENT, pkt);
 }
 
-void Flow::clear_service(Packet* pkt)
-{
-    service.reset();
-    DataBus::publish(FLOW_SERVICE_CHANGE_EVENT, pkt);
-}
-
 void Flow::swap_roles()
 {
     std::swap(flowstats.client_pkts, flowstats.server_pkts);
index 9b13f8d75734bc2f410965702b5816e5ba8adc86..710ffe28e1b46dae811e5dd4fb2d2957c8aec175 100644 (file)
@@ -27,7 +27,6 @@
 // state.  Inspector state is stored in FlowData, and Flow manages a list
 // of FlowData items.
 
-#include <memory>
 #include <string>
 #include <sys/time.h>
 
@@ -200,10 +199,7 @@ public:
     void set_mpls_layer_per_dir(Packet*);
     Layer get_mpls_layer_per_dir(bool);
     void swap_roles();
-    void set_service(Packet*, std::shared_ptr<std::string> new_service);
-    void clear_service(Packet*);
-    bool has_service() const
-    { return 0 != service.use_count(); }
+    void set_service(Packet*, const char* new_service);
     bool get_attr(const std::string& key, int32_t& val);
     bool get_attr(const std::string& key, std::string& val);
     void set_attr(const std::string& key, const int32_t& val);
@@ -406,7 +402,6 @@ public:  // FIXIT-M privatize if possible
     // void space and allow for memset of tail end of struct
 
     DeferredTrust deferred_trust;
-    std::shared_ptr<std::string> service;
 
     // Anything before this comment is not zeroed during construction
     const FlowKey* key;
@@ -441,6 +436,7 @@ public:  // FIXIT-M privatize if possible
     Inspector* gadget;    // service handler
     Inspector* assistant_gadget;
     Inspector* data;
+    const char* service;
 
     uint64_t expire_time;
 
index 6324ca993bb8d5be5e0905fb03699cf5231c8b43..ddbc45bbd8f2db828416a2e5cf02c1c105d1f9fe 100644 (file)
@@ -437,11 +437,7 @@ unsigned FlowControl::process(Flow* flow, Packet* p)
     {
         unsigned reload_id = SnortConfig::get_thread_reload_id();
         if (flow->reload_id != reload_id)
-        {
             flow->network_policy_id = get_network_policy()->policy_id;
-            if (flow->flow_state == Flow::FlowState::INSPECT)
-                DataBus::publish(FLOW_STATE_RELOADED_EVENT, p, flow);
-        }
         else
         {
             set_inspection_policy(flow->inspection_policy_id);
index e786c5b5ec8cc2332a9d1034410fea3fd740620e..118ea34545f3afa495915c980c4d49040417431f 100644 (file)
@@ -343,8 +343,8 @@ static void ff_server_pkts(const Args& a)
 static void ff_service(const Args& a)
 {
     const char* svc = "unknown";
-    if ( a.pkt->flow and a.pkt->flow->has_service() )
-        svc = a.pkt->flow->service->c_str();
+    if ( a.pkt->flow and a.pkt->flow->service )
+        svc = a.pkt->flow->service;
     TextLog_Puts(csv_log, svc);
 }
 
index bb1d1359915bb81a614b205a26735f736aaacef1..5bc6422f382ed1ab90bc8bd5346f4b679b424381 100644 (file)
@@ -473,8 +473,8 @@ static bool ff_service(const Args& a)
 {
     const char* svc = "unknown";
 
-    if ( a.pkt->flow and a.pkt->flow->has_service() )
-        svc = a.pkt->flow->service->c_str();
+    if ( a.pkt->flow and a.pkt->flow->service )
+        svc = a.pkt->flow->service;
 
     print_label(a, "service");
     TextLog_Quote(json_log, svc);
index ee19cd08d62bcdccde516869ff5e8e2be609ef95..2e62e3d8bd50e058438294bcbdc61645435cb208 100644 (file)
@@ -459,9 +459,9 @@ IpsPolicy* get_empty_ips_policy(const SnortConfig* sc)
 void set_network_policy(unsigned i)
 {
     PolicyMap* pm = SnortConfig::get_conf()->policy_map;
-
-    if ( i < pm->network_policy_count() )
-        set_network_policy(pm->get_network_policy(i));
+    NetworkPolicy* np = pm->get_network_policy(i);
+    if ( np )
+        set_network_policy(np);
 }
 
 void set_inspection_policy(unsigned i)
index d2c7c7a8c6b942e8a618ed3935f14adb81b22592..ce4d2c7b0f59e1d50236be21ee417b84d8dfd074 100644 (file)
 #include "snort_config.h"
 
 #include <grp.h>
+#include <mutex>
 #include <pwd.h>
 #include <syslog.h>
+#include <unordered_map>
 
 #include "actions/ips_actions.h"
 #include "detection/detect.h"
@@ -1056,3 +1058,15 @@ void SnortConfig::cleanup_fatal_error()
 #endif
 }
 
+std::mutex SnortConfig::static_names_mutex;
+std::unordered_map<std::string, std::string> SnortConfig::static_names;
+
+const char* SnortConfig::get_static_name(const char* name)
+{
+    std::lock_guard<std::mutex> static_name_lock(static_names_mutex);
+    auto entry = static_names.find(name);
+    if ( entry != static_names.end() )
+        return entry->second.c_str();
+    static_names.emplace(name, name);
+    return static_names[name].c_str();
+}
index 4411657071e38c039bbc592d236cbb9c82a46c23..9e89e10a96ff7c32aed94f49781b622e95e3e451 100644 (file)
@@ -26,6 +26,7 @@
 #include <sys/types.h>
 
 #include <list>
+#include <mutex>
 #include <unordered_map>
 #include <vector>
 
@@ -409,6 +410,8 @@ public:
 private:
     std::list<ReloadResourceTuner*> reload_tuners;
     unsigned reload_id = 0;
+    static std::mutex static_names_mutex;
+    static std::unordered_map<std::string, std::string> static_names;
 
 public:
     //------------------------------------------------------
@@ -712,6 +715,8 @@ public:
 
     static bool log_show_plugins()
     { return logging_flags & LOGGING_FLAG__SHOW_PLUGINS; }
+
+    SO_PUBLIC static const char* get_static_name(const char* name);
 };
 }
 
index 4c2ae796fa363f120f2bf8beec28d1e343921d39..7f440f4464b6bceb1e11f2d7fd9a4e54b1f821de 100644 (file)
@@ -2050,7 +2050,7 @@ void InspectorManager::full_inspection(Packet* p)
 {
     Flow* flow = p->flow;
 
-    if ( flow->has_service() and flow->searching_for_service()
+    if ( flow->service and flow->searching_for_service()
          and (!(p->is_cooked()) or p->is_defrag()) )
         bumble(p);
 
@@ -2118,7 +2118,13 @@ void InspectorManager::internal_execute(Packet* p)
     if ( p->disable_inspect )
         return;
 
-    if (!p->flow)
+    unsigned reload_id = SnortConfig::get_thread_reload_id();
+    if ( p->flow )
+    {
+        if ( p->flow->reload_id != reload_id )
+            DataBus::publish(FLOW_STATE_RELOADED_EVENT, p, p->flow);
+    }
+    else
         DataBus::publish(PKT_WITHOUT_FLOW_EVENT, p);
 
     FrameworkPolicy* fp = get_inspection_policy()->framework_policy;
@@ -2162,7 +2168,6 @@ void InspectorManager::internal_execute(Packet* p)
         if ( !p->has_paf_payload() and p->flow->flow_state == Flow::FlowState::INSPECT )
             p->flow->session->process(p);
 
-        unsigned reload_id = SnortConfig::get_thread_reload_id();
         if ( p->flow->reload_id != reload_id )
         {
             ::execute<T>(p, tp->first.vec, tp->first.num);
@@ -2172,7 +2177,7 @@ void InspectorManager::internal_execute(Packet* p)
                 return;
         }
 
-        if ( !p->flow->has_service() )
+        if ( !p->flow->service )
             ::execute<T>(p, fp->network.vec, fp->network.num);
 
         if ( p->disable_inspect )
index 518464ec6aee6cadbaa4c58a10394f2b8e5e7f1e..15f1b6a942ee378ca7e2b835f13106c783218c1a 100644 (file)
@@ -578,9 +578,13 @@ public:
 
     void handle(DataEvent&, Flow* flow) override
     {
-        Binder* binder = InspectorManager::get_binder();
-        if (binder && flow)
-            binder->handle_flow_after_reload(*flow);
+        // If reload_id is zero, this is a new flow and is bound by FLOW_STATE_SETUP_EVENT
+        if (flow && flow->reload_id && Flow::FlowState::INSPECT == flow->flow_state)
+        {
+            Binder* binder = InspectorManager::get_binder();
+            if (binder)
+                binder->handle_flow_after_reload(*flow);
+        }
     }
 };
 
@@ -729,7 +733,7 @@ void Binder::handle_flow_setup(Flow& flow, bool standby)
         if (flow.ssn_state.snort_protocol_id != UNKNOWN_PROTOCOL_ID)
         {
             const SnortConfig* sc = SnortConfig::get_conf();
-            flow.service = sc->proto_ref->get_shared_name(flow.ssn_state.snort_protocol_id);
+            flow.set_service(nullptr, sc->proto_ref->get_name(flow.ssn_state.snort_protocol_id));
         }
     }
 
@@ -761,7 +765,7 @@ void Binder::handle_flow_service_change(Flow& flow)
     Inspector* ins = nullptr;
     Inspector* data = nullptr;
 
-    if (flow.has_service())
+    if (flow.service)
     {
         ins = find_gadget(flow, data);
         if (flow.gadget != ins)
@@ -808,8 +812,8 @@ void Binder::handle_flow_service_change(Flow& flow)
 
     // If there is no inspector bound to this flow after the service change, see if there's at least
     // an associated protocol ID.
-    if (!ins && flow.has_service())
-        flow.ssn_state.snort_protocol_id = SnortConfig::get_conf()->proto_ref->find(flow.service->c_str());
+    if (!ins && flow.service)
+        flow.ssn_state.snort_protocol_id = SnortConfig::get_conf()->proto_ref->find(flow.service);
 
     if (flow.is_stream())
     {
@@ -992,7 +996,7 @@ void Binder::get_bindings(Packet* p, Stuff& stuff)
 Inspector* Binder::find_gadget(Flow& flow, Inspector*& data)
 {
     Stuff stuff;
-    get_bindings(flow, stuff, flow.has_service() ? flow.service->c_str() : nullptr);
+    get_bindings(flow, stuff, flow.service);
     data = stuff.data;
     return stuff.gadget;
 }
index 4b66064f1a5e6800a7b68b3b4a74b7b6b5341315..282bde1714563bb28c378fadca0dd772e73acde9 100644 (file)
@@ -579,10 +579,10 @@ inline bool Binding::check_service(const Flow& flow) const
     if (!when.has_criteria(BindWhen::Criteria::BWC_SVC))
         return true;
 
-    if (!flow.has_service())
+    if (!flow.service)
         return false;
 
-    return when.svc == flow.service->c_str();
+    return when.svc == flow.service;
 }
 
 inline bool Binding::check_service(const char* service) const
index 9aafeebd3413ecfa3499a80789601fda30158c00..4d7b046ad05dc606cb3653ae4ed21691b2025a94 100644 (file)
@@ -34,18 +34,18 @@ namespace snort
 class SO_PUBLIC OpportunisticTlsEvent : public snort::DataEvent
 {
 public:
-    OpportunisticTlsEvent(const snort::Packet* p, std::shared_ptr<std::string> service) :
+    OpportunisticTlsEvent(const snort::Packet* p, const char* service) :
         pkt(p), next_service(service) { }
 
     const snort::Packet* get_packet() override
     { return pkt; }
 
-    std::shared_ptr<std::string> get_next_service()
+    const char* get_next_service()
     { return next_service; }
 
 private:
     const snort::Packet* pkt;
-    std::shared_ptr<std::string> next_service;
+    const char* next_service;
 };
 
 }
index 1f520fab2c926946f5f7ec3c8dddc33f83298b1a..cee6e3be0ad1f99a831e371c45b8820cfa8b2ffa 100644 (file)
@@ -43,9 +43,6 @@ using namespace snort;
 THREAD_LOCAL int dce2_detected = 0;
 static THREAD_LOCAL bool using_rpkt = false;
 
-std::shared_ptr<std::string> dce_rpc_service_name =
-    std::make_shared<std::string>(DCE_RPC_SERVICE_NAME);
-
 static const char* dce2_get_policy_name(DCE2_Policy policy)
 {
     const char* policyStr = nullptr;
index 18396850cc43daadc713a49302070392f2bfed8c..481c21db9ba08289067dcc3a9cd12534d91b76b5 100644 (file)
@@ -43,7 +43,6 @@ extern THREAD_LOCAL int dce2_detected;
 
 #define GID_DCE2 133
 #define DCE_RPC_SERVICE_NAME "dcerpc"
-extern std::shared_ptr<std::string> dce_rpc_service_name;
 
 enum DCE2_Policy
 {
index 7da11138e9495625d21a2056f384aec02cf6aae8..2cdaad9e47ca5e074a045fcbb3aa81171da41577 100644 (file)
@@ -68,7 +68,7 @@ void DceHttpProxy::clear(Packet* p)
             if ( c2s_splitter->cutover_inspector() && s2c_splitter->cutover_inspector() )
             {
                 dce_http_proxy_stats.http_proxy_sessions++;
-                flow->set_service(p, dce_rpc_service_name);
+                flow->set_service(p, DCE_RPC_SERVICE_NAME);
             }
             else
                 dce_http_proxy_stats.http_proxy_session_failures++;
index 557b035da0f49bacaa719b57c614d69dbdc010fc..acf0126e78d39504bb3b8ad4867b68cb936a638c 100644 (file)
@@ -64,7 +64,7 @@ void DceHttpServer::clear(Packet* p)
             if ( splitter->cutover_inspector())
             {
                 dce_http_server_stats.http_server_sessions++;
-                flow->set_service(p, dce_rpc_service_name);
+                flow->set_service(p, DCE_RPC_SERVICE_NAME);
             }
             else
                 dce_http_server_stats.http_server_session_failures++;
index 435d79507d0d7723e952c01c550507e6c2419c81..f8a530172e9f4fc2ace680b4c090a98581e8683e 100644 (file)
@@ -49,8 +49,6 @@ using namespace snort;
     "FTP data channel handler"
 
 static const char* const fd_svc_name = "ftp-data";
-static std::shared_ptr<std::string> shared_fd_svc_name =
-    std::make_shared<std::string>(fd_svc_name);
 
 static THREAD_LOCAL ProfileStats ftpdataPerfStats;
 static THREAD_LOCAL SimpleStats fdstats;
@@ -228,15 +226,15 @@ FtpDataFlowData::~FtpDataFlowData()
 
 void FtpDataFlowData::handle_expected(Packet* p)
 {
-    if (!p->flow->has_service())
+    if (!p->flow->service)
     {
-        p->flow->set_service(p, shared_fd_svc_name);
+        p->flow->set_service(p, fd_svc_name);
 
         FtpDataFlowData* fd =
             (FtpDataFlowData*)p->flow->get_flow_data(FtpDataFlowData::inspector_id);
         if (fd and fd->in_tls)
         {
-            OpportunisticTlsEvent evt(p, shared_fd_svc_name);
+            OpportunisticTlsEvent evt(p, fd_svc_name);
             DataBus::publish(OPPORTUNISTIC_TLS_EVENT, evt, p->flow);
         }
         else
index b408e271980bceda8e4ffa4216661627c13d0685..51c78e091956a6075c79ae7ce34b7027f32fc93b 100755 (executable)
@@ -688,7 +688,7 @@ void HttpInspect::clear(Packet* p)
     if (session_data->cutover_on_clear)
     {
         Flow* flow = p->flow;
-        flow->clear_service(p);
+        flow->set_service(p, nullptr);
         flow->free_flow_data(HttpFlowData::inspector_id);
     }
 }
index 412dc0e7457fcfc06ff7cdcf995b660d4fcbb2c8..f54cc03b5786eee681ec12b050b3289560e97d12 100644 (file)
@@ -1116,7 +1116,6 @@ static void SMTP_ProcessServerPacket(
                 /* This is either an initial server response or a STARTTLS response */
                 if (smtp_ssn->state == STATE_CONNECT)
                     smtp_ssn->state = STATE_COMMAND;
-
                 break;
 
             case RESP_250:
index e4701db51b4d196b9b35396f747fa60d8e784e4a..d11b0541361b7e170f704a3c1b9f4bb33c335a76 100644 (file)
@@ -403,7 +403,6 @@ static void snort_ssl(SSL_PROTO_CONF* config, Packet* p)
 // class stuff
 //-------------------------------------------------------------------------
 static const char* s_name = "ssl";
-static std::shared_ptr<std::string> shared_s_name = std::make_shared<std::string>(s_name);
 
 class Ssl : public Inspector
 {
@@ -452,7 +451,7 @@ public:
             pkt->flow->flags.trigger_finalize_event = fd->finalize_info.orig_flag;
             fd->finalize_info.switch_in = false;
             pkt->flow->set_proxied();
-            pkt->flow->set_service(const_cast<Packet*>(pkt), shared_s_name);
+            pkt->flow->set_service(const_cast<Packet*>(pkt), s_name);
         }
     }
 };
index 96893475958047d548081eda81e4ebf5b5cedbef..b14727cab81e76da1d6dca6b2a3715f06d2b689e 100644 (file)
@@ -393,11 +393,11 @@ static bool ssl_v2_curse(const uint8_t* data, unsigned len, CurseTracker* tracke
 // map between service and curse details
 static vector<CurseDetails> curse_map
 {
-    // name      service                             alg            is_tcp
-    { "dce_udp", make_shared<string>("dcerpc")     , dce_udp_curse, false },
-    { "dce_tcp", make_shared<string>("dcerpc")     , dce_tcp_curse, true  },
-    { "dce_smb", make_shared<string>("netbios-ssn"), dce_smb_curse, true  },
-    { "sslv2"  , make_shared<string>("ssl")        , ssl_v2_curse , true  }
+    // name      service        alg            is_tcp
+    { "dce_udp", "dcerpc"     , dce_udp_curse, false },
+    { "dce_tcp", "dcerpc"     , dce_tcp_curse, true  },
+    { "dce_smb", "netbios-ssn", dce_smb_curse, true  },
+    { "sslv2"  , "ssl"        , ssl_v2_curse , true  }
 };
 
 bool CurseBook::add_curse(const char* key)
index 8b2d9b682e7e4b39512664563b880e340162bfa9..1ffe226a289888eb2baadc4a698faaedc74eae03 100644 (file)
@@ -21,7 +21,6 @@
 #define CURSES_H
 
 #include <cstdint>
-#include <memory>
 #include <string>
 #include <vector>
 
@@ -87,7 +86,7 @@ typedef bool (* curse_alg)(const uint8_t* data, unsigned len, CurseTracker*);
 struct CurseDetails
 {
     std::string name;
-    std::shared_ptr<std::string> service;
+    const char* service;
     curse_alg alg;
     bool is_tcp;
 };
index 9b2880fb7f12634ddd1faea14f44b9d7c8f31ca0..3a1cebf3391c62ec7e1fcf6e8896dbc8d0451548 100644 (file)
 
 #include <cstdlib>
 
+#include "main/snort_config.h"
+
 #include "magic.h"
 
+using namespace snort;
 using namespace std;
 
 #define WILD 0x100
@@ -91,7 +94,7 @@ void HexBook::add_spell(
         ++i;
     }
     p->key = key;
-    p->value = make_shared<string>(val);
+    p->value = SnortConfig::get_static_name(val);
 }
 
 bool HexBook::add_spell(const char* key, const char*& val)
@@ -124,7 +127,7 @@ bool HexBook::add_spell(const char* key, const char*& val)
     }
     if ( p->key == key )
     {
-        val = p->value->c_str();
+        val = p->value;
         return false;
     }
 
@@ -158,7 +161,7 @@ const MagicPage* HexBook::find_spell(
             if ( const MagicPage* q = find_spell(s, n, p->any, i+1) )
                 return q;
         }
-        return p->value.use_count() ? p : nullptr;
+        return p->value ? p : nullptr;
     }
     return p;
 }
index a6f2a3f84cda5b4a61c61ee7bd3fb207269228f1..dd56d2546470e9179b2ece094a617188d477b58b 100644 (file)
@@ -42,16 +42,12 @@ MagicPage::~MagicPage()
     delete any;
 }
 
-std::shared_ptr<std::string> MagicBook::find_spell(const uint8_t* data, unsigned len,
+const char* MagicBook::find_spell(const uint8_t* data, unsigned len,
     const MagicPage*& p) const
 {
     assert(p);
-
     p = find_spell(data, len, p, 0);
-    if ( p && p->value.use_count() )
-        return p->value;
-
-    return nullptr;
+    return p ? p->value : nullptr;
 }
 
 MagicBook::MagicBook()
index f35380a138d39c63da045eb105e890a6a84406fa..3d3ef76134d041e5c7b1fcb42ef0f14aaaa2bf69 100644 (file)
@@ -20,7 +20,6 @@
 #ifndef MAGIC_H
 #define MAGIC_H
 
-#include <memory>
 #include <string>
 #include <vector>
 
@@ -29,7 +28,7 @@ class MagicBook;
 struct MagicPage
 {
     std::string key;
-    std::shared_ptr<std::string> value;
+    const char* value = nullptr;
 
     MagicPage* next[256];
     MagicPage* any;
@@ -53,8 +52,7 @@ public:
     MagicBook& operator=(const MagicBook&) = delete;
 
     virtual bool add_spell(const char* key, const char*& val) = 0;
-    virtual std::shared_ptr<std::string> find_spell(const uint8_t*, unsigned len,
-        const MagicPage*&) const;
+    virtual const char* find_spell(const uint8_t* data, unsigned len, const MagicPage*&) const;
 
     const MagicPage* page1() const
     { return root; }
index ce6ba6f6d23bfa65d10f9b6ea974d9ff17e8edda..997876133450dc3c1142c78aa770d306320fadff 100644 (file)
 
 #include <cassert>
 
+#include "main/snort_config.h"
+
 #include "magic.h"
 
+using namespace snort;
 using namespace std;
 
 #define WILD 0x100
@@ -84,7 +87,7 @@ void SpellBook::add_spell(
         ++i;
     }
     p->key = key;
-    p->value = make_shared<string>(val);
+    p->value = SnortConfig::get_static_name(val);
 }
 
 bool SpellBook::add_spell(const char* key, const char*& val)
@@ -118,7 +121,7 @@ bool SpellBook::add_spell(const char* key, const char*& val)
     }
     if ( p->key == key )
     {
-        val = p->value->c_str();
+        val = p->value;
         return false;
     }
 
@@ -162,7 +165,7 @@ const MagicPage* SpellBook::find_spell(
         }
 
         // If no match but has glob, continue lookup from glob
-        if ( !p->value.use_count() && glob )
+        if ( !p->value && glob )
         {
             p = glob;
             glob = nullptr;
@@ -170,7 +173,7 @@ const MagicPage* SpellBook::find_spell(
             return find_spell(s, n, p, i);
         }
 
-        return p->value.use_count() ? p : nullptr;
+        return p->value ? p : nullptr;
     }
     return p;
 }
index 7d20b9c9d69440bc56e797dd424a99f59b10ab53..46de82103d859cf718ce161575e95e6540deb06d 100644 (file)
@@ -195,7 +195,7 @@ StreamSplitter::Status MagicSplitter::scan(
     if ( wizard->cast_spell(wand, pkt->flow, data, len, wizard_processed_bytes) )
     {
         trace_logf(wizard_trace, pkt, "%s streaming search found service %s\n",
-            to_server() ? "c2s" : "s2c", pkt->flow->service->c_str());
+            to_server() ? "c2s" : "s2c", pkt->flow->service);
         count_hit(pkt->flow);
         wizard_processed_bytes = 0;
         return STOP;
@@ -225,7 +225,7 @@ StreamSplitter::Status MagicSplitter::scan(
     // delayed. Because AppId depends on wizard only for SSH detection and SSH inspector can be
     // attached very early, event is raised here after first scan. In the future, wizard should be
     // enhanced to abort sooner if it can't detect service.
-    if (!pkt->flow->has_service() && !pkt->flow->flags.svc_event_generated)
+    if (!pkt->flow->service && !pkt->flow->flags.svc_event_generated)
     {
         DataBus::publish(FLOW_NO_SERVICE_EVENT, pkt);
         pkt->flow->flags.svc_event_generated = true;
@@ -309,7 +309,7 @@ void Wizard::eval(Packet* p)
     if ( cast_spell(wand, p->flow, p->data, p->dsize, udp_processed_bytes) )
     {
         trace_logf(wizard_trace, p, "%s datagram search found service %s\n",
-            c2s ? "c2s" : "s2c", p->flow->service->c_str());
+            c2s ? "c2s" : "s2c", p->flow->service);
         ++tstats.udp_hits;
     }
     else
@@ -328,12 +328,8 @@ StreamSplitter* Wizard::get_splitter(bool c2s)
 bool Wizard::spellbind(
     const MagicPage*& m, Flow* f, const uint8_t* data, unsigned len)
 {
-    std::shared_ptr<std::string> p_shared = m->book.find_spell(data, len, m);
-    if (p_shared.use_count())
-        f->service = p_shared;
-    else
-        f->service.reset();
-    return f->has_service();
+    f->service = m->book.find_spell(data, len, m);
+    return f->service != nullptr;
 }
 
 bool Wizard::cursebind(const vector<CurseServiceTracker>& curse_tracker, Flow* f,
@@ -343,11 +339,8 @@ bool Wizard::cursebind(const vector<CurseServiceTracker>& curse_tracker, Flow* f
     {
         if (cst.curse->alg(data, len, cst.tracker))
         {
-            if (cst.curse->service.use_count())
-                f->service = cst.curse->service;
-            else
-                f->service.reset();
-            if ( f->has_service() )
+            f->service = cst.curse->service;
+            if ( f->service )
                 return true;
         }
     }
@@ -375,7 +368,7 @@ bool Wizard::cast_spell(
 
     // If we reach max value of wizard_processed_bytes,
     // but not assign any inspector - raise tcp_miss and stop
-    if ( !f->has_service() && wizard_processed_bytes >= max_search_depth )
+    if ( !f->service && wizard_processed_bytes >= max_search_depth )
     {
         w.spell = nullptr;
         w.hex = nullptr;
index b37d0a2fa8f8b5833b4772ddb2097da3b437a670..fb09564fdc6bde0b7a16d36355b2918402f5b59e 100644 (file)
 #include "snort_protocols.h"
 
 #include <algorithm>
+#include <cassert>
 
 #include "log/messages.h"
+#include "main/snort_config.h"
 #include "protocols/packet.h"
 #include "utils/util.h"
 #include "utils/util_cstring.h"
@@ -39,12 +41,6 @@ SnortProtocolId ProtocolReference::get_count() const
 { return protocol_number; }
 
 const char* ProtocolReference::get_name(SnortProtocolId id) const
-{
-    std::shared_ptr<std::string> shared_name = get_shared_name(id);
-    return shared_name->c_str();
-}
-
-std::shared_ptr<std::string> ProtocolReference::get_shared_name(SnortProtocolId id) const
 {
     if ( id >= id_map.size() )
         id = 0;
@@ -55,9 +51,9 @@ std::shared_ptr<std::string> ProtocolReference::get_shared_name(SnortProtocolId
 struct Compare
 {
     bool operator()(SnortProtocolId a, SnortProtocolId b)
-    { return map[a]->c_str() < map[b]->c_str(); }
+    { return 0 > strcmp(map[a], map[b]); }
 
-    vector<shared_ptr<string>>& map;
+    vector<const char*>& map;
 };
 
 const char* ProtocolReference::get_name_sorted(SnortProtocolId id)
@@ -73,7 +69,7 @@ const char* ProtocolReference::get_name_sorted(SnortProtocolId id)
     if ( id >= ind_map.size() )
         return nullptr;
 
-    return id_map[ind_map[id]]->c_str();
+    return id_map[ind_map[id]];
 }
 
 SnortProtocolId ProtocolReference::add(const char* protocol)
@@ -86,7 +82,8 @@ SnortProtocolId ProtocolReference::add(const char* protocol)
         return protocol_ref->second;
 
     SnortProtocolId snort_protocol_id = protocol_number++;
-    id_map.emplace_back(make_shared<string>(protocol));
+    protocol = SnortConfig::get_static_name(protocol);
+    id_map.emplace_back(protocol);
     ref_table[protocol] = snort_protocol_id;
 
     return snort_protocol_id;
@@ -127,5 +124,9 @@ ProtocolReference::ProtocolReference(ProtocolReference* old_proto_ref)
 { init(old_proto_ref); }
 
 ProtocolReference::~ProtocolReference()
-{ ref_table.clear(); }
+{
+    ref_table.clear();
+    id_map.clear();
+    ind_map.clear();
+}
 
index 6281cd1b55c7fcad7d14a39723fea834adaf6ae5..b16712b2b69d5df53c8cf413b20ee518ea25f4f1 100644 (file)
@@ -22,7 +22,6 @@
 #ifndef SNORT_PROTOCOLS_H
 #define SNORT_PROTOCOLS_H
 
-#include <memory>
 #include <string>
 #include <vector>
 #include <unordered_map>
@@ -74,7 +73,6 @@ public:
     SnortProtocolId get_count() const;
 
     const char* get_name(SnortProtocolId id) const;
-    std::shared_ptr<std::string> get_shared_name(SnortProtocolId id) const;
     const char* get_name_sorted(SnortProtocolId id);
 
     SnortProtocolId add(const char* protocol);
@@ -83,7 +81,7 @@ public:
     bool operator()(SnortProtocolId a, SnortProtocolId b);
 
 private:
-    std::vector<std::shared_ptr<std::string>> id_map;
+    std::vector<const char*> id_map;
     std::vector<SnortProtocolId> ind_map;
     std::unordered_map<std::string, SnortProtocolId> ref_table;
 
@@ -91,6 +89,10 @@ private:
 
     void init(const ProtocolReference* old_proto_ref);
 };
+
+void protocol_reference_global_init();
+void protocol_reference_global_term();
+
 }
 #endif
 
index 198c67c021622c129989535077d8e1de5520fd00..a5869171c3f67791d2d1fdfffdb773235b796944 100644 (file)
 
 using namespace snort;
 
+const char* SnortConfig::get_static_name(const char* name) { return name; }
+
 TEST_GROUP(protocol_reference)
-{};
+{ };
 
 // Service Protocols
 //