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.
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;
* 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;
}
*/
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;
}