]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1901 in SNORT/snort3 from ~SHRARANG/snort3:appid_tp_reload_1_thre...
authorShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Fri, 3 Jan 2020 14:46:22 +0000 (14:46 +0000)
committerShravan Rangarajuvenkata (shrarang) <shrarang@cisco.com>
Fri, 3 Jan 2020 14:46:22 +0000 (14:46 +0000)
Squashed commit of the following:

commit cf334063cb9963471a4d3b87267f0e3e72966613
Author: Shravan Rangaraju <shrarang@cisco.com>
Date:   Tue Dec 17 06:27:06 2019 -0500

    appid: support third party reload when snort is running with single packet thread

18 files changed:
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_discovery.cc
src/network_inspectors/appid/appid_discovery.h
src/network_inspectors/appid/appid_inspector.cc
src/network_inspectors/appid/appid_inspector.h
src/network_inspectors/appid/appid_module.cc
src/network_inspectors/appid/appid_session.cc
src/network_inspectors/appid/http_xff_fields.h
src/network_inspectors/appid/test/appid_discovery_test.cc
src/network_inspectors/appid/test/tp_lib_handler_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_appid_utils.cc
src/network_inspectors/appid/tp_appid_utils.h
src/network_inspectors/appid/tp_lib_handler.cc
src/network_inspectors/appid/tp_lib_handler.h

index 98ad1d64c65fa3835729525be1cc3f2d6d81f1c0..e9eeb9ded100c39080595f277e532096d1f8e931 100644 (file)
@@ -265,12 +265,21 @@ bool AppIdConfig::init_appid(SnortConfig* sc)
     }
 
 #ifdef ENABLE_APPID_THIRD_PARTY
-    TPLibHandler::pinit(mod_config);
+    // do not reload third party on reload_config()
+    if (!tp_appid_ctxt)
+        tp_appid_ctxt = TPLibHandler::create_tp_appid_ctxt(*mod_config);
 #endif
     map_app_names_to_snort_ids(sc);
     return true;
 }
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+void AppIdConfig::create_tp_appid_ctxt()
+{
+    tp_appid_ctxt = TPLibHandler::create_tp_appid_ctxt(*mod_config);
+}
+#endif
+
 AppId AppIdConfig::get_port_service_id(IpProtocol proto, uint16_t port)
 {
     AppId appId;
index e6f2a52eb9432b69bf0a26a00c51516ef89cb2e6..a1b219198634ab152923fd66aa52a6151c5e0cf1 100644 (file)
@@ -32,6 +32,9 @@
 #include "sfip/sf_ip.h"
 #include "target_based/snort_protocols.h"
 #include "utils/sflsq.h"
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_module_api.h"
+#endif
 
 #define APP_ID_MAX_DIRS         16
 #define APP_ID_PORT_ARRAY_SIZE  65536
@@ -113,6 +116,20 @@ public:
     AppIdConfig(AppIdModuleConfig* config) : mod_config(config)
     { }
 
+    ~AppIdConfig()
+    {
+#ifdef ENABLE_APPID_THIRD_PARTY
+        delete tp_appid_ctxt;
+#endif
+    }
+
+#ifdef ENABLE_APPID_THIRD_PARTY
+    ThirdPartyAppIDModule* get_tp_appid_ctxt() const
+    { return tp_appid_ctxt; }
+
+    void create_tp_appid_ctxt();
+#endif
+
     bool init_appid(snort::SnortConfig*);
     static void pterm();
     void show();
@@ -137,6 +154,9 @@ private:
     // FIXIT-M: RELOAD - Remove static, once app_info_mgr cleanup is
     // removed from AppIdConfig::pterm
     static AppInfoManager& app_info_mgr;
+#ifdef ENABLE_APPID_THIRD_PARTY
+    ThirdPartyAppIDModule* tp_appid_ctxt = nullptr;
+#endif
 };
 
 #endif
index a13dd59216ebc24efb4b75c12a538cd6f56df6a9..b023d979eacb141eccc9092a5c2309a182be5086 100644 (file)
@@ -136,7 +136,12 @@ int AppIdDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&)
     return APPID_EINVALID;
 }
 
-void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
+#ifdef ENABLE_APPID_THIRD_PARTY
+void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector,
+    ThirdPartyAppIDModule* tp_appid_ctxt)
+#else
+  void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
+#endif
 {
     IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
     AppidSessionDirection direction = APP_ID_FROM_INITIATOR;
@@ -150,8 +155,13 @@ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspect
     AppId payload_id = APP_ID_NONE;
     AppId misc_id = APP_ID_NONE;
     AppidChangeBits change_bits;
-    bool is_discovery_done = do_discovery(p, *asd, protocol, direction, service_id, client_id,
-        payload_id, misc_id, change_bits);
+#ifdef ENABLE_APPID_THIRD_PARTY
+    bool is_discovery_done = do_discovery(p, *asd, protocol, direction, service_id,
+        client_id, payload_id, misc_id, change_bits, tp_appid_ctxt);
+#else
+    bool is_discovery_done = do_discovery(p, *asd, protocol, direction, service_id,
+        client_id, payload_id, misc_id, change_bits);
+#endif
 
     do_post_discovery(p, *asd, direction, is_discovery_done, service_id, client_id, payload_id,
         misc_id, change_bits);
@@ -826,9 +836,16 @@ static inline bool is_check_host_cache_valid(AppIdSession& asd, AppId service_id
     return false;
 }
 
-bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol protocol,
-    AppidSessionDirection direction, AppId& service_id, AppId& client_id, AppId& payload_id,
-    AppId& misc_id, AppidChangeBits& change_bits)
+#ifdef ENABLE_APPID_THIRD_PARTY
+bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd,
+    IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+    AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits,
+    ThirdPartyAppIDModule* tp_appid_ctxt)
+#else
+bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd,
+    IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+    AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits)
+#endif
 {
     bool is_discovery_done = false;
 
@@ -860,8 +877,13 @@ bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol proto
 
     // Third party detection
 #ifdef ENABLE_APPID_THIRD_PARTY
-    if ( TPLibHandler::have_tp() )
-        is_discovery_done = do_tp_discovery(asd, protocol, p, direction, change_bits);
+    if (tp_appid_ctxt)
+    {
+        // Skip third-party inspection for sessions using old config
+        if ((asd.tpsession and asd.tpsession->get_ctxt() == tp_appid_ctxt) || !asd.tpsession)
+            is_discovery_done = do_tp_discovery(*tp_appid_ctxt, asd, protocol, p,
+                direction, change_bits);
+    }
 #endif
 
     // Port-based service detection
index b89b26771198d1edea7332db3dcc83844fcf6a3b..409704f70e130cbb6745fafa8e65a619bb677c8d 100644 (file)
@@ -40,6 +40,7 @@ class AppIdSession;
 class AppIdDetector;
 class ServiceDetector;
 struct ServiceDetectorPort;
+class ThirdPartyAppIDModule;
 
 namespace snort
 {
@@ -111,7 +112,12 @@ public:
         int position, unsigned nocase);
     virtual int add_service_port(AppIdDetector*, const ServiceDetectorPort&);
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+    static void do_application_discovery(snort::Packet* p, AppIdInspector&,
+        ThirdPartyAppIDModule*);
+#else
     static void do_application_discovery(snort::Packet* p, AppIdInspector&);
+#endif
     static void publish_appid_event(AppidChangeBits&, snort::Flow*);
 
     AppIdDetectors* get_tcp_detectors()
@@ -136,9 +142,16 @@ protected:
 private:
     static bool do_pre_discovery(snort::Packet* p, AppIdSession** p_asd, AppIdInspector& inspector,
         IpProtocol& protocol, AppidSessionDirection& direction);
-    static bool do_discovery(snort::Packet* p, AppIdSession& asd, IpProtocol protocol,
-        AppidSessionDirection direction, AppId& service_id, AppId& client_id, AppId& payload_id,
-        AppId& misc_id, AppidChangeBits& change_bits);
+#ifdef ENABLE_APPID_THIRD_PARTY
+    static bool do_discovery(snort::Packet* p, AppIdSession& asd,
+        IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+        AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits,
+        ThirdPartyAppIDModule* tp_appid_ctxt);
+#else
+    static bool do_discovery(snort::Packet* p, AppIdSession& asd,
+        IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+        AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits);
+#endif
     static void do_post_discovery(snort::Packet* p, AppIdSession& asd,
         AppidSessionDirection direction, bool is_discovery_done, AppId service_id, AppId client_id,
         AppId payload_id, AppId misc_id, AppidChangeBits& change_bits);
index 18428ac41251af7beed2b77502dd4d1e10c37970..b73ec9cbc06d5a129217d68a02cef826b67b7a60 100644 (file)
 #include "service_plugins/service_discovery.h"
 #include "service_plugins/service_ssl.h"
 #ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_module_api.h"
 #include "tp_lib_handler.h"
 #endif
 
 using namespace snort;
+#ifdef ENABLE_APPID_THIRD_PARTY
+THREAD_LOCAL ThirdPartyAppIDModule* tp_appid_thread_ctxt = nullptr;
+#endif
 static THREAD_LOCAL PacketTracer::TracerMute appid_mute;
 
 // FIXIT-L - appid cleans up openssl now as it is the primary (only) user... eventually this
@@ -116,7 +120,7 @@ bool AppIdInspector::configure(SnortConfig* sc)
     active_config->init_appid(sc);
 
 #ifdef ENABLE_APPID_THIRD_PARTY
-    if (!TPLibHandler::have_tp())
+    if (!active_config->get_tp_appid_ctxt())
 #endif
     {
         DataBus::subscribe_global(HTTP_REQUEST_HEADER_EVENT_KEY, new HttpEventHandler(
@@ -155,9 +159,6 @@ void AppIdInspector::tinit()
     appidDebug = new AppIdDebug();
     if (active_config->mod_config and active_config->mod_config->log_all_sessions)
         appidDebug->set_enabled(true);
-#ifdef ENABLE_APPID_THIRD_PARTY
-    TPLibHandler::tinit();
-#endif
 }
 
 void AppIdInspector::tterm()
@@ -170,7 +171,9 @@ void AppIdInspector::tterm()
     delete appidDebug;
     appidDebug = nullptr;
 #ifdef ENABLE_APPID_THIRD_PARTY
-    TPLibHandler::tterm();
+    ThirdPartyAppIDModule* tp_appid_ctxt = active_config->get_tp_appid_ctxt();
+    if (tp_appid_ctxt)
+        tp_appid_ctxt->tfini();
 #endif
 }
 
@@ -179,9 +182,29 @@ void AppIdInspector::eval(Packet* p)
     Profile profile(appid_perf_stats);
     appid_stats.packets++;
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+    ThirdPartyAppIDModule* tp_appid_ctxt = active_config->get_tp_appid_ctxt();
+    if (tp_appid_thread_ctxt != tp_appid_ctxt)
+    {
+        if (tp_appid_thread_ctxt)
+        {
+            tp_appid_thread_ctxt->tfini();
+
+            // FIXIT-H: Assuming one packet thread
+            delete tp_appid_thread_ctxt;
+        }
+        tp_appid_ctxt->tinit();
+        tp_appid_thread_ctxt = tp_appid_ctxt;
+    }
+#endif
+
     if (p->flow)
     {
+#ifdef ENABLE_APPID_THIRD_PARTY
+        AppIdDiscovery::do_application_discovery(p, *this, tp_appid_thread_ctxt);
+#else
         AppIdDiscovery::do_application_discovery(p, *this);
+#endif
         // FIXIT-L tag verdict reason as appid for daq
         if (PacketTracer::is_active())
             add_appid_to_packet_trace(*p->flow);
@@ -238,6 +261,9 @@ static void appid_inspector_tinit()
 
 static void appid_inspector_tterm()
 {
+#ifdef ENABLE_APPID_THIRD_PARTY
+    TPLibHandler::tfini();
+#endif
     AppIdPegCounts::cleanup_pegs();
 }
 
index ab1b4704c1d7538835336c36e47fe7ccc4c485e3..6c582eafb3ecd0a13b9d13efc2ae1de72832e356 100644 (file)
@@ -60,5 +60,9 @@ private:
 
 };
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+extern THREAD_LOCAL ThirdPartyAppIDModule* tp_appid_thread_ctxt;
+#endif
+
 #endif
 
index 99f361c5b48a44de2f25e070555067b61fc30515..fec0ae9bc21a01b507216d4ddcbb6f3bf9c21bd8 100644 (file)
 #include "main/snort.h"
 #include "main/swapper.h"
 #include "main/thread_config.h"
+#include "managers/inspector_manager.h"
 #include "profiler/profiler.h"
 #include "utils/util.h"
 
 #include "app_info_table.h"
 #include "appid_debug.h"
+#include "appid_inspector.h"
 #include "appid_peg_counts.h"
 #include "service_state.h"
 
@@ -170,6 +172,7 @@ static int disable_debug(lua_State*)
 
 static int reload_third_party(lua_State*)
 {
+#ifdef ENABLE_APPID_THIRD_PARTY
     if (Swapper::get_reload_in_progress())
     {
         LogMessage("== reload pending; retry\n");
@@ -182,8 +185,14 @@ static int reload_third_party(lua_State*)
     {
         Swapper::set_reload_in_progress(true);
         LogMessage(".. reloading third-party");
+        AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+        AppIdConfig* config = inspector->get_appid_config();
+        config->create_tp_appid_ctxt();
         Swapper::set_reload_in_progress(false);
     }
+#else
+    LogMessage("== third party is not enabled\n");
+#endif
 
     return 0;
 }
index 868f8e4c4b466659c7a0cb5ff9d7160712aa172a..77c5313028d6e06660c41cff3ee4dc1571c096ce 100644 (file)
@@ -140,8 +140,10 @@ AppIdSession::~AppIdSession()
 #ifdef ENABLE_APPID_THIRD_PARTY
     if (tpsession)
     {
-        delete tpsession;
-        tpsession = nullptr;
+        if (tpsession->get_ctxt() == tp_appid_thread_ctxt)
+            tpsession->delete_with_ctxt();
+        else
+            delete tpsession;
     }
 #endif
 
@@ -926,7 +928,7 @@ AppIdDnsSession* AppIdSession::get_dns_session()
 bool AppIdSession::is_tp_appid_done() const
 {
 #ifdef ENABLE_APPID_THIRD_PARTY
-    if (TPLibHandler::have_tp())
+    if (config->get_tp_appid_ctxt())
     {
         if (!tpsession)
             return false;
@@ -955,7 +957,7 @@ bool AppIdSession::is_tp_processing_done() const
 bool AppIdSession::is_tp_appid_available() const
 {
 #ifdef ENABLE_APPID_THIRD_PARTY
-    if (TPLibHandler::have_tp())
+    if (config->get_tp_appid_ctxt())
     {
         if (!tpsession)
             return false;
index 073dec62292fcd1abaeeb68c06c5ba9e2441c467..ebd8012ada08a4a8b8e54b5c25f52213aaf22272 100644 (file)
@@ -27,9 +27,6 @@
 // FIXIT-L refactor
 #define HTTP_XFF_FIELD_X_FORWARDED_FOR  "X-Forwarded-For"
 #define HTTP_XFF_FIELD_TRUE_CLIENT_IP   "True-Client-IP"
-/* #define HTTP_MAX_XFF_FIELDS             8 */
-/* #define HTTP_XFF_FIELD_X_FORWARDED_FOR "" */
-/* #define HTTP_XFF_FIELD_TRUE_CLIENT_IP "" */
 
 #define HTTP_MAX_XFF_FIELDS 8
 
@@ -39,5 +36,4 @@ struct XffFieldValue
     std::string value;
 };
 
-
 #endif
index 82769df2ae1d8274e031d4f825257f3105e4fd5a..50050226c934b5159d74174dafddb7f57ab4cc0e 100644 (file)
@@ -256,7 +256,7 @@ int dns_host_scan_hostname(const uint8_t*, size_t, AppId*, AppId*)
 {
     return 0;
 }
-bool do_tp_discovery(AppIdSession&, IpProtocol,
+bool do_tp_discovery(ThirdPartyAppIDModule& , AppIdSession&, IpProtocol,
     Packet*, AppidSessionDirection&, AppidChangeBits&)
 {
     return true;
@@ -335,7 +335,11 @@ TEST(appid_discovery_tests, event_published_when_ignoring_flow)
     asd->common.initiator_ip.set("1.2.3.4");
     asd->set_session_flags(APPID_SESSION_IGNORE_FLOW);
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+    AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
     AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
 
     // Detect changes in service, client, payload, and misc appid
     CHECK_EQUAL(databus_publish_called, true);
@@ -366,7 +370,11 @@ TEST(appid_discovery_tests, event_published_when_processing_flow)
     asd->common.initiator_port = 21;
     asd->common.initiator_ip.set("1.2.3.4");
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+    AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
     AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
 
     // Detect changes in service, client, payload, and misc appid
     CHECK_EQUAL(databus_publish_called, true);
@@ -427,7 +435,11 @@ TEST(appid_discovery_tests, change_bits_for_non_http_appid)
     asd->client.set_id(APP_ID_CURL);
     asd->service.set_id(APP_ID_FTP);
 
+#ifdef ENABLE_APPID_THIRD_PARTY
+    AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
     AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
 
     // Detect event for FTP service and CURL client
     CHECK_EQUAL(databus_publish_called, true);
@@ -440,7 +452,11 @@ TEST(appid_discovery_tests, change_bits_for_non_http_appid)
     asd->payload.set_id(APP_ID_NONE);
     asd->client.set_id(APP_ID_NONE);
     asd->service.set_id(APP_ID_DNS);
+#ifdef ENABLE_APPID_THIRD_PARTY
+    AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
     AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
 
     // Detect event for DNS service
     CHECK_EQUAL(databus_publish_called, true);
index ee4c51be8f3b3dd105e889e3d188acbf8b45a2ff..877f8c22769dd702539cca8b898bd1413bd1f563 100644 (file)
@@ -52,24 +52,25 @@ TEST(tp_lib_handler, load_unload)
     config.tp_appid_config="./tp.config";
 
     tph = TPLibHandler::get();
-    tph->pinit(&config);
-    CHECK_TRUE(tph->have_tp());
+    ThirdPartyAppIDModule* tpm = TPLibHandler::create_tp_appid_ctxt(config);
+    CHECK_TRUE(tpm != nullptr);
 
-    CreateThirdPartyAppIDSession_t asf = tph->tpsession_factory();
-    ThirdPartyAppIDSession* tpsession = asf();
+    TpAppIdCreateSession asf = tph->tpsession_factory();
+    ThirdPartyAppIDSession* tpsession = asf(*tpm);
 
     CHECK_TRUE(tpsession != nullptr);
 
     delete tpsession;
+    delete tpm;
 
-    tph->pfini();
+    TPLibHandler::pfini();
 }
 
 TEST(tp_lib_handler, tp_lib_handler_get)
 {
-    tph=TPLibHandler::get();
-    TPLibHandler* tph2=TPLibHandler::get();
-    CHECK_EQUAL(tph,tph2);
+    tph = TPLibHandler::get();
+    TPLibHandler* tph2 = TPLibHandler::get();
+    CHECK_EQUAL(tph, tph2);
     TPLibHandler::pfini();
 }
 
@@ -79,23 +80,11 @@ TEST(tp_lib_handler, load_error)
     AppIdModuleConfig config;
     config.tp_appid_path="nonexistent.so";
     TPLibHandler::get();
-    TPLibHandler::pinit(&config);
-    CHECK_FALSE(TPLibHandler::have_tp());
+    ThirdPartyAppIDModule* tpm = TPLibHandler::create_tp_appid_ctxt(config);
+    CHECK_TRUE(tpm == nullptr);
     TPLibHandler::pfini();
 }
 
-TEST(tp_lib_handler, tp_appid_module_pinit_error)
-{
-    // Trigger MODULE pinit error:
-    AppIdModuleConfig config;
-    config.tp_appid_path="./libtp_mock.so";
-    config.tp_appid_config="";  // forces MODULE::pinit() to return 1.
-    tph=TPLibHandler::get();
-    tph->pinit(&config);
-    CHECK_FALSE(tph->have_tp());
-    tph->pfini(1);                      // print stats too.
-}
-
 int main(int argc, char** argv)
 {
     int rc = CommandLineTestRunner::RunAllTests(argc, argv);
index 3eb1b3423f19d71a70960829ab708ff645effbc2..b21dbd64d226044a3c1aeea5e406dc63407a68c7 100644 (file)
@@ -42,8 +42,8 @@ using namespace std;
 class ThirdPartyAppIDModuleImpl : public ThirdPartyAppIDModule
 {
 public:
-    ThirdPartyAppIDModuleImpl(uint32_t ver, const char* mname)
-        : ThirdPartyAppIDModule(ver, mname)
+    ThirdPartyAppIDModuleImpl(uint32_t ver, const char* mname, ThirdPartyConfig& config)
+        : ThirdPartyAppIDModule(ver, mname, config)
     {
         cerr << WhereMacro << endl;
     }
@@ -53,32 +53,18 @@ public:
         cerr << WhereMacro << endl;
     }
 
-    // Hack: use cfg to manipulate pinit to return 1, so we can hit the
-    // if (ret != 0) case in tp_lib_handler.cc.
-    int pinit(ThirdPartyConfig& cfg) override
-    {
-        cerr << WhereMacro << endl;
-        return cfg.tp_appid_config.empty() ? 1 : 0;
-    }
-
     int tinit() override { return 0; }
-    int reconfigure(const ThirdPartyConfig&) override { return 0; }
-    int pfini() override
-    {
-        cerr << WhereMacro << endl;
-        return 0;
-    }
-
     int tfini() override { return 0; }
-    int print_stats() override { return 0; }
-    int reset_stats() override { return 0; }
 };
 
 class ThirdPartyAppIDSessionImpl : public ThirdPartyAppIDSession
 {
 public:
-
+    ThirdPartyAppIDSessionImpl(ThirdPartyAppIDModule& ctxt)
+      : ThirdPartyAppIDSession(ctxt)
+    { }
     bool reset() override { return 1; }
+    void delete_with_ctxt() override { delete this; }
     TPState process(const Packet&, AppidSessionDirection, vector<AppId>&,
         ThirdPartyAppIDAttributeData&) override { return TP_STATE_INIT; }
 
@@ -98,17 +84,24 @@ private:
 // once the .so has been loaded.
 extern "C"
 {
-    SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module();
-    SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session();
+    SO_PUBLIC ThirdPartyAppIDModuleImpl* tp_appid_create_ctxt(ThirdPartyConfig& config)
+    {
+        return new ThirdPartyAppIDModuleImpl(2,"foobar", config);
+    }
+
+    SO_PUBLIC ThirdPartyAppIDSessionImpl* tp_appid_create_session(ThirdPartyAppIDModule& ctxt)
+    {
+        return new ThirdPartyAppIDSessionImpl(ctxt);
+    }
 
-    SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module()
+    SO_PUBLIC int tp_appid_pfini()
     {
-        return new ThirdPartyAppIDModuleImpl(1,"foobar");
+        return 0;
     }
 
-    SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session()
+    SO_PUBLIC int tp_appid_tfini()
     {
-        return new ThirdPartyAppIDSessionImpl;
+        return 0;
     }
 }
 
index dbc2ecc1200db3bbc8f1fc5dc7a3cb524e2be924..39bbee89981d9794c8b1fe603043e3e150cb8525 100644 (file)
@@ -25,7 +25,7 @@
 #include <string>
 #include "tp_appid_types.h"
 
-#define THIRD_PARTY_APP_ID_API_VERSION 1
+#define THIRD_PARTY_APP_ID_API_VERSION 2
 
 class ThirdPartyConfig
 {
@@ -38,16 +38,10 @@ public:
     unsigned http_response_version_enabled : 1;
     std::string tp_appid_config;
     std::vector<std::string> xff_fields;
-    std::vector<std::string> old_xff_fields;
     bool tp_appid_stats_enable = false;
     bool tp_appid_config_dump = false;
 
     ThirdPartyConfig()
-    {
-        getXffFields();
-    }
-
-    void getXffFields()
     {
         xff_fields.clear();
         xff_fields.emplace_back(HTTP_XFF_FIELD_X_FORWARDED_FOR);
@@ -58,41 +52,28 @@ public:
 class ThirdPartyAppIDModule
 {
 public:
-
-    /* ThirdPartyAppIdConfig tpac; */
-
-    ThirdPartyAppIDModule(uint32_t ver, const char* mname)
-        : version(ver), name(mname) { }
+    ThirdPartyAppIDModule(uint32_t ver, const char* mname, ThirdPartyConfig& config)
+        : version(ver), name(mname), cfg(config) { }
 
     virtual ~ThirdPartyAppIDModule() { }
 
     uint32_t api_version() const { return version; }
     const std::string& module_name() const { return name; }
 
-    virtual int pinit(ThirdPartyConfig&) = 0;
-    virtual int pfini() = 0;
-
     virtual int tinit() = 0;
     virtual int tfini() = 0;
 
-    virtual int reconfigure(const ThirdPartyConfig&) = 0;
-    virtual int print_stats() = 0;
-    virtual int reset_stats() = 0;
+    virtual const ThirdPartyConfig& get_config() const { return cfg; }
 
-private:
+protected:
+    const uint32_t version;
+    const std::string name;
+    ThirdPartyConfig cfg;
 
+private:
     // No implicit constructor as derived classes need to provide
     // version and name.
     ThirdPartyAppIDModule() : version(0), name("") { }
-
-    const uint32_t version;
-    const std::string name;
 };
 
-// Function pointer to object factory that returns a pointer to a newly
-// created object of a derived class.
-// This needs to be exported (SO_PUBLIC) by any third party .so library.
-// Must return NULL if it fails to create the object.
-typedef ThirdPartyAppIDModule* (* CreateThirdPartyAppIDModule_t)();
-
 #endif
index beed36430560a9518dab6788e93ec656050e5c9f..1a904985ba72607d1668662c9181c8f440511a73 100644 (file)
@@ -32,17 +32,17 @@ namespace snort
 struct Packet;
 }
 
-#define THIRD_PARTY_APP_ID_API_VERSION 1
+class ThirdPartyAppIDModule;
 
 class ThirdPartyAppIDSession
 {
 public:
-
-    ThirdPartyAppIDSession()
-        : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT) { }
+    ThirdPartyAppIDSession(ThirdPartyAppIDModule& ctxt)
+        : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT), ctxt(ctxt) { }
     virtual ~ThirdPartyAppIDSession() { }
 
     virtual bool reset() = 0;            // just reset state
+    virtual void delete_with_ctxt() = 0;
     virtual TPState process(const snort::Packet&,
         AppidSessionDirection direction,
         std::vector<AppId>& proto_list,
@@ -55,18 +55,15 @@ public:
     virtual void set_attr(TPSessionAttr) = 0;
     virtual unsigned get_attr(TPSessionAttr) = 0;
     virtual AppId get_appid(int& conf) { conf=confidence; return appid; }
+    virtual const ThirdPartyAppIDModule* get_ctxt() const
+    { return &ctxt; }
 
 protected:
     AppId appid;
     int confidence;
     TPState state;
+    const ThirdPartyAppIDModule& ctxt;
 };
 
-// Function pointer to object factory that returns a pointer to a newly
-// created object of a derived class.
-// This needs to be exported (SO_PUBLIC) by any third party .so library.
-// Must return NULL if it fails to create the object.
-typedef ThirdPartyAppIDSession* (* CreateThirdPartyAppIDSession_t)();
-
 #endif
 
index 9b1b9460f9b33e4a39cfd316e718f3057f86c105..fdd6556c02dc174f833c5d10dbe02db50b8db9b7 100644 (file)
@@ -621,7 +621,7 @@ static inline void check_terminate_tp_module(AppIdSession& asd, uint16_t tpPktCo
     }
 }
 
-bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol,
+bool do_tp_discovery(ThirdPartyAppIDModule& tp_module, AppIdSession& asd, IpProtocol protocol,
     Packet* p, AppidSessionDirection& direction, AppidChangeBits& change_bits)
 {
     AppId tp_app_id = asd.get_tp_app_id();
@@ -668,10 +668,10 @@ bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol,
                 if (!asd.tpsession)
                 {
                     const TPLibHandler* tph = TPLibHandler::get();
-                    CreateThirdPartyAppIDSession_t tpsf = tph->tpsession_factory();
-                    if ( !(asd.tpsession = tpsf()) )
-                        FatalError("Could not allocate asd.tpsession data");
-                }      // debug output of packet content
+                    TpAppIdCreateSession tpsf = tph->tpsession_factory();
+                    if ( !(asd.tpsession = tpsf(tp_module)) )
+                        ErrorMessage("Could not allocate asd.tpsession data");
+                }
 
                 TPState current_tp_state = asd.tpsession->process(*p, direction,
                     tp_proto_list, tp_attribute_data);
index 05a9bb84537219fa24e284a5247f6327150e6aff..943cb3ff39e54d05c51a41485796ed27999f25bb 100644 (file)
@@ -26,7 +26,7 @@
 
 class AppIdSession;
 
-bool do_tp_discovery(
-    AppIdSession&, IpProtocol, snort::Packet*, AppidSessionDirection&, AppidChangeBits&);
+bool do_tp_discovery(ThirdPartyAppIDModule& tp_module, AppIdSession&, IpProtocol, snort::Packet*,
+    AppidSessionDirection&, AppidChangeBits&);
 
 #endif
index c3dcade539ce8ef8b76f05752230910984482878..50720522ab5d7bd04bdf262505179b7dce9a100f 100644 (file)
 using namespace std;
 using namespace snort;
 
-#define TP_APPID_MODULE_SYMBOL "create_third_party_appid_module"
-#define TP_APPID_SESSION_SYMBOL "create_third_party_appid_session"
-
 TPLibHandler* TPLibHandler::self = nullptr;
 
-int TPLibHandler::LoadCallback(const char* const path, int /* indent */)
+bool TPLibHandler::load_callback(const char* const path)
 {
-    void* handle = 0;
-    ThirdPartyAppIDModule* tp_module = 0;
-    const char* error = nullptr;
-
-    if (tp_appid_module != nullptr)
-    {
-        ErrorMessage("Ignoring additional 3rd party AppID module (%s)!\n", path);
-        return 0;
-    }
-
-    // Load the tp library and get function pointers to the module and
-    // session object factories.
     dlerror();
-    handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
-    if (handle == nullptr)
+    self->tp_so_handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+    if (self->tp_so_handle == nullptr)
     {
         ErrorMessage("Failed to load 3rd party AppID library: %s - %s\n", path, dlerror());
-        return 0;
+        return false;
     }
 
-    CreateThirdPartyAppIDModule_t createThirdPartyAppIDModule=
-        (CreateThirdPartyAppIDModule_t)dlsym(handle, TP_APPID_MODULE_SYMBOL);
-    if ((error=dlerror()) != nullptr)
+    typedef void (*dummyFunc)();
+    struct funcBinding
     {
-        ErrorMessage(
-            "Failed to get 3rd party AppID module object factory: %s - %s\n",
-            TP_APPID_MODULE_SYMBOL, error);
-        dlclose(handle);
-        return 0;
-    }
-
-    createThirdPartyAppIDSession=(CreateThirdPartyAppIDSession_t)dlsym(
-        handle,TP_APPID_SESSION_SYMBOL);
-    if ((error=dlerror()) != nullptr)
+        const char* lib_sym;
+        dummyFunc* local_sym;
+    } bindings[] =
     {
-        ErrorMessage(
-            "Failed to get 3rd party AppID session object factory: %s - %s\n",
-            TP_APPID_SESSION_SYMBOL, error);
-        dlclose(handle);
-        return 0;
-    }
+        { "tp_appid_create_ctxt", (dummyFunc*)&tp_appid_create_ctxt },
+        { "tp_appid_create_session", (dummyFunc*)&tp_appid_create_session },
+        { "tp_appid_pfini", (dummyFunc*)&tp_appid_pfini },
+        { "tp_appid_tfini", (dummyFunc*)&tp_appid_tfini },
+        { nullptr, nullptr }
+    };
 
-    // The tp module object is a singleton and gets created here in main thread.
-    // TP session objects get created per worker thread.
-    tp_module=createThirdPartyAppIDModule();
-    if (tp_module == nullptr)
-    {
-        ErrorMessage("Failed to create third party appId module.\n");
-        dlclose(handle);
-        return 0;
-    }
+    funcBinding* index;
 
-    if ( (tp_module->api_version() != THIRD_PARTY_APP_ID_API_VERSION)
-        || (tp_module->module_name().empty()) )
+    for (index = bindings; index->lib_sym; index++)
     {
-        ErrorMessage("Ignoring incomplete 3rd party AppID module (%s, %u, %s)!\n",
-            path, tp_module->api_version(),
-            tp_module->module_name().empty() ? "empty" : tp_module->module_name().c_str());
-
-        dlclose(handle);
-        delete tp_module;
-        return 0;
+        *(void**)index->local_sym  = dlsym(self->tp_so_handle, index->lib_sym);
+        if (*(index->local_sym) == nullptr)
+        {
+            char* error;
+            ErrorMessage("AppId: Failed to resolve symbol: %s %s\n", index->lib_sym,
+                (error = dlerror()) ? error : "");
+            dlclose(self->tp_so_handle);
+            self->tp_so_handle = nullptr;
+            return false;
+        }
     }
 
-    this->tp_so_handle = handle;
-    tp_appid_module = tp_module;
-    return 0;
+    return true;
 }
 
-void TPLibHandler::pinit(const AppIdModuleConfig* config)
+ThirdPartyAppIDModule* TPLibHandler::create_tp_appid_ctxt(const AppIdModuleConfig& config)
 {
-    int ret;
-
-    if (self->tp_so_handle or config->tp_appid_path.empty())
-        return;
-
-    self->tp_config.tp_appid_config = config->tp_appid_config;
-    self->tp_config.tp_appid_stats_enable = config->tp_appid_stats_enable;
-    self->tp_config.tp_appid_config_dump = config->tp_appid_config_dump;
+    assert(self != nullptr);
 
-    self->LoadCallback(config->tp_appid_path.c_str(),1);
-
-    if (self->tp_appid_module == nullptr)
+    if (!self->tp_so_handle)
     {
-        ErrorMessage("Ignoring third party AppId library\n");
-        return;
+        if (config.tp_appid_path.empty())
+            return nullptr;
+
+        if (!self->load_callback(config.tp_appid_path.c_str()))
+            return nullptr;
     }
 
-    self->tp_config.chp_body_collection_max = config->chp_body_collection_max;
-    self->tp_config.ftp_userid_disabled = config->ftp_userid_disabled;
-    self->tp_config.chp_body_collection_disabled =
-        config->chp_body_collection_disabled;
-    self->tp_config.tp_allow_probes = config->tp_allow_probes;
-    if (config->http2_detection_enabled)
-        self->tp_config.http_upgrade_reporting_enabled = 1;
+    ThirdPartyConfig tp_config;
+    tp_config.tp_appid_config = config.tp_appid_config;
+    tp_config.tp_appid_stats_enable = config.tp_appid_stats_enable;
+    tp_config.tp_appid_config_dump = config.tp_appid_config_dump;
+    tp_config.chp_body_collection_max = config.chp_body_collection_max;
+    tp_config.ftp_userid_disabled = config.ftp_userid_disabled;
+    tp_config.chp_body_collection_disabled =
+        config.chp_body_collection_disabled;
+    tp_config.tp_allow_probes = config.tp_allow_probes;
+    if (config.http2_detection_enabled)
+        tp_config.http_upgrade_reporting_enabled = 1;
     else
-        self->tp_config.http_upgrade_reporting_enabled = 0;
+        tp_config.http_upgrade_reporting_enabled = 0;
+    tp_config.http_response_version_enabled = config.http_response_version_enabled;
 
-    self->tp_config.http_response_version_enabled = config->http_response_version_enabled;
+    ThirdPartyAppIDModule* tp_appid_ctxt = self->tp_appid_create_ctxt(tp_config);
+    if (tp_appid_ctxt == nullptr)
+    {
+        ErrorMessage("Failed to create third party appId context.\n");
+        dlclose(self->tp_so_handle);
+        self->tp_so_handle = nullptr;
+        return nullptr;
+    }
 
-    ret = self->tp_appid_module->pinit(self->tp_config);
-    if (ret != 0)
+    if ( (tp_appid_ctxt->api_version() != THIRD_PARTY_APP_ID_API_VERSION)
+        || (tp_appid_ctxt->module_name().empty()) )
     {
-        ErrorMessage("Unable to initialize 3rd party AppID module (%d)!\n", ret);
-        delete self->tp_appid_module;
+        ErrorMessage("Ignoring incomplete 3rd party AppID module (%s, %u, %s)!\n",
+            config.tp_appid_path.c_str(), tp_appid_ctxt->api_version(),
+            tp_appid_ctxt->module_name().empty() ? "empty" : tp_appid_ctxt->module_name().c_str());
+
+        delete tp_appid_ctxt;
         dlclose(self->tp_so_handle);
         self->tp_so_handle = nullptr;
-        self->tp_appid_module = nullptr;
-        return;
+        return nullptr;
     }
+
+    return tp_appid_ctxt;
 }
 
-void TPLibHandler::pfini(bool print_stats_flag)
+void TPLibHandler::tfini()
 {
-    if (self and self->tp_appid_module != nullptr)
-    {
-        if (print_stats_flag)
-            self->tp_appid_module->print_stats();
+    assert(self != nullptr);
 
-        int ret = self->tp_appid_module->pfini();
+    int ret = 0;
 
-        if (ret != 0)
-            ErrorMessage("Could not finalize 3rd party AppID module (%d)!\n", ret);
+    if (self->tp_appid_tfini)
+        ret = self->tp_appid_tfini();
 
-        delete self->tp_appid_module;
-        self->tp_appid_module = nullptr;
+    if (ret != 0)
+        ErrorMessage("Could not terminate packet thread in 3rd party AppID module (%d)!\n", ret);
+}
 
-        dlclose(self->tp_so_handle); // after delete, otherwise tpam will be dangling
-        self->tp_so_handle = nullptr;
-    }
+void TPLibHandler::pfini()
+{
+    assert(self != nullptr);
+
+    int ret = 0;
+
+    if (self->tp_appid_pfini)
+        ret = self->tp_appid_pfini();
+
+    if (ret != 0)
+        ErrorMessage("Could not terminate 3rd party AppID module (%d)!\n", ret);
+
+    // FIXIT-L: Find the right place to dlclose self->tp_so_handle. dlclose here was causing
+    // segfault
 
     if ( self ) {
         delete self;
index 6909a4ed76ceff632818bfd0ad37e01fa3edc2d3..e461d4582403dfd179bf60bdcdd9890d4e3cd102 100644 (file)
 
 class AppIdModuleConfig;
 
-// Class responsible for loading/reloading the thirdparty.so library and
-// for holding pointers to objects that live inside thirdparty.so.
+// This needs to be exported by any third party .so library.
+// Must return NULL if it fails to create the object.
+typedef ThirdPartyAppIDModule* (* TpAppIdCreateCtxt)(ThirdPartyConfig& );
+typedef ThirdPartyAppIDSession* (* TpAppIdCreateSession)(ThirdPartyAppIDModule& ctxt);
+typedef int (* TpAppIdPfini)();
+typedef int (* TpAppIdTfini)();
+
+// Class responsible for loading/reloading the thirdparty.so library
 class TPLibHandler
 {
 public:
-
-    static bool have_tp()
-    {
-        return self and self->tp_appid_module != nullptr;
-    }
-
     static TPLibHandler* get()
     {
         if (self)
             return self;
         else
-            return (self=new TPLibHandler());
+            return (self = new TPLibHandler());
     }
 
-    // called from appid_inspector.cc appid_inspector_pinit() / pterm()
-    static void pinit(const AppIdModuleConfig* config);
-    static void pfini(bool print_stats_flag=0);
+    static ThirdPartyAppIDModule* create_tp_appid_ctxt(const AppIdModuleConfig& config);
+    static void tfini();
+    static void pfini();
 
-    // called from AppIdInspector tinit/tterm via
-    // AppIdConfig::tp_appid_module_tinit/tterm.
-    static void tinit() { if ( have_tp() ) self->tp_appid_module->tinit(); }
-    static void tterm() { if ( have_tp() ) self->tp_appid_module->tfini(); }
-
-    CreateThirdPartyAppIDSession_t tpsession_factory() const
+    TpAppIdCreateSession tpsession_factory() const
     {
-        return createThirdPartyAppIDSession;
+        return tp_appid_create_session;
     }
 
 private:
-
     TPLibHandler() = default;
     ~TPLibHandler() = default;
 
     static TPLibHandler* self;
     void* tp_so_handle = nullptr;   // output of dlopen(thirdparty.so)
-    ThirdPartyAppIDModule* tp_appid_module = nullptr;
-    CreateThirdPartyAppIDSession_t createThirdPartyAppIDSession;
-
-    ThirdPartyConfig tp_config;
+    TpAppIdCreateCtxt tp_appid_create_ctxt = nullptr;
+    TpAppIdCreateSession tp_appid_create_session = nullptr;
+    TpAppIdPfini tp_appid_pfini = nullptr;
+    TpAppIdTfini tp_appid_tfini = nullptr;
 
-    int LoadCallback(const char* path, int);
+    bool load_callback(const char* path);
 };
 
 #endif