Fast pattern setup now configurable in our code.

You can either enable/disable fp for a particular type + set priority.
pull/325/head
Anoop Saldanha 13 years ago committed by Victor Julien
parent c63317d02e
commit 601836d831

@ -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;

@ -82,6 +82,7 @@ int SignatureHasPacketContent(Signature *);
int SignatureHasStreamContent(Signature *);
SigMatch *RetrieveFPForSig(Signature *s);
SigMatch *RetrieveFPForSigV2(Signature *s);
#endif /* __DETECT_ENGINE_MPM_H__ */

@ -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;
}

@ -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;

@ -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);
}

Loading…
Cancel
Save