net_stream/
message_types.rs

1//! Server/client connection message types.
2
3use serde::de::DeserializeOwned;
4use serde::Deserialize;
5use serde::Serialize;
6use std::fmt;
7use uuid::Uuid;
8
9/// Message types for the server and client communication.
10///
11/// This is a trait with no methods, used only to define strong types for TCP/UDP
12/// serialization and deserialization.
13pub trait MessageTypes: 'static + fmt::Debug {
14    /// Type for peers to send to the server over TCP.
15    type TcpToServer: Serialize + DeserializeOwned + fmt::Debug + Clone + Send + Sync + Unpin + 'static;
16
17    /// Type for server to send to peers over TCP.
18    type TcpFromServer: Serialize + DeserializeOwned + fmt::Debug + Clone + Send + Sync + Unpin + 'static;
19
20    /// Type for peers to send to server over UDP.
21    type UdpToServer: Serialize + DeserializeOwned + fmt::Debug + Clone + Send + Sync + Unpin + 'static;
22
23    /// Type for server to send to peers over UDP.
24    type UdpFromServer: Serialize + DeserializeOwned + fmt::Debug + Clone + Send + Sync + Unpin + 'static;
25}
26
27#[derive(Debug, Serialize, Deserialize)]
28pub(crate) enum TcpToServer<M: MessageTypes> {
29    /// Pass-through application level messages.
30    ApplicationLogic(M::TcpToServer),
31}
32
33#[derive(Debug, Serialize, Deserialize)]
34pub(crate) enum TcpFromServer<M: MessageTypes> {
35    /// Pass-through application level messages.
36    ApplicationLogic(M::TcpFromServer),
37
38    /// Welcome message, containing a unique UUID that the client uses to identify itself
39    /// when sending its first UDP message.
40    Welcome { handshake_uuid: Uuid },
41
42    /// An acknowledgement that an UDP Hello message carrying the handshake UUID has been
43    /// received on the server side.
44    UdpHandshakeAcknowledged,
45}
46
47#[derive(Debug, Serialize, Deserialize)]
48pub(crate) enum UdpToServer<M: MessageTypes> {
49    /// Pass-through application level messages.
50    ApplicationLogic(M::UdpToServer),
51
52    /// Hello message, containing the same UUID from the TCP welcome message.
53    ///
54    /// Sending this message from the client to the server sets up NAT on any gateway, and
55    /// allows the server to match the UDP socket address and port number to the TCP socket
56    /// of the client.
57    Hello { handshake_uuid: Uuid },
58}
59
60#[derive(Debug, Serialize, Deserialize)]
61pub(crate) enum UdpFromServer<M: MessageTypes> {
62    /// Pass-through application level messages.
63    ApplicationLogic(M::UdpFromServer),
64
65    /// One-time welcome UDP message from server.
66    Welcome,
67
68    /// Repeating heartbeat to keep firewall UPnP port forwards open from server to client.
69    Heartbeat,
70}
71
72// Deriving Clone doesn't work because MessageTypes itself is not Clone, even though all the types in MessageTypes are.
73impl<M: MessageTypes> Clone for TcpToServer<M> {
74    fn clone(&self) -> Self {
75        match self {
76            Self::ApplicationLogic(msg) => Self::ApplicationLogic(msg.clone()),
77        }
78    }
79}
80impl<M: MessageTypes> Clone for TcpFromServer<M> {
81    fn clone(&self) -> Self {
82        match self {
83            Self::ApplicationLogic(msg) => Self::ApplicationLogic(msg.clone()),
84            Self::Welcome { handshake_uuid } => Self::Welcome {
85                handshake_uuid: *handshake_uuid,
86            },
87            Self::UdpHandshakeAcknowledged => Self::UdpHandshakeAcknowledged,
88        }
89    }
90}
91impl<M: MessageTypes> Clone for UdpToServer<M> {
92    fn clone(&self) -> Self {
93        match self {
94            Self::ApplicationLogic(msg) => Self::ApplicationLogic(msg.clone()),
95            Self::Hello { handshake_uuid } => Self::Hello {
96                handshake_uuid: *handshake_uuid,
97            },
98        }
99    }
100}
101impl<M: MessageTypes> Clone for UdpFromServer<M> {
102    fn clone(&self) -> Self {
103        match self {
104            Self::ApplicationLogic(msg) => Self::ApplicationLogic(msg.clone()),
105            Self::Welcome => Self::Welcome,
106            Self::Heartbeat => Self::Heartbeat,
107        }
108    }
109}