diff --git a/src/detect-engine-threshold.c b/src/detect-engine-threshold.c index d44181e3eb..bce26d8692 100644 --- a/src/detect-engine-threshold.c +++ b/src/detect-engine-threshold.c @@ -463,7 +463,7 @@ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx if (td->track != TRACK_RULE) lookup_tsh = ThresholdHashSearch(de_ctx, &ste, p); else - lookup_tsh = s->th_entry; + lookup_tsh = (DetectThresholdEntry *)de_ctx->ths_ctx.th_entry[s->num]; if (lookup_tsh != NULL) { /* Check if we have a timeout enabled, if so, @@ -543,7 +543,7 @@ int PacketAlertThreshold(DetectEngineCtx *de_ctx, DetectEngineThreadCtx *det_ctx if (td->track != TRACK_RULE) ThresholdHashAdd(de_ctx, e, p); else - s->th_entry = e; + de_ctx->ths_ctx.th_entry[s->num] = e; } break; } @@ -666,6 +666,7 @@ void ThresholdHashInit(DetectEngineCtx *de_ctx) exit(EXIT_FAILURE); } } + } /** @@ -680,5 +681,7 @@ void ThresholdContextDestroy(DetectEngineCtx *de_ctx) HashListTableFree(de_ctx->ths_ctx.threshold_hash_table_src); HashListTableFree(de_ctx->ths_ctx.threshold_hash_table_dst_ipv6); HashListTableFree(de_ctx->ths_ctx.threshold_hash_table_src_ipv6); + if (de_ctx->ths_ctx.th_entry != NULL) + SCFree(de_ctx->ths_ctx.th_entry); } diff --git a/src/detect.h b/src/detect.h index 7474ec95b7..b0e263bff9 100644 --- a/src/detect.h +++ b/src/detect.h @@ -375,6 +375,10 @@ typedef struct ThresholdCtx_ { HashListTable *threshold_hash_table_dst_ipv6; /**< Ipv6 dst hash table */ HashListTable *threshold_hash_table_src_ipv6; /**< Ipv6 src hash table */ SCMutex threshold_table_lock; /**< Mutex for hash table */ + + /** to support rate_filter "by_rule" option */ + DetectThresholdEntry **th_entry; + uint32_t th_size; } ThresholdCtx; /** \brief main detection engine ctx */ diff --git a/src/util-threshold-config.c b/src/util-threshold-config.c index 42edae8152..f86f482ca9 100644 --- a/src/util-threshold-config.c +++ b/src/util-threshold-config.c @@ -390,6 +390,16 @@ int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx) sm->type = DETECT_THRESHOLD; sm->ctx = (void *)de; + if (parsed_track == TRACK_RULE) { + de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *)); + if (de_ctx->ths_ctx.th_entry == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config" + " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1); + } else { + de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL; + de_ctx->ths_ctx.th_size++; + } + } SigMatchAppendPacket(s, sm); s = ns; } @@ -437,6 +447,16 @@ int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx) sm->type = DETECT_THRESHOLD; sm->ctx = (void *)de; + if (parsed_track == TRACK_RULE) { + de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *)); + if (de_ctx->ths_ctx.th_entry == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config" + " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1); + } else { + de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL; + de_ctx->ths_ctx.th_size++; + } + } SigMatchAppendPacket(s, sm); } s = ns; @@ -481,6 +501,17 @@ int SCThresholdConfAddThresholdtype(char *rawstr, DetectEngineCtx *de_ctx) sm->type = DETECT_THRESHOLD; sm->ctx = (void *)de; + if (parsed_track == TRACK_RULE) { + de_ctx->ths_ctx.th_entry = SCRealloc(de_ctx->ths_ctx.th_entry, (de_ctx->ths_ctx.th_size + 1) * sizeof(DetectThresholdEntry *)); + if (de_ctx->ths_ctx.th_entry == NULL) { + SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory for threshold config" + " (tried to allocate %"PRIu32"th_entrys for rule tracking with rate_filter)", de_ctx->ths_ctx.th_size + 1); + } else { + de_ctx->ths_ctx.th_entry[de_ctx->ths_ctx.th_size] = NULL; + de_ctx->ths_ctx.th_size++; + } + } + SigMatchAppendPacket(sig, sm); } @@ -1398,7 +1429,7 @@ int SCThresholdConfTest10(void) result = 1; /* Ensure that a Threshold entry was installed at the sig */ - if (sig->th_entry == NULL) { + if (de_ctx->ths_ctx.th_entry[sig->num] == NULL) { result = 0; goto end; }