|
|
|
@ -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);
|
|
|
|
|
}
|
|
|
|
|