Skip to main content

retina_core/conntrack/
conn_id.rs

1//! Bidirectional connection identifiers.
2//!
3//! Provides endpoint-specific (distinguishes originator and responder) and generic identifiers for bi-directional connections.
4
5use crate::conntrack::L4Context;
6
7use std::cmp;
8use std::fmt;
9use std::net::SocketAddr;
10
11use serde::Serialize;
12
13/// Connection 5-tuple.
14///
15/// The sender of the first observed packet in the connection becomes the originator `orig`, and the
16/// recipient becomes the responder `resp`.
17#[derive(Debug, Copy, Clone, Hash, Eq, PartialEq, Serialize)]
18pub struct FiveTuple {
19    /// The originator connection endpoint.
20    pub orig: SocketAddr,
21    /// The responder connection endpoint.
22    pub resp: SocketAddr,
23    /// The layer-4 protocol.
24    pub proto: usize,
25}
26
27impl FiveTuple {
28    /// Creates a new 5-tuple from `ctxt`.
29    pub(super) fn from_ctxt(ctxt: L4Context) -> Self {
30        FiveTuple {
31            orig: ctxt.src,
32            resp: ctxt.dst,
33            proto: ctxt.proto,
34        }
35    }
36
37    /// Converts a 5-tuple to a non-directional connection identifier.
38    pub fn conn_id(&self) -> ConnId {
39        ConnId::new(self.orig, self.resp, self.proto)
40    }
41}
42
43impl fmt::Display for FiveTuple {
44    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45        write!(f, "{} -> ", self.orig)?;
46        write!(f, "{}", self.resp)?;
47        write!(f, " protocol {}", self.proto)?;
48        Ok(())
49    }
50}
51
52/// A generic connection identifier.
53///
54/// Identifies a connection independent of the source and destination socket address order. Does not
55/// distinguish between the originator and responder of the connection.
56#[derive(Debug, Clone, Hash, Eq, PartialEq)]
57pub struct ConnId(SocketAddr, SocketAddr, usize);
58
59impl ConnId {
60    /// Returns the connection ID of a packet with `src` and `dst` IP/port pairs.
61    pub(super) fn new(src: SocketAddr, dst: SocketAddr, protocol: usize) -> Self {
62        ConnId(cmp::max(src, dst), cmp::min(src, dst), protocol)
63    }
64}
65
66impl fmt::Display for ConnId {
67    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
68        write!(f, "{} <> ", self.0)?;
69        write!(f, "{}", self.1)?;
70        write!(f, " protocol {}", self.2)?;
71        Ok(())
72    }
73}