63static int ThresholdsInit(
struct Thresholds *t);
64static void ThresholdsDestroy(
struct Thresholds *t);
73 ThresholdsDestroy(&
ctx);
103static int ThresholdEntrySet(
void *
dst,
void *
src)
107 memset(edst, 0,
sizeof(*edst));
112static void ThresholdEntryFree(
void *ptr)
117static inline uint32_t HashAddress(
const Address *a)
121 if (a->
family == AF_INET) {
122 key = a->addr_data32[0];
123 }
else if (a->
family == AF_INET6) {
124 key =
hashword(a->addr_data32, 4, 0);
131static inline int CompareAddress(
const Address *a,
const Address *b)
136 return (a->addr_data32[0] == b->addr_data32[0]);
144static uint32_t ThresholdEntryHash(uint32_t seed,
void *ptr)
147 uint32_t hash =
hashword(e->
key,
sizeof(e->
key) /
sizeof(uint32_t), seed);
150 hash += HashAddress(&e->
addr2);
154 hash += HashAddress(&e->
addr);
160static bool ThresholdEntryCompare(
void *a,
void *b)
166 if (memcmp(e1->
key, e2->
key,
sizeof(e1->
key)) != 0)
170 if (!(CompareAddress(&e1->
addr2, &e2->
addr2)))
175 if (!(CompareAddress(&e1->
addr, &e2->
addr)))
182static bool ThresholdEntryExpire(
void *data,
const SCTime_t ts)
192static int ThresholdsInit(
struct Thresholds *t)
195 uint64_t memcap = 16 * 1024 * 1024;
200 SCLogError(
"Error parsing detect.thresholds.memcap from conf file - %s",
str);
206 if ((
SCConfGetInt(
"detect.thresholds.hash-size", &value)) == 1) {
207 if (value < 256 || value > INT_MAX) {
208 SCLogError(
"'detect.thresholds.hash-size' value %" PRIiMAX
209 " out of range. Valid range 256-2147483647.",
217 ThresholdEntryFree, ThresholdEntryHash, ThresholdEntryCompare, ThresholdEntryExpire,
219 if (t->
thash == NULL) {
220 SCLogError(
"failed to initialize thresholds hash table");
226static void ThresholdsDestroy(
struct Thresholds *t)
253static thread_local HashTable *threshold_cache_ht = NULL;
264static void DumpCacheStats(
void)
266 SCLogPerf(
"threshold thread cache stats: cnt:%" PRIu64
" notinit:%" PRIu64
" nosupport:%" PRIu64
267 " miss_expired:%" PRIu64
" miss:%" PRIu64
" hit:%" PRIu64
268 ", housekeeping: checks:%" PRIu64
", expired:%" PRIu64,
291static void ThresholdCacheExpire(
SCTime_t now)
314static uint32_t ThresholdCacheHashFunc(
HashTable *ht,
void *data, uint16_t datalen)
322static char ThresholdCacheHashCompareFunc(
323 void *data1, uint16_t datalen1,
void *data2, uint16_t datalen2)
328 memcmp(tci1->
key, tci2->
key,
sizeof(tci1->
key)) == 0;
331static void ThresholdCacheHashFreeFunc(
void *data)
337static int SetupCache(
const Packet *p,
const int8_t track,
const int8_t retval,
const uint32_t sid,
338 const uint32_t gid,
const uint32_t rev,
SCTime_t expires)
340 if (!threshold_cache_ht) {
341 threshold_cache_ht =
HashTableInit(256, ThresholdCacheHashFunc,
342 ThresholdCacheHashCompareFunc, ThresholdCacheHashFreeFunc);
347 addr = p->
src.addr_data32[0];
349 addr = p->
dst.addr_data32[0];
363 .expires_at = expires,
406static int CheckCache(
const Packet *p,
const int8_t track,
const uint32_t sid,
const uint32_t gid,
411 if (!threshold_cache_ht) {
418 addr = p->
src.addr_data32[0];
420 addr = p->
dst.addr_data32[0];
427 ThresholdCacheExpire(p->
ts);
456 if (threshold_cache_ht) {
458 threshold_cache_ht = NULL;
554 Flow *f, uint32_t sid, uint32_t gid, uint32_t rev, uint32_t tenant_id)
561 if (e->threshold.
key[
SID] == sid && e->threshold.
key[
GID] == gid &&
562 e->threshold.
key[
REV] == rev && e->threshold.
key[
TENANT] == tenant_id) {
563 return &e->threshold;
588static int ThresholdHandlePacketSuppress(
Packet *p,
624static inline void RateFilterSetAction(
PacketAlert *pa, uint8_t new_action)
626 switch (new_action) {
653static uint32_t BackoffCalcNextValue(
const uint32_t cur,
const uint32_t
m)
668 const SCTime_t packet_time,
const uint32_t sid,
const uint32_t gid,
const uint32_t rev,
669 const uint32_t tenant_id)
685 te->
tv1 = packet_time;
700 if (td->
count == 1) {
715 const uint32_t sid,
const uint32_t gid,
const uint32_t rev,
PacketAlert *pa)
732 if (PacketIsIPv4(p)) {
733 SetupCache(p, td->
track, (int8_t)ret, sid, gid, rev, entry);
767 if (PacketIsIPv4(p)) {
768 SetupCache(p, td->
track, (int8_t)ret, sid, gid, rev, entry);
799 const uint8_t original_action = pa->
action;
822 te->
tv1 = packet_time;
829 if (pa->
action == original_action) {
831 pa->
flags &= ~PACKET_ALERT_FLAG_RATE_FILTER_MODIFIED;
867 memset(&lookup, 0,
sizeof(lookup));
879 if (PacketIsIPv4(p)) {
908 r = ThresholdCheckUpdate(
de_ctx, td, te, p, s->
id, s->
gid, s->
rev, pa);
912 THashDataUnlock(res.
data);
928 SCLogDebug(
"found %p sid %u gid %u rev %u", found, sid, gid, rev);
936 ret = ThresholdSetup(td, &new->threshold, p->
ts, sid, gid, rev, p->
tenant_id);
938 if (AddEntryToFlow(f,
new, p->
ts) == -1) {
944 ret = ThresholdCheckUpdate(
de_ctx, td, found, p, sid, gid, rev, pa);
972 ret = ThresholdHandlePacketSuppress(p,td,s->
id,s->
gid);
975 int cache_ret = CheckCache(p, td->
track, s->
id, s->
gid, s->
rev);
976 if (cache_ret >= 0) {
981 ret = ThresholdGetFromHash(
de_ctx, &
ctx, p, s, td, pa);
984 int cache_ret = CheckCache(p, td->
track, s->
id, s->
gid, s->
rev);
985 if (cache_ret >= 0) {
990 ret = ThresholdGetFromHash(
de_ctx, &
ctx, p, s, td, pa);
992 ret = ThresholdGetFromHash(
de_ctx, &
ctx, p, s, td, pa);
994 ret = ThresholdGetFromHash(
de_ctx, &
ctx, p, s, td, pa);
struct HtpBodyChunk_ * next
int SCConfGetInt(const char *name, intmax_t *val)
Retrieve a configuration value as an integer.
int SCConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
#define COPY_ADDRESS(a, b)
int AddressIPv6Lt(const Address *a, const Address *b)
Compares 2 ipv6 addresses and returns if the first address(a) is less than the second address(b) or n...
DetectAddress * DetectAddressLookupInHead(const DetectAddressHead *gh, Address *a)
Find the group matching address in a group head.
@ DETECT_DETECTION_FILTER
#define PACKET_ALERT_FLAG_RATE_FILTER_MODIFIED
const DetectThresholdData * SigGetThresholdTypeIter(const Signature *sig, const SigMatchData **psm, int list)
Return next DetectThresholdData for signature.
thread_local uint64_t cache_lookup_cnt
thread_local uint64_t cache_lookup_miss
thread_local struct THRESHOLD_CACHE threshold_cache_tree
int PacketAlertThreshold(const DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx, const DetectThresholdData *td, Packet *p, const Signature *s, PacketAlert *pa)
Make the threshold logic for signatures.
thread_local uint64_t cache_lookup_nosupport
thread_local uint64_t cache_lookup_miss_expired
void ThresholdDestroy(void)
uint32_t ThresholdsExpire(const SCTime_t ts)
struct FlowVarThreshold_ FlowVarThreshold
thread_local uint64_t cache_housekeeping_expired
thread_local uint64_t cache_lookup_hit
struct ThresholdEntry_ ThresholdEntry
thread_local uint64_t cache_housekeeping_check
thread_local uint64_t cache_lookup_notinit
struct FlowThresholdEntryList_ FlowThresholdEntryList
void ThresholdCacheThreadFree(void)
void FlowThresholdVarFree(void *ptr)
thread_local uint64_t threshold_cache_housekeeping_ts
address structure for use in the detection engine.
main detection engine ctx
void * rate_filter_callback_arg
SCDetectRateFilterFunc RateFilterCallback
struct FlowThresholdEntryList_ * next
struct GenericVar_ * next
FlowThresholdEntryList * thresholds
struct HtpBodyChunk_ * next
SigMatchData * sm_arrays[DETECT_SM_LIST_MAX]
struct ThresholdEntry_::@69::@71 backoff
THashTableContext * thash
#define RB_PROTOTYPE(name, type, field, cmp)
#define RB_HEAD(name, type)
#define RB_FOREACH_SAFE(x, name, head, y)
#define RB_GENERATE(name, type, field, cmp)
#define SCLogError(...)
Macro used to log ERROR messages.
uint32_t hashword(const uint32_t *k, size_t length, uint32_t initval)
int HashTableRemove(HashTable *ht, void *data, uint16_t datalen)
int HashTableAdd(HashTable *ht, void *data, uint16_t datalen)
HashTable * HashTableInit(uint32_t size, uint32_t(*Hash)(struct HashTable_ *, void *, uint16_t), char(*Compare)(void *, uint16_t, void *, uint16_t), void(*Free)(void *))
void HashTableFree(HashTable *ht)
void * HashTableLookup(HashTable *ht, void *data, uint16_t datalen)
int ParseSizeStringU64(const char *size, uint64_t *res)
uint32_t THashExpire(THashTableContext *ctx, const SCTime_t ts)
expire data from the hash Walk the hash table and remove data that is exprired according to the DataE...
THashTableContext * THashInit(const char *cnf_prefix, uint32_t data_size, int(*DataSet)(void *, void *), void(*DataFree)(void *), uint32_t(*DataHash)(uint32_t, void *), bool(*DataCompare)(void *, void *), bool(*DataExpired)(void *, SCTime_t), uint32_t(*DataSize)(void *), bool reset_memcap, uint64_t memcap, uint32_t hashsize)
struct THashDataGetResult THashGetFromHash(THashTableContext *ctx, void *data)
void THashShutdown(THashTableContext *ctx)
shutdown the flow engine
#define THashDecrUsecnt(h)
#define SCTIME_CMP_NEQ(a, b)
#define SCTIME_CMP_GT(a, b)
#define SCTIME_CMP_LTE(a, b)
#define SCTIME_INITIALIZER
#define SCTIME_CMP_LT(a, b)
#define SCTIME_CMP_GTE(a, b)
#define SCTIME_ADD_SECS(ts, s)
#define DEBUG_VALIDATE_BUG_ON(exp)
void GenericVarAppend(GenericVar **list, GenericVar *gv)