tx5_signal/
wire.rs

1use crate::*;
2
3const F_HREQ: &[u8] = b"hreq";
4const F_HRES: &[u8] = b"hres";
5const F_OFFR: &[u8] = b"offr";
6const F_ANSW: &[u8] = b"answ";
7const F_ICEM: &[u8] = b"icem";
8const F_FMSG: &[u8] = b"fmsg";
9const F_KEEP: &[u8] = b"keep";
10
11/// Parsed signal message.
12pub enum SignalMessage {
13    /// Initiate a handshake with a peer.
14    HandshakeReq([u8; 32]),
15
16    /// Complete a handshake with a peer.
17    HandshakeRes([u8; 32]),
18
19    /// As an impolite node, send a webrtc offer.
20    Offer(Vec<u8>),
21
22    /// As a polite node, send a webrtc answer.
23    Answer(Vec<u8>),
24
25    /// Webrtc connectivity message.
26    Ice(Vec<u8>),
27
28    /// Pre-webrtc and webrtc failure fallback communication message.
29    Message(Vec<u8>),
30
31    /// Keepalive
32    Keepalive,
33
34    /// Message type not understood by this client.
35    Unknown,
36}
37
38impl std::fmt::Debug for SignalMessage {
39    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
40        match self {
41            Self::HandshakeReq(_) => f.write_str("HandshakeReq"),
42            Self::HandshakeRes(_) => f.write_str("HandshakeRes"),
43            Self::Offer(_) => f.write_str("Offer"),
44            Self::Answer(_) => f.write_str("Answer"),
45            Self::Ice(_) => f.write_str("Ice"),
46            Self::Message(_) => f.write_str("Message"),
47            Self::Keepalive => f.write_str("Keepalive"),
48            Self::Unknown => f.write_str("Unknown"),
49        }
50    }
51}
52
53impl SignalMessage {
54    /// Initiate a handshake with a peer.
55    pub(crate) fn handshake_req() -> ([u8; 32], Vec<u8>) {
56        use rand::Rng;
57
58        let mut nonce = [0; 32];
59        rand::rng().fill(&mut nonce[..]);
60
61        let mut out = Vec::with_capacity(4 + 32);
62        out.extend_from_slice(F_HREQ);
63        out.extend_from_slice(&nonce);
64
65        (nonce, out)
66    }
67
68    /// Complete a handshake with a peer.
69    pub(crate) fn handshake_res(nonce: [u8; 32]) -> Vec<u8> {
70        let mut out = Vec::with_capacity(4 + 32);
71        out.extend_from_slice(F_HRES);
72        out.extend_from_slice(&nonce);
73
74        out
75    }
76
77    /// As an impolite node, send a webrtc offer.
78    pub(crate) fn offer(mut offer: Vec<u8>) -> Result<Vec<u8>> {
79        offer.splice(0..0, F_OFFR.iter().cloned());
80        Ok(offer)
81    }
82
83    /// As a polite node, send a webrtc answer.
84    pub(crate) fn answer(mut answer: Vec<u8>) -> Result<Vec<u8>> {
85        answer.splice(0..0, F_ANSW.iter().cloned());
86        Ok(answer)
87    }
88
89    /// Webrtc connectivity message.
90    pub(crate) fn ice(mut ice: Vec<u8>) -> Result<Vec<u8>> {
91        ice.splice(0..0, F_ICEM.iter().cloned());
92        Ok(ice)
93    }
94
95    /// Pre-webrtc and webrtc failure fallback communication message.
96    pub(crate) fn message(mut msg: Vec<u8>) -> Result<Vec<u8>> {
97        if msg.len() > 16 * 1024 {
98            return Err(Error::other("msg too long"));
99        }
100        msg.splice(0..0, F_FMSG.iter().cloned());
101        Ok(msg)
102    }
103
104    /// Keepalive.
105    pub(crate) fn keepalive() -> Vec<u8> {
106        F_KEEP.to_vec()
107    }
108
109    /// Parse a raw received buffer into a signal message.
110    pub(crate) fn parse(mut b: Vec<u8>) -> Result<Self> {
111        if b.len() < 4 {
112            return Err(Error::other("msg too short"));
113        }
114        match &b[..4] {
115            F_HREQ => {
116                if b.len() != 4 + 32 {
117                    return Err(Error::other("invalid hreq"));
118                }
119                let mut nonce = [0; 32];
120                nonce.copy_from_slice(&b[4..]);
121                Ok(SignalMessage::HandshakeReq(nonce))
122            }
123            F_HRES => {
124                if b.len() != 4 + 32 {
125                    return Err(Error::other("invalid hres"));
126                }
127                let mut nonce = [0; 32];
128                nonce.copy_from_slice(&b[4..]);
129                Ok(SignalMessage::HandshakeRes(nonce))
130            }
131            F_OFFR => {
132                let _ = b.drain(..4);
133                Ok(SignalMessage::Offer(b))
134            }
135            F_ANSW => {
136                let _ = b.drain(..4);
137                Ok(SignalMessage::Answer(b))
138            }
139            F_ICEM => {
140                let _ = b.drain(..4);
141                Ok(SignalMessage::Ice(b))
142            }
143            F_FMSG => {
144                let _ = b.drain(..4);
145                Ok(SignalMessage::Message(b))
146            }
147            F_KEEP => Ok(SignalMessage::Keepalive),
148            _ => Ok(SignalMessage::Unknown),
149        }
150    }
151}