diff --git a/src/detect-engine-mpm.c b/src/detect-engine-mpm.c index 434cc570ad..b699ea7cda 100644 --- a/src/detect-engine-mpm.c +++ b/src/detect-engine-mpm.c @@ -138,13 +138,12 @@ uint32_t PacketPatternSearch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, /** \brief Uri Pattern match -- searches for one pattern per signature. * - * \param tv threadvars * \param det_ctx detection engine thread ctx * \param p packet to inspect * * \retval ret number of matches */ -uint32_t UriPatternSearch(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, +uint32_t UriPatternSearch(DetectEngineThreadCtx *det_ctx, uint8_t *uri, uint16_t uri_len) { SCEnter(); diff --git a/src/detect-engine-mpm.h b/src/detect-engine-mpm.h index 5fdea07b29..71bf4718fc 100644 --- a/src/detect-engine-mpm.h +++ b/src/detect-engine-mpm.h @@ -34,7 +34,7 @@ uint16_t PatternMatchDefaultMatcher(void); uint32_t PacketPatternSearch(ThreadVars *, DetectEngineThreadCtx *, Packet *); -uint32_t UriPatternSearch(ThreadVars *, DetectEngineThreadCtx *, uint8_t *, uint16_t); +uint32_t UriPatternSearch(DetectEngineThreadCtx *, uint8_t *, uint16_t); uint32_t StreamPatternSearch(ThreadVars *, DetectEngineThreadCtx *, StreamMsg *); void PacketPatternCleanup(ThreadVars *, DetectEngineThreadCtx *); diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index 82961f0740..19d885542b 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -278,19 +278,6 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, SCLogDebug("inspecting uri"); - if (s->flags & SIG_FLAG_MPM_URI) { - if (det_ctx->pmq.pattern_id_bitarray != NULL) { - /* filter out sigs that want pattern matches, but - * have no matches */ - if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) && - (s->flags & SIG_FLAG_MPM_URI) && !(s->flags & SIG_FLAG_MPM_URI_NEG)) { - SCLogDebug("mpm sig without matches (pat id %"PRIu32 - " check in uri).", s->mpm_uripattern_id); - goto next; - } - } - } - if (DetectEngineInspectPacketUris(de_ctx, det_ctx, s, f, flags, alstate) == 1) { @@ -299,7 +286,6 @@ int DeStateDetectStartDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, } else { SCLogDebug("uri inspected but no match"); } -next:; } } @@ -390,17 +376,6 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete SCLogDebug("id of signature to inspect: %"PRIuMAX, (uintmax_t)s->id); - /* if the sm is NULL, the sig matched already */ -#if 0 - if (item->nm == NULL) { - SCLogDebug("state detection already matched in a previous run"); - det_ctx->de_state_sig_array[item->sid] = DE_STATE_MATCH_STORED; - - SCLogDebug("signature %"PRIu32" match state %s", - s->id, DeStateMatchResultToString(det_ctx->de_state_sig_array[item->sid])); - continue; - } -#endif PROFILING_START; /* let's continue detection */ @@ -412,19 +387,6 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete SCLogDebug("inspecting uri"); uinspect = 1; - if (s->flags & SIG_FLAG_MPM_URI) { - if (det_ctx->pmq.pattern_id_bitarray != NULL) { - /* filter out sigs that want pattern matches, but - * have no matches */ - if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) && - (s->flags & SIG_FLAG_MPM_URI) && !(s->flags & SIG_FLAG_MPM_URI_NEG)) { - SCLogDebug("mpm sig without matches (pat id %"PRIu32 - " check in uri).", s->mpm_uripattern_id); - goto next; - } - } - } - if (DetectEngineInspectPacketUris(de_ctx, det_ctx, s, f, flags, alstate) == 1) { @@ -434,7 +396,6 @@ int DeStateDetectContinueDetection(ThreadVars *tv, DetectEngineCtx *de_ctx, Dete } else { SCLogDebug("uri inspected but no match"); } -next:; } else { SCLogDebug("uri already inspected"); } diff --git a/src/detect-engine-uri.c b/src/detect-engine-uri.c index fbf0dc8248..e442d3f68d 100644 --- a/src/detect-engine-uri.c +++ b/src/detect-engine-uri.c @@ -259,6 +259,11 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx, int r = 0; HtpState *htp_state = NULL; + if (!(det_ctx->sgh->flags & SIG_GROUP_HAVEURICONTENT)) { + SCLogDebug("no uricontent in sgh"); + SCReturnInt(0); + } + htp_state = (HtpState *)alstate; if (htp_state == NULL) { SCLogDebug("no HTTP state"); @@ -268,15 +273,50 @@ int DetectEngineInspectPacketUris(DetectEngineCtx *de_ctx, /* locking the flow, we will inspect the htp state */ SCMutexLock(&f->m); + if (htp_state->connp == NULL) { + SCLogDebug("HTP state has no connp"); + goto end; + } + + /* If we have the uricontent multi pattern matcher signatures in + signature list, then search the received HTTP uri(s) in the htp + state against those patterns */ + if (s->flags & SIG_FLAG_MPM_URI) { + if (det_ctx->de_mpm_scanned_uri == FALSE) { + uint32_t cnt = DetectUricontentInspectMpm(det_ctx, alstate); + + /* only consider uri sigs if we've seen at least one match */ + /** \warning when we start supporting negated uri content matches + * we need to update this check as well */ + if (cnt > 0) { + det_ctx->de_have_httpuri = TRUE; + } + + SCLogDebug("uricontent cnt %"PRIu32"", cnt); + + /* make sure we don't inspect this mpm again */ + det_ctx->de_mpm_scanned_uri = TRUE; + + } + } + /* if we don't have a uri, don't bother inspecting */ if (det_ctx->de_have_httpuri == FALSE) { SCLogDebug("We don't have uri"); goto end; } - if (htp_state->connp == NULL) { - SCLogDebug("HTP state has no connp"); - goto end; + if (det_ctx->de_mpm_scanned_uri == TRUE) { + if (det_ctx->pmq.pattern_id_bitarray != NULL) { + /* filter out sigs that want pattern matches, but + * have no matches */ + if (!(det_ctx->pmq.pattern_id_bitarray[(s->mpm_uripattern_id / 8)] & (1<<(s->mpm_uripattern_id % 8))) && + (s->flags & SIG_FLAG_MPM_URI) && !(s->flags & SIG_FLAG_MPM_URI_NEG)) { + SCLogDebug("mpm sig without matches (pat id %"PRIu32 + " check in uri).", s->mpm_uripattern_id); + goto end; + } + } } sm = s->umatch; diff --git a/src/detect-uricontent.c b/src/detect-uricontent.c index 221f20172b..202702da3c 100644 --- a/src/detect-uricontent.c +++ b/src/detect-uricontent.c @@ -375,14 +375,13 @@ error: * normalized http uri against the given rule using multi pattern * search algorithms. * - * \param t Pointer to the tv for this detection module instance * \param det_ctx Pointer to the detection engine thread context * \param content Pointer to the uri content currently being matched * \param content_len Content_len of the received uri content * * \retval 1 if the uri contents match; 0 no match */ -int DoDetectAppLayerUricontentMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ctx, +static inline int DoDetectAppLayerUricontentMatch (DetectEngineThreadCtx *det_ctx, uint8_t *uri, uint16_t uri_len) { int ret = 0; @@ -403,7 +402,7 @@ int DoDetectAppLayerUricontentMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ else if (det_ctx->sgh->mpm_uricontent_maxlen == 4) det_ctx->pkts_uri_searched4++; else det_ctx->pkts_uri_searched++; - ret += UriPatternSearch(tv, det_ctx, uri, uri_len); + ret += UriPatternSearch(det_ctx, uri, uri_len); SCLogDebug("post search: cnt %" PRIu32, ret); } @@ -419,7 +418,7 @@ int DoDetectAppLayerUricontentMatch (ThreadVars *tv, DetectEngineThreadCtx *det_ * \warning Make sure the flow/state is locked * \todo what should we return? Just the fact that we matched? */ -uint32_t DetectUricontentInspectMpm(ThreadVars *tv, DetectEngineThreadCtx *det_ctx, void *alstate) { +uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, void *alstate) { SCEnter(); uint32_t cnt = 0; @@ -439,7 +438,7 @@ uint32_t DetectUricontentInspectMpm(ThreadVars *tv, DetectEngineThreadCtx *det_c if (tx == NULL || tx->request_uri_normalized == NULL) continue; - cnt += DoDetectAppLayerUricontentMatch(tv, det_ctx, (uint8_t *) + cnt += DoDetectAppLayerUricontentMatch(det_ctx, (uint8_t *) bstr_ptr(tx->request_uri_normalized), bstr_len(tx->request_uri_normalized)); } diff --git a/src/detect-uricontent.h b/src/detect-uricontent.h index 06c0f76ed2..0acb228ace 100644 --- a/src/detect-uricontent.h +++ b/src/detect-uricontent.h @@ -62,7 +62,7 @@ typedef struct DetectUricontentData_ { /* prototypes */ void DetectUricontentRegister (void); uint32_t DetectUricontentMaxId(DetectEngineCtx *); -uint32_t DetectUricontentInspectMpm(ThreadVars *th_v, DetectEngineThreadCtx *det_ctx, void *alstate); +uint32_t DetectUricontentInspectMpm(DetectEngineThreadCtx *det_ctx, void *alstate); SigMatch *DetectUricontentGetLastPattern(SigMatch *); void DetectUricontentPrint(DetectUricontentData *); diff --git a/src/detect.c b/src/detect.c index 46923d4a51..5a9fd0d59c 100644 --- a/src/detect.c +++ b/src/detect.c @@ -509,7 +509,6 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh SCEnter(); - /* when we start there are no alerts yet. Only this function may set them */ p->alerts.cnt = 0; det_ctx->pkts++; @@ -634,27 +633,7 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh } } - /* If we have the uricontent multi pattern matcher signatures in - signature list, then search the received HTTP uri(s) in the htp - state against those patterns */ - if (det_ctx->sgh->flags & SIG_GROUP_HAVEURICONTENT && p->flow != NULL && - alproto == ALPROTO_HTTP) - { - SCMutexLock(&p->flow->m); - cnt = DetectUricontentInspectMpm(th_v, det_ctx, alstate); - SCMutexUnlock(&p->flow->m); - - /* only consider uri sigs if we've seen at least one match */ - /** \warning when we start supporting negated uri content matches - * we need to update this check as well */ - if (cnt > 0) { - det_ctx->de_have_httpuri = TRUE; - } - - SCLogDebug("uricontent cnt %"PRIu32"", cnt); - } else { - SCLogDebug("no uri inspection: have uri %s", det_ctx->sgh->flags & SIG_GROUP_HAVEURICONTENT ? "true":"false"); - } + det_ctx->de_mpm_scanned_uri = FALSE; /* stateful app layer detection */ char de_state_start = FALSE; @@ -672,11 +651,20 @@ int SigMatchSignatures(ThreadVars *th_v, DetectEngineCtx *de_ctx, DetectEngineTh /* inspect the sigs against the packet */ for (idx = 0; idx < det_ctx->sgh->sig_cnt; idx++) { PROFILING_START; + sig = det_ctx->sgh->match_array[idx]; s = de_ctx->sig_array[sig]; SCLogDebug("inspecting signature id %"PRIu32"", s->id); + if ((s->amatch != NULL || s->umatch != NULL) && p->flow != NULL) { + if (de_state_start == FALSE) { + if (det_ctx->de_state_sig_array[s->num] != DE_STATE_MATCH_NEW) { + goto next; + } + } + } + /* filter out the sigs that inspects the payload, if packet no payload inspection flag is set*/ if ((p->flags & PKT_NOPAYLOAD_INSPECTION) && (s->flags & SIG_FLAG_PAYLOAD)) { diff --git a/src/detect.h b/src/detect.h index 0d93953992..27785a9786 100644 --- a/src/detect.h +++ b/src/detect.h @@ -471,7 +471,7 @@ typedef struct DetectionEngineThreadCtx_ { /* http_uri stuff for uricontent */ char de_have_httpuri; - + char de_mpm_scanned_uri; /** Array of sigs that had a state change */ uint8_t *de_state_sig_array;