use crate::event::{EndReason, FlowSide, FlowStats};
use crate::timestamp::Timestamp;
pub trait SessionParser: Send + 'static {
type Message: Send + 'static;
fn feed_initiator(&mut self, bytes: &[u8]) -> Vec<Self::Message>;
fn feed_responder(&mut self, bytes: &[u8]) -> Vec<Self::Message>;
fn fin_initiator(&mut self) -> Vec<Self::Message> {
Vec::new()
}
fn fin_responder(&mut self) -> Vec<Self::Message> {
Vec::new()
}
fn rst_initiator(&mut self) {}
fn rst_responder(&mut self) {}
}
pub trait SessionParserFactory<K>: Send + 'static {
type Parser: SessionParser;
fn new_parser(&mut self, key: &K) -> Self::Parser;
}
impl<K, P> SessionParserFactory<K> for P
where
P: SessionParser + Default + Clone,
{
type Parser = P;
fn new_parser(&mut self, _key: &K) -> P {
self.clone()
}
}
pub trait DatagramParser: Send + 'static {
type Message: Send + 'static;
fn parse(&mut self, payload: &[u8], side: FlowSide) -> Vec<Self::Message>;
}
pub trait DatagramParserFactory<K>: Send + 'static {
type Parser: DatagramParser;
fn new_parser(&mut self, key: &K) -> Self::Parser;
}
impl<K, P> DatagramParserFactory<K> for P
where
P: DatagramParser + Default + Clone,
{
type Parser = P;
fn new_parser(&mut self, _key: &K) -> P {
self.clone()
}
}
#[derive(Debug, Clone)]
pub enum SessionEvent<K, M> {
Started { key: K, ts: Timestamp },
Application {
key: K,
side: FlowSide,
message: M,
ts: Timestamp,
},
Closed {
key: K,
reason: EndReason,
stats: FlowStats,
},
}
#[cfg(test)]
mod tests {
use super::*;
#[derive(Default, Clone)]
struct CountParser {
init_bytes: usize,
resp_bytes: usize,
}
impl SessionParser for CountParser {
type Message = (FlowSide, usize);
fn feed_initiator(&mut self, b: &[u8]) -> Vec<Self::Message> {
self.init_bytes += b.len();
vec![(FlowSide::Initiator, self.init_bytes)]
}
fn feed_responder(&mut self, b: &[u8]) -> Vec<Self::Message> {
self.resp_bytes += b.len();
vec![(FlowSide::Responder, self.resp_bytes)]
}
}
#[test]
fn auto_impl_session_parser_factory() {
let mut f: CountParser = CountParser::default();
let mut p: CountParser = SessionParserFactory::<u32>::new_parser(&mut f, &7);
let m = p.feed_initiator(b"abc");
assert_eq!(m, vec![(FlowSide::Initiator, 3)]);
}
#[derive(Default, Clone)]
struct EchoDgram;
impl DatagramParser for EchoDgram {
type Message = (FlowSide, Vec<u8>);
fn parse(&mut self, payload: &[u8], side: FlowSide) -> Vec<Self::Message> {
vec![(side, payload.to_vec())]
}
}
#[test]
fn auto_impl_datagram_parser_factory() {
let mut f = EchoDgram;
let mut p: EchoDgram = DatagramParserFactory::<()>::new_parser(&mut f, &());
let m = p.parse(b"hello", FlowSide::Responder);
assert_eq!(m, vec![(FlowSide::Responder, b"hello".to_vec())]);
}
}