#include "detect-content.h"
#include "detect-uricontent.h"
+#include "detect-flags.h"
#include "util-hash.h"
#include "util-hashlist.h"
sgh->match_array = NULL;
}
- if (sgh->non_mpm_store_array != NULL) {
- SCFree(sgh->non_mpm_store_array);
- sgh->non_mpm_store_array = NULL;
- sgh->non_mpm_store_cnt = 0;
+ if (sgh->non_mpm_other_store_array != NULL) {
+ SCFree(sgh->non_mpm_other_store_array);
+ sgh->non_mpm_other_store_array = NULL;
+ sgh->non_mpm_other_store_cnt = 0;
+ }
+
+ if (sgh->non_mpm_syn_store_array != NULL) {
+ SCFree(sgh->non_mpm_syn_store_array);
+ sgh->non_mpm_syn_store_array = NULL;
+ sgh->non_mpm_syn_store_cnt = 0;
}
sgh->sig_cnt = 0;
Signature *s = NULL;
uint32_t sig = 0;
uint32_t non_mpm = 0;
+ uint32_t non_mpm_syn = 0;
if (sgh == NULL)
return 0;
- BUG_ON(sgh->non_mpm_store_array != NULL);
+ BUG_ON(sgh->non_mpm_other_store_array != NULL);
for (sig = 0; sig < sgh->sig_cnt; sig++) {
s = sgh->match_array[sig];
if (s == NULL)
continue;
- if (s->mpm_sm == NULL)
- non_mpm++;
- else if (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG))
- non_mpm++;
+ if (s->mpm_sm == NULL || (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG))) {
+ if (!(DetectFlagsSignatureNeedsSynPackets(s))) {
+ non_mpm++;
+ }
+ non_mpm_syn++;
+ }
}
- if (non_mpm == 0) {
- sgh->non_mpm_store_array = NULL;
+ if (non_mpm == 0 && non_mpm_syn == 0) {
+ sgh->non_mpm_other_store_array = NULL;
+ sgh->non_mpm_syn_store_array = NULL;
return 0;
}
- sgh->non_mpm_store_array = SCMalloc(non_mpm * sizeof(SignatureNonMpmStore));
- BUG_ON(sgh->non_mpm_store_array == NULL);
- memset(sgh->non_mpm_store_array, 0, non_mpm * sizeof(SignatureNonMpmStore));
+ sgh->non_mpm_other_store_array = SCMalloc(non_mpm * sizeof(SignatureNonMpmStore));
+ BUG_ON(sgh->non_mpm_other_store_array == NULL);
+ memset(sgh->non_mpm_other_store_array, 0, non_mpm * sizeof(SignatureNonMpmStore));
+
+ sgh->non_mpm_syn_store_array = SCMalloc(non_mpm_syn * sizeof(SignatureNonMpmStore));
+ BUG_ON(sgh->non_mpm_syn_store_array == NULL);
+ memset(sgh->non_mpm_syn_store_array, 0, non_mpm_syn * sizeof(SignatureNonMpmStore));
for (sig = 0; sig < sgh->sig_cnt; sig++) {
s = sgh->match_array[sig];
if (s == NULL)
continue;
- if (s->mpm_sm == NULL) {
- BUG_ON(sgh->non_mpm_store_cnt >= non_mpm);
- sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].id = s->num;
- sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].mask = s->mask;
- sgh->non_mpm_store_cnt++;
- } else if (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG)) {
- BUG_ON(sgh->non_mpm_store_cnt >= non_mpm);
- sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].id = s->num;
- sgh->non_mpm_store_array[sgh->non_mpm_store_cnt].mask = s->mask;
- sgh->non_mpm_store_cnt++;
+ if (s->mpm_sm == NULL || (s->flags & (SIG_FLAG_MPM_PACKET_NEG|SIG_FLAG_MPM_STREAM_NEG|SIG_FLAG_MPM_APPLAYER_NEG))) {
+ if (!(DetectFlagsSignatureNeedsSynPackets(s))) {
+ BUG_ON(sgh->non_mpm_other_store_cnt >= non_mpm);
+ sgh->non_mpm_other_store_array[sgh->non_mpm_other_store_cnt].id = s->num;
+ sgh->non_mpm_other_store_array[sgh->non_mpm_other_store_cnt].mask = s->mask;
+ sgh->non_mpm_other_store_cnt++;
+ }
+
+ BUG_ON(sgh->non_mpm_syn_store_cnt >= non_mpm_syn);
+ sgh->non_mpm_syn_store_array[sgh->non_mpm_syn_store_cnt].id = s->num;
+ sgh->non_mpm_syn_store_array[sgh->non_mpm_syn_store_cnt].mask = s->mask;
+ sgh->non_mpm_syn_store_cnt++;
}
}
/* track highest cnt for any sgh in our de_ctx */
- if (sgh->non_mpm_store_cnt > de_ctx->non_mpm_store_cnt_max)
- de_ctx->non_mpm_store_cnt_max = sgh->non_mpm_store_cnt;
+ uint32_t max = MAX(sgh->non_mpm_other_store_cnt, sgh->non_mpm_syn_store_cnt);
+ if (max > de_ctx->non_mpm_store_cnt_max)
+ de_ctx->non_mpm_store_cnt_max = max;
return 0;
}
static inline void DetectPrefilterBuildNonMpmList(DetectEngineThreadCtx *det_ctx, SignatureMask mask)
{
uint32_t x = 0;
- for (x = 0; x < det_ctx->sgh->non_mpm_store_cnt; x++) {
+ for (x = 0; x < det_ctx->non_mpm_store_cnt; x++) {
/* only if the mask matches this rule can possibly match,
* so build the non_mpm array only for match candidates */
- SignatureMask rule_mask = det_ctx->sgh->non_mpm_store_array[x].mask;
+ SignatureMask rule_mask = det_ctx->non_mpm_store_ptr[x].mask;
if ((rule_mask & mask) == rule_mask) {
- det_ctx->non_mpm_id_array[det_ctx->non_mpm_id_cnt++] = det_ctx->sgh->non_mpm_store_array[x].id;
+ det_ctx->non_mpm_id_array[det_ctx->non_mpm_id_cnt++] = det_ctx->non_mpm_store_ptr[x].id;
}
}
}
+/** \internal
+ * \brief select non-mpm list
+ * Based on the packet properties, select the non-mpm list to use */
+static inline void DetectPrefilterSetNonMpmList(const Packet *p, DetectEngineThreadCtx *det_ctx)
+{
+ if ((p->proto == IPPROTO_TCP) && (p->tcph != NULL) && (p->tcph->th_flags & TH_SYN)) {
+ det_ctx->non_mpm_store_ptr = det_ctx->sgh->non_mpm_syn_store_array;
+ det_ctx->non_mpm_store_cnt = det_ctx->sgh->non_mpm_syn_store_cnt;
+ } else {
+ det_ctx->non_mpm_store_ptr = det_ctx->sgh->non_mpm_other_store_array;
+ det_ctx->non_mpm_store_cnt = det_ctx->sgh->non_mpm_other_store_cnt;
+ }
+ SCLogDebug("sgh non_mpm ptr %p cnt %u (syn %p/%u, other %p/%u)",
+ det_ctx->non_mpm_store_ptr, det_ctx->non_mpm_store_cnt,
+ det_ctx->sgh->non_mpm_syn_store_array, det_ctx->sgh->non_mpm_syn_store_cnt,
+ det_ctx->sgh->non_mpm_other_store_array, det_ctx->sgh->non_mpm_other_store_cnt);
+}
+
/**
* \brief Signature match function
*
goto end;
}
+ DetectPrefilterSetNonMpmList(p, det_ctx);
+
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_STATEFUL);
/* stateful app layer detection */
if ((p->flags & PKT_HAS_FLOW) && has_state) {
/* build and prefilter non_mpm list against the mask of the packet */
PACKET_PROFILING_DETECT_START(p, PROF_DETECT_NONMPMLIST);
det_ctx->non_mpm_id_cnt = 0;
- if (likely(det_ctx->sgh->non_mpm_store_cnt > 0)) {
+ if (likely(det_ctx->non_mpm_store_cnt > 0)) {
DetectPrefilterBuildNonMpmList(det_ctx, mask);
}
PACKET_PROFILING_DETECT_END(p, PROF_DETECT_NONMPMLIST);
StatsAddUI64(th_v, det_ctx->counter_mpm_list,
(uint64_t)det_ctx->pmq.rule_id_array_cnt);
StatsAddUI64(th_v, det_ctx->counter_nonmpm_list,
- (uint64_t)det_ctx->sgh->non_mpm_store_cnt);
+ (uint64_t)det_ctx->non_mpm_store_cnt);
/* non mpm sigs after mask prefilter */
StatsAddUI64(th_v, det_ctx->counter_fnonmpm_list,
(uint64_t)det_ctx->non_mpm_id_cnt);
/** \todo review how many we actually need here */
#define DETECT_SMSG_PMQ_NUM 256
+typedef struct SignatureNonMpmStore_ {
+ SigIntId id;
+ SignatureMask mask;
+} SignatureNonMpmStore;
+
/**
* Detection engine thread data.
*/
uint8_t *de_state_sig_array;
struct SigGroupHead_ *sgh;
+
+ SignatureNonMpmStore *non_mpm_store_ptr;
+ uint32_t non_mpm_store_cnt;
+
/** pointer to the current mpm ctx that is stored
* in a rule group head -- can be either a content
* or uricontent ctx. */
struct DetectPort_ *port;
} SigGroupHeadInitData;
-typedef struct SignatureNonMpmStore_ {
- SigIntId id;
- SignatureMask mask;
-} SignatureNonMpmStore;
-
/** \brief Container for matching data for a signature group */
typedef struct SigGroupHead_ {
uint32_t flags;
SignatureMask *mask_array;
#endif
- SignatureNonMpmStore *non_mpm_store_array; // size is non_mpm_store_cnt * sizeof(SignatureNonMpmStore)
- uint32_t non_mpm_store_cnt;
+ /* non mpm list excluding SYN rules */
+ SignatureNonMpmStore *non_mpm_other_store_array; // size is non_mpm_store_cnt * sizeof(SignatureNonMpmStore)
+ uint32_t non_mpm_other_store_cnt;
+ /* non mpm list including SYN rules */
+ SignatureNonMpmStore *non_mpm_syn_store_array; // size is non_mpm_syn_store_cnt * sizeof(SignatureNonMpmStore)
+ uint32_t non_mpm_syn_store_cnt;
/* pattern matcher instances */
const MpmCtx *mpm_proto_other_ctx;