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.
pull/6629/head
Jason Ish 4 years ago committed by Victor Julien
parent 6d5f59696d
commit 049d43212e

@ -507,3 +507,43 @@ pub unsafe fn get_event_info_by_id<T: AppLayerEvent>(
}
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<Tx: Transaction> {
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<S: State<Tx>, 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)
}

@ -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<DNSTransaction> 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::<DNSState, DNSTransaction>),
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::<DNSState, DNSTransaction>),
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,

Loading…
Cancel
Save