detect: store detect flags in AppLayerTxData

pull/5169/head
Victor Julien 5 years ago
parent c797c9f09c
commit e15995e2d2

@ -57,6 +57,10 @@ pub struct AppLayerTxData {
/// logger flags for tx logging api
logged: LoggerFlags,
/// detection engine flags for use by detection engine
detect_flags_ts: u64,
detect_flags_tc: u64,
}
impl AppLayerTxData {
@ -64,6 +68,8 @@ impl AppLayerTxData {
Self {
config: AppLayerTxConfig::new(),
logged: LoggerFlags::new(),
detect_flags_ts: 0,
detect_flags_tc: 0,
}
}
}

@ -745,6 +745,42 @@ uint64_t AppLayerParserGetTransactionInspectId(AppLayerParserState *pstate, uint
SCReturnCT(pstate->inspect_id[direction & STREAM_TOSERVER ? 0 : 1], "uint64_t");
}
static inline uint64_t GetTxDetectFlags(const uint8_t ipproto, const AppProto alproto, void *tx, const uint8_t dir)
{
uint64_t detect_flags;
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (txd != NULL) {
detect_flags = (dir & STREAM_TOSERVER) ? txd->detect_flags_ts : txd->detect_flags_tc;
} else {
detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, dir);
}
return detect_flags;
}
static inline void SetTxDetectFlags(const uint8_t ipproto, const AppProto alproto, void *tx, const uint8_t dir, const uint64_t detect_flags)
{
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx);
if (txd != NULL) {
if (dir & STREAM_TOSERVER) {
txd->detect_flags_ts = detect_flags;
} else {
txd->detect_flags_tc = detect_flags;
}
} else {
AppLayerParserSetTxDetectFlags(ipproto, alproto, tx, dir, detect_flags);
}
}
static inline uint32_t GetTxLogged(const Flow *f, void *alstate, void *tx)
{
AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx);
if (txd) {
return txd->logged.flags;
} else {
return AppLayerParserGetTxLogged(f, alstate, tx);
}
}
void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *pstate,
void *alstate, const uint8_t flags,
bool tag_txs_as_inspected)
@ -780,10 +816,10 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
break;
if (tag_txs_as_inspected) {
uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, flags);
uint64_t detect_flags = GetTxDetectFlags(ipproto, alproto, tx, flags);
if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
AppLayerParserSetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
SetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
SCLogDebug("%p/%"PRIu64" in-order tx is done for direction %s. Flag %016"PRIx64,
tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
}
@ -817,10 +853,10 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p
if (state_progress < state_done_progress)
break;
uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, flags);
uint64_t detect_flags = GetTxDetectFlags(ipproto, alproto, tx, flags);
if ((detect_flags & APP_LAYER_TX_INSPECTED_FLAG) == 0) {
detect_flags |= APP_LAYER_TX_INSPECTED_FLAG;
AppLayerParserSetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
SetTxDetectFlags(ipproto, alproto, tx, flags, detect_flags);
SCLogDebug("%p/%"PRIu64" out of order tx is done for direction %s. Flag %016"PRIx64,
tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", detect_flags);
@ -895,7 +931,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
if (unlikely(p->StateTransactionFree == NULL))
SCReturn;
const bool has_tx_detect_flags = (p->GetTxDetectFlags != NULL);
const bool has_tx_detect_flags = (p->GetTxDetectFlags != NULL || p->GetTxData != NULL);
const uint8_t ipproto = f->proto;
const AppProto alproto = f->alproto;
void * const alstate = f->alstate;
@ -942,7 +978,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
}
if (has_tx_detect_flags) {
if (f->sgh_toserver != NULL) {
uint64_t detect_flags_ts = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, STREAM_TOSERVER);
uint64_t detect_flags_ts = GetTxDetectFlags(ipproto, alproto, tx, STREAM_TOSERVER);
if (!(detect_flags_ts & APP_LAYER_TX_INSPECTED_FLAG)) {
SCLogDebug("%p/%"PRIu64" skipping: TS inspect not done: ts:%"PRIx64,
tx, i, detect_flags_ts);
@ -951,7 +987,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
}
}
if (f->sgh_toclient != NULL) {
uint64_t detect_flags_tc = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx, STREAM_TOCLIENT);
uint64_t detect_flags_tc = GetTxDetectFlags(ipproto, alproto, tx, STREAM_TOCLIENT);
if (!(detect_flags_tc & APP_LAYER_TX_INSPECTED_FLAG)) {
SCLogDebug("%p/%"PRIu64" skipping: TC inspect not done: tc:%"PRIx64,
tx, i, detect_flags_tc);
@ -961,7 +997,7 @@ void AppLayerParserTransactionsCleanup(Flow *f)
}
}
if (logger_expectation != 0) {
LoggerId tx_logged = AppLayerParserGetTxLogged(f, alstate, tx);
LoggerId tx_logged = GetTxLogged(f, alstate, tx);
if (tx_logged != logger_expectation) {
SCLogDebug("%p/%"PRIu64" skipping: logging not done: want:%"PRIx32", have:%"PRIx32,
tx, i, logger_expectation, tx_logged);
@ -1147,6 +1183,9 @@ bool AppLayerParserSupportsTxDetectFlags(AppProto alproto)
if (alp_ctx.ctxs[p][alproto].GetTxDetectFlags != NULL) {
SCReturnBool(true);
}
if (alp_ctx.ctxs[p][alproto].GetTxData != NULL) {
SCReturnBool(true);
}
}
SCReturnBool(false);
}

@ -97,6 +97,7 @@ typedef struct DetectEngineState_ {
typedef struct DetectTransaction_ {
void *tx_ptr;
const uint64_t tx_id;
struct AppLayerTxData *tx_data_ptr;
DetectEngineStateDirection *de_state;
const uint64_t detect_flags; /* detect flags get/set from/to applayer */
uint64_t prefilter_flags; /* prefilter flags for direction, to be updated by prefilter code */

@ -1233,12 +1233,18 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
void *alstate, const uint64_t tx_id, void *tx_ptr, const int tx_end_state,
const uint8_t flow_flags)
{
const uint64_t detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx_ptr, flow_flags);
uint64_t detect_flags;
AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx_ptr);
if (txd != NULL) {
detect_flags = (flow_flags & STREAM_TOSERVER) ? txd->detect_flags_ts : txd->detect_flags_tc;
} else {
detect_flags = AppLayerParserGetTxDetectFlags(ipproto, alproto, tx_ptr, flow_flags);
}
if (detect_flags & APP_LAYER_TX_INSPECTED_FLAG) {
SCLogDebug("%"PRIu64" tx already fully inspected for %s. Flags %016"PRIx64,
tx_id, flow_flags & STREAM_TOSERVER ? "toserver" : "toclient",
detect_flags);
DetectTransaction no_tx = { NULL, 0, NULL, 0, 0, 0, 0, 0, };
DetectTransaction no_tx = { NULL, 0, NULL, NULL, 0, 0, 0, 0, 0, };
return no_tx;
}
@ -1251,6 +1257,7 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
DetectTransaction tx = {
.tx_ptr = tx_ptr,
.tx_id = tx_id,
.tx_data_ptr = (struct AppLayerTxData *)txd,
.de_state = tx_dir_state,
.detect_flags = detect_flags,
.prefilter_flags = prefilter_flags,
@ -1261,6 +1268,22 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro
return tx;
}
static inline void StoreDetectFlags(DetectTransaction *tx, const uint8_t flow_flags,
const uint8_t ipproto, const AppProto alproto, const uint64_t detect_flags)
{
AppLayerTxData *txd = (AppLayerTxData *)tx->tx_data_ptr;
if (txd != NULL) {
if (flow_flags & STREAM_TOSERVER) {
txd->detect_flags_ts = detect_flags;
} else {
txd->detect_flags_tc = detect_flags;
}
} else {
AppLayerParserSetTxDetectFlags(ipproto, alproto, tx->tx_ptr,
flow_flags, detect_flags);
}
}
static void DetectRunTx(ThreadVars *tv,
DetectEngineCtx *de_ctx,
DetectEngineThreadCtx *det_ctx,
@ -1501,8 +1524,8 @@ static void DetectRunTx(ThreadVars *tv,
new_detect_flags |= tx.detect_flags;
SCLogDebug("%p/%"PRIu64" Storing new flags %016"PRIx64" (was %016"PRIx64")",
tx.tx_ptr, tx.tx_id, new_detect_flags, tx.detect_flags);
AppLayerParserSetTxDetectFlags(ipproto, alproto, tx.tx_ptr,
flow_flags, new_detect_flags);
StoreDetectFlags(&tx, flow_flags, ipproto, alproto, new_detect_flags);
}
next:
InspectionBufferClean(det_ctx);

Loading…
Cancel
Save