From b90adcc2bb0a64633bf744cc7005c6b8e9efb188 Mon Sep 17 00:00:00 2001 From: Philippe Antoine Date: Mon, 11 May 2026 22:44:58 +0200 Subject: [PATCH] rust/ffi: move AppLayerTxData to ffi Ticket: 7666 --- rust/Cargo.toml.in | 1 + rust/ffi/Cargo.toml.in | 1 + rust/ffi/cbindgen.toml | 2 +- rust/ffi/src/applayer.rs | 96 +++++++++++++++++++++++++++++++++++++++- rust/src/applayer.rs | 94 +-------------------------------------- 5 files changed, 99 insertions(+), 95 deletions(-) diff --git a/rust/Cargo.toml.in b/rust/Cargo.toml.in index f1eb9d2efa..6184c26220 100644 --- a/rust/Cargo.toml.in +++ b/rust/Cargo.toml.in @@ -95,3 +95,4 @@ htp = { package = "suricata-htp", path = "./htp", version = "@PACKAGE_VERSION@" [dev-dependencies] test-case = "~3.3.1" +suricata-ffi = { path = "./ffi", version = "@PACKAGE_VERSION@", features = ["testing"] } diff --git a/rust/ffi/Cargo.toml.in b/rust/ffi/Cargo.toml.in index cd8d48a2de..99977d4bdf 100644 --- a/rust/ffi/Cargo.toml.in +++ b/rust/ffi/Cargo.toml.in @@ -11,3 +11,4 @@ suricata-sys = { path = "../sys" } [features] debug = [] debug-validate = [] +testing = [] diff --git a/rust/ffi/cbindgen.toml b/rust/ffi/cbindgen.toml index 5625a6a365..10364e0ada 100644 --- a/rust/ffi/cbindgen.toml +++ b/rust/ffi/cbindgen.toml @@ -17,4 +17,4 @@ exclude = [ "IPPROTO_UDP", ] -item_types = ["constants"] +item_types = ["constants", "functions"] diff --git a/rust/ffi/src/applayer.rs b/rust/ffi/src/applayer.rs index 7b0f9c927c..b45918aa3a 100644 --- a/rust/ffi/src/applayer.rs +++ b/rust/ffi/src/applayer.rs @@ -17,7 +17,8 @@ //! App-layer utils. -use crate::cast_pointer; +use crate::direction::Direction; +use crate::{cast_pointer, SCLogDebug}; use std::ffi::CStr; pub use suricata_sys::sys::AppLayerEventType; use suricata_sys::sys::{ @@ -340,3 +341,96 @@ pub unsafe fn get_event_info_by_id( } -1 } + +#[cfg(not(any(test, feature = "testing")))] +use suricata_sys::sys::{SCAppLayerDecoderEventsSetEventRaw, SCAppLayerTxDataCleanup}; + +#[derive(Debug, Default, Eq, PartialEq)] +pub struct AppLayerTxData(pub suricata_sys::sys::AppLayerTxData); + +impl AppLayerTxData { + /// Create new AppLayerTxData for a transaction that covers both + /// directions. + pub fn new() -> Self { + Self(suricata_sys::sys::AppLayerTxData { + updated_tc: true, + updated_ts: true, + ..Default::default() + }) + } + + /// Create new AppLayerTxData for a transaction in a single + /// direction. + pub fn for_direction(direction: Direction) -> Self { + let (flags, updated_ts, updated_tc) = match direction { + Direction::ToServer => (APP_LAYER_TX_SKIP_INSPECT_TC, true, false), + Direction::ToClient => (APP_LAYER_TX_SKIP_INSPECT_TS, false, true), + }; + Self(suricata_sys::sys::AppLayerTxData { + updated_tc, + updated_ts, + flags, + ..Default::default() + }) + } + + pub fn init_files_opened(&mut self) { + self.0.files_opened = 1; + } + + pub fn incr_files_opened(&mut self) { + self.0.files_opened += 1; + } + + pub fn set_event(&mut self, _event: u8) { + #[cfg(not(any(test, feature = "testing")))] + unsafe { + SCAppLayerDecoderEventsSetEventRaw(&mut self.0.events, _event); + } + } + + pub fn update_file_flags(&mut self, state_flags: u16) { + unsafe { + SCTxDataUpdateFileFlags(&mut self.0, state_flags); + } + } +} + +impl Drop for AppLayerTxData { + fn drop(&mut self) { + #[cfg(not(any(test, feature = "testing")))] + unsafe { + SCAppLayerTxDataCleanup(&mut self.0); + } + } +} + +/// # Safety +/// +/// the caller must provide a valid AppLayerTxData pointer +#[no_mangle] +pub unsafe extern "C" fn SCTxDataUpdateFileFlags( + txd: &mut suricata_sys::sys::AppLayerTxData, state_flags: u16, +) { + if (txd.file_flags & state_flags) != state_flags { + SCLogDebug!( + "updating tx file_flags {:04x} with state flags {:04x}", + txd.file_flags, + state_flags + ); + let mut nf = state_flags; + // With keyword filestore:both,flow : + // There may be some opened unclosed file in one direction without filestore + // As such it has tx file_flags had FLOWFILE_NO_STORE_TS or TC + // But a new file in the other direction may trigger filestore:both,flow + // And thus set state_flags FLOWFILE_STORE_TS + // If the file was opened without storing it, do not try to store just the end of it + if (txd.file_flags & FLOWFILE_NO_STORE_TS) != 0 && (state_flags & FLOWFILE_STORE_TS) != 0 { + nf &= !FLOWFILE_STORE_TS; + } + if (txd.file_flags & FLOWFILE_NO_STORE_TC) != 0 && (state_flags & FLOWFILE_STORE_TC) != 0 { + nf &= !FLOWFILE_STORE_TC; + } + txd.file_flags |= nf; + } +} diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 67b5f3c949..91a213a352 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -35,103 +35,11 @@ pub use suricata_sys::sys::{ AppLayerTxConfig, StreamSlice, }; -#[cfg(not(test))] -use suricata_sys::sys::SCAppLayerDecoderEventsSetEventRaw; - pub use suricata_ffi::cast_pointer; -#[derive(Debug, Default, Eq, PartialEq)] -pub struct AppLayerTxData(pub suricata_sys::sys::AppLayerTxData); - -impl AppLayerTxData { - /// Create new AppLayerTxData for a transaction that covers both - /// directions. - pub fn new() -> Self { - Self (suricata_sys::sys::AppLayerTxData { - updated_tc: true, - updated_ts: true, - ..Default::default() - }) - } - - /// Create new AppLayerTxData for a transaction in a single - /// direction. - pub fn for_direction(direction: Direction) -> Self { - let (flags, updated_ts, updated_tc) = match direction { - Direction::ToServer => (APP_LAYER_TX_SKIP_INSPECT_TC, true, false), - Direction::ToClient => (APP_LAYER_TX_SKIP_INSPECT_TS, false, true), - }; - Self (suricata_sys::sys::AppLayerTxData{ - updated_tc, - updated_ts, - flags, - ..Default::default() - }) - } - - pub fn init_files_opened(&mut self) { - self.0.files_opened = 1; - } - - pub fn incr_files_opened(&mut self) { - self.0.files_opened += 1; - } - - pub fn set_event(&mut self, _event: u8) { - #[cfg(not(test))] - unsafe { - SCAppLayerDecoderEventsSetEventRaw(&mut self.0.events, _event); - } - } - - pub fn update_file_flags(&mut self, state_flags: u16) { - unsafe { - SCTxDataUpdateFileFlags(&mut self.0, state_flags); - } - } -} - -#[cfg(not(test))] -use suricata_sys::sys::SCAppLayerTxDataCleanup; - -impl Drop for AppLayerTxData { - fn drop(&mut self) { - #[cfg(not(test))] - unsafe { - SCAppLayerTxDataCleanup(&mut self.0); - } - } -} - - -pub use suricata_ffi::applayer::{ - FLOWFILE_NO_STORE_TS, FLOWFILE_NO_STORE_TC, FLOWFILE_STORE_TS, FLOWFILE_STORE_TC, -}; - -#[no_mangle] -pub unsafe extern "C" fn SCTxDataUpdateFileFlags(txd: &mut suricata_sys::sys::AppLayerTxData, state_flags: u16) { - if (txd.file_flags & state_flags) != state_flags { - SCLogDebug!("updating tx file_flags {:04x} with state flags {:04x}", txd.file_flags, state_flags); - let mut nf = state_flags; - // With keyword filestore:both,flow : - // There may be some opened unclosed file in one direction without filestore - // As such it has tx file_flags had FLOWFILE_NO_STORE_TS or TC - // But a new file in the other direction may trigger filestore:both,flow - // And thus set state_flags FLOWFILE_STORE_TS - // If the file was opened without storing it, do not try to store just the end of it - if (txd.file_flags & FLOWFILE_NO_STORE_TS) != 0 && (state_flags & FLOWFILE_STORE_TS) != 0 { - nf &= !FLOWFILE_STORE_TS; - } - if (txd.file_flags & FLOWFILE_NO_STORE_TC) != 0 && (state_flags & FLOWFILE_STORE_TC) != 0 { - nf &= !FLOWFILE_STORE_TC; - } - txd.file_flags |= nf; - } -} - pub use suricata_ffi::{export_tx_data_get, export_state_data_get}; -pub use suricata_ffi::applayer::{AppLayerEvent, AppLayerEventType, AppLayerResultRust, StreamSliceRust}; +pub use suricata_ffi::applayer::{AppLayerEvent, AppLayerEventType, AppLayerResultRust, AppLayerTxData, StreamSliceRust}; /// Rust parser declaration #[repr(C)]