iris_core/conntrack/conn/
conn_info.rs1#![doc(hidden)]
2use super::conn_actions::TrackedActions;
4use crate::lcore::CoreId;
5use crate::protocols::packet::tcp::TCP_PROTOCOL;
6use crate::protocols::stream::{ConnData, ParserRegistry};
7use crate::subscription::{Subscription, Trackable};
8use crate::FiveTuple;
9use crate::L4Pdu;
10
11use super::{conn_layers::*, conn_state::*};
12
13#[derive(Debug)]
20pub struct ConnInfo<T>
21where
22 T: Trackable,
23{
24 pub linfo: LayerInfo,
27 pub cdata: ConnData,
30 pub layers: [Layer; NUM_LAYERS],
33 pub tracked: T,
35}
36
37impl<T> ConnInfo<T>
38where
39 T: Trackable,
40{
41 pub(super) fn new(pdu: &L4Pdu, core_id: CoreId) -> Self {
42 let five_tuple = FiveTuple::from_ctxt(&pdu.ctxt);
43 ConnInfo {
44 linfo: LayerInfo {
45 state: if pdu.ctxt.proto == TCP_PROTOCOL {
46 LayerState::Headers } else {
48 LayerState::Payload
49 },
50 actions: TrackedActions::new(),
51 },
52 cdata: ConnData::new(five_tuple),
53 layers: [Layer::L7(L7Session::new())],
54 tracked: T::new(pdu, core_id),
55 }
56 }
57
58 pub(crate) fn filter_first_packet(
61 &mut self,
62 subscription: &Subscription<T::Subscribed>,
63 pdu: &L4Pdu,
64 ) {
65 subscription.state_tx::<T>(self, &StateTransition::L4FirstPacket, Some(pdu));
66 }
67
68 pub(crate) fn new_packet(&mut self, pdu: &L4Pdu, subscription: &Subscription<T::Subscribed>) {
73 #[cfg(debug_assertions)]
74 {
75 log::debug!(
76 "New packet for conn {:?}, state: {:?}, L4 actions: {:?}",
77 self.cdata.five_tuple,
78 self.linfo.state,
79 self.linfo.actions.active
80 );
81 }
82
83 let mut needs_update = self.linfo.actions.needs_update();
84 let tx = if pdu.ctxt.reassembled {
85 needs_update = self.linfo.actions.needs_parse();
86 StateTransition::InL4Stream
87 } else {
88 StateTransition::InL4Conn
89 };
90 if needs_update && subscription.update(self, pdu, tx) {
91 self.exec_state_tx(tx, subscription);
92 }
93 }
94
95 pub(super) fn handshake_done(&mut self, subscription: &Subscription<T::Subscribed>) {
97 self.linfo.state = LayerState::Payload;
98 self.exec_state_tx(StateTransition::L4EndHshk, subscription);
99 }
100
101 pub(crate) fn consume_stream(
104 &mut self,
105 pdu: &mut L4Pdu,
106 subscription: &Subscription<T::Subscribed>,
107 registry: &ParserRegistry,
108 ) {
109 if self.layers[0].needs_stream() {
111 let tx = self.layers[0].process_stream(pdu, registry);
112 self.exec_state_tx(tx, subscription);
113 if self.layers[0].needs_process(tx, pdu) {
114 let tx = self.layers[0].process_stream(pdu, registry);
115 self.exec_state_tx(tx, subscription);
116 }
117 }
118
119 self.new_packet(pdu, subscription);
121 }
122
123 pub(crate) fn exec_drop(&mut self) {
125 self.linfo.state = LayerState::None
126 }
127
128 pub(crate) fn drop(&self) -> bool {
130 self.linfo.state == LayerState::None
131 }
132
133 pub(crate) fn handle_terminate(&mut self, subscription: &Subscription<T::Subscribed>) {
136 while let Some(tx) = self.layers[0].handle_terminate() {
137 self.exec_state_tx(tx, subscription);
138 if self.drop() {
139 break;
140 }
141 }
142 if !self.drop() {
143 self.exec_state_tx(StateTransition::L4Terminated, subscription);
144 }
145 }
146
147 fn exec_state_tx(&mut self, tx: StateTransition, subscription: &Subscription<T::Subscribed>) {
150 #[cfg(debug_assertions)]
151 {
152 log::debug!("State transition {:?} for conn {:?}, state: {:?}, L4 actions: {:?}, L7 actions: {:?}",
153 tx, self.cdata.five_tuple, self.linfo.state, self.linfo.actions.active, self.layers[0].layer_info().actions.active);
154 }
155 if matches!(tx, StateTransition::Packet | StateTransition::L4FirstPacket) {
157 return;
158 }
159
160 if self.linfo.actions.skip_tx(&tx)
162 && self
163 .layers
164 .iter()
165 .all(|l| l.layer_info().actions.skip_tx(&tx))
166 {
167 return;
168 }
169 self.linfo.actions.start_state_tx(tx);
170 for layer in self.layers.iter_mut() {
171 layer.layer_info_mut().actions.start_state_tx(tx);
172 }
173 subscription.state_tx::<T>(self, &tx, None);
174 for layer in &mut self.layers {
175 layer.end_state_tx();
176 }
177 if self.linfo.drop() && self.layers.iter().all(|l| l.drop()) {
178 self.exec_drop();
179 } else {
180 if self.layers.iter().any(|l| !l.drop()) {
181 self.linfo.actions.set_next_layer();
182 }
183 }
184 }
185
186 pub(crate) fn clear(&mut self) {
187 self.tracked.clear();
188 }
189
190 pub(crate) fn needs_reassembly(&self) -> bool {
191 self.linfo.actions.needs_parse() || self.layers.iter().any(|l| l.needs_stream())
192 }
193
194 pub(crate) fn needs_update(&self) -> bool {
195 self.linfo.actions.needs_update()
196 }
197}