#include "detection_options.h"
+#include <mutex>
#include <string>
#include "filters/detection_filter.h"
void* add_detection_option_tree(SnortConfig* sc, detection_option_tree_node_t* option_tree)
{
+ static std::mutex build_mutex;
+ std::lock_guard<std::mutex> lock(build_mutex);
+
if ( !sc->detection_option_tree_hash_table )
sc->detection_option_tree_hash_table = DetectionTreeHashTableNew();
#include "framework/mpse_batch.h"
#include "hash/ghash.h"
#include "log/messages.h"
+#include "main/snort.h"
#include "main/snort_config.h"
+#include "main/thread_config.h"
#include "managers/mpse_manager.h"
#include "parser/parse_rule.h"
#include "parser/parser.h"
{
if (pg->mpsegrp[i]->normal_mpse->get_pattern_count() != 0)
{
- if ( !sc->test_mode() or sc->mem_check() )
- {
- if ( pg->mpsegrp[i]->normal_mpse->prep_patterns(sc) != 0 )
- FatalError("Failed to compile port group patterns for normal "
- "search engine.\n");
- }
+ queue_mpse(pg->mpsegrp[i]->normal_mpse);
if (fp->get_debug_mode())
pg->mpsegrp[i]->normal_mpse->print_info();
+
rules = 1;
}
else
{
if (pg->mpsegrp[i]->offload_mpse->get_pattern_count() != 0)
{
- if ( !sc->test_mode() or sc->mem_check() )
- {
- if ( pg->mpsegrp[i]->offload_mpse->prep_patterns(sc) != 0 )
- FatalError("Failed to compile port group patterns for offload "
- "search engine.\n");
- }
+ queue_mpse(pg->mpsegrp[i]->offload_mpse);
if (fp->get_debug_mode())
pg->mpsegrp[i]->offload_mpse->print_info();
+
rules = 1;
}
else
return 0;
}
+static unsigned can_build_mt(FastPatternConfig* fp)
+{
+ if ( Snort::is_reloading() )
+ return false;
+
+ const MpseApi* search_api = fp->get_search_api();
+ assert(search_api);
+
+ if ( !MpseManager::parallel_compiles(search_api) )
+ return false;
+
+ const MpseApi* offload_search_api = fp->get_offload_search_api();
+
+ if ( offload_search_api and !MpseManager::parallel_compiles(offload_search_api) )
+ return false;
+
+ return true;
+}
+
/*
* Port list version
*
if (fp->get_debug_print_rule_group_build_details())
LogMessage("Service Based Rule Maps Done....\n");
+ if ( !sc->test_mode() or sc->mem_check() )
+ {
+ unsigned c = compile_mpses(sc, can_build_mt(fp));
+
+ if ( c != mpse_count )
+ ParseError("Failed to compile %u search engines", mpse_count - c);
+ }
+
fp_print_port_groups(port_tables);
fp_print_service_groups(sc->spgmmTable);
unsigned count;
unsigned max;
std::vector<Node> queue;
+
+ // perf trade-off, same as Snort 2
+ // queue to keep mpse search cache warm
+ // but limit to avoid the O(n**2) effect of inserts
+ // and to get any rule hits before exhaustive searching
+ // consider a map in lieu of vector
+ const unsigned queue_limit = 32;
};
// uniquely insert into q, should splay elements for performance
if ( max and ( count == max ) )
{
pmqs.tot_inq_overruns++;
- return true;
+ return false;
}
- if ( !max or ( count < max ) )
- {
- Node node;
- node.user = user;
- node.tree = tree;
- node.index = index;
- node.list = list;
- queue.push_back(node);
- pmqs.tot_inq_uinserts++;
- pmqs.tot_inq_inserts++;
- count++;
- }
+ Node node;
+ node.user = user;
+ node.tree = tree;
+ node.index = index;
+ node.list = list;
+ queue.push_back(node);
+ pmqs.tot_inq_uinserts++;
+ pmqs.tot_inq_inserts++;
+ count++;
+
+ if ( queue.size() == queue_limit )
+ return true; // process now
return false;
}
if ( res > 0 )
{
/* terminate matching */
- pmqs.tot_inq_flush += count;
- count = 0;
+ pmqs.tot_inq_flush += i;
queue.clear();
return true;
}
}
- pmqs.tot_inq_flush += count;
- count = 0;
+ pmqs.tot_inq_flush += i;
queue.clear();
return false;
}
{
MpseStash* stash = ((IpsContext*)context)->stash;
- return stash->push(user, tree, index, list) ? 1 : 0;
+ if ( stash->push(user, tree, index, list) )
+ {
+ if ( stash->process(rule_tree_match, context) )
+ return 1;
+ }
+ return 0;
}
static inline int batch_search(
#include <cassert>
#include <cstring>
+#include <list>
+#include <mutex>
+#include <thread>
#include "ips_options/ips_flow.h"
#include "log/messages.h"
+#include "main/snort_config.h"
#include "main/thread_config.h"
+#include "pattern_match_data.h"
#include "ports/port_group.h"
#include "target_based/snort_protocols.h"
+#include "treenodes.h"
#include "utils/util.h"
#ifdef UNIT_TEST
#include "catch/snort_catch.h"
#endif
-#include "pattern_match_data.h"
-#include "treenodes.h"
-
using namespace snort;
//--------------------------------------------------------------------------
return pmds;
}
+//--------------------------------------------------------------------------
+// mpse compile threads
+//--------------------------------------------------------------------------
+
+static std::list<Mpse*> s_tbd;
+static std::mutex s_mutex;
+
+static Mpse* get_mpse()
+{
+ std::lock_guard<std::mutex> lock(s_mutex);
+
+ if ( s_tbd.empty() )
+ return nullptr;
+
+ Mpse* m = s_tbd.front();
+ s_tbd.pop_front();
+
+ return m;
+}
+
+static void compile_mpse(SnortConfig* sc, unsigned id, unsigned* count)
+{
+ set_instance_id(id);
+ unsigned c = 0;
+
+ while ( Mpse* m = get_mpse() )
+ {
+ if ( !m->prep_patterns(sc) )
+ c++;
+ }
+ std::lock_guard<std::mutex> lock(s_mutex);
+ *count += c;
+}
+
+void queue_mpse(Mpse* m)
+{
+ s_tbd.push_back(m);
+}
+
+unsigned compile_mpses(struct SnortConfig* sc, bool parallel)
+{
+ std::list<std::thread*> workers;
+ unsigned max = parallel ? sc->num_slots : 1;
+ unsigned count = 0;
+
+ if ( max == 1 )
+ {
+ compile_mpse(sc, get_instance_id(), &count);
+ return count;
+ }
+
+ for ( unsigned i = 0; i < max; ++i )
+ workers.push_back(new std::thread(compile_mpse, sc, i, &count));
+
+ for ( auto* w : workers )
+ {
+ w->join();
+ delete w;
+ }
+ return count;
+}
+
//--------------------------------------------------------------------------
// unit tests
//--------------------------------------------------------------------------
std::vector <PatternMatchData*> get_fp_content(
OptTreeNode*, OptFpList*&, bool srvc, bool only_literals, bool& exclude);
+void queue_mpse(snort::Mpse*);
+unsigned compile_mpses(struct snort::SnortConfig*, bool parallel = false);
+
#endif
typedef Mpse::MpseRespType (* MpsePollFunc)(MpseBatch*&, Mpse::MpseType);
-#define MPSE_BASE 0x00
-#define MPSE_TRIM 0x01
-#define MPSE_REGEX 0x02
-#define MPSE_ASYNC 0x04
+#define MPSE_BASE 0x00 // no optional features
+#define MPSE_TRIM 0x01 // should trim leading zero bytes from patterns
+#define MPSE_REGEX 0x02 // supports regex patterns
+#define MPSE_ASYNC 0x04 // does asynchronous (lookaside) searches
+#define MPSE_MTBLD 0x08 // support multithreaded / parallel compilation
struct MpseApi
{
}
}
-bool MpseGroup::create_normal_mpse(const char* type)
+bool MpseGroup::create_normal_mpse(SnortConfig* sc, const char* type)
{
- if ( !type and SnortConfig::get_conf()->fast_pattern_config )
- type = SnortConfig::get_conf()->fast_pattern_config->get_search_method();
+ if ( !type and sc->fast_pattern_config )
+ type = sc->fast_pattern_config->get_search_method();
if ( !type )
type = "ac_bnfa";
if (search_api)
{
Module* mod = ModuleManager::get_module(search_api->base.name);
- normal_mpse = search_api->ctor(nullptr, mod, nullptr);
+ normal_mpse = search_api->ctor(sc, mod, nullptr);
normal_mpse->set_api(search_api);
return true;
}
}
}
-bool MpseGroup::create_offload_mpse()
+bool MpseGroup::create_offload_mpse(SnortConfig* sc)
{
const MpseApi* search_api = nullptr;
const MpseApi* offload_search_api = nullptr;
- if (SnortConfig::get_conf()->fast_pattern_config )
+ if (sc->fast_pattern_config )
{
- search_api = SnortConfig::get_conf()->fast_pattern_config->get_search_api();
- offload_search_api = SnortConfig::get_conf()->fast_pattern_config->get_offload_search_api();
+ search_api = sc->fast_pattern_config->get_search_api();
+ offload_search_api = sc->fast_pattern_config->get_offload_search_api();
}
if (offload_search_api and (offload_search_api != search_api))
{
Module* mod = ModuleManager::get_module(offload_search_api->base.name);
- offload_mpse = offload_search_api->ctor(nullptr, mod, nullptr);
+ offload_mpse = offload_search_api->ctor(sc, mod, nullptr);
offload_mpse->set_api(offload_search_api);
return true;
}
{ return offload_mpse ? offload_mpse : normal_mpse; }
bool create_normal_mpse(SnortConfig*, const MpseAgent* agent);
- bool create_normal_mpse(const char*);
+ bool create_normal_mpse(SnortConfig*, const char*);
bool create_offload_mpse(SnortConfig*, const MpseAgent* agent);
- bool create_offload_mpse();
+ bool create_offload_mpse(SnortConfig*);
inline bool can_fallback() const
{ return get_offload_mpse() != normal_mpse; }
int8_t ind2 = AddVarNameToList("VALUE");
REQUIRE((ind2 == 1));
int8_t ind3 = AddVarNameToList("VAR3");
- REQUIRE((ind3 == 2));
+ REQUIRE((ind3 == IPS_OPTIONS_NO_VAR));
// Insert same name twice
REQUIRE((AddVarNameToList("VALUE") == 1));
#define PARSELEN 10
#define MAX_BYTES_TO_GRAB 4
-#define NUM_IPS_OPTIONS_VARS 3
+#define NUM_IPS_OPTIONS_VARS 2
#define IPS_OPTIONS_NO_VAR (-1)
#define INVALID_VAR_ERR_STR "%s uses an undefined rule option variable (%s)"
data.result_var = AddVarNameToList(data.result_name);
if (data.result_var == IPS_OPTIONS_NO_VAR)
{
- ParseError("Rule has more than %d variables.",
- NUM_IPS_OPTIONS_VARS);
+ ParseError("Rule has more than %d variables.", NUM_IPS_OPTIONS_VARS);
return nullptr;
}
return new ByteMathOption(m->data);
current_request->respond("== reload failed - restart required\n");
else
current_request->respond("== reload failed - bad config\n");
+
+ SnortConfig::set_parser_conf(nullptr);
return 0;
}
if ( !tc )
{
current_request->respond("== reload failed - bad config\n");
+ SnortConfig::set_parser_conf(nullptr);
return 0;
}
SnortConfig::set_conf(sc);
current_request->respond(".. swapping configuration\n", from_shell);
main_broadcast_command(new ACSwap(new Swapper(old, sc, old_tc, tc), current_request, from_shell), from_shell);
+ SnortConfig::set_parser_conf(nullptr);
return 0;
}
SFDAQ::set_local_instance(daq_instance);
set_state(State::INITIALIZED);
+ Profiler::start();
+
// Start the main loop
analyze();
+ Profiler::stop(pc.analyzed_pkts);
term();
set_state(State::STOPPED);
#define OUTPUT_U2 "unified2"
#define OUTPUT_FAST "alert_fast"
+SnortConfig* parser_conf = nullptr;
THREAD_LOCAL SnortConfig* snort_conf = nullptr;
uint32_t SnortConfig::warning_flags = 0;
return scratch_handlers.size() - 1;
}
+SO_PUBLIC SnortConfig* SnortConfig::get_parser_conf()
+{ return parser_conf; }
+
+void SnortConfig::set_parser_conf(SnortConfig* sc)
+{ parser_conf = sc; }
+
SO_PUBLIC SnortConfig* SnortConfig::get_conf()
{ return snort_conf; }
// Use this to access current thread's conf from other units
static void set_conf(SnortConfig*);
+ static void set_parser_conf(SnortConfig*);
SO_PUBLIC static SnortConfig* get_conf();
+ SO_PUBLIC static SnortConfig* get_parser_conf(); // main thread only!
SO_PUBLIC void register_reload_resource_tuner(ReloadResourceTuner& rrt)
{ reload_tuners.push_back(&rrt); }
return (api->poll);
}
+bool MpseManager::parallel_compiles(const MpseApi* api)
+{
+ assert(api);
+ return (api->flags & MPSE_MTBLD) != 0;
+}
+
// was called during drop stats but actually commented out
// FIXIT-M this one has to accumulate across threads
#if 0
static bool search_engine_trim(const snort::MpseApi*);
static bool is_async_capable(const snort::MpseApi*);
static bool is_regex_capable(const snort::MpseApi*);
+ static bool parallel_compiles(const snort::MpseApi*);
static bool is_poll_capable(const snort::MpseApi* api);
static void print_mpse_summary(const snort::MpseApi*);
static void print_search_engine_stats();
MimeDecode::init();
- /* Header search */
mime_hdr_search_mpse = new SearchTool;
+
if (mime_hdr_search_mpse == nullptr)
- {
- // FIXIT-M make configurable or at least fall back to any
- // available search engine
- FatalError("Could not instantiate ac_bnfa search engine.\n");
- }
+ FatalError("Could not instantiate search engine.\n");
for (tmp = &mime_hdrs[0]; tmp->name != nullptr; tmp++)
{
if (!print && unknown_pegs->all_zeros())
return;
- LogLabel("Appid dynamic stats:");
+ LogLabel("Appid Statistics");
+ LogLabel("detected apps and services");
+
+ LogMessage("%25.25s: %-10s %-10s %-10s %-10s %-10s %-10s %-10s\n",
+ "Application", "Flows", "Clients", "Users", "Payloads", "Misc", "Incompat.", "Failed");
for (unsigned i = 0; i < app_num; i++)
{
continue;
std::string app_name = AppIdPegCounts::appid_detectors_info[i];
- LogMessage("%s: ", app_name.c_str());
+ LogMessage("%25.25s:", app_name.c_str());
pegs->print();
}
- // Print unknown app stats
if (!unknown_pegs->all_zeros())
{
- LogMessage("unknown_app: flows: %" PRIu64 ", clients: %" PRIu64 ", users: %" PRIu64 ", payloads %"
- PRIu64 ", misc: %" PRIu64 "\n",
- unknown_pegs->stats[0], unknown_pegs->stats[1], unknown_pegs->stats[2],
- unknown_pegs->stats[3], unknown_pegs->stats[4]);
+ LogMessage("%25.25s:", "unknown");
+ unknown_pegs->print();
}
}
void print()
{
- snort::LogMessage("flows: %" PRIu64 ", clients: %" PRIu64 ", users: %" PRIu64 ", payloads %" PRIu64
- ", misc: %" PRIu64 ", incompatible: %" PRIu64 ", failed: %" PRIu64 "\n",
+ snort::LogMessage(" " FMTu64("-10") " " FMTu64("-10") " " FMTu64("-10") " " FMTu64("-10")
+ " " FMTu64("-10") " " FMTu64("-10") " " FMTu64("-10")"\n",
stats[0], stats[1], stats[2], stats[3], stats[4], stats[5], stats[6]);
}
};
return 0;
}
-int HttpPatternMatchers::process_host_patterns(DetectorHTTPPatterns patterns)
+int HttpPatternMatchers::process_host_patterns(DetectorHTTPPatterns& patterns)
{
if (!host_url_matcher)
host_url_matcher = mlmpCreate();
void insert_rtmp_url_pattern(DetectorAppUrlPattern*);
void insert_app_url_pattern(DetectorAppUrlPattern*);
int process_chp_list(CHPListElement*);
- int process_host_patterns(DetectorHTTPPatterns);
+ int process_host_patterns(DetectorHTTPPatterns&);
int process_mlmp_patterns();
void scan_key_chp(ChpMatchDescriptor&);
}
// Profiler mock functions
-void Profiler::register_module(Module*)
-{
-}
-
-void Profiler::register_module(const char*, const char*, Module*)
-{
-}
-
-void Profiler::consolidate_stats(uint64_t, uint64_t)
-{
-}
-
-void Profiler::reset_stats()
-{
-}
-
-void Profiler::show_stats()
-{
-}
-
-MemoryContext::MemoryContext(MemoryTracker&)
-{
-}
-
-MemoryContext::~MemoryContext()
-{
-}
+void Profiler::register_module(Module*) { }
+void Profiler::register_module(const char*, const char*, Module*) { }
+void Profiler::consolidate_stats() { }
+void Profiler::reset_stats() { }
+void Profiler::show_stats() { }
+
+MemoryContext::MemoryContext(MemoryTracker&) { }
+MemoryContext::~MemoryContext() { }
unsigned AppIdSession::inspector_id = 0;
THREAD_LOCAL AppIdDebug* appidDebug = nullptr;
SnortConfig* ParseSnortConf(const SnortConfig* boot_conf, const char* fname, bool is_fatal)
{
SnortConfig* sc = new SnortConfig(SnortConfig::get_conf()->proto_ref);
+ SnortConfig::set_parser_conf(sc);
sc->logging_flags = boot_conf->logging_flags;
sc->tweaks = boot_conf->tweaks;
#include "framework/module.h"
#include "main/snort_config.h"
+#include "main/thread_config.h"
+#include "time/stopwatch.h"
#include "memory_context.h"
#include "memory_profiler.h"
THREAD_LOCAL ProfileStats otherPerfStats;
THREAD_LOCAL TimeContext* ProfileContext::curr_time = nullptr;
+THREAD_LOCAL Stopwatch<SnortClock>* run_timer = nullptr;
static ProfilerNodeMap s_profiler_nodes;
s_profiler_nodes.register_node(n, pn, m);
}
-void Profiler::consolidate_stats(uint64_t num_pkts, uint64_t usecs)
+void Profiler::start()
{
- totalPerfStats.time.checks = otherPerfStats.time.checks = num_pkts;
-
-#ifdef USE_TSC_CLOCK
- totalPerfStats.time.elapsed = otherPerfStats.time.elapsed = clock_ticks(usecs);
-#else
- hr_duration dt = TO_DURATION(dt, usecs);
- totalPerfStats.time.elapsed = otherPerfStats.time.elapsed = dt;
-#endif
+ run_timer = new Stopwatch<SnortClock>;
+ run_timer->start();
+}
- const ProfilerNode& root = s_profiler_nodes.get_root();
- auto children = root.get_children();
+void Profiler::stop(uint64_t checks)
+{
+ run_timer->stop();
+ totalPerfStats.time.elapsed = run_timer->get();
+ totalPerfStats.time.checks = checks;
- for ( auto pn : children )
- otherPerfStats.time.elapsed -= pn->get_stats().time.elapsed;
+ delete run_timer;
+ run_timer = nullptr;
+}
+void Profiler::consolidate_stats()
+{
s_profiler_nodes.accumulate_nodes();
MemoryProfiler::consolidate_fallthrough_stats();
}
void Profiler::show_stats()
{
+ const ProfilerNode& root = s_profiler_nodes.get_root();
+ auto children = root.get_children();
+
+ hr_duration runtime = root.get_stats().time.elapsed;
+ hr_duration sum = 0_ticks;
+
+ for ( auto pn : children )
+ sum += pn->get_stats().time.elapsed;
+
+ otherPerfStats.time.checks = root.get_stats().time.checks;
+ otherPerfStats.time.elapsed = (runtime > sum) ? (runtime - sum) : 0_ticks;
+
+ s_profiler_nodes.accumulate_flex();
+
const auto* config = SnortConfig::get_profiler();
assert(config);
static void register_module(snort::Module*);
static void register_module(const char*, const char*, snort::Module*);
- static void consolidate_stats(uint64_t pkts = 0, uint64_t usecs = 0);
+ static void start();
+ static void stop(uint64_t);
+
+ static void consolidate_stats();
static void reset_stats();
static void show_stats();
namespace snort
{
#define ROOT_NODE "total"
+#define FLEX_NODE "other"
struct ProfilerConfig
{
it->second.accumulate();
}
+void ProfilerNodeMap::accumulate_flex()
+{
+ auto it = nodes.find(FLEX_NODE);
+
+ if ( it != nodes.end() )
+ it->second.accumulate();
+}
+
void ProfilerNodeMap::reset_nodes()
{
for ( auto it = nodes.begin(); it != nodes.end(); ++it )
void register_node(const std::string&, const char*, snort::Module*);
void accumulate_nodes();
+ void accumulate_flex();
void reset_nodes();
const ProfilerNode& get_root();
#include "framework/mpse.h"
#include "log/messages.h"
#include "main/snort_config.h"
+#include "main/thread.h"
#include "utils/stats.h"
using namespace snort;
typedef std::vector<Pattern> PatternVector;
-// we need to update scratch in the main thread as each pattern is processed
-// and then clone to thread specific after all rules are loaded. s_scratch is
-// a prototype that is large enough for all uses.
+// we need to update scratch in each compiler thread as each pattern is processed
+// and then select the largest to clone to packet thread specific after all rules
+// are loaded. s_scratch is a prototype that is large enough for all uses.
-static hs_scratch_t* s_scratch = nullptr;
+static std::vector<hs_scratch_t*> s_scratch;
static unsigned int scratch_index;
static bool scratch_registered = false;
return -2;
}
- if ( hs_error_t err = hs_alloc_scratch(hs_db, &s_scratch) )
+ if ( hs_error_t err = hs_alloc_scratch(hs_db, &s_scratch[get_instance_id()]) )
{
ParseError("can't allocate search scratch space (%d)", err);
return -3;
static void scratch_setup(SnortConfig* sc)
{
+ // find the largest scratch and clone for all slots
+ hs_scratch_t* max = nullptr;
+
for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- hs_scratch_t** ss = (hs_scratch_t**) &sc->state[i][scratch_index];
+ if ( !s_scratch[i] )
+ continue;
- if ( s_scratch )
- hs_clone_scratch(s_scratch, ss);
+ if ( !max )
+ {
+ max = s_scratch[i];
+ s_scratch[i] = nullptr;
+ continue;
+ }
+ size_t max_sz, idx_sz;
+ hs_scratch_size(max, &max_sz);
+ hs_scratch_size(s_scratch[i], &idx_sz);
+
+ if ( idx_sz > max_sz )
+ {
+ hs_free_scratch(max);
+ max = s_scratch[i];
+ }
else
- ss = nullptr;
+ {
+ hs_free_scratch(s_scratch[i]);
+ }
+ s_scratch[i] = nullptr;
}
- if ( s_scratch )
+ for ( unsigned i = 0; i < sc->num_slots; ++i )
{
- hs_free_scratch(s_scratch);
- s_scratch = nullptr;
+ hs_scratch_t** ss = (hs_scratch_t**) &sc->state[i][scratch_index];
+
+ if ( max )
+ hs_clone_scratch(max, ss);
+ else
+ *ss = nullptr;
}
+ if ( max )
+ hs_free_scratch(max);
}
static void scratch_cleanup(SnortConfig* sc)
if ( ss )
{
hs_free_scratch(ss);
- ss = nullptr;
+ sc->state[i][scratch_index] = nullptr;
}
}
}
{
if ( !scratch_registered )
{
+ s_scratch.resize(sc->num_slots);
scratch_index = SnortConfig::request_scratch(scratch_setup, scratch_cleanup);
scratch_registered = true;
}
nullptr,
nullptr
},
- MPSE_REGEX,
+ MPSE_REGEX | MPSE_MTBLD,
nullptr, // activate
nullptr, // setup
nullptr, // start
// pattern offload search method. If a method is passed in then an offload
// search engine will not be created
- if (mpsegrp->create_normal_mpse(method))
+ SnortConfig* sc = SnortConfig::get_parser_conf();
+ assert(sc);
+
+ if (mpsegrp->create_normal_mpse(sc, method))
{
if( dfa )
mpsegrp->normal_mpse->set_opt(1);
if (method == nullptr)
{
- if (mpsegrp->create_offload_mpse())
+ if (mpsegrp->create_offload_mpse(sc))
{
if ( dfa )
mpsegrp->offload_mpse->set_opt(1);
TEST(mpse_hs_base, mpse)
{
const MpseApi* mpse_api = (MpseApi*)se_hyperscan;
- CHECK(mpse_api->flags == MPSE_REGEX);
+ CHECK(mpse_api->flags == (MPSE_REGEX | MPSE_MTBLD));
CHECK(mpse_api->ctor);
CHECK(mpse_api->dtor);
SnortConfig* SnortConfig::get_conf()
{ return snort_conf; }
+SnortConfig* SnortConfig::get_parser_conf()
+{ return snort_conf; }
+
unsigned get_instance_id()
{ return 0; }
}
}
-bool MpseGroup::create_normal_mpse(const char* type)
+bool MpseGroup::create_normal_mpse(SnortConfig*, const char* type)
{
normal_mpse = MpseManager::get_search_engine(type);
return true;
}
-bool MpseGroup::create_offload_mpse()
+bool MpseGroup::create_offload_mpse(SnortConfig*)
{
offload_mpse = nullptr;
return false;
#include "http_inspect.h"
+#include <cassert>
+
#include "detection/detection_engine.h"
#include "detection/detection_util.h"
#include "log/unified2.h"
return true;
}
+void HttpInspect::show(snort::SnortConfig*)
+{
+ assert(params);
+ LogMessage("http_inspect\n");
+
+ if ( params->request_depth == -1 )
+ LogMessage(" request_depth: " "%s" "\n", "unlimited");
+ else
+ LogMessage(" request_depth: " STDi64 "\n", params->request_depth);
+
+ if ( params->response_depth == -1 )
+ LogMessage(" response_depth: " "%s" "\n", "unlimited");
+ else
+ LogMessage(" response_depth: " STDi64 "\n", params->response_depth);
+
+ LogMessage(" unzip: %s\n", params->unzip ? "yes" : "no");
+ LogMessage(" normalize_utf: %s\n", params->normalize_utf ? "yes" : "no");
+ LogMessage(" decompress_pdf: %s\n", params->decompress_pdf ? "yes" : "no");
+ LogMessage(" decompress_swf: %s\n", params->decompress_swf ? "yes" : "no");
+ LogMessage(" decompress_zip: %s\n", params->decompress_zip ? "yes" : "no");
+ LogMessage(" detained_inspection: %s\n", params->detained_inspection ? "yes" : "no");
+
+ LogMessage(" normalize_javascript: %s\n", params->js_norm_param.normalize_javascript ? "yes" : "no");
+ LogMessage(" max_javascript_whitespaces: %d\n", params->js_norm_param.max_javascript_whitespaces);
+
+ LogMessage(" percent_u: %s\n", params->uri_param.percent_u ? "yes" : "no");
+ LogMessage(" utf8: %s\n", params->uri_param.utf8 ? "yes" : "no");
+ LogMessage(" utf8_bare_byte: %s\n", params->uri_param.utf8_bare_byte ? "yes" : "no");
+ LogMessage(" oversize_dir_length: %d\n", params->uri_param.oversize_dir_length);
+ LogMessage(" iis_unicode: %s\n", params->uri_param.iis_unicode ? "yes" : "no");
+ LogMessage(" iis_unicode_map_file: %s\n", params->uri_param.iis_unicode_map_file.c_str());
+ LogMessage(" iis_double_decode: %s\n", params->uri_param.iis_double_decode ? "yes" : "no");
+ LogMessage(" backslash_to_slash: %s\n", params->uri_param.backslash_to_slash ? "yes" : "no");
+ LogMessage(" plus_to_space: %s\n", params->uri_param.plus_to_space ? "yes" : "no");
+ LogMessage(" simplify_path: %s\n", params->uri_param.simplify_path ? "yes" : "no");
+}
+
InspectSection HttpInspect::get_latest_is(const Packet* p)
{
HttpMsgSection* current_section = HttpContextData::get_snapshot(p);
snort::InspectionBuffer& b);
bool get_fp_buf(snort::InspectionBuffer::Type ibt, snort::Packet* p, snort::InspectionBuffer& b) override;
bool configure(snort::SnortConfig*) override;
- void show(snort::SnortConfig*) override { snort::LogMessage("HttpInspect\n"); }
+ void show(snort::SnortConfig*) override;
void eval(snort::Packet* p) override;
void clear(snort::Packet* p) override;
HttpStreamSplitter* get_splitter(bool is_client_to_server) override
gettimeofday(&endtime, nullptr);
}
-static void timing_stats(uint64_t& num_pkts, uint64_t& usecs)
+static void timing_stats()
{
struct timeval difftime;
TIMERSUB(&endtime, &starttime, &difftime);
-
uint32_t tmp = (uint32_t)difftime.tv_sec;
uint32_t total_secs = tmp;
if ( total_secs < 1 )
LogMessage("%25.25s: %lu.%06lu\n", "seconds",
(unsigned long)difftime.tv_sec, (unsigned long)difftime.tv_usec);
- usecs = (uint64_t)difftime.tv_sec * 1000000 + difftime.tv_usec;
- num_pkts = (uint64_t)ModuleManager::get_module("daq")->get_global_count("received");
+ uint64_t num_pkts = (uint64_t)ModuleManager::get_module("daq")->get_global_count("received");
LogMessage("%25.25s: " STDu64 "\n", "packets", num_pkts);
void PrintStatistics()
{
DropStats();
-
- PegCount pkts;
- uint64_t usecs;
- timing_stats(pkts, usecs);
+ timing_stats();
// FIXIT-L can do flag saving with RAII (much cleaner)
int save_quiet_flag = SnortConfig::get_conf()->logging_flags & LOGGING_FLAG__QUIET;
SnortConfig::get_conf()->logging_flags &= ~LOGGING_FLAG__QUIET;
// once more for the main thread
- Profiler::consolidate_stats(pkts, usecs);
+ Profiler::consolidate_stats();
+
Profiler::show_stats();
SnortConfig::get_conf()->logging_flags |= save_quiet_flag;