turn_server/turn/operations/mod.rs
1pub mod allocate;
2pub mod binding;
3pub mod channel_bind;
4pub mod channel_data;
5pub mod create_permission;
6pub mod indication;
7pub mod refresh;
8
9use super::{
10 Observer,
11 sessions::{SessionAddr, Sessions},
12};
13
14use crate::stun::{
15 Decoder, MessageRef, Payload, StunError,
16 attribute::{Nonce, UserName},
17 method::{
18 ALLOCATE_REQUEST, BINDING_REQUEST, CHANNEL_BIND_REQUEST, CREATE_PERMISSION_REQUEST, REFRESH_REQUEST,
19 SEND_INDICATION, StunMethod,
20 },
21};
22
23use std::{net::SocketAddr, sync::Arc};
24
25use bytes::BytesMut;
26
27#[derive(Debug, Clone, Copy, PartialEq, Eq)]
28pub enum ResponseMethod {
29 Stun(StunMethod),
30 ChannelData,
31}
32
33/// The context of the service.
34///
35/// A service corresponds to a Net Endpoint, different sockets have different
36/// addresses and so on, but other things are basically the same.
37pub struct ServiceContext<T: Observer> {
38 pub realm: String,
39 pub software: String,
40 pub sessions: Arc<Sessions<T>>,
41 pub endpoint: SocketAddr,
42 pub interface: SocketAddr,
43 pub interfaces: Arc<Vec<SocketAddr>>,
44 pub observer: T,
45}
46
47/// The request of the service.
48pub struct Requet<'a, 'b, T, M>
49where
50 T: Observer + 'static,
51{
52 pub address: &'a SessionAddr,
53 pub bytes: &'b mut BytesMut,
54 pub service: &'a ServiceContext<T>,
55 pub message: &'a M,
56}
57
58impl<'a, 'b, T> Requet<'a, 'b, T, MessageRef<'a>>
59where
60 T: Observer + 'static,
61{
62 /// Check if the ip address belongs to the current turn server.
63 #[inline(always)]
64 pub fn verify_ip(&self, address: &SocketAddr) -> bool {
65 self.service.interfaces.iter().any(|item| item.ip() == address.ip())
66 }
67
68 /// The key for the HMAC depends on whether long-term or short-term
69 /// credentials are in use. For long-term credentials, the key is 16
70 /// bytes:
71 ///
72 /// key = MD5(username ":" realm ":" SASLprep(password))
73 ///
74 /// That is, the 16-byte key is formed by taking the MD5 hash of the
75 /// result of concatenating the following five fields: (1) the username,
76 /// with any quotes and trailing nulls removed, as taken from the
77 /// USERNAME attribute (in which case SASLprep has already been applied);
78 /// (2) a single colon; (3) the realm, with any quotes and trailing nulls
79 /// removed; (4) a single colon; and (5) the password, with any trailing
80 /// nulls removed and after processing using SASLprep. For example, if
81 /// the username was 'user', the realm was 'realm', and the password was
82 /// 'pass', then the 16-byte HMAC key would be the result of performing
83 /// an MD5 hash on the string 'user:realm:pass', the resulting hash being
84 /// 0x8493fbc53ba582fb4c044c456bdc40eb.
85 ///
86 /// For short-term credentials:
87 ///
88 /// key = SASLprep(password)
89 ///
90 /// where MD5 is defined in RFC 1321 [RFC1321] and SASLprep() is defined
91 /// in RFC 4013 [RFC4013].
92 ///
93 /// The structure of the key when used with long-term credentials
94 /// facilitates deployment in systems that also utilize SIP. Typically,
95 /// SIP systems utilizing SIP's digest authentication mechanism do not
96 /// actually store the password in the database. Rather, they store a
97 /// value called H(A1), which is equal to the key defined above.
98 ///
99 /// Based on the rules above, the hash used to construct MESSAGE-
100 /// INTEGRITY includes the length field from the STUN message header.
101 /// Prior to performing the hash, the MESSAGE-INTEGRITY attribute MUST be
102 /// inserted into the message (with dummy content). The length MUST then
103 /// be set to point to the length of the message up to, and including,
104 /// the MESSAGE-INTEGRITY attribute itself, but excluding any attributes
105 /// after it. Once the computation is performed, the value of the
106 /// MESSAGE-INTEGRITY attribute can be filled in, and the value of the
107 /// length in the STUN header can be set to its correct value -- the
108 /// length of the entire message. Similarly, when validating the
109 /// MESSAGE-INTEGRITY, the length field should be adjusted to point to
110 /// the end of the MESSAGE-INTEGRITY attribute prior to calculating the
111 /// HMAC. Such adjustment is necessary when attributes, such as
112 /// FINGERPRINT, appear after MESSAGE-INTEGRITY.
113 #[inline(always)]
114 pub fn auth(&self) -> Option<(&str, [u8; 16])> {
115 let username = self.message.get::<UserName>()?;
116 let integrity = self
117 .service
118 .sessions
119 .get_integrity(&self.address, username, self.service.realm.as_str())?;
120
121 // if nonce is not empty, check nonce
122 if let Some(nonce) = self.message.get::<Nonce>() {
123 if self.service.sessions.get_nonce(&self.address).get_ref()?.0.as_str() != nonce {
124 return None;
125 }
126 }
127
128 self.message.integrity(&integrity).ok()?;
129 Some((username, integrity))
130 }
131}
132
133/// The response of the service.
134pub struct Response<'a> {
135 pub bytes: &'a [u8],
136 pub method: ResponseMethod,
137 pub relay: Option<SocketAddr>,
138 pub endpoint: Option<SocketAddr>,
139}
140
141/// process udp message and return message + address
142pub struct Operationer<T>
143where
144 T: Observer + 'static,
145{
146 service: ServiceContext<T>,
147 address: SessionAddr,
148 decoder: Decoder,
149 bytes: BytesMut,
150}
151
152impl<T> Operationer<T>
153where
154 T: Observer + 'static,
155{
156 pub fn new(service: ServiceContext<T>) -> Self {
157 Self {
158 address: SessionAddr {
159 address: "0.0.0.0:0".parse().unwrap(),
160 interface: service.interface,
161 },
162 bytes: BytesMut::with_capacity(4096),
163 decoder: Decoder::default(),
164 service,
165 }
166 }
167
168 /// process udp data
169 ///
170 /// receive STUN encoded Bytes,
171 /// and return any Bytes that can be responded to and the target address.
172 /// Note: unknown message is not process.
173 ///
174 /// In a typical configuration, a TURN client is connected to a private
175 /// network [RFC1918] and, through one or more NATs, to the public
176 /// Internet. On the public Internet is a TURN server. Elsewhere in the
177 /// Internet are one or more peers with which the TURN client wishes to
178 /// communicate. These peers may or may not be behind one or more NATs.
179 /// The client uses the server as a relay to send packets to these peers
180 /// and to receive packets from these peers.
181 ///
182 /// ```text
183 /// Peer A
184 /// Server-Reflexive +---------+
185 /// Transport Address | |
186 /// 192.0.2.150:32102 | |
187 /// | /| |
188 /// TURN | / ^| Peer A |
189 /// Client's Server | / || |
190 /// Host Transport Transport | // || |
191 /// Address Address | // |+---------+
192 /// 198.51.100.2:49721 192.0.2.15:3478 |+-+ // Peer A
193 /// | | ||N| / Host Transport
194 /// | +-+ | ||A|/ Address
195 /// | | | | v|T| 203.0.113.2:49582
196 /// | | | | /+-+
197 /// +---------+| | | |+---------+ / +---------+
198 /// | || |N| || | // | |
199 /// | TURN |v | | v| TURN |/ | |
200 /// | Client |----|A|-------| Server |------------------| Peer B |
201 /// | | | |^ | |^ ^| |
202 /// | | |T|| | || || |
203 /// +---------+ | || +---------+| |+---------+
204 /// | || | |
205 /// | || | |
206 /// +-+| | |
207 /// | | |
208 /// | | |
209 /// Client's | Peer B
210 /// Server-Reflexive Relayed Transport
211 /// Transport Address Transport Address Address
212 /// 192.0.2.1:7000 192.0.2.15:50000 192.0.2.210:49191
213 ///
214 /// Figure 1
215 /// ```
216 ///
217 /// Figure 1 shows a typical deployment. In this figure, the TURN client
218 /// and the TURN server are separated by a NAT, with the client on the
219 /// private side and the server on the public side of the NAT. This NAT
220 /// is assumed to be a "bad" NAT; for example, it might have a mapping
221 /// property of "address-and-port-dependent mapping" (see [RFC4787]).
222 ///
223 /// The client talks to the server from a (IP address, port) combination
224 /// called the client's "host transport address". (The combination of an
225 /// IP address and port is called a "transport address".)
226 ///
227 /// The client sends TURN messages from its host transport address to a
228 /// transport address on the TURN server that is known as the "TURN
229 /// server transport address". The client learns the TURN server
230 /// transport address through some unspecified means (e.g.,
231 /// configuration), and this address is typically used by many clients
232 /// simultaneously.
233 ///
234 /// Since the client is behind a NAT, the server sees packets from the
235 /// client as coming from a transport address on the NAT itself. This
236 /// address is known as the client's "server-reflexive transport
237 /// address"; packets sent by the server to the client's server-reflexive
238 /// transport address will be forwarded by the NAT to the client's host
239 /// transport address.
240 ///
241 /// The client uses TURN commands to create and manipulate an ALLOCATION
242 /// on the server. An allocation is a data structure on the server.
243 /// This data structure contains, amongst other things, the relayed
244 /// transport address for the allocation. The relayed transport address
245 /// is the transport address on the server that peers can use to have the
246 /// server relay data to the client. An allocation is uniquely
247 /// identified by its relayed transport address.
248 ///
249 /// Once an allocation is created, the client can send application data
250 /// to the server along with an indication of to which peer the data is
251 /// to be sent, and the server will relay this data to the intended peer.
252 /// The client sends the application data to the server inside a TURN
253 /// message; at the server, the data is extracted from the TURN message
254 /// and sent to the peer in a UDP datagram. In the reverse direction, a
255 /// peer can send application data in a UDP datagram to the relayed
256 /// transport address for the allocation; the server will then
257 /// encapsulate this data inside a TURN message and send it to the client
258 /// along with an indication of which peer sent the data. Since the TURN
259 /// message always contains an indication of which peer the client is
260 /// communicating with, the client can use a single allocation to
261 /// communicate with multiple peers.
262 ///
263 /// When the peer is behind a NAT, the client must identify the peer
264 /// using its server-reflexive transport address rather than its host
265 /// transport address. For example, to send application data to Peer A
266 /// in the example above, the client must specify 192.0.2.150:32102 (Peer
267 /// A's server-reflexive transport address) rather than 203.0.113.2:49582
268 /// (Peer A's host transport address).
269 ///
270 /// Each allocation on the server belongs to a single client and has
271 /// either one or two relayed transport addresses that are used only by
272 /// that allocation. Thus, when a packet arrives at a relayed transport
273 /// address on the server, the server knows for which client the data is
274 /// intended.
275 ///
276 /// The client may have multiple allocations on a server at the same
277 /// time.
278 pub fn route<'a, 'b: 'a>(
279 &'b mut self,
280 bytes: &'b [u8],
281 address: SocketAddr,
282 ) -> Result<Option<Response<'a>>, StunError> {
283 self.address.address = address;
284
285 Ok(match self.decoder.decode(bytes)? {
286 Payload::ChannelData(channel) => channel_data::process(
287 bytes,
288 Requet {
289 bytes: &mut self.bytes,
290 service: &self.service,
291 address: &self.address,
292 message: &channel,
293 },
294 ),
295 Payload::Message(message) => {
296 let method = message.method();
297 let req = Requet {
298 bytes: &mut self.bytes,
299 service: &self.service,
300 address: &self.address,
301 message: &message,
302 };
303
304 match method {
305 BINDING_REQUEST => binding::process(req),
306 ALLOCATE_REQUEST => allocate::process(req),
307 CREATE_PERMISSION_REQUEST => create_permission::process(req),
308 CHANNEL_BIND_REQUEST => channel_bind::process(req),
309 REFRESH_REQUEST => refresh::process(req),
310 SEND_INDICATION => indication::process(req),
311 _ => None,
312 }
313 }
314 })
315 }
316}