ips_isdataat.cc
ips_itype.cc
ips_msg.cc
+ ips_pcre.cc
ips_priority.cc
ips_raw_data.cc
ips_rem.cc
ips_metadata.cc
ips_options.cc
ips_options.h
- ips_pcre.cc
- ips_pcre.h
ips_pkt_data.cc
ips_reference.cc
ips_replace.cc
)
if ( HAVE_HYPERSCAN )
- set(OPTION_LIST ips_regex.cc ips_regex.h
- ips_sd_pattern.cc ips_sd_pattern.h
+ set(PLUGIN_LIST
+ ${PLUGIN_LIST}
+ ips_regex.cc
+ ips_sd_pattern.cc
sd_credit_card.cc sd_credit_card.h)
endif ()
add_dynamic_module(ips_isdataat ips_options ips_isdataat.cc)
add_dynamic_module(ips_itype ips_options ips_itype.cc)
add_dynamic_module(ips_msg ips_options ips_msg.cc)
+ add_dynamic_module(ips_pcre ips_options ips_pcre.cc)
add_dynamic_module(ips_priority ips_options ips_priority.cc)
add_dynamic_module(ips_raw_data ips_options ips_raw_data.cc)
add_dynamic_module(ips_rem ips_options ips_rem.cc)
add_dynamic_module(ips_tos ips_options ips_tos.cc)
add_dynamic_module(ips_ttl ips_options ips_ttl.cc)
add_dynamic_module(ips_window ips_options ips_window.cc)
+if ( HAVE_HYPERSCAN )
+ add_dynamic_module(ips_regex ips_options ips_regex.cc)
+ add_dynamic_module(ips_sd_pattern ips_options ips_sd_pattern.cc sd_credit_card.cc sd_credit_card.h)
+endif ( HAVE_HYPERSCAN )
endif (STATIC_IPS_OPTIONS)
extern const BaseApi* ips_flowbits;
extern const BaseApi* ips_md5;
extern const BaseApi* ips_metadata;
-extern const BaseApi* ips_pcre;
extern const BaseApi* ips_pkt_data;
extern const BaseApi* ips_reference;
-#ifdef HAVE_HYPERSCAN
-extern const BaseApi* ips_regex;
-extern const BaseApi* ips_sd_pattern;
-#endif
extern const BaseApi* ips_replace;
extern const BaseApi* ips_service;
extern const BaseApi* ips_sha256;
extern const BaseApi* ips_isdataat[];
extern const BaseApi* ips_itype[];
extern const BaseApi* ips_msg[];
+extern const BaseApi* ips_pcre[];
extern const BaseApi* ips_priority[];
extern const BaseApi* ips_raw_data[];
extern const BaseApi* ips_rem[];
extern const BaseApi* ips_ttl[];
extern const BaseApi* ips_bufferlen[];
extern const BaseApi* ips_window[];
+#ifdef HAVE_HYPERSCAN
+extern const BaseApi* ips_regex[];
+extern const BaseApi* ips_sd_pattern[];
+#endif
#endif
static const BaseApi* ips_options[] =
ips_flowbits,
ips_md5,
ips_metadata,
- ips_pcre,
ips_pkt_data,
ips_reference,
-#ifdef HAVE_HYPERSCAN
- ips_regex,
- ips_sd_pattern,
-#endif
ips_replace,
ips_service,
ips_sha256,
PluginManager::load_plugins(ips_isdataat);
PluginManager::load_plugins(ips_itype);
PluginManager::load_plugins(ips_msg);
+ PluginManager::load_plugins(ips_pcre);
PluginManager::load_plugins(ips_priority);
PluginManager::load_plugins(ips_raw_data);
PluginManager::load_plugins(ips_rem);
PluginManager::load_plugins(ips_ttl);
PluginManager::load_plugins(ips_bufferlen);
PluginManager::load_plugins(ips_window);
+#ifdef HAVE_HYPERSCAN
+ PluginManager::load_plugins(ips_regex);
+ PluginManager::load_plugins(ips_sd_pattern);
+#endif
#endif
}
#include "config.h"
#endif
-#include "ips_pcre.h"
-
#include <pcre.h>
#include <cassert>
// by verify; search uses the value in snort conf
static int s_ovector_size = 0;
+static unsigned scratch_index;
+
static THREAD_LOCAL ProfileStats pcrePerfStats;
//-------------------------------------------------------------------------
found_offset = -1;
- SnortState* ss = SnortConfig::get_conf()->state + get_instance_id();
- assert(ss->pcre_ovector);
+ std::vector<void *> ss = SnortConfig::get_conf()->state[get_instance_id()];
+ assert(ss[scratch_index]);
int result = pcre_exec(
pcre_data->re, /* result of pcre_compile() */
len, /* the length of the subject string */
start_offset, /* start at offset 0 in the subject */
0, /* options(handled at compile time */
- ss->pcre_ovector, /* vector for substring information */
+ (int*)ss[scratch_index], /* vector for substring information */
SnortConfig::get_conf()->pcre_ovector_size); /* number of elements in the vector */
if (result >= 0)
* and a single int for scratch space.
*/
- found_offset = ss->pcre_ovector[1];
+ found_offset = ((int*)ss[scratch_index])[1];
}
else if (result == PCRE_ERROR_NOMATCH)
{
return true; // continue
}
-//-------------------------------------------------------------------------
-// public methods
-//-------------------------------------------------------------------------
-
-void pcre_setup(SnortConfig* sc)
-{
- for ( unsigned i = 0; i < sc->num_slots; ++i )
- {
- SnortState* ss = sc->state + i;
- ss->pcre_ovector = (int*)snort_calloc(s_ovector_max, sizeof(int));
- }
-}
-
-void pcre_cleanup(SnortConfig* sc)
-{
- for ( unsigned i = 0; i < sc->num_slots; ++i )
- {
- SnortState* ss = sc->state + i;
-
- if ( ss->pcre_ovector )
- snort_free(ss->pcre_ovector);
-
- ss->pcre_ovector = nullptr;
- }
-}
-
//-------------------------------------------------------------------------
// module
//-------------------------------------------------------------------------
{
public:
PcreModule() : Module(s_name, s_help, s_params)
- { data = nullptr; }
+ {
+ data = nullptr;
+ scratch_index = SnortConfig::request_scratch(
+ PcreModule::scratch_setup, PcreModule::scratch_cleanup);
+ }
~PcreModule() override
{ delete data; }
private:
PcreData* data;
+ static void scratch_setup(SnortConfig* sc);
+ static void scratch_cleanup(SnortConfig* sc);
};
PcreData* PcreModule::get_data()
return true;
}
+void PcreModule::scratch_setup(SnortConfig* sc)
+{
+ for ( unsigned i = 0; i < sc->num_slots; ++i )
+ {
+ std::vector<void *>& ss = sc->state[i];
+ ss[scratch_index] = snort_calloc(s_ovector_max, sizeof(int));
+ }
+}
+
+void PcreModule::scratch_cleanup(SnortConfig* sc)
+{
+ for ( unsigned i = 0; i < sc->num_slots; ++i )
+ {
+ std::vector<void *>& ss = sc->state[i];
+
+ if ( ss[scratch_index] )
+ snort_free(ss[scratch_index]);
+
+ ss[scratch_index] = nullptr;
+ }
+}
+
//-------------------------------------------------------------------------
// api methods
//-------------------------------------------------------------------------
pcre_verify
};
-const BaseApi* ips_pcre = &pcre_api.base;
-
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+#else
+const BaseApi* ips_pcre[] =
+#endif
+{
+ &pcre_api.base,
+ nullptr
+};
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2014-2018 Cisco and/or its affiliates. All rights reserved.
-// Copyright (C) 2013-2013 Sourcefire, Inc.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation. You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//--------------------------------------------------------------------------
-
-#ifndef IPS_PCRE_H
-#define IPS_PCRE_H
-
-namespace snort
-{
-struct SnortConfig;
-}
-
-void pcre_setup(snort::SnortConfig*);
-void pcre_cleanup(snort::SnortConfig*);
-
-#endif
-
#include "config.h"
#endif
-#include "ips_regex.h"
-
#include <hs_compile.h>
#include <hs_runtime.h>
// rules.
static hs_scratch_t* s_scratch = nullptr;
+static unsigned scratch_index;
static THREAD_LOCAL unsigned s_to = 0;
static THREAD_LOCAL ProfileStats regex_perf_stats;
if ( pos > c.size() )
return NO_MATCH;
- SnortState* ss = SnortConfig::get_conf()->state + get_instance_id();
- assert(ss->regex_scratch);
+ hs_scratch_t *ss = (hs_scratch_t *) SnortConfig::get_conf()->state[get_instance_id()][scratch_index];
s_to = 0;
hs_error_t stat = hs_scan(
config.db, (const char*)c.buffer()+pos, c.size()-pos, 0,
- (hs_scratch_t*)ss->regex_scratch, hs_match, nullptr);
+ ss, hs_match, nullptr);
if ( s_to and stat == HS_SCAN_TERMINATED )
{
class RegexModule : public Module
{
public:
- RegexModule() : Module(s_name, s_help, s_params) { }
+ RegexModule() : Module(s_name, s_help, s_params)
+ {
+ scratch_index = SnortConfig::request_scratch(
+ RegexModule::scratch_setup, RegexModule::scratch_cleanup);
+ }
~RegexModule() override;
bool begin(const char*, int, SnortConfig*) override;
private:
RegexConfig config;
+ static void scratch_setup(SnortConfig* sc);
+ static void scratch_cleanup(SnortConfig* sc);
};
RegexModule::~RegexModule()
return true;
}
-//-------------------------------------------------------------------------
-// public methods
-//-------------------------------------------------------------------------
-
-void regex_setup(SnortConfig* sc)
+void RegexModule::scratch_setup(SnortConfig* sc)
{
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- SnortState* ss = sc->state + i;
+ hs_scratch_t** ss = (hs_scratch_t**) &sc->state[i][scratch_index];
if ( s_scratch )
- hs_clone_scratch(s_scratch, (hs_scratch_t**)&ss->regex_scratch);
+ hs_clone_scratch(s_scratch, ss);
else
- ss->regex_scratch = nullptr;
+ ss = nullptr;
}
}
-void regex_cleanup(SnortConfig* sc)
+void RegexModule::scratch_cleanup(SnortConfig* sc)
{
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- SnortState* ss = sc->state + i;
+ hs_scratch_t* ss = (hs_scratch_t*) sc->state[i][scratch_index];
- if ( ss->regex_scratch )
+ if ( ss )
{
- hs_free_scratch((hs_scratch_t*)ss->regex_scratch);
- ss->regex_scratch = nullptr;
+ hs_free_scratch(ss);
+ ss = nullptr;
}
}
}
nullptr
};
-const BaseApi* ips_regex = ®ex_api.base;
-
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+#else
+const BaseApi* ips_regex[] =
+#endif
+{
+ ®ex_api.base,
+ nullptr
+};
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2015-2018 Cisco and/or its affiliates. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation. You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//--------------------------------------------------------------------------
-
-#ifndef IPS_REGEX_H
-#define IPS_REGEX_H
-
-namespace snort
-{
-struct SnortConfig;
-}
-
-void regex_setup(snort::SnortConfig*);
-void regex_cleanup(snort::SnortConfig*);
-
-#endif
-
#include "config.h"
#endif
-#include "ips_sd_pattern.h"
-
#include <cctype>
#include <hs_compile.h>
// "regex" and "sd_pattern" keywords.
// FIXIT-L See ips_regex.cc for more information.
static hs_scratch_t* s_scratch = nullptr;
+static unsigned scratch_index;
struct SdStats
{
const uint8_t* buf = c.start();
unsigned int buflen = c.length();
- SnortState* ss = SnortConfig::get_conf()->state + get_instance_id();
- assert(ss->sdpattern_scratch);
+ std::vector<void *> ss = SnortConfig::get_conf()->state[get_instance_id()];
+ assert(ss[scratch_index]);
hsContext ctx(config, p, start, buf, buflen);
hs_error_t stat = hs_scan(config.db, (const char*)buf, buflen, 0,
- (hs_scratch_t*)ss->sdpattern_scratch, hs_match, (void*)&ctx);
+ (hs_scratch_t*)ss[scratch_index], hs_match, (void*)&ctx);
if ( stat == HS_SCAN_TERMINATED )
++s_stats.terminated;
class SdPatternModule : public Module
{
public:
- SdPatternModule() : Module(s_name, s_help, s_params) { }
+ SdPatternModule() : Module(s_name, s_help, s_params)
+ {
+ scratch_index = SnortConfig::request_scratch(
+ SdPatternModule::scratch_setup, SdPatternModule::scratch_cleanup);
+ }
bool begin(const char*, int, SnortConfig*) override;
bool set(const char*, Value& v, SnortConfig*) override;
private:
SdPatternConfig config;
+
+ static void scratch_setup(SnortConfig* sc);
+ static void scratch_cleanup(SnortConfig* sc);
};
bool SdPatternModule::begin(const char*, int, SnortConfig*)
// public methods
//-------------------------------------------------------------------------
-void sdpattern_setup(SnortConfig* sc)
+void SdPatternModule::scratch_setup(SnortConfig* sc)
{
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- SnortState* ss = sc->state + i;
+ std::vector<void *>& ss = sc->state[i];
if ( s_scratch )
- hs_clone_scratch(s_scratch, (hs_scratch_t**)&ss->sdpattern_scratch);
+ hs_clone_scratch(s_scratch, (hs_scratch_t**)&ss[scratch_index]);
else
- ss->sdpattern_scratch = nullptr;
+ ss[scratch_index] = nullptr;
}
}
-void sdpattern_cleanup(SnortConfig* sc)
+void SdPatternModule::scratch_cleanup(SnortConfig* sc)
{
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- SnortState* ss = sc->state + i;
+ std::vector<void *>& ss = sc->state[i];
- if ( ss->sdpattern_scratch )
+ if ( ss[scratch_index] )
{
- hs_free_scratch((hs_scratch_t*)ss->sdpattern_scratch);
- ss->sdpattern_scratch = nullptr;
+ hs_free_scratch((hs_scratch_t*)ss[scratch_index]);
+ ss[scratch_index] = nullptr;
}
}
}
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2015-2018 Cisco and/or its affiliates. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation. You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//--------------------------------------------------------------------------
-
-#ifndef IPS_SD_PATTERN_H
-#define IPS_SD_PATTERN_H
-
-namespace snort
-{
-struct SnortConfig;
-}
-
-void sdpattern_setup(snort::SnortConfig*);
-void sdpattern_cleanup(snort::SnortConfig*);
-
-#endif
#include "config.h"
#endif
-#include "ips_options/ips_regex.h"
-
#include "framework/base_api.h"
#include "framework/counts.h"
#include "framework/cursor.h"
SnortConfig s_conf;
THREAD_LOCAL SnortConfig* snort_conf = &s_conf;
-static SnortState s_state;
+static std::vector<void *> s_state;
+
+ScScratchFunc scratch_setup;
+ScScratchFunc scratch_cleanup;
SnortConfig::SnortConfig(const SnortConfig* const)
{
state = &s_state;
- memset(state, 0, sizeof(*state));
num_slots = 1;
}
SnortConfig::~SnortConfig() = default;
+int SnortConfig::request_scratch(ScScratchFunc setup, ScScratchFunc cleanup)
+{
+ scratch_setup = setup;
+ scratch_cleanup = cleanup;
+ s_state.resize(1);
+
+ return 0;
+}
+
SnortConfig* SnortConfig::get_conf()
{ return snort_conf; }
// FIXIT-L cpputest hangs or crashes in the leak detector
MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
opt = get_option(" foo ");
- regex_setup(snort_conf);
+ scratch_setup(snort_conf);
}
void teardown() override
{
IpsApi* api = (IpsApi*)ips_regex;
api->dtor(opt);
- regex_cleanup(snort_conf);
+ scratch_cleanup(snort_conf);
api->pterm(snort_conf);
MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
}
// FIXIT-L cpputest hangs or crashes in the leak detector
MemoryLeakWarningPlugin::turnOffNewDeleteOverloads();
opt = get_option("\\bfoo", true);
- regex_setup(snort_conf);
+ scratch_setup(snort_conf);
}
void teardown() override
{
IpsApi* api = (IpsApi*)ips_regex;
api->dtor(opt);
- regex_cleanup(snort_conf);
+ scratch_cleanup(snort_conf);
MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
}
};
#include "filters/sfthreshold.h"
#include "hash/xhash.h"
#include "helpers/process.h"
-#include "ips_options/ips_pcre.h"
#include "latency/latency_config.h"
#include "log/messages.h"
#include "managers/event_manager.h"
#include "utils/util.h"
#include "utils/util_cstring.h"
-#ifdef HAVE_HYPERSCAN
-#include "ips_options/ips_regex.h"
-#include "ips_options/ips_sd_pattern.h"
-#include "search_engines/hyperscan.h"
-#endif
-
#include "snort.h"
#include "thread_config.h"
THREAD_LOCAL SnortConfig* snort_conf = nullptr;
uint32_t SnortConfig::warning_flags = 0;
+static std::vector <std::pair<ScScratchFunc,ScScratchFunc>> scratch_handlers;
//-------------------------------------------------------------------------
// private implementation
InspectorManager::new_config(this);
num_slots = ThreadConfig::get_instance_max();
- state = (SnortState*)snort_calloc(num_slots, sizeof(SnortState));
+ state = new std::vector<void *>[num_slots];
profiler = new ProfilerConfig;
latency = new LatencyConfig();
FreeClassifications(classifications);
FreeReferences(references);
-#ifdef HAVE_HYPERSCAN
- hyperscan_cleanup(this);
- sdpattern_cleanup(this);
- regex_cleanup(this);
-#endif
- pcre_cleanup(this);
+ // Only call scratch cleanup if we actually called scratch setup
+ if ( state[0].size() > 0 )
+ {
+ for ( unsigned i = scratch_handlers.size(); i > 0; i-- )
+ {
+ if ( scratch_handlers[i - 1].second )
+ scratch_handlers[i - 1].second(this);
+ }
+ // FIXME-T: Do we need to shrink_to_fit() state->scratch at this point?
+ }
FreeRuleLists(this);
OtnLookupFree(otn_map);
delete policy_map;
InspectorManager::delete_config(this);
- snort_free(state);
+ delete[] state;
delete thread_config;
if (gtp_ports)
void SnortConfig::post_setup()
{
- // FIXIT-L register setup and cleanup to eliminate explicit calls and
- // allow pcre, regex, and hyperscan to be built dynamically. Hyperscan setup
- // moved to post_setup to ensure all the prep_patterns are called before it.
- pcre_setup(this);
-#ifdef HAVE_HYPERSCAN
- regex_setup(this);
- sdpattern_setup(this);
- hyperscan_setup(this);
-#endif
+ unsigned i;
+ unsigned int handler_count = scratch_handlers.size();
+
+ // Ensure we have allocated the scratch space vector for each thread
+ for ( i = 0; i < num_slots; ++i )
+ {
+ state[i].resize(handler_count);
+ }
+
+ for ( i = 0; i < handler_count; ++i )
+ {
+ if ( scratch_handlers[i].first )
+ scratch_handlers[i].first(this);
+ }
}
void SnortConfig::clone(const SnortConfig* const conf)
// FIXIT-M should cmd_line use the same var list / table?
var_list = nullptr;
- snort_free(state);
+ delete[] state;
num_slots = ThreadConfig::get_instance_max();
- state = (SnortState*)snort_calloc(num_slots, sizeof(SnortState));
+ state = new std::vector<void *>[num_slots];
}
bool SnortConfig::verify()
return (!((get_conf()->tunnel_mask & proto) or SFDAQ::get_tunnel_bypass(proto)));
}
+SO_PUBLIC int SnortConfig::request_scratch(ScScratchFunc setup, ScScratchFunc cleanup)
+{
+ scratch_handlers.push_back(std::make_pair(setup, cleanup));
+
+ // We return an index that the caller uses to reference their per thread
+ // scratch space
+ return scratch_handlers.size() - 1;
+}
+
SO_PUBLIC SnortConfig* SnortConfig::get_conf()
{ return snort_conf; }
{
struct ProfilerConfig;
-// SnortState members are updated during runtime. an array in SnortConfig is
-// used instead of thread_locals because these must get changed on reload
-// FIXIT-L register this data to avoid explicit dependency
-struct SnortState
-{
- int* pcre_ovector;
-
- // regex hyperscan and sdpattern are conditionally built but these are
- // unconditional to avoid compatibility issues with plugins. if these are
- // conditional then API_OPTIONS must be updated.
- // note: fwd decls don't work here.
- void* regex_scratch;
- void* hyperscan_scratch;
- void* sdpattern_scratch;
-};
+struct SnortConfig;
+typedef void (* ScScratchFunc)(SnortConfig* sc);
struct SnortConfig
{
MemoryConfig* memory = nullptr;
//------------------------------------------------------
- SnortState* state = nullptr;
+ std::vector<void *>* state = nullptr;
unsigned num_slots = 0;
ThreadConfig* thread_config;
bool track_on_syn() const
{ return (run_flags & RUN_FLAG__TRACK_ON_SYN) != 0; }
+ // This requests an entry in the scratch space vector and calls setup /
+ // cleanup as appropriate
+ SO_PUBLIC static int request_scratch(ScScratchFunc setup, ScScratchFunc cleanup);
+
// Use this to access current thread's conf from other units
static void set_conf(SnortConfig*);
if ( HAVE_HYPERSCAN )
set(HYPER_SOURCES
hyperscan.cc
- hyperscan.h
)
endif ()
search_engines.h
search_tool.cc
${BNFA_SOURCES}
- ${HYPER_SOURCES}
)
if ( STATIC_SEARCH_ENGINES )
add_library(search_engines OBJECT
${ACSMX_SOURCES}
${ACSMX2_SOURCES}
+ ${HYPER_SOURCES}
${INTEL_SOURCES}
${SEARCH_ENGINE_SOURCES}
${SEARCH_ENGINE_INCLUDES}
add_dynamic_module(acsmx search_engines ${ACSMX_SOURCES})
add_dynamic_module(acsmx2 search_engines ${ACSMX2_SOURCES})
+if ( HAVE_HYPERSCAN )
+ add_dynamic_module(hyperscan search_engines ${HYPER_SOURCES})
+endif ()
endif (STATIC_SEARCH_ENGINES)
#include "config.h"
#endif
-#include "hyperscan.h"
-
#include <hs_compile.h>
#include <hs_runtime.h>
// a prototype that is large enough for all uses.
static hs_scratch_t* s_scratch = nullptr;
+static unsigned int scratch_index;
+static bool scratch_registered = false;
//-------------------------------------------------------------------------
// mpse
match_cb = mf;
match_ctx = pv;
- SnortState* ss = SnortConfig::get_conf()->state + get_instance_id();
+ hs_scratch_t *ss = (hs_scratch_t *) SnortConfig::get_conf()->state[get_instance_id()][scratch_index];
// scratch is null for the degenerate case w/o patterns
- assert(!hs_db or ss->hyperscan_scratch);
+ assert(!hs_db or ss);
- hs_scan(hs_db, (const char*)buf, n, 0, (hs_scratch_t*)ss->hyperscan_scratch,
+ hs_scan(hs_db, (const char*)buf, n, 0, ss,
HyperscanMpse::match, this);
return nfound;
}
-//-------------------------------------------------------------------------
-// public methods
-//-------------------------------------------------------------------------
-
-void hyperscan_setup(SnortConfig* sc)
+static void scratch_setup(SnortConfig* sc)
{
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- SnortState* ss = sc->state + i;
+ hs_scratch_t** ss = (hs_scratch_t**) &sc->state[i][scratch_index];
if ( s_scratch )
- hs_clone_scratch(s_scratch, (hs_scratch_t**)&ss->hyperscan_scratch);
+ hs_clone_scratch(s_scratch, ss);
else
- ss->hyperscan_scratch = nullptr;
+ ss = nullptr;
}
if ( s_scratch )
{
}
}
-void hyperscan_cleanup(SnortConfig* sc)
+static void scratch_cleanup(SnortConfig* sc)
{
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- SnortState* ss = sc->state + i;
+ hs_scratch_t* ss = (hs_scratch_t*) sc->state[i][scratch_index];
- if ( ss->hyperscan_scratch )
+ if ( ss )
{
- hs_free_scratch((hs_scratch_t*)ss->hyperscan_scratch);
- ss->hyperscan_scratch = nullptr;
+ hs_free_scratch(ss);
+ ss = nullptr;
}
}
}
static Mpse* hs_ctor(
SnortConfig* sc, class Module*, const MpseAgent* a)
{
+ if ( !scratch_registered )
+ {
+ scratch_index = SnortConfig::request_scratch(scratch_setup, scratch_cleanup);
+ scratch_registered = true;
+ }
return new HyperscanMpse(sc, a);
}
hs_print,
};
-//#ifdef BUILDING_SO
-//SO_PUBLIC const BaseApi* snort_plugins[] =
-//#else
+#ifdef BUILDING_SO
+SO_PUBLIC const BaseApi* snort_plugins[] =
+#else
const BaseApi* se_hyperscan[] =
-//#endif
+#endif
{
&hs_api.base,
nullptr
+++ /dev/null
-//--------------------------------------------------------------------------
-// Copyright (C) 2015-2018 Cisco and/or its affiliates. All rights reserved.
-//
-// This program is free software; you can redistribute it and/or modify it
-// under the terms of the GNU General Public License Version 2 as published
-// by the Free Software Foundation. You may not use, modify or distribute
-// this program under any other version of the GNU General Public License.
-//
-// This program is distributed in the hope that it will be useful, but
-// WITHOUT ANY WARRANTY; without even the implied warranty of
-// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-// General Public License for more details.
-//
-// You should have received a copy of the GNU General Public License along
-// with this program; if not, write to the Free Software Foundation, Inc.,
-// 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
-//--------------------------------------------------------------------------
-
-// hyperscan.h author Russ Combs <rucombs@cisco.com>
-
-#ifndef HYPERSCAN_H
-#define HYPERSCAN_H
-
-namespace snort
-{
-struct SnortConfig;
-}
-
-void hyperscan_setup(snort::SnortConfig*);
-void hyperscan_cleanup(snort::SnortConfig*);
-
-#endif
extern const BaseApi* se_ac_bnfa[];
-#ifdef HAVE_HYPERSCAN
-extern const BaseApi* se_hyperscan[];
-#endif
-
#ifdef STATIC_SEARCH_ENGINES
extern const BaseApi* se_ac_std[];
extern const BaseApi* se_acsmx2[];
+#ifdef HAVE_HYPERSCAN
+extern const BaseApi* se_hyperscan[];
+#endif
#endif
void load_search_engines()
{
PluginManager::load_plugins(se_ac_bnfa);
-#ifdef HAVE_HYPERSCAN
- PluginManager::load_plugins(se_hyperscan);
-#endif
-
#ifdef STATIC_SEARCH_ENGINES
PluginManager::load_plugins(se_ac_std);
PluginManager::load_plugins(se_acsmx2);
+#ifdef HAVE_HYPERSCAN
+ PluginManager::load_plugins(se_hyperscan);
+#endif
#endif
}
#include "config.h"
#endif
-#include "search_engines/hyperscan.h"
-
#include <string.h>
#include "framework/base_api.h"
SnortConfig s_conf;
THREAD_LOCAL SnortConfig* snort_conf = &s_conf;
-static SnortState s_state;
+static std::vector<void *> s_state;
+
+ScScratchFunc scratch_setup;
+ScScratchFunc scratch_cleanup;
SnortConfig::SnortConfig(const SnortConfig* const)
{
state = &s_state;
- memset(state, 0, sizeof(*state));
num_slots = 1;
}
SnortConfig::~SnortConfig() = default;
+int SnortConfig::request_scratch(ScScratchFunc setup, ScScratchFunc cleanup)
+{
+ scratch_setup = setup;
+ scratch_cleanup = cleanup;
+ s_state.resize(1);
+
+ return 0;
+}
+
SnortConfig* SnortConfig::get_conf()
{ return snort_conf; }
void teardown() override
{
mpse_api->dtor(hs);
- hyperscan_cleanup(snort_conf);
+ scratch_cleanup(snort_conf);
MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
}
};
CHECK(hs->prep_patterns(snort_conf) == 0);
CHECK(hs->get_pattern_count() == 1);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs->search((uint8_t*)"foo", 3, match, nullptr, &state) == 1);
CHECK(hs->prep_patterns(snort_conf) == 0);
CHECK(hs->get_pattern_count() == 1);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs->search((uint8_t*)"foo", 3, match, nullptr, &state) == 1);
CHECK(hs->prep_patterns(snort_conf) == 0);
CHECK(hs->get_pattern_count() == 1);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs->search((uint8_t*)"foo", 3, match, nullptr, &state) == 1);
CHECK(hs->prep_patterns(snort_conf) == 0);
CHECK(hs->get_pattern_count() == 3);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs->search((uint8_t*)"foo bar baz", 11, match, nullptr, &state) == 3);
CHECK(hs->prep_patterns(snort_conf) == 0);
CHECK(hs->get_pattern_count() == 1);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs->search((uint8_t*)"foo bar baz", 11, match, nullptr, &state) == 0);
CHECK(hs->prep_patterns(snort_conf) == 0);
CHECK(hs->get_pattern_count() == 1);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs->search((uint8_t*)":definition(", 12, match, nullptr, &state) == 0);
{
mpse_api->dtor(hs1);
mpse_api->dtor(hs2);
- hyperscan_cleanup(snort_conf);
+ scratch_cleanup(snort_conf);
MemoryLeakWarningPlugin::turnOnNewDeleteOverloads();
}
};
CHECK(hs1->get_pattern_count() == 1);
CHECK(hs2->get_pattern_count() == 1);
- hyperscan_setup(snort_conf);
+ scratch_setup(snort_conf);
int state = 0;
CHECK(hs1->search((uint8_t*)"fubar", 5, match, nullptr, &state) == 1 );
THREAD_LOCAL SnortConfig* snort_conf = &s_conf;
-static SnortState s_state;
+static std::vector<void *> s_state;
SnortConfig::SnortConfig(const SnortConfig* const)
{
state = &s_state;
- memset(state, 0, sizeof(*state));
num_slots = 1;
fast_pattern_config = nullptr;
}