From 601836d8316b89c64810ec579ef699669077cd8a Mon Sep 17 00:00:00 2001 From: Anoop Saldanha Date: Fri, 1 Mar 2013 09:18:52 +0530 Subject: [PATCH] Fast pattern setup now configurable in our code. You can either enable/disable fp for a particular type + set priority. --- src/detect-engine-mpm.c | 120 +++++++++++++++++++++++++++++++++++++- src/detect-engine-mpm.h | 1 + src/detect-fast-pattern.c | 101 +++++++++++++++++++++++--------- src/detect-fast-pattern.h | 3 +- src/detect.c | 2 +- 5 files changed, 195 insertions(+), 32 deletions(-) diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 74c77fe46c..3030315444 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -1862,6 +1862,124 @@ SigMatch *RetrieveFPForSig(Signature *s) return mpm_sm; } +SigMatch *RetrieveFPForSigV2(Signature *s) +{ + if (s->mpm_sm != NULL) + return s->mpm_sm; + + + SigMatch *mpm_sm = NULL; + + int nn_sm_list[DETECT_SM_LIST_MAX]; + int n_sm_list[DETECT_SM_LIST_MAX]; + memset(nn_sm_list, 0, sizeof(nn_sm_list)); + memset(n_sm_list, 0, sizeof(n_sm_list)); + int count_nn_sm_list = 0; + int count_n_sm_list = 0; + + for (int list_id = 0; list_id < DETECT_SM_LIST_MAX; list_id++) { + if (!FastPatternSupportEnabledForSigMatchList(list_id)) + continue; + + for (SigMatch *sm = s->sm_lists[list_id]; sm != NULL; sm = sm->next) { + if (sm->type != DETECT_CONTENT) + continue; + + DetectContentData *cd = (DetectContentData *)sm->ctx; + if ((cd->flags & DETECT_CONTENT_FAST_PATTERN)) + return sm; + if (cd->flags & DETECT_CONTENT_NEGATED) { + n_sm_list[list_id] = 1; + count_n_sm_list++; + } else { + nn_sm_list[list_id] = 1; + count_nn_sm_list++; + } + } /* for */ + } /* for */ + + int *curr_sm_list = NULL; + int skip_negated_content = 1; + if (count_nn_sm_list > 0) { + curr_sm_list = nn_sm_list; + } else if (count_n_sm_list > 0) { + curr_sm_list = n_sm_list; + skip_negated_content = 0; + } else { + return NULL; + } + + int final_sm_list[DETECT_SM_LIST_MAX]; + int count_final_sm_list = 0; + + SCFPSupportSMList *tmp = sm_fp_support_smlist_list; + while (tmp != NULL) { + for (int priority = tmp->priority; + tmp != NULL && priority == tmp->priority; + tmp = tmp->next) { + + if (curr_sm_list[tmp->list_id] == 0) + continue; + final_sm_list[count_final_sm_list++] = tmp->list_id; + } + if (count_final_sm_list != 0) + break; + } + + BUG_ON(count_final_sm_list == 0); + + int max_len = 0; + for (int i = 0; i < count_final_sm_list; i++) { + for (SigMatch *sm = s->sm_lists[final_sm_list[i]]; sm != NULL; sm = sm->next) { + if (sm->type != DETECT_CONTENT) + continue; + + DetectContentData *cd = (DetectContentData *)sm->ctx; + /* skip_negated_content is only set if there's absolutely no + * non-negated content present in the sig */ + if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content) + continue; + if (max_len < cd->content_len) + max_len = cd->content_len; + } + } + + for (int i = 0; i < count_final_sm_list; i++) { + for (SigMatch *sm = s->sm_lists[final_sm_list[i]]; sm != NULL; sm = sm->next) { + if (sm->type != DETECT_CONTENT) + continue; + + DetectContentData *cd = (DetectContentData *)sm->ctx; + /* skip_negated_content is only set if there's absolutely no + * non-negated content present in the sig */ + if ((cd->flags & DETECT_CONTENT_NEGATED) && skip_negated_content) + continue; + if (cd->content_len != max_len) + continue; + + if (mpm_sm == NULL) { + mpm_sm = sm; + } else { + DetectContentData *data1 = (DetectContentData *)sm->ctx; + DetectContentData *data2 = (DetectContentData *)mpm_sm->ctx; + uint32_t ls = PatternStrength(data1->content, data1->content_len); + uint32_t ss = PatternStrength(data2->content, data2->content_len); + if (ls > ss) { + mpm_sm = sm; + } else if (ls == ss) { + /* if 2 patterns are of equal strength, we pick the longest */ + if (data1->content_len > data2->content_len) + mpm_sm = sm; + } else { + SCLogDebug("sticking with mpm_sm"); + } + } /* else - if */ + } /* for */ + } /* for */ + + return mpm_sm; +} + /** * \internal * \brief Setup the mpm content. @@ -1879,7 +1997,7 @@ static int PatternMatchPreparePopulateMpm(DetectEngineCtx *de_ctx, Signature *s = sgh->match_array[sig]; if (s == NULL) continue; - PopulateMpmAddPatternToMpm(de_ctx, sgh, s, RetrieveFPForSig(s)); + PopulateMpmAddPatternToMpm(de_ctx, sgh, s, RetrieveFPForSigV2(s)); } /* for (sig = 0; sig < sgh->sig_cnt; sig++) */ return 0; diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 05b74c8c5b..ff2d0e3b0e 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -82,6 +82,7 @@ int SignatureHasPacketContent(Signature *); int SignatureHasStreamContent(Signature *); SigMatch *RetrieveFPForSig(Signature *s); +SigMatch *RetrieveFPForSigV2(Signature *s); #endif /* __DETECT_ENGINE_MPM_H__ */ diff --git a/src/detect-fast-pattern.c b/src/detect-fast-pattern.c index e400047eb4..6c2583b87b 100644 --- a/src/detect-fast-pattern.c +++ b/src/detect-fast-pattern.c @@ -54,28 +54,57 @@ SCFPSupportSMList *sm_fp_support_smlist_list = NULL; * keywords later. * * \param list_id SM list id. + * \param priority Priority for this list. */ -static void SupportFastPatternForSigMatchList(int list_id) -{ - if (sm_fp_support_smlist_list != NULL) { - SCFPSupportSMList *tmp_smlist_fp = sm_fp_support_smlist_list; - while (tmp_smlist_fp != NULL) { - if (tmp_smlist_fp->list_id == list_id) - return; - tmp_smlist_fp = tmp_smlist_fp->next; +static void SupportFastPatternForSigMatchList(int list_id, int priority) +{ + if (sm_fp_support_smlist_list == NULL) { + SCFPSupportSMList *new = SCMalloc(sizeof(SCFPSupportSMList)); + if (unlikely(new == NULL)) + exit(EXIT_FAILURE); + memset(new, 0, sizeof(SCFPSupportSMList)); + new->list_id = list_id; + new->priority = priority; + + sm_fp_support_smlist_list = new; + + return; + } + + /* insertion point - ip */ + SCFPSupportSMList *ip = NULL; + for (SCFPSupportSMList *tmp = sm_fp_support_smlist_list; tmp != NULL; tmp = tmp->next) { + if (list_id == tmp->list_id) { + SCLogError(SC_ERR_FATAL, "SM list already registered."); + exit(EXIT_FAILURE); } + + if (priority <= tmp->priority) + break; + + ip = tmp; } - SCFPSupportSMList *new_smlist_fp = SCMalloc(sizeof(SCFPSupportSMList)); - if (unlikely(new_smlist_fp == NULL)) { - SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); + SCFPSupportSMList *new = SCMalloc(sizeof(SCFPSupportSMList)); + if (unlikely(new == NULL)) exit(EXIT_FAILURE); + memset(new, 0, sizeof(SCFPSupportSMList)); + new->list_id = list_id; + new->priority = priority; + if (ip == NULL) { + new->next = sm_fp_support_smlist_list; + sm_fp_support_smlist_list = new; + } else { + new->next = ip->next; + ip->next = new; } - memset(new_smlist_fp, 0, sizeof(SCFPSupportSMList)); - new_smlist_fp->list_id = list_id; - new_smlist_fp->next = sm_fp_support_smlist_list; - sm_fp_support_smlist_list = new_smlist_fp; + for (SCFPSupportSMList *tmp = new->next; tmp != NULL; tmp = tmp->next) { + if (list_id == tmp->list_id) { + SCLogError(SC_ERR_FATAL, "SM list already registered."); + exit(EXIT_FAILURE); + } + } return; } @@ -85,20 +114,34 @@ static void SupportFastPatternForSigMatchList(int list_id) */ void SupportFastPatternForSigMatchTypes(void) { - SupportFastPatternForSigMatchList(DETECT_SM_LIST_PMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_UMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCBDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSBDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HHDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRHDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HMDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRUDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSMDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSCDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HUADMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HHHDMATCH); - SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRHHDMATCH); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCBDMATCH, 2); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSBDMATCH, 2); + + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HHDMATCH, 2); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRHDMATCH, 2); + + SupportFastPatternForSigMatchList(DETECT_SM_LIST_UMATCH, 2); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRUDMATCH, 2); + + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HHHDMATCH, 2); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HRHHDMATCH, 2); + + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HCDMATCH, 2); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HUADMATCH, 2); + + SupportFastPatternForSigMatchList(DETECT_SM_LIST_PMATCH, 3); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HMDMATCH, 3); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSCDMATCH, 3); + SupportFastPatternForSigMatchList(DETECT_SM_LIST_HSMDMATCH, 3); + +#if 0 + SCFPSupportSMList *tmp = sm_fp_support_smlist_list; + while (tmp != NULL) { + printf("%d - %d\n", tmp->list_id, tmp->priority); + + tmp = tmp->next; + } +#endif return; } diff --git a/src/detect-fast-pattern.h b/src/detect-fast-pattern.h index 4261ca881a..8298e7bbf9 100644 --- a/src/detect-fast-pattern.h +++ b/src/detect-fast-pattern.h @@ -27,7 +27,8 @@ typedef struct SCFPSupportSMList_ { /* the list id. Have a look at Signature->sm_lists[] */ int list_id; - /* the next memeber in the list */ + int priority; + struct SCFPSupportSMList_ *next; } SCFPSupportSMList; diff --git a/src/detect.c b/src/detect.c index 01ef1ee923..f1cb901ffd 100644 --- a/src/detect.c +++ b/src/detect.c @@ -337,7 +337,7 @@ int DetectLoadSigFile(DetectEngineCtx *de_ctx, char *sig_file, int *sigs_tot) { (*sigs_tot)++; if (sig != NULL) { if (rule_engine_analysis_set || fp_engine_analysis_set) { - sig->mpm_sm = RetrieveFPForSig(sig); + sig->mpm_sm = RetrieveFPForSigV2(sig); if (fp_engine_analysis_set) { EngineAnalysisFP(sig, line); }