]> git.ipfire.org Git - thirdparty/snort3.git/commitdiff
Merge pull request #1264 in SNORT/snort3 from refactor_detector_init to master
authorMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 19 Jun 2018 19:54:24 +0000 (15:54 -0400)
committerMike Stepanek (mstepane) <mstepane@cisco.com>
Tue, 19 Jun 2018 19:54:24 +0000 (15:54 -0400)
Squashed commit of the following:

commit 8a59f6a1231548b5b614aebf2947dc87856b5564
Author: deramada <deramada@cisco.com>
Date:   Mon May 28 21:21:11 2018 -0400

    appid: refactor detector initialization

51 files changed:
src/network_inspectors/appid/app_forecast.cc
src/network_inspectors/appid/appid_config.cc
src/network_inspectors/appid/appid_config.h
src/network_inspectors/appid/appid_detector.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/client_plugins/client_detector.h
src/network_inspectors/appid/client_plugins/client_discovery.cc
src/network_inspectors/appid/client_plugins/client_discovery.h
src/network_inspectors/appid/detector_plugins/detector_dns.cc
src/network_inspectors/appid/detector_plugins/detector_http.cc
src/network_inspectors/appid/detector_plugins/detector_imap.cc
src/network_inspectors/appid/detector_plugins/detector_kerberos.cc
src/network_inspectors/appid/detector_plugins/detector_pattern.cc
src/network_inspectors/appid/detector_plugins/detector_pop3.cc
src/network_inspectors/appid/detector_plugins/detector_sip.cc
src/network_inspectors/appid/detector_plugins/detector_sip.h
src/network_inspectors/appid/detector_plugins/detector_smtp.cc
src/network_inspectors/appid/detector_plugins/http_url_patterns.cc
src/network_inspectors/appid/host_port_app_cache.cc
src/network_inspectors/appid/length_app_cache.cc
src/network_inspectors/appid/lua_detector_api.cc
src/network_inspectors/appid/lua_detector_api.h
src/network_inspectors/appid/lua_detector_flow_api.cc
src/network_inspectors/appid/lua_detector_module.cc
src/network_inspectors/appid/lua_detector_module.h
src/network_inspectors/appid/service_plugins/service_bootp.cc
src/network_inspectors/appid/service_plugins/service_bootp.h
src/network_inspectors/appid/service_plugins/service_detector.h
src/network_inspectors/appid/service_plugins/service_discovery.cc
src/network_inspectors/appid/service_plugins/service_discovery.h
src/network_inspectors/appid/service_plugins/service_ftp.cc
src/network_inspectors/appid/service_plugins/service_ftp.h
src/network_inspectors/appid/service_plugins/service_mdns.cc
src/network_inspectors/appid/service_plugins/service_mdns.h
src/network_inspectors/appid/service_plugins/service_netbios.cc
src/network_inspectors/appid/service_plugins/service_netbios.h
src/network_inspectors/appid/service_plugins/service_rexec.cc
src/network_inspectors/appid/service_plugins/service_rexec.h
src/network_inspectors/appid/service_plugins/service_rpc.cc
src/network_inspectors/appid/service_plugins/service_rpc.h
src/network_inspectors/appid/service_plugins/service_rshell.cc
src/network_inspectors/appid/service_plugins/service_rshell.h
src/network_inspectors/appid/service_plugins/service_snmp.cc
src/network_inspectors/appid/service_plugins/service_snmp.h
src/network_inspectors/appid/service_plugins/service_ssl.cc
src/network_inspectors/appid/service_plugins/service_tftp.cc
src/network_inspectors/appid/service_plugins/service_tftp.h
src/network_inspectors/appid/test/appid_detector_test.cc
src/network_inspectors/appid/test/service_state_test.cc

index 8b755c0dfa66a176d46a79e0ea74ff1decc847cd..66a7590c9f15d3186bbd14491d14c2d167d279be 100644 (file)
@@ -33,9 +33,9 @@
 
 using namespace snort;
 
-static THREAD_LOCAL AFActKey master_key;
-static THREAD_LOCAL XHash* AF_indicators = nullptr;     // list of "indicator apps"
-static THREAD_LOCAL XHash* AF_actives = nullptr;        // list of hosts to watch
+static AFActKey master_key;
+static XHash* AF_indicators = nullptr;     // list of "indicator apps"
+static XHash* AF_actives = nullptr;        // list of hosts to watch
 
 int init_appid_forecast()
 {
index d1effb2b7d952da58b2c776e905b2084938fe8e1..26db300493adc026eb669287ce7c55b1ceea0be9 100644 (file)
 #include <glob.h>
 #include <climits>
 
+#include "app_forecast.h"
 #include "app_info_table.h"
+#include "appid_discovery.h"
 #include "appid_session.h"
 #ifdef USE_RNA_CONFIG
 #include "appid_utils/network_set.h"
 #include "appid_utils/ip_funcs.h"
 #endif
+#include "detector_plugins/detector_pattern.h"
+#include "host_port_app_cache.h"
 #include "main/snort_config.h"
 #include "log/messages.h"
+#include "lua_detector_module.h"
 #include "utils/util.h"
+#include "service_plugins/service_ssl.h"
+#include "detector_plugins/detector_dns.h"
 #include "target_based/snort_protocols.h"
 #ifdef ENABLE_APPID_THIRD_PARTY
 #include "tp_lib_handler.h"
@@ -91,8 +98,12 @@ AppIdModuleConfig::~AppIdModuleConfig()
     snort_free((void*)app_detector_dir);
 }
 
+//FIXIT-M: RELOAD - move initialization back to AppIdConfig
+//class constructor
+AppInfoManager& AppIdConfig::app_info_mgr = AppInfoManager::get_instance();
+
 AppIdConfig::AppIdConfig(AppIdModuleConfig* config)
-    : mod_config(config), app_info_mgr(AppInfoManager::get_instance())
+    : mod_config(config)
 {
 #ifdef USE_RNA_CONFIG
     for ( unsigned i = 0; i < MAX_ZONES; i++ )
@@ -122,6 +133,13 @@ AppIdConfig::~AppIdConfig()
     cleanup();
 }
 
+//FIXIT-M: RELOAD - Move app info tabe cleanup back 
+//to AppId config destructor - cleanup()
+void AppIdConfig::pterm()
+{
+    AppIdConfig::app_info_mgr.cleanup_appid_info_table();
+}
+
 void AppIdConfig::read_port_detectors(const char* files)
 {
     int rval;
@@ -238,9 +256,9 @@ void AppIdConfig::read_port_detectors(const char* files)
                     udp_port_only[tmp_port->port] = appId;
 
                 snort_free(tmp_port);
-                app_info_mgr.set_app_info_active(appId);
+                AppIdConfig::app_info_mgr.set_app_info_active(appId);
             }
-            app_info_mgr.set_app_info_active(appId);
+            AppIdConfig::app_info_mgr.set_app_info_active(appId);
         }
         else
             ErrorMessage("Missing parameter(s) in port service '%s'\n",globs.gl_pathv[n]);
@@ -732,14 +750,33 @@ void AppIdConfig::set_safe_search_enforcement(bool enabled)
     mod_config->safe_search_enabled = enabled;
 }
 
-bool AppIdConfig::init_appid(SnortConfig* sc)
+bool AppIdConfig::init_appid(SnortConfig* sc, AppIdInspector *ins)
 {
-    app_info_mgr.init_appid_info_table(mod_config, sc);
+    //FIXIT -M: RELOAD - Get rid of "once" flag
+    //Handle the if condition in AppIdConfig::init_appid
+    static bool once = false;
+    if (!once)
+    {      
+        AppIdConfig::app_info_mgr.init_appid_info_table(mod_config, sc);
+        HostPortCache::initialize();
+        init_appid_forecast();
+        HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance();
+        AppIdDiscovery::initialize_plugins(ins);
+        init_length_app_cache();
+        LuaDetectorManager::initialize(*this, 1);
+        PatternServiceDetector::finalize_service_port_patterns();
+        PatternClientDetector::finalize_client_port_patterns();
+        AppIdDiscovery::finalize_plugins();
+        http_matchers->finalize();
+           ssl_detector_process_patterns();
+        dns_host_detector_process_patterns();
+        read_port_detectors(ODP_PORT_DETECTORS);
+        read_port_detectors(CUSTOM_PORT_DETECTORS);
+        once = true;
+    }
 #ifdef USE_RNA_CONFIG
     load_analysis_config(mod_config->conf_file, 0, mod_config->instance_id);
 #endif
-    read_port_detectors(ODP_PORT_DETECTORS);
-    read_port_detectors(CUSTOM_PORT_DETECTORS);
 
 #ifdef ENABLE_APPID_THIRD_PARTY
     TPLibHandler::pinit(mod_config);
@@ -762,8 +799,6 @@ static void free_port_exclusion_list(AppIdPortExclusions& pe_list)
 
 void AppIdConfig::cleanup()
 {
-    app_info_mgr.cleanup_appid_info_table();
-
 #ifdef USE_RNA_CONFIG
     NetworkSet* net_list;          ///< list of network sets
     while ((net_list = net_list_list))
index 6f500669af508c784069ddec0007b1fb211e3a71..e5fa936ffe286ed7a73826798c8276794678c421 100644 (file)
@@ -38,6 +38,7 @@
 #define MAX_ZONES               1024
 
 struct NetworkSet;
+class AppIdInspector;
 class AppInfoManager;
 
 extern unsigned appIdPolicyId;
@@ -106,7 +107,8 @@ public:
     AppIdConfig(AppIdModuleConfig*);
     ~AppIdConfig();
 
-    bool init_appid(snort::SnortConfig*);
+    bool init_appid(snort::SnortConfig*, AppIdInspector*);
+    static void pterm();
     void cleanup();
     void show();
     void set_safe_search_enforcement(bool enabled);
@@ -140,8 +142,9 @@ private:
     void process_config_directive(char* toklist[], int /* reload */);
     int load_analysis_config(const char* config_file, int reload, int instance_id);
     void display_port_config();
-
-    AppInfoManager& app_info_mgr;
+    //FIXIT-M: RELOAD - Remove static, once app_info_mgr cleanup is
+    //removed from AppIdConfig::pterm
+    static AppInfoManager& app_info_mgr;
 };
 
 #endif
index fa7176d527e58ad8178bd931aa94954df4249beb..bd8897439ca9003b0683a4b8585e70c50433d6bd 100644 (file)
@@ -111,6 +111,7 @@ public:
 
     virtual int initialize();
     virtual void do_custom_init() = 0;
+    virtual void release_thread_resources() = 0;
     virtual int validate(AppIdDiscoveryArgs&) = 0;
     virtual void register_appid(AppId, unsigned extractsInfo) = 0;
 
index 6c631ea86aad8cd67795cb575f8433b5e2f49ffc..c385be1921daa125d62fc50dae44238077c70f5f 100644 (file)
@@ -89,10 +89,10 @@ void AppIdDiscovery::finalize_plugins()
     ClientDiscovery::get_instance().finalize_client_plugins();
 }
 
-void AppIdDiscovery::release_plugins()
+void AppIdDiscovery::tterm()
 {
-    delete &ServiceDiscovery::get_instance();
-    delete &ClientDiscovery::get_instance();
+    ClientDiscovery::get_instance().release_thread_resources();
+    ServiceDiscovery::get_instance().release_thread_resources();
 }
 
 void AppIdDiscovery::register_detector(const std::string& name, AppIdDetector* cd,  IpProtocol proto)
index b986a82a237a532400dacf11414766013617964c..ca5b142c4bfc3649f2a908c9313b8fa7d1c06cbb 100644 (file)
@@ -96,6 +96,7 @@ public:
     static void initialize_plugins(AppIdInspector* ins);
     static void finalize_plugins();
     static void release_plugins();
+    static void tterm();
 
     virtual void initialize() = 0;
     virtual void register_detector(const std::string&, AppIdDetector*,  IpProtocol);
index 4e6ba55e72876ec3e50355f4b9d1086a43ae33b8..8a5fb0104bfd768c8ff7df18f659a38b3d1f6fd0 100644 (file)
@@ -114,7 +114,7 @@ bool AppIdInspector::configure(SnortConfig* sc)
     my_seh = SipEventHandler::create();
     my_seh->subscribe();
 
-    active_config->init_appid(sc);
+    active_config->init_appid(sc, this);
 
 #ifdef ENABLE_APPID_THIRD_PARTY
     if (!TPLibHandler::have_tp())
@@ -155,19 +155,8 @@ void AppIdInspector::tinit()
     appid_mute = PacketTracer::get_mute();
 
     AppIdStatistics::initialize_manager(*config);
-    HostPortCache::initialize();
-    AppIdServiceState::initialize();
-    init_appid_forecast();
-    HttpPatternMatchers* http_matchers = HttpPatternMatchers::get_instance();
-    AppIdDiscovery::initialize_plugins(this);
-    init_length_app_cache();
     LuaDetectorManager::initialize(*active_config);
-    PatternServiceDetector::finalize_service_port_patterns();
-    PatternClientDetector::finalize_client_port_patterns();
-    AppIdDiscovery::finalize_plugins();
-    http_matchers->finalize();
-    ssl_detector_process_patterns();
-    dns_host_detector_process_patterns();
+    AppIdServiceState::initialize();
     appidDebug = new AppIdDebug();
     if (active_config->mod_config and active_config->mod_config->log_all_sessions)
         appidDebug->set_enabled(true);
@@ -179,16 +168,9 @@ void AppIdInspector::tinit()
 void AppIdInspector::tterm()
 {
     AppIdStatistics::cleanup();
-    HostPortCache::terminate();
-    clean_appid_forecast();
-    service_dns_host_clean();
-    service_ssl_clean();
-    free_length_app_cache();
-
-    AppIdServiceState::clean();
     LuaDetectorManager::terminate();
-    AppIdDiscovery::release_plugins();
-    delete HttpPatternMatchers::get_instance();
+    AppIdDiscovery::tterm();
+    AppIdServiceState::clean();
     delete appidDebug;
     appidDebug = nullptr;
 #ifdef ENABLE_APPID_THIRD_PARTY
@@ -236,6 +218,16 @@ static void appid_inspector_pinit()
 
 static void appid_inspector_pterm()
 {
+//FIXIT-M: RELOAD - if app_info_table is associated with an object
+    HostPortCache::terminate();
+    clean_appid_forecast();
+    free_length_app_cache();
+    LuaDetectorManager::terminate();
+    delete HttpPatternMatchers::get_instance();
+    service_dns_host_clean();
+    service_ssl_clean();
+    AppIdConfig::pterm();
+//end of 'FIXIT-M: RELOAD' comment above
     openssl_cleanup();
 #ifdef ENABLE_APPID_THIRD_PARTY
     TPLibHandler::pfini();
index 007bcd797702f4474ec4aaa51a048b8abc98c334..b80844b00a7f35017e5489a14328034e7efb0544 100644 (file)
@@ -33,6 +33,7 @@ public:
     ClientDetector();
 
     void do_custom_init() override { }
+    void release_thread_resources() override { }
     void register_appid(AppId, unsigned extractsInfo) override;
 };
 #endif
index f5d3c9a17eb79c97848ca7661b2ac4c553df284b..2bfde41aee3589fbd3cc501b19d3bf8f70fd255e 100644 (file)
@@ -64,6 +64,11 @@ ClientDiscovery::ClientDiscovery(AppIdInspector& ins)
 }
 
 ClientDiscovery::~ClientDiscovery()
+{
+    release_thread_resources();
+}
+
+void ClientDiscovery::release_thread_resources()
 {
     ClientAppMatch* match;
     while ((match = match_free_list) != nullptr)
@@ -73,9 +78,10 @@ ClientDiscovery::~ClientDiscovery()
     }
 }
 
+//FIXIT-M: Don't use pointer and pass discovery_manager directly
 ClientDiscovery& ClientDiscovery::get_instance(AppIdInspector* ins)
 {
-    static THREAD_LOCAL ClientDiscovery* discovery_manager = nullptr;
+    static ClientDiscovery* discovery_manager = nullptr;
     if (!discovery_manager)
     {
         assert(ins);
index 344a610890f44904b964088af170510c2ae09c78..3c565714ac23cab410f6475810bf32250f4f3e2d 100644 (file)
@@ -48,6 +48,7 @@ public:
     static ClientDiscovery& get_instance(AppIdInspector* ins = nullptr);
 
     void finalize_client_plugins();
+    void release_thread_resources();
     bool do_client_discovery(AppIdSession&, snort::Packet*, AppidSessionDirection direction);
 
 private:
index ce618dc43f50021699d7ad197a6c779a678f495b..1dbde4e014d4c8649483605b793cd28f9a7c6534 100644 (file)
@@ -161,7 +161,7 @@ struct ServiceDnsConfig
     DetectorDNSHostPattern* DetectorDNSHostPatternList;
     snort::SearchTool* dns_host_host_matcher;
 };
-static THREAD_LOCAL ServiceDnsConfig serviceDnsConfig;      // DNS service configuration
+static ServiceDnsConfig serviceDnsConfig;      // DNS service configuration
 
 static int dns_host_pattern_match(void* id, void*, int, void* data, void*)
 {
index d3c71c523c142b2acb4986ca39cf104e2a9d172e..659ce24a6dface6d6d794d4262114236db1fd386 100644 (file)
@@ -37,7 +37,7 @@ static const char HTTP2_PREFACE[] = "PRI * HTTP/2.0\r\n\r\nSM\r\n\r\n";
 #define HTTP2_PREFACE_LEN (sizeof(HTTP2_PREFACE) - 1)
 #define HTTP2_PREFACE_MAXPOS (sizeof(HTTP2_PREFACE)-2)
 
-static THREAD_LOCAL HttpServiceDetector* http_service_detector;
+static HttpServiceDetector* http_service_detector;
 
 HttpClientDetector::HttpClientDetector(ClientDiscovery* cdm)
 {
index 82f44294f3985c8a587b401f0d56f621694c673e..e71f603517a251edaaea7faf09927528d24e76d9 100644 (file)
@@ -153,7 +153,7 @@ struct ImapDetectorData
     int need_continue;
 };
 
-static THREAD_LOCAL ImapClientDetector* imap_client_detector = nullptr;
+static ImapClientDetector* imap_client_detector;
 
 static int isImapTagChar(uint8_t tag)
 {
index 2172ae92adaff5f117d219b57feb3b664794ed9d..bc94cff99d5514e83e0500d4c2ab28875ccc06d6 100644 (file)
@@ -111,8 +111,8 @@ struct KerberosDetectorData
 #define TGS_REP_MSG_TYPE    0x0d
 #define ERROR_MSG_TYPE      0x1e
 
-static THREAD_LOCAL KerberosClientDetector* krb_client_detector = nullptr;
-static THREAD_LOCAL KerberosServiceDetector* krb_service_detector = nullptr;
+static KerberosClientDetector* krb_client_detector;
+static KerberosServiceDetector* krb_service_detector;
 
 static int krb_walk_server_packet(KRBState* krbs, const uint8_t* s, const uint8_t* end,
     AppIdSession& asd, snort::Packet* pkt, const AppidSessionDirection dir, const char* reqCname)
index b70f872e0cfbe028639532c5d7e5936b847f4989..da6c8c0871c909d19ec4dda94a808cfd105787c3 100644 (file)
@@ -32,8 +32,8 @@
 
 using namespace snort;
 
-static THREAD_LOCAL PatternServiceDetector* service_pattern_detector;
-static THREAD_LOCAL PatternClientDetector* client_pattern_detector;
+static PatternServiceDetector* service_pattern_detector;
+static PatternClientDetector* client_pattern_detector;
 
 static void dumpPatterns(const char* name, PatternService* pList)
 {
index 2e1b0f0c68e7e951de79da0ebc8a1f5ac464fd4a..1448f20a3526aa99294ecc12193aa3ed914fb091 100644 (file)
@@ -125,8 +125,8 @@ struct POP3DetectorData
     int need_continue;
 };
 
-static THREAD_LOCAL Pop3ClientDetector* pop3_client_detector = nullptr;
-static THREAD_LOCAL Pop3ServiceDetector* pop3_service_detector = nullptr;
+static Pop3ClientDetector* pop3_client_detector;
+static Pop3ServiceDetector* pop3_service_detector;
 
 static AppIdFlowContentPattern pop3_client_patterns[] =
 {
index 8c45237859e007aec025d517890d5886a799b78d..916b124cd2388f81230ce64b53efd3ededf71eb9 100644 (file)
@@ -85,7 +85,7 @@ struct DetectorSipConfig
     DetectorAppSipPattern* sip_server_list;
 };
 
-static THREAD_LOCAL DetectorSipConfig detector_sip_config;
+static DetectorSipConfig detector_sip_config;
 
 static void clean_sip_ua()
 {
@@ -452,8 +452,8 @@ int SipServiceDetector::validate(AppIdDiscoveryArgs& args)
     return APPID_INPROCESS;
 }
 
-THREAD_LOCAL SipUdpClientDetector* SipEventHandler::client = nullptr;
-THREAD_LOCAL SipServiceDetector* SipEventHandler::service = nullptr;
+SipUdpClientDetector* SipEventHandler::client = nullptr;
+SipServiceDetector* SipEventHandler::service = nullptr;
 
 void SipEventHandler::handle(DataEvent& event, Flow* flow)
 {
index 37b874d993fa9e2de7ca1b8c576ab3ca13629fc9..4268b5aefd18f30ffe10e0fcabf160c32538c9f0 100644 (file)
@@ -109,8 +109,8 @@ private:
     void client_handler(SipEvent&, AppIdSession&);
     void service_handler(SipEvent&, AppIdSession&);
 
-    static THREAD_LOCAL SipUdpClientDetector* client;
-    static THREAD_LOCAL SipServiceDetector* service;
+    static SipUdpClientDetector* client;
+    static SipServiceDetector* service;
 };
 #endif
 
index 05e149e709266c829124939954236cd6623fc5ec..2294c4181008bf7025c70b16d28a3d573de2f111 100644 (file)
@@ -123,7 +123,7 @@ static const uint8_t APP_SMTP_THUNDERBIRD[] =  "Thunderbird ";
 static const uint8_t APP_SMTP_MOZILLA[] = "Mozilla";
 static const uint8_t APP_SMTP_THUNDERBIRD_SHORT[] = "Thunderbird/";
 
-static THREAD_LOCAL SmtpClientDetector* smtp_client_detector = nullptr;
+static SmtpClientDetector* smtp_client_detector;
 
 SmtpClientDetector::SmtpClientDetector(ClientDiscovery* cdm)
 {
index bd8e9e9c29136697fd212c26cfc85d771bd8eb93..43a1f6b953340edf1965fbbed9eab619d929097f 100644 (file)
@@ -315,7 +315,7 @@ static int match_query_elements(tMlpPattern* packetData, tMlpPattern* userPatter
 
 HttpPatternMatchers* HttpPatternMatchers::get_instance()
 {
-    static THREAD_LOCAL HttpPatternMatchers* http_matchers = nullptr;
+    static HttpPatternMatchers* http_matchers;
     if (!http_matchers)
         http_matchers = new HttpPatternMatchers;
     return http_matchers;
index 1ac61974449698d0ff602e435755f870542e6a8c..76fcaed221e80f10757b92ec88eb551a5eaa166e 100644 (file)
@@ -71,7 +71,8 @@ struct HostPortKey
 };
 PADDING_GUARD_END
 
-static THREAD_LOCAL std::map<HostPortKey, HostPortVal>* host_port_cache = nullptr;
+//FIXIT-H: Use unordered map
+static std::map<HostPortKey, HostPortVal>* host_port_cache = nullptr;
 
 void HostPortCache::initialize()
 {
index 16a3965a55eba9b98e18057cc724e3459678077f..4ba2162ef1d8ba61f5807887bcee6049c033a2d5 100644 (file)
@@ -34,7 +34,7 @@ using namespace snort;
 
 #define HASH_NUM_ROWS (1024)
 
-static THREAD_LOCAL XHash* lengthCache = nullptr;
+static XHash* lengthCache = nullptr;
 
 void init_length_app_cache()
 {
index 5cb8475be73d48a257cd817ae32f199284155e46..1c0b01dc8e20064c8c9b92b8b77c2c8fadc458ef 100644 (file)
@@ -67,7 +67,7 @@ ProfileStats luaDetectorsPerfStats;
 ProfileStats luaCiscoPerfStats;
 ProfileStats luaCustomPerfStats;
 
-static THREAD_LOCAL XHash* CHP_glossary = nullptr;      // keep track of http multipatterns here
+static XHash* CHP_glossary = nullptr;      // keep track of http multipatterns here
 
 static int free_chp_data(void* /* key */, void* data)
 {
@@ -117,6 +117,37 @@ static inline int convert_string_to_address(const char* string, SfIp* address)
     return 1;    // success
 }
 
+static inline bool lua_params_validator(LuaDetectorParameters& ldp, bool packet_context)
+{
+    if ( packet_context )
+    {
+        assert(ldp.asd);
+        assert(ldp.pkt);
+    }
+    else
+    {
+        assert(!ldp.pkt);
+    }
+
+#ifdef NDEBUG
+    UNUSED(ldp);
+#endif
+
+    return true;
+}
+
+int init(lua_State* L, int result)
+{
+    lua_getglobal(L,"is_control");
+    auto res = lua_toboolean(L, -1);
+    lua_pop(L, 1);
+
+    if (result)
+        lua_pushnumber(L, 0);
+
+    return res;
+}
+
 // Creates a new detector instance. Creates a new detector instance and leaves the instance
 // on stack. This is the first call by a lua detector to create an instance. Later calls
 // provide the detector instance.
@@ -128,7 +159,10 @@ static inline int convert_string_to_address(const char* string, SfIp* address)
 //  return - a detector instance or none
 static int service_init(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
 
     // auto pServiceName = luaL_checkstring(L, 2);
     auto pValidator = luaL_checkstring(L, 3);
@@ -148,7 +182,7 @@ static int service_init(lua_State* L)
     }
 
     ErrorMessage("%s: attempted setting validator/fini to non-function\n",
-        ud->get_name().c_str());
+        ud->sd->get_name().c_str());
     lua_pop(L, 1);
     return 0;
 }
@@ -166,9 +200,12 @@ static int service_init(lua_State* L)
 //  return - status/stack - 0 if successful, -1 otherwise.
 static int service_register_pattern(lua_State* L)
 {
-    int index = 1;
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L, 1)) return 1;
 
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, index);
+    int index = 1;
 
     // FIXIT-M  none of these params check for signedness casting issues
     // FIXIT-M May want to create a lua_toipprotocol() so we can handle
@@ -185,10 +222,10 @@ static int service_register_pattern(lua_State* L)
     unsigned int position = lua_tonumber(L, ++index);
 
     if ( protocol == IpProtocol::TCP)
-        ServiceDiscovery::get_instance().register_tcp_pattern(ud, (const uint8_t*)pattern,
+        ServiceDiscovery::get_instance().register_tcp_pattern(ud->sd, (const uint8_t*)pattern,
             size, position, 0);
     else
-        ServiceDiscovery::get_instance().register_udp_pattern(ud, (const uint8_t*)pattern,
+        ServiceDiscovery::get_instance().register_udp_pattern(ud->sd, (const uint8_t*)pattern,
             size, position, 0);
 
     lua_pushnumber(L, 0);
@@ -197,15 +234,20 @@ static int service_register_pattern(lua_State* L)
 
 static int common_register_application_id(lua_State* L)
 {
-    int index = 1;
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L, 1)) return 1;
+
+    auto ad = ud->get_detector();
 
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    int index = 1;
     AppId appId = lua_tonumber(L, ++index);
 
-    if ( ud->is_client() )
-        ud->register_appid(appId, APPINFO_FLAG_CLIENT_ADDITIONAL);
+    if ( ad->is_client() )
+        ad->register_appid(appId, APPINFO_FLAG_CLIENT_ADDITIONAL);
     else
-        ud->register_appid(appId, APPINFO_FLAG_SERVICE_ADDITIONAL);
+        ad->register_appid(appId, APPINFO_FLAG_SERVICE_ADDITIONAL);
 
     AppInfoManager::get_instance().set_app_info_active(appId);
 
@@ -213,6 +255,8 @@ static int common_register_application_id(lua_State* L)
     return 1;
 }
 
+//  Callback could be used either at init
+//  or during packet processing
 static int detector_htons(lua_State* L)
 {
     unsigned short aShort = lua_tonumber(L, 2);
@@ -221,6 +265,8 @@ static int detector_htons(lua_State* L)
     return 1;
 }
 
+//  Callback could be used either at init
+//  or during packet processing
 static int detector_htonl(lua_State* L)
 {
     unsigned int anInt = lua_tonumber(L, 2);
@@ -235,9 +281,11 @@ static int detector_htonl(lua_State* L)
 // lua params:
 //  #1 - level - level of message. See DetectorCommon for enumeration.
 //  #2 - message - message to be logged.
+//  Callback could be used either at init
+//  or during packet processing
 static int detector_log_message(lua_State* L)
 {
-    const auto& name = (*UserData<AppIdDetector>::check(L, DETECTOR, 1))->get_name();
+    const auto& name = (*UserData<LuaObject>::check(L, DETECTOR, 1))->get_detector()->get_name();
 
     unsigned int level = lua_tonumber(L, 2);
     const char* message = lua_tostring(L, 3);
@@ -277,8 +325,10 @@ static int detector_log_message(lua_State* L)
 //  4 - flags/stack - any flags
 static int service_analyze_payload(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     lsd->ldp.asd->payload.set_id(lua_tonumber(L, 2));
     return 0;
 }
@@ -298,7 +348,8 @@ static int service_analyze_payload(lua_State* L)
 // @return service_id/stack - service_id if successful, -1 otherwise.
 static int service_get_service_id(lua_State* L)
 {
-    auto ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(false);
 
     lua_pushnumber(L, lsd->service_id);
@@ -312,7 +363,10 @@ static int service_get_service_id(lua_State* L)
 // @return status/stack - 0 if successful, -1 otherwise.
 static int service_add_ports(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L, 1)) return 1;
 
     ServiceDetectorPort pp;
     pp.proto = (IpProtocol)lua_tonumber(L, 2);
@@ -325,7 +379,7 @@ static int service_add_ports(lua_State* L)
         return 1;
     }
 
-    if ( ud->get_handler().add_service_port(ud, pp) )
+    if ( ud->sd->get_handler().add_service_port(ud->sd, pp) )
     {
         lua_pushnumber(L, -1);
         return 1;
@@ -340,7 +394,7 @@ static int service_add_ports(lua_State* L)
 // @return status/stack - 0 if successful, -1 otherwise.
 static int service_remove_ports(lua_State* L)
 {
-    //auto& ud = *UserData<LuaDetectionState>::check(L, DETECTOR, 1);
+    if (!init(L, 1)) return 1;
 
     // FIXIT-L - do we need to support removing ports registered by specific detector...
     lua_pushnumber(L, 0);
@@ -354,12 +408,15 @@ static int service_remove_ports(lua_State* L)
 // @return status/stack - 0 if successful, -1 otherwise.
 static int service_set_service_name(lua_State* L)
 {
+    if (!init(L, 1)) return 1;
+
     lua_pushnumber(L, 0);
     return 1;
 }
 
 /**Get service name. Lua detectors call this function to get service name. There is
  * rarely a need to change service name.
+ * Callback could be used either at init or during packet processing
  *
  * @param Lua_State* - Lua state variable.
  * @param detector/stack - detector object
@@ -368,14 +425,14 @@ static int service_set_service_name(lua_State* L)
  */
 static int service_get_service_name(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
-
-    lua_pushstring(L, ud->get_name().c_str());
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    lua_pushstring(L, ud->get_detector()->get_name().c_str());
     return 1;
 }
 
 /**Is this a customer defined detector. Lua detectors can call this function to verify if the detector
  * was created by Sourcefire or not.
+ * Callback could be used either at init or during packet processing
  *
  * @param Lua_State* - Lua state variable.
  * @param detector/stack - detector object
@@ -384,8 +441,8 @@ static int service_get_service_name(lua_State* L)
  */
 static int service_is_custom_detector(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
-    lua_pushnumber(L, ud->is_custom_detector());
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    lua_pushnumber(L, ud->get_detector()->is_custom_detector());
     return 1;
 }
 
@@ -400,7 +457,10 @@ static int service_is_custom_detector(lua_State* L)
  */
 static int service_set_validator(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L, 1)) return 1;
 
     const char* pValidator = lua_tostring(L, 2);
     lua_getfield(L, LUA_REGISTRYINDEX, ud->lsd.package_info.name.c_str());
@@ -408,7 +468,7 @@ static int service_set_validator(lua_State* L)
     if (!lua_isfunction(L, -1))
     {
         ErrorMessage("%s: attempted setting validator to non-function\n",
-            ud->get_name().c_str());
+            ud->sd->get_name().c_str());
 
         lua_pop(L, 1);
         lua_pushnumber(L, -1);
@@ -431,10 +491,12 @@ static int service_set_validator(lua_State* L)
  */
 static int service_add_data_id(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     uint16_t sport = lua_tonumber(L, 2);
-    lsd->ldp.asd->add_flow_data_id(sport, ud);
+    lsd->ldp.asd->add_flow_data_id(sport, ud->sd);
     lua_pushnumber(L, 0);
     return 1;
 }
@@ -451,15 +513,17 @@ static int service_add_data_id(lua_State* L)
  */
 static int service_add_service(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     AppId service_id = lua_tonumber(L, 2);
     const char* vendor = luaL_optstring(L, 3, nullptr);
     const char* version = luaL_optstring(L, 4, nullptr);
 
     /*Phase2 - discuss AppIdServiceSubtype will be maintained on lua side therefore the last
       parameter on the following call is nullptr. Subtype is not displayed on DC at present. */
-    unsigned int retValue = ud->add_service(*lsd->ldp.asd, lsd->ldp.pkt, lsd->ldp.dir,
+    unsigned int retValue = ud->sd->add_service(*lsd->ldp.asd, lsd->ldp.pkt, lsd->ldp.dir,
         AppInfoManager::get_instance().get_appid_by_service_id(service_id),
         vendor, version, nullptr);
 
@@ -476,9 +540,11 @@ static int service_add_service(lua_State* L)
  */
 static int service_fail_service(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
-    ServiceDiscovery& sdm = static_cast<ServiceDiscovery&>(ud->get_handler());
+
+    ServiceDiscovery& sdm = static_cast<ServiceDiscovery&>(ud->sd->get_handler());
     unsigned int retValue = sdm.fail_service(*lsd->ldp.asd, lsd->ldp.pkt,
         lsd->ldp.dir, nullptr);
     lua_pushnumber(L, retValue);
@@ -494,10 +560,11 @@ static int service_fail_service(lua_State* L)
  */
 static int service_in_process_service(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
-    unsigned int retValue = ud->service_inprocess(*lsd->ldp.asd,
+    unsigned int retValue = ud->sd->service_inprocess(*lsd->ldp.asd,
         lsd->ldp.pkt, lsd->ldp.dir);
     lua_pushnumber(L, retValue);
     return 1;
@@ -512,10 +579,11 @@ static int service_in_process_service(lua_State* L)
  */
 static int service_set_incompatible_data(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
-    unsigned int retValue = ud->incompatible_data(*lsd->ldp.asd,
+    unsigned int retValue = ud->sd->incompatible_data(*lsd->ldp.asd,
         lsd->ldp.pkt, lsd->ldp.dir);
     lua_pushnumber(L, retValue);
     return 1;
@@ -532,7 +600,8 @@ static int service_set_incompatible_data(lua_State* L)
  */
 static int detector_get_packet_size(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     lua_pushnumber(L, lsd->ldp.size);
@@ -549,7 +618,8 @@ static int detector_get_packet_size(lua_State* L)
  */
 static int detector_get_packet_direction(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     lua_pushnumber(L, lsd->ldp.dir);
@@ -567,13 +637,14 @@ static int detector_get_packet_direction(lua_State* L)
  */
 static int detector_get_pcre_groups(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
+    LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     int ovector[OVECCOUNT];
     const char* error;
     int erroffset;
 
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
-    LuaStateDescriptor* lsd = ud->validate_lua_state(true);
-
     const char* pattern = lua_tostring(L, 2);
     unsigned int offset = lua_tonumber(L, 3);     /*offset can be zero, no check necessary. */
 
@@ -641,7 +712,8 @@ static int detector_get_pcre_groups(lua_State* L)
  */
 static int detector_memcmp(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     const char* pattern = lua_tostring(L, 2);
@@ -661,7 +733,8 @@ static int detector_memcmp(lua_State* L)
  */
 static int detector_get_protocol_type(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     if ( !lsd->ldp.pkt->has_ip() )
@@ -687,7 +760,8 @@ static int detector_get_protocol_type(lua_State* L)
  */
 static int detector_get_packet_src_addr(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     const SfIp* ipAddr = lsd->ldp.pkt->ptrs.ip_api.get_src();
@@ -705,7 +779,8 @@ static int detector_get_packet_src_addr(lua_State* L)
  */
 static int detector_get_packet_dst_addr(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     const SfIp* ipAddr = lsd->ldp.pkt->ptrs.ip_api.get_dst();
@@ -723,7 +798,8 @@ static int detector_get_packet_dst_addr(lua_State* L)
  */
 static int detector_get_packet_src_port(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     unsigned int port = lsd->ldp.pkt->ptrs.sp;
@@ -741,7 +817,8 @@ static int detector_get_packet_src_port(lua_State* L)
  */
 static int detector_get_packet_dst_port(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     unsigned int port = lsd->ldp.pkt->ptrs.dp;
@@ -752,12 +829,13 @@ static int detector_get_packet_dst_port(lua_State* L)
 
 /**Get packet count. This is used mostly for printing packet sequence
  * number when RNA is being tested with a pcap file.
+ * Callback could be used either at init or during packet processing
  *
  * @param Lua_State* - Lua state variable.
  * @param detector/stack - detector object
  * @return int - Number of elements on stack, which is 1 if successful, 0 otherwise.
  * @return packetCount/stack - Total packet processed by RNA.
- */
+**/
 static int detector_get_packet_count(lua_State* L)
 {
     lua_checkstack (L, 1);
@@ -767,9 +845,13 @@ static int detector_get_packet_count(lua_State* L)
 
 static int client_register_pattern(lua_State* L)
 {
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L, 1)) return 1;
+
     int index = 1;
 
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, index);
     IpProtocol protocol = (IpProtocol)lua_tonumber(L, ++index);
     const char* pattern = lua_tostring(L, ++index);
     size_t size = lua_tonumber(L, ++index);
@@ -782,10 +864,10 @@ static int client_register_pattern(lua_State* L)
     /*mpse library does not hold reference to pattern therefore we don't need to allocate it. */
 
     if ( protocol == IpProtocol::TCP)
-        ClientDiscovery::get_instance().register_tcp_pattern(ud, (const uint8_t*)pattern,
+        ClientDiscovery::get_instance().register_tcp_pattern(ud->cd, (const uint8_t*)pattern,
             size, position, 0);
     else
-        ClientDiscovery::get_instance().register_udp_pattern(ud, (const uint8_t*)pattern,
+        ClientDiscovery::get_instance().register_udp_pattern(ud->cd, (const uint8_t*)pattern,
             size, position, 0);
 
     lua_pushnumber(L, 0);
@@ -795,6 +877,7 @@ static int client_register_pattern(lua_State* L)
 /**Creates a new detector instance. Creates a new detector instance and leaves the instance
  * on stack. This is the first call by a lua detector to create an instance. Later calls
  * provide the detector instance.
+ * Called at detector initialization
  *
  * @param Lua_State* - Lua state variable.
  * @param serviceName/stack - name of service
@@ -805,13 +888,13 @@ static int client_register_pattern(lua_State* L)
  */
 static int client_init(lua_State*)
 {
-    /*nothing to do */
     return 0;
 }
 
 static int service_add_client(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     AppId client_id = lua_tonumber(L, 2);
@@ -824,20 +907,21 @@ static int service_add_client(lua_State* L)
         return 1;
     }
 
-    ud->add_app(*lsd->ldp.asd, service_id, client_id, version);
+    ud->cd->add_app(*lsd->ldp.asd, service_id, client_id, version);
     lua_pushnumber(L, 0);
     return 1;
 }
 
 static int client_add_application(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     unsigned int service_id = lua_tonumber(L, 2);
     unsigned int productId = lua_tonumber(L, 4);
     const char* version = lua_tostring(L, 5);
-    ud->add_app(*lsd->ldp.asd,
+    ud->cd->add_app(*lsd->ldp.asd,
         AppInfoManager::get_instance().get_appid_by_service_id(service_id),
         AppInfoManager::get_instance().get_appid_by_client_id(productId), version);
 
@@ -847,21 +931,25 @@ static int client_add_application(lua_State* L)
 
 static int client_add_info(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     const char* info = lua_tostring(L, 2);
-    ud->add_info(*lsd->ldp.asd, info);
+    ud->cd->add_info(*lsd->ldp.asd, info);
     lua_pushnumber(L, 0);
     return 1;
 }
 
 static int client_add_user(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     const char* userName = lua_tostring(L, 2);
     unsigned int service_id = lua_tonumber(L, 3);
-    ud->add_user(*lsd->ldp.asd, userName,
+    ud->cd->add_user(*lsd->ldp.asd, userName,
         AppInfoManager::get_instance().get_appid_by_service_id(service_id), true);
     lua_pushnumber(L, 0);
     return 1;
@@ -869,11 +957,12 @@ static int client_add_user(lua_State* L)
 
 static int client_add_payload(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
-    unsigned int payloadId = lua_tonumber(L, 2);
 
-    ud->add_payload(*lsd->ldp.asd,
+    unsigned int payloadId = lua_tonumber(L, 2);
+    ud->cd->add_payload(*lsd->ldp.asd,
         AppInfoManager::get_instance().get_appid_by_payload_id(payloadId));
 
     lua_pushnumber(L, 0);
@@ -892,7 +981,8 @@ static int client_add_payload(lua_State* L)
  */
 static int detector_get_flow(lua_State* L)
 {
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     auto df = new DetectorFlow();
@@ -907,10 +997,12 @@ static int detector_get_flow(lua_State* L)
 
 static int detector_add_http_pattern(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     enum httpPatternType pat_type = (enum httpPatternType)lua_tointeger(L, ++index);
     if (pat_type < HTTP_PAYLOAD || pat_type > HTTP_URL)
@@ -947,10 +1039,12 @@ static int detector_add_http_pattern(lua_State* L)
 // for Lua this looks something like: addSSLCertPattern(<appId>, '<pattern string>')
 static int detector_add_ssl_cert_pattern(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint8_t type = lua_tointeger(L, ++index);
     AppId app_id  = (AppId)lua_tointeger(L, ++index);
@@ -977,10 +1071,12 @@ static int detector_add_ssl_cert_pattern(lua_State* L)
 // for Lua this looks something like: addDNSHostPattern(<appId>, '<pattern string>')
 static int detector_add_dns_host_pattern(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint8_t type = lua_tointeger(L, ++index);
     AppId app_id = (AppId)lua_tointeger(L, ++index);
@@ -1005,10 +1101,12 @@ static int detector_add_dns_host_pattern(lua_State* L)
 
 static int detector_add_ssl_cname_pattern(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint8_t type = lua_tointeger(L, ++index);
     AppId app_id  = (AppId)lua_tointeger(L, ++index);
@@ -1035,11 +1133,13 @@ static int detector_add_ssl_cname_pattern(lua_State* L)
 
 static int detector_add_host_port_application(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
     SfIp ip_addr;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     uint8_t type = lua_tointeger(L, ++index);
     AppId app_id  = (AppId)lua_tointeger(L, ++index);
@@ -1067,11 +1167,13 @@ static int detector_add_host_port_application(lua_State* L)
 
 static int detector_add_content_type_pattern(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
     size_t stringSize = 0;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     const char* tmp_string = lua_tolstring(L, ++index, &stringSize);
     if (!tmp_string || !stringSize)
@@ -1111,10 +1213,12 @@ static int create_chp_application(AppId appIdInstance, unsigned app_type_flags,
 
 static int detector_chp_create_application(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     AppId appId = lua_tointeger(L, ++index);
     AppId appIdInstance = CHP_APPID_SINGLE_INSTANCE(appId); // Last instance for the old API
@@ -1290,15 +1394,17 @@ static int add_chp_pattern_action(AppId appIdInstance, int isKeyPattern, HttpFie
 
 static int detector_add_chp_action(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
     HttpFieldIds ptype;
     size_t psize;
     char* pattern;
     ActionType action;
     char* action_data;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     // Parameter 1
     AppId appId = lua_tointeger(L, ++index);
@@ -1335,12 +1441,14 @@ static int detector_add_chp_action(lua_State* L)
 
 static int detector_create_chp_multi_application(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    int control = init(L);
+
     AppId appIdInstance = APP_ID_UNKNOWN;
     int instance;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     AppId appId = lua_tointeger(L, ++index);
     unsigned app_type_flags = lua_tointeger(L, ++index);
@@ -1353,7 +1461,13 @@ static int detector_create_chp_multi_application(lua_State* L)
             continue;
         break;
     }
-
+    
+    if (!control)
+    {
+        lua_pushnumber(L, appIdInstance);
+        return 1;
+    }
+    
     // We only want a maximum of these for each appId.
     if (instance == CHP_APPID_INSTANCE_MAX)
     {
@@ -1371,15 +1485,17 @@ static int detector_create_chp_multi_application(lua_State* L)
 
 static int detector_add_chp_multi_action(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
     HttpFieldIds ptype;
     size_t psize;
     char* pattern;
     ActionType action;
     char* action_data;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     // Parameter 1
     AppId appIdInstance = lua_tointeger(L, ++index);
@@ -1415,16 +1531,18 @@ static int detector_add_chp_multi_action(lua_State* L)
 
 static int detector_port_only_service(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     AppId appId = lua_tointeger(L, ++index);
     uint16_t port = lua_tointeger(L, ++index);
     uint8_t protocol = lua_tointeger(L, ++index);
 
-    AppIdConfig* config = ud->get_handler().get_inspector().get_appid_config();
+    AppIdConfig* config = ud->get_detector()->get_handler().get_inspector().get_appid_config();
     if (port == 0)
         config->ip_protocol[protocol] = appId;
     else if (protocol == 6)
@@ -1455,12 +1573,15 @@ static int detector_port_only_service(lua_State* L)
  */
 static int detector_add_length_app_cache(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L, 1)) return 1;
+
     int i;
     const char* str_ptr;
     int index = 1;
 
-    UserData<AppIdDetector>::check(L, DETECTOR, index);
-
     AppId appId = lua_tonumber(L, ++index);
     IpProtocol proto = (IpProtocol)lua_tonumber(L, ++index);
     uint8_t sequence_cnt = lua_tonumber(L, ++index);
@@ -1552,10 +1673,12 @@ static int detector_add_length_app_cache(lua_State* L)
 
 static int detector_add_af_application(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     AppId indicator = (AppId)lua_tointeger(L, ++index);
     AppId forecast  = (AppId)lua_tointeger(L, ++index);
@@ -1567,10 +1690,12 @@ static int detector_add_af_application(lua_State* L)
 
 static int detector_add_url_application(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    // Verify detector user data and that we are NOT in packet context
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint32_t service_id      = lua_tointeger(L, ++index);
     uint32_t client_app      = lua_tointeger(L, ++index);
@@ -1652,10 +1777,12 @@ static int detector_add_url_application(lua_State* L)
 
 static int detector_add_rtmp_url(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint32_t service_id      = lua_tointeger(L, ++index);
     uint32_t client_app      = lua_tointeger(L, ++index);
@@ -1737,10 +1864,12 @@ static int detector_add_rtmp_url(lua_State* L)
 /*Lua should inject patterns in <clientAppId, clientVersion, multi-Pattern> format. */
 static int detector_add_sip_user_agent(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint32_t client_app = lua_tointeger(L, ++index);
     const char* clientVersion = lua_tostring(L, ++index);
@@ -1766,11 +1895,14 @@ static int detector_add_sip_user_agent(lua_State* L)
 }
 
 static int create_custom_application(lua_State* L)
-{
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+{ 
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    int control = init(L);
+
+    int index = 1;
+    AppId appId;
 
     /* Verify that host pattern is a valid string */
     size_t appNameLen = 0;
@@ -1782,9 +1914,16 @@ static int create_custom_application(lua_State* L)
         return 1;   /*number of results */
     }
 
-    AppInfoTableEntry* entry = AppInfoManager::get_instance().add_dynamic_app_entry(tmp_string);
-    if (entry)
-        lua_pushnumber(L, entry->appId);
+    if (control)
+    {
+        AppInfoTableEntry* entry = AppInfoManager::get_instance().add_dynamic_app_entry(tmp_string);
+        appId = entry->appId;
+    }
+    else 
+        appId  = AppInfoManager::get_instance().get_appid_by_name(tmp_string);
+       
+    if (appId != APP_ID_NONE)
+        lua_pushnumber(L, appId);
     else
         lua_pushnumber(L, APP_ID_NONE);
     return 1;   /*number of results */
@@ -1792,12 +1931,14 @@ static int create_custom_application(lua_State* L)
 
 static int add_client_application(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     unsigned int service_id = lua_tonumber(L, 2);
     unsigned int client_id = lua_tonumber(L, 3);
 
-    ud->add_app(*lsd->ldp.asd, service_id, client_id, "");
+    ud->cd->add_app(*lsd->ldp.asd, service_id, client_id, "");
     lua_pushnumber(L, 0);
     return 1;
 }
@@ -1814,14 +1955,16 @@ static int add_client_application(lua_State* L)
  */
 static int add_service_application(lua_State* L)
 {
-    auto& ud = *UserData<LuaServiceDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaServiceObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     unsigned service_id = lua_tonumber(L, 2);
 
     /*Phase2 - discuss AppIdServiceSubtype will be maintained on lua side therefore the last
       parameter on the following call is nullptr.
       Subtype is not displayed on DC at present. */
-    unsigned retValue = ud->add_service(*lsd->ldp.asd, lsd->ldp.pkt,
+    unsigned retValue = ud->sd->add_service(*lsd->ldp.asd, lsd->ldp.pkt,
         lsd->ldp.dir, service_id);
 
     lua_pushnumber(L, retValue);
@@ -1830,21 +1973,24 @@ static int add_service_application(lua_State* L)
 
 static int add_payload_application(lua_State* L)
 {
-    auto& ud = *UserData<LuaClientDetector>::check(L, DETECTOR, 1);
+    auto& ud = *UserData<LuaClientObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     unsigned payload_id = lua_tonumber(L, 2);
-    ud->add_payload(*lsd->ldp.asd, payload_id);
+    ud->cd->add_payload(*lsd->ldp.asd, payload_id);
     lua_pushnumber(L, 0);
     return 1;
 }
 
 static int add_http_pattern(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     /* Verify valid pattern type */
     enum httpPatternType pat_type = (enum httpPatternType)lua_tointeger(L, ++index);
@@ -1878,10 +2024,12 @@ static int add_http_pattern(lua_State* L)
 
 static int add_url_pattern(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint32_t service_id = lua_tointeger(L, ++index);
     uint32_t clientAppId   = lua_tointeger(L, ++index);
@@ -1963,11 +2111,13 @@ static int add_url_pattern(lua_State* L)
  */
 static int add_port_pattern_client(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
     size_t patternSize = 0;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     IpProtocol protocol = (IpProtocol)lua_tonumber(L, ++index);
     uint16_t port = 0;      //port      = lua_tonumber(L, ++index);  FIXIT-L - why commented out?
@@ -1977,7 +2127,7 @@ static int add_port_pattern_client(lua_State* L)
     if (appId <= APP_ID_NONE || !pattern || !patternSize ||
         (protocol != IpProtocol::TCP && protocol != IpProtocol::UDP))
     {
-        ErrorMessage("addPortPatternClient(): Invalid input in %s\n", ud->get_name().c_str());
+        ErrorMessage("addPortPatternClient(): Invalid input in %s\n", ud->get_detector()->get_name().c_str());
         return 0;
     }
 
@@ -1989,7 +2139,7 @@ static int add_port_pattern_client(lua_State* L)
     memcpy(pPattern->pattern, pattern, patternSize);
     pPattern->length = patternSize;
     pPattern->offset = position;
-    pPattern->detectorName = snort_strdup(ud->get_name().c_str());
+    pPattern->detectorName = snort_strdup(ud->get_detector()->get_name().c_str());
     PatternClientDetector::insert_client_port_pattern(pPattern);
 
     AppInfoManager::get_instance().set_app_info_active(appId);
@@ -2012,11 +2162,13 @@ static int add_port_pattern_client(lua_State* L)
  */
 static int add_port_pattern_service(lua_State* L)
 {
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
+    ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
     size_t patternSize = 0;
     int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
-    ud->validate_lua_state(false);
 
     IpProtocol protocol = (IpProtocol)lua_tonumber(L, ++index);
     uint16_t port = lua_tonumber(L, ++index);
@@ -2032,7 +2184,7 @@ static int add_port_pattern_service(lua_State* L)
     memcpy(pPattern->pattern, pattern, patternSize);
     pPattern->length = patternSize;
     pPattern->offset = position;
-    pPattern->detectorName = snort_strdup(ud->get_name().c_str());
+    pPattern->detectorName = snort_strdup(ud->get_detector()->get_name().c_str());
     PatternServiceDetector::insert_service_port_pattern(pPattern);
     AppInfoManager::get_instance().set_app_info_active(appId);
 
@@ -2042,10 +2194,12 @@ static int add_port_pattern_service(lua_State* L)
 /*Lua should inject patterns in <clientAppId, clientVersion, multi-Pattern> format. */
 static int detector_add_sip_server(lua_State* L)
 {
-    int index = 1;
-    // Verify detector user data and that we are not in packet context
-    auto& ud = *UserData<AppIdDetector>::check(L, DETECTOR, index);
+    auto& ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are NOT in packet context
     ud->validate_lua_state(false);
+    if (!init(L)) return 0;
+
+    int index = 1;
 
     uint32_t client_app = lua_tointeger(L, ++index);
     const char* clientVersion = lua_tostring(L, ++index);
@@ -2096,11 +2250,13 @@ static int detector_add_sip_server(lua_State* L)
  */
 static int create_future_flow(lua_State* L)
 {
+    auto ud = *UserData<LuaObject>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
+    LuaStateDescriptor* lsd = ud->validate_lua_state(true);
+
     SfIp client_addr;
     SfIp server_addr;
     SnortProtocolId snort_protocol_id = UNKNOWN_PROTOCOL_ID;
-    AppIdDetector* ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
-    LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     const char* pattern = lua_tostring(L, 2);
     if (!convert_string_to_address(pattern, &client_addr))
@@ -2129,7 +2285,7 @@ static int create_future_flow(lua_State* L)
 
     AppIdSession* fp = AppIdSession::create_future_session(lsd->ldp.pkt,  &client_addr,
         client_port, &server_addr, server_port, proto, snort_protocol_id,
-        APPID_EARLY_SESSION_FLAG_FW_RULE, ud->get_handler().get_inspector());
+        APPID_EARLY_SESSION_FLAG_FW_RULE, ud->get_detector()->get_handler().get_inspector());
     if (fp)
     {
         fp->service.set_id(service_id);
@@ -2293,7 +2449,7 @@ static int Detector_gc(lua_State*)
 /*convert detector to string for printing */
 static int Detector_tostring(lua_State* L)
 {
-    lua_pushfstring(L, "Detector (%p)", UserData<AppIdDetector>::check(L, DETECTOR, 1));
+    lua_pushfstring(L, "Detector (%p)", (*UserData<LuaObject>::check(L, DETECTOR, 1))->get_detector());
     return 1;
 }
 
@@ -2415,65 +2571,128 @@ static inline void init_lsd(LuaStateDescriptor* lsd, const std::string& detector
     lua_pop(L, 1);    // pop DetectorPackageInfo table
 }
 
-static inline bool lua_params_validator(LuaDetectorParameters& ldp, bool packet_context)
+LuaServiceDetector::LuaServiceDetector(AppIdDiscovery* sdm, const std::string& detector_name,
+    IpProtocol protocol)
 {
-    if ( packet_context )
+    handler = sdm;
+    name = detector_name;
+    proto = protocol;
+    handler->register_detector(name, this, proto);
+}
+
+
+LuaServiceObject::LuaServiceObject(AppIdDiscovery* sdm, const std::string& detector_name,
+    IpProtocol protocol, lua_State* L)
+{
+    if (init(L))
     {
-        assert(ldp.asd);
-        assert(ldp.pkt);
+           sd = new LuaServiceDetector(sdm,detector_name,protocol);
     }
     else
     {
-        assert(!ldp.pkt);
-    }
-
-#ifdef NDEBUG
-    UNUSED(ldp);
-#endif
+           AppIdDetector *ad = nullptr;
+           AppIdDetectors *appid_detectors = nullptr;
 
-    return true;
-}
+           if (protocol == IpProtocol::TCP)
+        {
+            appid_detectors = ServiceDiscovery::get_instance().get_tcp_detectors();
+               auto detector = appid_detectors->find(detector_name);
+            if (detector != appid_detectors->end())
+                ad = detector->second;  
+        }
+           else if (protocol == IpProtocol::UDP)
+        {
+            appid_detectors = ServiceDiscovery::get_instance().get_udp_detectors();
+               auto detector = appid_detectors->find(detector_name);
+            if (detector != appid_detectors->end())
+                ad = detector->second;  
+        }
+           sd = (ServiceDetector*)ad;
+    }  
 
-LuaServiceDetector::LuaServiceDetector(AppIdDiscovery* sdm, const std::string& detector_name,
-    IpProtocol protocol, lua_State* L)
-{
-    handler = sdm;
-    name = detector_name;
-    proto = protocol;
-    handler->register_detector(name, this, proto);
     init_lsd(&lsd, detector_name, L);
-    UserData<AppIdDetector>::push(L, DETECTOR, this);
-    // add a lua reference so the detector doesn't get garbage-collected
+    UserData<LuaServiceObject>::push(L, DETECTOR, this);
+
     lua_pushvalue(L, -1);
-    lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
-}
 
-LuaStateDescriptor* LuaServiceDetector::validate_lua_state(bool packet_context)
-{
-    lua_params_validator(lsd.ldp, packet_context);
-    return &lsd;
+    // FIXIT-M: RELOAD - go back to using lua reference 
+    // instead of using a string for lookups
+    // lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    
+    // FIXIT-H: The control and thread states have the same initialization
+    // sequence, the stack index shouldn't change between the states, maybe
+    // use a common index for a detector between all the states
+    std::string name = detector_name + "_";
+    lua_setglobal(L, name.c_str());
 }
 
 int LuaServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
-    return lsd.lua_validate(args);
+    //FIXIT-M: RELOAD - use lua references to get user data object from stack
+    auto my_lua_state = lua_detector_mgr? lua_detector_mgr->L : nullptr;
+    lua_settop(my_lua_state,0);
+    std::string name = this->name + "_";
+    lua_getglobal(my_lua_state, name.c_str());
+    auto& ud = *UserData<LuaServiceObject>::check(my_lua_state, DETECTOR, 1);
+    return ud->lsd.lua_validate(args);
 }
 
 LuaClientDetector::LuaClientDetector(AppIdDiscovery* cdm, const std::string& detector_name,
-    IpProtocol protocol, lua_State* L)
+    IpProtocol protocol)
 {
     handler = cdm;
     name = detector_name;
     proto = protocol;
     handler->register_detector(name, this, proto);
+}
+
+LuaClientObject::LuaClientObject(AppIdDiscovery* cdm, const std::string& detector_name,
+    IpProtocol protocol, lua_State* L)
+{
+    if (init(L))
+    {
+        cd = new LuaClientDetector(cdm, detector_name, protocol);
+    }
+    else
+    {
+           AppIdDetector *ad = nullptr;
+           AppIdDetectors *appid_detectors = nullptr;
+
+           if (protocol == IpProtocol::TCP)
+        {
+            appid_detectors = ClientDiscovery::get_instance().get_tcp_detectors();
+               auto detector = appid_detectors->find(detector_name);
+            if (detector != appid_detectors->end())
+                ad = detector->second;  
+        }
+           else if (protocol == IpProtocol::UDP)
+        {
+            appid_detectors = ClientDiscovery::get_instance().get_udp_detectors();
+               auto detector = appid_detectors->find(detector_name);
+            if (detector != appid_detectors->end())
+                ad = detector->second;  
+        }
+           cd = (ClientDetector*)ad;
+    }  
+    
     init_lsd(&lsd, detector_name, L);
-    UserData<AppIdDetector>::push(L, DETECTOR, this);
-    // add a lua reference so the detector doesn't get garbage-collected
+    UserData<LuaClientObject>::push(L, DETECTOR, this);
+
     lua_pushvalue(L, -1);
-    lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+
+    // FIXIT-M: RELOAD - go back to using lua reference 
+    // instead of using a string for lookups
+    // lsd.detector_user_data_ref = luaL_ref(L, LUA_REGISTRYINDEX);
+    
+    // FIXIT-H: The control and thread states have the same initialization
+    // sequence, the stack index shouldn't change between the states, maybe
+    // use a common index for a detector between all the states
+    std::string name = detector_name + "_";
+    lua_setglobal(L, name.c_str());
 }
 
-LuaStateDescriptor* LuaClientDetector::validate_lua_state(bool packet_context)
+
+LuaStateDescriptor* LuaObject::validate_lua_state(bool packet_context)
 {
     lua_params_validator(lsd.ldp, packet_context);
     return &lsd;
@@ -2481,6 +2700,11 @@ LuaStateDescriptor* LuaClientDetector::validate_lua_state(bool packet_context)
 
 int LuaClientDetector::validate(AppIdDiscoveryArgs& args)
 {
-    return lsd.lua_validate(args);
+    //FIXIT-M: RELOAD - use lua references to get user data object from stack
+    auto my_lua_state = lua_detector_mgr? lua_detector_mgr->L : nullptr;
+    std::string name = this->name + "_";
+    lua_settop(my_lua_state,0); //set stack index to 0
+    lua_getglobal(my_lua_state, name.c_str());
+    auto& ud = *UserData<LuaClientObject>::check(my_lua_state, DETECTOR, 1);
+    return ud->lsd.lua_validate(args);
 }
-
index 74e02b797c3c88fe7876f4322c979244ffc1a7a3..49d9a47725f80a811eb288197f160db0bec14c1d 100644 (file)
@@ -31,6 +31,7 @@
 #include "service_plugins/service_detector.h"
 
 #include "main/snort_debug.h"
+
 extern Trace TRACE_NAME(appid_module);
 
 namespace snort
@@ -77,37 +78,67 @@ class LuaStateDescriptor
 public:
     LuaDetectorParameters ldp;
     // FIXIT-M: RELOAD - When reload is supported, update this whenever lua-state is changed
-    int detector_user_data_ref = 0;    // key into LUA_REGISTRYINDEX
+    // move it to the detector classes
+    //int detector_user_data_ref = 0;    // key into LUA_REGISTRYINDEX
     DetectorPackageInfo package_info;
     unsigned int service_id = APP_ID_UNKNOWN;
-
     int lua_validate(AppIdDiscoveryArgs&);
 };
 
 class LuaServiceDetector : public ServiceDetector
 {
 public:
-    LuaServiceDetector(AppIdDiscovery* sdm, const std::string& detector_name, IpProtocol protocol,
-        lua_State* L);
+    LuaServiceDetector(AppIdDiscovery* sdm, const std::string& detector_name, IpProtocol protocol);
     int validate(AppIdDiscoveryArgs&) override;
-    LuaStateDescriptor* validate_lua_state(bool packet_context) override;
-
-    LuaStateDescriptor lsd;
 };
 
 class LuaClientDetector : public ClientDetector
 {
 public:
-    LuaClientDetector(AppIdDiscovery* cdm, const std::string& detector_name, IpProtocol protocol,
-        lua_State* L);
+    LuaClientDetector(AppIdDiscovery* cdm, const std::string& detector_name, IpProtocol protocol);
     int validate(AppIdDiscoveryArgs&) override;
-    LuaStateDescriptor* validate_lua_state(bool packet_context) override;
+
+};
+
+
+//FIXIT-M: RELOAD - Don't use this class, 
+//required now to store LSD objects
+class LuaObject {
+   
+public:
+    LuaObject() = default;
+    virtual ~LuaObject() = default;
+    LuaObject(const LuaObject&) = delete;
+    LuaObject& operator=(const LuaObject&) = delete;
 
     LuaStateDescriptor lsd;
+    virtual AppIdDetector* get_detector() = 0;
+    LuaStateDescriptor* validate_lua_state(bool packet_context);
+};
+
+class LuaServiceObject: public LuaObject
+{ 
+public:
+    ServiceDetector* sd;
+    LuaServiceObject(AppIdDiscovery* cdm, const std::string& detector_name, IpProtocol protocol,
+        lua_State* L);
+    ServiceDetector* get_detector()
+    { return sd; }
+};
+
+class LuaClientObject : public LuaObject
+{ 
+public:
+    ClientDetector* cd;
+    LuaClientObject(AppIdDiscovery* cdm, const std::string& detector_name, IpProtocol protocol,
+        lua_State* L);
+    ClientDetector* get_detector()
+    { return cd; }
 };
 
 int register_detector(lua_State*);
 int init_chp_glossary();
+int init(lua_State*, int result=0);
 void free_chp_glossary();
 
 #endif
index 678a5376130f6aa252a0181f85ecb140656191ae..c1e1908150d62937c802b18d1c4134ca80c95874 100644 (file)
@@ -159,6 +159,7 @@ static int create_detector_flow(lua_State* L)
     snort::SfIp daddr;
 
     AppIdDetector* ud = *UserData<AppIdDetector>::check(L, DETECTOR, 1);
+    // Verify detector user data and that we are in packet context
     LuaStateDescriptor* lsd = ud->validate_lua_state(true);
 
     const char* pattern = lua_tostring(L, 2);
@@ -238,7 +239,7 @@ void free_detector_flow(void* userdata)
     delete detector_flow;
 }
 
-/**Sets a flow flag.
+/**Sets a flow flag
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorFlow/stack - UserData<DetectorFlow> object
@@ -250,6 +251,7 @@ static int set_detector_flow_flag(lua_State* L)
     uint64_t flags;
 
     auto& pLuaData = *UserData<DetectorFlow>::check(L, DETECTORFLOW, 1);
+    // Verify detector user data and that we are in packet context
     assert(pLuaData.ptr);
 
     flags = lua_tonumber(L, 2);
@@ -260,7 +262,7 @@ static int set_detector_flow_flag(lua_State* L)
     return 0;
 }
 
-/**Gets a flow flag value.
+/**Gets a flow flag value
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorFlow/stack - UserData<DetectorFlow> object
@@ -274,6 +276,7 @@ static int get_detector_flow_flag(lua_State* L)
     uint64_t ret;
 
     auto& pLuaData = *UserData<DetectorFlow>::check(L, DETECTORFLOW, 1);
+    // Verify detector user data and that we are in packet context
     assert(pLuaData.ptr);
 
     flags = lua_tonumber(L, 2);
@@ -286,7 +289,7 @@ static int get_detector_flow_flag(lua_State* L)
     return 1;
 }
 
-/**Clear a flow flag.
+/**Clear a flow flag,
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorFlow/stack - UserData<DetectorFlow> object
@@ -298,6 +301,7 @@ static int clear_detector_flow_flag(lua_State* L)
     uint64_t flags;
 
     auto& pLuaData = *UserData<DetectorFlow>::check(L, DETECTORFLOW, 1);
+    // Verify detector user data and that we are in packet context
     assert(pLuaData.ptr);
 
     flags = lua_tonumber(L, 2);
@@ -308,7 +312,9 @@ static int clear_detector_flow_flag(lua_State* L)
     return 0;
 }
 
-/**Set service id on a flow.
+/**Set service id on a flow
+ * If funtion is implemented, then
+ * verify detector user data and that we are in packet context
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorFlow/stack - UserData<DetectorFlow> object
@@ -318,7 +324,9 @@ static int clear_detector_flow_flag(lua_State* L)
 static int set_detector_flow_service_id(lua_State*)
 { return 0; }
 
-/**Set client application id on a flow.
+/**Set client application id on a flow, during packet processing
+ * If funtion is implemented, then
+ * verify detector user data and that we are in packet context
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorFlow/stack - UserData<DetectorFlow> object
@@ -330,7 +338,9 @@ static int set_detecter_flow_cln_app_id(lua_State*)
     return 0;
 }
 
-/**Set client application type id on a flow.
+/**Set client application type id on a flow, during packet processing
+ * If funtion is implemented, then
+ * verify detector user data and that we are in packet context
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorFlow/stack - UserData<DetectorFlow> object
@@ -349,7 +359,7 @@ static int set_detector_flow_cln_app_type(lua_State*)
  * For optimization, I could have created an integer index on C side. This can be taken up in future.
  */
 
-/**Get flow key from a UserData<DetectorFlow> object.
+/**Get flow key from a UserData<DetectorFlow> object
  *
  * @param Lua_State* - Lua state variable.
  * @param detectorflow/stack - UserData<DetectorFlow> object
@@ -359,6 +369,7 @@ static int set_detector_flow_cln_app_type(lua_State*)
 static int get_detector_flow_key(lua_State* L)
 {
     auto& pLuaData = *UserData<DetectorFlow>::check(L, DETECTORFLOW, 1);
+    // Verify detector user data and that we are in packet context
     assert(pLuaData.ptr);
 
     lua_pushlstring(L, (char*)&pLuaData->asd->session_id,
index 3395dcc751d05028964b42d7eb7c8ea9244106a6..6b82f1a7184298e4c73a3ddf88bb6397db7a1b6d 100644 (file)
@@ -86,7 +86,14 @@ bool get_lua_field(lua_State* L, int table, const char* field, IpProtocol& out)
     return result;
 }
 
-static lua_State* create_lua_state(const AppIdModuleConfig* mod_config)
+inline void set_control(lua_State* L, int is_control)
+{
+    lua_pushboolean (L, is_control); // push flag to stack 
+    lua_setglobal(L, "is_control"); // create global key to store value
+    lua_pop(L, 1);
+}
+
+static lua_State* create_lua_state(const AppIdModuleConfig* mod_config, int is_control)
 {
     auto L = luaL_newstate();
 
@@ -95,6 +102,7 @@ static lua_State* create_lua_state(const AppIdModuleConfig* mod_config)
 
     luaL_openlibs(L);
 
+    set_control(L, is_control);
     register_detector(L);
     lua_pop(L, 1);          // After registration the methods are still on the stack, remove them
 
@@ -140,13 +148,14 @@ static lua_State* create_lua_state(const AppIdModuleConfig* mod_config)
     return L;
 }
 
-LuaDetectorManager::LuaDetectorManager(AppIdConfig& config) :
+LuaDetectorManager::LuaDetectorManager(AppIdConfig& config, int is_control) :
     config(config)
 {
-    init_chp_glossary();
     sflist_init(&allocated_detector_flow_list);
-    allocated_detectors.clear();
-    L = create_lua_state(config.mod_config);
+    allocated_objects.clear();
+    L = create_lua_state(config.mod_config, is_control);
+    if (is_control == 1)
+        init_chp_glossary();
 }
 
 LuaDetectorManager::~LuaDetectorManager()
@@ -154,38 +163,44 @@ LuaDetectorManager::~LuaDetectorManager()
     auto L = lua_detector_mgr? lua_detector_mgr->L : nullptr;
     if (L)
     {
-        for ( auto& detector : allocated_detectors )
+        if (init(L))
+            free_chp_glossary();
+
+        for ( auto& lua_object : allocated_objects )
         {
-            LuaStateDescriptor* lsd = detector->validate_lua_state(false);
+            LuaStateDescriptor* lsd = lua_object->validate_lua_state(false);
 
             lua_getfield(L, LUA_REGISTRYINDEX, lsd->package_info.name.c_str());
             lua_getfield(L, -1, lsd->package_info.cleanFunctionName.c_str());
             if ( lua_isfunction(L, -1) )
             {
+                //FIXIT-M: RELOAD - use lua references to get user data object from stack
                 //first parameter is DetectorUserData
-                lua_rawgeti(L, LUA_REGISTRYINDEX, lsd->detector_user_data_ref);
+                std::string name = lsd->package_info.name + "_";
+                lua_getglobal(L, name.c_str());
+
                 if ( lua_pcall(L, 1, 1, 0) )
                 {
                     ErrorMessage("Could not cleanup the %s client app element: %s\n",
                         lsd->package_info.name.c_str(), lua_tostring(L, -1));
                 }
             }
+           delete lua_object;
         }
         lua_close(L);
     }
 
     sflist_static_free_all(&allocated_detector_flow_list, free_detector_flow);
-    allocated_detectors.clear();
-    free_chp_glossary();
+    allocated_objects.clear();
 }
 
-void LuaDetectorManager::initialize(AppIdConfig& config)
+void LuaDetectorManager::initialize(AppIdConfig& config, int is_control)
 {
     // FIXIT-M: RELOAD - When reload is supported, remove this line which prevents re-initialize
     if (lua_detector_mgr)
         return;
 
-    lua_detector_mgr = new LuaDetectorManager(config);
+    lua_detector_mgr = new LuaDetectorManager(config, is_control);
     if (!lua_detector_mgr->L)
         FatalError("Error - appid: can not create new luaState, instance=%u\n", get_instance_id());
 
@@ -201,13 +216,6 @@ void LuaDetectorManager::terminate()
     if (!lua_detector_mgr)
         return;
 
-    // release the reference of the userdata on the lua side
-    for (auto ld : lua_detector_mgr->allocated_detectors)
-    {
-        LuaStateDescriptor* lsd = ld->validate_lua_state(false);
-        if (lsd->detector_user_data_ref != LUA_REFNIL)
-            luaL_unref(lua_detector_mgr->L, LUA_REGISTRYINDEX, lsd->detector_user_data_ref);
-    }
     delete lua_detector_mgr;
     lua_detector_mgr = nullptr;
 }
@@ -277,7 +285,7 @@ static inline uint32_t compute_lua_tracker_size(uint64_t rnaMemory, uint32_t num
 }
 
 // Leaves 1 value (the Detector userdata) at the top of the stack
-static AppIdDetector* create_lua_detector(lua_State* L, const char* detectorName, bool is_custom)
+static LuaObject* create_lua_detector(lua_State* L, const char* detectorName, bool is_custom)
 {
     std::string detector_name;
     IpProtocol proto = IpProtocol::PROTO_NOT_SET;
@@ -298,10 +306,10 @@ static AppIdDetector* create_lua_detector(lua_State* L, const char* detectorName
     lua_getfield(L, -1, "client");
     if ( lua_istable(L, -1) )
     {
-        LuaClientDetector* cd = new LuaClientDetector(&ClientDiscovery::get_instance(),
+        LuaClientObject* lco = new LuaClientObject(&ClientDiscovery::get_instance(),
             detectorName, proto, L);
-        cd->set_custom_detector(is_custom);
-        return cd;
+        lco->cd->set_custom_detector(is_custom);
+        return lco;
     }
     else
     {
@@ -310,10 +318,10 @@ static AppIdDetector* create_lua_detector(lua_State* L, const char* detectorName
         lua_getfield(L, -1, "server");
         if ( lua_istable(L, -1) )
         {
-            LuaServiceDetector* sd = new LuaServiceDetector(&ServiceDiscovery::get_instance(),
+            LuaServiceObject* lso = new LuaServiceObject(&ServiceDiscovery::get_instance(),
                 detectorName, proto, L);
-            sd->set_custom_detector(is_custom);
-            return sd;
+            lso->sd->set_custom_detector(is_custom);
+            return lso;
         }
 
         lua_pop(L, 1);        // pop server table
@@ -359,9 +367,9 @@ void LuaDetectorManager::load_detector(char* detector_filename, bool isCustom)
         return;
     }
 
-    AppIdDetector* detector = create_lua_detector(L, detectorName, isCustom);
-    if (detector)
-        allocated_detectors.push_front(detector);
+    LuaObject* lua_object = create_lua_detector(L, detectorName, isCustom);
+    if (lua_object)
+        allocated_objects.push_front(lua_object);
 }
 
 void LuaDetectorManager::load_lua_detectors(const char* path, bool isCustom)
@@ -397,7 +405,7 @@ void LuaDetectorManager::initialize_lua_detectors()
 
     snprintf(path, sizeof(path), "%s/odp/lua", dir);
     load_lua_detectors(path, false);
-    num_odp_detectors = allocated_detectors.size();
+    num_odp_detectors = allocated_objects.size();
 
     snprintf(path, sizeof(path), "%s/custom/lua", dir);
     load_lua_detectors(path, true);
@@ -406,28 +414,30 @@ void LuaDetectorManager::initialize_lua_detectors()
 void LuaDetectorManager::activate_lua_detectors()
 {
     uint32_t lua_tracker_size = compute_lua_tracker_size(MAX_MEMORY_FOR_LUA_DETECTORS,
-        allocated_detectors.size());
+        allocated_objects.size());
 
-    for ( auto ld : allocated_detectors )
+    for ( auto lo : allocated_objects )
     {
-        LuaStateDescriptor* lsd = ld->validate_lua_state(false);
+        LuaStateDescriptor* lsd = lo->validate_lua_state(false);
         lua_getfield(L, LUA_REGISTRYINDEX, lsd->package_info.name.c_str());
         lua_getfield(L, -1, lsd->package_info.initFunctionName.c_str());
         if (!lua_isfunction(L, -1))
         {
             ErrorMessage("Detector %s: does not contain DetectorInit() function\n",
-                ld->get_name().c_str());
+                lo->get_detector()->get_name().c_str());
             return;
         }
 
+        //FIXIT-M: RELOAD - use lua references to get user data object from stack
         /*first parameter is DetectorUserData */
-        lua_rawgeti(L, LUA_REGISTRYINDEX, lsd->detector_user_data_ref);
+        std::string name = lsd->package_info.name + "_";
+           lua_getglobal(L, name.c_str());
 
         /*second parameter is a table containing configuration stuff. */
         lua_newtable(L);
         if ( lua_pcall(L, 2, 1, 0) )
             ErrorMessage("Could not initialize the %s client app element: %s\n",
-                ld->get_name().c_str(), lua_tostring(L, -1));
+                lo->get_detector()->get_name().c_str(), lua_tostring(L, -1));
 
         lua_getfield(L, LUA_REGISTRYINDEX, lsd->package_info.name.c_str());
         set_lua_tracker_size(L, lua_tracker_size);
@@ -438,6 +448,6 @@ void LuaDetectorManager::list_lua_detectors()
 {
     LogMessage("AppId Lua-Detector Stats: instance %u, odp detectors %zu, custom detectors %zu,"
         " total memory %d kb\n", get_instance_id(), num_odp_detectors,
-        (allocated_detectors.size() - num_odp_detectors), lua_gc(L, LUA_GCCOUNT, 0));
+        (allocated_objects.size() - num_odp_detectors), lua_gc(L, LUA_GCCOUNT, 0));
 }
 
index d411f197875fc1c86c9b738499f863633793c462..149550c4fd5d4a0da3df2d99f91cdf0631c0da11 100644 (file)
@@ -35,6 +35,7 @@
 class AppIdConfig;
 class AppIdDetector;
 struct DetectorFlow;
+class LuaObject;
 
 bool get_lua_field(lua_State* L, int table, const char* field, std::string& out);
 bool get_lua_field(lua_State* L, int table, const char* field, int& out);
@@ -43,9 +44,9 @@ bool get_lua_field(lua_State* L, int table, const char* field, IpProtocol& out);
 class LuaDetectorManager
 {
 public:
-    LuaDetectorManager(AppIdConfig&);
+    LuaDetectorManager(AppIdConfig&, int);
     ~LuaDetectorManager();
-    static void initialize(AppIdConfig&);
+    static void initialize(AppIdConfig&, int is_control=0);
     static void terminate();
     static void add_detector_flow(DetectorFlow*);
     static void free_detector_flows();
@@ -60,7 +61,7 @@ private:
     void load_lua_detectors(const char* path, bool isCustom);
 
     AppIdConfig& config;
-    std::list<AppIdDetector*> allocated_detectors;
+    std::list<LuaObject*> allocated_objects;
     size_t num_odp_detectors = 0;
 };
 
index 5f5a46353ff87070a925005a0aba8d69934bb2cf..b269dec090ae4969a2815a3d897cb2f1d0b2c229 100644 (file)
@@ -100,6 +100,11 @@ BootpServiceDetector::BootpServiceDetector(ServiceDiscovery* sd)
 }
 
 BootpServiceDetector::~BootpServiceDetector()
+{
+    release_thread_resources();
+}
+
+void BootpServiceDetector::release_thread_resources()
 {
     DHCPInfo* info;
 
index 2d3eb6b0d2e9808fe61d014620c960431be66b34..d66fe9484d27c5e9f9740a3c6e9d5431d0bb8e04 100644 (file)
@@ -39,6 +39,7 @@ public:
     static void AppIdFreeDhcpData(snort::DHCPData*);
     static void AppIdFreeDhcpInfo(snort::DHCPInfo*);
 
+    void release_thread_resources() override;
 private:
     int add_dhcp_info(AppIdSession&, unsigned op55_len, const uint8_t* op55, unsigned
         op60_len, const uint8_t* op60, const uint8_t* mac);
index f772193bf359165d3e3a2f3c11990f72e40173ee..0cb25c77600b994ee8b3b0aaef992cc7946808e4 100644 (file)
@@ -31,8 +31,8 @@ class ServiceDetector : public AppIdDetector
 {
 public:
     ServiceDetector();
-
     void do_custom_init() override { }
+    void release_thread_resources() override { }
     void register_appid(AppId, unsigned extractsInfo) override;
     int service_inprocess(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
     int add_service(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, AppId, const char* vendor = nullptr,
index 6931da89d22461aef9c2135dbf4c3887c1afec5b..2ebf5bdc9666d1268c8bbe6a5b5b7b39854d1fc9 100644 (file)
@@ -86,7 +86,7 @@
 
 using namespace snort;
 
-static THREAD_LOCAL ServiceDetector* ftp_service = nullptr;
+static ServiceDetector* ftp_service;
 
 ProfileStats serviceMatchPerfStats;
 
@@ -96,10 +96,10 @@ ServiceDiscovery::ServiceDiscovery(AppIdInspector& ins)
     initialize();
 }
 
-
+//FIXIT-M: Don't use pointer and pass discovery_manager directly
 ServiceDiscovery& ServiceDiscovery::get_instance(AppIdInspector* ins)
 {
-    static THREAD_LOCAL ServiceDiscovery* discovery_manager = nullptr;
+    static  ServiceDiscovery* discovery_manager = nullptr;
     if (!discovery_manager)
     {
         assert(ins);
@@ -160,10 +160,15 @@ void ServiceDiscovery::initialize()
 #endif
 
     for ( auto kv : tcp_detectors )
+    {
         kv.second->initialize();
-
+        service_detector_list.push_back(kv.second);
+    }
     for ( auto kv : udp_detectors )
+    {
         kv.second->initialize();
+        service_detector_list.push_back(kv.second);    
+    }
 }
 
 void ServiceDiscovery::finalize_service_patterns()
@@ -812,3 +817,8 @@ int ServiceDiscovery::fail_service(AppIdSession& asd, const Packet* pkt, AppidSe
     return APPID_SUCCESS;
 }
 
+void ServiceDiscovery::release_thread_resources()
+{
+    for (auto detectors : service_detector_list)
+           detectors->release_thread_resources();
+}
index 7d2728be53392803263e6519b53cf8c3022080d2..a84556793dc32182ee4b7db123797f67e50e9696 100644 (file)
@@ -82,14 +82,14 @@ public:
     int fail_service(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, ServiceDetector*, ServiceDiscoveryState* sds = nullptr);
     int incompatible_data(AppIdSession&, const snort::Packet*, AppidSessionDirection dir, ServiceDetector*);
     static int add_ftp_service_state(AppIdSession&);
-
+    void release_thread_resources();
 private:
     ServiceDiscovery(AppIdInspector& ins);
     void initialize() override;
     void get_next_service(const snort::Packet*, const AppidSessionDirection dir, AppIdSession&);
     void get_port_based_services(IpProtocol, uint16_t port, AppIdSession&);
     void match_by_pattern(AppIdSession&, const snort::Packet*, IpProtocol);
-
+    std::vector<AppIdDetector*> service_detector_list;
     std::unordered_map<uint16_t, std::vector<ServiceDetector*> > tcp_services;
     std::unordered_map<uint16_t, std::vector<ServiceDetector*> > udp_services;
     std::unordered_map<uint16_t, std::vector<ServiceDetector*> > udp_reversed_services;
index cb66a9463ce56ef7c5b92afb0ce025dde5556bea..31df782850c31fb13dc9744c8c7d126009e13e67 100644 (file)
@@ -798,6 +798,8 @@ void FtpServiceDetector::create_expected_session(AppIdSession& asd, const Packet
     uint16_t cliPort, const SfIp* srvIp, uint16_t srvPort, IpProtocol proto,
     int flags, AppidSessionDirection dir)
 {
+    //FIXIT-M - Avoid thread locals
+    static THREAD_LOCAL SnortProtocolId ftp_data_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
     if(ftp_data_snort_protocol_id == UNKNOWN_PROTOCOL_ID)
         ftp_data_snort_protocol_id = SnortConfig::get_conf()->proto_ref->find("ftp-data");
 
index 7bd6283614c6d1c9196113f4d2c41c7f91c7d7c0..dca0ddd906110f5da170ef360c82b89f5cd69733 100644 (file)
@@ -37,8 +37,6 @@ private:
     void create_expected_session(AppIdSession& asd,const snort::Packet* pkt,
         const snort::SfIp* cliIp, uint16_t cliPort, const snort::SfIp* srvIp,
         uint16_t srvPort, IpProtocol proto, int flags, AppidSessionDirection dir);
-
-    SnortProtocolId ftp_data_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
 #endif
 
index 0e83ce9dda16b91b96b46d266686965c613d4201..f52278c44d03f45066db9dc97ac2c28e8a23d6fd 100644 (file)
@@ -79,6 +79,7 @@ struct MatchedPatterns
     MatchedPatterns* next;
 };
 
+static THREAD_LOCAL MatchedPatterns* patternList;
 static THREAD_LOCAL MatchedPatterns* patternFreeList;
 
 static MdnsPattern patterns[] =
@@ -119,6 +120,19 @@ MdnsServiceDetector::~MdnsServiceDetector()
     destory_matcher();
 }
 
+void MdnsServiceDetector::release_thread_resources()
+{   
+    MatchedPatterns* node;
+
+    destroy_match_list();
+
+    while ((node = patternFreeList))
+    {
+        patternFreeList = node->next;
+        snort_free(node);
+    }
+}
+
 int MdnsServiceDetector::validate(AppIdDiscoveryArgs& args)
 {
     int ret_val;
index 64ba52a0c777ba9003115c50c64cf8383874947a..b19c234fc633753cd45586d6d2bcf57396b7a391 100644 (file)
@@ -38,6 +38,7 @@ public:
     ~MdnsServiceDetector() override;
 
     int validate(AppIdDiscoveryArgs&) override;
+    void release_thread_resources() override;
 
 private:
     unsigned create_match_list(const char* data, uint16_t dataSize);
@@ -51,7 +52,6 @@ private:
         uint16_t data_size, uint8_t* user_name_len, unsigned size);
 
     snort::SearchTool* matcher = nullptr;
-    MatchedPatterns* patternList= nullptr;
 };
 #endif
 
index 76f2c17a726fcacb37c54177a0392bfba52b0752..b7578274218d9407a9c33a94f7fa1d23bdb758ef 100644 (file)
@@ -1019,6 +1019,11 @@ NbdgmServiceDetector::NbdgmServiceDetector(ServiceDiscovery* sd)
 }
 
 NbdgmServiceDetector::~NbdgmServiceDetector()
+{
+    release_thread_resources();
+}
+
+void NbdgmServiceDetector::release_thread_resources()
 {
     FpSMBData* sd;
 
index bfc4beba9d092c6252a010be15b154be01d992a1..0c3f53e6839f4770913723f326ed4d71cf81cc9a 100644 (file)
@@ -52,6 +52,7 @@ public:
     int validate(AppIdDiscoveryArgs&) override;
 
     static void AppIdFreeSMBData(snort::FpSMBData*);
+    void release_thread_resources() override;
 
 private:
     void add_smb_info(AppIdSession&, unsigned major, unsigned minor, uint32_t flags);
index 70eeca6b665dd4c317d492e9d71170dddffb9079..50164acccbed812e114bbec6298616ee24e6fa6b 100644 (file)
@@ -103,6 +103,8 @@ int RexecServiceDetector::validate(AppIdDiscoveryArgs& args)
     uint32_t port = 0;
     const uint8_t* data = args.data;
     uint16_t size = args.size;
+    //FIXIT-M - Avoid thread locals
+    static THREAD_LOCAL SnortProtocolId rexec_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 
     ServiceREXECData* rd = (ServiceREXECData*)data_get(args.asd);
     if (!rd)
index 8191b2fb9dcf743cb5cc604cf0f68c3cff2369b6..f14cd0f22d8a777d1e1860791957ce851a1c11f6 100644 (file)
@@ -32,9 +32,6 @@ public:
     RexecServiceDetector(ServiceDiscovery*);
 
     int validate(AppIdDiscoveryArgs&) override;
-
-private:
-    SnortProtocolId rexec_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
 
 #endif
index 7448ffdb1be7e2ecb465bf52e6768227d5862884..42fd6523235061544f0d4754719e9e865de1c100 100644 (file)
@@ -283,6 +283,8 @@ int RpcServiceDetector::validate_packet(const uint8_t* data, uint16_t size, Appi
     uint32_t val = 0;
     const uint8_t* end = nullptr;
     const RPCProgram* rprog = nullptr;
+    //FIXIT-M - Avoid thread locals
+    static THREAD_LOCAL SnortProtocolId sunrpc_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 
     if (!size)
         return APPID_INPROCESS;
index 9b0fa46cae1f0db569aa5b22ab74f9d9cd859d7d..4b30a6886b2fd04daedefe19ef3a205cbe9f2135 100644 (file)
@@ -41,7 +41,6 @@ private:
     int rpc_tcp_validate(AppIdDiscoveryArgs&);
     int validate_packet(const uint8_t* data, uint16_t size, AppidSessionDirection dir, AppIdSession&,
         snort::Packet*, ServiceRPCData*, const char** pname, uint32_t* program);
-    SnortProtocolId sunrpc_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
 #endif
 
index 8b83e6c2012202e391acef8e651657102dbb0ffc..24169ef77d4c508f8b1d561d50025d1010001f79 100644 (file)
@@ -101,6 +101,8 @@ int RshellServiceDetector::validate(AppIdDiscoveryArgs& args)
     uint32_t port = 0;
     const uint8_t* data = args.data;
     uint16_t size = args.size;
+    //FIXIT-M - Avoid thread locals
+    static THREAD_LOCAL SnortProtocolId rsh_error_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 
     ServiceRSHELLData* rd = (ServiceRSHELLData*)data_get(args.asd);
     if (!rd)
index b872b7f311ee8c287c525927a199ccc4f9fcdb38..3f880e0e585704b3af8723290807cec807b2c333 100644 (file)
@@ -32,9 +32,6 @@ public:
     RshellServiceDetector(ServiceDiscovery*);
 
     int validate(AppIdDiscoveryArgs&) override;
-
-private:
-    SnortProtocolId rsh_error_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
 #endif
 
index 3f99f1a4fa0bfae758b573fcc1b722f9eada2d50..c403a6775ac8c70298c92378470f33910cdde845 100644 (file)
@@ -406,6 +406,8 @@ int SnmpServiceDetector::validate(AppIdDiscoveryArgs& args)
     const char* version_str = nullptr;
     const uint8_t* data = args.data;
     uint16_t size = args.size;
+    //FIXIT-M - Avoid thread locals
+    static THREAD_LOCAL SnortProtocolId snmp_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 
     if (!size)
         goto inprocess;
index 73499754f27c31e1cddc27e65c8c264dfc6cba04..5851e5655bfc2f3ca8f583e42945637e020fc6d0 100644 (file)
@@ -32,9 +32,6 @@ public:
     SnmpServiceDetector(ServiceDiscovery*);
 
     int validate(AppIdDiscoveryArgs&) override;
-
-private:
-    SnortProtocolId snmp_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
 
 #endif
index b10c5dd70f535c96e218d03ede96d5da8b92464f..d5cc5911693a3c62d863f8485107ffd15699dab7 100644 (file)
@@ -204,7 +204,7 @@ struct ServiceSslConfig
     SearchTool* ssl_cname_matcher;
 };
 
-static THREAD_LOCAL ServiceSslConfig service_ssl_config;
+static ServiceSslConfig service_ssl_config;
 
 #pragma pack()
 
index 70e1d0027e562bb7281474d443e0bd6db09e416d..e39e4b97635e1a9b8484de488e2b7c019e34f3be 100644 (file)
@@ -132,6 +132,8 @@ int TftpServiceDetector::validate(AppIdDiscoveryArgs& args)
     AppIdSession* pf = nullptr;
     const uint8_t* data = args.data;
     uint16_t size = args.size;
+    //FIXIT-M - Avoid thread locals
+    static THREAD_LOCAL SnortProtocolId tftp_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 
     if (!size)
         goto inprocess;
index 8fc8778fa2fda069b04ae8000db45382466badd4..6b12490766e0bc34b8ff7914c22d4baf5885eeb4 100644 (file)
@@ -32,9 +32,6 @@ public:
     TftpServiceDetector(ServiceDiscovery*);
 
     int validate(AppIdDiscoveryArgs&) override;
-
-private:
-    SnortProtocolId tftp_snort_protocol_id = UNKNOWN_PROTOCOL_ID;
 };
 #endif
 
index 11cb07249f627726b762a468871d99e30a21a56c..49cdade67d64ae45ad6f15af84750921c3d5e5c5 100644 (file)
@@ -47,6 +47,7 @@ public:
     void do_custom_init() override { }
     int validate(AppIdDiscoveryArgs&) override { return 0; }
     void register_appid(AppId, unsigned) override { }
+    void release_thread_resources() override { }
 };
 
 TEST_GROUP(appid_detector_tests)
index 68b25918d403a15f03d55feab693518c7d0ec537..389065c7b37196c87971706727137e0d93f91d41 100644 (file)
@@ -99,18 +99,11 @@ int ServiceDiscovery::add_service_port(AppIdDetector*,
     const ServiceDetectorPort&) { return APPID_EINVALID; }
 ServiceDiscovery::ServiceDiscovery(AppIdInspector& ins)
     : AppIdDiscovery(ins) {}
-bool new_manager_test = true;
+
 ServiceDiscovery& ServiceDiscovery::get_instance(AppIdInspector* ins)
 {
-    static THREAD_LOCAL ServiceDiscovery* discovery_manager = nullptr;
-    if (!new_manager_test)
-    {
-        delete discovery_manager;
-        discovery_manager = nullptr;
-    }
-    else if (!discovery_manager)
-        discovery_manager = new ServiceDiscovery(*ins);
-    return *discovery_manager;
+    static ServiceDiscovery discovery_manager(*ins);
+    return discovery_manager;
 }
 
 TEST_GROUP(service_state_tests)
@@ -130,7 +123,6 @@ TEST_GROUP(service_state_tests)
 TEST(service_state_tests, select_detector_by_brute_force)
 {
     ServiceDiscoveryState sds;
-    new_manager_test = true;
     AppIdInspector ins;
     ServiceDiscovery::get_instance(&ins);
 
@@ -146,9 +138,6 @@ TEST(service_state_tests, select_detector_by_brute_force)
     test_log[0] = '\0';
     sds.select_detector_by_brute_force(IpProtocol::IP);
     STRCMP_EQUAL(test_log, "");
-
-    new_manager_test = false;
-    delete &ServiceDiscovery::get_instance();
 }
 
 TEST(service_state_tests, set_service_id_failed)
@@ -157,7 +146,6 @@ TEST(service_state_tests, set_service_id_failed)
     AppIdInspector inspector;
     AppIdSession asd(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
     SfIp client_ip;
-    new_manager_test = true;
     AppIdInspector ins;
     ServiceDiscovery::get_instance(&ins);
 
@@ -169,9 +157,6 @@ TEST(service_state_tests, set_service_id_failed)
     sds.set_service_id_failed(asd, &client_ip, 0);
     sds.set_service_id_failed(asd, &client_ip, 0);
     CHECK_TRUE(sds.get_state() == SERVICE_ID_STATE::SEARCHING_PORT_PATTERN);
-
-    new_manager_test = false;
-    delete &ServiceDiscovery::get_instance();
 }
 
 
@@ -181,7 +166,6 @@ TEST(service_state_tests, set_service_id_failed_with_valid)
     AppIdInspector inspector;
     AppIdSession asd(IpProtocol::PROTO_NOT_SET, nullptr, 0, inspector);
     SfIp client_ip;
-    new_manager_test = true;
     AppIdInspector ins;
     ServiceDiscovery::get_instance(&ins);
 
@@ -195,9 +179,6 @@ TEST(service_state_tests, set_service_id_failed_with_valid)
     sds.set_service_id_failed(asd, &client_ip, 0);
     sds.set_service_id_failed(asd, &client_ip, 0);
     CHECK_TRUE(sds.get_state() == SERVICE_ID_STATE::VALID);
-
-    new_manager_test = false;
-    delete &ServiceDiscovery::get_instance();
 }
 
 int main(int argc, char** argv)