detect: mpm deduplication

Create hash for mpm's that we can reuse. Have packet/stream mpms
use this.
pull/1978/head
Victor Julien 10 years ago
parent f0ba00e51d
commit fac2cc0560

@ -60,8 +60,17 @@
#endif
#include "util-validate.h"
/** \todo make it possible to use multiple pattern matcher algorithms next to
each other. */
const char *builtin_mpms[] = {
"toserver TCP packet",
"toclient TCP packet",
"toserver TCP stream",
"toclient TCP stream",
"toserver UDP packet",
"toclient UDP packet",
"other IP packet",
NULL };
#define POPULATE_MPM_AVOID_PACKET_MPM_PATTERNS 0x01
#define POPULATE_MPM_AVOID_STREAM_MPM_PATTERNS 0x02
@ -1104,8 +1113,8 @@ uint32_t PatternStrength(uint8_t *pat, uint16_t patlen)
}
static void PopulateMpmHelperAddPatternToPktCtx(MpmCtx *mpm_ctx,
DetectContentData *cd,
Signature *s, uint8_t flags,
const DetectContentData *cd,
const Signature *s, uint8_t flags,
int chop)
{
uint16_t pat_offset = cd->offset;
@ -1153,135 +1162,6 @@ static void PopulateMpmHelperAddPatternToPktCtx(MpmCtx *mpm_ctx,
#define SGH_DIRECTION_TS(sgh) ((sgh)->init->direction & SIG_FLAG_TOSERVER)
#define SGH_DIRECTION_TC(sgh) ((sgh)->init->direction & SIG_FLAG_TOCLIENT)
/* TODO the sig updates don't belong here */
static void PopulateMpmAddPatternToMpmPMATCH(const DetectEngineCtx *de_ctx,
SigGroupHead *sgh, Signature *s,
SigMatch *mpm_sm)
{
DetectContentData *cd = (DetectContentData *)mpm_sm->ctx;
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
if (DETECT_CONTENT_IS_SINGLE(cd) &&
!(cd->flags & DETECT_CONTENT_NEGATED) &&
!(cd->flags & DETECT_CONTENT_REPLACE) &&
cd->content_len == cd->fp_chop_len)
{
cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED;
}
} else {
if (DETECT_CONTENT_IS_SINGLE(cd) &&
!(cd->flags & DETECT_CONTENT_NEGATED) &&
!(cd->flags & DETECT_CONTENT_REPLACE))
{
cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED;
}
}
/* add the content to the "packet" mpm:
* chop is handled in PopulateMpmHelperAddPatternToPktCtx
*/
if (SignatureHasPacketContent(s)) {
/* per TCP packet mpm */
if (SGH_PROTO(sgh, IPPROTO_TCP) && (s->proto.proto[IPPROTO_TCP / 8] & 1 << (IPPROTO_TCP % 8))) {
if (SGH_DIRECTION_TS(sgh) && s->flags & SIG_FLAG_TOSERVER) {
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_ts,
cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
}
if (SGH_DIRECTION_TC(sgh) && s->flags & SIG_FLAG_TOCLIENT) {
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_tcp_ctx_tc,
cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
}
}
}
/* per UDP packet mpm */
if (SGH_PROTO(sgh, IPPROTO_UDP) && (s->proto.proto[IPPROTO_UDP / 8] & 1 << (IPPROTO_UDP % 8))) {
if (SGH_DIRECTION_TS(sgh) && s->flags & SIG_FLAG_TOSERVER) {
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_ts,
cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
}
if (SGH_DIRECTION_TC(sgh) && s->flags & SIG_FLAG_TOCLIENT) {
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_udp_ctx_tc,
cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
}
}
/* other IP protocols */
if (!(SGH_PROTO(sgh, IPPROTO_TCP) || SGH_PROTO(sgh, IPPROTO_UDP))) {
PopulateMpmHelperAddPatternToPktCtx(sgh->mpm_proto_other_ctx,
cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
}
/* tell matcher we are inspecting packet */
s->flags |= SIG_FLAG_MPM_PACKET;
s->mpm_pattern_id_div_8 = cd->id / 8;
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
if (cd->flags & DETECT_CONTENT_NEGATED) {
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
s->flags |= SIG_FLAG_MPM_PACKET_NEG;
}
sgh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
/* for TCP, we have a special "stream" mpm as well */
if (SGH_PROTO(sgh, IPPROTO_TCP) && SignatureHasStreamContent(s)) {
if (cd->flags & DETECT_CONTENT_NOCASE) {
if (SGH_DIRECTION_TS(sgh) && s->flags & SIG_FLAG_TOSERVER) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
MpmAddPatternCI(sgh->mpm_stream_ctx_ts,
cd->content + cd->fp_chop_offset, cd->fp_chop_len,
0, 0, cd->id, s->num, 0);
} else {
MpmAddPatternCI(sgh->mpm_stream_ctx_ts,
cd->content, cd->content_len,
0, 0, cd->id, s->num, 0);
}
}
if (SGH_DIRECTION_TC(sgh) && s->flags & SIG_FLAG_TOCLIENT) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
MpmAddPatternCI(sgh->mpm_stream_ctx_tc,
cd->content + cd->fp_chop_offset, cd->fp_chop_len,
0, 0, cd->id, s->num, 0);
} else {
MpmAddPatternCI(sgh->mpm_stream_ctx_tc,
cd->content, cd->content_len,
0, 0, cd->id, s->num, 0);
}
}
} else {
if (SGH_DIRECTION_TS(sgh) && s->flags & SIG_FLAG_TOSERVER) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
MpmAddPatternCS(sgh->mpm_stream_ctx_ts,
cd->content + cd->fp_chop_offset, cd->fp_chop_len,
0, 0, cd->id, s->num, 0);
} else {
MpmAddPatternCS(sgh->mpm_stream_ctx_ts,
cd->content, cd->content_len,
0, 0, cd->id, s->num, 0);
}
}
if (SGH_DIRECTION_TC(sgh) && s->flags & SIG_FLAG_TOCLIENT) {
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
MpmAddPatternCS(sgh->mpm_stream_ctx_tc,
cd->content + cd->fp_chop_offset, cd->fp_chop_len,
0, 0, cd->id, s->num, 0);
} else {
MpmAddPatternCS(sgh->mpm_stream_ctx_tc,
cd->content, cd->content_len,
0, 0, cd->id, s->num, 0);
}
}
}
/* tell matcher we are inspecting stream */
s->flags |= SIG_FLAG_MPM_STREAM;
s->mpm_pattern_id_div_8 = cd->id / 8;
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
if (cd->flags & DETECT_CONTENT_NEGATED) {
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
s->flags |= SIG_FLAG_MPM_STREAM_NEG;
}
sgh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
}
}
static void PopulateMpmAddPatternToMpm(const DetectEngineCtx *de_ctx,
SigGroupHead *sgh, Signature *s,
SigMatch *mpm_sm)
@ -1304,7 +1184,7 @@ static void PopulateMpmAddPatternToMpm(const DetectEngineCtx *de_ctx,
switch (sm_list) {
case DETECT_SM_LIST_PMATCH:
{
PopulateMpmAddPatternToMpmPMATCH(de_ctx, sgh, s, mpm_sm);
BUG_ON(1);
break;
} /* case DETECT_CONTENT */
@ -1666,23 +1546,481 @@ static int PatternMatchPreparePopulateMpm(const DetectEngineCtx *de_ctx,
Signature *s = sgh->match_array[sig];
if (s == NULL)
continue;
if (s->mpm_sm == NULL)
continue;
int list = SigMatchListSMBelongsTo(s, s->mpm_sm);
if (list < 0)
continue;
if (list == DETECT_SM_LIST_PMATCH)
continue;
PopulateMpmAddPatternToMpm(de_ctx, sgh, s, s->mpm_sm);
} /* for (sig = 0; sig < sgh->sig_cnt; sig++) */
return 0;
}
/** \internal
* \brief The hash function for MpmStore
*
* \param ht Pointer to the hash table.
* \param data Pointer to the MpmStore.
* \param datalen Not used in our case.
*
* \retval hash The generated hash value.
*/
static uint32_t MpmStoreHashFunc(HashListTable *ht, void *data, uint16_t datalen)
{
const MpmStore *ms = (MpmStore *)data;
uint32_t hash = 0;
uint32_t b = 0;
for (b = 0; b < ms->sid_array_size; b++)
hash += ms->sid_array[b];
return hash % ht->array_size;
}
/**
* \brief The Compare function for MpmStore
*
* \param data1 Pointer to the first MpmStore.
* \param len1 Not used.
* \param data2 Pointer to the second MpmStore.
* \param len2 Not used.
*
* \retval 1 If the 2 MpmStores sent as args match.
* \retval 0 If the 2 MpmStores sent as args do not match.
*/
static char MpmStoreCompareFunc(void *data1, uint16_t len1, void *data2,
uint16_t len2)
{
const MpmStore *ms1 = (MpmStore *)data1;
const MpmStore *ms2 = (MpmStore *)data2;
if (ms1->sid_array_size != ms2->sid_array_size)
return 0;
if (ms1->buffer != ms2->buffer)
return 0;
if (ms1->direction != ms2->direction)
return 0;
if (SCMemcmp(ms1->sid_array, ms2->sid_array,
ms1->sid_array_size) != 0)
{
return 0;
}
return 1;
}
/**
* \brief Initializes the MpmStore mpm hash table to be used by the detection
* engine context.
*
* \param de_ctx Pointer to the detection engine context.
*
* \retval 0 On success.
* \retval -1 On failure.
*/
int MpmStoreInit(DetectEngineCtx *de_ctx)
{
de_ctx->mpm_hash_table = HashListTableInit(4096,
MpmStoreHashFunc,
MpmStoreCompareFunc,
NULL);
if (de_ctx->mpm_hash_table == NULL)
goto error;
return 0;
error:
return -1;
}
/**
* \brief Adds a MpmStore to the detection engine context MpmStore
*
* \param de_ctx Pointer to the detection engine context.
* \param sgh Pointer to the MpmStore.
*
* \retval ret 0 on Successfully adding the argument sgh; -1 on failure.
*/
static int MpmStoreAdd(DetectEngineCtx *de_ctx, MpmStore *s)
{
int ret = HashListTableAdd(de_ctx->mpm_hash_table, (void *)s, 0);
return ret;
}
/**
* \brief Used to lookup a MpmStore from the MpmStore
*
* \param de_ctx Pointer to the detection engine context.
* \param sgh Pointer to the MpmStore.
*
* \retval rsgh On success a pointer to the MpmStore if the MpmStore is
* found in the hash table; NULL on failure.
*/
static MpmStore *MpmStoreLookup(DetectEngineCtx *de_ctx, MpmStore *s)
{
MpmStore *rs = HashListTableLookup(de_ctx->mpm_hash_table,
(void *)s, 0);
return rs;
}
void MpmStoreReportStats(const DetectEngineCtx *de_ctx)
{
HashListTableBucket *htb = NULL;
uint32_t stats[MPMB_MAX] = {0};
for (htb = HashListTableGetListHead(de_ctx->mpm_hash_table);
htb != NULL;
htb = HashListTableGetListNext(htb))
{
const MpmStore *ms = (MpmStore *)HashListTableGetListData(htb);
if (ms == NULL) {
continue;
}
stats[ms->buffer]++;
}
uint32_t x;
for (x = 0; x < MPMB_MAX; x++) {
SCLogInfo("Builtin MPM \"%s\": %u", builtin_mpms[x], stats[x]);
}
}
/**
* \brief Frees the hash table - DetectEngineCtx->mpm_hash_table, allocated by
* MpmStoreInit() function.
*
* \param de_ctx Pointer to the detection engine context.
*/
void MpmStoreFree(DetectEngineCtx *de_ctx)
{
if (de_ctx->mpm_hash_table == NULL)
return;
HashListTableFree(de_ctx->mpm_hash_table);
de_ctx->mpm_hash_table = NULL;
return;
}
void MpmStoreSetup(const DetectEngineCtx *de_ctx, MpmStore *ms)
{
Signature *s = NULL; // TODO const
uint32_t sig;
int32_t sgh_mpm_context = 0;
switch (ms->buffer) {
case MPMB_TCP_PKT_TS:
case MPMB_TCP_PKT_TC:
sgh_mpm_context = de_ctx->sgh_mpm_context_proto_tcp_packet;
break;
case MPMB_TCP_STREAM_TS:
case MPMB_TCP_STREAM_TC:
sgh_mpm_context = de_ctx->sgh_mpm_context_stream;
break;
case MPMB_UDP_TS:
case MPMB_UDP_TC:
sgh_mpm_context = de_ctx->sgh_mpm_context_proto_udp_packet;
break;
case MPMB_OTHERIP:
sgh_mpm_context = de_ctx->sgh_mpm_context_proto_other_packet;
break;
default:
break;
}
int dir = 0;
switch (ms->buffer) {
/* TS is 1 */
case MPMB_TCP_PKT_TS:
case MPMB_TCP_STREAM_TS:
case MPMB_UDP_TS:
dir = 1;
break;
/* TC is 0 */
default:
case MPMB_UDP_TC:
case MPMB_TCP_STREAM_TC:
case MPMB_TCP_PKT_TC:
case MPMB_OTHERIP: /**< use 0 for other */
dir = 0;
break;
}
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
ms->mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, sgh_mpm_context, dir);
} else {
ms->mpm_ctx = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, dir);
}
MpmInitCtx(ms->mpm_ctx, de_ctx->mpm_matcher);
/* add the patterns */
for (sig = 0; sig < (ms->sid_array_size * 8); sig++) {
if (ms->sid_array[sig / 8] & (1 << (sig % 8))) {
s = de_ctx->sig_array[sig];
if (s == NULL)
continue;
if (s->mpm_sm == NULL)
continue;
int list = SigMatchListSMBelongsTo(s, s->mpm_sm);
if (list < 0)
continue;
if (list != DETECT_SM_LIST_PMATCH)
continue;
SCLogDebug("adding %u", s->id);
DetectContentData *cd = (DetectContentData *)s->mpm_sm->ctx; // TODO const
/* TODO move this into cd setup code */
if (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP) {
if (DETECT_CONTENT_IS_SINGLE(cd) &&
!(cd->flags & DETECT_CONTENT_NEGATED) &&
!(cd->flags & DETECT_CONTENT_REPLACE) &&
cd->content_len == cd->fp_chop_len)
{
cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED;
}
} else {
if (DETECT_CONTENT_IS_SINGLE(cd) &&
!(cd->flags & DETECT_CONTENT_NEGATED) &&
!(cd->flags & DETECT_CONTENT_REPLACE))
{
cd->flags |= DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED;
}
}
PopulateMpmHelperAddPatternToPktCtx(ms->mpm_ctx,
cd, s, 0, (cd->flags & DETECT_CONTENT_FAST_PATTERN_CHOP));
/* tell matcher we are inspecting packet */
/* TODO remove! */
if (!(ms->buffer == MPMB_TCP_STREAM_TC || ms->buffer == MPMB_TCP_STREAM_TS)) {
s->flags |= SIG_FLAG_MPM_PACKET;
s->mpm_pattern_id_div_8 = cd->id / 8;
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
if (cd->flags & DETECT_CONTENT_NEGATED) {
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
s->flags |= SIG_FLAG_MPM_PACKET_NEG;
}
} else {
/* tell matcher we are inspecting stream */
s->flags |= SIG_FLAG_MPM_STREAM;
s->mpm_pattern_id_div_8 = cd->id / 8;
s->mpm_pattern_id_mod_8 = 1 << (cd->id % 8);
if (cd->flags & DETECT_CONTENT_NEGATED) {
SCLogDebug("flagging sig %"PRIu32" to be looking for negated mpm", s->id);
s->flags |= SIG_FLAG_MPM_STREAM_NEG;
}
}
}
}
if (ms->mpm_ctx != NULL) {
if (ms->mpm_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, ms->mpm_ctx);
ms->mpm_ctx = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[ms->mpm_ctx->mpm_type].Prepare != NULL) {
mpm_table[ms->mpm_ctx->mpm_type].Prepare(ms->mpm_ctx);
}
}
}
}
}
/** \brief Get MpmStore for a built-in buffer type
*
*/
MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
enum MpmBuiltinBuffers buf)
{
const Signature *s = NULL;
uint32_t sig;
uint32_t cnt = 0;
int direction = 0;
uint32_t max_sid = DetectEngineGetMaxSigId(de_ctx) / 8 + 1;
uint8_t sids_array[max_sid];
memset(sids_array, 0x00, max_sid);
switch(buf) {
case MPMB_TCP_PKT_TS:
case MPMB_TCP_STREAM_TS:
case MPMB_UDP_TS:
direction = SIG_FLAG_TOSERVER;
break;
case MPMB_TCP_PKT_TC:
case MPMB_TCP_STREAM_TC:
case MPMB_UDP_TC:
direction = SIG_FLAG_TOCLIENT;
break;
case MPMB_OTHERIP:
direction = (SIG_FLAG_TOCLIENT|SIG_FLAG_TOSERVER);
break;
case MPMB_MAX:
BUG_ON(1);
break;
}
for (sig = 0; sig < sgh->sig_cnt; sig++) {
s = sgh->match_array[sig];
if (s == NULL)
continue;
if (s->mpm_sm == NULL)
continue;
int list = SigMatchListSMBelongsTo(s, s->mpm_sm);
if (list < 0)
continue;
if (list != DETECT_SM_LIST_PMATCH)
continue;
switch (buf) {
case MPMB_TCP_PKT_TS:
case MPMB_TCP_PKT_TC:
if (SignatureHasPacketContent(s) == 1)
{
sids_array[s->num / 8] |= 1 << (s->num % 8);
cnt++;
}
break;
case MPMB_TCP_STREAM_TS:
case MPMB_TCP_STREAM_TC:
if (SignatureHasStreamContent(s) == 1)
{
sids_array[s->num / 8] |= 1 << (s->num % 8);
cnt++;
}
break;
case MPMB_UDP_TS:
case MPMB_UDP_TC:
sids_array[s->num / 8] |= 1 << (s->num % 8);
cnt++;
break;
case MPMB_OTHERIP:
sids_array[s->num / 8] |= 1 << (s->num % 8);
cnt++;
break;
default:
break;
}
}
if (cnt == 0)
return NULL;
MpmStore lookup = { sids_array, max_sid, direction, buf, NULL};
MpmStore *result = MpmStoreLookup(de_ctx, &lookup);
if (result == NULL) {
MpmStore *copy = SCCalloc(1, sizeof(MpmStore));
if (copy == NULL)
return NULL;
uint8_t *sids = SCCalloc(1, max_sid);
if (sids == NULL) {
SCFree(copy);
return NULL;
}
memcpy(sids, sids_array, max_sid);
copy->sid_array = sids;
copy->sid_array_size = max_sid;
copy->buffer = buf;
copy->direction = direction;
MpmStoreSetup(de_ctx, copy);
MpmStoreAdd(de_ctx, copy);
return copy;
} else {
return result;
}
}
/** \brief Prepare the pattern matcher ctx in a sig group head.
*
* \todo determine if a content match can set the 'single' flag
* \todo do error checking
* \todo rewrite the COPY stuff
*/
int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
int PatternMatchPrepareGroup(DetectEngineCtx *de_ctx, SigGroupHead *sh)
{
MpmStore *mpm_store = NULL;
if (SGH_PROTO(sh, IPPROTO_TCP)) {
if (SGH_DIRECTION_TS(sh)) {
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_PKT_TS);
if (mpm_store != NULL) {
sh->mpm_proto_tcp_ctx_ts = mpm_store->mpm_ctx;
if (sh->mpm_proto_tcp_ctx_ts)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
}
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_STREAM_TS);
if (mpm_store != NULL) {
BUG_ON(mpm_store == NULL);
sh->mpm_stream_ctx_ts = mpm_store->mpm_ctx;
if (sh->mpm_stream_ctx_ts)
sh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
}
}
if (SGH_DIRECTION_TC(sh)) {
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_PKT_TC);
if (mpm_store != NULL) {
sh->mpm_proto_tcp_ctx_tc = mpm_store->mpm_ctx;
if (sh->mpm_proto_tcp_ctx_tc)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
}
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_TCP_STREAM_TC);
if (mpm_store != NULL) {
sh->mpm_stream_ctx_tc = mpm_store->mpm_ctx;
if (sh->mpm_stream_ctx_tc)
sh->flags |= SIG_GROUP_HEAD_MPM_STREAM;
}
}
} else if (SGH_PROTO(sh, IPPROTO_UDP)) {
if (SGH_DIRECTION_TS(sh)) {
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_UDP_TS);
if (mpm_store != NULL) {
BUG_ON(mpm_store == NULL);
sh->mpm_proto_udp_ctx_ts = mpm_store->mpm_ctx;
if (sh->mpm_proto_udp_ctx_ts != NULL)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
}
}
if (SGH_DIRECTION_TC(sh)) {
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_UDP_TC);
if (mpm_store != NULL) {
sh->mpm_proto_udp_ctx_tc = mpm_store->mpm_ctx;
if (sh->mpm_proto_udp_ctx_tc != NULL)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
}
}
} else {
mpm_store = MpmStorePrepareBuffer(de_ctx, sh, MPMB_OTHERIP);
if (mpm_store != NULL) {
sh->mpm_proto_other_ctx = mpm_store->mpm_ctx;
if (sh->mpm_proto_other_ctx != NULL)
sh->flags |= SIG_GROUP_HEAD_MPM_PACKET;
}
}
Signature *s = NULL;
uint32_t has_co_packet = 0; /**< our sgh has packet payload inspecting content */
uint32_t has_co_stream = 0; /**< our sgh has stream inspecting content */
uint32_t has_co_uri = 0; /**< our sgh has uri inspecting content */
/* used to indicate if sgh has atleast one sig with http_client_body */
uint32_t has_co_hcbd = 0;
@ -1720,26 +2058,27 @@ int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
s = sh->match_array[sig];
if (s == NULL)
continue;
if (!(SGH_PROTO(sh, IPPROTO_TCP)) ||
(SGH_PROTO(sh, IPPROTO_TCP) && SignatureHasPacketContent(s) == 1))
{
has_co_packet = 1;
}
if (s->mpm_sm == NULL)
continue;
if (SGH_PROTO(sh, IPPROTO_TCP)) {
if (SignatureHasStreamContent(s) == 1) {
has_co_stream = 1;
}
int list = SigMatchListSMBelongsTo(s, s->mpm_sm);
if (list < 0)
continue;
if (list == DETECT_SM_LIST_PMATCH)
continue;
if (s->sm_lists[DETECT_SM_LIST_UMATCH] != NULL) {
if (SGH_PROTO(sh, IPPROTO_TCP)) {
switch (list) {
case DETECT_SM_LIST_UMATCH:
has_co_uri = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) {
case DETECT_SM_LIST_HCBDMATCH:
has_co_hcbd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL) {
case DETECT_SM_LIST_FILEDATA:
if (s->alproto == ALPROTO_SMTP)
has_co_smtp = 1;
else if (s->alproto == ALPROTO_HTTP)
@ -1748,117 +2087,77 @@ int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
has_co_smtp = 1;
has_co_hsbd = 1;
}
}
break;
if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) {
case DETECT_SM_LIST_HHDMATCH:
has_co_hhd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) {
case DETECT_SM_LIST_HRHDMATCH:
has_co_hrhd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) {
case DETECT_SM_LIST_HMDMATCH:
has_co_hmd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) {
case DETECT_SM_LIST_HCDMATCH:
has_co_hcd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) {
case DETECT_SM_LIST_HRUDMATCH:
has_co_hrud = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) {
case DETECT_SM_LIST_HSMDMATCH:
has_co_hsmd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) {
case DETECT_SM_LIST_HSCDMATCH:
has_co_hscd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) {
case DETECT_SM_LIST_HUADMATCH:
has_co_huad = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL) {
case DETECT_SM_LIST_HHHDMATCH:
has_co_hhhd = 1;
}
break;
if (s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) {
case DETECT_SM_LIST_HRHHDMATCH:
has_co_hrhhd = 1;
}
}
break;
if (SGH_PROTO(sh, IPPROTO_TCP) || SGH_PROTO(sh, IPPROTO_UDP)) {
if (s->sm_lists[DETECT_SM_LIST_DNSQUERYNAME_MATCH] != NULL) {
case DETECT_SM_LIST_DNSQUERYNAME_MATCH:
has_co_dnsquery = 1;
}
}
}
break;
/* intialize contexes */
if (has_co_packet) {
if (SGH_PROTO(sh, IPPROTO_TCP)) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 0);
sh->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_tcp_packet, 1);
} else {
sh->mpm_proto_tcp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
sh->mpm_proto_tcp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
}
if (sh->mpm_proto_tcp_ctx_ts == NULL || sh->mpm_proto_tcp_ctx_tc == NULL) {
SCLogDebug("sh->mpm_proto_tcp_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
MpmInitCtx(sh->mpm_proto_tcp_ctx_ts, de_ctx->mpm_matcher);
MpmInitCtx(sh->mpm_proto_tcp_ctx_tc, de_ctx->mpm_matcher);
}
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 0);
sh->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_udp_packet, 1);
} else {
sh->mpm_proto_udp_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
sh->mpm_proto_udp_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
}
if (sh->mpm_proto_udp_ctx_ts == NULL || sh->mpm_proto_udp_ctx_tc == NULL) {
SCLogDebug("sh->mpm_proto_udp_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
default:
BUG_ON(1);
}
MpmInitCtx(sh->mpm_proto_udp_ctx_ts, de_ctx->mpm_matcher);
MpmInitCtx(sh->mpm_proto_udp_ctx_tc, de_ctx->mpm_matcher);
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_proto_other_ctx =
MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_proto_other_packet, 0);
} else {
sh->mpm_proto_other_ctx =
MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
}
if (sh->mpm_proto_other_ctx == NULL) {
SCLogDebug("sh->mpm_proto_other_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
/* UDP */
} else if (SGH_PROTO(sh, IPPROTO_UDP)) {
switch (list) {
case DETECT_SM_LIST_DNSQUERYNAME_MATCH:
has_co_dnsquery = 1;
break;
default:
BUG_ON(1);
}
MpmInitCtx(sh->mpm_proto_other_ctx, de_ctx->mpm_matcher);
} /* if (has_co_packet) */
if (has_co_stream) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_stream_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 0);
sh->mpm_stream_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_stream, 1);
/* all other protos just support PMATCH */
} else {
sh->mpm_stream_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 0);
sh->mpm_stream_ctx_tc = MpmFactoryGetMpmCtxForProfile(de_ctx, MPM_CTX_FACTORY_UNIQUE_CONTEXT, 1);
switch (list) {
default:
BUG_ON(1);
}
if (sh->mpm_stream_ctx_tc == NULL || sh->mpm_stream_ctx_ts == NULL) {
SCLogDebug("sh->mpm_stream_ctx == NULL. This should never happen");
exit(EXIT_FAILURE);
}
MpmInitCtx(sh->mpm_stream_ctx_ts, de_ctx->mpm_matcher);
MpmInitCtx(sh->mpm_stream_ctx_tc, de_ctx->mpm_matcher);
}
/* intialize contexes */
if (has_co_uri) {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_SINGLE) {
sh->mpm_uri_ctx_ts = MpmFactoryGetMpmCtxForProfile(de_ctx, de_ctx->sgh_mpm_context_uri, 0);
@ -2078,9 +2377,7 @@ int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
MpmInitCtx(sh->mpm_dnsquery_ctx_ts, de_ctx->mpm_matcher);
}
if (has_co_packet ||
has_co_stream ||
has_co_uri ||
if (has_co_uri ||
has_co_hcbd ||
has_co_hsbd ||
has_co_smtp ||
@ -2099,97 +2396,6 @@ int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
/* add the patterns of all the rules to the mpms of this sgh */
PatternMatchPreparePopulateMpm(de_ctx, sh);
if (sh->mpm_proto_tcp_ctx_ts != NULL) {
if (sh->mpm_proto_tcp_ctx_ts->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_ts);
sh->mpm_proto_tcp_ctx_ts = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type].Prepare != NULL) {
mpm_table[sh->mpm_proto_tcp_ctx_ts->mpm_type].
Prepare(sh->mpm_proto_tcp_ctx_ts);
}
}
}
}
if (sh->mpm_proto_tcp_ctx_tc != NULL) {
if (sh->mpm_proto_tcp_ctx_tc->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc);
sh->mpm_proto_tcp_ctx_tc = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type].Prepare != NULL) {
mpm_table[sh->mpm_proto_tcp_ctx_tc->mpm_type].
Prepare(sh->mpm_proto_tcp_ctx_tc);
}
}
}
}
if (sh->mpm_proto_udp_ctx_ts != NULL) {
if (sh->mpm_proto_udp_ctx_ts->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_ts);
sh->mpm_proto_udp_ctx_ts = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type].Prepare != NULL) {
mpm_table[sh->mpm_proto_udp_ctx_ts->mpm_type].
Prepare(sh->mpm_proto_udp_ctx_ts);
}
}
}
}
if (sh->mpm_proto_udp_ctx_tc != NULL) {
if (sh->mpm_proto_udp_ctx_tc->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_tc);
sh->mpm_proto_udp_ctx_tc = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type].Prepare != NULL) {
mpm_table[sh->mpm_proto_udp_ctx_tc->mpm_type].
Prepare(sh->mpm_proto_udp_ctx_tc);
}
}
}
}
if (sh->mpm_proto_other_ctx != NULL) {
if (sh->mpm_proto_other_ctx->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx);
sh->mpm_proto_other_ctx = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_proto_other_ctx->mpm_type].Prepare != NULL) {
mpm_table[sh->mpm_proto_other_ctx->mpm_type].
Prepare(sh->mpm_proto_other_ctx);
}
}
}
}
if (sh->mpm_stream_ctx_ts != NULL) {
if (sh->mpm_stream_ctx_ts->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_ts);
sh->mpm_stream_ctx_ts = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_stream_ctx_ts->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_stream_ctx_ts->mpm_type].Prepare(sh->mpm_stream_ctx_ts);
}
}
}
if (sh->mpm_stream_ctx_tc != NULL) {
if (sh->mpm_stream_ctx_tc->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_tc);
sh->mpm_stream_ctx_tc = NULL;
} else {
if (de_ctx->sgh_mpm_context == ENGINE_SGH_MPM_FACTORY_CONTEXT_FULL) {
if (mpm_table[sh->mpm_stream_ctx_tc->mpm_type].Prepare != NULL)
mpm_table[sh->mpm_stream_ctx_tc->mpm_type].Prepare(sh->mpm_stream_ctx_tc);
}
}
}
if (sh->mpm_uri_ctx_ts != NULL) {
if (sh->mpm_uri_ctx_ts->pattern_cnt == 0) {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_ts);
@ -2404,15 +2610,6 @@ int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
}
}
} else {
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_other_ctx);
sh->mpm_proto_other_ctx = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_ts);
sh->mpm_proto_tcp_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_ts);
sh->mpm_proto_udp_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_ts);
sh->mpm_stream_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_uri_ctx_ts);
sh->mpm_uri_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hcbd_ctx_ts);
@ -2438,12 +2635,6 @@ int PatternMatchPrepareGroup(const DetectEngineCtx *de_ctx, SigGroupHead *sh)
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_smtp_filedata_ctx_ts);
sh->mpm_smtp_filedata_ctx_ts = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_tcp_ctx_tc);
sh->mpm_proto_tcp_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_proto_udp_ctx_tc);
sh->mpm_proto_udp_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_stream_ctx_tc);
sh->mpm_stream_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hhd_ctx_tc);
sh->mpm_hhd_ctx_tc = NULL;
MpmFactoryReClaimMpmCtx(de_ctx, sh->mpm_hrhd_ctx_tc);

@ -64,7 +64,7 @@ void PatternMatchDestroy(MpmCtx *, uint16_t);
void PatternMatchThreadDestroy(MpmThreadCtx *mpm_thread_ctx, uint16_t);
void PatternMatchThreadPrint(MpmThreadCtx *, uint16_t);
int PatternMatchPrepareGroup(const DetectEngineCtx *, SigGroupHead *);
int PatternMatchPrepareGroup(DetectEngineCtx *, SigGroupHead *);
void DetectEngineThreadCtxInfo(ThreadVars *, DetectEngineThreadCtx *);
void PatternMatchDestroyGroup(SigGroupHead *);
@ -83,6 +83,11 @@ int SignatureHasStreamContent(const Signature *);
SigMatch *RetrieveFPForSig(Signature *s);
int MpmStoreInit(DetectEngineCtx *);
void MpmStoreFree(DetectEngineCtx *);
void MpmStoreReportStats(const DetectEngineCtx *de_ctx);
MpmStore *MpmStorePrepareBuffer(DetectEngineCtx *de_ctx, SigGroupHead *sgh, enum MpmBuiltinBuffers buf);
/**
* \brief Figured out the FP and their respective content ids for all the
* sigs in the engine.

@ -203,133 +203,6 @@ void SigGroupHeadFree(SigGroupHead *sgh)
return;
}
/**
* \brief The hash function to be the used by the mpm SigGroupHead hash table -
* DetectEngineCtx->sgh_mpm_hash_table.
*
* \param ht Pointer to the hash table.
* \param data Pointer to the SigGroupHead.
* \param datalen Not used in our case.
*
* \retval hash The generated hash value.
*/
uint32_t SigGroupHeadMpmHashFunc(HashListTable *ht, void *data, uint16_t datalen)
{
SigGroupHead *sgh = (SigGroupHead *)data;
uint32_t hash = 0;
uint32_t b = 0;
for (b = 0; b < sgh->init->content_size; b++)
hash += sgh->init->content_array[b];
return hash % ht->array_size;
}
/**
* \brief The Compare function to be used by the mpm SigGroupHead hash table -
* DetectEngineCtx->sgh_mpm_hash_table.
*
* \param data1 Pointer to the first SigGroupHead.
* \param len1 Not used.
* \param data2 Pointer to the second SigGroupHead.
* \param len2 Not used.
*
* \retval 1 If the 2 SigGroupHeads sent as args match.
* \retval 0 If the 2 SigGroupHeads sent as args do not match.
*/
char SigGroupHeadMpmCompareFunc(void *data1, uint16_t len1, void *data2,
uint16_t len2)
{
SigGroupHead *sgh1 = (SigGroupHead *)data1;
SigGroupHead *sgh2 = (SigGroupHead *)data2;
if (sgh1->init->content_size != sgh2->init->content_size)
return 0;
if (SCMemcmp(sgh1->init->content_array, sgh2->init->content_array,
sgh1->init->content_size) != 0) {
return 0;
}
return 1;
}
/**
* \brief Initializes the SigGroupHead mpm hash table to be used by the detection
* engine context.
*
* \param de_ctx Pointer to the detection engine context.
*
* \retval 0 On success.
* \retval -1 On failure.
*/
int SigGroupHeadMpmHashInit(DetectEngineCtx *de_ctx)
{
de_ctx->sgh_mpm_hash_table = HashListTableInit(4096, SigGroupHeadMpmHashFunc,
SigGroupHeadMpmCompareFunc,
NULL);
if (de_ctx->sgh_mpm_hash_table == NULL)
goto error;
return 0;
error:
return -1;
}
/**
* \brief Adds a SigGroupHead to the detection engine context SigGroupHead
* mpm hash table.
*
* \param de_ctx Pointer to the detection engine context.
* \param sgh Pointer to the SigGroupHead.
*
* \retval ret 0 on Successfully adding the argument sgh; -1 on failure.
*/
int SigGroupHeadMpmHashAdd(DetectEngineCtx *de_ctx, SigGroupHead *sgh)
{
int ret = HashListTableAdd(de_ctx->sgh_mpm_hash_table, (void *)sgh, 0);
return ret;
}
/**
* \brief Used to lookup a SigGroupHead from the detection engine context
* SigGroupHead mpm hash table.
*
* \param de_ctx Pointer to the detection engine context.
* \param sgh Pointer to the SigGroupHead.
*
* \retval rsgh On success a pointer to the SigGroupHead if the SigGroupHead is
* found in the hash table; NULL on failure.
*/
SigGroupHead *SigGroupHeadMpmHashLookup(DetectEngineCtx *de_ctx,
SigGroupHead *sgh)
{
SigGroupHead *rsgh = HashListTableLookup(de_ctx->sgh_mpm_hash_table,
(void *)sgh, 0);
return rsgh;
}
/**
* \brief Frees the hash table - DetectEngineCtx->sgh_mpm_hash_table, allocated by
* SigGroupHeadMpmHashInit() function.
*
* \param de_ctx Pointer to the detection engine context.
*/
void SigGroupHeadMpmHashFree(DetectEngineCtx *de_ctx)
{
if (de_ctx->sgh_mpm_hash_table == NULL)
return;
HashListTableFree(de_ctx->sgh_mpm_hash_table);
de_ctx->sgh_mpm_hash_table = NULL;
return;
}
/**
* \brief The hash function to be the used by the hash table -
* DetectEngineCtx->sgh_hash_table.
@ -1192,28 +1065,6 @@ int SigGroupHeadContainsSigId(DetectEngineCtx *de_ctx, SigGroupHead *sgh,
int SigAddressPrepareStage1(DetectEngineCtx *);
/**
* \test Check if a SigGroupHead mpm hash table is properly allocated and
* deallocated when calling SigGroupHeadMpmHashInit() and
* SigGroupHeadMpmHashFree() respectively.
*/
static int SigGroupHeadTest01(void)
{
int result = 1;
DetectEngineCtx de_ctx;
SigGroupHeadMpmHashInit(&de_ctx);
result &= (de_ctx.sgh_mpm_hash_table != NULL);
SigGroupHeadMpmHashFree(&de_ctx);
result &= (de_ctx.sgh_mpm_hash_table == NULL);
return result;
}
/**
* \test Check if a SigGroupHead hash table is properly allocated and
* deallocated when calling SigGroupHeadHashInit() and
@ -1720,7 +1571,6 @@ end:
void SigGroupHeadRegisterTests(void)
{
#ifdef UNITTESTS
UtRegisterTest("SigGroupHeadTest01", SigGroupHeadTest01, 1);
UtRegisterTest("SigGroupHeadTest03", SigGroupHeadTest03, 1);
UtRegisterTest("SigGroupHeadTest04", SigGroupHeadTest04, 1);
UtRegisterTest("SigGroupHeadTest06", SigGroupHeadTest06, 1);

@ -871,7 +871,7 @@ static DetectEngineCtx *DetectEngineCtxInitReal(int minimal, const char *prefix)
DetectEngineCtxLoadConf(de_ctx);
SigGroupHeadHashInit(de_ctx);
SigGroupHeadMpmHashInit(de_ctx);
MpmStoreInit(de_ctx);
SigGroupHeadDPortHashInit(de_ctx);
ThresholdHashInit(de_ctx);
VariableNameInitHash(de_ctx);
@ -956,7 +956,7 @@ void DetectEngineCtxFree(DetectEngineCtx *de_ctx)
* to be sure look at them again here.
*/
SigGroupHeadHashFree(de_ctx);
SigGroupHeadMpmHashFree(de_ctx);
MpmStoreFree(de_ctx);
SigGroupHeadDPortHashFree(de_ctx);
DetectParseDupSigHashFree(de_ctx);
SCSigSignatureOrderingModuleCleanup(de_ctx);

@ -3534,6 +3534,7 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx)
SigGroupHead *sgh = de_ctx->sgh_array[idx];
if (sgh == NULL)
continue;
SigGroupHeadSetFilemagicFlag(de_ctx, sgh);
SigGroupHeadSetFileMd5Flag(de_ctx, sgh);
SigGroupHeadSetFilesizeFlag(de_ctx, sgh);
@ -3549,6 +3550,8 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx)
}
SCLogInfo("Unique rule groups: %u", cnt);
MpmStoreReportStats(de_ctx);
if (de_ctx->decoder_event_sgh != NULL) {
/* no need to set filestore count here as that would make a
* signature not decode event only. */
@ -3563,7 +3566,7 @@ int SigAddressPrepareStage4(DetectEngineCtx *de_ctx)
* after the initialization phase. */
SigGroupHeadHashFree(de_ctx);
SigGroupHeadDPortHashFree(de_ctx);
SigGroupHeadMpmHashFree(de_ctx);
MpmStoreFree(de_ctx);
SCFree(de_ctx->sgh_array);
de_ctx->sgh_array_cnt = 0;

@ -606,7 +606,7 @@ typedef struct DetectEngineCtx_ {
/* init phase vars */
HashListTable *sgh_hash_table;
HashListTable *sgh_mpm_hash_table;
HashListTable *mpm_hash_table;
HashListTable *sgh_dport_hash_table;
@ -959,10 +959,30 @@ typedef struct SigTableElmt_ {
#define SIG_GROUP_HEAD_MPM_DNSQUERY (1 << 23)
#define SIG_GROUP_HEAD_MPM_FD_SMTP (1 << 24)
enum MpmBuiltinBuffers {
MPMB_TCP_PKT_TS,
MPMB_TCP_PKT_TC,
MPMB_TCP_STREAM_TS,
MPMB_TCP_STREAM_TC,
MPMB_UDP_TS,
MPMB_UDP_TC,
MPMB_OTHERIP,
MPMB_MAX,
};
typedef struct MpmStore_ {
uint8_t *sid_array;
uint32_t sid_array_size;
int direction;
enum MpmBuiltinBuffers buffer;
MpmCtx *mpm_ctx;
} MpmStore;
typedef struct SigGroupHeadInitData_ {
/* list of content containers */
uint8_t *content_array;
uint32_t content_size;
MpmStore mpm_store[MPMB_MAX];
uint8_t *sig_array; /**< bit array of sig nums (internal id's) */
uint32_t sig_size; /**< size in bytes */

Loading…
Cancel
Save