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}