#![deny(missing_docs)]
use crate::{
config::{Config, HtpServerPersonality, HtpUrlEncodingHandling},
- hook::{DataExternalCallbackFn, TxExternalCallbackFn},
+ hook::{DataExternalCallbackFn, TxCreateCallbackFn, TxDestroyCallbackFn, TxExternalCallbackFn},
HtpStatus,
};
use std::convert::TryInto;
}
}
+/// 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
.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.
HtpStatus,
};
+use crate::hook::{TxCreateCallbackFn, TxDestroyCallbackFn};
+
#[cfg(test)]
use crate::hook::{DataNativeCallbackFn, TxNativeCallbackFn};
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<TxCreateCallbackFn>,
+ /// Transaction destroy hook.
+ /// Used by suricata to free its transaction (user data)
+ pub(crate) hook_tx_destroy: Option<TxDestroyCallbackFn>,
/// 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.
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(),
/// Hook for Transaction
pub(crate) type TxHook = Hook<TxExternalCallbackFn, TxNativeCallbackFn>;
+/// 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;
use crate::{
bstr::Bstr,
+ c_api::transaction::htp_tx_get_user_data,
config::{Config, HtpUnwanted},
connection_parser::ParserData,
decompressors::{Decompressor, HtpContentEncoding},
}
}
+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<Self> {
+ let mut tx = Self {
logger: logger.clone(),
cfg,
user_data: None,
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?
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
}
}
}
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
}
}
}
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);
}
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);
/* 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);
}
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);
}
}
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;
}
}
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,
}
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);
}
}
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) {
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.
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);
}
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);
}
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);
}
}
}
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
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);
}
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) {
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));
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);
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;
}
{
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)
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) {
/* 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)
/* 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;
}
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);
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");
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)
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 */
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;
}
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);
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 ?
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);
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);
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;
}
}
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)) {
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;
}
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");
}
}
}
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");
}
}
}
}
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;
Streamer(cbdata, f, NULL, 0, tx_id,
iflags|OUTPUT_STREAMING_FLAG_CLOSE|OUTPUT_STREAMING_FLAG_TRANSACTION);
}
- }
}
return 0;
}
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);
{
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;
}
}
}
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;
}
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)