detect: don't rescan when just distance is used

Content inspection optimization: when just distance is used without
within we don't need to search recursively.

E.g. content:"a"; content:"b"; distance:1; will scan the buffer for
'a' and when it finds 'a' it will scan the remainder for 'b'. Until
now, the failure to find 'b' would lead to looking for the next 'a'
and then for 'b' after that. However, we already inspected the
entire buffer for 'b', so we know this will fail.
pull/2942/head
Victor Julien 8 years ago
parent 7419bb2bac
commit 1a39ab99f3

@ -3031,7 +3031,7 @@ int DetectByteExtractTest48(void)
if (strncmp((char *)cd->content, "four", cd->content_len) != 0 ||
cd->flags != (DETECT_CONTENT_DISTANCE_BE |
DETECT_CONTENT_DISTANCE |
DETECT_CONTENT_RELATIVE_NEXT) ||
DETECT_CONTENT_DISTANCE_NEXT) ||
cd->distance != bed1->local_id ||
cd->depth != 0 ||
cd->offset != 0) {
@ -3260,7 +3260,7 @@ int DetectByteExtractTest50(void)
if (strncmp((char *)cd->content, "four", cd->content_len) != 0 ||
cd->flags != (DETECT_CONTENT_WITHIN_BE |
DETECT_CONTENT_WITHIN|
DETECT_CONTENT_RELATIVE_NEXT) ||
DETECT_CONTENT_WITHIN_NEXT) ||
cd->within != bed1->local_id ||
cd->depth != 0 ||
cd->offset != 0 ||

@ -39,8 +39,7 @@
/** content is negated */
#define DETECT_CONTENT_NEGATED (1 << 9)
/** a relative match to this content is next, used in matching phase */
#define DETECT_CONTENT_RELATIVE_NEXT (1 << 10)
// bit 10 unused
/* BE - byte extract */
#define DETECT_CONTENT_OFFSET_BE (1 << 11)
@ -53,7 +52,12 @@
/* this flag is set during the staging phase. It indicates that a content
* has been added to the mpm phase and requires no further inspection inside
* the inspection phase */
#define DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED (1 << 16)
#define DETECT_CONTENT_NO_DOUBLE_INSPECTION_REQUIRED BIT_U32(16)
#define DETECT_CONTENT_WITHIN_NEXT BIT_U32(17)
#define DETECT_CONTENT_DISTANCE_NEXT BIT_U32(18)
/** a relative match to this content is next, used in matching phase */
#define DETECT_CONTENT_RELATIVE_NEXT (DETECT_CONTENT_WITHIN_NEXT|DETECT_CONTENT_DISTANCE_NEXT)
#define DETECT_CONTENT_IS_SINGLE(c) (!( ((c)->flags & DETECT_CONTENT_DISTANCE) || \
((c)->flags & DETECT_CONTENT_WITHIN) || \

@ -163,7 +163,11 @@ static int DetectDistanceSetup (DetectEngineCtx *de_ctx, Signature *s,
"only content");
goto end;
}
prev_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
if ((cd->flags & DETECT_CONTENT_NEGATED) == 0) {
prev_cd->flags |= DETECT_CONTENT_DISTANCE_NEXT;
} else {
prev_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
}
} else if (prev_pm->type == DETECT_PCRE) {
DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
pd->flags |= DETECT_PCRE_RELATIVE_NEXT;

@ -339,7 +339,7 @@ int DetectEngineContentInspection(DetectEngineCtx *de_ctx, DetectEngineThreadCtx
}
/* no match and no reason to look for another instance */
if ((cd->flags & DETECT_CONTENT_RELATIVE_NEXT) == 0) {
if ((cd->flags & DETECT_CONTENT_WITHIN_NEXT) == 0) {
SCLogDebug("'next sm' does not depend on me, so we can give up");
det_ctx->discontinue_matching = 1;
goto no_match;

@ -178,7 +178,7 @@ static int DetectWithinSetup(DetectEngineCtx *de_ctx, Signature *s, char *within
"only content");
goto end;
}
prev_cd->flags |= DETECT_CONTENT_RELATIVE_NEXT;
prev_cd->flags |= DETECT_CONTENT_WITHIN_NEXT;
} else if (prev_pm->type == DETECT_PCRE) {
DetectPcreData *pd = (DetectPcreData *)prev_pm->ctx;
pd->flags |= DETECT_PCRE_RELATIVE_NEXT;

Loading…
Cancel
Save