carrier_pigeon/
net.rs

1//! Networking things that are not specific to either transport.
2
3pub use crate::header::TcpHeader;
4use serde::{Deserialize, Serialize};
5use std::any::Any;
6use std::fmt::{Debug, Display, Formatter};
7use std::io;
8use std::io::Error;
9use std::ops::Deref;
10use std::time::Duration;
11
12/// The maximum safe message size that can be sent on udp,
13/// after taking off the possible overheads from the transport.
14///
15/// The data must be `MAX_SAFE_MESSAGE_SIZE` or less to be guaranteed to
16/// be deliverable on udp.
17/// [source](https://newbedev.com/what-is-the-largest-safe-udp-packet-size-on-the-internet/)
18pub const MAX_SAFE_MESSAGE_SIZE: usize = 504;
19
20/// An enum representing the 2 possible transports.
21///
22/// - TCP is reliable but slower.
23/// - UDP is unreliable but quicker.
24#[derive(Copy, Clone, Debug, Eq, PartialEq)]
25pub enum Transport {
26    TCP,
27    UDP,
28}
29
30/// The function used to deserialize a message.
31///
32/// fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, io::Error>
33pub type DeserFn = fn(&[u8]) -> Result<Box<dyn Any + Send + Sync>, io::Error>;
34/// The function used to serialize a message.
35///
36/// fn(&(dyn Any + Send + Sync)) -> Result<Vec<u8>, io::Error>
37pub type SerFn = fn(&(dyn Any + Send + Sync)) -> Result<Vec<u8>, io::Error>;
38
39#[derive(Debug)]
40/// An enum for the possible states of a connection.
41pub enum Status {
42    /// The connection is still live.
43    Connected,
44    /// The connection is closed because the peer disconnected by sending a disconnection message.
45    Disconnected(Box<dyn Any + Send + Sync>),
46    /// The connection is closed because we chose to close the connection.
47    Closed,
48    /// The connection was dropped without sending a disconnection message.
49    Dropped(Error),
50}
51
52impl Display for Status {
53    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
54        match self {
55            Self::Connected => write!(f, "Connected"),
56            Self::Disconnected(_) => write!(f, "Disconnected gracefully"),
57            Self::Closed => write!(f, "Closed"),
58            Self::Dropped(e) => write!(f, "Dropped with error {}", e),
59        }
60    }
61}
62
63impl Status {
64    /// Returns whether the status is [`Status::Connected`].
65    pub fn connected(&self) -> bool {
66        match self {
67            Status::Connected => true,
68            _ => false,
69        }
70    }
71
72    /// Turns this into an option with the disconnect message.
73    ///
74    /// ### Panics
75    /// Panics if the generic parameter `D` isn't the disconnect message type (the same `D` that
76    /// you passed into `MsgTable::build`).
77    pub fn disconnected<D: Any + Send + Sync>(&self) -> Option<&D> {
78        match self {
79            Status::Disconnected(d) => Some(d.downcast_ref().expect("The generic parameter `D` must be the disconnection message type (the same `D` that you passed into `MsgTable::build`).")),
80            _ => None,
81        }
82    }
83
84    /// Turns this into an option with the disconnect message.
85    pub fn disconnected_dyn(&self) -> Option<&Box<dyn Any + Send + Sync>> {
86        match self {
87            Status::Disconnected(d) => Some(d),
88            _ => None,
89        }
90    }
91
92    /// Turns this into an option with the drop error.
93    pub fn dropped(&self) -> Option<&Error> {
94        match self {
95            Status::Dropped(e) => Some(e),
96            _ => None,
97        }
98    }
99
100    /// Returns whether the status is [`Status::Closed`].
101    pub fn closed(&self) -> bool {
102        match self {
103            Status::Closed => true,
104            _ => false,
105        }
106    }
107}
108
109/// Message ID.
110pub type MId = usize;
111
112/// Connection ID.
113pub type CId = u32;
114
115/// A way to specify the valid [`CId`]s for an operation.
116#[derive(Copy, Clone, Eq, PartialEq, Debug, Hash)]
117pub enum CIdSpec {
118    /// Matches all [`CId`]s
119    All,
120    /// Matches no [`CId`]s.
121    None,
122    /// Matches all except the inner [`CId`]
123    Except(CId),
124    /// Matches only the inner [`CId`]
125    Only(CId),
126}
127
128impl CIdSpec {
129    /// Weather the given cid matches the pattern.
130    pub fn matches(&self, cid: CId) -> bool {
131        match self {
132            CIdSpec::All => true,
133            CIdSpec::None => false,
134            CIdSpec::Except(o) => cid != *o,
135            CIdSpec::Only(o) => cid == *o,
136        }
137    }
138
139    /// Checks if the `other` [`CIdSpec`] overlaps (shares at least on common [`CId`]).
140    pub fn overlaps(&self, other: CIdSpec) -> bool {
141        use CIdSpec::*;
142
143        match (*self, other) {
144            (None, _) => false,
145            (_, None) => false,
146            (All, _) => true,
147            (_, All) => true,
148
149            (Except(_), Except(_)) => true,
150            (Only(o1), Only(o2)) => o1 == o2,
151
152            (Only(only), Except(except)) => only != except,
153            (Except(except), Only(only)) => only != except,
154        }
155    }
156}
157
158/// Configuration for a client or server.
159///
160/// This needs to be defined before starting up the server.
161///
162/// Contains all configurable information about the server.
163#[derive(Copy, Clone, Eq, PartialEq, Debug, Serialize, Deserialize)]
164pub struct Config {
165    /// The timeout for handling new connections. The time to wait for a connection message
166    /// after establishing a tcp connection.
167    pub timeout: Duration,
168    /// The maximum number of connections that this can handle at the same time.
169    pub max_con_handle: usize,
170    /// The maximum message size in bytes. This is used for sizing the buffer for TCP and UDP.
171    /// Any attempts to send messages over this size will be discarded. Keep in mind, there is
172    /// still a soft limit for UDP messages (`MAX_SAFE_MSG_SIZE`)
173    pub max_msg_size: usize,
174}
175
176impl Config {
177    /// Creates a new Server configuration.
178    pub fn new(timeout: Duration, max_con_handle: usize, max_msg_size: usize) -> Self {
179        Config {
180            timeout,
181            max_con_handle,
182            max_msg_size,
183        }
184    }
185}
186
187impl Default for Config {
188    fn default() -> Self {
189        Config {
190            timeout: Duration::from_millis(5_000),
191            max_con_handle: 4,
192            max_msg_size: 2048,
193        }
194    }
195}
196
197/// An untyped network message containing the message content, along with the metadata associated.
198#[derive(Debug)]
199pub(crate) struct ErasedNetMsg {
200    /// The [`CId`] that the message was sent from.
201    pub(crate) cid: CId,
202    /// The timestamp that the message was sent in unix millis.
203    ///
204    /// This is always `Some` if the message was sent with UDP, and always `None` if sent with TCP.
205    pub(crate) time: Option<u32>,
206    /// The actual message.
207    pub(crate) msg: Box<dyn Any + Send + Sync>,
208}
209
210impl ErasedNetMsg {
211    /// Converts this to NetMsg, borrowed from this.
212    pub(crate) fn to_typed<T: Any + Send + Sync>(&self) -> Option<NetMsg<T>> {
213        let msg = self.msg.downcast_ref()?;
214        Some(NetMsg {
215            cid: self.cid,
216            time: self.time,
217            m: msg,
218        })
219    }
220}
221
222/// A network message containing the message content, along with the metadata associated.
223#[derive(Eq, PartialEq, Copy, Clone, Debug)]
224pub struct NetMsg<'n, T: Any + Send + Sync> {
225    /// The [`CId`] that the message was sent from.
226    pub cid: CId,
227    /// The timestamp that the message was sent in unix millis.
228    ///
229    /// This is always `Some` if the message was sent with UDP, and always `None` if sent with TCP.
230    pub time: Option<u32>,
231    /// The actual message.
232    ///
233    /// Borrowed from the client or server.
234    pub m: &'n T,
235}
236
237impl<'n, T: Any + Send + Sync> Deref for NetMsg<'n, T> {
238    type Target = T;
239
240    fn deref(&self) -> &Self::Target {
241        self.m
242    }
243}