turn_server/stun/
channel.rs

1use bytes::{BufMut, BytesMut};
2
3use super::StunError;
4
5use std::convert::TryFrom;
6
7/// The ChannelData Message
8///
9/// The ChannelData message is used to carry application data between the
10/// client and the server.  
11/// It has the following format:
12///
13/// ```text
14/// 0                   1                   2                   3
15/// 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
16/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
17/// |         Channel Number        |            Length             |
18/// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
19/// |                                                               |
20/// /                       Application Data                        /
21/// /                                                               /
22/// |                                                               |
23/// |                               +-------------------------------+
24/// |                               |
25/// +-------------------------------+
26///
27///                               Figure 5
28/// ```
29///
30/// The Channel Number field specifies the number of the channel on which
31/// the data is traveling, and thus, the address of the peer that is
32/// sending or is to receive the data.
33///
34/// The Length field specifies the length in bytes of the application
35/// data field (i.e., it does not include the size of the ChannelData
36/// header).  Note that 0 is a valid length.
37///
38/// The Application Data field carries the data the client is trying to
39/// send to the peer, or that the peer is sending to the client.
40#[derive(Debug)]
41pub struct ChannelData<'a> {
42    /// channnel data bytes.
43    pub bytes: &'a [u8],
44    /// channel number.
45    pub number: u16,
46}
47
48impl ChannelData<'_> {
49    /// # Test
50    ///
51    /// ```
52    /// use bytes::{BufMut, BytesMut};
53    /// use std::convert::TryFrom;
54    /// use turn_server::stun::*;
55    ///
56    /// let data: [u8; 4] = [0x40, 0x00, 0x00, 0x40];
57    /// let mut bytes = BytesMut::with_capacity(1500);
58    ///
59    /// ChannelData {
60    ///     number: 16384,
61    ///     bytes: &data[..],
62    /// }
63    /// .encode(&mut bytes);
64    ///
65    /// let size = ChannelData::message_size(&bytes[..], false).unwrap();
66    /// assert_eq!(size, 8);
67    /// ```
68    pub fn message_size(bytes: &[u8], is_tcp: bool) -> Result<usize, StunError> {
69        if bytes.len() < 4 {
70            return Err(StunError::InvalidInput);
71        }
72
73        if !(1..3).contains(&(bytes[0] >> 6)) {
74            return Err(StunError::InvalidInput);
75        }
76
77        let mut size = (u16::from_be_bytes(bytes[2..4].try_into()?) + 4) as usize;
78        if is_tcp && (size % 4) > 0 {
79            size += 4 - (size % 4);
80        }
81
82        Ok(size)
83    }
84
85    /// # Test
86    ///
87    /// ```
88    /// use bytes::{BufMut, BytesMut};
89    /// use std::convert::TryFrom;
90    /// use turn_server::stun::*;
91    ///
92    /// let data: [u8; 4] = [0x40, 0x00, 0x00, 0x40];
93    /// let mut bytes = BytesMut::with_capacity(1500);
94    ///
95    /// ChannelData {
96    ///     number: 16384,
97    ///     bytes: &data[..],
98    /// }
99    /// .encode(&mut bytes);
100    ///
101    /// let ret = ChannelData::try_from(&bytes[..]).unwrap();
102    /// assert_eq!(ret.number, 16384);
103    /// assert_eq!(ret.bytes, &data[..]);
104    /// ```
105    pub fn encode(self, bytes: &mut BytesMut) {
106        unsafe { bytes.set_len(0) }
107        bytes.put_u16(self.number);
108        bytes.put_u16(self.bytes.len() as u16);
109        bytes.extend_from_slice(self.bytes);
110    }
111}
112
113impl<'a> TryFrom<&'a [u8]> for ChannelData<'a> {
114    type Error = StunError;
115
116    /// # Test
117    ///
118    /// ```
119    /// use bytes::{BufMut, BytesMut};
120    /// use std::convert::TryFrom;
121    /// use turn_server::stun::*;
122    ///
123    /// let data: [u8; 4] = [0x40, 0x00, 0x00, 0x40];
124    /// let mut bytes = BytesMut::with_capacity(1500);
125    ///
126    /// ChannelData {
127    ///     number: 16384,
128    ///     bytes: &data[..],
129    /// }
130    /// .encode(&mut bytes);
131    ///
132    /// let ret = ChannelData::try_from(&bytes[..]).unwrap();
133    /// assert_eq!(ret.number, 16384);
134    /// assert_eq!(ret.bytes, &data[..]);
135    /// ```
136    fn try_from(bytes: &'a [u8]) -> Result<Self, Self::Error> {
137        if bytes.len() < 4 {
138            return Err(StunError::InvalidInput);
139        }
140
141        let number = u16::from_be_bytes(bytes[..2].try_into()?);
142        if !(0x4000..0xFFFF).contains(&number) {
143            return Err(StunError::InvalidInput);
144        }
145
146        let size = u16::from_be_bytes(bytes[2..4].try_into()?) as usize;
147        if size > bytes.len() - 4 {
148            return Err(StunError::InvalidInput);
149        }
150
151        Ok(Self {
152            bytes: &bytes[4..],
153            number,
154        })
155    }
156}