From: Jason Ish Date: Thu, 14 Oct 2021 18:37:03 +0000 (-0600) Subject: rust/app-layer: provide generic implementation of iterator X-Git-Tag: suricata-7.0.0-beta1~1210 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=049d43212ee7954dea43c5b71d8d2f184189aea5;p=thirdparty%2Fsuricata.git rust/app-layer: provide generic implementation of iterator Create traits for app-layer State and Transaction that allow a generic implementation of a transaction iterator that parser can use when the follow the common pattern for iterating transactions. Also convert DNS to use the generic for testing purposes. --- diff --git a/rust/src/applayer.rs b/rust/src/applayer.rs index 9518606cef..a9ac44394d 100644 --- a/rust/src/applayer.rs +++ b/rust/src/applayer.rs @@ -507,3 +507,43 @@ pub unsafe fn get_event_info_by_id( } return -1; } + +/// Transaction trait. +/// +/// This trait defines methods that a Transaction struct must implement +/// in order to define some generic helper functions. +pub trait Transaction { + fn id(&self) -> u64; +} + +pub trait State { + fn get_transactions(&self) -> &[Tx]; + + fn get_transaction_iterator(&self, min_tx_id: u64, state: &mut u64) -> AppLayerGetTxIterTuple { + let mut index = *state as usize; + let transactions = self.get_transactions(); + let len = transactions.len(); + while index < len { + let tx = &transactions[index]; + if tx.id() < min_tx_id + 1 { + index += 1; + continue; + } + *state = index as u64; + return AppLayerGetTxIterTuple::with_values( + tx as *const _ as *mut _, + tx.id() - 1, + len - index > 1, + ); + } + return AppLayerGetTxIterTuple::not_found(); + } +} + +pub unsafe extern "C" fn state_get_tx_iterator, Tx: Transaction>( + _ipproto: u8, _alproto: AppProto, state: *mut std::os::raw::c_void, min_tx_id: u64, + _max_tx_id: u64, istate: &mut u64, +) -> AppLayerGetTxIterTuple { + let state = cast_pointer!(state, S); + state.get_transaction_iterator(min_tx_id, istate) +} diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index ae7b06cf58..16b67cfa9c 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -236,6 +236,12 @@ pub struct DNSTransaction { pub tx_data: AppLayerTxData, } +impl Transaction for DNSTransaction { + fn id(&self) -> u64 { + self.id + } +} + impl DNSTransaction { pub fn new() -> Self { @@ -336,6 +342,12 @@ pub struct DNSState { gap: bool, } +impl State for DNSState { + fn get_transactions(&self) -> &[DNSTransaction] { + &self.transactions + } +} + impl DNSState { pub fn new() -> Self { @@ -991,7 +1003,7 @@ pub unsafe extern "C" fn rs_dns_udp_register_parser() { localstorage_new: None, localstorage_free: None, get_files: None, - get_tx_iterator: None, + get_tx_iterator: Some(crate::applayer::state_get_tx_iterator::), get_de_state: rs_dns_state_get_tx_detect_state, set_de_state: rs_dns_state_set_tx_detect_state, get_tx_data: rs_dns_state_get_tx_data, @@ -1037,7 +1049,7 @@ pub unsafe extern "C" fn rs_dns_tcp_register_parser() { localstorage_new: None, localstorage_free: None, get_files: None, - get_tx_iterator: None, + get_tx_iterator: Some(crate::applayer::state_get_tx_iterator::), get_de_state: rs_dns_state_get_tx_detect_state, set_de_state: rs_dns_state_set_tx_detect_state, get_tx_data: rs_dns_state_get_tx_data,