]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
Fast pattern setup now configurable in our code.
authorAnoop Saldanha <anoopsaldanha@gmail.com>
Fri, 1 Mar 2013 03:48:52 +0000 (09:18 +0530)
committerVictor Julien <victor@inliniac.net>
Wed, 20 Mar 2013 11:23:52 +0000 (12:23 +0100)
You can either enable/disable fp for a particular type + set priority.

src/detect-engine-mpm.c
src/detect-engine-mpm.h
src/detect-fast-pattern.c
src/detect-fast-pattern.h
src/detect.c

index 74c77fe46ccd66c6b36c2b024a539b565de2e56d..303031544438fa8984fb17019b3bb8ed4a1b11b0 100644 (file)
@@ -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;
index 05b74c8c5bdbde11b464fb7b306fc84b6c350d42..ff2d0e3b0e963b80d557367ff91b79ec056f2a28 100644 (file)
@@ -82,6 +82,7 @@ int SignatureHasPacketContent(Signature *);
 int SignatureHasStreamContent(Signature *);
 
 SigMatch *RetrieveFPForSig(Signature *s);
+SigMatch *RetrieveFPForSigV2(Signature *s);
 
 #endif /* __DETECT_ENGINE_MPM_H__ */
 
index e400047eb4ea433109a6394164e7556c9386e2ea..6c2583b87bb652a51f8fbef9ef7b503dc23c0a6e 100644 (file)
@@ -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;
 }
index 4261ca881a5fa438358ce3b64c8ae3141ab7edf9..8298e7bbf9decd1d67445d340bfec3eca5b62956 100644 (file)
@@ -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;
 
index 01ef1ee9239f6fc706e67e4bbd2f7f2cbb7afc72..f1cb901ffd42032997044bd848288804596e9b3b 100644 (file)
@@ -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);
                 }