}
}
+int RulesGroupByProto(DetectEngineCtx *de_ctx)
+{
+ Signature *s = de_ctx->sig_list;
+
+ uint32_t max_idx = 0;
+ SigGroupHead *sgh_ts[256] = {NULL};
+ SigGroupHead *sgh_tc[256] = {NULL};
+
+ for ( ; s != NULL; s = s->next) {
+ if (s->flags & SIG_FLAG_IPONLY)
+ continue;
+
+ int p;
+ for (p = 0; p < 256; p++) {
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP) {
+ continue;
+ }
+ if (!(s->proto.proto[p / 8] & (1<<(p % 8)) || (s->proto.flags & DETECT_PROTO_ANY))) {
+ continue;
+ }
+
+ if (s->flags & SIG_FLAG_TOCLIENT) {
+ SigGroupHeadAppendSig(de_ctx, &sgh_tc[p], s);
+ max_idx = s->num;
+ }
+ if (s->flags & SIG_FLAG_TOSERVER) {
+ SigGroupHeadAppendSig(de_ctx, &sgh_ts[p], s);
+ max_idx = s->num;
+ }
+ }
+ }
+ SCLogDebug("max_idx %u", max_idx);
+
+ /* lets look at deduplicating this list */
+ SigGroupHeadHashFree(de_ctx);
+ SigGroupHeadHashInit(de_ctx);
+
+ uint32_t cnt = 0;
+ uint32_t own = 0;
+ uint32_t ref = 0;
+ int p;
+ for (p = 0; p < 256; p++) {
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP)
+ continue;
+ if (sgh_ts[p] == NULL)
+ continue;
+
+ cnt++;
+
+ SigGroupHead *lookup_sgh = SigGroupHeadHashLookup(de_ctx, sgh_ts[p]);
+ if (lookup_sgh == NULL) {
+ SCLogDebug("proto group %d sgh %p is the original", p, sgh_ts[p]);
+
+ SigGroupHeadSetSigCnt(sgh_ts[p], max_idx);
+ SigGroupHeadBuildMatchArray(de_ctx, sgh_ts[p], max_idx);
+
+ SigGroupHeadHashAdd(de_ctx, sgh_ts[p]);
+ SigGroupHeadStore(de_ctx, sgh_ts[p]);
+
+ de_ctx->gh_unique++;
+ own++;
+ } else {
+ SCLogDebug("proto group %d sgh %p is a copy", p, sgh_ts[p]);
+
+ SigGroupHeadFree(sgh_ts[p]);
+ sgh_ts[p] = lookup_sgh;
+ sgh_ts[p]->flags |= SIG_GROUP_HEAD_REFERENCED;
+
+ de_ctx->gh_reuse++;
+ ref++;
+ }
+ }
+ SCLogInfo("OTHER %s: %u proto groups, %u unique SGH's, %u copies", "toserver", cnt, own, ref);
+
+ cnt = 0;
+ own = 0;
+ ref = 0;
+ for (p = 0; p < 256; p++) {
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP)
+ continue;
+ if (sgh_tc[p] == NULL)
+ continue;
+
+ cnt++;
+
+ SigGroupHead *lookup_sgh = SigGroupHeadHashLookup(de_ctx, sgh_tc[p]);
+ if (lookup_sgh == NULL) {
+ SCLogDebug("proto group %d sgh %p is the original", p, sgh_tc[p]);
+
+ SigGroupHeadSetSigCnt(sgh_tc[p], max_idx);
+ SigGroupHeadBuildMatchArray(de_ctx, sgh_tc[p], max_idx);
+
+ SigGroupHeadHashAdd(de_ctx, sgh_tc[p]);
+ SigGroupHeadStore(de_ctx, sgh_tc[p]);
+
+ de_ctx->gh_unique++;
+ own++;
+ } else {
+ SCLogDebug("proto group %d sgh %p is a copy", p, sgh_tc[p]);
+
+ SigGroupHeadFree(sgh_tc[p]);
+ sgh_tc[p] = lookup_sgh;
+ sgh_tc[p]->flags |= SIG_GROUP_HEAD_REFERENCED;
+
+ de_ctx->gh_reuse++;
+ ref++;
+ }
+ }
+ SCLogInfo("OTHER %s: %u proto groups, %u unique SGH's, %u copies", "toclient", cnt, own, ref);
+
+ for (p = 0; p < 256; p++) {
+ if (p == IPPROTO_TCP || p == IPPROTO_UDP)
+ continue;
+
+ de_ctx->flow_gh[0].sgh[p] = sgh_tc[p];
+ de_ctx->flow_gh[1].sgh[p] = sgh_ts[p];
+ }
+
+ return 0;
+}
+
static DetectPort *RulesGroupByPorts(DetectEngineCtx *de_ctx, int ipproto, uint32_t direction) {
/* step 1: create a list of 'DetectPort' objects based on all the
* rules. Each object will have a SGH with the sigs added
return -1;
}
-/**
- * \brief add signature to the right flow group(s)
- */
-static int DetectEngineLookupFlowAddSig(DetectEngineCtx *de_ctx, Signature *s)
-{
- SCLogDebug("s->id %u", s->id);
-
- uint32_t cnt_ts = 0;
- uint32_t cnt_tc = 0;
-
- int p;
- for (p = 0; p < 256; p++) {
- if (p == IPPROTO_TCP || p == IPPROTO_UDP)
- continue;
-
- if (s->proto.proto[p / 8] & (1<<(p % 8)) || (s->proto.flags & DETECT_PROTO_ANY)) {
- if (s->flags & SIG_FLAG_TOCLIENT) {
- SigGroupHeadAppendSig(de_ctx, &de_ctx->flow_gh[0].sgh[p], s);
- cnt_tc++;
- }
- if (s->flags & SIG_FLAG_TOSERVER) {
- SigGroupHeadAppendSig(de_ctx, &de_ctx->flow_gh[1].sgh[p], s);
- cnt_ts++;
- }
- }
- }
-
- /* see which rules use many protos. > 2 as alert icmp actually is also icmpv6. */
- if (cnt_ts > 2 || cnt_tc > 2) {
- SCLogDebug("Rule %u added to multiple proto groups (%u ts/%u tc)", s->id, cnt_ts, cnt_tc);
- }
-
- return 0;
-}
-
//#define SMALL_MPM(c) 0
#define SMALL_MPM(c) ((c) == 1)
// || (c) == 2)
de_ctx->flow_gh[1].udp = RulesGroupByPorts(de_ctx, IPPROTO_UDP, SIG_FLAG_TOSERVER);
de_ctx->flow_gh[0].udp = RulesGroupByPorts(de_ctx, IPPROTO_UDP, SIG_FLAG_TOCLIENT);
+ /* Setup the other IP Protocols (so not TCP/UDP) */
+ RulesGroupByProto(de_ctx);
+
/* now for every rule add the source group to our temp lists */
for (tmp_s = de_ctx->sig_list; tmp_s != NULL; tmp_s = tmp_s->next) {
SCLogDebug("tmp_s->id %"PRIu32, tmp_s->id);
if (tmp_s->flags & SIG_FLAG_IPONLY) {
IPOnlyAddSignature(de_ctx, &de_ctx->io_ctx, tmp_s);
- } else {
- /* handle non-tcp/non-udp rules */
- DetectEngineLookupFlowAddSig(de_ctx, tmp_s);
}
if (tmp_s->init_flags & SIG_FLAG_INIT_DEONLY) {
//SCLogInfo("sgh's %"PRIu32, de_ctx->sgh_array_cnt);
uint32_t idx = 0;
-
- for (idx = 0; idx < 256; idx++) {
- int f = 0;
- for (f = 0; f <= 1; f++) {
- SigGroupHead *sgh = de_ctx->flow_gh[f].sgh[idx];
- if (sgh == NULL) {
- //SCLogInfo("skipped %u/%d", idx, f);
- continue;
- }
-
- uint32_t max_idx = DetectEngineGetMaxSigId(de_ctx);
- SigGroupHeadSetSigCnt(sgh, max_idx);
- SigGroupHeadSetProtoAndDirection(sgh, idx,
- ((f == 1) ? SIG_FLAG_TOSERVER : SIG_FLAG_TOCLIENT));
- SigGroupHeadBuildMatchArray(de_ctx, sgh, max_idx);
- SigGroupHeadSetFilemagicFlag(de_ctx, sgh);
- SigGroupHeadSetFileMd5Flag(de_ctx, sgh);
- SigGroupHeadSetFilesizeFlag(de_ctx, sgh);
- SigGroupHeadSetFilestoreCount(de_ctx, sgh);
- SCLogDebug("filestore count %u", sgh->filestore_cnt);
-
- PatternMatchPrepareGroup(de_ctx, sgh);
- SigGroupHeadBuildNonMpmArray(de_ctx, sgh);
- }
- }
-
-
for (idx = 0; idx < de_ctx->sgh_array_cnt; idx++) {
SigGroupHead *sgh = de_ctx->sgh_array[idx];
if (sgh == NULL)