From 932c2a7ec5e75451a813c7a70281a9df762e9ab7 Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Wed, 23 Jan 2019 21:18:59 +0100 Subject: [PATCH] eve: fix missing decoder-events in stats In the eve log the decoder events are added as optional counters. This behaviour is enabled by default. However, lots of the counters are missing, as the names colide with other counters. E.g. decoder.ipv6 counts ipv6 packets decoder.ipv6.unknown_next_header counts how often an unknown next header is encountered. In this example 'ipv6' would be both a json integer and a json object. It appears that jansson favours the first that is generated, so the event counters are mostly missing. This patch registers them as 'decoder.events.' instead. As these names are generated on the fly, a hash table to contain the allocated strings was added as well. --- src/decode.c | 53 +++++++++++++++++++++++++++++++++++++++++++++----- src/decode.h | 1 + src/suricata.c | 1 + 3 files changed, 50 insertions(+), 5 deletions(-) diff --git a/src/decode.c b/src/decode.c index 20e7a2cf24..8589086e7d 100644 --- a/src/decode.c +++ b/src/decode.c @@ -63,7 +63,7 @@ #include "util-profiling.h" #include "pkt-var.h" #include "util-mpm-ac.h" - +#include "util-hash-string.h" #include "output.h" #include "output-flow.h" @@ -125,7 +125,7 @@ void PacketUpdateEngineEventCounters(ThreadVars *tv, if (e <= DECODE_EVENT_PACKET_MAX && !stats_decoder_events) continue; - if (e > DECODE_EVENT_PACKET_MAX && !stats_stream_events) + else if (e > DECODE_EVENT_PACKET_MAX && !stats_stream_events) continue; StatsIncr(tv, dtv->counter_engine_events[e]); } @@ -413,6 +413,20 @@ void PacketBypassCallback(Packet *p) } } +/* counter name store */ +static HashTable *g_counter_table = NULL; +static SCMutex g_counter_table_mutex = SCMUTEX_INITIALIZER; + +void DecodeUnregisterCounters(void) +{ + SCMutexLock(&g_counter_table_mutex); + if (g_counter_table) { + HashTableFree(g_counter_table); + g_counter_table = NULL; + } + SCMutexUnlock(&g_counter_table_mutex); +} + void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) { /* register counters */ @@ -470,11 +484,40 @@ void DecodeRegisterPerfCounters(DecodeThreadVars *dtv, ThreadVars *tv) if (i <= DECODE_EVENT_PACKET_MAX && !stats_decoder_events) continue; - if (i > DECODE_EVENT_PACKET_MAX && !stats_stream_events) + else if (i > DECODE_EVENT_PACKET_MAX && !stats_stream_events) continue; - dtv->counter_engine_events[i] = StatsRegisterCounter( - DEvents[i].event_name, tv); + if (i < DECODE_EVENT_PACKET_MAX && + strncmp(DEvents[i].event_name, "decoder.", 8) == 0) + { + SCMutexLock(&g_counter_table_mutex); + if (g_counter_table == NULL) { + g_counter_table = HashTableInit(256, StringHashFunc, + StringHashCompareFunc, + StringHashFreeFunc); + BUG_ON(g_counter_table == NULL); + } + + char name[256]; + char *dot = index(DEvents[i].event_name, '.'); + BUG_ON(!dot); + snprintf(name, sizeof(name), "decoder.events.%s", dot+1); + + const char *found = HashTableLookup(g_counter_table, name, 0); + if (!found) { + char *add = SCStrdup(name); + BUG_ON(!add); + HashTableAdd(g_counter_table, add, 0); + found = add; + } + dtv->counter_engine_events[i] = StatsRegisterCounter( + found, tv); + + SCMutexUnlock(&g_counter_table_mutex); + } else { + dtv->counter_engine_events[i] = StatsRegisterCounter( + DEvents[i].event_name, tv); + } } return; diff --git a/src/decode.h b/src/decode.h index 5931304b98..675d141ab1 100644 --- a/src/decode.h +++ b/src/decode.h @@ -971,6 +971,7 @@ int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder); int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder); #endif void DecodeGlobalConfig(void); +void DecodeUnregisterCounters(void); /** \brief Set the No payload inspection Flag for the packet. * diff --git a/src/suricata.c b/src/suricata.c index 7a8b27f646..a9e8c806fe 100644 --- a/src/suricata.c +++ b/src/suricata.c @@ -2327,6 +2327,7 @@ void PostRunDeinit(const int runmode, struct timeval *start_time) /* mgt and ppt threads killed, we can run non thread-safe * shutdown functions */ StatsReleaseResources(); + DecodeUnregisterCounters(); RunModeShutDown(); FlowShutdown(); IPPairShutdown();