detect/engine: set max sig ID per SGH

Present scenario
----------------
Currently, as a part of setting signature count per SGH, a max_idx is
passed which could be as high as the highest signature number (internal
ID).

Issue
-----
Not every SGH needs to evaluate all the signatures while setting
the signature count or while creating the match_array.
In a nonideal scenario, when say, there are 2 SGHs and one SGH has 2
signatures and the other one has 60k, given the current scheme of
evaluating max_idx, the max_idx will be set to 60k, and this shall
later be passed on to SigGroupHeadSetSigCnt or
SigGroupHeadBuildMatchArra which shall traverse over all the 60k sigs
for either SGHs.

Other info
----------
This is a very fast operation as the internal arithmetic is done
bitwise.

Patch
-----
The functions SigGroupHeadSetSigCnt and SigGroupHeadBuildMatchArray can
be optimized by storing the max signature id (internal) per SGH (which
also seemed to be the initial intention as per fn comments).
As a result of this, the sig_array is only walked up until the max sig
id of that respective SGH.
pull/10321/head
Shivani Bhardwaj 2 years ago committed by Victor Julien
parent 264101ba22
commit 395c74d81e

@ -1009,8 +1009,8 @@ static int RulesGroupByProto(DetectEngineCtx *de_ctx)
if (lookup_sgh == NULL) { if (lookup_sgh == NULL) {
SCLogDebug("proto group %d sgh %p is the original", p, sgh_ts[p]); SCLogDebug("proto group %d sgh %p is the original", p, sgh_ts[p]);
SigGroupHeadSetSigCnt(sgh_ts[p], max_idx); SigGroupHeadSetSigCnt(sgh_ts[p], 0);
SigGroupHeadBuildMatchArray(de_ctx, sgh_ts[p], max_idx); SigGroupHeadBuildMatchArray(de_ctx, sgh_ts[p], 0);
SigGroupHeadHashAdd(de_ctx, sgh_ts[p]); SigGroupHeadHashAdd(de_ctx, sgh_ts[p]);
SigGroupHeadStore(de_ctx, sgh_ts[p]); SigGroupHeadStore(de_ctx, sgh_ts[p]);
@ -1041,8 +1041,8 @@ static int RulesGroupByProto(DetectEngineCtx *de_ctx)
if (lookup_sgh == NULL) { if (lookup_sgh == NULL) {
SCLogDebug("proto group %d sgh %p is the original", p, sgh_tc[p]); SCLogDebug("proto group %d sgh %p is the original", p, sgh_tc[p]);
SigGroupHeadSetSigCnt(sgh_tc[p], max_idx); SigGroupHeadSetSigCnt(sgh_tc[p], 0);
SigGroupHeadBuildMatchArray(de_ctx, sgh_tc[p], max_idx); SigGroupHeadBuildMatchArray(de_ctx, sgh_tc[p], 0);
SigGroupHeadHashAdd(de_ctx, sgh_tc[p]); SigGroupHeadHashAdd(de_ctx, sgh_tc[p]);
SigGroupHeadStore(de_ctx, sgh_tc[p]); SigGroupHeadStore(de_ctx, sgh_tc[p]);
@ -1129,7 +1129,8 @@ static int RuleSetWhitelist(Signature *s)
return wl; return wl;
} }
int CreateGroupedPortList(DetectEngineCtx *de_ctx, DetectPort *port_list, DetectPort **newhead, uint32_t unique_groups, int (*CompareFunc)(DetectPort *, DetectPort *), uint32_t max_idx); int CreateGroupedPortList(DetectEngineCtx *de_ctx, DetectPort *port_list, DetectPort **newhead,
uint32_t unique_groups, int (*CompareFunc)(DetectPort *, DetectPort *));
int CreateGroupedPortListCmpCnt(DetectPort *a, DetectPort *b); int CreateGroupedPortListCmpCnt(DetectPort *a, DetectPort *b);
static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, uint8_t ipproto, uint32_t direction) static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, uint8_t ipproto, uint32_t direction)
@ -1223,7 +1224,7 @@ static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, uint8_t ipproto, u
DetectPort *newlist = NULL; DetectPort *newlist = NULL;
uint16_t groupmax = (direction == SIG_FLAG_TOCLIENT) ? de_ctx->max_uniq_toclient_groups : uint16_t groupmax = (direction == SIG_FLAG_TOCLIENT) ? de_ctx->max_uniq_toclient_groups :
de_ctx->max_uniq_toserver_groups; de_ctx->max_uniq_toserver_groups;
CreateGroupedPortList(de_ctx, list, &newlist, groupmax, CreateGroupedPortListCmpCnt, max_idx); CreateGroupedPortList(de_ctx, list, &newlist, groupmax, CreateGroupedPortListCmpCnt);
list = newlist; list = newlist;
/* step 4: deduplicate the SGH's */ /* step 4: deduplicate the SGH's */
@ -1243,8 +1244,8 @@ static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, uint8_t ipproto, u
if (lookup_sgh == NULL) { if (lookup_sgh == NULL) {
SCLogDebug("port group %p sgh %p is the original", iter, iter->sh); SCLogDebug("port group %p sgh %p is the original", iter, iter->sh);
SigGroupHeadSetSigCnt(iter->sh, max_idx); SigGroupHeadSetSigCnt(iter->sh, 0);
SigGroupHeadBuildMatchArray(de_ctx, iter->sh, max_idx); SigGroupHeadBuildMatchArray(de_ctx, iter->sh, 0);
SigGroupHeadSetProtoAndDirection(iter->sh, ipproto, direction); SigGroupHeadSetProtoAndDirection(iter->sh, ipproto, direction);
SigGroupHeadHashAdd(de_ctx, iter->sh); SigGroupHeadHashAdd(de_ctx, iter->sh);
SigGroupHeadStore(de_ctx, iter->sh); SigGroupHeadStore(de_ctx, iter->sh);
@ -1541,7 +1542,8 @@ int CreateGroupedPortListCmpCnt(DetectPort *a, DetectPort *b)
* The joingr is meant to be a catch all. * The joingr is meant to be a catch all.
* *
*/ */
int CreateGroupedPortList(DetectEngineCtx *de_ctx, DetectPort *port_list, DetectPort **newhead, uint32_t unique_groups, int (*CompareFunc)(DetectPort *, DetectPort *), uint32_t max_idx) int CreateGroupedPortList(DetectEngineCtx *de_ctx, DetectPort *port_list, DetectPort **newhead,
uint32_t unique_groups, int (*CompareFunc)(DetectPort *, DetectPort *))
{ {
DetectPort *tmplist = NULL, *joingr = NULL; DetectPort *tmplist = NULL, *joingr = NULL;
char insert = 0; char insert = 0;
@ -1560,8 +1562,7 @@ int CreateGroupedPortList(DetectEngineCtx *de_ctx, DetectPort *port_list, Detect
list->next = NULL; list->next = NULL;
groups++; groups++;
SigGroupHeadSetSigCnt(list->sh, 0);
SigGroupHeadSetSigCnt(list->sh, max_idx);
/* insert it */ /* insert it */
DetectPort *tmpgr = tmplist, *prevtmpgr = NULL; DetectPort *tmpgr = tmplist, *prevtmpgr = NULL;

@ -347,7 +347,7 @@ int SigGroupHeadAppendSig(const DetectEngineCtx *de_ctx, SigGroupHead **sgh,
/* enable the sig in the bitarray */ /* enable the sig in the bitarray */
(*sgh)->init->sig_array[s->num / 8] |= 1 << (s->num % 8); (*sgh)->init->sig_array[s->num / 8] |= 1 << (s->num % 8);
(*sgh)->init->max_sig_id = MAX(s->num, (*sgh)->init->max_sig_id);
return 0; return 0;
error: error:
@ -405,6 +405,8 @@ int SigGroupHeadCopySigs(DetectEngineCtx *de_ctx, SigGroupHead *src, SigGroupHea
if (src->init->score) if (src->init->score)
(*dst)->init->score = MAX((*dst)->init->score, src->init->score); (*dst)->init->score = MAX((*dst)->init->score, src->init->score);
if (src->init->max_sig_id)
(*dst)->init->max_sig_id = MAX((*dst)->init->max_sig_id, src->init->max_sig_id);
return 0; return 0;
error: error:
@ -422,9 +424,9 @@ error:
void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx) void SigGroupHeadSetSigCnt(SigGroupHead *sgh, uint32_t max_idx)
{ {
uint32_t sig; uint32_t sig;
sgh->init->max_sig_id = MAX(max_idx, sgh->init->max_sig_id);
sgh->init->sig_cnt = 0; sgh->init->sig_cnt = 0;
for (sig = 0; sig < max_idx + 1; sig++) { for (sig = 0; sig < sgh->init->max_sig_id + 1; sig++) {
if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8))) if (sgh->init->sig_array[sig / 8] & (1 << (sig % 8)))
sgh->init->sig_cnt++; sgh->init->sig_cnt++;
} }
@ -492,12 +494,13 @@ int SigGroupHeadBuildMatchArray(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
return 0; return 0;
BUG_ON(sgh->init->match_array != NULL); BUG_ON(sgh->init->match_array != NULL);
sgh->init->max_sig_id = MAX(sgh->init->max_sig_id, max_idx);
sgh->init->match_array = SCCalloc(sgh->init->sig_cnt, sizeof(Signature *)); sgh->init->match_array = SCCalloc(sgh->init->sig_cnt, sizeof(Signature *));
if (sgh->init->match_array == NULL) if (sgh->init->match_array == NULL)
return -1; return -1;
for (sig = 0; sig < max_idx + 1; sig++) { for (sig = 0; sig < sgh->init->max_sig_id + 1; sig++) {
if (!(sgh->init->sig_array[(sig / 8)] & (1 << (sig % 8))) ) if (!(sgh->init->sig_array[(sig / 8)] & (1 << (sig % 8))) )
continue; continue;

@ -1419,6 +1419,7 @@ typedef struct SigGroupHeadInitData_ {
uint8_t protos[256]; /**< proto(s) this sgh is for */ uint8_t protos[256]; /**< proto(s) this sgh is for */
uint32_t direction; /**< set to SIG_FLAG_TOSERVER, SIG_FLAG_TOCLIENT or both */ uint32_t direction; /**< set to SIG_FLAG_TOSERVER, SIG_FLAG_TOCLIENT or both */
int score; /**< try to make this group a unique one */ int score; /**< try to make this group a unique one */
uint32_t max_sig_id; /**< max signature idx for this sgh */
MpmCtx **app_mpms; MpmCtx **app_mpms;
MpmCtx **pkt_mpms; MpmCtx **pkt_mpms;

Loading…
Cancel
Save