]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #2447 in SNORT/snort3 from ~SHRARANG/snort3:appid_tp_reload_reorde...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Fri, 4 Sep 2020 23:07:27 +0000 (23:07 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Fri, 4 Sep 2020 23:07:27 +0000 (23:07 +0000)
Squashed commit of the following:

commit df9e98dfacc0edb9a9f1861357a09e6c73ded252
Author: Shravan Rangaraju <shrarang@cisco.com>
Date:   Thu Aug 27 17:28:49 2020 -0400

    appid: reorder third-party reload to keep only one handle open at a time

23 files changed:
src/network_inspectors/appid/appid_api.cc
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_dcerpc_event_handler.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_http_event_handler.cc
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_module.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/appid_session.h
src/network_inspectors/appid/appid_session_api.cc
src/network_inspectors/appid/appid_stats.cc
src/network_inspectors/appid/ips_appid_option.cc
src/network_inspectors/appid/test/appid_api_test.cc
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/appid_http_event_test.cc
src/network_inspectors/appid/test/appid_mock_inspector.h
src/network_inspectors/appid/test/appid_mock_session.h
src/network_inspectors/appid/test/appid_session_api_test.cc
src/network_inspectors/appid/test/tp_mock.cc
src/network_inspectors/appid/tp_appid_module_api.h
src/network_inspectors/appid/tp_appid_session_api.h
src/network_inspectors/appid/tp_lib_handler.cc

index b06fdbc1f95a2b7db65843e4757f6bacf69e8632..74ac5b31f5c20c9f2c6c999e70c269fb98aeb596 100644 (file)
@@ -64,8 +64,8 @@ const char* AppIdApi::get_application_name(AppId app_id, const Flow& flow)
     if (asd)
     {
         // Skip sessions using old odp context after odp reload
-        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-        if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &(asd->get_odp_ctxt())))
+        if (!pkt_thread_odp_ctxt or
+            pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version())
             return nullptr;
 
         if (app_id == APP_ID_UNKNOWN)
@@ -83,8 +83,8 @@ const char* AppIdApi::get_application_name(const Flow& flow, bool from_client)
     if (asd)
     {
         // Skip sessions using old odp context after odp reload
-        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-        if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &(asd->get_odp_ctxt())))
+        if (!pkt_thread_odp_ctxt or
+            pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version())
             return nullptr;
 
         AppId appid = asd->pick_ss_payload_app_id();
@@ -244,8 +244,8 @@ bool AppIdApi::ssl_app_group_id_lookup(Flow* flow, const char* server_name,
     if (asd)
     {
         // Skip detection for sessions using old odp context after odp reload
-        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-        if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &(asd->get_odp_ctxt())))
+        if (!pkt_thread_odp_ctxt or
+            pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version())
             return false;
 
         AppidChangeBits change_bits;
index 6167801ca6fcecc25018c65697e660e454a40b61..72e3daa359a0adc047114b93b5e9f44eead4d2f2 100644 (file)
@@ -49,6 +49,7 @@ using namespace snort;
 
 ThirdPartyAppIdContext* AppIdContext::tp_appid_ctxt = nullptr;
 OdpContext* AppIdContext::odp_ctxt = nullptr;
+uint32_t OdpContext::next_version = 0;
 
 static void map_app_names_to_snort_ids(SnortConfig* sc, AppIdConfig& config)
 {
@@ -151,6 +152,7 @@ OdpContext::OdpContext(const AppIdConfig& config, SnortConfig* sc)
     app_info_mgr.init_appid_info_table(config, sc, *this);
     client_pattern_detector = new PatternClientDetector(&client_disco_mgr);
     service_pattern_detector = new PatternServiceDetector(&service_disco_mgr);
+    version = next_version++;
 }
 
 OdpContext::~OdpContext()
index dadeb0437dbe36f3e6859b85d2119a6f653d8a5d..29c0b47fadaa4ddc6149dc5fa944ff115c80be17 100644 (file)
@@ -122,6 +122,11 @@ public:
     ~OdpContext();
     void initialize();
 
+    uint32_t get_version() const
+    {
+        return version;
+    }
+
     AppInfoManager& get_app_info_mgr()
     {
         return app_info_mgr;
@@ -217,6 +222,9 @@ private:
     std::array<AppId, APP_ID_PORT_ARRAY_SIZE> tcp_port_only = {}; // port-only TCP services
     std::array<AppId, APP_ID_PORT_ARRAY_SIZE> udp_port_only = {}; // port-only UDP services
     std::array<AppId, 256> ip_protocol = {}; // non-TCP / UDP protocol services
+
+    uint32_t version;
+    static uint32_t next_version;
 };
 
 class OdpThreadContext
index 7db84333bb23b5c9717524e477f10517389d3d8f..a461ac042200496dd940b4d423a613d2a9e0793c 100644 (file)
@@ -41,8 +41,8 @@ public:
         else
         {
             // Skip sessions using old odp context after reload detectors
-            AppIdInspector* inspector = (AppIdInspector*) snort::InspectorManager::get_inspector(MOD_NAME, true);
-            if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &(asd->get_odp_ctxt())))
+            if (!pkt_thread_odp_ctxt or
+                (pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version()))
                 return;
         }
 
index 77a1ee7bdc0c96a3b9aceccf69a01253a6920564..fda210257c78f1b3a41ef1a43d25151b1e505c4e 100644 (file)
@@ -369,7 +369,8 @@ bool AppIdDiscovery::do_pre_discovery(Packet* p, AppIdSession*& asd, AppIdInspec
     OdpContext& odp_ctxt)
 {
     // Skip inspection for sessions using old odp context after an odp reload
-    if (asd and (&(asd->get_odp_ctxt()) != &(inspector.get_ctxt().get_odp_ctxt())))
+    if (asd and
+        asd->get_odp_ctxt_version() != odp_ctxt.get_version())
     {
         appid_stats.odp_reload_ignored_pkts++;
         appid_stats.tp_reload_ignored_pkts++;
@@ -751,7 +752,7 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
     if (tp_appid_ctxt and ((service_id = asd.pick_service_app_id()) != APP_ID_HTTP2))
     {
         // Skip third-party inspection for sessions using old config
-        if (asd.tpsession and &(asd.tpsession->get_ctxt()) != tp_appid_ctxt)
+        if (asd.tpsession and asd.tpsession->get_ctxt_version() != tp_appid_ctxt->get_version())
         {
             bool is_tp_done = asd.is_tp_processing_done();
             delete asd.tpsession;
index 06ee55248d175d1aa5bf8536056dbdebe73310e0..9cfbced434a0c0d8d28fd12e97ac34acbd93614e 100644 (file)
@@ -50,8 +50,8 @@ void HttpEventHandler::handle(DataEvent& event, Flow* flow)
     else
     {
         // Skip detection for sessions using old odp context after odp reload
-        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-        if (inspector and (&(asd->get_odp_ctxt()) != &(inspector->get_ctxt().get_odp_ctxt())))
+        if (!pkt_thread_odp_ctxt or
+            (asd->get_odp_ctxt_version() != pkt_thread_odp_ctxt->get_version()))
             return;
     }
 
index 3f4d4555358c4f1036841d2bdebe1782b1ba415f..ffbde75307fb12fde5e141b69f50b62889ba0db4 100644 (file)
@@ -65,11 +65,11 @@ static void openssl_cleanup()
     CRYPTO_cleanup_all_ex_data();
 }
 
-static void add_appid_to_packet_trace(Flow& flow, OdpContext& odp_context)
+static void add_appid_to_packet_trace(Flow& flow, const OdpContext& odp_context)
 {
     AppIdSession* session = appid_api.get_appid_session(flow);
     // Skip sessions using old odp context after odp reload
-    if (!session || (&(session->get_odp_ctxt()) != &odp_context))
+    if (!session || (session->get_odp_ctxt_version() != odp_context.get_version()))
         return;
 
     AppId service_id, client_id, payload_id, misc_id;
@@ -169,9 +169,8 @@ void AppIdInspector::tterm()
     assert(odp_thread_local_ctxt);
     delete odp_thread_local_ctxt;
     odp_thread_local_ctxt = nullptr;
-    ThirdPartyAppIdContext* tp_appid_ctxt = ctxt->get_tp_appid_ctxt();
-    if (tp_appid_ctxt)
-        tp_appid_ctxt->tfini();
+    if (pkt_thread_tp_appid_ctxt)
+        pkt_thread_tp_appid_ctxt->tfini();
 }
 
 void AppIdInspector::eval(Packet* p)
index c1b9925c8aae97b16b7878ea3b065bae2aa20bf9..7fb90f1ba7bb133242659ab3c0b90d6fcfdf1158 100644 (file)
@@ -129,39 +129,74 @@ class ACThirdPartyAppIdContextSwap : public AnalyzerCommand
 {
 public:
     bool execute(Analyzer&, void**) override;
-    ACThirdPartyAppIdContextSwap(const AppIdInspector& inspector, ThirdPartyAppIdContext* tp_ctxt,
+    ACThirdPartyAppIdContextSwap(const AppIdInspector& inspector,
         Request& current_request, bool from_shell): inspector(inspector),
-        tp_ctxt(tp_ctxt),request(current_request), from_shell(from_shell) { }
+        request(current_request), from_shell(from_shell)
+    {
+        LogMessage("== swapping third-party configuration\n");
+        request.respond("== swapping third-party configuration\n", from_shell, true);
+    }
+
     ~ACThirdPartyAppIdContextSwap() override;
     const char* stringify() override { return "THIRD-PARTY_CONTEXT_SWAP"; }
 private:
     const AppIdInspector& inspector;
-    ThirdPartyAppIdContext* tp_ctxt =  nullptr;
     Request& request;
     bool from_shell;
 };
 
 bool ACThirdPartyAppIdContextSwap::execute(Analyzer&, void**)
+{
+    assert(!pkt_thread_tp_appid_ctxt);
+    pkt_thread_tp_appid_ctxt = inspector.get_ctxt().get_tp_appid_ctxt();
+    pkt_thread_tp_appid_ctxt->tinit();
+    pkt_thread_tp_appid_ctxt->set_tp_reload_in_progress(false);
+
+    return true;
+}
+
+ACThirdPartyAppIdContextSwap::~ACThirdPartyAppIdContextSwap()
+{
+    Swapper::set_reload_in_progress(false);
+    LogMessage("== reload third-party complete\n");
+    request.respond("== reload third-party complete\n", from_shell, true);
+}
+
+class ACThirdPartyAppIdContextUnload : public AnalyzerCommand
+{
+public:
+    bool execute(Analyzer&, void**) override;
+    ACThirdPartyAppIdContextUnload(const AppIdInspector& inspector, ThirdPartyAppIdContext* tp_ctxt,
+        Request& current_request, bool from_shell): inspector(inspector),
+        tp_ctxt(tp_ctxt), request(current_request), from_shell(from_shell) { }
+    ~ACThirdPartyAppIdContextUnload() override;
+    const char* stringify() override { return "THIRD-PARTY_CONTEXT_UNLOAD"; }
+private:
+    const AppIdInspector& inspector;
+    ThirdPartyAppIdContext* tp_ctxt =  nullptr;
+    Request& request;
+    bool from_shell;
+};
+
+bool ACThirdPartyAppIdContextUnload::execute(Analyzer&, void**)
 {
     assert(pkt_thread_tp_appid_ctxt);
-    ThirdPartyAppIdContext* tp_appid_ctxt = inspector.get_ctxt().get_tp_appid_ctxt();
-    assert(pkt_thread_tp_appid_ctxt != tp_appid_ctxt);
+    pkt_thread_tp_appid_ctxt->set_tp_reload_in_progress(true);
     bool reload_in_progress = pkt_thread_tp_appid_ctxt->tfini(true);
-    pkt_thread_tp_appid_ctxt->set_tp_reload_in_progress(reload_in_progress);
     if (reload_in_progress)
         return false;
-    tp_appid_ctxt->tinit();
-    pkt_thread_tp_appid_ctxt = tp_appid_ctxt;
+    pkt_thread_tp_appid_ctxt = nullptr;
 
     return true;
 }
 
-ACThirdPartyAppIdContextSwap::~ACThirdPartyAppIdContextSwap()
+ACThirdPartyAppIdContextUnload::~ACThirdPartyAppIdContextUnload()
 {
     delete tp_ctxt;
-    Swapper::set_reload_in_progress(false);
-    LogMessage("== reload third-party complete\n");
-    request.respond("== reload third-party complete\n", from_shell, true);
+    AppIdContext& ctxt = inspector.get_ctxt();
+    ctxt.create_tp_appid_ctxt();
+    main_broadcast_command(new ACThirdPartyAppIdContextSwap(inspector,
+        request, from_shell), from_shell);
 }
 
 class ACOdpContextSwap : public AnalyzerCommand
@@ -266,7 +301,7 @@ static int reload_third_party(lua_State* L)
         current_request.respond("== reload third-party failed - appid not enabled\n", from_shell);
         return 0;
     }
-    AppIdContext& ctxt = inspector->get_ctxt();
+    const AppIdContext& ctxt = inspector->get_ctxt();
     ThirdPartyAppIdContext* old_ctxt = ctxt.get_tp_appid_ctxt();
     if (!old_ctxt)
     {
@@ -274,9 +309,8 @@ static int reload_third_party(lua_State* L)
         return 0;
     }
     Swapper::set_reload_in_progress(true);
-    ctxt.create_tp_appid_ctxt();
-    current_request.respond("== swapping third-party configuration\n", from_shell);
-    main_broadcast_command(new ACThirdPartyAppIdContextSwap(*inspector, old_ctxt,
+    current_request.respond("== unloading old third-party configuration\n", from_shell);
+    main_broadcast_command(new ACThirdPartyAppIdContextUnload(*inspector, old_ctxt,
         current_request, from_shell), from_shell);
     return 0;
 }
index 29c34a88cfc72fea6639631a6ca4f7e8dbaacf37..62d1f7d11bcce6e37ef35c7d7e1d82e5bfbd8f45 100644 (file)
@@ -100,6 +100,7 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t port,
 {
     service_ip.clear();
     initiator_port = port;
+    odp_ctxt_version = odp_ctxt.get_version();
 
     appid_stats.total_sessions++;
 }
index 794421249e197b7b545cbd78c783fc66fc9b02d3..4a7f5c8665bb904684762c166b7b900337713d3a 100644 (file)
@@ -553,6 +553,11 @@ public:
         return odp_ctxt;
     }
 
+    uint32_t get_odp_ctxt_version() const
+    {
+        return odp_ctxt_version;
+    }
+
     ThirdPartyAppIdContext* get_tp_appid_ctxt() const
     {
         return tp_appid_ctxt;
@@ -575,6 +580,7 @@ private:
     snort::AppIdSessionApi& api;
     static uint16_t inferred_svcs_ver;
     OdpContext& odp_ctxt;
+    uint32_t odp_ctxt_version;
     ThirdPartyAppIdContext* tp_appid_ctxt = nullptr;
 };
 
index 4adcdf83b4340f25ddffbf857c5e53f262918e08..adfb0f03888081725cc02afac8720a20d7d5567b 100644 (file)
@@ -192,8 +192,8 @@ bool AppIdSessionApi::is_appid_inspecting_session() const
     else
     {
         // Inspection is not done for sessions using old odp context after reload detectors
-        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-        if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &(asd->get_odp_ctxt())))
+        if (!pkt_thread_odp_ctxt or
+            (pkt_thread_odp_ctxt->get_version() != asd->get_odp_ctxt_version()))
             return false;
     }
 
index 0a5f45e2f35d242e2ae6946e59168bb0d832ae2f..fe2065b9f2953010330d8bae22db105d5ecad34b 100644 (file)
@@ -206,14 +206,14 @@ static void update_stats(const AppIdSession& asd, AppId app_id, StatsBucket* buc
             cooked_client = true;
 
         // Skip stats for sessions using old odp context after reload detectors
-        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
-        OdpContext& odp_ctxt = asd.get_odp_ctxt();
-        if (inspector and (&(inspector->get_ctxt().get_odp_ctxt()) != &odp_ctxt))
+        if (!pkt_thread_odp_ctxt or
+            (pkt_thread_odp_ctxt->get_version() != asd.get_odp_ctxt_version()))
         {
             snort_free(record);
             return;
         }
 
+        OdpContext& odp_ctxt = asd.get_odp_ctxt();
         AppInfoTableEntry* entry
             = odp_ctxt.get_app_info_mgr().get_app_info_entry(app_id);
 
index f35743f18adcd53c1c6ddbc0e856bedf73e61813..803eaf4e1afe13981a242ab8bde4f09fdd71f338 100644 (file)
@@ -121,7 +121,8 @@ IpsOption::EvalStatus AppIdIpsOption::eval(Cursor&, Packet* p)
     AppIdSession* session = appid_api.get_appid_session(*(p->flow));
 
     // Skip detection for sessions using old odp context after odp reload
-    if ( !session || (&(session->get_odp_ctxt()) != pkt_thread_odp_ctxt))
+    if ( !session or !pkt_thread_odp_ctxt or
+        (session->get_odp_ctxt_version() != pkt_thread_odp_ctxt->get_version()))
         return NO_MATCH;
 
     AppId app_ids[APP_PROTOID_MAX];
index 2873fcd5a1cab3d53d21a50850664e4c1d982e33..17600de619b1f85ca8eef783ecab710c5027c32c 100644 (file)
@@ -203,7 +203,8 @@ TEST_GROUP(appid_api)
         mock_init_appid_pegs();
         SfIp ip;
         mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector,
-        dummy_appid_inspector.get_ctxt().get_odp_ctxt());
+            dummy_appid_inspector.get_ctxt().get_odp_ctxt());
+        pkt_thread_odp_ctxt = &mock_session->get_odp_ctxt();
         flow = new Flow;
         flow->set_flow_data(mock_session);
         mock().setDataObject("test_log", "char", test_log);
index 6ffa57f18e1a837178d5952360218950efe9cce1..85774f5d69e6593c2feccc3de3033e2997ca3fbb 100644 (file)
@@ -38,6 +38,8 @@
 #include <CppUTest/TestHarness.h>
 #include <CppUTestExt/MockSupport.h>
 
+uint32_t ThirdPartyAppIdContext::next_version = 0;
+
 namespace snort
 {
 // Stubs for packet
index e4fc3766afbfd3be101c281b45d729cef86d3dfc..71f0c52f6c11eea573e2060e1dcb799677d418b5 100644 (file)
@@ -248,6 +248,7 @@ TEST_GROUP(appid_http_event)
         flow = new Flow;
         SfIp ip;
         mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, stub_odp_ctxt);
+        pkt_thread_odp_ctxt = &mock_session->get_odp_ctxt();
         mock_session->create_http_session();
         flow->set_flow_data(mock_session);
         appidDebug = new AppIdDebug();
index 9a9aeea9d2dbedaaac48beb3844c8007d417de1d..e3213948bce108e667bb5176cd567a0d66e5b07b 100644 (file)
@@ -72,6 +72,7 @@ AppIdModule appid_mod;
 AppIdInspector dummy_appid_inspector( appid_mod );
 AppIdConfig appid_config;
 AppIdContext appid_ctxt(appid_config);
+THREAD_LOCAL OdpContext* pkt_thread_odp_ctxt = nullptr;
 
 AppIdInspector::AppIdInspector(AppIdModule& ) { ctxt = &appid_ctxt; }
 
index af0cb4b9dc77810b8f0e7799b3abac6acc552ef4..5c51fd5bd9292c33c2db9d7f82bae2d1e3f8db72 100644 (file)
@@ -56,6 +56,7 @@ AppIdServiceSubtype APPID_UT_SERVICE_SUBTYPE = { nullptr, APPID_UT_SERVICE,
 unsigned AppIdSession::inspector_id = 0;
 std::mutex AppIdSession::inferred_svcs_lock;
 uint16_t AppIdSession::inferred_svcs_ver = 0;
+uint32_t OdpContext::next_version = 0;
 
 class MockAppIdDnsSession : public AppIdDnsSession
 {
@@ -82,6 +83,7 @@ AppIdSession::AppIdSession(IpProtocol proto, const SfIp* ip, uint16_t, AppIdInsp
     OdpContext&) : FlowData(inspector_id, &inspector), config(stub_config),
     protocol(proto), api(*(new AppIdSessionApi(this, *ip))), odp_ctxt(stub_odp_ctxt)
 {
+    odp_ctxt_version = odp_ctxt.get_version();
     service_port = APPID_UT_SERVICE_PORT;
     AppidChangeBits change_bits;
 
index caafc38d7e082698e40577263c4ad25c770d791b..a0f7b2ee58c9a17844715b619c01b10bed4169f4 100644 (file)
 #include <CppUTest/CommandLineTestRunner.h>
 #include <CppUTest/TestHarness.h>
 
-void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
-
 AppIdSession* mock_session = nullptr;
 AppIdSessionApi* appid_session_api = nullptr;
 static AppIdConfig config;
 static OdpContext odpctxt(config, nullptr);
+
+void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
+
 Inspector* InspectorManager::get_inspector(char const*, bool, const snort::SnortConfig*)
 {
     return nullptr;
@@ -68,6 +69,7 @@ TEST_GROUP(appid_session_api)
 
         SfIp ip;
         mock_session = new AppIdSession(IpProtocol::TCP, &ip, 1492, dummy_appid_inspector, odpctxt);
+        pkt_thread_odp_ctxt = &mock_session->get_odp_ctxt();
         mock_session->set_ss_application_ids(APPID_UT_ID, APPID_UT_ID, APPID_UT_ID,
             APPID_UT_ID, APPID_UT_ID, change_bits);
     }
index bdc94ebdc3d0e28244059fa9bc606c1700eaf4a6..ad50397faed9cb60fee875f8824fd51af2ab2b9f 100644 (file)
@@ -39,6 +39,8 @@
 using namespace snort;
 using namespace std;
 
+uint32_t ThirdPartyAppIdContext::next_version = 0;
+
 class ThirdPartyAppIdContextImpl : public ThirdPartyAppIdContext
 {
 public:
index c70ceedadc7d950ff9e550256749193005011093..95760aa18547e78a6beefbf2099eac3ee74eb8d2 100644 (file)
@@ -44,11 +44,19 @@ class ThirdPartyAppIdContext
 {
 public:
     ThirdPartyAppIdContext(uint32_t ver, const char* mname, ThirdPartyConfig& config)
-        : version(ver), name(mname), cfg(config) { }
+        : api_version(ver), name(mname), cfg(config)
+    {
+        version = next_version++;
+    }
+
+    uint32_t get_version() const
+    {
+        return version;
+    }
 
     virtual ~ThirdPartyAppIdContext() { }
 
-    uint32_t api_version() const { return version; }
+    uint32_t get_api_version() const { return api_version; }
     const std::string& module_name() const { return name; }
 
     virtual int tinit() = 0;
@@ -60,15 +68,18 @@ public:
     bool get_tp_reload_in_progress() { return tp_reload_in_progress; }
 
 protected:
-    const uint32_t version;
+    const uint32_t api_version;
     const std::string name;
     ThirdPartyConfig cfg;
 
 private:
     // No implicit constructor as derived classes need to provide
     // version and name.
-    ThirdPartyAppIdContext() : version(0), name("") { }
+    ThirdPartyAppIdContext() : api_version(0), name(""), version(0) { }
+    uint32_t version;
     static THREAD_LOCAL bool tp_reload_in_progress;
+    // Increments when a new third-party context is loaded
+    SO_PUBLIC static uint32_t next_version;
 };
 
 #endif
index 521a5c1f00dc50cc774310e936133b4a60541e4f..d1e11bd2f36742aaa86071661155539ce234a9a6 100644 (file)
@@ -38,7 +38,10 @@ class ThirdPartyAppIdSession
 {
 public:
     ThirdPartyAppIdSession(const ThirdPartyAppIdContext& ctxt)
-        : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT), ctxt(ctxt) { }
+        : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT), ctxt(ctxt)
+    {
+        ctxt_version = ctxt.get_version();
+    }
     virtual ~ThirdPartyAppIdSession() { }
 
     virtual bool reset() = 0;            // just reset state
@@ -57,12 +60,14 @@ public:
     virtual AppId get_appid(int& conf) { conf=confidence; return appid; }
     virtual const ThirdPartyAppIdContext& get_ctxt() const
     { return ctxt; }
+    uint32_t get_ctxt_version() { return ctxt_version; }
 
 protected:
     AppId appid;
     int confidence;
     TPState state;
     const ThirdPartyAppIdContext& ctxt;
+    uint32_t ctxt_version;
 };
 
 #endif
index 7514b4c30adf526e3448be5a18fcd4e4751a9f4e..7e333a3dc6af7ddd2d2e6fdfa2ff0471cfe94ad9 100644 (file)
@@ -35,6 +35,7 @@ using namespace std;
 using namespace snort;
 
 TPLibHandler* TPLibHandler::self = nullptr;
+uint32_t ThirdPartyAppIdContext::next_version = 0;
 
 bool TPLibHandler::load_callback(const char* const path)
 {
@@ -112,11 +113,11 @@ ThirdPartyAppIdContext* TPLibHandler::create_tp_appid_ctxt(const AppIdConfig& co
         return nullptr;
     }
 
-    if ( (tp_appid_ctxt->api_version() != THIRD_PARTY_APPID_API_VERSION)
+    if ( (tp_appid_ctxt->get_api_version() != THIRD_PARTY_APPID_API_VERSION)
         || (tp_appid_ctxt->module_name().empty()) )
     {
         ErrorMessage("Ignoring incomplete 3rd party AppID module (%s, %u, %s)!\n",
-            config.tp_appid_path.c_str(), tp_appid_ctxt->api_version(),
+            config.tp_appid_path.c_str(), tp_appid_ctxt->get_api_version(),
             tp_appid_ctxt->module_name().empty() ? "empty" : tp_appid_ctxt->module_name().c_str());
 
         delete tp_appid_ctxt;