From: Shravan Rangarajuvenkata (shrarang) Date: Fri, 4 Sep 2020 23:07:27 +0000 (+0000) Subject: Merge pull request #2447 in SNORT/snort3 from ~SHRARANG/snort3:appid_tp_reload_reorde... X-Git-Tag: 3.0.2-6~17 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=99d13aa92d82534590f06e22c3a0a44d58672863;p=thirdparty%2Fsnort3.git Merge pull request #2447 in SNORT/snort3 from ~SHRARANG/snort3:appid_tp_reload_reorder to master Squashed commit of the following: commit df9e98dfacc0edb9a9f1861357a09e6c73ded252 Author: Shravan Rangaraju Date: Thu Aug 27 17:28:49 2020 -0400 appid: reorder third-party reload to keep only one handle open at a time --- diff --git a/src/network_inspectors/appid/appid_api.cc b/src/network_inspectors/appid/appid_api.cc index b06fdbc1f..74ac5b31f 100644 --- a/src/network_inspectors/appid/appid_api.cc +++ b/src/network_inspectors/appid/appid_api.cc @@ -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; diff --git a/src/network_inspectors/appid/appid_config.cc b/src/network_inspectors/appid/appid_config.cc index 6167801ca..72e3daa35 100644 --- a/src/network_inspectors/appid/appid_config.cc +++ b/src/network_inspectors/appid/appid_config.cc @@ -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() diff --git a/src/network_inspectors/appid/appid_config.h b/src/network_inspectors/appid/appid_config.h index dadeb0437..29c0b47fa 100644 --- a/src/network_inspectors/appid/appid_config.h +++ b/src/network_inspectors/appid/appid_config.h @@ -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 tcp_port_only = {}; // port-only TCP services std::array udp_port_only = {}; // port-only UDP services std::array ip_protocol = {}; // non-TCP / UDP protocol services + + uint32_t version; + static uint32_t next_version; }; class OdpThreadContext diff --git a/src/network_inspectors/appid/appid_dcerpc_event_handler.h b/src/network_inspectors/appid/appid_dcerpc_event_handler.h index 7db84333b..a461ac042 100644 --- a/src/network_inspectors/appid/appid_dcerpc_event_handler.h +++ b/src/network_inspectors/appid/appid_dcerpc_event_handler.h @@ -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; } diff --git a/src/network_inspectors/appid/appid_discovery.cc b/src/network_inspectors/appid/appid_discovery.cc index 77a1ee7bd..fda210257 100644 --- a/src/network_inspectors/appid/appid_discovery.cc +++ b/src/network_inspectors/appid/appid_discovery.cc @@ -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; diff --git a/src/network_inspectors/appid/appid_http_event_handler.cc b/src/network_inspectors/appid/appid_http_event_handler.cc index 06ee55248..9cfbced43 100644 --- a/src/network_inspectors/appid/appid_http_event_handler.cc +++ b/src/network_inspectors/appid/appid_http_event_handler.cc @@ -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; } diff --git a/src/network_inspectors/appid/appid_inspector.cc b/src/network_inspectors/appid/appid_inspector.cc index 3f4d45553..ffbde7530 100644 --- a/src/network_inspectors/appid/appid_inspector.cc +++ b/src/network_inspectors/appid/appid_inspector.cc @@ -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) diff --git a/src/network_inspectors/appid/appid_module.cc b/src/network_inspectors/appid/appid_module.cc index c1b9925c8..7fb90f1ba 100644 --- a/src/network_inspectors/appid/appid_module.cc +++ b/src/network_inspectors/appid/appid_module.cc @@ -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; } diff --git a/src/network_inspectors/appid/appid_session.cc b/src/network_inspectors/appid/appid_session.cc index 29c34a88c..62d1f7d11 100644 --- a/src/network_inspectors/appid/appid_session.cc +++ b/src/network_inspectors/appid/appid_session.cc @@ -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++; } diff --git a/src/network_inspectors/appid/appid_session.h b/src/network_inspectors/appid/appid_session.h index 794421249..4a7f5c866 100644 --- a/src/network_inspectors/appid/appid_session.h +++ b/src/network_inspectors/appid/appid_session.h @@ -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; }; diff --git a/src/network_inspectors/appid/appid_session_api.cc b/src/network_inspectors/appid/appid_session_api.cc index 4adcdf83b..adfb0f038 100644 --- a/src/network_inspectors/appid/appid_session_api.cc +++ b/src/network_inspectors/appid/appid_session_api.cc @@ -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; } diff --git a/src/network_inspectors/appid/appid_stats.cc b/src/network_inspectors/appid/appid_stats.cc index 0a5f45e2f..fe2065b9f 100644 --- a/src/network_inspectors/appid/appid_stats.cc +++ b/src/network_inspectors/appid/appid_stats.cc @@ -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); diff --git a/src/network_inspectors/appid/ips_appid_option.cc b/src/network_inspectors/appid/ips_appid_option.cc index f35743f18..803eaf4e1 100644 --- a/src/network_inspectors/appid/ips_appid_option.cc +++ b/src/network_inspectors/appid/ips_appid_option.cc @@ -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]; diff --git a/src/network_inspectors/appid/test/appid_api_test.cc b/src/network_inspectors/appid/test/appid_api_test.cc index 2873fcd5a..17600de61 100644 --- a/src/network_inspectors/appid/test/appid_api_test.cc +++ b/src/network_inspectors/appid/test/appid_api_test.cc @@ -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); diff --git a/src/network_inspectors/appid/test/appid_discovery_test.cc b/src/network_inspectors/appid/test/appid_discovery_test.cc index 6ffa57f18..85774f5d6 100644 --- a/src/network_inspectors/appid/test/appid_discovery_test.cc +++ b/src/network_inspectors/appid/test/appid_discovery_test.cc @@ -38,6 +38,8 @@ #include #include +uint32_t ThirdPartyAppIdContext::next_version = 0; + namespace snort { // Stubs for packet diff --git a/src/network_inspectors/appid/test/appid_http_event_test.cc b/src/network_inspectors/appid/test/appid_http_event_test.cc index e4fc3766a..71f0c52f6 100644 --- a/src/network_inspectors/appid/test/appid_http_event_test.cc +++ b/src/network_inspectors/appid/test/appid_http_event_test.cc @@ -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(); diff --git a/src/network_inspectors/appid/test/appid_mock_inspector.h b/src/network_inspectors/appid/test/appid_mock_inspector.h index 9a9aeea9d..e3213948b 100644 --- a/src/network_inspectors/appid/test/appid_mock_inspector.h +++ b/src/network_inspectors/appid/test/appid_mock_inspector.h @@ -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; } diff --git a/src/network_inspectors/appid/test/appid_mock_session.h b/src/network_inspectors/appid/test/appid_mock_session.h index af0cb4b9d..5c51fd5bd 100644 --- a/src/network_inspectors/appid/test/appid_mock_session.h +++ b/src/network_inspectors/appid/test/appid_mock_session.h @@ -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; diff --git a/src/network_inspectors/appid/test/appid_session_api_test.cc b/src/network_inspectors/appid/test/appid_session_api_test.cc index caafc38d7..a0f7b2ee5 100644 --- a/src/network_inspectors/appid/test/appid_session_api_test.cc +++ b/src/network_inspectors/appid/test/appid_session_api_test.cc @@ -30,12 +30,13 @@ #include #include -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); } diff --git a/src/network_inspectors/appid/test/tp_mock.cc b/src/network_inspectors/appid/test/tp_mock.cc index bdc94ebdc..ad50397fa 100644 --- a/src/network_inspectors/appid/test/tp_mock.cc +++ b/src/network_inspectors/appid/test/tp_mock.cc @@ -39,6 +39,8 @@ using namespace snort; using namespace std; +uint32_t ThirdPartyAppIdContext::next_version = 0; + class ThirdPartyAppIdContextImpl : public ThirdPartyAppIdContext { public: diff --git a/src/network_inspectors/appid/tp_appid_module_api.h b/src/network_inspectors/appid/tp_appid_module_api.h index c70ceedad..95760aa18 100644 --- a/src/network_inspectors/appid/tp_appid_module_api.h +++ b/src/network_inspectors/appid/tp_appid_module_api.h @@ -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 diff --git a/src/network_inspectors/appid/tp_appid_session_api.h b/src/network_inspectors/appid/tp_appid_session_api.h index 521a5c1f0..d1e11bd2f 100644 --- a/src/network_inspectors/appid/tp_appid_session_api.h +++ b/src/network_inspectors/appid/tp_appid_session_api.h @@ -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 diff --git a/src/network_inspectors/appid/tp_lib_handler.cc b/src/network_inspectors/appid/tp_lib_handler.cc index 7514b4c30..7e333a3dc 100644 --- a/src/network_inspectors/appid/tp_lib_handler.cc +++ b/src/network_inspectors/appid/tp_lib_handler.cc @@ -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;