}
#ifdef ENABLE_APPID_THIRD_PARTY
- TPLibHandler::pinit(mod_config);
+ // do not reload third party on reload_config()
+ if (!tp_appid_ctxt)
+ tp_appid_ctxt = TPLibHandler::create_tp_appid_ctxt(*mod_config);
#endif
map_app_names_to_snort_ids(sc);
return true;
}
+#ifdef ENABLE_APPID_THIRD_PARTY
+void AppIdConfig::create_tp_appid_ctxt()
+{
+ tp_appid_ctxt = TPLibHandler::create_tp_appid_ctxt(*mod_config);
+}
+#endif
+
AppId AppIdConfig::get_port_service_id(IpProtocol proto, uint16_t port)
{
AppId appId;
#include "sfip/sf_ip.h"
#include "target_based/snort_protocols.h"
#include "utils/sflsq.h"
+#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_module_api.h"
+#endif
#define APP_ID_MAX_DIRS 16
#define APP_ID_PORT_ARRAY_SIZE 65536
AppIdConfig(AppIdModuleConfig* config) : mod_config(config)
{ }
+ ~AppIdConfig()
+ {
+#ifdef ENABLE_APPID_THIRD_PARTY
+ delete tp_appid_ctxt;
+#endif
+ }
+
+#ifdef ENABLE_APPID_THIRD_PARTY
+ ThirdPartyAppIDModule* get_tp_appid_ctxt() const
+ { return tp_appid_ctxt; }
+
+ void create_tp_appid_ctxt();
+#endif
+
bool init_appid(snort::SnortConfig*);
static void pterm();
void show();
// FIXIT-M: RELOAD - Remove static, once app_info_mgr cleanup is
// removed from AppIdConfig::pterm
static AppInfoManager& app_info_mgr;
+#ifdef ENABLE_APPID_THIRD_PARTY
+ ThirdPartyAppIDModule* tp_appid_ctxt = nullptr;
+#endif
};
#endif
return APPID_EINVALID;
}
-void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
+#ifdef ENABLE_APPID_THIRD_PARTY
+void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector,
+ ThirdPartyAppIDModule* tp_appid_ctxt)
+#else
+ void AppIdDiscovery::do_application_discovery(Packet* p, AppIdInspector& inspector)
+#endif
{
IpProtocol protocol = IpProtocol::PROTO_NOT_SET;
AppidSessionDirection direction = APP_ID_FROM_INITIATOR;
AppId payload_id = APP_ID_NONE;
AppId misc_id = APP_ID_NONE;
AppidChangeBits change_bits;
- bool is_discovery_done = do_discovery(p, *asd, protocol, direction, service_id, client_id,
- payload_id, misc_id, change_bits);
+#ifdef ENABLE_APPID_THIRD_PARTY
+ bool is_discovery_done = do_discovery(p, *asd, protocol, direction, service_id,
+ client_id, payload_id, misc_id, change_bits, tp_appid_ctxt);
+#else
+ bool is_discovery_done = do_discovery(p, *asd, protocol, direction, service_id,
+ client_id, payload_id, misc_id, change_bits);
+#endif
do_post_discovery(p, *asd, direction, is_discovery_done, service_id, client_id, payload_id,
misc_id, change_bits);
return false;
}
-bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd, IpProtocol protocol,
- AppidSessionDirection direction, AppId& service_id, AppId& client_id, AppId& payload_id,
- AppId& misc_id, AppidChangeBits& change_bits)
+#ifdef ENABLE_APPID_THIRD_PARTY
+bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd,
+ IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+ AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits,
+ ThirdPartyAppIDModule* tp_appid_ctxt)
+#else
+bool AppIdDiscovery::do_discovery(Packet* p, AppIdSession& asd,
+ IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+ AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits)
+#endif
{
bool is_discovery_done = false;
// Third party detection
#ifdef ENABLE_APPID_THIRD_PARTY
- if ( TPLibHandler::have_tp() )
- is_discovery_done = do_tp_discovery(asd, protocol, p, direction, change_bits);
+ if (tp_appid_ctxt)
+ {
+ // Skip third-party inspection for sessions using old config
+ if ((asd.tpsession and asd.tpsession->get_ctxt() == tp_appid_ctxt) || !asd.tpsession)
+ is_discovery_done = do_tp_discovery(*tp_appid_ctxt, asd, protocol, p,
+ direction, change_bits);
+ }
#endif
// Port-based service detection
class AppIdDetector;
class ServiceDetector;
struct ServiceDetectorPort;
+class ThirdPartyAppIDModule;
namespace snort
{
int position, unsigned nocase);
virtual int add_service_port(AppIdDetector*, const ServiceDetectorPort&);
+#ifdef ENABLE_APPID_THIRD_PARTY
+ static void do_application_discovery(snort::Packet* p, AppIdInspector&,
+ ThirdPartyAppIDModule*);
+#else
static void do_application_discovery(snort::Packet* p, AppIdInspector&);
+#endif
static void publish_appid_event(AppidChangeBits&, snort::Flow*);
AppIdDetectors* get_tcp_detectors()
private:
static bool do_pre_discovery(snort::Packet* p, AppIdSession** p_asd, AppIdInspector& inspector,
IpProtocol& protocol, AppidSessionDirection& direction);
- static bool do_discovery(snort::Packet* p, AppIdSession& asd, IpProtocol protocol,
- AppidSessionDirection direction, AppId& service_id, AppId& client_id, AppId& payload_id,
- AppId& misc_id, AppidChangeBits& change_bits);
+#ifdef ENABLE_APPID_THIRD_PARTY
+ static bool do_discovery(snort::Packet* p, AppIdSession& asd,
+ IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+ AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits,
+ ThirdPartyAppIDModule* tp_appid_ctxt);
+#else
+ static bool do_discovery(snort::Packet* p, AppIdSession& asd,
+ IpProtocol protocol, AppidSessionDirection direction, AppId& service_id, AppId& client_id,
+ AppId& payload_id, AppId& misc_id, AppidChangeBits& change_bits);
+#endif
static void do_post_discovery(snort::Packet* p, AppIdSession& asd,
AppidSessionDirection direction, bool is_discovery_done, AppId service_id, AppId client_id,
AppId payload_id, AppId misc_id, AppidChangeBits& change_bits);
#include "service_plugins/service_discovery.h"
#include "service_plugins/service_ssl.h"
#ifdef ENABLE_APPID_THIRD_PARTY
+#include "tp_appid_module_api.h"
#include "tp_lib_handler.h"
#endif
using namespace snort;
+#ifdef ENABLE_APPID_THIRD_PARTY
+THREAD_LOCAL ThirdPartyAppIDModule* tp_appid_thread_ctxt = nullptr;
+#endif
static THREAD_LOCAL PacketTracer::TracerMute appid_mute;
// FIXIT-L - appid cleans up openssl now as it is the primary (only) user... eventually this
active_config->init_appid(sc);
#ifdef ENABLE_APPID_THIRD_PARTY
- if (!TPLibHandler::have_tp())
+ if (!active_config->get_tp_appid_ctxt())
#endif
{
DataBus::subscribe_global(HTTP_REQUEST_HEADER_EVENT_KEY, new HttpEventHandler(
appidDebug = new AppIdDebug();
if (active_config->mod_config and active_config->mod_config->log_all_sessions)
appidDebug->set_enabled(true);
-#ifdef ENABLE_APPID_THIRD_PARTY
- TPLibHandler::tinit();
-#endif
}
void AppIdInspector::tterm()
delete appidDebug;
appidDebug = nullptr;
#ifdef ENABLE_APPID_THIRD_PARTY
- TPLibHandler::tterm();
+ ThirdPartyAppIDModule* tp_appid_ctxt = active_config->get_tp_appid_ctxt();
+ if (tp_appid_ctxt)
+ tp_appid_ctxt->tfini();
#endif
}
Profile profile(appid_perf_stats);
appid_stats.packets++;
+#ifdef ENABLE_APPID_THIRD_PARTY
+ ThirdPartyAppIDModule* tp_appid_ctxt = active_config->get_tp_appid_ctxt();
+ if (tp_appid_thread_ctxt != tp_appid_ctxt)
+ {
+ if (tp_appid_thread_ctxt)
+ {
+ tp_appid_thread_ctxt->tfini();
+
+ // FIXIT-H: Assuming one packet thread
+ delete tp_appid_thread_ctxt;
+ }
+ tp_appid_ctxt->tinit();
+ tp_appid_thread_ctxt = tp_appid_ctxt;
+ }
+#endif
+
if (p->flow)
{
+#ifdef ENABLE_APPID_THIRD_PARTY
+ AppIdDiscovery::do_application_discovery(p, *this, tp_appid_thread_ctxt);
+#else
AppIdDiscovery::do_application_discovery(p, *this);
+#endif
// FIXIT-L tag verdict reason as appid for daq
if (PacketTracer::is_active())
add_appid_to_packet_trace(*p->flow);
static void appid_inspector_tterm()
{
+#ifdef ENABLE_APPID_THIRD_PARTY
+ TPLibHandler::tfini();
+#endif
AppIdPegCounts::cleanup_pegs();
}
};
+#ifdef ENABLE_APPID_THIRD_PARTY
+extern THREAD_LOCAL ThirdPartyAppIDModule* tp_appid_thread_ctxt;
+#endif
+
#endif
#include "main/snort.h"
#include "main/swapper.h"
#include "main/thread_config.h"
+#include "managers/inspector_manager.h"
#include "profiler/profiler.h"
#include "utils/util.h"
#include "app_info_table.h"
#include "appid_debug.h"
+#include "appid_inspector.h"
#include "appid_peg_counts.h"
#include "service_state.h"
static int reload_third_party(lua_State*)
{
+#ifdef ENABLE_APPID_THIRD_PARTY
if (Swapper::get_reload_in_progress())
{
LogMessage("== reload pending; retry\n");
{
Swapper::set_reload_in_progress(true);
LogMessage(".. reloading third-party");
+ AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME, true);
+ AppIdConfig* config = inspector->get_appid_config();
+ config->create_tp_appid_ctxt();
Swapper::set_reload_in_progress(false);
}
+#else
+ LogMessage("== third party is not enabled\n");
+#endif
return 0;
}
#ifdef ENABLE_APPID_THIRD_PARTY
if (tpsession)
{
- delete tpsession;
- tpsession = nullptr;
+ if (tpsession->get_ctxt() == tp_appid_thread_ctxt)
+ tpsession->delete_with_ctxt();
+ else
+ delete tpsession;
}
#endif
bool AppIdSession::is_tp_appid_done() const
{
#ifdef ENABLE_APPID_THIRD_PARTY
- if (TPLibHandler::have_tp())
+ if (config->get_tp_appid_ctxt())
{
if (!tpsession)
return false;
bool AppIdSession::is_tp_appid_available() const
{
#ifdef ENABLE_APPID_THIRD_PARTY
- if (TPLibHandler::have_tp())
+ if (config->get_tp_appid_ctxt())
{
if (!tpsession)
return false;
// FIXIT-L refactor
#define HTTP_XFF_FIELD_X_FORWARDED_FOR "X-Forwarded-For"
#define HTTP_XFF_FIELD_TRUE_CLIENT_IP "True-Client-IP"
-/* #define HTTP_MAX_XFF_FIELDS 8 */
-/* #define HTTP_XFF_FIELD_X_FORWARDED_FOR "" */
-/* #define HTTP_XFF_FIELD_TRUE_CLIENT_IP "" */
#define HTTP_MAX_XFF_FIELDS 8
std::string value;
};
-
#endif
{
return 0;
}
-bool do_tp_discovery(AppIdSession&, IpProtocol,
+bool do_tp_discovery(ThirdPartyAppIDModule& , AppIdSession&, IpProtocol,
Packet*, AppidSessionDirection&, AppidChangeBits&)
{
return true;
asd->common.initiator_ip.set("1.2.3.4");
asd->set_session_flags(APPID_SESSION_IGNORE_FLOW);
+#ifdef ENABLE_APPID_THIRD_PARTY
+ AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
// Detect changes in service, client, payload, and misc appid
CHECK_EQUAL(databus_publish_called, true);
asd->common.initiator_port = 21;
asd->common.initiator_ip.set("1.2.3.4");
+#ifdef ENABLE_APPID_THIRD_PARTY
+ AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
// Detect changes in service, client, payload, and misc appid
CHECK_EQUAL(databus_publish_called, true);
asd->client.set_id(APP_ID_CURL);
asd->service.set_id(APP_ID_FTP);
+#ifdef ENABLE_APPID_THIRD_PARTY
+ AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
// Detect event for FTP service and CURL client
CHECK_EQUAL(databus_publish_called, true);
asd->payload.set_id(APP_ID_NONE);
asd->client.set_id(APP_ID_NONE);
asd->service.set_id(APP_ID_DNS);
+#ifdef ENABLE_APPID_THIRD_PARTY
+ AppIdDiscovery::do_application_discovery(&p, ins, nullptr);
+#else
AppIdDiscovery::do_application_discovery(&p, ins);
+#endif
// Detect event for DNS service
CHECK_EQUAL(databus_publish_called, true);
config.tp_appid_config="./tp.config";
tph = TPLibHandler::get();
- tph->pinit(&config);
- CHECK_TRUE(tph->have_tp());
+ ThirdPartyAppIDModule* tpm = TPLibHandler::create_tp_appid_ctxt(config);
+ CHECK_TRUE(tpm != nullptr);
- CreateThirdPartyAppIDSession_t asf = tph->tpsession_factory();
- ThirdPartyAppIDSession* tpsession = asf();
+ TpAppIdCreateSession asf = tph->tpsession_factory();
+ ThirdPartyAppIDSession* tpsession = asf(*tpm);
CHECK_TRUE(tpsession != nullptr);
delete tpsession;
+ delete tpm;
- tph->pfini();
+ TPLibHandler::pfini();
}
TEST(tp_lib_handler, tp_lib_handler_get)
{
- tph=TPLibHandler::get();
- TPLibHandler* tph2=TPLibHandler::get();
- CHECK_EQUAL(tph,tph2);
+ tph = TPLibHandler::get();
+ TPLibHandler* tph2 = TPLibHandler::get();
+ CHECK_EQUAL(tph, tph2);
TPLibHandler::pfini();
}
AppIdModuleConfig config;
config.tp_appid_path="nonexistent.so";
TPLibHandler::get();
- TPLibHandler::pinit(&config);
- CHECK_FALSE(TPLibHandler::have_tp());
+ ThirdPartyAppIDModule* tpm = TPLibHandler::create_tp_appid_ctxt(config);
+ CHECK_TRUE(tpm == nullptr);
TPLibHandler::pfini();
}
-TEST(tp_lib_handler, tp_appid_module_pinit_error)
-{
- // Trigger MODULE pinit error:
- AppIdModuleConfig config;
- config.tp_appid_path="./libtp_mock.so";
- config.tp_appid_config=""; // forces MODULE::pinit() to return 1.
- tph=TPLibHandler::get();
- tph->pinit(&config);
- CHECK_FALSE(tph->have_tp());
- tph->pfini(1); // print stats too.
-}
-
int main(int argc, char** argv)
{
int rc = CommandLineTestRunner::RunAllTests(argc, argv);
class ThirdPartyAppIDModuleImpl : public ThirdPartyAppIDModule
{
public:
- ThirdPartyAppIDModuleImpl(uint32_t ver, const char* mname)
- : ThirdPartyAppIDModule(ver, mname)
+ ThirdPartyAppIDModuleImpl(uint32_t ver, const char* mname, ThirdPartyConfig& config)
+ : ThirdPartyAppIDModule(ver, mname, config)
{
cerr << WhereMacro << endl;
}
cerr << WhereMacro << endl;
}
- // Hack: use cfg to manipulate pinit to return 1, so we can hit the
- // if (ret != 0) case in tp_lib_handler.cc.
- int pinit(ThirdPartyConfig& cfg) override
- {
- cerr << WhereMacro << endl;
- return cfg.tp_appid_config.empty() ? 1 : 0;
- }
-
int tinit() override { return 0; }
- int reconfigure(const ThirdPartyConfig&) override { return 0; }
- int pfini() override
- {
- cerr << WhereMacro << endl;
- return 0;
- }
-
int tfini() override { return 0; }
- int print_stats() override { return 0; }
- int reset_stats() override { return 0; }
};
class ThirdPartyAppIDSessionImpl : public ThirdPartyAppIDSession
{
public:
-
+ ThirdPartyAppIDSessionImpl(ThirdPartyAppIDModule& ctxt)
+ : ThirdPartyAppIDSession(ctxt)
+ { }
bool reset() override { return 1; }
+ void delete_with_ctxt() override { delete this; }
TPState process(const Packet&, AppidSessionDirection, vector<AppId>&,
ThirdPartyAppIDAttributeData&) override { return TP_STATE_INIT; }
// once the .so has been loaded.
extern "C"
{
- SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module();
- SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session();
+ SO_PUBLIC ThirdPartyAppIDModuleImpl* tp_appid_create_ctxt(ThirdPartyConfig& config)
+ {
+ return new ThirdPartyAppIDModuleImpl(2,"foobar", config);
+ }
+
+ SO_PUBLIC ThirdPartyAppIDSessionImpl* tp_appid_create_session(ThirdPartyAppIDModule& ctxt)
+ {
+ return new ThirdPartyAppIDSessionImpl(ctxt);
+ }
- SO_PUBLIC ThirdPartyAppIDModuleImpl* create_third_party_appid_module()
+ SO_PUBLIC int tp_appid_pfini()
{
- return new ThirdPartyAppIDModuleImpl(1,"foobar");
+ return 0;
}
- SO_PUBLIC ThirdPartyAppIDSessionImpl* create_third_party_appid_session()
+ SO_PUBLIC int tp_appid_tfini()
{
- return new ThirdPartyAppIDSessionImpl;
+ return 0;
}
}
#include <string>
#include "tp_appid_types.h"
-#define THIRD_PARTY_APP_ID_API_VERSION 1
+#define THIRD_PARTY_APP_ID_API_VERSION 2
class ThirdPartyConfig
{
unsigned http_response_version_enabled : 1;
std::string tp_appid_config;
std::vector<std::string> xff_fields;
- std::vector<std::string> old_xff_fields;
bool tp_appid_stats_enable = false;
bool tp_appid_config_dump = false;
ThirdPartyConfig()
- {
- getXffFields();
- }
-
- void getXffFields()
{
xff_fields.clear();
xff_fields.emplace_back(HTTP_XFF_FIELD_X_FORWARDED_FOR);
class ThirdPartyAppIDModule
{
public:
-
- /* ThirdPartyAppIdConfig tpac; */
-
- ThirdPartyAppIDModule(uint32_t ver, const char* mname)
- : version(ver), name(mname) { }
+ ThirdPartyAppIDModule(uint32_t ver, const char* mname, ThirdPartyConfig& config)
+ : version(ver), name(mname), cfg(config) { }
virtual ~ThirdPartyAppIDModule() { }
uint32_t api_version() const { return version; }
const std::string& module_name() const { return name; }
- virtual int pinit(ThirdPartyConfig&) = 0;
- virtual int pfini() = 0;
-
virtual int tinit() = 0;
virtual int tfini() = 0;
- virtual int reconfigure(const ThirdPartyConfig&) = 0;
- virtual int print_stats() = 0;
- virtual int reset_stats() = 0;
+ virtual const ThirdPartyConfig& get_config() const { return cfg; }
-private:
+protected:
+ const uint32_t version;
+ const std::string name;
+ ThirdPartyConfig cfg;
+private:
// No implicit constructor as derived classes need to provide
// version and name.
ThirdPartyAppIDModule() : version(0), name("") { }
-
- const uint32_t version;
- const std::string name;
};
-// Function pointer to object factory that returns a pointer to a newly
-// created object of a derived class.
-// This needs to be exported (SO_PUBLIC) by any third party .so library.
-// Must return NULL if it fails to create the object.
-typedef ThirdPartyAppIDModule* (* CreateThirdPartyAppIDModule_t)();
-
#endif
struct Packet;
}
-#define THIRD_PARTY_APP_ID_API_VERSION 1
+class ThirdPartyAppIDModule;
class ThirdPartyAppIDSession
{
public:
-
- ThirdPartyAppIDSession()
- : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT) { }
+ ThirdPartyAppIDSession(ThirdPartyAppIDModule& ctxt)
+ : appid(APP_ID_NONE), confidence(100), state(TP_STATE_INIT), ctxt(ctxt) { }
virtual ~ThirdPartyAppIDSession() { }
virtual bool reset() = 0; // just reset state
+ virtual void delete_with_ctxt() = 0;
virtual TPState process(const snort::Packet&,
AppidSessionDirection direction,
std::vector<AppId>& proto_list,
virtual void set_attr(TPSessionAttr) = 0;
virtual unsigned get_attr(TPSessionAttr) = 0;
virtual AppId get_appid(int& conf) { conf=confidence; return appid; }
+ virtual const ThirdPartyAppIDModule* get_ctxt() const
+ { return &ctxt; }
protected:
AppId appid;
int confidence;
TPState state;
+ const ThirdPartyAppIDModule& ctxt;
};
-// Function pointer to object factory that returns a pointer to a newly
-// created object of a derived class.
-// This needs to be exported (SO_PUBLIC) by any third party .so library.
-// Must return NULL if it fails to create the object.
-typedef ThirdPartyAppIDSession* (* CreateThirdPartyAppIDSession_t)();
-
#endif
}
}
-bool do_tp_discovery(AppIdSession& asd, IpProtocol protocol,
+bool do_tp_discovery(ThirdPartyAppIDModule& tp_module, AppIdSession& asd, IpProtocol protocol,
Packet* p, AppidSessionDirection& direction, AppidChangeBits& change_bits)
{
AppId tp_app_id = asd.get_tp_app_id();
if (!asd.tpsession)
{
const TPLibHandler* tph = TPLibHandler::get();
- CreateThirdPartyAppIDSession_t tpsf = tph->tpsession_factory();
- if ( !(asd.tpsession = tpsf()) )
- FatalError("Could not allocate asd.tpsession data");
- } // debug output of packet content
+ TpAppIdCreateSession tpsf = tph->tpsession_factory();
+ if ( !(asd.tpsession = tpsf(tp_module)) )
+ ErrorMessage("Could not allocate asd.tpsession data");
+ }
TPState current_tp_state = asd.tpsession->process(*p, direction,
tp_proto_list, tp_attribute_data);
class AppIdSession;
-bool do_tp_discovery(
- AppIdSession&, IpProtocol, snort::Packet*, AppidSessionDirection&, AppidChangeBits&);
+bool do_tp_discovery(ThirdPartyAppIDModule& tp_module, AppIdSession&, IpProtocol, snort::Packet*,
+ AppidSessionDirection&, AppidChangeBits&);
#endif
using namespace std;
using namespace snort;
-#define TP_APPID_MODULE_SYMBOL "create_third_party_appid_module"
-#define TP_APPID_SESSION_SYMBOL "create_third_party_appid_session"
-
TPLibHandler* TPLibHandler::self = nullptr;
-int TPLibHandler::LoadCallback(const char* const path, int /* indent */)
+bool TPLibHandler::load_callback(const char* const path)
{
- void* handle = 0;
- ThirdPartyAppIDModule* tp_module = 0;
- const char* error = nullptr;
-
- if (tp_appid_module != nullptr)
- {
- ErrorMessage("Ignoring additional 3rd party AppID module (%s)!\n", path);
- return 0;
- }
-
- // Load the tp library and get function pointers to the module and
- // session object factories.
dlerror();
- handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
- if (handle == nullptr)
+ self->tp_so_handle = dlopen(path, RTLD_NOW | RTLD_LOCAL);
+ if (self->tp_so_handle == nullptr)
{
ErrorMessage("Failed to load 3rd party AppID library: %s - %s\n", path, dlerror());
- return 0;
+ return false;
}
- CreateThirdPartyAppIDModule_t createThirdPartyAppIDModule=
- (CreateThirdPartyAppIDModule_t)dlsym(handle, TP_APPID_MODULE_SYMBOL);
- if ((error=dlerror()) != nullptr)
+ typedef void (*dummyFunc)();
+ struct funcBinding
{
- ErrorMessage(
- "Failed to get 3rd party AppID module object factory: %s - %s\n",
- TP_APPID_MODULE_SYMBOL, error);
- dlclose(handle);
- return 0;
- }
-
- createThirdPartyAppIDSession=(CreateThirdPartyAppIDSession_t)dlsym(
- handle,TP_APPID_SESSION_SYMBOL);
- if ((error=dlerror()) != nullptr)
+ const char* lib_sym;
+ dummyFunc* local_sym;
+ } bindings[] =
{
- ErrorMessage(
- "Failed to get 3rd party AppID session object factory: %s - %s\n",
- TP_APPID_SESSION_SYMBOL, error);
- dlclose(handle);
- return 0;
- }
+ { "tp_appid_create_ctxt", (dummyFunc*)&tp_appid_create_ctxt },
+ { "tp_appid_create_session", (dummyFunc*)&tp_appid_create_session },
+ { "tp_appid_pfini", (dummyFunc*)&tp_appid_pfini },
+ { "tp_appid_tfini", (dummyFunc*)&tp_appid_tfini },
+ { nullptr, nullptr }
+ };
- // The tp module object is a singleton and gets created here in main thread.
- // TP session objects get created per worker thread.
- tp_module=createThirdPartyAppIDModule();
- if (tp_module == nullptr)
- {
- ErrorMessage("Failed to create third party appId module.\n");
- dlclose(handle);
- return 0;
- }
+ funcBinding* index;
- if ( (tp_module->api_version() != THIRD_PARTY_APP_ID_API_VERSION)
- || (tp_module->module_name().empty()) )
+ for (index = bindings; index->lib_sym; index++)
{
- ErrorMessage("Ignoring incomplete 3rd party AppID module (%s, %u, %s)!\n",
- path, tp_module->api_version(),
- tp_module->module_name().empty() ? "empty" : tp_module->module_name().c_str());
-
- dlclose(handle);
- delete tp_module;
- return 0;
+ *(void**)index->local_sym = dlsym(self->tp_so_handle, index->lib_sym);
+ if (*(index->local_sym) == nullptr)
+ {
+ char* error;
+ ErrorMessage("AppId: Failed to resolve symbol: %s %s\n", index->lib_sym,
+ (error = dlerror()) ? error : "");
+ dlclose(self->tp_so_handle);
+ self->tp_so_handle = nullptr;
+ return false;
+ }
}
- this->tp_so_handle = handle;
- tp_appid_module = tp_module;
- return 0;
+ return true;
}
-void TPLibHandler::pinit(const AppIdModuleConfig* config)
+ThirdPartyAppIDModule* TPLibHandler::create_tp_appid_ctxt(const AppIdModuleConfig& config)
{
- int ret;
-
- if (self->tp_so_handle or config->tp_appid_path.empty())
- return;
-
- self->tp_config.tp_appid_config = config->tp_appid_config;
- self->tp_config.tp_appid_stats_enable = config->tp_appid_stats_enable;
- self->tp_config.tp_appid_config_dump = config->tp_appid_config_dump;
+ assert(self != nullptr);
- self->LoadCallback(config->tp_appid_path.c_str(),1);
-
- if (self->tp_appid_module == nullptr)
+ if (!self->tp_so_handle)
{
- ErrorMessage("Ignoring third party AppId library\n");
- return;
+ if (config.tp_appid_path.empty())
+ return nullptr;
+
+ if (!self->load_callback(config.tp_appid_path.c_str()))
+ return nullptr;
}
- self->tp_config.chp_body_collection_max = config->chp_body_collection_max;
- self->tp_config.ftp_userid_disabled = config->ftp_userid_disabled;
- self->tp_config.chp_body_collection_disabled =
- config->chp_body_collection_disabled;
- self->tp_config.tp_allow_probes = config->tp_allow_probes;
- if (config->http2_detection_enabled)
- self->tp_config.http_upgrade_reporting_enabled = 1;
+ ThirdPartyConfig tp_config;
+ tp_config.tp_appid_config = config.tp_appid_config;
+ tp_config.tp_appid_stats_enable = config.tp_appid_stats_enable;
+ tp_config.tp_appid_config_dump = config.tp_appid_config_dump;
+ tp_config.chp_body_collection_max = config.chp_body_collection_max;
+ tp_config.ftp_userid_disabled = config.ftp_userid_disabled;
+ tp_config.chp_body_collection_disabled =
+ config.chp_body_collection_disabled;
+ tp_config.tp_allow_probes = config.tp_allow_probes;
+ if (config.http2_detection_enabled)
+ tp_config.http_upgrade_reporting_enabled = 1;
else
- self->tp_config.http_upgrade_reporting_enabled = 0;
+ tp_config.http_upgrade_reporting_enabled = 0;
+ tp_config.http_response_version_enabled = config.http_response_version_enabled;
- self->tp_config.http_response_version_enabled = config->http_response_version_enabled;
+ ThirdPartyAppIDModule* tp_appid_ctxt = self->tp_appid_create_ctxt(tp_config);
+ if (tp_appid_ctxt == nullptr)
+ {
+ ErrorMessage("Failed to create third party appId context.\n");
+ dlclose(self->tp_so_handle);
+ self->tp_so_handle = nullptr;
+ return nullptr;
+ }
- ret = self->tp_appid_module->pinit(self->tp_config);
- if (ret != 0)
+ if ( (tp_appid_ctxt->api_version() != THIRD_PARTY_APP_ID_API_VERSION)
+ || (tp_appid_ctxt->module_name().empty()) )
{
- ErrorMessage("Unable to initialize 3rd party AppID module (%d)!\n", ret);
- delete self->tp_appid_module;
+ ErrorMessage("Ignoring incomplete 3rd party AppID module (%s, %u, %s)!\n",
+ config.tp_appid_path.c_str(), tp_appid_ctxt->api_version(),
+ tp_appid_ctxt->module_name().empty() ? "empty" : tp_appid_ctxt->module_name().c_str());
+
+ delete tp_appid_ctxt;
dlclose(self->tp_so_handle);
self->tp_so_handle = nullptr;
- self->tp_appid_module = nullptr;
- return;
+ return nullptr;
}
+
+ return tp_appid_ctxt;
}
-void TPLibHandler::pfini(bool print_stats_flag)
+void TPLibHandler::tfini()
{
- if (self and self->tp_appid_module != nullptr)
- {
- if (print_stats_flag)
- self->tp_appid_module->print_stats();
+ assert(self != nullptr);
- int ret = self->tp_appid_module->pfini();
+ int ret = 0;
- if (ret != 0)
- ErrorMessage("Could not finalize 3rd party AppID module (%d)!\n", ret);
+ if (self->tp_appid_tfini)
+ ret = self->tp_appid_tfini();
- delete self->tp_appid_module;
- self->tp_appid_module = nullptr;
+ if (ret != 0)
+ ErrorMessage("Could not terminate packet thread in 3rd party AppID module (%d)!\n", ret);
+}
- dlclose(self->tp_so_handle); // after delete, otherwise tpam will be dangling
- self->tp_so_handle = nullptr;
- }
+void TPLibHandler::pfini()
+{
+ assert(self != nullptr);
+
+ int ret = 0;
+
+ if (self->tp_appid_pfini)
+ ret = self->tp_appid_pfini();
+
+ if (ret != 0)
+ ErrorMessage("Could not terminate 3rd party AppID module (%d)!\n", ret);
+
+ // FIXIT-L: Find the right place to dlclose self->tp_so_handle. dlclose here was causing
+ // segfault
if ( self ) {
delete self;
class AppIdModuleConfig;
-// Class responsible for loading/reloading the thirdparty.so library and
-// for holding pointers to objects that live inside thirdparty.so.
+// This needs to be exported by any third party .so library.
+// Must return NULL if it fails to create the object.
+typedef ThirdPartyAppIDModule* (* TpAppIdCreateCtxt)(ThirdPartyConfig& );
+typedef ThirdPartyAppIDSession* (* TpAppIdCreateSession)(ThirdPartyAppIDModule& ctxt);
+typedef int (* TpAppIdPfini)();
+typedef int (* TpAppIdTfini)();
+
+// Class responsible for loading/reloading the thirdparty.so library
class TPLibHandler
{
public:
-
- static bool have_tp()
- {
- return self and self->tp_appid_module != nullptr;
- }
-
static TPLibHandler* get()
{
if (self)
return self;
else
- return (self=new TPLibHandler());
+ return (self = new TPLibHandler());
}
- // called from appid_inspector.cc appid_inspector_pinit() / pterm()
- static void pinit(const AppIdModuleConfig* config);
- static void pfini(bool print_stats_flag=0);
+ static ThirdPartyAppIDModule* create_tp_appid_ctxt(const AppIdModuleConfig& config);
+ static void tfini();
+ static void pfini();
- // called from AppIdInspector tinit/tterm via
- // AppIdConfig::tp_appid_module_tinit/tterm.
- static void tinit() { if ( have_tp() ) self->tp_appid_module->tinit(); }
- static void tterm() { if ( have_tp() ) self->tp_appid_module->tfini(); }
-
- CreateThirdPartyAppIDSession_t tpsession_factory() const
+ TpAppIdCreateSession tpsession_factory() const
{
- return createThirdPartyAppIDSession;
+ return tp_appid_create_session;
}
private:
-
TPLibHandler() = default;
~TPLibHandler() = default;
static TPLibHandler* self;
void* tp_so_handle = nullptr; // output of dlopen(thirdparty.so)
- ThirdPartyAppIDModule* tp_appid_module = nullptr;
- CreateThirdPartyAppIDSession_t createThirdPartyAppIDSession;
-
- ThirdPartyConfig tp_config;
+ TpAppIdCreateCtxt tp_appid_create_ctxt = nullptr;
+ TpAppIdCreateSession tp_appid_create_session = nullptr;
+ TpAppIdPfini tp_appid_pfini = nullptr;
+ TpAppIdTfini tp_appid_tfini = nullptr;
- int LoadCallback(const char* path, int);
+ bool load_callback(const char* path);
};
#endif