thresholds: use dedicated storage

Instead of a Host and IPPair table thresholding layer, use a dedicated
THash to store both. This allows hashing on host+sid+tracker or
ippair+sid+tracker, to create more unique hash keys.

This allows for fewer hash collisions.

The per rule tracking also uses this, so that the single big lock is no
longer a single point of contention.

Reimplement storage for flow thresholds to reuse as much logic as
possible from the host/ippair/rule thresholds.

Ticket: #426.
pull/11394/head
Victor Julien 2 years ago
parent ac400af8f4
commit b8028bf386

@ -378,7 +378,7 @@ static int DetectDetectionFilterTestSig1(void)
ThreadVars th_v; ThreadVars th_v;
DetectEngineThreadCtx *det_ctx; DetectEngineThreadCtx *det_ctx;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -418,7 +418,7 @@ static int DetectDetectionFilterTestSig1(void)
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -435,7 +435,7 @@ static int DetectDetectionFilterTestSig2(void)
ThreadVars th_v; ThreadVars th_v;
DetectEngineThreadCtx *det_ctx; DetectEngineThreadCtx *det_ctx;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -480,7 +480,7 @@ static int DetectDetectionFilterTestSig2(void)
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -493,7 +493,7 @@ static int DetectDetectionFilterTestSig3(void)
ThreadVars th_v; ThreadVars th_v;
DetectEngineThreadCtx *det_ctx; DetectEngineThreadCtx *det_ctx;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -556,7 +556,7 @@ static int DetectDetectionFilterTestSig3(void)
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }

@ -2219,8 +2219,6 @@ int SigGroupBuild(DetectEngineCtx *de_ctx)
SCProfilingRuleInitCounters(de_ctx); SCProfilingRuleInitCounters(de_ctx);
#endif #endif
ThresholdHashAllocate(de_ctx);
if (!DetectEngineMultiTenantEnabled()) { if (!DetectEngineMultiTenantEnabled()) {
VarNameStoreActivate(); VarNameStoreActivate();
} }

@ -71,34 +71,150 @@
#include "action-globals.h" #include "action-globals.h"
#include "util-validate.h" #include "util-validate.h"
static HostStorageId host_threshold_id = { .id = -1 }; /**< host storage id for thresholds */ #include "util-thash.h"
static IPPairStorageId ippair_threshold_id = { .id = -1 }; /**< ip pair storage id for thresholds */ #include "util-hash-lookup3.h"
HostStorageId ThresholdHostStorageId(void) struct Thresholds {
THashTableContext *thash;
} ctx;
static int ThresholdsInit(struct Thresholds *t);
static void ThresholdsDestroy(struct Thresholds *t);
void ThresholdInit(void)
{ {
return host_threshold_id; ThresholdsInit(&ctx);
} }
void ThresholdInit(void) void ThresholdDestroy(void)
{
ThresholdsDestroy(&ctx);
}
typedef struct ThresholdEntry_ {
uint32_t sid; /**< Signature id */
uint32_t gid; /**< Signature group id */
int track; /**< Track type: by_src, by_dst, etc */
uint32_t tv_timeout; /**< Timeout for new_action (for rate_filter)
its not "seconds", that define the time interval */
uint32_t seconds; /**< Event seconds */
uint32_t current_count; /**< Var for count control */
SCTime_t tv1; /**< Var for time control */
Address addr; /* used for src/dst/either tracking */
Address addr2; /* used for both tracking */
} ThresholdEntry;
static int ThresholdEntrySet(void *dst, void *src)
{
const ThresholdEntry *esrc = src;
ThresholdEntry *edst = dst;
memset(edst, 0, sizeof(*edst));
*edst = *esrc;
return 0;
}
static void ThresholdEntryFree(void *ptr)
{
// nothing to free, base data is part of hash
}
static inline uint32_t HashAddress(const Address *a)
{
uint32_t key;
if (a->family == AF_INET) {
key = a->addr_data32[0];
} else if (a->family == AF_INET6) {
key = hashword(a->addr_data32, 4, 0);
} else
key = 0;
return key;
}
static inline int CompareAddress(const Address *a, const Address *b)
{
if (a->family == b->family) {
switch (a->family) {
case AF_INET:
return (a->addr_data32[0] == b->addr_data32[0]);
case AF_INET6:
return CMP_ADDR(a, b);
}
}
return 0;
}
static uint32_t ThresholdEntryHash(void *ptr)
{
const ThresholdEntry *e = ptr;
uint32_t hash = e->sid + e->gid + e->track;
switch (e->track) {
case TRACK_BOTH:
hash += HashAddress(&e->addr2);
/* fallthrough */
case TRACK_SRC:
case TRACK_DST:
hash += HashAddress(&e->addr);
break;
}
return hash;
}
static bool ThresholdEntryCompare(void *a, void *b)
{ {
host_threshold_id = HostStorageRegister("threshold", sizeof(void *), NULL, ThresholdListFree); const ThresholdEntry *e1 = a;
if (host_threshold_id.id == -1) { const ThresholdEntry *e2 = b;
FatalError("Can't initiate host storage for thresholding"); SCLogDebug("sid1: %u sid2: %u", e1->sid, e2->sid);
if (!(e1->sid == e2->sid && e1->gid == e2->gid && e1->track == e2->track))
return false;
switch (e1->track) {
case TRACK_BOTH:
if (!(CompareAddress(&e1->addr2, &e2->addr2)))
return false;
/* fallthrough */
case TRACK_SRC:
case TRACK_DST:
if (!(CompareAddress(&e1->addr, &e2->addr)))
return false;
break;
} }
ippair_threshold_id = IPPairStorageRegister("threshold", sizeof(void *), NULL, ThresholdListFree); return true;
if (ippair_threshold_id.id == -1) { }
FatalError("Can't initiate IP pair storage for thresholding");
static bool ThresholdEntryExpire(void *data, const SCTime_t ts)
{
const ThresholdEntry *e = data;
const SCTime_t entry = SCTIME_ADD_SECS(e->tv1, e->seconds);
if (SCTIME_CMP_GT(ts, entry)) {
return true;
} }
return false;
} }
int ThresholdHostHasThreshold(Host *host) static int ThresholdsInit(struct Thresholds *t)
{ {
return HostGetStorageById(host, host_threshold_id) ? 1 : 0; uint64_t memcap = 16 * 1024 * 1024;
uint32_t hashsize = 16384;
t->thash = THashInit("thresholds", sizeof(ThresholdEntry), ThresholdEntrySet,
ThresholdEntryFree, ThresholdEntryHash, ThresholdEntryCompare, ThresholdEntryExpire, 0,
memcap, hashsize);
BUG_ON(t->thash == NULL);
return 0;
}
static void ThresholdsDestroy(struct Thresholds *t)
{
if (t->thash) {
THashShutdown(t->thash);
}
} }
int ThresholdIPPairHasThreshold(IPPair *pair) uint32_t ThresholdsExpire(const SCTime_t ts)
{ {
return IPPairGetStorageById(pair, ippair_threshold_id) ? 1 : 0; return THashExpire(ctx.thash, ts);
} }
#include "util-hash.h" #include "util-hash.h"
@ -234,7 +350,9 @@ static int SetupCache(const Packet *p, const int8_t track, const int8_t retval,
n->expires_at = expires; n->expires_at = expires;
if (HashTableAdd(threshold_cache_ht, n, 0) == 0) { if (HashTableAdd(threshold_cache_ht, n, 0) == 0) {
(void)THRESHOLD_CACHE_RB_INSERT(&threshold_cache_tree, n); ThresholdCacheItem *r = THRESHOLD_CACHE_RB_INSERT(&threshold_cache_tree, n);
DEBUG_VALIDATE_BUG_ON(r != NULL); // duplicate; should be impossible
(void)r; // only used by DEBUG_VALIDATE_BUG_ON
return 1; return 1;
} }
SCFree(n); SCFree(n);
@ -358,98 +476,18 @@ const DetectThresholdData *SigGetThresholdTypeIter(
return NULL; return NULL;
} }
/** typedef struct FlowThresholdEntryList_ {
* \brief Remove timeout threshold hash elements struct FlowThresholdEntryList_ *next;
* ThresholdEntry threshold;
* \param head Current head element of storage } FlowThresholdEntryList;
* \param tv Current time
*
* \retval DetectThresholdEntry Return new head element or NULL if all expired
*
*/
static DetectThresholdEntry *ThresholdTimeoutCheck(DetectThresholdEntry *head, SCTime_t ts)
{
DetectThresholdEntry *tmp = head;
DetectThresholdEntry *prev = NULL;
DetectThresholdEntry *new_head = head;
while (tmp != NULL) {
/* check if the 'check' timestamp is not before the creation ts.
* This can happen due to the async nature of the host timeout
* code that also calls this code from a management thread. */
SCTime_t entry = SCTIME_ADD_SECS(tmp->tv1, (time_t)tmp->seconds);
if (SCTIME_CMP_LTE(ts, entry)) {
prev = tmp;
tmp = tmp->next;
continue;
}
/* timed out */
DetectThresholdEntry *tde = tmp;
if (prev != NULL) {
prev->next = tmp->next;
}
else {
new_head = tmp->next;
}
tmp = tde->next;
SCFree(tde);
}
return new_head;
}
int ThresholdHostTimeoutCheck(Host *host, SCTime_t ts)
{
DetectThresholdEntry* head = HostGetStorageById(host, host_threshold_id);
DetectThresholdEntry *new_head = ThresholdTimeoutCheck(head, ts);
if (new_head != head) {
HostSetStorageById(host, host_threshold_id, new_head);
}
return new_head == NULL;
}
int ThresholdIPPairTimeoutCheck(IPPair *pair, SCTime_t ts)
{
DetectThresholdEntry* head = IPPairGetStorageById(pair, ippair_threshold_id);
DetectThresholdEntry *new_head = ThresholdTimeoutCheck(head, ts);
if (new_head != head) {
IPPairSetStorageById(pair, ippair_threshold_id, new_head);
}
return new_head == NULL;
}
static DetectThresholdEntry *DetectThresholdEntryAlloc( static void FlowThresholdEntryListFree(FlowThresholdEntryList *list)
const DetectThresholdData *td, uint32_t sid, uint32_t gid)
{ {
SCEnter(); for (FlowThresholdEntryList *i = list; i != NULL;) {
FlowThresholdEntryList *next = i->next;
DetectThresholdEntry *ste = SCCalloc(1, sizeof(DetectThresholdEntry)); SCFree(i);
if (unlikely(ste == NULL)) { i = next;
SCReturnPtr(NULL, "DetectThresholdEntry");
} }
ste->sid = sid;
ste->gid = gid;
ste->track = td->track;
ste->seconds = td->seconds;
SCReturnPtr(ste, "DetectThresholdEntry");
}
static DetectThresholdEntry *ThresholdHostLookupEntry(Host *h,
uint32_t sid, uint32_t gid)
{
DetectThresholdEntry *e;
for (e = HostGetStorageById(h, host_threshold_id); e != NULL; e = e->next) {
if (e->sid == sid && e->gid == gid)
break;
}
return e;
} }
/** struct for storing per flow thresholds. This will be stored in the Flow::flowvar list, so it /** struct for storing per flow thresholds. This will be stored in the Flow::flowvar list, so it
@ -458,13 +496,13 @@ typedef struct FlowVarThreshold_ {
uint8_t type; uint8_t type;
uint8_t pad[7]; uint8_t pad[7];
struct GenericVar_ *next; struct GenericVar_ *next;
DetectThresholdEntry *thresholds; FlowThresholdEntryList *thresholds;
} FlowVarThreshold; } FlowVarThreshold;
void FlowThresholdVarFree(void *ptr) void FlowThresholdVarFree(void *ptr)
{ {
FlowVarThreshold *t = ptr; FlowVarThreshold *t = ptr;
ThresholdListFree(t->thresholds); FlowThresholdEntryListFree(t->thresholds);
SCFree(t); SCFree(t);
} }
@ -481,21 +519,21 @@ static FlowVarThreshold *FlowThresholdVarGet(Flow *f)
return NULL; return NULL;
} }
static DetectThresholdEntry *ThresholdFlowLookupEntry(Flow *f, uint32_t sid, uint32_t gid) static ThresholdEntry *ThresholdFlowLookupEntry(Flow *f, uint32_t sid, uint32_t gid)
{ {
FlowVarThreshold *t = FlowThresholdVarGet(f); FlowVarThreshold *t = FlowThresholdVarGet(f);
if (t == NULL) if (t == NULL)
return NULL; return NULL;
for (DetectThresholdEntry *e = t->thresholds; e != NULL; e = e->next) { for (FlowThresholdEntryList *e = t->thresholds; e != NULL; e = e->next) {
if (e->sid == sid && e->gid == gid) { if (e->threshold.sid == sid && e->threshold.gid == gid) {
return e; return &e->threshold;
} }
} }
return NULL; return NULL;
} }
static int AddEntryToFlow(Flow *f, DetectThresholdEntry *e, SCTime_t packet_time) static int AddEntryToFlow(Flow *f, FlowThresholdEntryList *e, SCTime_t packet_time)
{ {
DEBUG_VALIDATE_BUG_ON(e == NULL); DEBUG_VALIDATE_BUG_ON(e == NULL);
@ -509,27 +547,11 @@ static int AddEntryToFlow(Flow *f, DetectThresholdEntry *e, SCTime_t packet_time
GenericVarAppend(&f->flowvar, (GenericVar *)t); GenericVarAppend(&f->flowvar, (GenericVar *)t);
} }
e->current_count = 1;
e->tv1 = packet_time;
e->tv_timeout = 0;
e->next = t->thresholds; e->next = t->thresholds;
t->thresholds = e; t->thresholds = e;
return 0; return 0;
} }
static DetectThresholdEntry *ThresholdIPPairLookupEntry(IPPair *pair,
uint32_t sid, uint32_t gid)
{
DetectThresholdEntry *e;
for (e = IPPairGetStorageById(pair, ippair_threshold_id); e != NULL; e = e->next) {
if (e->sid == sid && e->gid == gid)
break;
}
return e;
}
static int ThresholdHandlePacketSuppress(Packet *p, static int ThresholdHandlePacketSuppress(Packet *p,
const DetectThresholdData *td, uint32_t sid, uint32_t gid) const DetectThresholdData *td, uint32_t sid, uint32_t gid)
{ {
@ -591,285 +613,208 @@ static inline void RateFilterSetAction(PacketAlert *pa, uint8_t new_action)
} }
} }
/** static int ThresholdSetup(const DetectThresholdData *td, ThresholdEntry *te,
* \brief Check if the entry reached threshold count limit const SCTime_t packet_time, const uint32_t sid, const uint32_t gid)
*
* \param lookup_tsh Current threshold entry
* \param td Threshold settings
* \param packet_time used to compare against previous detection and to set timeouts
*
* \retval int 1 if threshold reached for this entry
*
*/
static int IsThresholdReached(
DetectThresholdEntry *lookup_tsh, const DetectThresholdData *td, SCTime_t packet_time)
{ {
int ret = 0; te->sid = sid;
te->gid = gid;
/* Check if we have a timeout enabled, if so, te->track = td->track;
* we still matching (and enabling the new_action) */ te->seconds = td->seconds;
if (lookup_tsh->tv_timeout != 0) {
if ((SCTIME_SECS(packet_time) - lookup_tsh->tv_timeout) > td->timeout) {
/* Ok, we are done, timeout reached */
lookup_tsh->tv_timeout = 0;
} else {
/* Already matching */
ret = 1;
} /* else - if ((packet_time - lookup_tsh->tv_timeout) > td->timeout) */
}
else {
/* Update the matching state with the timeout interval */
SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
if (SCTIME_CMP_LTE(packet_time, entry)) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count > td->count) {
/* Then we must enable the new action by setting a
* timeout */
lookup_tsh->tv_timeout = SCTIME_SECS(packet_time);
ret = 1;
}
} else {
lookup_tsh->tv1 = packet_time;
lookup_tsh->current_count = 1;
}
} /* else - if (lookup_tsh->tv_timeout != 0) */
return ret;
}
static void AddEntryToHostStorage(Host *h, DetectThresholdEntry *e, SCTime_t packet_time) te->current_count = 1;
{ te->tv1 = packet_time;
if (h && e) { te->tv_timeout = 0;
e->current_count = 1;
e->tv1 = packet_time;
e->tv_timeout = 0;
e->next = HostGetStorageById(h, host_threshold_id);
HostSetStorageById(h, host_threshold_id, e);
}
}
static void AddEntryToIPPairStorage(IPPair *pair, DetectThresholdEntry *e, SCTime_t packet_time) switch (td->type) {
{ case TYPE_LIMIT:
if (pair && e) { case TYPE_RATE:
e->current_count = 1; return 1;
e->tv1 = packet_time; case TYPE_THRESHOLD:
e->tv_timeout = 0; case TYPE_BOTH:
e->next = IPPairGetStorageById(pair, ippair_threshold_id); if (td->count == 1)
IPPairSetStorageById(pair, ippair_threshold_id, e); return 1;
return 0;
case TYPE_DETECTION:
return 0;
} }
return 0;
} }
/** static int ThresholdCheckUpdate(const DetectThresholdData *td, ThresholdEntry *te,
* \retval 2 silent match (no alert but apply actions) const Packet *p, // ts only? - cache too
* \retval 1 normal match const uint32_t sid, PacketAlert *pa)
* \retval 0 no match
*
* If a new DetectThresholdEntry is generated to track the threshold
* for this rule, then it will be returned in new_tsh.
*/
static int ThresholdHandlePacket(Packet *p, DetectThresholdEntry *lookup_tsh,
DetectThresholdEntry **new_tsh, const DetectThresholdData *td,
uint32_t sid, uint32_t gid, PacketAlert *pa)
{ {
int ret = 0; int ret = 0;
const SCTime_t packet_time = p->ts;
switch(td->type) { const SCTime_t entry = SCTIME_ADD_SECS(te->tv1, td->seconds);
switch (td->type) {
case TYPE_LIMIT: case TYPE_LIMIT:
{
SCLogDebug("limit"); SCLogDebug("limit");
if (lookup_tsh != NULL) { if (SCTIME_CMP_LTE(p->ts, entry)) {
SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds); te->current_count++;
if (SCTIME_CMP_LTE(p->ts, entry)) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count <= td->count) {
ret = 1;
} else {
ret = 2;
if (PacketIsIPv4(p)) { if (te->current_count <= td->count) {
SetupCache(p, td->track, (int8_t)ret, sid, entry); ret = 1;
}
}
} else { } else {
lookup_tsh->tv1 = p->ts; ret = 2;
lookup_tsh->current_count = 1;
ret = 1; if (PacketIsIPv4(p)) {
SetupCache(p, td->track, (int8_t)ret, sid, entry);
}
} }
} else { } else {
*new_tsh = DetectThresholdEntryAlloc(td, sid, gid); /* entry expired, reset */
te->tv1 = p->ts;
te->current_count = 1;
ret = 1; ret = 1;
} }
break; break;
}
case TYPE_THRESHOLD: case TYPE_THRESHOLD:
{ if (SCTIME_CMP_LTE(p->ts, entry)) {
SCLogDebug("threshold"); te->current_count++;
if (lookup_tsh != NULL) {
SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
if (SCTIME_CMP_LTE(p->ts, entry)) {
lookup_tsh->current_count++;
if (lookup_tsh->current_count >= td->count) { if (te->current_count >= td->count) {
ret = 1;
lookup_tsh->current_count = 0;
}
} else {
lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
}
} else {
if (td->count == 1) {
ret = 1; ret = 1;
} else { te->current_count = 0;
*new_tsh = DetectThresholdEntryAlloc(td, sid, gid);
} }
} else {
te->tv1 = p->ts;
te->current_count = 1;
} }
break; break;
}
case TYPE_BOTH: case TYPE_BOTH:
{ if (SCTIME_CMP_LTE(p->ts, entry)) {
SCLogDebug("both"); /* within time limit */
if (lookup_tsh != NULL) {
SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds);
if (SCTIME_CMP_LTE(p->ts, entry)) {
/* within time limit */
lookup_tsh->current_count++;
if (lookup_tsh->current_count == td->count) {
ret = 1;
} else if (lookup_tsh->current_count > td->count) {
/* silent match */
ret = 2;
if (PacketIsIPv4(p)) {
SetupCache(p, td->track, (int8_t)ret, sid, entry);
}
}
} else {
/* expired, so reset */
lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
/* if we have a limit of 1, this is a match */ te->current_count++;
if (lookup_tsh->current_count == td->count) { if (te->current_count == td->count) {
ret = 1; ret = 1;
} else if (te->current_count > td->count) {
/* silent match */
ret = 2;
if (PacketIsIPv4(p)) {
SetupCache(p, td->track, (int8_t)ret, sid, entry);
} }
} }
} else { } else {
*new_tsh = DetectThresholdEntryAlloc(td, sid, gid); /* expired, so reset */
te->tv1 = p->ts;
te->current_count = 1;
/* for the first match we return 1 to /* if we have a limit of 1, this is a match */
* indicate we should alert */ if (te->current_count == td->count) {
if (td->count == 1) {
ret = 1; ret = 1;
} }
} }
break; break;
}
/* detection_filter */
case TYPE_DETECTION: case TYPE_DETECTION:
{
SCLogDebug("detection_filter"); SCLogDebug("detection_filter");
if (lookup_tsh != NULL) { if (SCTIME_CMP_LTE(p->ts, entry)) {
SCTime_t entry = SCTIME_ADD_SECS(lookup_tsh->tv1, td->seconds); /* within timeout */
if (SCTIME_CMP_LTE(p->ts, entry)) { te->current_count++;
/* within timeout */ if (te->current_count > td->count) {
lookup_tsh->current_count++; ret = 1;
if (lookup_tsh->current_count > td->count) {
ret = 1;
}
} else {
/* expired, reset */
lookup_tsh->tv1 = p->ts;
lookup_tsh->current_count = 1;
} }
} else { } else {
*new_tsh = DetectThresholdEntryAlloc(td, sid, gid); /* expired, reset */
te->tv1 = p->ts;
te->current_count = 1;
} }
break; break;
}
/* rate_filter */
case TYPE_RATE: case TYPE_RATE:
{
SCLogDebug("rate_filter"); SCLogDebug("rate_filter");
ret = 1; ret = 1;
if (lookup_tsh && IsThresholdReached(lookup_tsh, td, p->ts)) { /* Check if we have a timeout enabled, if so,
RateFilterSetAction(pa, td->new_action); * we still matching (and enabling the new_action) */
} else if (!lookup_tsh) { if (te->tv_timeout != 0) {
*new_tsh = DetectThresholdEntryAlloc(td, sid, gid); if ((SCTIME_SECS(packet_time) - te->tv_timeout) > td->timeout) {
/* Ok, we are done, timeout reached */
te->tv_timeout = 0;
} else {
/* Already matching */
RateFilterSetAction(pa, td->new_action);
}
} else {
/* Update the matching state with the timeout interval */
if (SCTIME_CMP_LTE(packet_time, entry)) {
te->current_count++;
if (te->current_count > td->count) {
/* Then we must enable the new action by setting a
* timeout */
te->tv_timeout = SCTIME_SECS(packet_time);
RateFilterSetAction(pa, td->new_action);
}
} else {
te->tv1 = packet_time;
te->current_count = 1;
}
} }
break; break;
}
/* case TYPE_SUPPRESS: is not handled here */
default:
SCLogError("type %d is not supported", td->type);
} }
return ret; return ret;
} }
static int ThresholdHandlePacketIPPair(IPPair *pair, Packet *p, const DetectThresholdData *td, #include "detect-engine-address-ipv6.h"
uint32_t sid, uint32_t gid, PacketAlert *pa)
{
int ret = 0;
DetectThresholdEntry *lookup_tsh = ThresholdIPPairLookupEntry(pair, sid, gid);
SCLogDebug("ippair lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid);
DetectThresholdEntry *new_tsh = NULL;
ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa);
if (new_tsh != NULL) {
AddEntryToIPPairStorage(pair, new_tsh, p->ts);
}
return ret;
}
/** static int ThresholdGetFromHash(struct Thresholds *tctx, const Packet *p, const Signature *s,
* \retval 2 silent match (no alert but apply actions) const DetectThresholdData *td, PacketAlert *pa)
* \retval 1 normal match
* \retval 0 no match
*/
static int ThresholdHandlePacketHost(Host *h, Packet *p, const DetectThresholdData *td,
uint32_t sid, uint32_t gid, PacketAlert *pa)
{ {
int ret = 0; /* fast track for count 1 threshold */
DetectThresholdEntry *lookup_tsh = ThresholdHostLookupEntry(h, sid, gid); if (td->count == 1 && td->type == TYPE_THRESHOLD) {
SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid); return 1;
DetectThresholdEntry *new_tsh = NULL;
ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa);
if (new_tsh != NULL) {
AddEntryToHostStorage(h, new_tsh, p->ts);
} }
return ret;
}
static int ThresholdHandlePacketRule(DetectEngineCtx *de_ctx, Packet *p, ThresholdEntry lookup;
const DetectThresholdData *td, const Signature *s, PacketAlert *pa) memset(&lookup, 0, sizeof(lookup));
{ lookup.sid = s->id;
int ret = 0; lookup.gid = s->gid;
lookup.track = td->track;
if (td->track == TRACK_SRC) {
COPY_ADDRESS(&p->src, &lookup.addr);
} else if (td->track == TRACK_DST) {
COPY_ADDRESS(&p->dst, &lookup.addr);
} else if (td->track == TRACK_BOTH) {
/* make sure lower ip address is first */
if (PacketIsIPv4(p)) {
if (SCNtohl(p->src.addr_data32[0]) < SCNtohl(p->dst.addr_data32[0])) {
COPY_ADDRESS(&p->src, &lookup.addr);
COPY_ADDRESS(&p->dst, &lookup.addr2);
} else {
COPY_ADDRESS(&p->dst, &lookup.addr);
COPY_ADDRESS(&p->src, &lookup.addr2);
}
} else {
if (AddressIPv6Lt(&p->src, &p->dst)) {
COPY_ADDRESS(&p->src, &lookup.addr);
COPY_ADDRESS(&p->dst, &lookup.addr2);
} else {
COPY_ADDRESS(&p->dst, &lookup.addr);
COPY_ADDRESS(&p->src, &lookup.addr2);
}
}
}
DetectThresholdEntry* lookup_tsh = (DetectThresholdEntry *)de_ctx->ths_ctx.th_entry[s->num]; struct THashDataGetResult res = THashGetFromHash(tctx->thash, &lookup);
SCLogDebug("by_rule lookup_tsh %p num %u", lookup_tsh, s->num); if (res.data) {
SCLogDebug("found %p, is_new %s", res.data, BOOL2STR(res.is_new));
int r;
ThresholdEntry *te = res.data->data;
if (res.is_new) {
// new threshold, set up
r = ThresholdSetup(td, te, p->ts, s->id, s->gid);
} else {
// existing, check/update
r = ThresholdCheckUpdate(td, te, p, s->id, pa);
}
DetectThresholdEntry *new_tsh = NULL; (void)THashDecrUsecnt(res.data);
ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, s->id, s->gid, pa); THashDataUnlock(res.data);
if (new_tsh != NULL) { return r;
new_tsh->tv1 = p->ts;
new_tsh->current_count = 1;
new_tsh->tv_timeout = 0;
de_ctx->ths_ctx.th_entry[s->num] = new_tsh;
} }
return 0; // TODO error?
return ret;
} }
/** /**
@ -881,15 +826,24 @@ static int ThresholdHandlePacketFlow(Flow *f, Packet *p, const DetectThresholdDa
uint32_t sid, uint32_t gid, PacketAlert *pa) uint32_t sid, uint32_t gid, PacketAlert *pa)
{ {
int ret = 0; int ret = 0;
DetectThresholdEntry *lookup_tsh = ThresholdFlowLookupEntry(f, sid, gid); ThresholdEntry *found = ThresholdFlowLookupEntry(f, sid, gid);
SCLogDebug("lookup_tsh %p sid %u gid %u", lookup_tsh, sid, gid); SCLogDebug("found %p sid %u gid %u", found, sid, gid);
DetectThresholdEntry *new_tsh = NULL; if (found == NULL) {
ret = ThresholdHandlePacket(p, lookup_tsh, &new_tsh, td, sid, gid, pa); FlowThresholdEntryList *new = SCCalloc(1, sizeof(*new));
if (new_tsh != NULL) { if (new == NULL)
if (AddEntryToFlow(f, new_tsh, p->ts) == -1) { return 0;
SCFree(new_tsh);
// new threshold, set up
ret = ThresholdSetup(td, &new->threshold, p->ts, sid, gid);
if (AddEntryToFlow(f, new, p->ts) == -1) {
SCFree(new);
return 0;
} }
} else {
// existing, check/update
ret = ThresholdCheckUpdate(td, found, p, sid, pa);
} }
return ret; return ret;
} }
@ -925,11 +879,8 @@ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
SCReturnInt(cache_ret); SCReturnInt(cache_ret);
} }
} }
Host *src = HostGetHostFromHash(&p->src);
if (src) { ret = ThresholdGetFromHash(&ctx, p, s, td, pa);
ret = ThresholdHandlePacketHost(src,p,td,s->id,s->gid,pa);
HostRelease(src);
}
} else if (td->track == TRACK_DST) { } else if (td->track == TRACK_DST) {
if (PacketIsIPv4(p) && (td->type == TYPE_LIMIT || td->type == TYPE_BOTH)) { if (PacketIsIPv4(p) && (td->type == TYPE_LIMIT || td->type == TYPE_BOTH)) {
int cache_ret = CheckCache(p, td->track, s->id); int cache_ret = CheckCache(p, td->track, s->id);
@ -937,21 +888,12 @@ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
SCReturnInt(cache_ret); SCReturnInt(cache_ret);
} }
} }
Host *dst = HostGetHostFromHash(&p->dst);
if (dst) { ret = ThresholdGetFromHash(&ctx, p, s, td, pa);
ret = ThresholdHandlePacketHost(dst,p,td,s->id,s->gid,pa);
HostRelease(dst);
}
} else if (td->track == TRACK_BOTH) { } else if (td->track == TRACK_BOTH) {
IPPair *pair = IPPairGetIPPairFromHash(&p->src, &p->dst); ret = ThresholdGetFromHash(&ctx, p, s, td, pa);
if (pair) {
ret = ThresholdHandlePacketIPPair(pair, p, td, s->id, s->gid, pa);
IPPairRelease(pair);
}
} else if (td->track == TRACK_RULE) { } else if (td->track == TRACK_RULE) {
SCMutexLock(&de_ctx->ths_ctx.threshold_table_lock); ret = ThresholdGetFromHash(&ctx, p, s, td, pa);
ret = ThresholdHandlePacketRule(de_ctx,p,td,s,pa);
SCMutexUnlock(&de_ctx->ths_ctx.threshold_table_lock);
} else if (td->track == TRACK_FLOW) { } else if (td->track == TRACK_FLOW) {
if (p->flow) { if (p->flow) {
ret = ThresholdHandlePacketFlow(p->flow, p, td, s->id, s->gid, pa); ret = ThresholdHandlePacketFlow(p->flow, p, td, s->id, s->gid, pa);
@ -961,125 +903,6 @@ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx
SCReturnInt(ret); SCReturnInt(ret);
} }
/**
* \brief Init threshold context hash tables
*
* \param de_ctx Detection Context
*
*/
void ThresholdHashInit(DetectEngineCtx *de_ctx)
{
if (SCMutexInit(&de_ctx->ths_ctx.threshold_table_lock, NULL) != 0) {
FatalError("Threshold: Failed to initialize hash table mutex.");
}
}
/**
* \brief Allocate threshold context hash tables
*
* \param de_ctx Detection Context
*/
void ThresholdHashAllocate(DetectEngineCtx *de_ctx)
{
const Signature *s = de_ctx->sig_list;
bool has_by_rule_tracking = false;
/* Find the signature with the highest signature number that is using
thresholding with by_rule tracking. */
uint32_t highest_signum = 0;
while (s != NULL) {
if (s->sm_arrays[DETECT_SM_LIST_SUPPRESS] != NULL) {
const SigMatchData *smd = NULL;
do {
const DetectThresholdData *td =
SigGetThresholdTypeIter(s, &smd, DETECT_SM_LIST_SUPPRESS);
if (td == NULL) {
continue;
}
if (td->track != TRACK_RULE) {
continue;
}
if (s->num >= highest_signum) {
highest_signum = s->num;
has_by_rule_tracking = true;
}
} while (smd != NULL);
}
if (s->sm_arrays[DETECT_SM_LIST_THRESHOLD] != NULL) {
const SigMatchData *smd = NULL;
do {
const DetectThresholdData *td =
SigGetThresholdTypeIter(s, &smd, DETECT_SM_LIST_THRESHOLD);
if (td == NULL) {
continue;
}
if (td->track != TRACK_RULE) {
continue;
}
if (s->num >= highest_signum) {
highest_signum = s->num;
has_by_rule_tracking = true;
}
} while (smd != NULL);
}
s = s->next;
}
/* Skip allocating if by_rule tracking is not used */
if (has_by_rule_tracking == false) {
return;
}
de_ctx->ths_ctx.th_size = highest_signum + 1;
de_ctx->ths_ctx.th_entry = SCCalloc(de_ctx->ths_ctx.th_size, sizeof(DetectThresholdEntry *));
if (de_ctx->ths_ctx.th_entry == NULL) {
FatalError(
"failed to allocate memory for \"by_rule\" thresholding (tried to allocate %" PRIu32
" entries)",
de_ctx->ths_ctx.th_size);
}
}
/**
* \brief Destroy threshold context hash tables
*
* \param de_ctx Detection Context
*
*/
void ThresholdContextDestroy(DetectEngineCtx *de_ctx)
{
if (de_ctx->ths_ctx.th_entry != NULL) {
for (uint32_t i = 0; i < de_ctx->ths_ctx.th_size; i++) {
if (de_ctx->ths_ctx.th_entry[i] != NULL) {
SCFree(de_ctx->ths_ctx.th_entry[i]);
}
}
SCFree(de_ctx->ths_ctx.th_entry);
}
SCMutexDestroy(&de_ctx->ths_ctx.threshold_table_lock);
}
/**
* \brief this function will free all the entries of a list
* DetectTagDataEntry
*
* \param td pointer to DetectTagDataEntryList
*/
void ThresholdListFree(void *ptr)
{
if (ptr != NULL) {
DetectThresholdEntry *entry = ptr;
while (entry != NULL) {
DetectThresholdEntry *next_entry = entry->next;
SCFree(entry);
entry = next_entry;
}
}
}
/** /**
* @} * @}
*/ */

@ -26,16 +26,12 @@
#define SURICATA_DETECT_ENGINE_THRESHOLD_H #define SURICATA_DETECT_ENGINE_THRESHOLD_H
#include "detect.h" #include "detect.h"
#include "host.h" #include "detect-threshold.h"
#include "ippair.h"
#include "host-storage.h"
void ThresholdInit(void); void ThresholdInit(void);
void ThresholdDestroy(void);
HostStorageId ThresholdHostStorageId(void); uint32_t ThresholdsExpire(const SCTime_t ts);
int ThresholdHostHasThreshold(Host *);
int ThresholdIPPairHasThreshold(IPPair *pair);
const DetectThresholdData *SigGetThresholdTypeIter( const DetectThresholdData *SigGetThresholdTypeIter(
const Signature *, const SigMatchData **, int list); const Signature *, const SigMatchData **, int list);
@ -43,12 +39,6 @@ int PacketAlertThreshold(DetectEngineCtx *, DetectEngineThreadCtx *,
const DetectThresholdData *, Packet *, const DetectThresholdData *, Packet *,
const Signature *, PacketAlert *); const Signature *, PacketAlert *);
void ThresholdHashInit(DetectEngineCtx *);
void ThresholdHashAllocate(DetectEngineCtx *);
void ThresholdContextDestroy(DetectEngineCtx *);
int ThresholdHostTimeoutCheck(Host *, SCTime_t);
int ThresholdIPPairTimeoutCheck(IPPair *, SCTime_t);
void ThresholdListFree(void *ptr); void ThresholdListFree(void *ptr);
void ThresholdCacheThreadFree(void); void ThresholdCacheThreadFree(void);

@ -2506,7 +2506,6 @@ static DetectEngineCtx *DetectEngineCtxInitReal(
SigGroupHeadHashInit(de_ctx); SigGroupHeadHashInit(de_ctx);
MpmStoreInit(de_ctx); MpmStoreInit(de_ctx);
ThresholdHashInit(de_ctx);
DetectParseDupSigHashInit(de_ctx); DetectParseDupSigHashInit(de_ctx);
DetectAddressMapInit(de_ctx); DetectAddressMapInit(de_ctx);
DetectMetadataHashInit(de_ctx); DetectMetadataHashInit(de_ctx);
@ -2620,7 +2619,6 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx)
MpmStoreFree(de_ctx); MpmStoreFree(de_ctx);
DetectParseDupSigHashFree(de_ctx); DetectParseDupSigHashFree(de_ctx);
SCSigSignatureOrderingModuleCleanup(de_ctx); SCSigSignatureOrderingModuleCleanup(de_ctx);
ThresholdContextDestroy(de_ctx);
SigCleanSignatures(de_ctx); SigCleanSignatures(de_ctx);
if (de_ctx->sig_array) if (de_ctx->sig_array)
SCFree(de_ctx->sig_array); SCFree(de_ctx->sig_array);

@ -509,7 +509,7 @@ static int DetectThresholdTestSig1(void)
int result = 0; int result = 0;
int alerts = 0; int alerts = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -587,8 +587,8 @@ static int DetectThresholdTestSig1(void)
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown();
end: end:
ThresholdDestroy();
return result; return result;
} }
@ -610,7 +610,7 @@ static int DetectThresholdTestSig2(void)
int result = 0; int result = 0;
int alerts = 0; int alerts = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -658,15 +658,12 @@ static int DetectThresholdTestSig2(void)
goto cleanup; goto cleanup;
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -681,94 +678,49 @@ end:
static int DetectThresholdTestSig3(void) static int DetectThresholdTestSig3(void)
{ {
Packet *p = NULL;
Signature *s = NULL;
ThreadVars th_v; ThreadVars th_v;
DetectEngineThreadCtx *det_ctx;
int result = 0;
int alerts = 0;
DetectThresholdEntry *lookup_tsh = NULL;
HostInitConfig(HOST_QUIET);
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); ThresholdInit();
Packet *p = UTHBuildPacketReal((uint8_t *)"A", 1, IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
DetectEngineCtx *de_ctx = DetectEngineCtxInit(); DetectEngineCtx *de_ctx = DetectEngineCtxInit();
if (de_ctx == NULL) { FAIL_IF_NULL(de_ctx);
goto end;
}
de_ctx->flags |= DE_QUIET; de_ctx->flags |= DE_QUIET;
s = de_ctx->sig_list = SigInit(de_ctx,"alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, track by_dst, count 5, seconds 60; sid:10;)"); Signature *s = DetectEngineAppendSig(de_ctx,
if (s == NULL) { "alert tcp any any -> any 80 (msg:\"Threshold limit\"; threshold: type limit, "
goto end; "track by_dst, count 5, seconds 60; sid:10;)");
} FAIL_IF_NULL(s);
SigGroupBuild(de_ctx); SigGroupBuild(de_ctx);
DetectEngineThreadCtx *det_ctx;
DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx); DetectEngineThreadCtxInit(&th_v, (void *)de_ctx, (void *)&det_ctx);
p->ts = TimeGet(); p->ts = TimeGet();
SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
Host *host = HostLookupHostFromHash(&p->dst);
if (host == NULL) {
printf("host not found: ");
goto cleanup;
}
if (!(ThresholdHostHasThreshold(host))) {
HostRelease(host);
printf("host has no threshold: ");
goto cleanup;
}
HostRelease(host);
TimeSetIncrementTime(200); TimeSetIncrementTime(200);
p->ts = TimeGet(); p->ts = TimeGet();
SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
SigMatchSignatures(&th_v, de_ctx, det_ctx, p); SigMatchSignatures(&th_v, de_ctx, det_ctx, p);
FAIL_IF_NOT(PacketAlertCheck(p, 10) == 1);
host = HostLookupHostFromHash(&p->dst);
if (host == NULL) {
printf("host not found: ");
goto cleanup;
}
HostRelease(host);
lookup_tsh = HostGetStorageById(host, ThresholdHostStorageId());
if (lookup_tsh == NULL) {
HostRelease(host);
printf("lookup_tsh is NULL: ");
goto cleanup;
}
alerts = lookup_tsh->current_count;
if (alerts == 3)
result = 1;
else {
printf("alerts %u != 3: ", alerts);
goto cleanup;
}
cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; PASS;
} }
/** /**
@ -789,7 +741,7 @@ static int DetectThresholdTestSig4(void)
int result = 0; int result = 0;
int alerts = 0; int alerts = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -834,14 +786,11 @@ static int DetectThresholdTestSig4(void)
goto cleanup; goto cleanup;
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -863,7 +812,7 @@ static int DetectThresholdTestSig5(void)
int result = 0; int result = 0;
int alerts = 0; int alerts = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
@ -921,15 +870,12 @@ static int DetectThresholdTestSig5(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -942,7 +888,7 @@ static int DetectThresholdTestSig6Ticks(void)
int result = 0; int result = 0;
int alerts = 0; int alerts = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
@ -1004,15 +950,12 @@ static int DetectThresholdTestSig6Ticks(void)
goto cleanup; goto cleanup;
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -1029,7 +972,7 @@ static int DetectThresholdTestSig7(void)
int alerts = 0; int alerts = 0;
int drops = 0; int drops = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -1095,14 +1038,11 @@ static int DetectThresholdTestSig7(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -1119,7 +1059,7 @@ static int DetectThresholdTestSig8(void)
int alerts = 0; int alerts = 0;
int drops = 0; int drops = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -1185,14 +1125,11 @@ static int DetectThresholdTestSig8(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -1209,7 +1146,7 @@ static int DetectThresholdTestSig9(void)
int alerts = 0; int alerts = 0;
int drops = 0; int drops = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -1275,14 +1212,11 @@ static int DetectThresholdTestSig9(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -1299,7 +1233,7 @@ static int DetectThresholdTestSig10(void)
int alerts = 0; int alerts = 0;
int drops = 0; int drops = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -1365,14 +1299,11 @@ static int DetectThresholdTestSig10(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -1389,7 +1320,7 @@ static int DetectThresholdTestSig11(void)
int alerts = 0; int alerts = 0;
int drops = 0; int drops = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -1455,14 +1386,11 @@ static int DetectThresholdTestSig11(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
return result; return result;
} }
@ -1479,7 +1407,7 @@ static int DetectThresholdTestSig12(void)
int alerts = 0; int alerts = 0;
int drops = 0; int drops = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
@ -1545,14 +1473,12 @@ static int DetectThresholdTestSig12(void)
} }
cleanup: cleanup:
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void*)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void*)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
end: end:
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); HostShutdown();
ThresholdDestroy();
return result; return result;
} }
@ -1573,7 +1499,7 @@ static int DetectThresholdTestSig13(void)
DetectEngineThreadCtx *det_ctx; DetectEngineThreadCtx *det_ctx;
int alerts = 0; int alerts = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); p = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
@ -1616,12 +1542,10 @@ static int DetectThresholdTestSig13(void)
FAIL_IF(alerts != 4); FAIL_IF(alerts != 4);
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
UTHFreePackets(&p, 1); UTHFreePackets(&p, 1);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -1644,8 +1568,7 @@ static int DetectThresholdTestSig14(void)
int alerts1 = 0; int alerts1 = 0;
int alerts2 = 0; int alerts2 = 0;
HostInitConfig(HOST_QUIET); ThresholdInit();
IPPairInitConfig(IPPAIR_QUIET);
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
p1 = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80); p1 = UTHBuildPacketReal((uint8_t *)"A",1,IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);
@ -1699,13 +1622,11 @@ static int DetectThresholdTestSig14(void)
FAIL_IF(alerts1 != 3); FAIL_IF(alerts1 != 3);
FAIL_IF(alerts2 != 3); FAIL_IF(alerts2 != 3);
SigGroupCleanup(de_ctx);
SigCleanSignatures(de_ctx);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
UTHFreePackets(&p1, 1); UTHFreePackets(&p1, 1);
UTHFreePackets(&p2, 1); UTHFreePackets(&p2, 1);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }

@ -62,21 +62,6 @@ typedef struct DetectThresholdData_ {
DetectAddressHead addrs; DetectAddressHead addrs;
} DetectThresholdData; } DetectThresholdData;
typedef struct DetectThresholdEntry_ {
uint32_t sid; /**< Signature id */
uint32_t gid; /**< Signature group id */
uint32_t tv_timeout; /**< Timeout for new_action (for rate_filter)
its not "seconds", that define the time interval */
uint32_t seconds; /**< Event seconds */
uint32_t current_count; /**< Var for count control */
int track; /**< Track type: by_src, by_src */
SCTime_t tv1; /**< Var for time control */
struct DetectThresholdEntry_ *next;
} DetectThresholdEntry;
/** /**
* Registration function for threshold: keyword * Registration function for threshold: keyword
*/ */

@ -785,17 +785,6 @@ typedef struct DetectEngineLookupFlow_ {
struct SigGroupHead_ *sgh[256]; struct SigGroupHead_ *sgh[256];
} DetectEngineLookupFlow; } DetectEngineLookupFlow;
#include "detect-threshold.h"
/** \brief threshold ctx */
typedef struct ThresholdCtx_ {
SCMutex threshold_table_lock; /**< Mutex for hash table */
/** to support rate_filter "by_rule" option */
DetectThresholdEntry **th_entry;
uint32_t th_size;
} ThresholdCtx;
typedef struct SigString_ { typedef struct SigString_ {
char *filename; char *filename;
char *sig_str; char *sig_str;
@ -886,7 +875,6 @@ typedef struct DetectEngineCtx_ {
HashListTable *dup_sig_hash_table; HashListTable *dup_sig_hash_table;
DetectEngineIPOnlyCtx io_ctx; DetectEngineIPOnlyCtx io_ctx;
ThresholdCtx ths_ctx;
/* maximum recursion depth for content inspection */ /* maximum recursion depth for content inspection */
int inspection_recursion_limit; int inspection_recursion_limit;

@ -47,6 +47,7 @@
#include "util-debug.h" #include "util-debug.h"
#include "threads.h" #include "threads.h"
#include "detect-engine-threshold.h"
#include "host-timeout.h" #include "host-timeout.h"
#include "defrag-hash.h" #include "defrag-hash.h"
@ -931,6 +932,7 @@ static TmEcode FlowManager(ThreadVars *th_v, void *thread_data)
HostTimeoutHash(ts); HostTimeoutHash(ts);
IPPairTimeoutHash(ts); IPPairTimeoutHash(ts);
HttpRangeContainersTimeoutHash(ts); HttpRangeContainersTimeoutHash(ts);
ThresholdsExpire(ts);
other_last_sec = (uint32_t)SCTIME_SECS(ts); other_last_sec = (uint32_t)SCTIME_SECS(ts);
} }
} }

@ -25,7 +25,6 @@
#include "host.h" #include "host.h"
#include "detect-engine-tag.h" #include "detect-engine-tag.h"
#include "detect-engine-threshold.h"
#include "host-bit.h" #include "host-bit.h"
#include "host-timeout.h" #include "host-timeout.h"
@ -53,7 +52,6 @@ static int HostHostTimedOut(Host *h, SCTime_t ts)
busy |= (h->iprep && SRepHostTimedOut(h) == 0); busy |= (h->iprep && SRepHostTimedOut(h) == 0);
busy |= (TagHostHasTag(h) && TagTimeoutCheck(h, ts) == 0); busy |= (TagHostHasTag(h) && TagTimeoutCheck(h, ts) == 0);
busy |= (ThresholdHostHasThreshold(h) && ThresholdHostTimeoutCheck(h, ts) == 0);
busy |= (HostHasHostBits(h) && HostBitsTimedoutCheck(h, ts) == 0); busy |= (HostHasHostBits(h) && HostBitsTimedoutCheck(h, ts) == 0);
SCLogDebug("host %p %s", h, busy ? "still active" : "timed out"); SCLogDebug("host %p %s", h, busy ? "still active" : "timed out");
return !busy; return !busy;

@ -25,7 +25,6 @@
#include "ippair.h" #include "ippair.h"
#include "ippair-bit.h" #include "ippair-bit.h"
#include "ippair-timeout.h" #include "ippair-timeout.h"
#include "detect-engine-threshold.h"
/** \internal /** \internal
* \brief See if we can really discard this ippair. Check use_cnt reference. * \brief See if we can really discard this ippair. Check use_cnt reference.
@ -39,8 +38,6 @@
static int IPPairTimedOut(IPPair *h, SCTime_t ts) static int IPPairTimedOut(IPPair *h, SCTime_t ts)
{ {
int vars = 0; int vars = 0;
int thresholds = 0;
/** never prune a ippair that is used by a packet /** never prune a ippair that is used by a packet
* we are currently processing in one of the threads */ * we are currently processing in one of the threads */
if (SC_ATOMIC_GET(h->use_cnt) > 0) { if (SC_ATOMIC_GET(h->use_cnt) > 0) {
@ -50,12 +47,7 @@ static int IPPairTimedOut(IPPair *h, SCTime_t ts)
if (IPPairHasBits(h) && IPPairBitsTimedoutCheck(h, ts) == 0) { if (IPPairHasBits(h) && IPPairBitsTimedoutCheck(h, ts) == 0) {
vars = 1; vars = 1;
} }
if (vars) {
if (ThresholdIPPairHasThreshold(h) && ThresholdIPPairTimeoutCheck(h, ts) == 0) {
thresholds = 1;
}
if (vars || thresholds) {
return 0; return 0;
} }

@ -369,6 +369,7 @@ void GlobalsInitPreConfig(void)
void GlobalsDestroy(void) void GlobalsDestroy(void)
{ {
SCInstance *suri = &suricata; SCInstance *suri = &suricata;
ThresholdDestroy();
HostShutdown(); HostShutdown();
HTPFreeConfig(); HTPFreeConfig();
HTPAtExitPrintStats(); HTPAtExitPrintStats();

@ -37,6 +37,7 @@
#include "detect.h" #include "detect.h"
#include "detect-engine.h" #include "detect-engine.h"
#include "detect-engine-address.h" #include "detect-engine-address.h"
#include "detect-engine-threshold.h"
#include "detect-threshold.h" #include "detect-threshold.h"
#include "detect-parse.h" #include "detect-parse.h"
#include "detect-engine-build.h" #include "detect-engine-build.h"
@ -1534,7 +1535,7 @@ static int SCThresholdConfTest09(void)
ThreadVars th_v; ThreadVars th_v;
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP);
FAIL_IF_NULL(p); FAIL_IF_NULL(p);
@ -1603,7 +1604,7 @@ static int SCThresholdConfTest09(void)
UTHFreePacket(p); UTHFreePacket(p);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -1615,7 +1616,7 @@ static int SCThresholdConfTest09(void)
*/ */
static int SCThresholdConfTest10(void) static int SCThresholdConfTest10(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
/* Create two different packets falling to the same rule, and /* Create two different packets falling to the same rule, and
* because count:3, we should drop on match #4. * because count:3, we should drop on match #4.
@ -1685,15 +1686,15 @@ static int SCThresholdConfTest10(void)
SigMatchSignatures(&th_v, de_ctx, det_ctx, p1); SigMatchSignatures(&th_v, de_ctx, det_ctx, p1);
FAIL_IF(PacketTestAction(p1, ACTION_DROP)); FAIL_IF(PacketTestAction(p1, ACTION_DROP));
FAIL_IF(PacketAlertCheck(p1, 10) != 1); FAIL_IF(PacketAlertCheck(p1, 10) != 1);
#if 0
/* Ensure that a Threshold entry was installed at the sig */ /* Ensure that a Threshold entry was installed at the sig */
FAIL_IF_NULL(de_ctx->ths_ctx.th_entry[s->num]); FAIL_IF_NULL(de_ctx->ths_ctx.th_entry[s->num]);
#endif
UTHFreePacket(p1); UTHFreePacket(p1);
UTHFreePacket(p2); UTHFreePacket(p2);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -1705,7 +1706,7 @@ static int SCThresholdConfTest10(void)
*/ */
static int SCThresholdConfTest11(void) static int SCThresholdConfTest11(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP);
FAIL_IF_NULL(p); FAIL_IF_NULL(p);
@ -1798,7 +1799,7 @@ static int SCThresholdConfTest11(void)
UTHFreePacket(p); UTHFreePacket(p);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -1810,7 +1811,7 @@ static int SCThresholdConfTest11(void)
*/ */
static int SCThresholdConfTest12(void) static int SCThresholdConfTest12(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP); Packet *p = UTHBuildPacket((uint8_t*)"lalala", 6, IPPROTO_TCP);
FAIL_IF_NULL(p); FAIL_IF_NULL(p);
@ -1903,7 +1904,7 @@ static int SCThresholdConfTest12(void)
UTHFreePacket(p); UTHFreePacket(p);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -1948,7 +1949,7 @@ static int SCThresholdConfTest13(void)
*/ */
static int SCThresholdConfTest14(void) static int SCThresholdConfTest14(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p1 = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10", Packet *p1 = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10",
"192.168.0.100", 1234, 24); "192.168.0.100", 1234, 24);
@ -1997,7 +1998,7 @@ static int SCThresholdConfTest14(void)
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2009,7 +2010,7 @@ static int SCThresholdConfTest14(void)
*/ */
static int SCThresholdConfTest15(void) static int SCThresholdConfTest15(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10", Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10",
"192.168.0.100", 1234, 24); "192.168.0.100", 1234, 24);
@ -2045,7 +2046,7 @@ static int SCThresholdConfTest15(void)
UTHFreePacket(p); UTHFreePacket(p);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2057,7 +2058,7 @@ static int SCThresholdConfTest15(void)
*/ */
static int SCThresholdConfTest16(void) static int SCThresholdConfTest16(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.1.1", Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.1.1",
"192.168.0.100", 1234, 24); "192.168.0.100", 1234, 24);
@ -2092,7 +2093,7 @@ static int SCThresholdConfTest16(void)
UTHFreePacket(p); UTHFreePacket(p);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2104,7 +2105,7 @@ static int SCThresholdConfTest16(void)
*/ */
static int SCThresholdConfTest17(void) static int SCThresholdConfTest17(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10", Packet *p = UTHBuildPacketReal((uint8_t*)"lalala", 6, IPPROTO_TCP, "192.168.0.10",
"192.168.0.100", 1234, 24); "192.168.0.100", 1234, 24);
@ -2140,7 +2141,7 @@ static int SCThresholdConfTest17(void)
UTHFreePacket(p); UTHFreePacket(p);
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2171,7 +2172,7 @@ static FILE *SCThresholdConfGenerateInvalidDummyFD12(void)
*/ */
static int SCThresholdConfTest18(void) static int SCThresholdConfTest18(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
DetectEngineCtx *de_ctx = DetectEngineCtxInit(); DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx); FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET; de_ctx->flags |= DE_QUIET;
@ -2192,7 +2193,7 @@ static int SCThresholdConfTest18(void)
FAIL_IF_NOT(de->type == TYPE_SUPPRESS && de->track == TRACK_DST); FAIL_IF_NOT(de->type == TYPE_SUPPRESS && de->track == TRACK_DST);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2223,7 +2224,7 @@ static FILE *SCThresholdConfGenerateInvalidDummyFD13(void)
*/ */
static int SCThresholdConfTest19(void) static int SCThresholdConfTest19(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
DetectEngineCtx *de_ctx = DetectEngineCtxInit(); DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx); FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET; de_ctx->flags |= DE_QUIET;
@ -2241,7 +2242,7 @@ static int SCThresholdConfTest19(void)
FAIL_IF_NULL(de); FAIL_IF_NULL(de);
FAIL_IF_NOT(de->type == TYPE_SUPPRESS && de->track == TRACK_DST); FAIL_IF_NOT(de->type == TYPE_SUPPRESS && de->track == TRACK_DST);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2273,7 +2274,7 @@ static FILE *SCThresholdConfGenerateValidDummyFD20(void)
*/ */
static int SCThresholdConfTest20(void) static int SCThresholdConfTest20(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
DetectEngineCtx *de_ctx = DetectEngineCtxInit(); DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx); FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET; de_ctx->flags |= DE_QUIET;
@ -2306,7 +2307,7 @@ static int SCThresholdConfTest20(void)
FAIL_IF_NOT(smd->is_last); FAIL_IF_NOT(smd->is_last);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2319,7 +2320,7 @@ static int SCThresholdConfTest20(void)
*/ */
static int SCThresholdConfTest21(void) static int SCThresholdConfTest21(void)
{ {
HostInitConfig(HOST_QUIET); ThresholdInit();
DetectEngineCtx *de_ctx = DetectEngineCtxInit(); DetectEngineCtx *de_ctx = DetectEngineCtxInit();
FAIL_IF_NULL(de_ctx); FAIL_IF_NULL(de_ctx);
de_ctx->flags |= DE_QUIET; de_ctx->flags |= DE_QUIET;
@ -2351,7 +2352,7 @@ static int SCThresholdConfTest21(void)
FAIL_IF_NOT(smd->is_last); FAIL_IF_NOT(smd->is_last);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
HostShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2384,7 +2385,7 @@ static int SCThresholdConfTest22(void)
ThreadVars th_v; ThreadVars th_v;
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
IPPairInitConfig(IPPAIR_QUIET); ThresholdInit();
/* This packet will cause rate_filter */ /* This packet will cause rate_filter */
Packet *p1 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP, "172.26.0.1", "172.26.0.10"); Packet *p1 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP, "172.26.0.1", "172.26.0.10");
@ -2487,7 +2488,7 @@ static int SCThresholdConfTest22(void)
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
IPPairShutdown(); ThresholdDestroy();
PASS; PASS;
} }
@ -2521,7 +2522,7 @@ static int SCThresholdConfTest23(void)
ThreadVars th_v; ThreadVars th_v;
memset(&th_v, 0, sizeof(th_v)); memset(&th_v, 0, sizeof(th_v));
IPPairInitConfig(IPPAIR_QUIET); ThresholdInit();
/* Create two packets between same addresses in opposite direction */ /* Create two packets between same addresses in opposite direction */
Packet *p1 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP, "172.26.0.1", "172.26.0.10"); Packet *p1 = UTHBuildPacketSrcDst((uint8_t*)"lalala", 6, IPPROTO_TCP, "172.26.0.1", "172.26.0.10");
@ -2568,7 +2569,7 @@ static int SCThresholdConfTest23(void)
DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx); DetectEngineThreadCtxDeinit(&th_v, (void *)det_ctx);
DetectEngineCtxFree(de_ctx); DetectEngineCtxFree(de_ctx);
IPPairShutdown(); ThresholdDestroy();
PASS; PASS;
} }
#endif /* UNITTESTS */ #endif /* UNITTESTS */

Loading…
Cancel
Save