turn_server/codec/mod.rs
1//! ## Session Traversal Utilities for NAT (STUN)
2//!
3//! [RFC8445]: https://tools.ietf.org/html/rfc8445
4//! [RFC5626]: https://tools.ietf.org/html/rfc5626
5//! [Section 13]: https://tools.ietf.org/html/rfc8489#section-13
6//!
7//! STUN is intended to be used in the context of one or more NAT
8//! traversal solutions. These solutions are known as "STUN Usages".
9//! Each usage describes how STUN is utilized to achieve the NAT
10//! traversal solution. Typically, a usage indicates when STUN messages
11//! get sent, which optional attributes to include, what server is used,
12//! and what authentication mechanism is to be used. Interactive
13//! Connectivity Establishment (ICE) [RFC8445] is one usage of STUN.
14//! SIP Outbound [RFC5626] is another usage of STUN. In some cases,
15//! a usage will require extensions to STUN. A STUN extension can be
16//! in the form of new methods, attributes, or error response codes.
17//! More information on STUN Usages can be found in [Section 13].
18
19pub mod channel_data;
20pub mod crypto;
21pub mod message;
22
23use self::{
24 channel_data::ChannelData,
25 message::{Message, attributes::AttributeType},
26};
27
28use std::{array::TryFromSliceError, ops::Range, str::Utf8Error};
29
30#[derive(Debug)]
31pub enum Error {
32 InvalidInput,
33 SummaryFailed,
34 NotFoundIntegrity,
35 IntegrityFailed,
36 NotFoundMagicNumber,
37 UnknownMethod,
38 FatalError,
39 Utf8Error(Utf8Error),
40 TryFromSliceError(TryFromSliceError),
41}
42
43impl std::error::Error for Error {}
44
45impl std::fmt::Display for Error {
46 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
47 write!(f, "{:?}", self)
48 }
49}
50
51impl From<Utf8Error> for Error {
52 fn from(value: Utf8Error) -> Self {
53 Self::Utf8Error(value)
54 }
55}
56
57impl From<TryFromSliceError> for Error {
58 fn from(value: TryFromSliceError) -> Self {
59 Self::TryFromSliceError(value)
60 }
61}
62
63pub enum DecodeResult<'a> {
64 Message(Message<'a>),
65 ChannelData(ChannelData<'a>),
66}
67
68impl<'a> DecodeResult<'a> {
69 /// Consumes the decode result and returns the message if it is a message.
70 pub fn into_message(self) -> Option<Message<'a>> {
71 match self {
72 DecodeResult::Message(msg) => Some(msg),
73 _ => None,
74 }
75 }
76
77 /// Consumes the decode result and returns the channel data if it is channel data.
78 pub fn into_channel_data(self) -> Option<ChannelData<'a>> {
79 match self {
80 DecodeResult::ChannelData(data) => Some(data),
81 _ => None,
82 }
83 }
84}
85
86/// A cache of the list of attributes, this is for internal use only.
87#[derive(Debug, Clone)]
88pub struct Attributes(Vec<(AttributeType, Range<usize>)>);
89
90impl Default for Attributes {
91 fn default() -> Self {
92 Self(Vec::with_capacity(20))
93 }
94}
95
96impl Attributes {
97 /// Adds an attribute to the list.
98 pub fn append(&mut self, kind: AttributeType, range: Range<usize>) {
99 self.0.push((kind, range));
100 }
101
102 /// Gets an attribute from the list.
103 ///
104 /// Note: This function will only look for the first matching property in
105 /// the list and return it.
106 pub fn get(&self, kind: &AttributeType) -> Option<Range<usize>> {
107 self.0
108 .iter()
109 .find(|(k, _)| k == kind)
110 .map(|(_, v)| v.clone())
111 }
112
113 /// Gets all the values of an attribute from a list.
114 ///
115 /// Normally a stun message can have multiple attributes with the same name,
116 /// and this function will all the values of the current attribute.
117 pub fn get_all<'a>(
118 &'a self,
119 kind: &'a AttributeType,
120 ) -> impl Iterator<Item = &'a Range<usize>> {
121 self.0
122 .iter()
123 .filter(move |(k, _)| k == kind)
124 .map(|(_, v)| v)
125 }
126
127 pub fn clear(&mut self) {
128 if !self.0.is_empty() {
129 self.0.clear();
130 }
131 }
132}
133
134#[derive(Default)]
135pub struct Decoder(Attributes);
136
137impl Decoder {
138 /// # Test
139 ///
140 /// ```
141 /// use turn_server::codec::message::attributes::UserName;
142 /// use turn_server::codec::{Decoder, DecodeResult};
143 ///
144 /// let buffer = [
145 /// 0x00, 0x01, 0x00, 0x4c, 0x21, 0x12, 0xa4, 0x42, 0x71, 0x66, 0x46, 0x31,
146 /// 0x2b, 0x59, 0x79, 0x65, 0x56, 0x69, 0x32, 0x72, 0x00, 0x06, 0x00, 0x09,
147 /// 0x55, 0x43, 0x74, 0x39, 0x3a, 0x56, 0x2f, 0x2b, 0x2f, 0x00, 0x00, 0x00,
148 /// 0xc0, 0x57, 0x00, 0x04, 0x00, 0x00, 0x03, 0xe7, 0x80, 0x29, 0x00, 0x08,
149 /// 0x22, 0x49, 0xda, 0x28, 0x2c, 0x6f, 0x2e, 0xdb, 0x00, 0x24, 0x00, 0x04,
150 /// 0x6e, 0x00, 0x28, 0xff, 0x00, 0x08, 0x00, 0x14, 0x19, 0x58, 0xda, 0x38,
151 /// 0xed, 0x1e, 0xdd, 0xc8, 0x6b, 0x8e, 0x22, 0x63, 0x3a, 0x22, 0x63, 0x97,
152 /// 0xcf, 0xf5, 0xde, 0x82, 0x80, 0x28, 0x00, 0x04, 0x56, 0xf7, 0xa3, 0xed,
153 /// ];
154 ///
155 /// let mut decoder = Decoder::default();
156 /// let payload = decoder.decode(&buffer).unwrap();
157 ///
158 /// if let DecodeResult::Message(reader) = payload {
159 /// assert!(reader.get::<UserName>().is_some())
160 /// }
161 /// ```
162 pub fn decode<'a>(&'a mut self, bytes: &'a [u8]) -> Result<DecodeResult<'a>, Error> {
163 assert!(bytes.len() >= 4);
164
165 let flag = bytes[0] >> 6;
166 if flag > 3 {
167 return Err(Error::InvalidInput);
168 }
169
170 Ok(if flag == 0 {
171 self.0.clear();
172
173 DecodeResult::Message(Message::decode(bytes, &mut self.0)?)
174 } else {
175 DecodeResult::ChannelData(ChannelData::decode(bytes)?)
176 })
177 }
178
179 /// # Test
180 ///
181 /// ```
182 /// use turn_server::codec::Decoder;
183 ///
184 /// let buffer = [
185 /// 0x00, 0x01, 0x00, 0x4c, 0x21, 0x12, 0xa4, 0x42, 0x71, 0x66, 0x46, 0x31,
186 /// 0x2b, 0x59, 0x79, 0x65, 0x56, 0x69, 0x32, 0x72, 0x00, 0x06, 0x00, 0x09,
187 /// 0x55, 0x43, 0x74, 0x39, 0x3a, 0x56, 0x2f, 0x2b, 0x2f, 0x00, 0x00, 0x00,
188 /// 0xc0, 0x57, 0x00, 0x04, 0x00, 0x00, 0x03, 0xe7, 0x80, 0x29, 0x00, 0x08,
189 /// 0x22, 0x49, 0xda, 0x28, 0x2c, 0x6f, 0x2e, 0xdb, 0x00, 0x24, 0x00, 0x04,
190 /// 0x6e, 0x00, 0x28, 0xff, 0x00, 0x08, 0x00, 0x14, 0x19, 0x58, 0xda, 0x38,
191 /// 0xed, 0x1e, 0xdd, 0xc8, 0x6b, 0x8e, 0x22, 0x63, 0x3a, 0x22, 0x63, 0x97,
192 /// 0xcf, 0xf5, 0xde, 0x82, 0x80, 0x28, 0x00, 0x04, 0x56, 0xf7, 0xa3, 0xed,
193 /// ];
194 ///
195 /// let size = Decoder::message_size(&buffer, false).unwrap();
196 ///
197 /// assert_eq!(size, 96);
198 /// ```
199 pub fn message_size(bytes: &[u8], is_tcp: bool) -> Result<usize, Error> {
200 let flag = bytes[0] >> 6;
201 if flag > 3 {
202 return Err(Error::InvalidInput);
203 }
204
205 Ok(if flag == 0 {
206 Message::message_size(bytes)?
207 } else {
208 ChannelData::message_size(bytes, is_tcp)?
209 })
210 }
211}