turmoil/
envelope.rs

1use std::{fmt::Display, net::SocketAddr};
2
3use bytes::Bytes;
4use tokio::sync::oneshot;
5
6#[derive(Debug)]
7pub(crate) struct Envelope {
8    pub(crate) src: SocketAddr,
9    pub(crate) dst: SocketAddr,
10    pub(crate) message: Protocol,
11}
12
13/// Supported network protocols.
14#[derive(Debug)]
15pub enum Protocol {
16    Tcp(Segment),
17    Udp(Datagram),
18}
19
20/// UDP datagram.
21#[derive(Clone, Debug)]
22pub struct Datagram(pub Bytes);
23
24/// This is a simplification of real TCP.
25///
26/// We implement just enough to ensure fidelity and provide knobs for real world
27/// scenarios, but we skip a ton of complexity (e.g. checksums, flow control,
28/// etc) because said complexity isn't useful in tests.
29#[derive(Debug)]
30pub enum Segment {
31    Syn(Syn),
32    Data(u64, Bytes),
33    Fin(u64),
34    Rst,
35}
36
37#[derive(Debug)]
38pub struct Syn {
39    pub(crate) ack: oneshot::Sender<()>,
40}
41
42impl Display for Protocol {
43    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
44        match self {
45            Protocol::Tcp(segment) => Display::fmt(segment, f),
46            Protocol::Udp(datagram) => Display::fmt(&datagram, f),
47        }
48    }
49}
50
51impl Display for Datagram {
52    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
53        hex("UDP", &self.0, f)
54    }
55}
56
57impl Display for Segment {
58    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
59        match self {
60            Segment::Syn(_) => write!(f, "TCP SYN"),
61            Segment::Data(_, data) => hex("TCP", data, f),
62            Segment::Fin(_) => write!(f, "TCP FIN"),
63            Segment::Rst => write!(f, "TCP RST"),
64        }
65    }
66}
67
68pub(crate) fn hex(
69    protocol: &str,
70    bytes: &Bytes,
71    f: &mut std::fmt::Formatter<'_>,
72) -> std::fmt::Result {
73    write!(f, "{protocol} [")?;
74
75    for (i, &b) in bytes.iter().enumerate() {
76        if i < bytes.len() - 1 {
77            write!(f, "{b:#2X}, ")?;
78        } else {
79            write!(f, "{b:#2X}")?;
80        }
81    }
82
83    write!(f, "]")
84}