diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index d678e9aa9f..4c37958e05 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -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,145 +2058,106 @@ 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) { - has_co_uri = 1; - } - if (s->sm_lists[DETECT_SM_LIST_HCBDMATCH] != NULL) { - has_co_hcbd = 1; - } + if (SGH_PROTO(sh, IPPROTO_TCP)) { + switch (list) { + case DETECT_SM_LIST_UMATCH: + has_co_uri = 1; + break; + + case DETECT_SM_LIST_HCBDMATCH: + has_co_hcbd = 1; + break; + + case DETECT_SM_LIST_FILEDATA: + if (s->alproto == ALPROTO_SMTP) + has_co_smtp = 1; + else if (s->alproto == ALPROTO_HTTP) + has_co_hsbd = 1; + else if (s->alproto == ALPROTO_UNKNOWN) { + has_co_smtp = 1; + has_co_hsbd = 1; + } + break; - if (s->sm_lists[DETECT_SM_LIST_FILEDATA] != NULL) { - if (s->alproto == ALPROTO_SMTP) - has_co_smtp = 1; - else if (s->alproto == ALPROTO_HTTP) - has_co_hsbd = 1; - else if (s->alproto == ALPROTO_UNKNOWN) { - has_co_smtp = 1; - has_co_hsbd = 1; - } - } + case DETECT_SM_LIST_HHDMATCH: + has_co_hhd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HHDMATCH] != NULL) { - has_co_hhd = 1; - } + case DETECT_SM_LIST_HRHDMATCH: + has_co_hrhd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HRHDMATCH] != NULL) { - has_co_hrhd = 1; - } + case DETECT_SM_LIST_HMDMATCH: + has_co_hmd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HMDMATCH] != NULL) { - has_co_hmd = 1; - } + case DETECT_SM_LIST_HCDMATCH: + has_co_hcd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HCDMATCH] != NULL) { - has_co_hcd = 1; - } + case DETECT_SM_LIST_HRUDMATCH: + has_co_hrud = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HRUDMATCH] != NULL) { - has_co_hrud = 1; - } + case DETECT_SM_LIST_HSMDMATCH: + has_co_hsmd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HSMDMATCH] != NULL) { - has_co_hsmd = 1; - } + case DETECT_SM_LIST_HSCDMATCH: + has_co_hscd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HSCDMATCH] != NULL) { - has_co_hscd = 1; - } + case DETECT_SM_LIST_HUADMATCH: + has_co_huad = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HUADMATCH] != NULL) { - has_co_huad = 1; - } + case DETECT_SM_LIST_HHHDMATCH: + has_co_hhhd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HHHDMATCH] != NULL) { - has_co_hhhd = 1; - } + case DETECT_SM_LIST_HRHHDMATCH: + has_co_hrhhd = 1; + break; - if (s->sm_lists[DETECT_SM_LIST_HRHHDMATCH] != NULL) { - has_co_hrhhd = 1; - } - } + case DETECT_SM_LIST_DNSQUERYNAME_MATCH: + has_co_dnsquery = 1; + break; - if (SGH_PROTO(sh, IPPROTO_TCP) || SGH_PROTO(sh, IPPROTO_UDP)) { - if (s->sm_lists[DETECT_SM_LIST_DNSQUERYNAME_MATCH] != NULL) { - has_co_dnsquery = 1; + default: + BUG_ON(1); } - } - } - /* 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); - } - MpmInitCtx(sh->mpm_proto_udp_ctx_ts, de_ctx->mpm_matcher); - MpmInitCtx(sh->mpm_proto_udp_ctx_tc, de_ctx->mpm_matcher); + /* UDP */ + } else if (SGH_PROTO(sh, IPPROTO_UDP)) { + switch (list) { + case DETECT_SM_LIST_DNSQUERYNAME_MATCH: + has_co_dnsquery = 1; + break; - 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); - } - MpmInitCtx(sh->mpm_proto_other_ctx, de_ctx->mpm_matcher); - } /* if (has_co_packet) */ + default: + BUG_ON(1); + } - 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); - } - 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); + switch (list) { + default: + BUG_ON(1); + } } - 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); diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index b0d9f12fca..235b96da08 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -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. diff --git a/src/detect-engine-siggroup.c b/src/detect-engine-siggroup.c index fd2f404bd4..9d04697cc9 100644 --- a/src/detect-engine-siggroup.c +++ b/src/detect-engine-siggroup.c @@ -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); diff --git a/src/detect-engine.c b/src/detect-engine.c index 0885e590c0..80a701e7e9 100644 --- a/src/detect-engine.c +++ b/src/detect-engine.c @@ -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); diff --git a/src/detect.c b/src/detect.c index 10180e438b..1abf9d5459 100644 --- a/src/detect.c +++ b/src/detect.c @@ -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; diff --git a/src/detect.h b/src/detect.h index ae4011c268..e1c441b0da 100644 --- a/src/detect.h +++ b/src/detect.h @@ -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 */