file_stats_print();
}
+void FileIdModule::reset_stats()
+{
+ file_stats_clear();
+ Module::reset_stats();
+}
void load_config(FileConfig*& dst);
+ void reset_stats() override;
+
Usage get_usage() const override
{ return GLOBAL; }
}
}
+void file_stats_clear()
+{
+ memset(&file_counts, 0, sizeof(file_counts));
+ memset(&file_totals, 0, sizeof(file_totals));
+ if (file_stats)
+ memset(file_stats, 0, sizeof(*file_stats));
+}
+
void file_stats_print()
{
uint64_t processed_total[2];
void file_stats_sum();
void file_stats_print();
+void file_stats_clear();
#endif
unsigned long get_realized() { return realized; }
unsigned long get_prunes() { return prunes; }
unsigned long get_overflows() { return overflows; }
+ void reset_stats()
+ {
+ expects = 0;
+ realized = 0;
+ prunes = 0;
+ overflows = 0;
+ }
private:
void prune_lru();
void Module::reset_stats()
{
+ PegCount* p = get_counts();
+
+ if ( !p )
+ return;
+
+ const PegInfo* pegs = get_pegs();
+
+ if ( !pegs )
+ return;
+
if ( num_counts <= 0 )
{
num_counts = 0;
- const PegInfo* pegs = get_pegs();
-
- if ( !pegs )
- return;
while ( pegs[num_counts].name )
++num_counts;
}
for ( int i = 0; i < num_counts; i++ )
+ {
counts[i] = 0;
+
+ if ( pegs[i].type != CountType::NOW )
+ p[i] = 0;
+ }
}
PegCount Module::get_global_count(const char* name) const
return 0;
}
+int main_reset_stats(lua_State* L)
+{
+ int type = luaL_optint(L, 1, 0);
+ bool from_shell = ( L != nullptr );
+ current_request->respond("== clearing stats\n", from_shell);
+ main_broadcast_command(new ACResetStats(static_cast<clear_counter_type_t>(type)), true);
+ return 0;
+}
+
int main_rotate_stats(lua_State* L)
{
bool from_shell = ( L != nullptr );
// commands provided by the snort module
int main_delete_inspector(lua_State* = nullptr);
int main_dump_stats(lua_State* = nullptr);
+int main_reset_stats(lua_State* = nullptr);
int main_rotate_stats(lua_State* = nullptr);
int main_reload_config(lua_State* = nullptr);
int main_reload_policy(lua_State* = nullptr);
LogMessage("==================================================\n"); // Marking End of stats
}
+bool ACResetStats::execute(Analyzer&, void**)
+{
+ ModuleManager::reset_stats(requested_type);
+ return true;
+}
+
+ACResetStats::ACResetStats(clear_counter_type_t requested_type_l) : requested_type(
+ requested_type_l) { }
+
ACSwap::ACSwap(Swapper* ps, SharedRequest req, bool from_shell) : ps(ps), request(req), from_shell(from_shell)
{
assert(Swapper::get_reload_in_progress() == false);
~ACGetStats() override;
};
+typedef enum clear_counter_type
+{
+ TYPE_UNKNOWN=-1,
+ TYPE_DAQ=0,
+ TYPE_MODULE,
+ TYPE_APPID,
+ TYPE_FILE_ID,
+ TYPE_SNORT,
+ TYPE_HA
+} clear_counter_type_t;
+
+// FIXIT-M Will replace this vector with an unordered map of
+// <clear_counter_type, clear_counter_type_string_map> when
+// will come up with more granular form of clearing module stats.
+static std::vector<const char*> clear_counter_type_string_map
+{
+ "daq",
+ "module",
+ "appid",
+ "file_id",
+ "snort",
+ "high_availability"
+};
+
+class ACResetStats : public snort::AnalyzerCommand
+{
+public:
+ explicit ACResetStats(clear_counter_type_t requested_type);
+ bool execute(Analyzer&, void**) override;
+ const char* stringify() override { return "RESET_STATS"; }
+private:
+ clear_counter_type_t requested_type;
+};
+
class ACPause : public snort::AnalyzerCommand
{
public:
HighAvailabilityManager::configure(sc->ha_config);
+ ModuleManager::reset_stats(sc);
+
if (sc->alert_before_pass())
sc->rule_order = "reset block drop alert pass log";
// Must be after InspectorManager::configure()
FileService::post_init(sc);
- ModuleManager::reset_stats(sc);
-
if (sc->file_mask != 0)
umask(sc->file_mask);
else
"delete an inspector from the default policy" },
{ "dump_stats", main_dump_stats, nullptr, "show summary statistics" },
+ { "reset_stats", main_reset_stats, nullptr, "clear summary statistics" },
{ "rotate_stats", main_rotate_stats, nullptr, "roll perfmonitor log files" },
{ "reload_config", main_reload_config, s_reload_w_path, "load new configuration" },
{ "reload_policy", main_reload_policy, s_reload, "reload part or all of the default policy" },
#include "parser/parse_conf.h"
#include "parser/parser.h"
#include "profiler/profiler.h"
+#include "protocols/packet_manager.h"
#include "utils/util.h"
#include "plugin_manager.h"
}
}
+void ModuleManager::reset_stats(clear_counter_type_t type)
+{
+ if ( type != TYPE_MODULE and type != TYPE_UNKNOWN )
+ {
+ ModHook* mh = get_hook(clear_counter_type_string_map[type]);
+ if ( mh and mh->mod )
+ {
+ lock_guard<mutex> lock(stats_mutex);
+ mh->mod->reset_stats();
+ }
+
+ }
+ else
+ {
+ auto mod_hooks = get_all_modhooks();
+ for ( auto* mh : mod_hooks )
+ {
+ bool ignore = false;
+
+ // FIXIT-M Will remove this for loop when will come up with more
+ // granular form of clearing module stats.
+ for ( int i = 0; i < static_cast<int>(clear_counter_type_string_map.size()); i++ )
+ {
+ if ( !strcmp(mh->mod->get_name(), clear_counter_type_string_map[i]) )
+ {
+ ignore = true;
+ break;
+ }
+ }
+
+ if ( type == TYPE_UNKNOWN or !ignore )
+ {
+ lock_guard<mutex> lock(stats_mutex);
+ mh->mod->reset_stats();
+ }
+ }
+ }
+ if ( type == TYPE_DAQ or type == TYPE_UNKNOWN )
+ {
+ lock_guard<mutex> lock(stats_mutex);
+ PacketManager::reset_stats();
+ }
+}
+
+
+
//-------------------------------------------------------------------------
// parameter loading
//-------------------------------------------------------------------------
#include <mutex>
#include <set>
+#include "main/analyzer_command.h"
#include "main/snort_types.h"
//-------------------------------------------------------------------------
static void accumulate();
static void accumulate_offload(const char* name);
static void reset_stats(SnortConfig*);
+ static void reset_stats(clear_counter_type_t);
static std::set<uint32_t> gids;
SO_PUBLIC static std::mutex stats_mutex;
AppIdPegCounts::print();
}
+void AppIdModule::reset_stats()
+{
+ AppIdPegCounts::cleanup_dynamic_sum();
+ Module::reset_stats();
+}
+
bool AppIdReloadTuner::tinit()
{
return AppIdServiceState::initialize(memcap);
const AppIdConfig* get_data();
+ void reset_stats() override;
+
Usage get_usage() const override
{ return CONTEXT; }
void sum_stats(bool) override;
appid_detector_pegs_idx.clear();
}
+void AppIdPegCounts::cleanup_dynamic_sum()
+{
+ if ( !appid_peg_counts )
+ return;
+
+ for ( unsigned app_num = 0; app_num < AppIdPegCounts::appid_detectors_info.size(); app_num++ )
+ {
+ memset(appid_dynamic_sum[app_num].stats, 0, sizeof(PegCount) *
+ DetectorPegs::NUM_APPID_DETECTOR_PEGS);
+ memset((*appid_peg_counts)[app_num].stats, 0, sizeof(PegCount) *
+ DetectorPegs::NUM_APPID_DETECTOR_PEGS);
+ }
+}
+
void AppIdPegCounts::add_app_peg_info(std::string app_name, AppId app_id)
{
std::replace(app_name.begin(), app_name.end(), ' ', '_');
if (!appid_peg_counts)
return;
- const unsigned peg_num = appid_peg_counts->size() - 1;
+ const unsigned peg_num = appid_peg_counts->size() ? (appid_peg_counts->size() - 1) : 0;
const AppIdDynamicPeg* ptr = (AppIdDynamicPeg*)appid_peg_counts->data();
for ( unsigned i = 0; i < peg_num; ++i )
{
if (increment)
(*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::SERVICE_DETECTS]++;
- else
+ else if ((*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::SERVICE_DETECTS])
(*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::SERVICE_DETECTS]--;
}
{
if (increment)
(*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::CLIENT_DETECTS]++;
- else
+ else if ((*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::CLIENT_DETECTS])
(*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::CLIENT_DETECTS]--;
}
{
if (increment)
(*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::PAYLOAD_DETECTS]++;
- else
+ else if ((*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::PAYLOAD_DETECTS])
(*appid_peg_counts)[get_stats_index(id)].stats[DetectorPegs::PAYLOAD_DETECTS]--;
}
static void init_pegs();
static void cleanup_pegs();
static void cleanup_peg_info();
+ static void cleanup_dynamic_sum();
static void update_service_count(AppId id, bool increment);
static void update_client_count(AppId id, bool increment);
DnsPatternMatchers::~DnsPatternMatchers() { }
SipPatternMatchers::~SipPatternMatchers() { }
SslPatternMatchers::~SslPatternMatchers() { }
+void AppIdModule::reset_stats() {}
TEST_GROUP(http_url_patterns_tests)
{
StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
}
+void AppIdModule::reset_stats() {}
+
class DummyInspector : public snort::Inspector
{
public:
void AppIdHttpSession::set_http_change_bits(AppidChangeBits&, HttpFieldIds) {}
+void AppIdModule::reset_stats() {}
+
class TestDetector : public AppIdDetector
{
public:
AppIdSessionApi::AppIdSessionApi(const AppIdSession*, const SfIp&) :
StashGenericObject(STASH_GENERIC_OBJECT_APPID) {}
} // namespace snort
+void AppIdModule::reset_stats() {}
// Stubs for publish
void DataBus::publish(const char*, DataEvent& event, Flow*)
{
return nullptr;
}
+void AppIdModule::reset_stats() {}
void AppIdSession::set_application_ids_service(AppId, AppidChangeBits&) {}
void AppIdSession::set_ss_application_ids(AppId, AppId, AppId, AppId, AppId, AppidChangeBits&) {}
AppIdHttpSession* AppIdSession::get_http_session(uint32_t stream_index) const
return true;
}
+void AppIdModule::reset_stats() {}
+
// AppIdDebug mock functions
void AppIdDebug::activate(const uint32_t*, const uint32_t*, uint16_t,
uint16_t, IpProtocol, const int, uint16_t, const AppIdSession*, bool,
static Flow flow;
void ApplicationDescriptor::set_id(const Packet&, AppIdSession&, AppidSessionDirection, AppId, AppidChangeBits&) { }
+void AppIdModule::reset_stats() {}
Inspector* InspectorManager::get_inspector(char const*, bool, const snort::SnortConfig*)
{
prev_daq_stats = new_daq_stats;
}
+void SFDAQModule::reset_stats()
+{
+ Trough::clear_file_count();
+ Module::reset_stats();
+}
const PegInfo* get_pegs() const override;
PegCount* get_counts() const override;
void prep_counts() override;
+ void reset_stats() override;
bool counts_need_prep() const override
{ return true; }
{
return file_count;
}
+ static void clear_file_count()
+ {
+ file_count = 0;
+ }
static unsigned get_queue_size()
{
return pcap_queue.size();
(unsigned int)pkt_names.size(), "codec");
}
+void PacketManager::reset_stats()
+{
+ std::fill(std::begin(g_stats), std::end(g_stats), 0);
+ std::fill(std::begin(s_stats), std::end(s_stats), 0);
+}
+
void PacketManager::accumulate()
{
static std::mutex stats_mutex;
// print codec information. MUST be called after thread_term.
static void dump_stats();
+ static void reset_stats();
+
// Get the name of the given protocol ID
static const char* get_proto_name(ProtocolId);
{
sum_stats((PegCount*)&g_stats, (PegCount*)&stream_base_stats,
array_size(base_pegs) - 1);
- base_reset();
+ base_reset(false);
}
void base_stats()
show_stats((PegCount*)&g_stats, base_pegs, array_size(base_pegs) - 1, MOD_NAME);
}
-void base_reset()
+void base_reset(bool reset_all)
{
if ( flow_con )
flow_con->clear_counts();
memset(&stream_base_stats, 0, sizeof(stream_base_stats));
+
+ if ( reset_all )
+ {
+ if ( flow_con )
+ {
+ ExpectCache* exp_cache = flow_con->get_exp_cache();
+ if ( exp_cache )
+ exp_cache->reset_stats();
+ }
+ memset(&g_stats, 0, sizeof(g_stats));
+ }
}
//-------------------------------------------------------------------------
extern void base_prep();
extern void base_sum();
extern void base_stats();
-extern void base_reset();
+extern void base_reset(bool reset_all=true);
#endif
#endif
#include "tcp_module.h"
+#include "tcp_normalizer.h"
#include "main/snort_config.h"
#include "profiler/profiler_defs.h"
PegCount* StreamTcpModule::get_counts() const
{ return (PegCount*)&tcpStats; }
+void StreamTcpModule::reset_stats()
+{
+ TcpNormalizer::reset_stats();
+ Module::reset_stats();
+}
const snort::RuleMap* get_rules() const override;
+ void reset_stats() override;
+
unsigned get_gid() const override
{ return GID_STREAM_TCP; }
return urg_offset;
}
+void TcpNormalizer::reset_stats()
+{
+ for (int i = 0; i < PC_TCP_MAX; i++)
+ for (int j = 0; j < NORM_MODE_MAX; j++)
+ tcp_norm_stats[i][j] = 0;
+}
static const PegInfo* get_normalization_pegs();
static NormPegs get_normalization_counts(unsigned&);
+ static void reset_stats();
protected:
TcpNormalizer() = default;