@ -86,8 +86,6 @@ void SCACRegisterTests(void);
/* a placeholder to denote a failure transition in the goto table */
# define SC_AC_FAIL (-1)
/* size of the hash table used to speed up pattern insertions initially */
# define INIT_HASH_SIZE 65536
# define STATE_QUEUE_CONTAINER_SIZE 65536
@ -118,286 +116,6 @@ static void SCACGetConfig()
return ;
}
/**
* \ internal
* \ brief Creates a hash of the pattern . We use it for the hashing process
* during the initial pattern insertion time , to cull duplicate sigs .
*
* \ param pat Pointer to the pattern .
* \ param patlen Pattern length .
*
* \ retval hash A 32 bit unsigned hash .
*/
static inline uint32_t SCACInitHashRaw ( uint8_t * pat , uint16_t patlen )
{
uint32_t hash = patlen * pat [ 0 ] ;
if ( patlen > 1 )
hash + = pat [ 1 ] ;
return ( hash % INIT_HASH_SIZE ) ;
}
/**
* \ internal
* \ brief Looks up a pattern . We use it for the hashing process during the
* the initial pattern insertion time , to cull duplicate sigs .
*
* \ param ctx Pointer to the AC ctx .
* \ param pat Pointer to the pattern .
* \ param patlen Pattern length .
* \ param flags Flags . We don ' t need this .
*
* \ retval hash A 32 bit unsigned hash .
*/
static inline SCACPattern * SCACInitHashLookup ( SCACCtx * ctx , uint8_t * pat ,
uint16_t patlen , char flags ,
uint32_t pid )
{
uint32_t hash = SCACInitHashRaw ( pat , patlen ) ;
if ( ctx - > init_hash = = NULL ) {
return NULL ;
}
SCACPattern * t = ctx - > init_hash [ hash ] ;
for ( ; t ! = NULL ; t = t - > next ) {
if ( t - > id = = pid )
return t ;
}
return NULL ;
}
/**
* \ internal
* \ brief Allocs a new pattern instance .
*
* \ param mpm_ctx Pointer to the mpm context .
*
* \ retval p Pointer to the newly created pattern .
*/
static inline SCACPattern * SCACAllocPattern ( MpmCtx * mpm_ctx )
{
SCACPattern * p = SCMalloc ( sizeof ( SCACPattern ) ) ;
if ( unlikely ( p = = NULL ) ) {
exit ( EXIT_FAILURE ) ;
}
memset ( p , 0 , sizeof ( SCACPattern ) ) ;
mpm_ctx - > memory_cnt + + ;
mpm_ctx - > memory_size + = sizeof ( SCACPattern ) ;
return p ;
}
/**
* \ internal
* \ brief Used to free SCACPattern instances .
*
* \ param mpm_ctx Pointer to the mpm context .
* \ param p Pointer to the SCACPattern instance to be freed .
* \ param free Free the above pointer or not .
*/
static inline void SCACFreePattern ( MpmCtx * mpm_ctx , SCACPattern * p )
{
if ( p ! = NULL & & p - > cs ! = NULL & & p - > cs ! = p - > ci ) {
SCFree ( p - > cs ) ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = p - > len ;
}
if ( p ! = NULL & & p - > ci ! = NULL ) {
SCFree ( p - > ci ) ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = p - > len ;
}
if ( p ! = NULL & & p - > original_pat ! = NULL ) {
SCFree ( p - > original_pat ) ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = p - > len ;
}
if ( p ! = NULL & & p - > sids ! = NULL ) {
SCFree ( p - > sids ) ;
}
if ( p ! = NULL ) {
SCFree ( p ) ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = sizeof ( SCACPattern ) ;
}
return ;
}
static inline uint32_t SCACInitHash ( SCACPattern * p )
{
uint32_t hash = p - > len * p - > original_pat [ 0 ] ;
if ( p - > len > 1 )
hash + = p - > original_pat [ 1 ] ;
return ( hash % INIT_HASH_SIZE ) ;
}
static inline int SCACInitHashAdd ( SCACCtx * ctx , SCACPattern * p )
{
uint32_t hash = SCACInitHash ( p ) ;
if ( ctx - > init_hash = = NULL ) {
return 0 ;
}
if ( ctx - > init_hash [ hash ] = = NULL ) {
ctx - > init_hash [ hash ] = p ;
return 0 ;
}
SCACPattern * tt = NULL ;
SCACPattern * t = ctx - > init_hash [ hash ] ;
/* get the list tail */
do {
tt = t ;
t = t - > next ;
} while ( t ! = NULL ) ;
tt - > next = p ;
return 0 ;
}
/**
* \ internal
* \ brief Add a pattern to the mpm - ac context .
*
* \ param mpm_ctx Mpm context .
* \ param pat Pointer to the pattern .
* \ param patlen Length of the pattern .
* \ param pid Pattern id
* \ param sid Signature id ( internal id ) .
* \ param flags Pattern ' s MPM_PATTERN_ * flags .
*
* \ retval 0 On success .
* \ retval - 1 On failure .
*/
static int SCACAddPattern ( MpmCtx * mpm_ctx , uint8_t * pat , uint16_t patlen ,
uint16_t offset , uint16_t depth , uint32_t pid ,
SigIntId sid , uint8_t flags )
{
SCACCtx * ctx = ( SCACCtx * ) mpm_ctx - > ctx ;
SCLogDebug ( " Adding pattern for ctx %p, patlen % " PRIu16 " and pid % " PRIu32 ,
ctx , patlen , pid ) ;
if ( patlen = = 0 ) {
SCLogWarning ( SC_ERR_INVALID_ARGUMENTS , " pattern length 0 " ) ;
return 0 ;
}
/* check if we have already inserted this pattern */
SCACPattern * p = SCACInitHashLookup ( ctx , pat , patlen , flags , pid ) ;
if ( p = = NULL ) {
SCLogDebug ( " Allocing new pattern " ) ;
/* p will never be NULL */
p = SCACAllocPattern ( mpm_ctx ) ;
p - > len = patlen ;
p - > flags = flags ;
p - > id = pid ;
p - > original_pat = SCMalloc ( patlen ) ;
if ( p - > original_pat = = NULL )
goto error ;
mpm_ctx - > memory_cnt + + ;
mpm_ctx - > memory_size + = patlen ;
memcpy ( p - > original_pat , pat , patlen ) ;
p - > ci = SCMalloc ( patlen ) ;
if ( p - > ci = = NULL )
goto error ;
mpm_ctx - > memory_cnt + + ;
mpm_ctx - > memory_size + = patlen ;
memcpy_tolower ( p - > ci , pat , patlen ) ;
/* setup the case sensitive part of the pattern */
if ( p - > flags & MPM_PATTERN_FLAG_NOCASE ) {
/* nocase means no difference between cs and ci */
p - > cs = p - > ci ;
} else {
if ( memcmp ( p - > ci , pat , p - > len ) = = 0 ) {
/* no diff between cs and ci: pat is lowercase */
p - > cs = p - > ci ;
} else {
p - > cs = SCMalloc ( patlen ) ;
if ( p - > cs = = NULL )
goto error ;
mpm_ctx - > memory_cnt + + ;
mpm_ctx - > memory_size + = patlen ;
memcpy ( p - > cs , pat , patlen ) ;
}
}
/* put in the pattern hash */
SCACInitHashAdd ( ctx , p ) ;
//if (mpm_ctx->pattern_cnt == 65535) {
// SCLogError(SC_ERR_AHO_CORASICK, "Max search words reached. Can't "
// "insert anymore. Exiting");
// exit(EXIT_FAILURE);
//}
mpm_ctx - > pattern_cnt + + ;
if ( mpm_ctx - > maxlen < patlen )
mpm_ctx - > maxlen = patlen ;
if ( mpm_ctx - > minlen = = 0 ) {
mpm_ctx - > minlen = patlen ;
} else {
if ( 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 = SCMalloc ( p - > sids_size * sizeof ( SigIntId ) ) ;
BUG_ON ( p - > sids = = NULL ) ;
p - > sids [ 0 ] = sid ;
//SCLogInfo("MPM added %u:%u", pid, 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 ) {
SigIntId * sids = SCRealloc ( p - > sids , ( sizeof ( SigIntId ) * ( p - > sids_size + 1 ) ) ) ;
BUG_ON ( sids = = NULL ) ;
p - > sids = sids ;
p - > sids [ p - > sids_size ] = sid ;
p - > sids_size + + ;
//SCLogInfo("p->sids_size %u", p->sids_size);
//SCLogInfo("MPM added %u:%u (append)", pid, sid);
} else {
//SCLogInfo("rule %u already part of pid %u", sid, pid);
}
}
return 0 ;
error :
SCACFreePattern ( mpm_ctx , p ) ;
return - 1 ;
}
/**
* \ internal
* \ brief Initialize a new state in the goto and output tables .
@ -1036,24 +754,24 @@ int SCACPreparePatterns(MpmCtx *mpm_ctx)
{
SCACCtx * ctx = ( SCACCtx * ) mpm_ctx - > ctx ;
if ( mpm_ctx - > pattern_cnt = = 0 | | ctx- > init_hash = = NULL ) {
if ( mpm_ctx - > pattern_cnt = = 0 | | mpm_ ctx- > init_hash = = NULL ) {
SCLogDebug ( " no patterns supplied to this mpm_ctx " ) ;
return 0 ;
}
/* alloc the pattern array */
ctx - > parray = ( SCAC Pattern * * ) SCMalloc ( mpm_ctx - > pattern_cnt *
sizeof ( SCAC Pattern * ) ) ;
ctx - > parray = ( Mpm Pattern * * ) SCMalloc ( mpm_ctx - > pattern_cnt *
sizeof ( Mpm Pattern * ) ) ;
if ( ctx - > parray = = NULL )
goto error ;
memset ( ctx - > parray , 0 , mpm_ctx - > pattern_cnt * sizeof ( SCAC Pattern * ) ) ;
memset ( ctx - > parray , 0 , mpm_ctx - > pattern_cnt * sizeof ( Mpm Pattern * ) ) ;
mpm_ctx - > memory_cnt + + ;
mpm_ctx - > memory_size + = ( mpm_ctx - > pattern_cnt * sizeof ( SCAC Pattern * ) ) ;
mpm_ctx - > memory_size + = ( mpm_ctx - > pattern_cnt * sizeof ( Mpm Pattern * ) ) ;
/* populate it with the patterns in the hash */
uint32_t i = 0 , p = 0 ;
for ( i = 0 ; i < INIT_HASH_SIZE; i + + ) {
SCACPattern * node = ctx- > init_hash [ i ] , * nnode = NULL ;
for ( i = 0 ; i < MPM_ INIT_HASH_SIZE; i + + ) {
MpmPattern * node = mpm_ ctx- > init_hash [ i ] , * nnode = NULL ;
while ( node ! = NULL ) {
nnode = node - > next ;
node - > next = NULL ;
@ -1063,19 +781,19 @@ int SCACPreparePatterns(MpmCtx *mpm_ctx)
}
/* we no longer need the hash, so free it's memory */
SCFree ( ctx- > init_hash ) ;
ctx- > init_hash = NULL ;
SCFree ( mpm_ ctx- > init_hash ) ;
mpm_ ctx- > init_hash = NULL ;
/* the memory consumed by a single state in our goto table */
ctx - > single_state_size = sizeof ( int32_t ) * 256 ;
/* handle no case patterns */
ctx - > pid_pat_list = SCMalloc ( ( ctx- > max_pat_id + 1 ) * sizeof ( SCACPatternList ) ) ;
ctx - > pid_pat_list = SCMalloc ( ( mpm_ ctx- > max_pat_id + 1 ) * sizeof ( SCACPatternList ) ) ;
if ( ctx - > pid_pat_list = = NULL ) {
SCLogError ( SC_ERR_MEM_ALLOC , " Error allocating memory " ) ;
exit ( EXIT_FAILURE ) ;
}
memset ( ctx - > pid_pat_list , 0 , ( ctx- > max_pat_id + 1 ) * sizeof ( SCACPatternList ) ) ;
memset ( ctx - > pid_pat_list , 0 , ( mpm_ ctx- > max_pat_id + 1 ) * sizeof ( SCACPatternList ) ) ;
for ( i = 0 ; i < mpm_ctx - > pattern_cnt ; i + + ) {
if ( ! ( ctx - > parray [ i ] - > flags & MPM_PATTERN_FLAG_NOCASE ) ) {
@ -1123,15 +841,16 @@ int SCACPreparePatterns(MpmCtx *mpm_ctx)
/* free all the stored patterns. Should save us a good 100-200 mbs */
for ( i = 0 ; i < mpm_ctx - > pattern_cnt ; i + + ) {
if ( ctx - > parray [ i ] ! = NULL ) {
SCAC FreePattern( mpm_ctx , ctx - > parray [ i ] ) ;
Mpm FreePattern( mpm_ctx , ctx - > parray [ i ] ) ;
}
}
SCFree ( ctx - > parray ) ;
ctx - > parray = NULL ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = ( mpm_ctx - > pattern_cnt * sizeof ( SCAC Pattern * ) ) ;
mpm_ctx - > memory_size - = ( mpm_ctx - > pattern_cnt * sizeof ( Mpm Pattern * ) ) ;
ctx - > pattern_id_bitarray_size = ( ctx - > max_pat_id / 8 ) + 1 ;
ctx - > pattern_id_bitarray_size = ( mpm_ctx - > max_pat_id / 8 ) + 1 ;
SCLogDebug ( " ctx->pattern_id_bitarray_size %u " , ctx - > pattern_id_bitarray_size ) ;
return 0 ;
@ -1181,12 +900,11 @@ void SCACInitCtx(MpmCtx *mpm_ctx)
mpm_ctx - > memory_size + = sizeof ( SCACCtx ) ;
/* initialize the hash we use to speed up pattern insertions */
SCACCtx * ctx = ( SCACCtx * ) mpm_ctx - > ctx ;
ctx - > init_hash = SCMalloc ( sizeof ( SCACPattern * ) * INIT_HASH_SIZE ) ;
if ( ctx - > init_hash = = NULL ) {
mpm_ctx - > init_hash = SCMalloc ( sizeof ( MpmPattern * ) * MPM_INIT_HASH_SIZE ) ;
if ( mpm_ctx - > init_hash = = NULL ) {
exit ( EXIT_FAILURE ) ;
}
memset ( ctx- > init_hash , 0 , sizeof ( SCACPattern * ) * INIT_HASH_SIZE) ;
memset ( mpm_ ctx- > init_hash , 0 , sizeof ( MpmPattern * ) * MPM_ INIT_HASH_SIZE) ;
/* get conf values for AC from our yaml file. We have no conf values for
* now . We will certainly need this , as we develop the algo */
@ -1226,25 +944,25 @@ void SCACDestroyCtx(MpmCtx *mpm_ctx)
if ( ctx = = NULL )
return ;
if ( ctx- > init_hash ! = NULL ) {
SCFree ( ctx- > init_hash ) ;
ctx- > init_hash = NULL ;
if ( mpm_ ctx- > init_hash ! = NULL ) {
SCFree ( mpm_ ctx- > init_hash ) ;
mpm_ ctx- > init_hash = NULL ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = ( INIT_HASH_SIZE * sizeof ( SCAC Pattern * ) ) ;
mpm_ctx - > memory_size - = ( MPM_ INIT_HASH_SIZE * sizeof ( Mpm Pattern * ) ) ;
}
if ( ctx - > parray ! = NULL ) {
uint32_t i ;
for ( i = 0 ; i < mpm_ctx - > pattern_cnt ; i + + ) {
if ( ctx - > parray [ i ] ! = NULL ) {
SCAC FreePattern( mpm_ctx , ctx - > parray [ i ] ) ;
Mpm FreePattern( mpm_ctx , ctx - > parray [ i ] ) ;
}
}
SCFree ( ctx - > parray ) ;
ctx - > parray = NULL ;
mpm_ctx - > memory_cnt - - ;
mpm_ctx - > memory_size - = ( mpm_ctx - > pattern_cnt * sizeof ( SCAC Pattern * ) ) ;
mpm_ctx - > memory_size - = ( mpm_ctx - > pattern_cnt * sizeof ( Mpm Pattern * ) ) ;
}
if ( ctx - > state_table_u16 ! = NULL ) {
@ -1276,7 +994,7 @@ void SCACDestroyCtx(MpmCtx *mpm_ctx)
if ( ctx - > pid_pat_list ! = NULL ) {
uint32_t i ;
for ( i = 0 ; i < ( ctx- > max_pat_id + 1 ) ; i + + ) {
for ( i = 0 ; i < ( mpm_ 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 )
@ -1425,7 +1143,7 @@ int SCACAddPatternCI(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
SigIntId sid , uint8_t flags )
{
flags | = MPM_PATTERN_FLAG_NOCASE ;
return SCAC AddPattern( mpm_ctx , pat , patlen , offset , depth , pid , sid , flags ) ;
return Mpm AddPattern( mpm_ctx , pat , patlen , offset , depth , pid , sid , flags ) ;
}
/**
@ -1449,7 +1167,7 @@ int SCACAddPatternCS(MpmCtx *mpm_ctx, uint8_t *pat, uint16_t patlen,
uint16_t offset , uint16_t depth , uint32_t pid ,
SigIntId sid , uint8_t flags )
{
return SCAC AddPattern( mpm_ctx , pat , patlen , offset , depth , pid , sid , flags ) ;
return Mpm AddPattern( mpm_ctx , pat , patlen , offset , depth , pid , sid , flags ) ;
}
void SCACPrintSearchStats ( MpmThreadCtx * mpm_thread_ctx )
@ -1475,8 +1193,8 @@ void SCACPrintInfo(MpmCtx *mpm_ctx)
printf ( " Sizeof: \n " ) ;
printf ( " MpmCtx % " PRIuMAX " \n " , ( uintmax_t ) sizeof ( MpmCtx ) ) ;
printf ( " SCACCtx: % " PRIuMAX " \n " , ( uintmax_t ) sizeof ( SCACCtx ) ) ;
printf ( " SCAC Pattern %" PRIuMAX " \n " , ( uintmax_t ) sizeof ( SCAC Pattern) ) ;
printf ( " SCAC Pattern %" PRIuMAX " \n " , ( uintmax_t ) sizeof ( SCAC Pattern) ) ;
printf ( " Mpm Pattern %" PRIuMAX " \n " , ( uintmax_t ) sizeof ( Mpm Pattern) ) ;
printf ( " Mpm Pattern %" PRIuMAX " \n " , ( uintmax_t ) sizeof ( Mpm Pattern) ) ;
printf ( " Unique Patterns: % " PRIu32 " \n " , mpm_ctx - > pattern_cnt ) ;
printf ( " Smallest: % " PRIu32 " \n " , mpm_ctx - > minlen ) ;
printf ( " Largest: % " PRIu32 " \n " , mpm_ctx - > maxlen ) ;