virtual int prep_patterns(SnortConfig*) = 0;
+ virtual void reuse_search() { }
+
int search(
const uint8_t* T, int n, MpseMatch, void* context, int* current_state);
if (!odp_thread_local_ctxt)
odp_thread_local_ctxt = new OdpThreadContext(true);
- // FIXIT-M: RELOAD - Get rid of "once" flag
- // Handle the if condition in AppIdContext::init_appid
static bool once = false;
if (!once)
{
tp_appid_ctxt = TPLibHandler::create_tp_appid_ctxt(config, *odp_ctxt);
once = true;
}
+ else
+ {
+ odp_ctxt->get_client_disco_mgr().reload();
+ odp_ctxt->get_service_disco_mgr().reload();
+ odp_ctxt->reload();
+ }
map_app_names_to_snort_ids(sc, config);
return true;
service_pattern_detector->finalize_service_port_patterns();
client_pattern_detector->finalize_client_port_patterns();
service_disco_mgr.finalize_service_patterns();
- client_disco_mgr.finalize_client_plugins();
+ client_disco_mgr.finalize_client_patterns();
http_matchers.finalize_patterns();
// sip patterns need to be finalized after http patterns because they
// are dependent on http patterns
dns_matchers.finalize_patterns();
}
+void OdpContext::reload()
+{
+ assert(service_pattern_detector);
+ service_pattern_detector->reload_service_port_patterns();
+ assert(client_pattern_detector);
+ client_pattern_detector->reload_client_port_patterns();
+ service_disco_mgr.reload_service_patterns();
+ client_disco_mgr.reload_client_patterns();
+ http_matchers.reload_patterns();
+ sip_matchers.reload_patterns();
+ ssl_matchers.reload_patterns();
+ dns_matchers.reload_patterns();
+}
+
void OdpContext::add_port_service_id(IpProtocol proto, uint16_t port, AppId appid)
{
if (proto == IpProtocol::TCP)
OdpContext(const AppIdConfig&, snort::SnortConfig*);
~OdpContext();
void initialize();
+ void reload();
uint32_t get_version() const
{
if (!appid_registry.empty())
{
- // FIXIT-M: RELOAD - to support ODP reload, store ODP context in AppIdDetector
AppIdInspector* inspector = (AppIdInspector*) InspectorManager::get_inspector(MOD_NAME);
assert(inspector);
AppIdContext& ctxt = inspector->get_ctxt();
return APPID_SUCCESS;
}
+void AppIdDetector::reload()
+{
+ do_custom_reload();
+}
+
void* AppIdDetector::data_get(AppIdSession& asd)
{
return asd.get_flow_data(flow_data_index);
virtual ~AppIdDetector() = default;
virtual int initialize();
- virtual void do_custom_init() = 0;
+ virtual void reload();
+ virtual void do_custom_init() { }
+ virtual void do_custom_reload() { }
virtual int validate(AppIdDiscoveryArgs&) = 0;
virtual void register_appid(AppId, unsigned extractsInfo, OdpContext& odp_ctxt) = 0;
#include "tp_appid_utils.h"
using namespace snort;
-AppIdDiscovery::AppIdDiscovery()
-{
- tcp_patterns = new SearchTool;
- udp_patterns = new SearchTool;
-}
-
AppIdDiscovery::~AppIdDiscovery()
{
for (auto pd : pattern_data)
pattern_data.clear();
- delete tcp_patterns;
- delete udp_patterns;
-
for (auto kv : tcp_detectors)
delete kv.second;
ErrorMessage("Detector %s has unsupported protocol %u", name.c_str(), (unsigned)proto);
}
-void AppIdDiscovery::add_pattern_data(AppIdDetector* detector, SearchTool* st, int position, const
+void AppIdDiscovery::add_pattern_data(AppIdDetector* detector, SearchTool& st, int position, const
uint8_t* const pattern, unsigned size, unsigned nocase)
{
AppIdPatternMatchNode* pd = new AppIdPatternMatchNode(detector, position, size);
pattern_data.emplace_back(pd);
- st->add((const char*)pattern, size, pd, nocase);
+ st.add((const char*)pattern, size, pd, nocase);
}
void AppIdDiscovery::register_tcp_pattern(AppIdDetector* detector, const uint8_t* const pattern,
class AppIdDiscovery
{
public:
- AppIdDiscovery();
+ AppIdDiscovery() { }
virtual ~AppIdDiscovery();
AppIdDiscovery(const AppIdDiscovery&) = delete;
static void tterm();
virtual void initialize() = 0;
+ virtual void reload() = 0;
virtual void register_detector(const std::string&, AppIdDetector*, IpProtocol);
- virtual void add_pattern_data(AppIdDetector*, snort::SearchTool*, int position,
+ virtual void add_pattern_data(AppIdDetector*, snort::SearchTool&, int position,
const uint8_t* const pattern, unsigned size, unsigned nocase);
virtual void register_tcp_pattern(AppIdDetector*, const uint8_t* const pattern, unsigned size,
int position, unsigned nocase);
protected:
AppIdDetectors tcp_detectors;
AppIdDetectors udp_detectors;
- snort::SearchTool* tcp_patterns = nullptr;
+ snort::SearchTool tcp_patterns;
int tcp_pattern_count = 0;
- snort::SearchTool* udp_patterns = nullptr;
+ snort::SearchTool udp_patterns;
int udp_pattern_count = 0;
std::vector<AppIdPatternMatchNode*> pattern_data;
return rvalue;
}
+void mlmp_reload_patterns(tMlmpTree& root)
+{
+ assert(root.patternTree);
+ root.patternTree->reload();
+}
+
void* mlmpMatchPatternUrl(tMlmpTree* root, tMlmpPattern* inputPatternList)
{
return mlmpMatchPatternCustom(root, inputPatternList, urlPatternSelector);
tMlmpTree* mlmpCreate();
int mlmpAddPattern(tMlmpTree*, const tMlmpPattern*, void* metaData);
int mlmpProcessPatterns(tMlmpTree*);
+void mlmp_reload_patterns(tMlmpTree&);
void* mlmpMatchPatternUrl(tMlmpTree*, tMlmpPattern*);
void* mlmpMatchPatternGeneric(tMlmpTree*, tMlmpPattern*);
void mlmpDestroy(tMlmpTree*);
public:
ClientDetector();
- void do_custom_init() override { }
void register_appid(AppId, unsigned extractsInfo, OdpContext& odp_ctxt) override;
};
#endif
kv.second->initialize();
}
-void ClientDiscovery::finalize_client_plugins()
+void ClientDiscovery::reload()
{
- if ( tcp_patterns )
- tcp_patterns->prep();
+ for ( auto kv : tcp_detectors )
+ kv.second->reload();
+ for ( auto kv : udp_detectors )
+ kv.second->reload();
+}
- if ( udp_patterns )
- udp_patterns->prep();
+void ClientDiscovery::finalize_client_patterns()
+{
+ tcp_patterns.prep();
+ udp_patterns.prep();
+}
+
+void ClientDiscovery::reload_client_patterns()
+{
+ tcp_patterns.reload();
+ udp_patterns.reload();
}
/*
SearchTool* patterns;
if (asd.protocol == IpProtocol::TCP)
- patterns = asd.get_odp_ctxt().get_client_disco_mgr().tcp_patterns;
+ patterns = &asd.get_odp_ctxt().get_client_disco_mgr().tcp_patterns;
else
- patterns = asd.get_odp_ctxt().get_client_disco_mgr().udp_patterns;
+ patterns = &asd.get_odp_ctxt().get_client_disco_mgr().udp_patterns;
if ( patterns )
patterns->find_all((const char*)pkt->data, pkt->dsize, &pattern_match, false, (void*)&match_list);
{
public:
void initialize() override;
+ void reload() override;
- void finalize_client_plugins();
+ void finalize_client_patterns();
+ void reload_client_patterns();
bool do_client_discovery(AppIdSession&, snort::Packet*,
AppidSessionDirection direction, AppidChangeBits& change_bits);
#include <CppUTestExt/MockSupport.h>
void ServiceDiscovery::initialize() {}
+void ServiceDiscovery::reload() {}
int ServiceDiscovery::fail_service(AppIdSession&, const Packet*, AppidSessionDirection,
ServiceDetector*, ServiceDiscoveryState*) { return 0; }
int ServiceDiscovery::add_service_port(AppIdDetector*,
HttpPatternMatchers::~HttpPatternMatchers() { }
DnsPatternMatchers::~DnsPatternMatchers() { }
void ClientDiscovery::initialize() {}
+void ClientDiscovery::reload() {}
int AppIdDetector::initialize(){return 0;}
+void AppIdDetector::reload() { }
int AppIdDetector::data_add(AppIdSession&, void*, AppIdFreeFCN){return 0;}
void* AppIdDetector::data_get(AppIdSession&) {return nullptr;}
void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool){}
void AppIdDetector::add_payload(AppIdSession&, AppId){}
void AppIdDetector::add_app(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppId, const char*, AppidChangeBits&){}
-void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool*, int,
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int,
const uint8_t* const, unsigned, unsigned){}
void AppIdDiscovery::register_detector(const std::string&, AppIdDetector*, IpProtocol){}
void add_pattern_data(AppIdDetector*, snort::SearchTool*, int,
int AppIdDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&){return 0;}
void ApplicationDescriptor::set_id(const snort::Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&){}
void ApplicationDescriptor::set_id(AppId){}
-AppIdDiscovery::AppIdDiscovery() { }
AppIdDiscovery::~AppIdDiscovery() { }
void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
void show_stats(PegCount*, const PegInfo*, const IndexVec&, const char*, FILE*) { }
cmd_matcher->prep();
}
+void ImapClientDetector::do_custom_reload()
+{
+ assert(cmd_matcher);
+ cmd_matcher->reload();
+}
+
static int pattern_match(void* id, void*, int match_end_pos, void* data, void*)
{
unsigned long idx = (unsigned long)id;
~ImapClientDetector() override;
void do_custom_init() override;
+ void do_custom_reload() override;
int validate(AppIdDiscoveryArgs&) override;
ImapDetectorData* get_common_data(AppIdSession&);
}
}
-static void register_pattern(SearchTool** patterns, Pattern* pattern)
+static void register_pattern(SearchTool*& patterns, Pattern* pattern)
{
- if (!*patterns)
+ if (!patterns)
{
- *patterns = new SearchTool;
- if (!*patterns)
- {
- ErrorMessage("Error initializing the pattern table\n");
- return;
- }
+ patterns = new SearchTool;
}
- (*patterns)->add((char*)pattern->data, pattern->length, pattern, false);
+ patterns->add((char*)pattern->data, pattern->length, pattern, false);
}
struct PServiceMatch
for (PortNode* port = ps->port; port; port = port->next)
for (Pattern* pattern = ps->pattern; pattern; pattern = pattern->next)
if (ps->proto == IpProtocol::TCP)
- register_pattern(&tcp_port_pattern_tree[port->port],
+ register_pattern(tcp_port_pattern_tree[port->port],
pattern);
else
- register_pattern(&udp_port_pattern_tree[port->port],
+ register_pattern(udp_port_pattern_tree[port->port],
pattern);
for (unsigned i = 0; i < 65536; i++)
continue;
for (Pattern* pattern = ps->pattern; pattern; pattern = pattern->next)
- register_pattern(&tcp_port_pattern_tree[i], pattern);
+ register_pattern(tcp_port_pattern_tree[i], pattern);
}
tcp_port_pattern_tree[i]->prep();
continue;
for (Pattern* pattern = ps->pattern; pattern; pattern = pattern->next)
- register_pattern(&udp_port_pattern_tree[i], pattern);
+ register_pattern(udp_port_pattern_tree[i], pattern);
}
udp_port_pattern_tree[i]->prep();
{
handler->register_tcp_pattern(this, pattern->data, pattern->length,
pattern->offset, 0);
- register_pattern(&tcp_pattern_matcher, pattern);
+ register_pattern(tcp_pattern_matcher, pattern);
}
else
{
handler->register_udp_pattern(this, pattern->data, pattern->length,
pattern->offset, 0);
- register_pattern(&udp_pattern_matcher, pattern);
+ register_pattern(udp_pattern_matcher, pattern);
}
}
}
dump_patterns("Server", service_port_pattern);
}
+void PatternServiceDetector::reload_service_port_patterns()
+{
+ for (unsigned i = 0; i < 65536; i++)
+ {
+ if (tcp_port_pattern_tree[i])
+ tcp_port_pattern_tree[i]->reload();
+
+ if (udp_port_pattern_tree[i])
+ udp_port_pattern_tree[i]->reload();
+ }
+
+ if (tcp_pattern_matcher)
+ tcp_pattern_matcher->reload();
+
+ if (udp_pattern_matcher)
+ udp_pattern_matcher->reload();
+}
+
PatternServiceDetector::PatternServiceDetector(ServiceDiscovery* sd)
{
handler = sd;
for ( Pattern* pattern = ps->pattern; pattern; pattern = pattern->next)
{
if (ps->proto == IpProtocol::TCP)
- register_pattern(&tcp_pattern_matcher, pattern);
+ register_pattern(tcp_pattern_matcher, pattern);
else
- register_pattern(&udp_pattern_matcher, pattern);
+ register_pattern(udp_pattern_matcher, pattern);
}
}
}
{
handler->register_tcp_pattern(this, pattern->data, pattern->length,
pattern->offset, 0);
- register_pattern(&tcp_pattern_matcher, pattern);
+ register_pattern(tcp_pattern_matcher, pattern);
}
else
{
handler->register_udp_pattern(this, pattern->data, pattern->length,
pattern->offset, 0);
- register_pattern(&udp_pattern_matcher, pattern);
+ register_pattern(udp_pattern_matcher, pattern);
}
}
ps->count++;
dump_patterns("Client", service_port_pattern);
}
+void PatternClientDetector::reload_client_port_patterns()
+{
+ if (tcp_pattern_matcher)
+ tcp_pattern_matcher->reload();
+
+ if (udp_pattern_matcher)
+ udp_pattern_matcher->reload();
+}
+
void insert_client_port_pattern(PortPatternNode*);
void finalize_client_port_patterns();
+ void reload_client_port_patterns();
int validate(AppIdDiscoveryArgs&) override;
void insert_service_port_pattern(PortPatternNode*);
void finalize_service_port_patterns();
+ void reload_service_port_patterns();
int validate(AppIdDiscoveryArgs&) override;
cmd_matcher->prep();
}
+void Pop3ClientDetector::do_custom_reload()
+{
+ assert(cmd_matcher);
+ cmd_matcher->reload();
+}
+
static int pop3_pattern_match(void* id, void*, int match_end_pos, void* data, void*)
{
unsigned long idx = (unsigned long)id;
~Pop3ClientDetector() override;
void do_custom_init() override;
+ void do_custom_reload() override;
int validate(AppIdDiscoveryArgs&) override;
POP3DetectorData* get_common_data(AppIdSession&);
dns_host_matcher.prep();
}
+void DnsPatternMatchers::reload_patterns()
+{
+ dns_host_matcher.reload();
+}
+
DnsPatternMatchers::~DnsPatternMatchers()
{
DnsHostPatternList* tmp_pattern;
~DnsPatternMatchers();
void add_host_pattern(uint8_t*, size_t, uint8_t, AppId);
void finalize_patterns();
+ void reload_patterns();
int scan_hostname(const uint8_t*, size_t, AppId&, AppId&);
private:
free_http_patterns(content_type_patterns);
free_chp_app_elements();
- delete field_matcher;
-
- for (size_t i = 0; i < NUM_HTTP_FIELDS; i++)
- delete chp_matchers[i];
-
for (auto* pattern : host_url_patterns)
delete pattern;
host_url_patterns.clear();
int HttpPatternMatchers::process_chp_list(CHPListElement* chplist)
{
- for (size_t i = 0; i < NUM_HTTP_FIELDS; i++)
- chp_matchers[i] = new SearchTool;
-
for (CHPListElement* chpe = chplist; chpe; chpe = chpe->next)
- chp_matchers[chpe->chp_action.ptype]->add(chpe->chp_action.pattern,
+ chp_matchers[chpe->chp_action.ptype].add(chpe->chp_action.pattern,
chpe->chp_action.psize, &chpe->chp_action, true);
for (size_t i = 0; i < NUM_HTTP_FIELDS; i++)
- chp_matchers[i]->prep();
+ chp_matchers[i].prep();
return 1;
}
#define HTTP_FIELD_PREFIX_COOKIE "\r\nCookie: "
#define HTTP_FIELD_PREFIX_COOKIE_SIZE (sizeof(HTTP_FIELD_PREFIX_COOKIE)-1)
-typedef struct _FIELD_PATTERN
-{
- const uint8_t* data;
- HttpFieldIds patternType;
- unsigned length;
-} FieldPattern;
-
static FieldPattern http_field_patterns[] =
{
{ (const uint8_t*)HTTP_FIELD_PREFIX_URI, REQ_URI_FID, HTTP_FIELD_PREFIX_URI_SIZE },
HTTP_FIELD_PREFIX_USER_AGENT_SIZE },
};
-static SearchTool* process_http_field_patterns(FieldPattern* patternList,
+void HttpPatternMatchers::process_http_field_patterns(FieldPattern* patternList,
size_t patternListCount)
{
- SearchTool* patternMatcher = new SearchTool;
-
- for (size_t i=0; i < patternListCount; i++)
- patternMatcher->add( (const char*)patternList[i].data, patternList[i].length,
+ for (size_t i = 0; i < patternListCount; i++)
+ field_matcher.add( (const char*)patternList[i].data, patternList[i].length,
&patternList[i], false);
- patternMatcher->prep();
- return patternMatcher;
+ field_matcher.prep();
}
static void process_patterns(SearchTool& matcher, DetectorHTTPPatterns& patterns, bool
process_patterns(content_type_matcher, content_type_patterns);
uint32_t numPatterns = sizeof(http_field_patterns) / sizeof(*http_field_patterns);
- field_matcher = process_http_field_patterns(http_field_patterns, numPatterns);
+ process_http_field_patterns(http_field_patterns, numPatterns);
process_chp_list(chpList);
return 0;
}
+void HttpPatternMatchers::reload_patterns()
+{
+ via_matcher.reload();
+ url_matcher.reload();
+ client_agent_matcher.reload();
+ assert(host_url_matcher);
+ mlmp_reload_patterns(*host_url_matcher);
+ assert(rtmp_host_url_matcher);
+ mlmp_reload_patterns(*rtmp_host_url_matcher);
+ content_type_matcher.reload();
+ field_matcher.reload();
+ for (size_t i = 0; i < NUM_HTTP_FIELDS; i++)
+ chp_matchers[i].reload();
+}
+
typedef struct fieldPatternData_t
{
const uint8_t* payload;
headerEnd += crlfcrlfLen;
patternMatchData.length = (unsigned)(headerEnd - pkt->data);
- field_matcher->find_all((const char*)pkt->data, patternMatchData.length,
+ field_matcher.find_all((const char*)pkt->data, patternMatchData.length,
&http_field_pattern_match, false, (void*)(&patternMatchData));
}
void HttpPatternMatchers::scan_key_chp(ChpMatchDescriptor& cmd)
{
unsigned i = cmd.cur_ptype;
- chp_matchers[i]->find_all(cmd.buffer[i], cmd.length[i], &chp_key_pattern_match,
+ chp_matchers[i].find_all(cmd.buffer[i], cmd.length[i], &chp_key_pattern_match,
false, (void*)&cmd);
cmd.sort_chp_matches();
}
if ( pt > MAX_KEY_PATTERN )
{
// There is no previous attempt to match generated by scan_key_chp()
- chp_matchers[pt]->find_all(cmd.buffer[pt], cmd.length[pt], &chp_pattern_match, false,
+ chp_matchers[pt].find_all(cmd.buffer[pt], cmd.length[pt], &chp_pattern_match, false,
(void*)&cmd);
}
USER_AGENT_HEADER = 5
};
+struct FieldPattern
+{
+ const uint8_t* data;
+ HttpFieldIds patternType;
+ unsigned length;
+};
+
struct DetectorHTTPPattern
{
bool init(const uint8_t* pat, unsigned len, DHPSequence seq, AppId service, AppId client, AppId payload, AppId app)
~HttpPatternMatchers();
int finalize_patterns();
+ void reload_patterns();
void insert_chp_pattern(CHPListElement*);
void insert_http_pattern(enum httpPatternType, DetectorHTTPPattern&);
void remove_http_patterns_for_id(AppId);
int process_chp_list(CHPListElement*);
int process_host_patterns(DetectorHTTPPatterns&);
int process_mlmp_patterns();
+ void process_http_field_patterns(FieldPattern*, size_t);
void scan_key_chp(ChpMatchDescriptor&);
AppId scan_chp(ChpMatchDescriptor&, char**, char**, int*, AppIdHttpSession*,
snort::SearchTool client_agent_matcher;
snort::SearchTool via_matcher;
snort::SearchTool content_type_matcher;
- snort::SearchTool* field_matcher = nullptr;
- snort::SearchTool* chp_matchers[NUM_HTTP_FIELDS] = { nullptr };
+ snort::SearchTool field_matcher;
+ snort::SearchTool chp_matchers[NUM_HTTP_FIELDS];
tMlmpTree* host_url_matcher = nullptr;
tMlmpTree* rtmp_host_url_matcher = nullptr;
return 0;
}
-static int get_sip_client_app(void* pattern_matcher, const char* pattern, uint32_t pattern_len,
+static int get_sip_client_app(tMlmpTree* pattern_matcher, const char* pattern, uint32_t pattern_len,
AppId& client_id, char*& client_version)
{
tMlmpPattern patterns[3];
patterns[0].patternSize = pattern_len;
patterns[1].pattern = nullptr;
- data = (DetectorAppSipPattern*)mlmpMatchPatternGeneric((tMlmpTree*)pattern_matcher, patterns);
+ data = (DetectorAppSipPattern*)mlmpMatchPatternGeneric(pattern_matcher, patterns);
if ( !data )
return 0;
{
if ( sip_ua_matcher )
{
- mlmpDestroy((tMlmpTree*)sip_ua_matcher);
+ mlmpDestroy(sip_ua_matcher);
}
free_patterns(sip_ua_list);
if ( sip_server_matcher )
{
- mlmpDestroy((tMlmpTree*)sip_server_matcher);
+ mlmpDestroy(sip_server_matcher);
}
free_patterns(sip_server_list);
(const char*)pattern_node->pattern.pattern, patterns, PATTERN_PART_MAX, 0);
patterns[num_patterns].pattern = nullptr;
- mlmpAddPattern((tMlmpTree*)sip_ua_matcher, patterns, pattern_node);
+ mlmpAddPattern(sip_ua_matcher, patterns, pattern_node);
}
for ( pattern_node = sip_server_list; pattern_node; pattern_node =
(const char*)pattern_node->pattern.pattern, patterns, PATTERN_PART_MAX, 0);
patterns[num_patterns].pattern = nullptr;
- mlmpAddPattern((tMlmpTree*)sip_server_matcher, patterns, pattern_node);
+ mlmpAddPattern(sip_server_matcher, patterns, pattern_node);
}
- mlmpProcessPatterns((tMlmpTree*)sip_ua_matcher);
- mlmpProcessPatterns((tMlmpTree*)sip_server_matcher);
+ mlmpProcessPatterns(sip_ua_matcher);
+ mlmpProcessPatterns(sip_server_matcher);
+}
+
+void SipPatternMatchers::reload_patterns()
+{
+ assert(sip_ua_matcher);
+ mlmp_reload_patterns(*sip_ua_matcher);
+ assert(sip_server_matcher);
+ mlmp_reload_patterns(*sip_server_matcher);
}
int SipPatternMatchers::get_client_from_ua(const char* pattern, uint32_t pattern_len,
int get_client_from_ua(const char*, uint32_t, AppId&, char*&);
int get_client_from_server(const char*, uint32_t, AppId&, char*&);
void finalize_patterns(OdpContext&);
+ void reload_patterns();
private:
static const int PATTERN_PART_MAX = 10;
tMlmpPattern patterns[PATTERN_PART_MAX] = { { nullptr, 0, 0 } };
- void* sip_ua_matcher = nullptr;
+ tMlmpTree* sip_ua_matcher = nullptr;
DetectorAppSipPattern* sip_ua_list = nullptr;
- void* sip_server_matcher = nullptr;
+ tMlmpTree* sip_server_matcher = nullptr;
DetectorAppSipPattern* sip_server_list = nullptr;
};
create_matcher(ssl_cname_matcher, cname_pattern_list);
}
+void SslPatternMatchers::reload_patterns()
+{
+ ssl_host_matcher.reload();
+ ssl_cname_matcher.reload();
+}
+
bool SslPatternMatchers::scan_hostname(const uint8_t* hostname, size_t size, AppId& client_id, AppId& payload_id)
{
return scan_patterns(ssl_host_matcher, hostname, size, client_id, payload_id);
void add_cert_pattern(uint8_t*, size_t, uint8_t, AppId);
void add_cname_pattern(uint8_t*, size_t, uint8_t, AppId);
void finalize_patterns();
+ void reload_patterns();
bool scan_hostname(const uint8_t*, size_t, AppId&, AppId&);
bool scan_cname(const uint8_t*, size_t, AppId&, AppId&);
void ClientAppDescriptor::update_user(AppId, const char*){}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
-void ServiceDiscovery::initialize()
-{ }
+void ServiceDiscovery::initialize() {}
+void ServiceDiscovery::reload() {}
int ServiceDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&)
{ return 0; }
{
AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
+void SearchTool::reload() { }
}
void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
-AppIdDiscovery::AppIdDiscovery() { }
AppIdDiscovery::~AppIdDiscovery() { }
void ClientDiscovery::initialize() { }
+void ClientDiscovery::reload() { }
void AppIdDiscovery::register_detector(const string&, AppIdDetector*, IpProtocol) { }
-void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool*, int, unsigned char const*, unsigned int, unsigned int) { }
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int, unsigned char const*, unsigned int, unsigned int) { }
void AppIdDiscovery::register_tcp_pattern(AppIdDetector*, unsigned char const*, unsigned int, int, unsigned int) { }
void AppIdDiscovery::register_udp_pattern(AppIdDetector*, unsigned char const*, unsigned int, int, unsigned int) { }
int AppIdDiscovery::add_service_port(AppIdDetector*, ServiceDetectorPort const&) { return 0; }
public:
ServiceDetector();
- void do_custom_init() override { }
void register_appid(AppId, unsigned extractsInfo, OdpContext& odp_ctxt) override;
int service_inprocess(AppIdSession&, const snort::Packet*, AppidSessionDirection dir);
}
}
+void ServiceDiscovery::reload()
+{
+ for ( auto kv : tcp_detectors )
+ kv.second->reload();
+ for ( auto kv : udp_detectors )
+ kv.second->reload();
+}
+
void ServiceDiscovery::finalize_service_patterns()
{
- if (tcp_patterns)
- tcp_patterns->prep();
- if (udp_patterns)
- udp_patterns->prep();
+ tcp_patterns.prep();
+ udp_patterns.prep();
+}
+
+void ServiceDiscovery::reload_service_patterns()
+{
+ tcp_patterns.reload();
+ udp_patterns.reload();
}
int ServiceDiscovery::add_service_port(AppIdDetector* detector, const ServiceDetectorPort& pp)
SearchTool* patterns = nullptr;
if (proto == IpProtocol::TCP)
- patterns = tcp_patterns;
+ patterns = &tcp_patterns;
else
- patterns = udp_patterns;
+ patterns = &udp_patterns;
if (patterns)
{
class ServiceDiscovery : public AppIdDiscovery
{
public:
- ServiceDiscovery() { }
~ServiceDiscovery() override { }
void initialize() override;
+ void reload() override;
void finalize_service_patterns();
+ void reload_service_patterns();
int add_service_port(AppIdDetector*, const ServiceDetectorPort&) override;
AppIdDetectorsIterator get_detector_iterator(IpProtocol);
{ 5353, IpProtocol::UDP, false },
};
- matcher = new SearchTool;
for (unsigned i = 0; i < sizeof(patterns) / sizeof(*patterns); i++)
- matcher->add((const char*)patterns[i].pattern, patterns[i].length, &patterns[i]);
- matcher->prep();
+ matcher.add((const char*)patterns[i].pattern, patterns[i].length, &patterns[i]);
+ matcher.prep();
handler->register_detector(name, this, proto);
}
-MdnsServiceDetector::~MdnsServiceDetector()
+void MdnsServiceDetector::do_custom_reload()
{
- delete matcher;
+ matcher.reload();
}
int MdnsServiceDetector::validate(AppIdDiscoveryArgs& args)
MatchedPatterns* MdnsServiceDetector::create_match_list(const char* data, uint16_t dataSize)
{
MatchedPatterns* pattern_list = nullptr;
- matcher->find_all((const char*)data, dataSize, mdns_pattern_match, false, (void*)&pattern_list);
+ matcher.find_all((const char*)data, dataSize, mdns_pattern_match, false, (void*)&pattern_list);
return pattern_list;
}
{
public:
MdnsServiceDetector(ServiceDiscovery*);
- ~MdnsServiceDetector() override;
int validate(AppIdDiscoveryArgs&) override;
+ void do_custom_reload() override;
private:
MatchedPatterns* create_match_list(const char* data, uint16_t dataSize);
int reference_pointer(const char* start_ptr, const char** resp_endptr, int* start_index,
uint16_t data_size, uint8_t* user_name_len, unsigned size, MatchedPatterns*& pattern_list);
- snort::SearchTool* matcher = nullptr;
+ snort::SearchTool matcher;
};
#endif
#include <CppUTestExt/MockSupport.h>
void ServiceDiscovery::initialize() {}
+void ServiceDiscovery::reload() {}
void ServiceDiscovery::finalize_service_patterns() {}
void ServiceDiscovery::match_by_pattern(AppIdSession&, const Packet*, IpProtocol) {}
void ServiceDiscovery::get_port_based_services(IpProtocol, uint16_t, AppIdSession&) {}
HttpPatternMatchers::~HttpPatternMatchers() { }
DnsPatternMatchers::~DnsPatternMatchers() { }
void ClientDiscovery::initialize() {}
+void ClientDiscovery::reload() {}
FpSMBData* smb_data = nullptr;
int AppIdDetector::initialize(){return 0;}
+void AppIdDetector::reload() { }
int AppIdDetector::data_add(AppIdSession&, void*, AppIdFreeFCN){return 0;}
void* AppIdDetector::data_get(AppIdSession&) {return nullptr;}
void AppIdDetector::add_user(AppIdSession&, const char*, AppId, bool){}
void ClientAppDescriptor::update_user(AppId, const char*){}
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
-void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool*, int,
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int,
const uint8_t* const, unsigned, unsigned){}
void AppIdDiscovery::register_detector(const std::string&, AppIdDetector*, IpProtocol){}
-void add_pattern_data(AppIdDetector*, snort::SearchTool*, int,
- const uint8_t* const, unsigned, unsigned) {}
void AppIdDiscovery::register_tcp_pattern(AppIdDetector*, const uint8_t* const, unsigned,
int, unsigned){}
void AppIdDiscovery::register_udp_pattern(AppIdDetector*, const uint8_t* const, unsigned,
return 0;
}
int dcerpc_validate(const uint8_t*, int){return 0; }
-AppIdDiscovery::AppIdDiscovery() { }
AppIdDiscovery::~AppIdDiscovery() { }
void show_stats(PegCount*, const PegInfo*, unsigned, const char*) { }
void show_stats(PegCount*, const PegInfo*, const IndexVec&, const char*, FILE*) { }
TestDetector() = default;
void do_custom_init() override { }
+ void do_custom_reload() override { }
int validate(AppIdDiscoveryArgs&) override { return 0; }
void register_appid(AppId, unsigned, OdpContext&) override { }
};
// Stubs for ServiceDiscovery
void ServiceDiscovery::initialize() {}
+void ServiceDiscovery::reload() {}
void ServiceDiscovery::finalize_service_patterns() {}
void ServiceDiscovery::match_by_pattern(AppIdSession&, const Packet*, IpProtocol) {}
void ServiceDiscovery::get_port_based_services(IpProtocol, uint16_t, AppIdSession&) {}
// Stubs for ClientDiscovery
void ClientDiscovery::initialize() {}
-void ClientDiscovery::finalize_client_plugins() {}
+void ClientDiscovery::reload() {}
+void ClientDiscovery::finalize_client_patterns() {}
static ClientDiscovery* c_discovery_manager = new ClientDiscovery();
bool ClientDiscovery::do_client_discovery(AppIdSession&, Packet*,
AppidSessionDirection, AppidChangeBits&)
void ClientAppDescriptor::update_stats(AppId, bool) {}
void PayloadAppDescriptor::update_stats(AppId, bool) {}
-AppIdDiscovery::AppIdDiscovery() { }
AppIdDiscovery::~AppIdDiscovery() { }
void ClientDiscovery::initialize() { }
+void ClientDiscovery::reload() { }
void AppIdDiscovery::register_detector(const string&, AppIdDetector*, IpProtocol) { }
-void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool*, int, unsigned char const*, unsigned int, unsigned int) { }
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int, unsigned char const*, unsigned int, unsigned int) { }
void AppIdDiscovery::register_tcp_pattern(AppIdDetector*, unsigned char const*, unsigned int, int, unsigned int) { }
void AppIdDiscovery::register_udp_pattern(AppIdDetector*, unsigned char const*, unsigned int, int, unsigned int) { }
int AppIdDiscovery::add_service_port(AppIdDetector*, ServiceDetectorPort const&) { return 0; }
return 0;
}
-void ServiceDiscovery::initialize()
-{ }
+void ServiceDiscovery::initialize() { }
+void ServiceDiscovery::reload() { }
int ServiceDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&)
{ return 0; }
: FlowData(0), config(stub_config), api(*(new AppIdSessionApi(this, *ip))),
odp_ctxt(stub_odp_ctxt) { }
AppIdSession::~AppIdSession() = default;
-AppIdDiscovery::AppIdDiscovery() {}
AppIdDiscovery::~AppIdDiscovery() {}
void ClientDiscovery::initialize() { }
+void ClientDiscovery::reload() { }
void AppIdDiscovery::register_detector(const std::string&, AppIdDetector*, IpProtocol) {}
-void AppIdDiscovery::add_pattern_data(AppIdDetector*, SearchTool*, int, const uint8_t* const,
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, SearchTool&, int, const uint8_t* const,
unsigned, unsigned) {}
void AppIdDiscovery::register_tcp_pattern(AppIdDetector*, const uint8_t* const, unsigned,
int, unsigned) {}
int AppIdDiscovery::add_service_port(AppIdDetector*,
const ServiceDetectorPort&) { return APPID_EINVALID; }
void ServiceDiscovery::initialize() {}
+void ServiceDiscovery::reload() {}
void ServiceDiscovery::finalize_service_patterns() {}
void ServiceDiscovery::match_by_pattern(AppIdSession&, const Packet*, IpProtocol) {}
void ServiceDiscovery::get_port_based_services(IpProtocol, uint16_t, AppIdSession&) {}
snort::SearchTool::SearchTool(char const*, bool) { }
snort::SearchTool::~SearchTool() { }
-AppIdDiscovery::AppIdDiscovery() { }
AppIdDiscovery::~AppIdDiscovery() { }
void ClientDiscovery::initialize() { }
+void ClientDiscovery::reload() { }
void AppIdDiscovery::register_detector(const string&, AppIdDetector*, IpProtocol) { }
-void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool*, int, unsigned char const*, unsigned int, unsigned int) { }
+void AppIdDiscovery::add_pattern_data(AppIdDetector*, snort::SearchTool&, int, unsigned char const*, unsigned int, unsigned int) { }
void AppIdDiscovery::register_tcp_pattern(AppIdDetector*, unsigned char const*, unsigned int, int, unsigned int) { }
void AppIdDiscovery::register_udp_pattern(AppIdDetector*, unsigned char const*, unsigned int, int, unsigned int) { }
int AppIdDiscovery::add_service_port(AppIdDetector*, ServiceDetectorPort const&) { return 0; }
OdpContext::OdpContext(const AppIdConfig&, snort::SnortConfig*) { }
OdpContext::~OdpContext() { }
void ServiceDiscovery::initialize() { }
+void ServiceDiscovery::reload() { }
int ServiceDiscovery::add_service_port(AppIdDetector*, const ServiceDetectorPort&)
{ return 0; }
}
int prep_patterns(SnortConfig*) override;
+ void reuse_search() override;
int _search(const uint8_t*, int, MpseMatch, void*, int*) override;
return 0;
}
+void HyperscanMpse::reuse_search()
+{
+ if ( pvector.empty() )
+ return;
+
+ if ( hs_error_t err = hs_alloc_scratch(hs_db, &s_scratch[get_instance_id()]) )
+ ErrorMessage("can't allocate search scratch space (%d)", err);
+}
+
int HyperscanMpse::match(unsigned id, unsigned long long to, MpseMatch match_cb, void* match_ctx)
{
assert(id < pvector.size());
mpsegrp->offload_mpse->prep_patterns(nullptr);
}
+void SearchTool::reload()
+{
+ if ( mpsegrp->normal_mpse )
+ mpsegrp->normal_mpse->reuse_search();
+ if ( mpsegrp->offload_mpse )
+ mpsegrp->offload_mpse->reuse_search();
+}
+
int SearchTool::find(
const char* str, unsigned len, MpseMatch mf, int& state, bool confine, void* user_data)
{
void add(const uint8_t* pattern, unsigned len, void* s_context, bool no_case = true);
void prep();
+ void reload();
// set state to zero on first call
int find(const char* s, unsigned s_len, MpseMatch, int& state,
static unsigned parse_errors = 0;
void ParseError(const char*, ...)
{ parse_errors++; }
+void ErrorMessage(const char*, ...) { }
void LogCount(char const*, uint64_t, FILE*)
{ }