pcapsql_core/stream/
context.rs

1use std::collections::HashMap;
2use std::net::IpAddr;
3
4use crate::protocol::OwnedFieldValue;
5
6/// Direction of data flow in a TCP connection.
7#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
8pub enum Direction {
9    ToServer,
10    ToClient,
11}
12
13impl Direction {
14    /// Return a string representation of the direction.
15    pub fn as_str(&self) -> &'static str {
16        match self {
17            Direction::ToServer => "to_server",
18            Direction::ToClient => "to_client",
19        }
20    }
21}
22
23/// Context for stream parsing.
24#[derive(Debug, Clone)]
25pub struct StreamContext {
26    pub connection_id: u64,
27    pub direction: Direction,
28    pub src_ip: IpAddr,
29    pub dst_ip: IpAddr,
30    pub src_port: u16,
31    pub dst_port: u16,
32    /// Bytes already parsed from this stream
33    pub bytes_parsed: usize,
34    /// Messages already parsed from this stream
35    pub messages_parsed: usize,
36    /// ALPN protocol hint (from TLS handshake)
37    pub alpn: Option<String>,
38}
39
40/// Result of stream parsing.
41#[derive(Debug, Clone)]
42pub enum StreamParseResult {
43    /// Successfully parsed one or more messages.
44    Complete {
45        messages: Vec<ParsedMessage>,
46        bytes_consumed: usize,
47    },
48
49    /// Parser produced a transformed stream for child parsing (e.g., TLS decryption).
50    Transform {
51        child_protocol: &'static str,
52        child_data: Vec<u8>,
53        bytes_consumed: usize,
54        metadata: Option<ParsedMessage>,
55    },
56
57    /// Need more data before parsing can proceed.
58    NeedMore { minimum_bytes: Option<usize> },
59
60    /// This stream doesn't match our protocol.
61    NotThisProtocol,
62
63    /// Parse error - stream is malformed.
64    Error {
65        message: String,
66        skip_bytes: Option<usize>,
67    },
68}
69
70/// A parsed application-layer message.
71///
72/// All field values are owned since stream parsing may outlive the original packet data.
73/// Field names are always static strings from protocol definitions.
74#[derive(Debug, Clone)]
75pub struct ParsedMessage {
76    pub protocol: &'static str,
77    pub connection_id: u64,
78    pub message_id: u32,
79    pub direction: Direction,
80    pub frame_number: u64,
81    pub fields: HashMap<&'static str, OwnedFieldValue>,
82}