From 71905d3f7e8e781fd69792378a4d0f6fa5958136 Mon Sep 17 00:00:00 2001 From: Thea Rossman Date: Fri, 26 Jun 2026 14:33:20 -0700 Subject: [PATCH 1/5] run update_body before adding more predicates in compiler --- compiler/src/state_filters.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/compiler/src/state_filters.rs b/compiler/src/state_filters.rs index 1e6e4308..d1ac6a7b 100644 --- a/compiler/src/state_filters.rs +++ b/compiler/src/state_filters.rs @@ -244,8 +244,8 @@ fn add_unary_pred( }; let mut body: Vec = vec![]; - gen_state_filter_util(&mut body, node, tree, statics, sub, extract_sessions); update_body(&mut body, node, sub); + gen_state_filter_util(&mut body, node, tree, statics, sub, extract_sessions); if first_unary { code.push(quote! { @@ -304,8 +304,8 @@ fn add_pred( extract_sessions: bool, ) { let mut body: Vec = vec![]; - gen_state_filter_util(&mut body, node, tree, statics, sub, extract_sessions); update_body(&mut body, node, sub); + gen_state_filter_util(&mut body, node, tree, statics, sub, extract_sessions); if node.if_else { code.push(quote! { else if #pred_tokenstream { From 0379bfc6dc184ccf250c3002a5ad85e711d3b8a4 Mon Sep 17 00:00:00 2001 From: Thea Rossman Date: Thu, 9 Jul 2026 16:08:03 -0700 Subject: [PATCH 2/5] include TLS state in handshake data --- core/src/protocols/stream/tls/mod.rs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/core/src/protocols/stream/tls/mod.rs b/core/src/protocols/stream/tls/mod.rs index 41776955..ee5809dd 100644 --- a/core/src/protocols/stream/tls/mod.rs +++ b/core/src/protocols/stream/tls/mod.rs @@ -9,6 +9,12 @@ use itertools::Itertools; use serde::Serialize; use tls_parser::{TlsCipherSuite, TlsState}; +/// Serializes [`TlsState`] using its `Debug` representation, since the upstream `tls-parser` +/// crate does not implement `Serialize` for it. +fn serialize_state(state: &TlsState, s: S) -> Result { + s.serialize_str(&format!("{:?}", state)) +} + /// GREASE values. See [RFC 8701](https://datatracker.ietf.org/doc/html/rfc8701). const GREASE_TABLE: &[u16] = &[ 0x0a0a, 0x1a1a, 0x2a2a, 0x3a3a, 0x4a4a, 0x5a5a, 0x6a6a, 0x7a7a, 0x8a8a, 0x9a9a, 0xaaaa, 0xbaba, @@ -34,7 +40,7 @@ pub struct Tls { pub client_key_exchange: Option, /// TLS state. - #[serde(skip)] + #[serde(serialize_with = "serialize_state")] state: TlsState, /// TCP chunks defragmentation buffer. Defragments TCP segments that arrive over multiple /// packets. @@ -139,6 +145,17 @@ impl Tls { } } + /// Returns `true` if the handshake state machine encountered an invalid or out-of-order + /// message sequence. + /// + /// ## Remarks + /// A handshake can still be fully parsed (e.g. a valid ClientHello/SNI) even if a later + /// message renders the overall state invalid, so this should be checked in addition to + /// inspecting the parsed handshake contents. + pub fn is_invalid(&self) -> bool { + self.state == TlsState::Invalid + } + /// Returns the name of the server the client is trying to connect to. /// /// ## Remarks From c61399e9becc590805e2a0e2b8905d501b072bbb Mon Sep 17 00:00:00 2001 From: Thea Rossman Date: Fri, 17 Jul 2026 16:46:24 -0700 Subject: [PATCH 3/5] Fix TLS 1.3 handshake incorrectly marked invalid The tls-parser state table only reaches the "session now encrypted" bypass state directly from ServerHello; we need to add handling for ClientChangeCipherSpec added in RFC 8446 Appendix D.4. Co-Authored-By: Claude Sonnet 5 --- core/src/protocols/stream/tls/parser.rs | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-) diff --git a/core/src/protocols/stream/tls/parser.rs b/core/src/protocols/stream/tls/parser.rs index 6cf28251..59fae247 100644 --- a/core/src/protocols/stream/tls/parser.rs +++ b/core/src/protocols/stream/tls/parser.rs @@ -368,7 +368,18 @@ impl Tls { } // update state machine - match tls_state_transition(self.state, msg, direction) { + // + // Note: `tls_state_transition` from the `tls-parser` crate + // doesn't handle the TLS 1.3 middlebox-compatibility ChangeCipherSpec + // transition (RFC 8446). + let transition = if self.state == TlsState::ServerHello + && matches!(msg, TlsMessage::ChangeCipherSpec) + { + Ok(TlsState::ClientChangeCipherSpec) + } else { + tls_state_transition(self.state, msg, direction) + }; + match transition { Ok(s) => self.state = s, Err(_) => { self.state = TlsState::Invalid; @@ -540,4 +551,4 @@ impl Tls { } status } -} +} \ No newline at end of file From 8bf2591928d69190baa8a95f87f4f56226e1020b Mon Sep 17 00:00:00 2001 From: Thea Rossman Date: Wed, 22 Jul 2026 14:34:43 -0700 Subject: [PATCH 4/5] fmt --- core/src/protocols/stream/tls/parser.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/core/src/protocols/stream/tls/parser.rs b/core/src/protocols/stream/tls/parser.rs index 59fae247..2be1949f 100644 --- a/core/src/protocols/stream/tls/parser.rs +++ b/core/src/protocols/stream/tls/parser.rs @@ -372,13 +372,12 @@ impl Tls { // Note: `tls_state_transition` from the `tls-parser` crate // doesn't handle the TLS 1.3 middlebox-compatibility ChangeCipherSpec // transition (RFC 8446). - let transition = if self.state == TlsState::ServerHello - && matches!(msg, TlsMessage::ChangeCipherSpec) - { - Ok(TlsState::ClientChangeCipherSpec) - } else { - tls_state_transition(self.state, msg, direction) - }; + let transition = + if self.state == TlsState::ServerHello && matches!(msg, TlsMessage::ChangeCipherSpec) { + Ok(TlsState::ClientChangeCipherSpec) + } else { + tls_state_transition(self.state, msg, direction) + }; match transition { Ok(s) => self.state = s, Err(_) => { @@ -551,4 +550,4 @@ impl Tls { } status } -} \ No newline at end of file +} From f445d7c9764fd5cd91af4df80d1d52fa2fdd2901 Mon Sep 17 00:00:00 2001 From: Thea Rossman Date: Wed, 22 Jul 2026 15:28:42 -0700 Subject: [PATCH 5/5] clippy --- core/src/filter/ptree.rs | 2 +- core/src/multicore/channel_dispatcher.rs | 2 +- core/src/runtime/online.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/core/src/filter/ptree.rs b/core/src/filter/ptree.rs index d21bda7a..b0626881 100644 --- a/core/src/filter/ptree.rs +++ b/core/src/filter/ptree.rs @@ -1200,7 +1200,7 @@ impl PTree { impl fmt::Display for PTree { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Tree {:?}\n,{}", &self.filter_layer, self.pprint())?; + write!(f, "Tree {:?}\n,{}", self.filter_layer, self.pprint())?; Ok(()) } } diff --git a/core/src/multicore/channel_dispatcher.rs b/core/src/multicore/channel_dispatcher.rs index ac28065c..b63ddf7c 100644 --- a/core/src/multicore/channel_dispatcher.rs +++ b/core/src/multicore/channel_dispatcher.rs @@ -143,7 +143,7 @@ impl ChannelDispatcher { match &mut *channels { Channels::PerCore(map) => { - for (_, (sender_result, _)) in map.iter_mut() { + for (sender_result, _) in map.values_mut() { *sender_result = None; } } diff --git a/core/src/runtime/online.rs b/core/src/runtime/online.rs index 82672352..c57ef853 100644 --- a/core/src/runtime/online.rs +++ b/core/src/runtime/online.rs @@ -74,7 +74,7 @@ where log::info!("Initializing RX Cores..."); let mut rx_cores: BTreeMap> = BTreeMap::new(); let mut core_map: BTreeMap> = BTreeMap::new(); - for (_port_id, port) in ports.iter() { + for port in ports.values() { for (rxqueue, core_id) in port.queue_map.iter() { core_map.entry(*core_id).or_default().push(*rxqueue); } @@ -107,7 +107,7 @@ where self.start_ports(); log::info!("Launching RX cores..."); - for (core_id, _rx_core) in self.rx_cores.iter() { + for core_id in self.rx_cores.keys() { let role = unsafe { dpdk::rte_eal_lcore_role(core_id.raw()) }; if role != dpdk::rte_lcore_role_t_ROLE_RTE { log::error!("Attempted to launch non-DPDK core");