diff --git a/rust/htp/src/c_api/config.rs b/rust/htp/src/c_api/config.rs index 0b85b7c2ed..e3c9110c77 100644 --- a/rust/htp/src/c_api/config.rs +++ b/rust/htp/src/c_api/config.rs @@ -1,7 +1,7 @@ #![deny(missing_docs)] use crate::{ config::{Config, HtpServerPersonality, HtpUrlEncodingHandling}, - hook::{DataExternalCallbackFn, TxExternalCallbackFn}, + hook::{DataExternalCallbackFn, TxCreateCallbackFn, TxDestroyCallbackFn, TxExternalCallbackFn}, HtpStatus, }; use std::convert::TryInto; @@ -74,6 +74,31 @@ pub unsafe extern "C" fn htp_config_register_request_line( } } +/// Registers a tx create callback, which is invoked every time a new +/// request begins and before any parsing is done. +/// # Safety +/// When calling this method, you have to ensure that cfg is either properly initialized or NULL +#[no_mangle] +pub unsafe extern "C" fn htp_config_register_tx_create( + cfg: *mut Config, cbk_fn: TxCreateCallbackFn, +) { + if let Some(cfg) = cfg.as_mut() { + cfg.hook_tx_create = Some(cbk_fn); + } +} + +/// Registers a tx destroy callback, which is invoked every time a tx is dropped +/// # Safety +/// When calling this method, you have to ensure that cfg is either properly initialized or NULL +#[no_mangle] +pub unsafe extern "C" fn htp_config_register_tx_destroy( + cfg: *mut Config, cbk_fn: TxDestroyCallbackFn, +) { + if let Some(cfg) = cfg.as_mut() { + cfg.hook_tx_destroy = Some(cbk_fn); + } +} + /// Registers a REQUEST_START callback, which is invoked every time a new /// request begins and before any parsing is done. /// # Safety diff --git a/rust/htp/src/c_api/transaction.rs b/rust/htp/src/c_api/transaction.rs index 6c0fc9b00b..9830b6183f 100644 --- a/rust/htp/src/c_api/transaction.rs +++ b/rust/htp/src/c_api/transaction.rs @@ -45,16 +45,6 @@ pub unsafe extern "C" fn htp_tx_get_user_data(tx: *const Transaction) -> *mut li .unwrap_or(std::ptr::null_mut()) } -/// Associates user data with this transaction. -/// # Safety -/// When calling this method, you have to ensure that tx is either properly initialized or NULL -#[no_mangle] -pub unsafe extern "C" fn htp_tx_set_user_data(tx: *mut Transaction, user_data: *mut libc::c_void) { - if let Some(tx) = tx.as_mut() { - tx.set_user_data(Box::new(user_data)) - } -} - /// Get a transaction's request line. /// /// tx: Transaction pointer. diff --git a/rust/htp/src/config.rs b/rust/htp/src/config.rs index fc629652aa..d165cb98d2 100644 --- a/rust/htp/src/config.rs +++ b/rust/htp/src/config.rs @@ -6,6 +6,8 @@ use crate::{ HtpStatus, }; +use crate::hook::{TxCreateCallbackFn, TxDestroyCallbackFn}; + #[cfg(test)] use crate::hook::{DataNativeCallbackFn, TxNativeCallbackFn}; @@ -20,6 +22,14 @@ pub struct Config { pub(crate) server_personality: HtpServerPersonality, /// Decoder configuration for url path. pub(crate) decoder_cfg: DecoderConfig, + /// Transaction creation hook. + /// Used by suricata to allocate its transaction (user data) + /// And make libhtp.rs tx creation fail (return None) if suricata failed + /// to do the C allocation. + pub(crate) hook_tx_create: Option, + /// Transaction destroy hook. + /// Used by suricata to free its transaction (user data) + pub(crate) hook_tx_destroy: Option, /// Request start hook, invoked when the parser receives the first byte of a new /// request. Because an HTTP transaction always starts with a request, this hook /// doubles as a transaction start hook. @@ -104,6 +114,8 @@ impl Default for Config { field_limit: 18000, server_personality: HtpServerPersonality::MINIMAL, decoder_cfg: Default::default(), + hook_tx_create: None, + hook_tx_destroy: None, hook_request_start: TxHook::default(), hook_request_line: TxHook::default(), hook_request_header_data: DataHook::default(), diff --git a/rust/htp/src/hook.rs b/rust/htp/src/hook.rs index 29d02c027b..a9a598cc7b 100644 --- a/rust/htp/src/hook.rs +++ b/rust/htp/src/hook.rs @@ -15,6 +15,12 @@ pub(crate) type TxNativeCallbackFn = fn(tx: &mut Transaction) -> Result<()>; /// Hook for Transaction pub(crate) type TxHook = Hook; +/// External (C) callback function prototype +pub(crate) type TxCreateCallbackFn = unsafe extern "C" fn(req: bool) -> *mut libc::c_void; + +/// External (C) callback function prototype +pub(crate) type TxDestroyCallbackFn = unsafe extern "C" fn(tx_ud: *mut libc::c_void); + /// External (C) callback function prototype pub(crate) type DataExternalCallbackFn = unsafe extern "C" fn(connp: *const ConnectionParser, data: *mut Data) -> HtpStatus; diff --git a/rust/htp/src/transaction.rs b/rust/htp/src/transaction.rs index fd60c7b145..146192d0fd 100644 --- a/rust/htp/src/transaction.rs +++ b/rust/htp/src/transaction.rs @@ -1,5 +1,6 @@ use crate::{ bstr::Bstr, + c_api::transaction::htp_tx_get_user_data, config::{Config, HtpUnwanted}, connection_parser::ParserData, decompressors::{Decompressor, HtpContentEncoding}, @@ -598,10 +599,23 @@ impl std::fmt::Debug for Transaction { } } +impl Drop for Transaction { + fn drop(&mut self) { + if self.user_data.is_none() { + return; + } + if let Some(cb) = self.cfg.hook_tx_destroy { + unsafe { cb(htp_tx_get_user_data(self)) }; + } + } +} + impl Transaction { /// Construct a new transaction. - pub(crate) fn new(cfg: &'static Config, logger: &Logger, index: usize) -> Self { - Self { + pub(crate) fn new( + cfg: &'static Config, logger: &Logger, index: usize, req: bool, + ) -> Option { + let mut tx = Self { logger: logger.clone(), cfg, user_data: None, @@ -661,7 +675,15 @@ impl Transaction { response_header_repetitions: 0, request_header_parser: HeaderParser::new(Side::Request), response_header_parser: HeaderParser::new(Side::Response), + }; + if let Some(cb) = cfg.hook_tx_create { + let r = unsafe { cb(req) }; + if r.is_null() { + return None; + } + tx.set_user_data(Box::new(r)); } + Some(tx) } /// Has this transaction started? diff --git a/rust/htp/src/transactions.rs b/rust/htp/src/transactions.rs index 0b7e527c97..1b2aba9bec 100644 --- a/rust/htp/src/transactions.rs +++ b/rust/htp/src/transactions.rs @@ -67,7 +67,11 @@ impl Transactions { if nbtx >= cfg.max_tx as usize { return None; } - Some(entry.insert(Transaction::new(cfg, logger, request))) + let tx = Transaction::new(cfg, logger, request, true); + if let Some(tx) = tx { + return Some(entry.insert(tx)); + } + None } } } @@ -97,7 +101,11 @@ impl Transactions { if nbtx >= cfg.max_tx as usize { return None; } - Some(entry.insert(Transaction::new(cfg, logger, response))) + let tx = Transaction::new(cfg, logger, response, false); + if let Some(tx) = tx { + return Some(entry.insert(tx)); + } + None } } } diff --git a/src/app-layer-htp.c b/src/app-layer-htp.c index b6de7baa78..4f6e5b9d48 100644 --- a/src/app-layer-htp.c +++ b/src/app-layer-htp.c @@ -439,11 +439,9 @@ static void HTPSetEvent(HtpState *s, HtpTxUserData *htud, tx = HTPStateGetTx(s, tx_id - 1); if (tx != NULL) { htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - AppLayerDecoderEventsSetEventRaw(&htud->tx_data.events, e); - s->events++; - return; - } + AppLayerDecoderEventsSetEventRaw(&htud->tx_data.events, e); + s->events++; + return; } SCLogDebug("couldn't set event %u", e); } @@ -473,8 +471,9 @@ static void *HTPStateAlloc(void *orig_state, AppProto proto_orig) SCReturnPtr((void *)s, "void"); } -static void HtpTxUserDataFree(HtpState *state, HtpTxUserData *htud) +static void HtpTxUserDataFree(void *txud) { + HtpTxUserData *htud = (HtpTxUserData *)txud; if (likely(htud)) { HtpBodyFree(&htud->request_body); HtpBodyFree(&htud->response_body); @@ -510,20 +509,6 @@ void HTPStateFree(void *state) /* free the connection parser memory used by HTP library */ if (s->connp != NULL) { SCLogDebug("freeing HTP state"); - - uint64_t tx_id; - uint64_t total_txs = HTPStateGetTxCnt(state); - /* free the list of body chunks */ - if (s->conn != NULL) { - for (tx_id = 0; tx_id < total_txs; tx_id++) { - htp_tx_t *tx = HTPStateGetTx(s, tx_id); - if (tx != NULL) { - HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - HtpTxUserDataFree(s, htud); - htp_tx_set_user_data(tx, NULL); - } - } - } htp_connp_destroy_all(s->connp); } @@ -554,10 +539,6 @@ static void HTPStateTransactionFree(void *state, uint64_t id) htp_tx_t *tx = HTPStateGetTx(s, id); if (tx != NULL) { - /* This will remove obsolete body chunks */ - HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - HtpTxUserDataFree(s, htud); - htp_tx_set_user_data(tx, NULL); htp_tx_destroy(s->connp, tx); } } @@ -607,13 +588,11 @@ void AppLayerHtpNeedFileInspection(void) static void AppLayerHtpSetStreamDepthFlag(void *tx, const uint8_t flags) { HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data((htp_tx_t *)tx); - if (tx_ud) { - SCLogDebug("setting HTP_STREAM_DEPTH_SET, flags %02x", flags); - if (flags & STREAM_TOCLIENT) { - tx_ud->tcflags |= HTP_STREAM_DEPTH_SET; - } else { - tx_ud->tsflags |= HTP_STREAM_DEPTH_SET; - } + SCLogDebug("setting HTP_STREAM_DEPTH_SET, flags %02x", flags); + if (flags & STREAM_TOCLIENT) { + tx_ud->tcflags |= HTP_STREAM_DEPTH_SET; + } else { + tx_ud->tsflags |= HTP_STREAM_DEPTH_SET; } } @@ -709,8 +688,6 @@ static inline void HTPErrorCheckTxRequestFlags(HtpState *s, const htp_tx_t *tx) HTP_FLAGS_HOST_MISSING | HTP_FLAGS_HOST_AMBIGUOUS | HTP_FLAGS_HOSTU_INVALID | HTP_FLAGS_HOSTH_INVALID)) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud == NULL) - return; if (htp_tx_flags(tx) & HTP_FLAGS_REQUEST_INVALID_T_E) HTPSetEvent(s, htud, STREAM_TOSERVER, @@ -729,16 +706,12 @@ static inline void HTPErrorCheckTxRequestFlags(HtpState *s, const htp_tx_t *tx) } if (htp_tx_request_auth_type(tx) == HTP_AUTH_TYPE_UNRECOGNIZED) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud == NULL) - return; HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_AUTH_UNRECOGNIZED); } if (htp_tx_is_protocol_0_9(tx) && htp_tx_request_method_number(tx) == HTP_METHOD_UNKNOWN && (htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_INVALID || htp_tx_request_protocol_number(tx) == HTP_PROTOCOL_UNKNOWN)) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud == NULL) - return; HTPSetEvent(s, htud, STREAM_TOSERVER, HTP_LOG_CODE_REQUEST_LINE_INVALID); } } @@ -1539,9 +1512,6 @@ static int HTPCallbackResponseBodyData(const htp_connp_t *connp, htp_tx_data_t * hstate, d, htp_tx_data_data(d), (uint32_t)htp_tx_data_len(d)); HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - SCReturnInt(HTP_STATUS_OK); - } tx_ud->tx_data.updated_tc = true; SCTxDataUpdateFileFlags(&tx_ud->tx_data, hstate->state_data.file_flags); if (!tx_ud->request_body_init) { @@ -1650,23 +1620,34 @@ void HTPFreeConfig(void) static int HTPCallbackRequestHasTrailer(const htp_connp_t *connp, htp_tx_t *tx) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - htud->tx_data.updated_ts = true; - htud->request_has_trailers = 1; - } + htud->tx_data.updated_ts = true; + htud->request_has_trailers = 1; return HTP_STATUS_OK; } static int HTPCallbackResponseHasTrailer(const htp_connp_t *connp, htp_tx_t *tx) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - htud->tx_data.updated_tc = true; - htud->response_has_trailers = 1; - } + htud->tx_data.updated_tc = true; + htud->response_has_trailers = 1; return HTP_STATUS_OK; } +static void *HTPCallbackTxCreate(bool request) +{ + HtpTxUserData *tx_ud = HTPCalloc(1, sizeof(HtpTxUserData)); + if (unlikely(tx_ud == NULL)) { + return NULL; + } + if (request) { + // each http tx may xfer files + tx_ud->tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT; + } else { + tx_ud->tx_data.file_tx = STREAM_TOCLIENT; // Toserver already missed. + } + return tx_ud; +} + /**\internal * \brief called at start of request * Set min inspect size. @@ -1696,14 +1677,6 @@ static int HTPCallbackRequestStart(const htp_connp_t *connp, htp_tx_t *tx) hstate->cfg->request.inspect_min_size); HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - tx_ud = HTPCalloc(1, sizeof(HtpTxUserData)); - if (unlikely(tx_ud == NULL)) { - SCReturnInt(HTP_STATUS_OK); - } - tx_ud->tx_data.file_tx = STREAM_TOSERVER | STREAM_TOCLIENT; // each http tx may xfer files - htp_tx_set_user_data(tx, tx_ud); - } tx_ud->tx_data.updated_ts = true; SCReturnInt(HTP_STATUS_OK); } @@ -1736,15 +1709,6 @@ static int HTPCallbackResponseStart(const htp_connp_t *connp, htp_tx_t *tx) hstate->cfg->response.inspect_min_size); HtpTxUserData *tx_ud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - tx_ud = HTPCalloc(1, sizeof(HtpTxUserData)); - if (unlikely(tx_ud == NULL)) { - SCReturnInt(HTP_STATUS_OK); - } - tx_ud->tx_data.file_tx = - STREAM_TOCLIENT; // each http tx may xfer files. Toserver already missed. - htp_tx_set_user_data(tx, tx_ud); - } tx_ud->tx_data.updated_tc = true; SCReturnInt(HTP_STATUS_OK); } @@ -1795,16 +1759,14 @@ static int HTPCallbackRequestComplete(const htp_connp_t *connp, htp_tx_t *tx) HTPErrorCheckTxRequestFlags(hstate, tx); HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - htud->tx_data.updated_ts = true; - if (htud->tsflags & HTP_FILENAME_SET) { - SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER); - htud->tsflags &= ~HTP_FILENAME_SET; - if (abs_right_edge < (uint64_t)UINT32_MAX) { - StreamTcpReassemblySetMinInspectDepth( - hstate->f->protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge); - } + htud->tx_data.updated_ts = true; + if (htud->tsflags & HTP_FILENAME_SET) { + SCLogDebug("closing file that was being stored"); + (void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOSERVER); + htud->tsflags &= ~HTP_FILENAME_SET; + if (abs_right_edge < (uint64_t)UINT32_MAX) { + StreamTcpReassemblySetMinInspectDepth( + hstate->f->protoctx, STREAM_TOSERVER, (uint32_t)abs_right_edge); } } @@ -1851,13 +1813,11 @@ static int HTPCallbackResponseComplete(const htp_connp_t *connp, htp_tx_t *tx) } HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - htud->tx_data.updated_tc = true; - if (htud->tcflags & HTP_FILENAME_SET) { - SCLogDebug("closing file that was being stored"); - (void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOCLIENT); - htud->tcflags &= ~HTP_FILENAME_SET; - } + htud->tx_data.updated_tc = true; + if (htud->tcflags & HTP_FILENAME_SET) { + SCLogDebug("closing file that was being stored"); + (void)HTPFileClose(htud, NULL, 0, 0, STREAM_TOCLIENT); + htud->tcflags &= ~HTP_FILENAME_SET; } /* response done, do raw reassembly now to inspect state and stream @@ -1888,14 +1848,8 @@ static int HTPCallbackResponseComplete(const htp_connp_t *connp, htp_tx_t *tx) static int HTPCallbackRequestLine(const htp_connp_t *connp, htp_tx_t *tx) { - HtpTxUserData *tx_ud; HtpState *hstate = htp_connp_user_data(connp); - tx_ud = htp_tx_get_user_data(tx); - if (unlikely(tx_ud == NULL)) { - return HTP_STATUS_OK; - } - if (htp_tx_flags(tx)) { HTPErrorCheckTxRequestFlags(hstate, tx); } @@ -1910,9 +1864,6 @@ static int HTPCallbackRequestHeaderData(const htp_connp_t *connp, htp_tx_data_t return HTP_STATUS_OK; HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - return HTP_STATUS_OK; - } ptmp = HTPRealloc(tx_ud->request_headers_raw, tx_ud->request_headers_raw_len, tx_ud->request_headers_raw_len + htp_tx_data_len(tx_data)); if (ptmp == NULL) { @@ -1940,9 +1891,6 @@ static int HTPCallbackResponseHeaderData(const htp_connp_t *connp, htp_tx_data_t return HTP_STATUS_OK; HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud == NULL) { - return HTP_STATUS_OK; - } tx_ud->tx_data.updated_tc = true; ptmp = HTPRealloc(tx_ud->response_headers_raw, tx_ud->response_headers_raw_len, tx_ud->response_headers_raw_len + htp_tx_data_len(tx_data)); @@ -1989,6 +1937,9 @@ static void HTPConfigSetDefaultsPhase1(HTPCfgRec *cfg_prec) htp_config_register_request_body_data(cfg_prec->cfg, HTPCallbackRequestBodyData); htp_config_register_response_body_data(cfg_prec->cfg, HTPCallbackResponseBodyData); + htp_config_register_tx_create(cfg_prec->cfg, HTPCallbackTxCreate); + htp_config_register_tx_destroy(cfg_prec->cfg, HtpTxUserDataFree); + htp_config_register_request_start(cfg_prec->cfg, HTPCallbackRequestStart); htp_config_register_request_complete(cfg_prec->cfg, HTPCallbackRequestComplete); @@ -2494,12 +2445,10 @@ static AppLayerGetFileState HTPGetTxFiles(void *txv, uint8_t direction) AppLayerGetFileState files = { .fc = NULL, .cfg = &htp_sbcfg }; htp_tx_t *tx = (htp_tx_t *)txv; HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud) { - if (direction & STREAM_TOCLIENT) { - files.fc = &tx_ud->files_tc; - } else { - files.fc = &tx_ud->files_ts; - } + if (direction & STREAM_TOCLIENT) { + files.fc = &tx_ud->files_tc; + } else { + files.fc = &tx_ud->files_ts; } return files; } @@ -2581,10 +2530,7 @@ static AppLayerTxData *HTPGetTxData(void *vtx) { htp_tx_t *tx = (htp_tx_t *)vtx; HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud) { - return &tx_ud->tx_data; - } - return NULL; + return &tx_ud->tx_data; } static AppLayerStateData *HTPGetStateData(void *vstate) diff --git a/src/app-layer-parser.c b/src/app-layer-parser.c index 5b2b619860..9139b73db8 100644 --- a/src/app-layer-parser.c +++ b/src/app-layer-parser.c @@ -784,7 +784,7 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p break; AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx); - if (txd && tag_txs_as_inspected) { + if (tag_txs_as_inspected) { const uint8_t inspected_flag = (flags & STREAM_TOSERVER) ? APP_LAYER_TX_INSPECTED_TS : APP_LAYER_TX_INSPECTED_TC; if (txd->flags & inspected_flag) { @@ -824,22 +824,16 @@ void AppLayerParserSetTransactionInspectId(const Flow *f, AppLayerParserState *p /* txd can be NULL for HTTP sessions where the user data alloc failed */ AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx); - if (likely(txd)) { - const uint8_t inspected_flag = (flags & STREAM_TOSERVER) - ? APP_LAYER_TX_INSPECTED_TS - : APP_LAYER_TX_INSPECTED_TC; - if (txd->flags & inspected_flag) { - txd->flags |= inspected_flag; - SCLogDebug("%p/%" PRIu64 " out of order tx is done for direction %s. Flag %02x", - tx, idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", txd->flags); - - SCLogDebug("%p/%"PRIu64" out of order tx. Update inspect_id? %"PRIu64, - tx, idx, pstate->inspect_id[direction]); - if (pstate->inspect_id[direction]+1 == idx) - pstate->inspect_id[direction] = idx; - } - } else { - if (pstate->inspect_id[direction]+1 == idx) + const uint8_t inspected_flag = (flags & STREAM_TOSERVER) ? APP_LAYER_TX_INSPECTED_TS + : APP_LAYER_TX_INSPECTED_TC; + if (txd->flags & inspected_flag) { + txd->flags |= inspected_flag; + SCLogDebug("%p/%" PRIu64 " out of order tx is done for direction %s. Flag %02x", tx, + idx, flags & STREAM_TOSERVER ? "toserver" : "toclient", txd->flags); + + SCLogDebug("%p/%" PRIu64 " out of order tx. Update inspect_id? %" PRIu64, tx, idx, + pstate->inspect_id[direction]); + if (pstate->inspect_id[direction] + 1 == idx) pstate->inspect_id[direction] = idx; } if (!ires.has_next) @@ -868,7 +862,7 @@ AppLayerDecoderEvents *AppLayerParserGetEventsByTx(uint8_t ipproto, AppProto alp /* Access events via the tx_data. */ AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx); - if (txd != NULL && txd->events != NULL) { + if (txd->events != NULL) { ptr = txd->events; } @@ -953,7 +947,7 @@ void AppLayerParserTransactionsCleanup(Flow *f, const uint8_t pkt_dir) SCLogDebug("%p/%"PRIu64" checking", tx, i); AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx); - if (txd != NULL && AppLayerParserHasFilesInDir(txd, pkt_dir)) { + if (AppLayerParserHasFilesInDir(txd, pkt_dir)) { if (pkt_dir_trunc == -1) pkt_dir_trunc = IS_DISRUPTED( (pkt_dir == STREAM_TOSERVER) ? ts_disrupt_flags : tc_disrupt_flags); diff --git a/src/detect-config.c b/src/detect-config.c index d700e5d0f9..c1f0e10340 100644 --- a/src/detect-config.c +++ b/src/detect-config.c @@ -94,23 +94,18 @@ static void ConfigApplyTx(Flow *f, void *tx = AppLayerParserGetTx(f->proto, f->alproto, f->alstate, tx_id); if (tx) { AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx); - if (txd) { - SCLogDebug("tx %p txd %p: log_flags %x", tx, txd, txd->config.log_flags); - txd->config.log_flags |= BIT_U8(config->type); - - const bool unidir = - (txd->flags & (APP_LAYER_TX_SKIP_INSPECT_TS | APP_LAYER_TX_SKIP_INSPECT_TC)) != - 0; - if (unidir) { - SCLogDebug("handle unidir tx"); - AppLayerTxConfig req; - memset(&req, 0, sizeof(req)); - req.log_flags = BIT_U8(config->type); - AppLayerParserApplyTxConfig( - f->proto, f->alproto, f->alstate, tx, CONFIG_ACTION_SET, req); - } - } else { - SCLogDebug("no tx data"); + SCLogDebug("tx %p txd %p: log_flags %x", tx, txd, txd->config.log_flags); + txd->config.log_flags |= BIT_U8(config->type); + + const bool unidir = + (txd->flags & (APP_LAYER_TX_SKIP_INSPECT_TS | APP_LAYER_TX_SKIP_INSPECT_TC)) != 0; + if (unidir) { + SCLogDebug("handle unidir tx"); + AppLayerTxConfig req; + memset(&req, 0, sizeof(req)); + req.log_flags = BIT_U8(config->type); + AppLayerParserApplyTxConfig( + f->proto, f->alproto, f->alstate, tx, CONFIG_ACTION_SET, req); } } else { SCLogDebug("no tx"); diff --git a/src/detect-engine-state.c b/src/detect-engine-state.c index c1552ab893..f887cbfb36 100644 --- a/src/detect-engine-state.c +++ b/src/detect-engine-state.c @@ -219,11 +219,6 @@ void DetectRunStoreStateTx( const uint16_t file_no_match) { AppLayerTxData *tx_data = AppLayerParserGetTxData(f->proto, f->alproto, tx); - BUG_ON(tx_data == NULL); - if (tx_data == NULL) { - SCLogDebug("No TX data for %" PRIu64, tx_id); - return; - } if (tx_data->de_state == NULL) { tx_data->de_state = DetectEngineStateAlloc(); if (tx_data->de_state == NULL) diff --git a/src/detect-filestore.c b/src/detect-filestore.c index e93dcceabd..d281bbf2a1 100644 --- a/src/detect-filestore.c +++ b/src/detect-filestore.c @@ -159,15 +159,12 @@ static int FilestorePostMatchWithOptions(Packet *p, Flow *f, const DetectFilesto DEBUG_VALIDATE_BUG_ON(txv == NULL); if (txv != NULL) { AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, txv); - DEBUG_VALIDATE_BUG_ON(txd == NULL); - if (txd != NULL) { - if (toclient_dir) { - txd->file_flags |= FLOWFILE_STORE_TC; - } + if (toclient_dir) { + txd->file_flags |= FLOWFILE_STORE_TC; + } if (toserver_dir) { txd->file_flags |= FLOWFILE_STORE_TS; } - } } } else if (this_flow) { /* set in flow and AppLayerStateData */ diff --git a/src/detect-http-client-body.c b/src/detect-http-client-body.c index 2504f67fd8..35f8b976e9 100644 --- a/src/detect-http-client-body.c +++ b/src/detect-http-client-body.c @@ -182,11 +182,6 @@ static int DetectHttpClientBodySetupSticky(DetectEngineCtx *de_ctx, Signature *s static inline HtpBody *GetRequestBody(htp_tx_t *tx) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud == NULL) { - SCLogDebug("no htud"); - return NULL; - } - return &htud->request_body; } diff --git a/src/detect-http-header.c b/src/detect-http-header.c index 5a7536f819..094375f42e 100644 --- a/src/detect-http-header.c +++ b/src/detect-http-header.c @@ -274,9 +274,8 @@ static void PrefilterMpmHttpTrailer(DetectEngineThreadCtx *det_ctx, const void * htp_tx_t *tx = txv; const HtpTxUserData *htud = (const HtpTxUserData *)htp_tx_get_user_data(tx); /* if the request wasn't flagged as having a trailer, we skip */ - if (htud && ( - ((flags & STREAM_TOSERVER) && !htud->request_has_trailers) || - ((flags & STREAM_TOCLIENT) && !htud->response_has_trailers))) { + if (((flags & STREAM_TOSERVER) && !htud->request_has_trailers) || + ((flags & STREAM_TOCLIENT) && !htud->response_has_trailers)) { SCReturn; } PrefilterMpmHttpHeader(det_ctx, pectx, p, f, txv, idx, _txd, flags); diff --git a/src/detect-http-raw-header.c b/src/detect-http-raw-header.c index 8adc67be4a..0b4adef6fa 100644 --- a/src/detect-http-raw-header.c +++ b/src/detect-http-raw-header.c @@ -191,8 +191,6 @@ static InspectionBuffer *GetData(DetectEngineThreadCtx *det_ctx, htp_tx_t *tx = (htp_tx_t *)txv; HtpTxUserData *tx_ud = htp_tx_get_user_data(tx); - if (tx_ud == NULL) - return NULL; const bool ts = ((flow_flags & STREAM_TOSERVER) != 0); const uint8_t *data = ts ? @@ -280,9 +278,8 @@ static void PrefilterMpmHttpTrailerRaw(DetectEngineThreadCtx *det_ctx, const voi htp_tx_t *tx = txv; const HtpTxUserData *htud = (const HtpTxUserData *)htp_tx_get_user_data(tx); /* if the request wasn't flagged as having a trailer, we skip */ - if (htud && ( - ((flags & STREAM_TOSERVER) && !htud->request_has_trailers) || - ((flags & STREAM_TOCLIENT) && !htud->response_has_trailers))) { + if (((flags & STREAM_TOSERVER) && !htud->request_has_trailers) || + ((flags & STREAM_TOCLIENT) && !htud->response_has_trailers)) { SCReturn; } PrefilterMpmHttpHeaderRaw(det_ctx, pectx, p, f, txv, idx, _txd, flags); diff --git a/src/detect-xbits.c b/src/detect-xbits.c index 50f88144f4..ca24ca4738 100644 --- a/src/detect-xbits.c +++ b/src/detect-xbits.c @@ -224,9 +224,6 @@ static int DetectXbitTxMatch(DetectEngineThreadCtx *det_ctx, Flow *f, uint8_t fl BUG_ON(xd == NULL); AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, txv); - if (txd == NULL) { - return 0; - } SCLogDebug("sid:%u: tx:%" PRIu64 ", txd->txbits:%p", s->id, det_ctx->tx_id, txd->txbits); int r = TxBitIsset(txd, xd->idx); diff --git a/src/detect.c b/src/detect.c index d662e66e99..d0da677578 100644 --- a/src/detect.c +++ b/src/detect.c @@ -590,9 +590,8 @@ static bool IsOnlyTxInDirection(Flow *f, uint64_t txid, uint8_t dir) if (tx) { AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx); // test if the other tx is unidirectional in the other way - if (txd && ((dir == STREAM_TOSERVER && (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TS)) || - (dir == STREAM_TOCLIENT && - (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TC)))) { + if ((dir == STREAM_TOSERVER && (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TS)) || + (dir == STREAM_TOCLIENT && (txd->flags & APP_LAYER_TX_SKIP_INSPECT_TC))) { return true; } } @@ -1358,10 +1357,6 @@ static DetectTransaction GetDetectTx(const uint8_t ipproto, const AppProto alpro const uint64_t tx_id, void *tx_ptr, const int tx_end_state, const uint8_t flow_flags) { AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx_ptr); - if (unlikely(txd == NULL)) { - DetectTransaction no_tx = NO_TX; - return no_tx; - } const int tx_progress = AppLayerParserGetStateProgress(ipproto, alproto, tx_ptr, flow_flags); bool updated = (flow_flags & STREAM_TOSERVER) ? txd->updated_ts : txd->updated_tc; if (!updated && tx_progress < tx_end_state && ((flow_flags & STREAM_EOF) == 0)) { diff --git a/src/output-filedata.c b/src/output-filedata.c index fdff2d9781..476ab18a58 100644 --- a/src/output-filedata.c +++ b/src/output-filedata.c @@ -114,10 +114,8 @@ static void CloseFile(const Packet *p, Flow *f, File *file, void *txv) DEBUG_VALIDATE_BUG_ON((file->flags & FILE_STORED) != 0); AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, txv); - if (txd) { - BUG_ON(f->alproto == ALPROTO_SMB && txd->files_logged != 0); - txd->files_stored++; - } + BUG_ON(f->alproto == ALPROTO_SMB && txd->files_logged != 0); + txd->files_stored++; file->flags |= FILE_STORED; } diff --git a/src/output-json-http.c b/src/output-json-http.c index adf5234daf..95ca0cbdec 100644 --- a/src/output-json-http.c +++ b/src/output-json-http.c @@ -395,10 +395,8 @@ void EveHttpLogJSONBodyPrintable(SCJsonBuilder *js, Flow *f, uint64_t tx_id) htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id); if (tx) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - BodyPrintableBuffer(js, &htud->request_body, "http_request_body_printable"); - BodyPrintableBuffer(js, &htud->response_body, "http_response_body_printable"); - } + BodyPrintableBuffer(js, &htud->request_body, "http_request_body_printable"); + BodyPrintableBuffer(js, &htud->response_body, "http_response_body_printable"); } } } @@ -426,10 +424,8 @@ void EveHttpLogJSONBodyBase64(SCJsonBuilder *js, Flow *f, uint64_t tx_id) htp_tx_t *tx = AppLayerParserGetTx(IPPROTO_TCP, ALPROTO_HTTP1, htp_state, tx_id); if (tx) { HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); - if (htud != NULL) { - BodyBase64Buffer(js, &htud->request_body, "http_request_body"); - BodyBase64Buffer(js, &htud->response_body, "http_response_body"); - } + BodyBase64Buffer(js, &htud->request_body, "http_request_body"); + BodyBase64Buffer(js, &htud->response_body, "http_response_body"); } } } diff --git a/src/output-streaming.c b/src/output-streaming.c index 8f2f65ab20..51906dc9dd 100644 --- a/src/output-streaming.c +++ b/src/output-streaming.c @@ -178,19 +178,18 @@ static int HttpBodyIterator(Flow *f, int close, void *cbdata, uint8_t iflags) } SCLogDebug("tx %p", tx); - HtpTxUserData *htud = (HtpTxUserData *) htp_tx_get_user_data(tx); - if (htud != NULL) { - SCLogDebug("htud %p", htud); - HtpBody *body = NULL; - if (iflags & OUTPUT_STREAMING_FLAG_TOSERVER) - body = &htud->request_body; - else if (iflags & OUTPUT_STREAMING_FLAG_TOCLIENT) - body = &htud->response_body; - - if (body == NULL) { - SCLogDebug("no body"); - goto next; - } + HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx); + SCLogDebug("htud %p", htud); + HtpBody *body = NULL; + if (iflags & OUTPUT_STREAMING_FLAG_TOSERVER) + body = &htud->request_body; + else if (iflags & OUTPUT_STREAMING_FLAG_TOCLIENT) + body = &htud->response_body; + + if (body == NULL) { + SCLogDebug("no body"); + goto next; + } if (body->first == NULL) { SCLogDebug("no body chunks"); goto next; @@ -236,7 +235,6 @@ static int HttpBodyIterator(Flow *f, int close, void *cbdata, uint8_t iflags) Streamer(cbdata, f, NULL, 0, tx_id, iflags|OUTPUT_STREAMING_FLAG_CLOSE|OUTPUT_STREAMING_FLAG_TRANSACTION); } - } } return 0; } diff --git a/src/output-tx.c b/src/output-tx.c index a4da9d5e2f..9bc08ad45c 100644 --- a/src/output-tx.c +++ b/src/output-tx.c @@ -416,13 +416,6 @@ static TmEcode OutputTxLog(ThreadVars *tv, Packet *p, void *thread_data) SCLogDebug("STARTING tx_id %" PRIu64 ", tx %p", tx_id, tx); AppLayerTxData *txd = AppLayerParserGetTxData(ipproto, alproto, tx); - if (unlikely(txd == NULL)) { - SCLogDebug("NO TXD"); - /* make sure this tx, which can't be properly logged is skipped */ - logged = 1; - max_id = tx_id; - goto next_tx; - } const int tx_progress_ts = AppLayerParserGetStateProgress(ipproto, alproto, tx, ts_disrupt_flags); diff --git a/src/util-file.c b/src/util-file.c index fe1b4e7684..8fc8998bc7 100644 --- a/src/util-file.c +++ b/src/util-file.c @@ -1157,12 +1157,10 @@ void FileDisableStoringForTransaction(Flow *f, const uint8_t direction, void *tx { if (g_file_force_filestore == 0) { AppLayerTxData *txd = AppLayerParserGetTxData(f->proto, f->alproto, tx); - if (txd != NULL) { - if (direction & STREAM_TOSERVER) { - txd->file_flags |= FLOWFILE_NO_STORE_TS; - } else { - txd->file_flags |= FLOWFILE_NO_STORE_TC; - } + if (direction & STREAM_TOSERVER) { + txd->file_flags |= FLOWFILE_NO_STORE_TS; + } else { + txd->file_flags |= FLOWFILE_NO_STORE_TC; } } } diff --git a/src/util-lua-http.c b/src/util-lua-http.c index f92a706ac4..7849f4ae52 100644 --- a/src/util-lua-http.c +++ b/src/util-lua-http.c @@ -169,8 +169,6 @@ static int LuaHttpGetRawHeaders(lua_State *luastate, int dir) return 1; } HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx->tx); - if (htud == NULL) - return LuaCallbackError(luastate, "no htud in tx"); uint8_t *raw = htud->request_headers_raw; uint32_t raw_len = htud->request_headers_raw_len; @@ -245,8 +243,6 @@ static int LuaHttpGetBody(lua_State *luastate, int dir) } HtpTxUserData *htud = (HtpTxUserData *)htp_tx_get_user_data(tx->tx); - if (htud == NULL) - return LuaCallbackError(luastate, "no htud in tx"); HtpBody *body = NULL; if (dir == 0)