@ -81,6 +81,7 @@
/** convert enum to string */
# define CASE_CODE(E) case E: return #E
#if 0
/** The DetectEngineThreadCtx::de_state_sig_array contains 2 separate values:
* 1. the first bit tells the prefilter engine to bypass the rule ( or not )
* 2. the other bits allow ' ContinueDetect ' to specify an offset again the
@ -94,6 +95,7 @@
# define MAX_STORED_TXID_OFFSET 127
/******** static internal helpers *********/
# endif
static inline int StateIsValid ( uint16_t alproto , void * alstate )
{
@ -110,12 +112,14 @@ static inline int StateIsValid(uint16_t alproto, void *alstate)
return 0 ;
}
#if 0
static inline int TxIsLast ( uint64_t tx_id , uint64_t total_txs )
{
if ( total_txs - tx_id < = 1 )
return 1 ;
return 0 ;
}
# endif
static DeStateStore * DeStateStoreAlloc ( void )
{
@ -127,6 +131,7 @@ static DeStateStore *DeStateStoreAlloc(void)
return d ;
}
# ifdef DEBUG_VALIDATION
static int DeStateSearchState ( DetectEngineState * state , uint8_t direction , SigIntId num )
{
DetectEngineStateDirection * dir_state = & state - > dir_state [ direction & STREAM_TOSERVER ? 0 : 1 ] ;
@ -151,6 +156,7 @@ static int DeStateSearchState(DetectEngineState *state, uint8_t direction, SigIn
}
return 0 ;
}
# endif
static void DeStateSignatureAppend ( DetectEngineState * state ,
const Signature * s , uint32_t inspect_flags , uint8_t direction )
@ -194,21 +200,6 @@ static void DeStateSignatureAppend(DetectEngineState *state,
return ;
}
static void DeStateStoreFileNoMatchCnt ( DetectEngineState * de_state , uint16_t file_no_match , uint8_t direction )
{
de_state - > dir_state [ direction & STREAM_TOSERVER ? 0 : 1 ] . filestore_cnt + = file_no_match ;
return ;
}
static int DeStateStoreFilestoreSigsCantMatch ( const SigGroupHead * sgh , DetectEngineState * de_state , uint8_t direction )
{
if ( de_state - > dir_state [ direction & STREAM_TOSERVER ? 0 : 1 ] . filestore_cnt = = sgh - > filestore_cnt )
return 1 ;
else
return 0 ;
}
DetectEngineState * DetectEngineStateAlloc ( void )
{
DetectEngineState * d = SCMalloc ( sizeof ( DetectEngineState ) ) ;
@ -238,75 +229,37 @@ void DetectEngineStateFree(DetectEngineState *state)
return ;
}
static int HasStoredSigs ( const Flow * f , const uint8_t flags )
static void StoreFileNoMatchCnt ( DetectEngineState * de_state , uint16_t file_no_match , uint8_t direction )
{
AppProto alproto = f - > alproto ;
void * alstate = FlowGetAppState ( f ) ;
if ( ! StateIsValid ( f - > alproto , alstate ) ) {
return 0 ;
}
int state = AppLayerParserHasTxDetectState ( f - > proto , alproto , f - > alstate ) ;
if ( state = = - ENOSYS ) { /* proto doesn't support this API call */
/* fall through */
} else if ( state = = 0 ) {
return 0 ;
}
/* if state == 1 we also fall through */
uint64_t inspect_tx_id = AppLayerParserGetTransactionInspectId ( f - > alparser , flags ) ;
uint64_t total_txs = AppLayerParserGetTxCnt ( f , alstate ) ;
de_state - > dir_state [ direction & STREAM_TOSERVER ? 0 : 1 ] . filestore_cnt + = file_no_match ;
for ( ; inspect_tx_id < total_txs ; inspect_tx_id + + ) {
void * inspect_tx = AppLayerParserGetTx ( f - > proto , alproto , alstate , inspect_tx_id ) ;
if ( inspect_tx ! = NULL ) {
DetectEngineState * tx_de_state = AppLayerParserGetTxDetectState ( f - > proto , alproto , inspect_tx ) ;
if ( tx_de_state = = NULL ) {
continue ;
}
if ( tx_de_state - > dir_state [ flags & STREAM_TOSERVER ? 0 : 1 ] . cnt ! = 0 ) {
SCLogDebug ( " tx % " PRIu64 " has sigs present " , inspect_tx_id ) ;
return 1 ;
}
}
}
return 0 ;
return ;
}
/** \brief Check if we need to inspect this state
*
* State needs to be inspected if :
* 1. state has been updated
* 2. we already have de_state in progress
*
* \ retval 0 no inspectable state
* \ retval 1 inspectable state
*/
int DeStateFlowHasInspectableState ( const Flow * f , const uint8_t flags )
static bool StoreFilestoreSigsCantMatch ( const SigGroupHead * sgh , const DetectEngineState * de_state , uint8_t direction )
{
int r = 0 ;
if ( HasStoredSigs ( f , flags ) ) {
r = 1 ;
} else {
r = 0 ;
}
return r ;
if ( de_state - > dir_state [ direction & STREAM_TOSERVER ? 0 : 1 ] . filestore_cnt = = sgh - > filestore_cnt )
return true ;
else
return false ;
}
static void StoreStateTxHandleFiles ( DetectEngineThreadCtx * det_ctx , Flow * f ,
DetectEngineState * destate , const uint8_t fl ags,
static void StoreStateTxHandleFiles ( const SigGroupHead * sgh , Flow * f ,
DetectEngineState * destate , const uint8_t flow_flags ,
const uint64_t tx_id , const uint16_t file_no_match )
{
SCLogDebug ( " tx % " PRIu64 " , file_no_match %u " , tx_id , file_no_match ) ;
DeState StoreFileNoMatchCnt( destate , file_no_match , flags) ;
if ( DeState StoreFilestoreSigsCantMatch( det_ctx- > sgh, destate , fl ags) = = 1 ) {
FileDisableStoringForTransaction ( f , fl ags & ( STREAM_TOCLIENT | STREAM_TOSERVER ) , tx_id ) ;
StoreFileNoMatchCnt( destate , file_no_match , flow_ flags) ;
if ( StoreFilestoreSigsCantMatch( sgh, destate , fl ow_fl ags) ) {
FileDisableStoringForTransaction ( f , fl ow_fl ags & ( STREAM_TOCLIENT | STREAM_TOSERVER ) , tx_id ) ;
}
}
static void StoreStateTxFileOnly ( DetectEngineThreadCtx * det_ctx ,
Flow * f , const uint8_t flags , const uint64_t tx_id , void * tx ,
void DetectRunStoreStateTx (
const SigGroupHead * sgh ,
Flow * f , void * tx , uint64_t tx_id ,
const Signature * s ,
uint32_t inspect_flags , uint8_t flow_flags ,
const uint16_t file_no_match )
{
DetectEngineState * destate = AppLayerParserGetTxDetectState ( f - > proto , f - > alproto , tx ) ;
@ -320,9 +273,33 @@ static void StoreStateTxFileOnly(DetectEngineThreadCtx *det_ctx,
}
SCLogDebug ( " destate created for % " PRIu64 , tx_id ) ;
}
StoreStateTxHandleFiles ( det_ctx , f , destate , flags , tx_id , file_no_match ) ;
DeStateSignatureAppend ( destate , s , inspect_flags , flow_flags ) ;
StoreStateTxHandleFiles ( sgh , f , destate , flow_flags , tx_id , file_no_match ) ;
SCLogDebug ( " Stored for TX % " PRIu64 , tx_id ) ;
}
void DetectRunStoreStateTxFileOnly (
const SigGroupHead * sgh ,
Flow * f , void * tx , uint64_t tx_id ,
const uint8_t flow_flags ,
const uint16_t file_no_match )
{
DetectEngineState * destate = AppLayerParserGetTxDetectState ( f - > proto , f - > alproto , tx ) ;
if ( destate = = NULL ) {
destate = DetectEngineStateAlloc ( ) ;
if ( destate = = NULL )
return ;
if ( AppLayerParserSetTxDetectState ( f , f - > alstate , tx , destate ) < 0 ) {
DetectEngineStateFree ( destate ) ;
return ;
}
SCLogDebug ( " destate created for % " PRIu64 , tx_id ) ;
}
StoreStateTxHandleFiles ( sgh , f , destate , flow_flags , tx_id , file_no_match ) ;
}
#if 0
/**
* \ param check_before_add check for duplicates before adding the sig
*/
@ -353,6 +330,62 @@ static void StoreStateTx(DetectEngineThreadCtx *det_ctx,
SCLogDebug ( " Stored for TX % " PRIu64 , tx_id ) ;
}
static int HasStoredSigs ( const Flow * f , const uint8_t flags )
{
AppProto alproto = f - > alproto ;
void * alstate = FlowGetAppState ( f ) ;
if ( ! StateIsValid ( f - > alproto , alstate ) ) {
return 0 ;
}
int state = AppLayerParserHasTxDetectState ( f - > proto , alproto , f - > alstate ) ;
if ( state = = - ENOSYS ) { /* proto doesn't support this API call */
/* fall through */
} else if ( state = = 0 ) {
return 0 ;
}
/* if state == 1 we also fall through */
uint64_t inspect_tx_id = AppLayerParserGetTransactionInspectId ( f - > alparser , flags ) ;
uint64_t total_txs = AppLayerParserGetTxCnt ( f , alstate ) ;
for ( ; inspect_tx_id < total_txs ; inspect_tx_id + + ) {
void * inspect_tx = AppLayerParserGetTx ( f - > proto , alproto , alstate , inspect_tx_id ) ;
if ( inspect_tx ! = NULL ) {
DetectEngineState * tx_de_state = AppLayerParserGetTxDetectState ( f - > proto , alproto , inspect_tx ) ;
if ( tx_de_state = = NULL ) {
continue ;
}
if ( tx_de_state - > dir_state [ flags & STREAM_TOSERVER ? 0 : 1 ] . cnt ! = 0 ) {
SCLogDebug ( " tx % " PRIu64 " has sigs present " , inspect_tx_id ) ;
return 1 ;
}
}
}
return 0 ;
}
/** \brief Check if we need to inspect this state
*
* State needs to be inspected if :
* 1. state has been updated
* 2. we already have de_state in progress
*
* \ retval 0 no inspectable state
* \ retval 1 inspectable state
*/
int DeStateFlowHasInspectableState ( const Flow * f , const uint8_t flags )
{
int r = 0 ;
if ( HasStoredSigs ( f , flags ) ) {
r = 1 ;
} else {
r = 0 ;
}
return r ;
}
/* returns: true match, false no match */
bool DeStateDetectStartDetection ( ThreadVars * tv ,
DetectEngineCtx * de_ctx ,
@ -822,17 +855,23 @@ end:
det_ctx - > tx_id_set = 0 ;
return ;
}
# endif
/** \brief update flow's inspection id's
*
* \ param f unlocked flow
* \ param flags direction and disruption flags
* \ param tag_txs_as_inspected if true all ' complete ' txs will be marked
* ' inspected '
*
* \ note it is possible that f - > alstate , f - > alparser are NULL */
void DeStateUpdateInspectTransactionId ( Flow * f , const uint8_t flags )
void DeStateUpdateInspectTransactionId ( Flow * f , const uint8_t flags ,
const bool tag_txs_as_inspected )
{
if ( f - > alparser & & f - > alstate ) {
AppLayerParserSetTransactionInspectId ( f , f - > alparser ,
f - > alstate , flags ) ;
f - > alstate , flags ,
tag_txs_as_inspected ) ;
}
return ;
}