iris_core/conntrack/conn/tcp_conn/
mod.rs1pub mod reassembly;
2
3use self::reassembly::TcpFlow;
4use crate::conntrack::conn::conn_info::ConnInfo;
5use crate::conntrack::pdu::{L4Context, L4Pdu};
6use crate::protocols::packet::tcp::{ACK, SYN};
7use crate::protocols::packet::tcp::{FIN, RST};
8use crate::protocols::stream::ParserRegistry;
9use crate::subscription::{Subscription, Trackable};
10
11pub(crate) struct TcpConn {
12 pub(crate) ctos: TcpFlow,
13 pub(crate) stoc: TcpFlow,
14 handshake_done: bool,
15}
16
17impl TcpConn {
18 pub(crate) fn new_on_syn(ctxt: L4Context, max_ooo: usize) -> Self {
19 let flags = ctxt.flags;
20 let next_seq = ctxt.seq_no.wrapping_add(1 + ctxt.length as u32);
21 let ack = ctxt.ack_no;
22 TcpConn {
23 ctos: TcpFlow::new(max_ooo, next_seq, flags, ack),
24 stoc: TcpFlow::default(max_ooo),
25 handshake_done: false,
26 }
27 }
28
29 #[inline]
31 pub(crate) fn reassemble<T: Trackable>(
32 &mut self,
33 segment: L4Pdu,
34 info: &mut ConnInfo<T>,
35 subscription: &Subscription<T::Subscribed>,
36 registry: &ParserRegistry,
37 ) {
38 if segment.dir {
39 self.ctos
40 .insert_segment::<T>(segment, info, subscription, registry);
41 } else {
42 self.stoc
43 .insert_segment::<T>(segment, info, subscription, registry);
44 }
45 if self.handshake_done() {
46 self.handshake_done = true;
47 info.handshake_done(subscription);
48 }
49 }
50
51 #[inline]
56 pub(crate) fn handshake_done(&self) -> bool {
57 !self.handshake_done
58 && self.ctos.consumed_flags & (SYN | ACK) != 0
59 && self.stoc.consumed_flags & (SYN | ACK) != 0
60 }
61
62 #[inline]
63 pub(crate) fn flow_len(&self, dir: bool) -> usize {
64 if dir {
65 self.ctos.observed
66 } else {
67 self.stoc.observed
68 }
69 }
70
71 #[inline]
72 pub(crate) fn total_len(&self) -> usize {
73 self.ctos.observed + self.stoc.observed
74 }
75
76 #[inline]
78 pub(crate) fn is_terminated(&self) -> bool {
79 (self.ctos.consumed_flags & self.stoc.consumed_flags & FIN != 0
81 && self.ctos.last_ack == self.stoc.next_seq
82 && self.stoc.last_ack == self.ctos.next_seq)
83 || (self.ctos.consumed_flags & RST | self.stoc.consumed_flags & RST) != 0
84 }
85
86 #[inline]
89 pub(crate) fn inactivity_timeout(
90 &self,
91 default_inactivity_timeout: usize,
92 reassembly_timeout: usize,
93 ) -> usize {
94 match self.ctos.ooo_buf.is_empty() && self.stoc.ooo_buf.is_empty() {
95 true => default_inactivity_timeout,
96 false => reassembly_timeout,
97 }
98 }
99
100 #[inline]
103 pub(super) fn update_flags(&mut self, flags: u8, dir: bool) {
104 if dir {
105 self.ctos.consumed_flags |= flags;
106 } else {
107 self.stoc.consumed_flags |= flags;
108 }
109 }
110}