From: Ken Steele Date: Wed, 1 Oct 2014 21:13:54 +0000 (-0400) Subject: Implement MPM opt for ac-bs and ac-gfbs X-Git-Tag: suricata-2.1beta3~41 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=f83022d818616ccacf3e532564d38d9d51f19d74;p=thirdparty%2Fsuricata.git Implement MPM opt for ac-bs and ac-gfbs Copies sids changes from ac. --- diff --git a/src/util-mpm-ac-bs.c b/src/util-mpm-ac-bs.c index faec5b2a59..9ea9eed895 100644 --- a/src/util-mpm-ac-bs.c +++ b/src/util-mpm-ac-bs.c @@ -370,6 +370,29 @@ static int SCACBSAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, /* we need the max pat id */ if (pid > ctx->max_pat_id) ctx->max_pat_id = pid; + + p->sids_size = 1; + p->sids = SCMalloc(p->sids_size * sizeof(uint32_t)); + BUG_ON(p->sids == NULL); + p->sids[0] = sid; + } else { + /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ + + int found = 0; + uint32_t x = 0; + for (x = 0; x < p->sids_size; x++) { + if (p->sids[x] == sid) { + found = 1; + break; + } + } + if (!found) { + uint32_t *sids = SCRealloc(p->sids, (sizeof(uint32_t) * (p->sids_size + 1))); + BUG_ON(sids == NULL); + p->sids = sids; + p->sids[p->sids_size] = sid; + p->sids_size++; + } } return 0; @@ -1196,6 +1219,10 @@ int SCACBSPreparePatterns(MpmCtx *mpm_ctx) ctx->parray[i]->original_pat, ctx->parray[i]->len); ctx->pid_pat_list[ctx->parray[i]->id].patlen = ctx->parray[i]->len; } + + /* ACPatternList now owns this memory */ + ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; + ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids; } /* prepare the state table required by AC */ @@ -1359,6 +1386,8 @@ void SCACBSDestroyCtx(MpmCtx *mpm_ctx) for (i = 0; i < (ctx->max_pat_id + 1); i++) { if (ctx->pid_pat_list[i].cs != NULL) SCFree(ctx->pid_pat_list[i].cs); + if (ctx->pid_pat_list[i].sids != NULL) + SCFree(ctx->pid_pat_list[i].sids); } SCFree(ctx->pid_pat_list); } @@ -1405,6 +1434,9 @@ uint32_t SCACBSSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ SCACBSPatternList *pid_pat_list = ctx->pid_pat_list; + uint8_t bitarray[pmq->pattern_id_bitarray_size]; + memset(bitarray, 0, pmq->pattern_id_bitarray_size); + if (ctx->state_count < 32767) { register SC_AC_BS_STATE_TYPE_U16 state = 0; uint16_t no_of_entries; @@ -1464,19 +1496,31 @@ uint32_t SCACBSSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* inside loop */ continue; } - if (pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { + if (bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { ; } else { + bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k] & 0x0000FFFF; + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { + if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { ; } else { + bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k]; + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } @@ -1545,19 +1589,31 @@ uint32_t SCACBSSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, /* inside loop */ continue; } - if (pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { + if (bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { ; } else { + bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k] & 0x0000FFFF; + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { + if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { ; } else { + bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k]; + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } diff --git a/src/util-mpm-ac-bs.h b/src/util-mpm-ac-bs.h index 46e196dd44..935bc77c27 100644 --- a/src/util-mpm-ac-bs.h +++ b/src/util-mpm-ac-bs.h @@ -39,12 +39,20 @@ typedef struct SCACBSPattern_ { /* pattern id */ uint32_t id; + /* sid(s) for this pattern */ + uint32_t sids_size; + uint32_t *sids; + struct SCACBSPattern_ *next; } SCACBSPattern; typedef struct SCACBSPatternList_ { uint8_t *cs; uint16_t patlen; + + /* sid(s) for this pattern */ + uint32_t sids_size; + uint32_t *sids; } SCACBSPatternList; typedef struct SCACBSOutputTable_ { diff --git a/src/util-mpm-ac-gfbs.c b/src/util-mpm-ac-gfbs.c index 28b1fc2b3d..8ccb8e3f43 100644 --- a/src/util-mpm-ac-gfbs.c +++ b/src/util-mpm-ac-gfbs.c @@ -363,6 +363,29 @@ static int SCACGfbsAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen, /* we need the max pat id */ if (pid > ctx->max_pat_id) ctx->max_pat_id = pid; + + p->sids_size = 1; + p->sids = SCMalloc(p->sids_size * sizeof(uint32_t)); + BUG_ON(p->sids == NULL); + p->sids[0] = sid; + } else { + /* TODO figure out how we can be called multiple times for the same CTX with the same sid */ + + int found = 0; + uint32_t x = 0; + for (x = 0; x < p->sids_size; x++) { + if (p->sids[x] == sid) { + found = 1; + break; + } + } + if (!found) { + uint32_t *sids = SCRealloc(p->sids, (sizeof(uint32_t) * (p->sids_size + 1))); + BUG_ON(sids == NULL); + p->sids = sids; + p->sids[p->sids_size] = sid; + p->sids_size++; + } } return 0; @@ -1067,6 +1090,10 @@ int SCACGfbsPreparePatterns(MpmCtx *mpm_ctx) ctx->parray[i]->original_pat, ctx->parray[i]->len); ctx->pid_pat_list[ctx->parray[i]->id].patlen = ctx->parray[i]->len; } + + /* ACPatternList now owns this memory */ + ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; + ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids; } /* prepare the state table required by AC */ @@ -1236,6 +1263,8 @@ void SCACGfbsDestroyCtx(MpmCtx *mpm_ctx) for (i = 0; i < (ctx->max_pat_id + 1); i++) { if (ctx->pid_pat_list[i].cs != NULL) SCFree(ctx->pid_pat_list[i].cs); + if (ctx->pid_pat_list[i].sids != NULL) + SCFree(ctx->pid_pat_list[i].sids); } SCFree(ctx->pid_pat_list); } @@ -1268,6 +1297,9 @@ uint32_t SCACGfbsSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, SCACGfbsPatternList *pid_pat_list = ctx->pid_pat_list; + uint8_t bitarray[pmq->pattern_id_bitarray_size]; + memset(bitarray, 0, pmq->pattern_id_bitarray_size); + /* really hate the extra cmp here, but can't help it */ if (ctx->state_count < 32767) { /* \todo Change it for stateful MPM. Supply the state using mpm_thread_ctx */ @@ -1377,19 +1409,31 @@ uint32_t SCACGfbsSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, continue; } - if (pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { + if (bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { ; } else { + bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = (pids[k] & 0x0000FFFF); + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { + if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { ; } else { + bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k]; + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } @@ -1502,19 +1546,31 @@ uint32_t SCACGfbsSearch(MpmCtx *mpm_ctx, MpmThreadCtx *mpm_thread_ctx, continue; } - if (pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { + if (bitarray[(pids[k] & 0x0000FFFF) / 8] & (1 << ((pids[k] & 0x0000FFFF) % 8))) { ; } else { + bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_bitarray[(pids[k] & 0x0000FFFF) / 8] |= (1 << ((pids[k] & 0x0000FFFF) % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = (pids[k] & 0x0000FFFF); + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } else { - if (pmq->pattern_id_bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { + if (bitarray[pids[k] / 8] & (1 << (pids[k] % 8))) { ; } else { + bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_bitarray[pids[k] / 8] |= (1 << (pids[k] % 8)); pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = pids[k]; + + uint32_t x; + for (x = 0; x < pid_pat_list[pids[k] & 0x0000FFFF].sids_size; x++) { + pmq->rule_id_array[pmq->rule_id_array_cnt++] = pid_pat_list[pids[k] & 0x0000FFFF].sids[x]; + } } matches++; } diff --git a/src/util-mpm-ac-gfbs.h b/src/util-mpm-ac-gfbs.h index e790c685b7..5f1fc7bbad 100644 --- a/src/util-mpm-ac-gfbs.h +++ b/src/util-mpm-ac-gfbs.h @@ -39,12 +39,20 @@ typedef struct SCACGfbsPattern_ { /* pattern id */ uint32_t id; + /* sid(s) for this pattern */ + uint32_t sids_size; + uint32_t *sids; + struct SCACGfbsPattern_ *next; } SCACGfbsPattern; typedef struct SCACGfbsPatternList_ { uint8_t *cs; uint16_t patlen; + + /* sid(s) for this pattern */ + uint32_t sids_size; + uint32_t *sids; } SCACGfbsPatternList; typedef struct SCACGfbsOutputTable_ {