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/2681/head
Victor Julien 10 years ago
parent 84b97ca155
commit 7eda6beade

@ -2918,7 +2918,7 @@ static 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) {
@ -3147,7 +3147,7 @@ static 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 BIT_U32(9)
/** a relative match to this content is next, used in matching phase */
#define DETECT_CONTENT_RELATIVE_NEXT BIT_U32(10)
// bit 10 unused
/* BE - byte extract */
#define DETECT_CONTENT_OFFSET_BE BIT_U32(11)
@ -55,6 +54,10 @@
* the inspection phase */
#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) || \

@ -142,7 +142,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;

@ -340,7 +340,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;

@ -152,7 +152,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;

@ -83,7 +83,7 @@ static int DetectEngineContentInspectionTest03(void) {
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; content:\"d\";", false, 3);
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0;", true, 3);
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; content:\"d\"; distance:0;", false, 6); // TODO should be 3?
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; content:\"d\"; distance:0;", false, 3);
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:\"d\"; distance:0; within:1;", false, 5);
@ -155,15 +155,15 @@ static int DetectEngineContentInspectionTest07(void) {
TEST_RUN("abcabcabcabcabcabcabcabcabcabcd", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; content:\"d\"; within:1; distance:0; ", true, 31);
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; content:\"d\"; within:1; distance:0; ", false, 31);
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; ", false, 286); // TODO should be 4?
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; pcre:\"/^d/R\"; ", false, 286); // TODO should be 4?
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; isdataat:!1,relative; ", false, 286); // TODO should be 4?
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; ", false, 4);
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; pcre:\"/^d/R\"; ", false, 13);
TEST_RUN("abcabcabcabcabcabcabcabcabcabcx", 31, "content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; isdataat:!1,relative; ", false, 13); // TODO should be 4?
TEST_RUN("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdx", 41,
"content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; content:\"e\"; distance:0; ", false, 1001); // TODO should be 5?
"content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; content:\"e\"; distance:0; ", false, 5);
TEST_RUN("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdx", 41,
"content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; pcre:\"/^e/R\"; ", false, 1001); // TODO should be 5?
"content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; pcre:\"/^e/R\"; ", false, 14); // TODO should be 5?
TEST_RUN("abcdabcdabcdabcdabcdabcdabcdabcdabcdabcdx", 41,
"content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; isdataat:!1,relative; ", false, 1001); // TODO should be 5?
"content:\"a\"; content:\"b\"; distance:0; content:\"c\"; distance:0; content:\"d\"; distance:0; isdataat:!1,relative; ", false, 14); // TODO should be 5?
TEST_RUN("abcabcabcabcabcabcabcabcabcabcd", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; pcre:\"/d/\";", true, 4);
TEST_RUN("abcabcabcabcabcabcabcabcabcabcd", 31, "content:\"a\"; content:\"b\"; within:1; distance:0; content:\"c\"; distance:0; within:1; pcre:\"/d/R\";", true, 4);
@ -175,6 +175,18 @@ static int DetectEngineContentInspectionTest07(void) {
TEST_FOOTER;
}
/** \test mix in negation */
static int DetectEngineContentInspectionTest08(void) {
TEST_HEADER;
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; content:!\"d\";", true, 3);
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; content:!\"c\";", false, 3);
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:!\"a\"; distance:0; within:1;", true, 5);
TEST_RUN("ababc", 5, "content:\"a\"; content:\"b\"; distance:0; within:1; content:!\"a\"; distance:0; ", true, 5);
TEST_FOOTER;
}
void DetectEngineContentInspectionRegisterTests(void)
{
UtRegisterTest("DetectEngineContentInspectionTest01",
@ -191,6 +203,8 @@ void DetectEngineContentInspectionRegisterTests(void)
DetectEngineContentInspectionTest06);
UtRegisterTest("DetectEngineContentInspectionTest07",
DetectEngineContentInspectionTest07);
UtRegisterTest("DetectEngineContentInspectionTest08",
DetectEngineContentInspectionTest08);
}
#undef TEST_HEADER

Loading…
Cancel
Save