From 5e0abf1572b6bddd06a5e30233e90f25e0874dc1 Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Fri, 29 May 2026 14:24:42 -0600 Subject: [PATCH] rust/ffi: use ThreadVars wrapper in flow callbacks Update the flow init, update and finish callback registrations to pass the safe ThreadVars wrapper instead of a raw pointer. Ticket: #8598 --- .../extending/flow-lifecycle-callbacks.rst | 9 ++--- examples/plugins/rust/src/mod.rs | 6 ++-- rust/ffi/src/flow.rs | 33 +++++++++++-------- 3 files changed, 27 insertions(+), 21 deletions(-) diff --git a/doc/userguide/devguide/extending/flow-lifecycle-callbacks.rst b/doc/userguide/devguide/extending/flow-lifecycle-callbacks.rst index ff1195ce3a..a11f945fc3 100644 --- a/doc/userguide/devguide/extending/flow-lifecycle-callbacks.rst +++ b/doc/userguide/devguide/extending/flow-lifecycle-callbacks.rst @@ -104,18 +104,19 @@ The Rust wrappers register closures or function items and return .. code-block:: rust - use suricata_ffi::flow::{self, Flow, Packet, ThreadVars}; + use suricata_ffi::flow::{self, Flow, Packet}; + use suricata_ffi::thread::ThreadVars; use suricata_ffi::SCLogNotice; - fn flow_init(_tv: *mut ThreadVars, f: *mut Flow, _p: *const Packet) { + fn flow_init(_tv: &mut ThreadVars, f: *mut Flow, _p: *const Packet) { SCLogNotice!("flow initialized: {:p}", f); } - fn flow_update(_tv: *mut ThreadVars, f: *mut Flow, p: *mut Packet) { + fn flow_update(_tv: &mut ThreadVars, f: *mut Flow, p: *mut Packet) { SCLogNotice!("flow updated: {:p} packet: {:p}", f, p); } - fn flow_finish(_tv: *mut ThreadVars, f: *mut Flow) { + fn flow_finish(_tv: &mut ThreadVars, f: *mut Flow) { SCLogNotice!("flow finished: {:p}", f); } diff --git a/examples/plugins/rust/src/mod.rs b/examples/plugins/rust/src/mod.rs index bdd112c4c4..4fd012bb25 100644 --- a/examples/plugins/rust/src/mod.rs +++ b/examples/plugins/rust/src/mod.rs @@ -73,11 +73,11 @@ fn on_thread_init(tv: &mut ThreadVars) { ); } -fn log_flow_init(_tv: *mut sys::ThreadVars, _f: *mut Flow, _p: *const Packet) { +fn log_flow_init(_tv: &mut ThreadVars, _f: *mut Flow, _p: *const Packet) { SCLogNotice!("rust example flow init callback: flow={:p}", _f); } -fn log_flow_update(_tv: *mut sys::ThreadVars, _f: *mut Flow, _p: *mut Packet) { +fn log_flow_update(_tv: &mut ThreadVars, _f: *mut Flow, _p: *mut Packet) { SCLogNotice!( "rust example flow update callback: flow={:p}, packet={:p}", _f, @@ -85,7 +85,7 @@ fn log_flow_update(_tv: *mut sys::ThreadVars, _f: *mut Flow, _p: *mut Packet) { ); } -fn log_flow_finish(_tv: *mut sys::ThreadVars, _f: *mut Flow) { +fn log_flow_finish(_tv: &mut ThreadVars, _f: *mut Flow) { SCLogNotice!("rust example flow finish callback: flow={:p}", _f); } diff --git a/rust/ffi/src/flow.rs b/rust/ffi/src/flow.rs index 91f22eca3c..0b59b1683b 100644 --- a/rust/ffi/src/flow.rs +++ b/rust/ffi/src/flow.rs @@ -17,11 +17,13 @@ use std::os::raw::c_void; -use suricata_sys::sys::{Flow, Packet, ThreadVars}; use suricata_sys::sys::{ - SCFlowRegisterFinishCallback, SCFlowRegisterInitCallback, SCFlowRegisterUpdateCallback, + self, Flow, Packet, SCFlowRegisterFinishCallback, SCFlowRegisterInitCallback, + SCFlowRegisterUpdateCallback, }; +use crate::thread::ThreadVars; + /// Register a flow initialization callback. /// /// The callback is invoked whenever Suricata initializes a flow. It receives: @@ -37,7 +39,7 @@ use suricata_sys::sys::{ /// The callback must not panic. pub fn register_init_callback(callback: F) -> Result<(), &'static str> where - F: Fn(*mut ThreadVars, *mut Flow, *const Packet) + Send + Sync + 'static, + F: Fn(&mut ThreadVars, *mut Flow, *const Packet) + Send + Sync + 'static, { let user = Box::into_raw(Box::new(callback)) as *mut c_void; if unsafe { SCFlowRegisterInitCallback(Some(init_callback_wrapper::), user) } { @@ -66,7 +68,7 @@ where /// The callback must not panic. pub fn register_update_callback(callback: F) -> Result<(), &'static str> where - F: Fn(*mut ThreadVars, *mut Flow, *mut Packet) + Send + Sync + 'static, + F: Fn(&mut ThreadVars, *mut Flow, *mut Packet) + Send + Sync + 'static, { let user = Box::into_raw(Box::new(callback)) as *mut c_void; if unsafe { SCFlowRegisterUpdateCallback(Some(update_callback_wrapper::), user) } { @@ -93,7 +95,7 @@ where /// The callback must not panic. pub fn register_finish_callback(callback: F) -> Result<(), &'static str> where - F: Fn(*mut ThreadVars, *mut Flow) + Send + Sync + 'static, + F: Fn(&mut ThreadVars, *mut Flow) + Send + Sync + 'static, { let user = Box::into_raw(Box::new(callback)) as *mut c_void; if unsafe { SCFlowRegisterFinishCallback(Some(finish_callback_wrapper::), user) } { @@ -107,28 +109,31 @@ where } unsafe extern "C" fn init_callback_wrapper( - tv: *mut ThreadVars, f: *mut Flow, p: *const Packet, user: *mut c_void, + tv: *mut sys::ThreadVars, f: *mut Flow, p: *const Packet, user: *mut c_void, ) where - F: Fn(*mut ThreadVars, *mut Flow, *const Packet) + Send + Sync + 'static, + F: Fn(&mut ThreadVars, *mut Flow, *const Packet) + Send + Sync + 'static, { let callback = &*(user as *const F); - callback(tv, f, p); + let mut tv = ThreadVars::from_ptr(tv); + callback(&mut tv, f, p); } unsafe extern "C" fn update_callback_wrapper( - tv: *mut ThreadVars, f: *mut Flow, p: *mut Packet, user: *mut c_void, + tv: *mut sys::ThreadVars, f: *mut Flow, p: *mut Packet, user: *mut c_void, ) where - F: Fn(*mut ThreadVars, *mut Flow, *mut Packet) + Send + Sync + 'static, + F: Fn(&mut ThreadVars, *mut Flow, *mut Packet) + Send + Sync + 'static, { let callback = &*(user as *const F); - callback(tv, f, p); + let mut tv = ThreadVars::from_ptr(tv); + callback(&mut tv, f, p); } unsafe extern "C" fn finish_callback_wrapper( - tv: *mut ThreadVars, f: *mut Flow, user: *mut c_void, + tv: *mut sys::ThreadVars, f: *mut Flow, user: *mut c_void, ) where - F: Fn(*mut ThreadVars, *mut Flow) + Send + Sync + 'static, + F: Fn(&mut ThreadVars, *mut Flow) + Send + Sync + 'static, { let callback = &*(user as *const F); - callback(tv, f); + let mut tv = ThreadVars::from_ptr(tv); + callback(&mut tv, f); }