In AC-Tile, convert from using pids for indexing to pattern index

Use an MPM specific pattern index, which is simply an index starting
at zero and incremented for each pattern added to the MPM, rather than
the externally provided Pattern ID (pid), since that can be much
larger than the number of patterns. The Pattern ID is shared across at
MPMs. For example, an MPM with one pattern with pid=8000 would result
in a max_pid of 8000, so the pid_pat_list would have 8000 entries.

The pid_pat_list[] is replaced by a array of pattern indexes. The PID is
moved to the SCACTilePatternList as a single value. The PatternList is
also indexed by the Pattern Index.

max_pat_id is no longer needed and mpm_ctx->pattern_cnt is used instead.

The local bitarray is then also indexed by pattern index instead of PID, making
it much smaller. The local bit array sets a bit for each pattern found
for this MPM. It is only kept during one MPM search (stack allocated).

One note, the local bit array is checked first and if the pattern has already
been found, it will stop checking, but count a match. This could result in
over counting matches of case-sensitve matches, since following case-insensitive
matches will also be counted. For example, finding "Foo" in "foo Foo foo" would
report finding "Foo" 2 times, mis-counting the third word as "Foo".
pull/1295/head
Ken Steele 11 years ago committed by Victor Julien
parent 77269fbb2c
commit 7a2095d851

@ -37,8 +37,8 @@ uint32_t FUNC_NAME(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
int i = 0; int i = 0;
int matches = 0; int matches = 0;
uint8_t bitarray[pmq->pattern_id_bitarray_size]; uint8_t mpm_bitarray[ctx->mpm_bitarray_size];
memset(bitarray, 0, pmq->pattern_id_bitarray_size); memset(mpm_bitarray, 0, ctx->mpm_bitarray_size);
uint8_t* restrict xlate = ctx->translate_table; uint8_t* restrict xlate = ctx->translate_table;
STYPE *state_table = (STYPE*)ctx->state_table; STYPE *state_table = (STYPE*)ctx->state_table;
@ -56,21 +56,21 @@ uint32_t FUNC_NAME(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
state = SLOAD(state_table + index + c); state = SLOAD(state_table + index + c);
c = xlate[BYTE1(data)]; c = xlate[BYTE1(data)];
if (unlikely(SCHECK(state))) { if (unlikely(SCHECK(state))) {
matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, bitarray); matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray);
} }
i++; i++;
index = SINDEX(index, state); index = SINDEX(index, state);
state = SLOAD(state_table + index + c); state = SLOAD(state_table + index + c);
c = xlate[BYTE2(data)]; c = xlate[BYTE2(data)];
if (unlikely(SCHECK(state))) { if (unlikely(SCHECK(state))) {
matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, bitarray); matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray);
} }
i++; i++;
index = SINDEX(index, state); index = SINDEX(index, state);
state = SLOAD(state_table + index + c); state = SLOAD(state_table + index + c);
c = xlate[BYTE3(data)]; c = xlate[BYTE3(data)];
if (unlikely(SCHECK(state))) { if (unlikely(SCHECK(state))) {
matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, bitarray); matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray);
} }
data = data1; data = data1;
i++; i++;
@ -78,7 +78,7 @@ uint32_t FUNC_NAME(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
state = SLOAD(state_table + index + c); state = SLOAD(state_table + index + c);
c = xlate[BYTE0(data)]; c = xlate[BYTE0(data)];
if (unlikely(SCHECK(state))) { if (unlikely(SCHECK(state))) {
matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, bitarray); matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray);
} }
i++; i++;
} }
@ -90,7 +90,7 @@ uint32_t FUNC_NAME(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ctx,
state = SLOAD(state_table + index + c); state = SLOAD(state_table + index + c);
c = xlate[buf[i+1]]; c = xlate[buf[i+1]];
if (unlikely(SCHECK(state))) { if (unlikely(SCHECK(state))) {
matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, bitarray); matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray);
} }
} /* for (i = 0; i < buflen; i++) */ } /* for (i = 0; i < buflen; i++) */

@ -511,10 +511,6 @@ static int SCACTileAddPattern(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
mpm_ctx->minlen = patlen; mpm_ctx->minlen = patlen;
} }
/* we need the max pat id */
if (pid > ctx->max_pat_id)
ctx->max_pat_id = pid;
p->sids_size = 1; p->sids_size = 1;
p->sids = SCMalloc(p->sids_size * sizeof(uint32_t)); p->sids = SCMalloc(p->sids_size * sizeof(uint32_t));
BUG_ON(p->sids == NULL); BUG_ON(p->sids == NULL);
@ -625,7 +621,7 @@ static inline int SCACTileInitNewState(MpmCtx *mpm_ctx)
* \param pid The pattern id to add. * \param pid The pattern id to add.
* \param mpm_ctx Pointer to the mpm context. * \param mpm_ctx Pointer to the mpm context.
*/ */
static void SCACTileSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx) static void SCACTileSetOutputState(int32_t state, MpmPatternIndex pindex, MpmCtx *mpm_ctx)
{ {
void *ptmp; void *ptmp;
SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
@ -636,24 +632,24 @@ static void SCACTileSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx)
/* Don't add the pattern more than once to the same state. */ /* Don't add the pattern more than once to the same state. */
for (i = 0; i < output_state->no_of_entries; i++) { for (i = 0; i < output_state->no_of_entries; i++) {
if (output_state->pids[i] == pid) if (output_state->patterns[i] == pindex)
return; return;
} }
/* Increase the size of the array of pids for this state and add /* Increase the size of the array of pids for this state and add
* the new pid. */ * the new pid. */
output_state->no_of_entries++; output_state->no_of_entries++;
ptmp = SCRealloc(output_state->pids, ptmp = SCRealloc(output_state->patterns,
output_state->no_of_entries * sizeof(uint32_t)); output_state->no_of_entries * sizeof(MpmPatternIndex));
if (ptmp == NULL) { if (ptmp == NULL) {
SCFree(output_state->pids); SCFree(output_state->patterns);
output_state->pids = NULL; output_state->patterns = NULL;
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
output_state->pids = ptmp; output_state->patterns = ptmp;
output_state->pids[output_state->no_of_entries - 1] = pid; output_state->patterns[output_state->no_of_entries - 1] = pindex;
} }
/** /**
@ -667,7 +663,7 @@ static void SCACTileSetOutputState(int32_t state, uint32_t pid, MpmCtx *mpm_ctx)
* \param mpm_ctx Pointer to the mpm context. * \param mpm_ctx Pointer to the mpm context.
*/ */
static void SCACTileEnter(uint8_t *pattern, uint16_t pattern_len, static void SCACTileEnter(uint8_t *pattern, uint16_t pattern_len,
uint32_t pid, MpmCtx *mpm_ctx) MpmPatternIndex pindex, MpmCtx *mpm_ctx)
{ {
SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx; SCACTileSearchCtx *search_ctx = (SCACTileSearchCtx *)mpm_ctx->ctx;
SCACTileCtx *ctx = search_ctx->init_ctx; SCACTileCtx *ctx = search_ctx->init_ctx;
@ -698,7 +694,7 @@ static void SCACTileEnter(uint8_t *pattern, uint16_t pattern_len,
/* Add this pattern id, to the output table of the last state, where the /* Add this pattern id, to the output table of the last state, where the
* pattern ends in the trie */ * pattern ends in the trie */
SCACTileSetOutputState(state, pid, mpm_ctx); SCACTileSetOutputState(state, pindex, mpm_ctx);
} }
/** /**
@ -717,7 +713,7 @@ static void SCACTileCreateGotoTable(MpmCtx *mpm_ctx)
/* add each pattern to create the goto table */ /* add each pattern to create the goto table */
for (i = 0; i < mpm_ctx->pattern_cnt; i++) { for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
SCACTileEnter(ctx->parray[i]->ci, ctx->parray[i]->len, SCACTileEnter(ctx->parray[i]->ci, ctx->parray[i]->len,
ctx->parray[i]->id, mpm_ctx); i, mpm_ctx);
} }
int aa = 0; int aa = 0;
@ -797,25 +793,25 @@ static void SCACTileClubOutputStates(int32_t dst_state,
for (i = 0; i < output_src_state->no_of_entries; i++) { for (i = 0; i < output_src_state->no_of_entries; i++) {
for (j = 0; j < output_dst_state->no_of_entries; j++) { for (j = 0; j < output_dst_state->no_of_entries; j++) {
if (output_src_state->pids[i] == output_dst_state->pids[j]) { if (output_src_state->patterns[i] == output_dst_state->patterns[j]) {
break; break;
} }
} }
if (j == output_dst_state->no_of_entries) { if (j == output_dst_state->no_of_entries) {
output_dst_state->no_of_entries++; output_dst_state->no_of_entries++;
ptmp = SCRealloc(output_dst_state->pids, ptmp = SCRealloc(output_dst_state->patterns,
(output_dst_state->no_of_entries * sizeof(uint32_t))); (output_dst_state->no_of_entries * sizeof(uint32_t)));
if (ptmp == NULL) { if (ptmp == NULL) {
SCFree(output_dst_state->pids); SCFree(output_dst_state->patterns);
output_dst_state->pids = NULL; output_dst_state->patterns = NULL;
SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory"); SCLogError(SC_ERR_MEM_ALLOC, "Error allocating memory");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
output_dst_state->pids = ptmp; output_dst_state->patterns = ptmp;
output_dst_state->pids[output_dst_state->no_of_entries - 1] = output_dst_state->patterns[output_dst_state->no_of_entries - 1] =
output_src_state->pids[i]; output_src_state->patterns[i];
} }
} }
} }
@ -1083,9 +1079,10 @@ static inline void SCACTileInsertCaseSensitiveEntriesForPatterns(MpmCtx *mpm_ctx
continue; continue;
for (k = 0; k < ctx->output_table[state].no_of_entries; k++) { for (k = 0; k < ctx->output_table[state].no_of_entries; k++) {
if (ctx->pid_pat_list[ctx->output_table[state].pids[k]].cs != NULL) { if (ctx->pattern_list[ctx->output_table[state].patterns[k]].cs != NULL) {
ctx->output_table[state].pids[k] &= 0x0000FFFF; /* TODO - Find better way to store this. */
ctx->output_table[state].pids[k] |= 1 << 16; ctx->output_table[state].patterns[k] &= 0x0000FFFF;
ctx->output_table[state].patterns[k] |= 1 << 16;
} }
} }
} }
@ -1178,8 +1175,11 @@ static void SCACTilePrepareSearch(MpmCtx *mpm_ctx)
search_ctx->output_table = ctx->output_table; search_ctx->output_table = ctx->output_table;
ctx->output_table = NULL; ctx->output_table = NULL;
search_ctx->pid_pat_list = ctx->pid_pat_list; search_ctx->pattern_list = ctx->pattern_list;
ctx->pid_pat_list = NULL; ctx->pattern_list = NULL;
/* One bit per pattern, rounded up to the next byte size. */
search_ctx->mpm_bitarray_size = (mpm_ctx->pattern_cnt + 7) / 8;
/* Can now free the Initialization data */ /* Can now free the Initialization data */
SCACTileDestroyInitCtx(mpm_ctx); SCACTileDestroyInitCtx(mpm_ctx);
@ -1241,7 +1241,7 @@ int SCACTilePreparePatterns(MpmCtx *mpm_ctx)
} }
} }
size_t pattern_list_size = (ctx->max_pat_id + 1) * sizeof(SCACTilePatternList); size_t pattern_list_size = mpm_ctx->pattern_cnt * sizeof(SCACTilePatternList);
size_t mem_size = string_space_needed + pattern_list_size; size_t mem_size = string_space_needed + pattern_list_size;
void *mem_block = SCCalloc(1, mem_size); void *mem_block = SCCalloc(1, mem_size);
if (mem_block == NULL) { if (mem_block == NULL) {
@ -1251,7 +1251,7 @@ int SCACTilePreparePatterns(MpmCtx *mpm_ctx)
mpm_ctx->memory_cnt++; mpm_ctx->memory_cnt++;
mpm_ctx->memory_size += mem_size; mpm_ctx->memory_size += mem_size;
/* Split the allocated block into pattern list array and string space. */ /* Split the allocated block into pattern list array and string space. */
ctx->pid_pat_list = mem_block; ctx->pattern_list = mem_block;
uint8_t *string_space = mem_block + pattern_list_size; uint8_t *string_space = mem_block + pattern_list_size;
/* Now make the copies of the no-case strings. */ /* Now make the copies of the no-case strings. */
@ -1260,15 +1260,15 @@ int SCACTilePreparePatterns(MpmCtx *mpm_ctx)
uint32_t len = ctx->parray[i]->len; uint32_t len = ctx->parray[i]->len;
uint32_t space = ((len + 7) / 8) * 8; uint32_t space = ((len + 7) / 8) * 8;
memcpy(string_space, ctx->parray[i]->original_pat, len); memcpy(string_space, ctx->parray[i]->original_pat, len);
ctx->pid_pat_list[ctx->parray[i]->id].cs = string_space; ctx->pattern_list[i].cs = string_space;
ctx->pid_pat_list[ctx->parray[i]->id].patlen = len; ctx->pattern_list[i].patlen = len;
string_space += space; string_space += space;
} }
ctx->pattern_list[i].pid = ctx->parray[i]->id;
/* ACPatternList now owns this memory */ /* ACPatternList now owns this memory */
//SCLogInfo("ctx->parray[i]->sids_size %u", ctx->parray[i]->sids_size); ctx->pattern_list[i].sids_size = ctx->parray[i]->sids_size;
ctx->pid_pat_list[ctx->parray[i]->id].sids_size = ctx->parray[i]->sids_size; ctx->pattern_list[i].sids = ctx->parray[i]->sids;
ctx->pid_pat_list[ctx->parray[i]->id].sids = ctx->parray[i]->sids;
} }
/* prepare the state table required by AC */ /* prepare the state table required by AC */
@ -1403,22 +1403,22 @@ static void SCACTileDestroyInitCtx(MpmCtx *mpm_ctx)
if (ctx->output_table != NULL) { if (ctx->output_table != NULL) {
int state; int state;
for (state = 0; state < ctx->state_count; state++) { for (state = 0; state < ctx->state_count; state++) {
if (ctx->output_table[state].pids != NULL) { if (ctx->output_table[state].patterns != NULL) {
SCFree(ctx->output_table[state].pids); SCFree(ctx->output_table[state].patterns);
} }
} }
SCFree(ctx->output_table); SCFree(ctx->output_table);
} }
if (ctx->pid_pat_list != NULL) { if (ctx->pattern_list != NULL) {
int i; uint32_t i;
for (i = 0; i < (ctx->max_pat_id + 1); i++) { for (i = 0; i < mpm_ctx->pattern_cnt; i++) {
if (ctx->pid_pat_list[i].cs != NULL) if (ctx->pattern_list[i].cs != NULL)
SCFree(ctx->pid_pat_list[i].cs); SCFree(ctx->pattern_list[i].cs);
if (ctx->pid_pat_list[i].sids != NULL) if (ctx->pattern_list[i].sids != NULL)
SCFree(ctx->pid_pat_list[i].sids); SCFree(ctx->pattern_list[i].sids);
} }
SCFree(ctx->pid_pat_list); SCFree(ctx->pattern_list);
} }
SCFree(ctx); SCFree(ctx);
@ -1443,7 +1443,7 @@ void SCACTileDestroyCtx(MpmCtx *mpm_ctx)
/* Free Search tables */ /* Free Search tables */
SCFree(search_ctx->state_table); SCFree(search_ctx->state_table);
SCFree(search_ctx->pid_pat_list); SCFree(search_ctx->pattern_list);
SCFree(search_ctx->output_table); SCFree(search_ctx->output_table);
SCFree(search_ctx); SCFree(search_ctx);
@ -1467,45 +1467,53 @@ void SCACTileDestroyCtx(MpmCtx *mpm_ctx)
int CheckMatch(SCACTileSearchCtx *ctx, PatternMatcherQueue *pmq, int CheckMatch(SCACTileSearchCtx *ctx, PatternMatcherQueue *pmq,
uint8_t *buf, uint16_t buflen, uint8_t *buf, uint16_t buflen,
uint16_t state, int i, int matches, uint8_t *bitarray) uint16_t state, int i, int matches,
uint8_t *mpm_bitarray)
{ {
SCACTilePatternList *pid_pat_list = ctx->pid_pat_list; SCACTilePatternList *pattern_list = ctx->pattern_list;
uint8_t *buf_offset = buf + i + 1; // Lift out of loop uint8_t *buf_offset = buf + i + 1; // Lift out of loop
uint32_t no_of_entries = ctx->output_table[state].no_of_entries; uint32_t no_of_entries = ctx->output_table[state].no_of_entries;
uint32_t *pids = ctx->output_table[state].pids; uint32_t *patterns = ctx->output_table[state].patterns;
uint8_t *pmq_bitarray = pmq->pattern_id_bitarray; uint8_t *pmq_bitarray = pmq->pattern_id_bitarray;
uint32_t k; uint32_t k;
/* Where to start storing new patterns */
uint32_t *orig_pattern = pmq->pattern_id_array + pmq->pattern_id_array_cnt;
uint32_t *new_pattern = orig_pattern;
for (k = 0; k < no_of_entries; k++) { for (k = 0; k < no_of_entries; k++) {
uint16_t lower_pid = pids[k] & 0x0000FFFF; MpmPatternIndex pindex = patterns[k] & 0x0000FFFF;
if (pids[k] & 0xFFFF0000) { if (mpm_bitarray[pindex / 8] & (1 << (pindex % 8))) {
uint16_t patlen = pid_pat_list[lower_pid].patlen; /* Pattern already seen by this MPM. */
if (SCMemcmp(pid_pat_list[lower_pid].cs, buf_offset - patlen, patlen) != 0) { /* NOTE: This is faster then rechecking if it is a case-sensitive match
/* inside loop */ * since we know this pattern has already been seen, but imcrementing
* matches here could over report matches. For example if the case-sensitive
* pattern is "Foo" and the string is "Foo bar foo", matches would be reported
* as 2, when it should really be 1, since "foo" is not a true match.
*/
matches++;
continue;
}
uint32_t pid = pattern_list[pindex].pid;
/* Double check case-sensitve match now. */
if (patterns[k] & 0xFFFF0000) {
uint16_t patlen = pattern_list[pindex].patlen;
if (SCMemcmp(pattern_list[pindex].cs, buf_offset - patlen, patlen) != 0) {
/* Case-sensitive match failed. */
continue; continue;
} }
} }
if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) { /* New match found */
; mpm_bitarray[pindex / 8] |= (1 << (pindex % 8));
} else {
bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8));
pmq_bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8));
*new_pattern++ = lower_pid;
MpmAddSids(pmq, pid_pat_list[lower_pid].sids, if ((pmq_bitarray[pid / 8] & (1 << (pid % 8))) == 0) {
pid_pat_list[lower_pid].sids_size); pmq_bitarray[(pid) / 8] |= (1 << ((pid) % 8));
MpmAddPid(pmq, pid);
} }
/* Always add the Signature IDs, since they could be different in the current MPM
* than in a previous MPM on the same PMQ when finding the same pattern.
*/
MpmAddSids(pmq, pattern_list[pindex].sids,
pattern_list[pindex].sids_size);
matches++; matches++;
} }
/* Only update the pattern count if a new pattern was added.
* No need to compute it or dirty that cache data for no change.
*/
if (new_pattern != orig_pattern)
pmq->pattern_id_array_cnt = new_pattern - orig_pattern;
return matches; return matches;
} }
@ -1542,10 +1550,8 @@ uint32_t SCACTileSearchLarge(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ct
int i = 0; int i = 0;
int matches = 0; int matches = 0;
SCACTilePatternList *pid_pat_list = ctx->pid_pat_list; uint8_t mpm_bitarray[ctx->mpm_bitarray_size];
memset(mpm_bitarray, 0, ctx->mpm_bitarray_size);
uint8_t bitarray[pmq->pattern_id_bitarray_size];
memset(bitarray, 0, pmq->pattern_id_bitarray_size);
uint8_t* restrict xlate = ctx->translate_table; uint8_t* restrict xlate = ctx->translate_table;
register int state = 0; register int state = 0;
@ -1553,44 +1559,7 @@ uint32_t SCACTileSearchLarge(SCACTileSearchCtx *ctx, MpmThreadCtx *mpm_thread_ct
for (i = 0; i < buflen; i++) { for (i = 0; i < buflen; i++) {
state = state_table_u32[state & 0x00FFFFFF][xlate[buf[i]]]; state = state_table_u32[state & 0x00FFFFFF][xlate[buf[i]]];
if (SCHECK(state)) { if (SCHECK(state)) {
uint32_t no_of_entries = ctx->output_table[state].no_of_entries; matches = CheckMatch(ctx, pmq, buf, buflen, state, i, matches, mpm_bitarray);
uint32_t *pids = ctx->output_table[state].pids;
uint32_t k;
for (k = 0; k < no_of_entries; k++) {
if (pids[k] & 0xFFFF0000) {
uint32_t lower_pid = pids[k] & 0x0000FFFF;
if (SCMemcmp(pid_pat_list[lower_pid].cs,
buf + i - pid_pat_list[lower_pid].patlen + 1,
pid_pat_list[lower_pid].patlen) != 0) {
/* inside loop */
continue;
}
if (bitarray[(lower_pid) / 8] & (1 << ((lower_pid) % 8))) {
;
} else {
bitarray[(lower_pid) / 8] |= (1 << ((lower_pid) % 8));
pmq->pattern_id_bitarray[(lower_pid) / 8] |=
(1 << ((lower_pid) % 8));
pmq->pattern_id_array[pmq->pattern_id_array_cnt++] = lower_pid;
MpmAddSids(pmq, pid_pat_list[lower_pid].sids,
pid_pat_list[lower_pid].sids_size);
}
matches++;
} else {
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];
MpmAddSids(pmq, pid_pat_list[pids[k]].sids,
pid_pat_list[pids[k]].sids_size);
}
matches++;
}
}
} }
} /* for (i = 0; i < buflen; i++) */ } /* for (i = 0; i < buflen; i++) */

@ -51,15 +51,18 @@ typedef struct SCACTilePatternList_ {
uint8_t *cs; uint8_t *cs;
uint16_t patlen; uint16_t patlen;
/* Pattern Id */
uint32_t pid;
/* sid(s) for this pattern */ /* sid(s) for this pattern */
uint32_t sids_size; uint32_t sids_size;
uint32_t *sids; uint32_t *sids;
} SCACTilePatternList; } SCACTilePatternList;
typedef struct SCACTileOutputTable_ { typedef struct SCACTileOutputTable_ {
/* list of pattern sids */ /* list of pattern indexes */
uint32_t *pids; MpmPatternIndex *patterns;
/* no of entries we have in pids */ /* number of entries in pattern list */
uint32_t no_of_entries; uint32_t no_of_entries;
} SCACTileOutputTable; } SCACTileOutputTable;
@ -90,8 +93,10 @@ typedef struct SCACTileCtx_ {
void (*set_next_state)(struct SCACTileCtx_ *ctx, int state, int aa, void (*set_next_state)(struct SCACTileCtx_ *ctx, int state, int aa,
int new_state, int outputs); int new_state, int outputs);
/* List of patterns that match for this state. Indexed by State Number */
SCACTileOutputTable *output_table; SCACTileOutputTable *output_table;
SCACTilePatternList *pid_pat_list; /* Indexed by MpmPatternIndex */
SCACTilePatternList *pattern_list;
/* hash used during ctx initialization */ /* hash used during ctx initialization */
SCACTilePattern **init_hash; SCACTilePattern **init_hash;
@ -111,9 +116,6 @@ typedef struct SCACTileCtx_ {
/* Number of states allocated for ac-tile. */ /* Number of states allocated for ac-tile. */
uint32_t allocated_state_count; uint32_t allocated_state_count;
/* Largest Pattern Identifier. */
uint16_t max_pat_id;
uint32_t alpha_hist[256]; uint32_t alpha_hist[256];
/* Number of characters in the compressed alphabet. */ /* Number of characters in the compressed alphabet. */
uint16_t alphabet_size; uint16_t alphabet_size;
@ -147,8 +149,12 @@ typedef struct SCACTileSearchCtx_ {
/* the all important memory hungry state_table */ /* the all important memory hungry state_table */
void *state_table; void *state_table;
/* List of patterns that match for this state. Indexed by State Number */
SCACTileOutputTable *output_table; SCACTileOutputTable *output_table;
SCACTilePatternList *pid_pat_list; SCACTilePatternList *pattern_list;
/* Number of bytes in the array of bits. One bit per pattern in this MPM. */
uint32_t mpm_bitarray_size;
/* MPM Creation data, only used at initialization. */ /* MPM Creation data, only used at initialization. */
SCACTileCtx *init_ctx; SCACTileCtx *init_ctx;

@ -82,6 +82,9 @@ enum {
#define DEFAULT_MPM MPM_AC #define DEFAULT_MPM MPM_AC
#endif #endif
/* Internal Pattern Index: 0 to pattern_cnt-1 */
typedef uint32_t MpmPatternIndex;
typedef struct MpmMatchBucket_ { typedef struct MpmMatchBucket_ {
uint32_t len; uint32_t len;
} MpmMatchBucket; } MpmMatchBucket;
@ -101,8 +104,8 @@ typedef struct PatternMatcherQueue_ {
uint32_t *pattern_id_array; /** array with pattern id's that had a uint32_t *pattern_id_array; /** array with pattern id's that had a
pattern match. These will be inspected pattern match. These will be inspected
futher by the detection engine. */ futher by the detection engine. */
uint32_t pattern_id_array_cnt; uint32_t pattern_id_array_cnt; /**< Number currently stored */
uint32_t pattern_id_array_size; /**< size in bytes */ uint32_t pattern_id_array_size; /**< Allocated size in bytes */
uint8_t *pattern_id_bitarray; /** bitarray with pattern id matches */ uint8_t *pattern_id_bitarray; /** bitarray with pattern id matches */
uint32_t pattern_id_bitarray_size; /**< size in bytes */ uint32_t pattern_id_bitarray_size; /**< size in bytes */

Loading…
Cancel
Save