turn_rs/processor/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 crate::{router::Router, Observer, StunClass};
10
11use std::{net::SocketAddr, sync::Arc};
12
13use bytes::BytesMut;
14use faster_stun::attribute::*;
15use faster_stun::*;
16
17pub struct Env {
18 pub interface: SocketAddr,
19 pub realm: Arc<String>,
20 pub router: Arc<Router>,
21 pub external: Arc<SocketAddr>,
22 pub externals: Arc<Vec<SocketAddr>>,
23 pub observer: Arc<dyn Observer>,
24}
25
26/// process udp message
27/// and return message + address.
28pub struct Processor {
29 env: Arc<Env>,
30 decoder: Decoder,
31 buf: BytesMut,
32}
33
34impl Processor {
35 pub(crate) fn new(
36 interface: SocketAddr,
37 external: SocketAddr,
38 externals: Arc<Vec<SocketAddr>>,
39 realm: String,
40 router: Arc<Router>,
41 observer: Arc<dyn Observer>,
42 ) -> Self {
43 Self {
44 decoder: Decoder::new(),
45 buf: BytesMut::with_capacity(4096),
46 env: Arc::new(Env {
47 external: Arc::new(external),
48 realm: Arc::new(realm),
49 externals,
50 interface,
51 observer,
52 router,
53 }),
54 }
55 }
56
57 /// process udp data
58 ///
59 /// receive STUN encoded Bytes,
60 /// and return any Bytes that can be responded to and the target address.
61 /// Note: unknown message is not process.
62 ///
63 /// In a typical configuration, a TURN client is connected to a private
64 /// network [RFC1918] and, through one or more NATs, to the public
65 /// Internet. On the public Internet is a TURN server. Elsewhere in the
66 /// Internet are one or more peers with which the TURN client wishes to
67 /// communicate. These peers may or may not be behind one or more NATs.
68 /// The client uses the server as a relay to send packets to these peers
69 /// and to receive packets from these peers.
70 ///
71 /// ```text
72 /// Peer A
73 /// Server-Reflexive +---------+
74 /// Transport Address | |
75 /// 192.0.2.150:32102 | |
76 /// | /| |
77 /// TURN | / ^| Peer A |
78 /// Client's Server | / || |
79 /// Host Transport Transport | // || |
80 /// Address Address | // |+---------+
81 /// 198.51.100.2:49721 192.0.2.15:3478 |+-+ // Peer A
82 /// | | ||N| / Host Transport
83 /// | +-+ | ||A|/ Address
84 /// | | | | v|T| 203.0.113.2:49582
85 /// | | | | /+-+
86 /// +---------+| | | |+---------+ / +---------+
87 /// | || |N| || | // | |
88 /// | TURN |v | | v| TURN |/ | |
89 /// | Client |----|A|-------| Server |------------------| Peer B |
90 /// | | | |^ | |^ ^| |
91 /// | | |T|| | || || |
92 /// +---------+ | || +---------+| |+---------+
93 /// | || | |
94 /// | || | |
95 /// +-+| | |
96 /// | | |
97 /// | | |
98 /// Client's | Peer B
99 /// Server-Reflexive Relayed Transport
100 /// Transport Address Transport Address Address
101 /// 192.0.2.1:7000 192.0.2.15:50000 192.0.2.210:49191
102 ///
103 /// Figure 1
104 /// ```
105 ///
106 /// Figure 1 shows a typical deployment. In this figure, the TURN client
107 /// and the TURN server are separated by a NAT, with the client on the
108 /// private side and the server on the public side of the NAT. This NAT
109 /// is assumed to be a "bad" NAT; for example, it might have a mapping
110 /// property of "address-and-port-dependent mapping" (see [RFC4787]).
111 ///
112 /// The client talks to the server from a (IP address, port) combination
113 /// called the client's "host transport address". (The combination of an
114 /// IP address and port is called a "transport address".)
115 ///
116 /// The client sends TURN messages from its host transport address to a
117 /// transport address on the TURN server that is known as the "TURN
118 /// server transport address". The client learns the TURN server
119 /// transport address through some unspecified means (e.g.,
120 /// configuration), and this address is typically used by many clients
121 /// simultaneously.
122 ///
123 /// Since the client is behind a NAT, the server sees packets from the
124 /// client as coming from a transport address on the NAT itself. This
125 /// address is known as the client's "server-reflexive transport
126 /// address"; packets sent by the server to the client's server-reflexive
127 /// transport address will be forwarded by the NAT to the client's host
128 /// transport address.
129 ///
130 /// The client uses TURN commands to create and manipulate an ALLOCATION
131 /// on the server. An allocation is a data structure on the server.
132 /// This data structure contains, amongst other things, the relayed
133 /// transport address for the allocation. The relayed transport address
134 /// is the transport address on the server that peers can use to have the
135 /// server relay data to the client. An allocation is uniquely
136 /// identified by its relayed transport address.
137 ///
138 /// Once an allocation is created, the client can send application data
139 /// to the server along with an indication of to which peer the data is
140 /// to be sent, and the server will relay this data to the intended peer.
141 /// The client sends the application data to the server inside a TURN
142 /// message; at the server, the data is extracted from the TURN message
143 /// and sent to the peer in a UDP datagram. In the reverse direction, a
144 /// peer can send application data in a UDP datagram to the relayed
145 /// transport address for the allocation; the server will then
146 /// encapsulate this data inside a TURN message and send it to the client
147 /// along with an indication of which peer sent the data. Since the TURN
148 /// message always contains an indication of which peer the client is
149 /// communicating with, the client can use a single allocation to
150 /// communicate with multiple peers.
151 ///
152 /// When the peer is behind a NAT, the client must identify the peer
153 /// using its server-reflexive transport address rather than its host
154 /// transport address. For example, to send application data to Peer A
155 /// in the example above, the client must specify 192.0.2.150:32102 (Peer
156 /// A's server-reflexive transport address) rather than 203.0.113.2:49582
157 /// (Peer A's host transport address).
158 ///
159 /// Each allocation on the server belongs to a single client and has
160 /// either one or two relayed transport addresses that are used only by
161 /// that allocation. Thus, when a packet arrives at a relayed transport
162 /// address on the server, the server knows for which client the data is
163 /// intended.
164 ///
165 /// The client may have multiple allocations on a server at the same
166 /// time.
167 pub async fn process<'c, 'a: 'c>(
168 &'a mut self,
169 b: &'a [u8],
170 addr: SocketAddr,
171 ) -> Result<Option<Response<'c>>, StunError> {
172 let ctx = Context {
173 env: self.env.clone(),
174 addr,
175 };
176
177 Ok(match self.decoder.decode(b)? {
178 Payload::ChannelData(x) => channel_data::process(ctx, x),
179 Payload::Message(x) => Self::message_process(ctx, x, &mut self.buf).await?,
180 })
181 }
182
183 /// process stun message
184 ///
185 /// TURN is an extension to STUN. All TURN messages, with the exception
186 /// of the ChannelData message, are STUN-formatted messages. All the
187 /// base processing rules described in [RFC8489] apply to STUN-formatted
188 /// messages. This means that all the message-forming and message-
189 /// processing descriptions in this document are implicitly prefixed with
190 /// the rules of [RFC8489].
191 ///
192 /// [RFC8489] specifies an authentication mechanism called the "long-term
193 /// credential mechanism". TURN servers and clients MUST implement this
194 /// mechanism, and the authentication options are discussed in
195 /// Section 7.2.
196 ///
197 /// Note that the long-term credential mechanism applies only to requests
198 /// and cannot be used to authenticate indications; thus, indications in
199 /// TURN are never authenticated. If the server requires requests to be
200 /// authenticated, then the server's administrator MUST choose a realm
201 /// value that will uniquely identify the username and password
202 /// combination that the client must use, even if the client uses
203 /// multiple servers under different administrations. The server's
204 /// administrator MAY choose to allocate a unique username to each
205 /// client, or it MAY choose to allocate the same username to more than
206 /// one client (for example, to all clients from the same department or
207 /// company). For each Allocate request, the server SHOULD generate a
208 /// new random nonce when the allocation is first attempted following the
209 /// randomness recommendations in [RFC4086] and SHOULD expire the nonce
210 /// at least once every hour during the lifetime of the allocation. The
211 /// server uses the mechanism described in Section 9.2 of [RFC8489] to
212 /// indicate that it supports [RFC8489].
213 ///
214 /// All requests after the initial Allocate must use the same username as
215 /// that used to create the allocation to prevent attackers from
216 /// hijacking the client's allocation.
217 ///
218 /// Specifically, if:
219 ///
220 /// * the server requires the use of the long-term credential mechanism, and;
221 ///
222 /// * a non-Allocate request passes authentication under this mechanism, and;
223 ///
224 /// * the 5-tuple identifies an existing allocation, but;
225 ///
226 /// * the request does not use the same username as used to create the
227 /// allocation,
228 ///
229 /// then the request MUST be rejected with a 441 (Wrong Credentials)
230 /// error.
231 ///
232 /// When a TURN message arrives at the server from the client, the server
233 /// uses the 5-tuple in the message to identify the associated
234 /// allocation. For all TURN messages (including ChannelData) EXCEPT an
235 /// Allocate request, if the 5-tuple does not identify an existing
236 /// allocation, then the message MUST either be rejected with a 437
237 /// Allocation Mismatch error (if it is a request) or be silently ignored
238 /// (if it is an indication or a ChannelData message). A client
239 /// receiving a 437 error response to a request other than Allocate MUST
240 /// assume the allocation no longer exists.
241 ///
242 /// [RFC8489] defines a number of attributes, including the SOFTWARE and
243 /// FINGERPRINT attributes. The client SHOULD include the SOFTWARE
244 /// attribute in all Allocate and Refresh requests and MAY include it in
245 /// any other requests or indications. The server SHOULD include the
246 /// SOFTWARE attribute in all Allocate and Refresh responses (either
247 /// success or failure) and MAY include it in other responses or
248 /// indications. The client and the server MAY include the FINGERPRINT
249 /// attribute in any STUN-formatted messages defined in this document.
250 ///
251 /// TURN does not use the backwards-compatibility mechanism described in
252 /// [RFC8489].
253 ///
254 /// TURN, as defined in this specification, supports both IPv4 and IPv6.
255 /// IPv6 support in TURN includes IPv4-to-IPv6, IPv6-to-IPv6, and IPv6-
256 /// to-IPv4 relaying. When only a single address type is desired, the
257 /// REQUESTED-ADDRESS-FAMILY attribute is used to explicitly request the
258 /// address type the TURN server will allocate (e.g., an IPv4-only node
259 /// may request the TURN server to allocate an IPv6 address). If both
260 /// IPv4 and IPv6 are desired, the single ADDITIONAL-ADDRESS-FAMILY
261 /// attribute indicates a request to the server to allocate one IPv4 and
262 /// one IPv6 relay address in a single Allocate request. This saves
263 /// local ports on the client and reduces the number of messages sent
264 /// between the client and the TURN server.
265 ///
266 /// By default, TURN runs on the same ports as STUN: 3478 for TURN over
267 /// UDP and TCP, and 5349 for TURN over (D)TLS. However, TURN has its
268 /// own set of Service Record (SRV) names: "turn" for UDP and TCP, and
269 /// "turns" for (D)TLS. Either the DNS resolution procedures or the
270 /// ALTERNATE-SERVER procedures, both described in Section 7, can be used
271 /// to run TURN on a different port.
272 ///
273 /// To ensure interoperability, a TURN server MUST support the use of UDP
274 /// transport between the client and the server, and it SHOULD support
275 /// the use of TCP, TLS-over-TCP, and DTLS-over-UDP transports.
276 ///
277 /// When UDP or DTLS-over-UDP transport is used between the client and
278 /// the server, the client will retransmit a request if it does not
279 /// receive a response within a certain timeout period. Because of this,
280 /// the server may receive two (or more) requests with the same 5-tuple
281 /// and same transaction id. STUN requires that the server recognize
282 /// this case and treat the request as idempotent (see [RFC8489]). Some
283 /// implementations may choose to meet this requirement by remembering
284 /// all received requests and the corresponding responses for 40 seconds
285 /// (Section 6.3.1 of [RFC8489]). Other implementations may choose to
286 /// reprocess the request and arrange that such reprocessing returns
287 /// essentially the same response. To aid implementors who choose the
288 /// latter approach (the so-called "stateless stack approach"), this
289 /// specification includes some implementation notes on how this might be
290 /// done. Implementations are free to choose either approach or some
291 /// other approach that gives the same results.
292 ///
293 /// To mitigate either intentional or unintentional denial-of-service
294 /// attacks against the server by clients with valid usernames and
295 /// passwords, it is RECOMMENDED that the server impose limits on both
296 /// the number of allocations active at one time for a given username and
297 /// on the amount of bandwidth those allocations can use. The server
298 /// should reject new allocations that would exceed the limit on the
299 /// allowed number of allocations active at one time with a 486
300 /// (Allocation Quota Exceeded) (see Section 7.2), and since UDP does not
301 /// include a congestion control mechanism, it should discard application
302 /// data traffic that exceeds the bandwidth quota.
303 #[rustfmt::skip]
304 #[inline(always)]
305 async fn message_process<'c>(
306 ctx: Context,
307 m: MessageReader<'_, '_>,
308 w: &'c mut BytesMut,
309 ) -> Result<Option<Response<'c>>, StunError> {
310 match m.method {
311 Method::Binding(Kind::Request) => binding::process(ctx, m, w),
312 Method::Allocate(Kind::Request) => allocate::process(ctx, m, w).await,
313 Method::CreatePermission(Kind::Request) => create_permission::process(ctx, m, w).await,
314 Method::ChannelBind(Kind::Request) => channel_bind::process(ctx, m, w).await,
315 Method::Refresh(Kind::Request) => refresh::process(ctx, m, w).await,
316 Method::SendIndication => indication::process(ctx, m, w).await,
317 _ => Ok(None),
318 }
319 }
320}
321
322pub struct Response<'a> {
323 pub data: &'a [u8],
324 pub kind: StunClass,
325 pub relay: Option<SocketAddr>,
326 pub interface: Option<SocketAddr>,
327}
328
329impl<'a> Response<'a> {
330 #[inline(always)]
331 pub(crate) fn new(
332 data: &'a [u8],
333 kind: StunClass,
334 relay: Option<SocketAddr>,
335 interface: Option<SocketAddr>,
336 ) -> Self {
337 Self {
338 data,
339 kind,
340 relay,
341 interface,
342 }
343 }
344}
345
346pub struct Context {
347 pub env: Arc<Env>,
348 pub addr: SocketAddr,
349}
350
351/// The key for the HMAC depends on whether long-term or short-term
352/// credentials are in use. For long-term credentials, the key is 16
353/// bytes:
354///
355/// key = MD5(username ":" realm ":" SASLprep(password))
356///
357/// That is, the 16-byte key is formed by taking the MD5 hash of the
358/// result of concatenating the following five fields: (1) the username,
359/// with any quotes and trailing nulls removed, as taken from the
360/// USERNAME attribute (in which case SASLprep has already been applied);
361/// (2) a single colon; (3) the realm, with any quotes and trailing nulls
362/// removed; (4) a single colon; and (5) the password, with any trailing
363/// nulls removed and after processing using SASLprep. For example, if
364/// the username was 'user', the realm was 'realm', and the password was
365/// 'pass', then the 16-byte HMAC key would be the result of performing
366/// an MD5 hash on the string 'user:realm:pass', the resulting hash being
367/// 0x8493fbc53ba582fb4c044c456bdc40eb.
368///
369/// For short-term credentials:
370///
371/// key = SASLprep(password)
372///
373/// where MD5 is defined in RFC 1321 [RFC1321] and SASLprep() is defined
374/// in RFC 4013 [RFC4013].
375///
376/// The structure of the key when used with long-term credentials
377/// facilitates deployment in systems that also utilize SIP. Typically,
378/// SIP systems utilizing SIP's digest authentication mechanism do not
379/// actually store the password in the database. Rather, they store a
380/// value called H(A1), which is equal to the key defined above.
381///
382/// Based on the rules above, the hash used to construct MESSAGE-
383/// INTEGRITY includes the length field from the STUN message header.
384/// Prior to performing the hash, the MESSAGE-INTEGRITY attribute MUST be
385/// inserted into the message (with dummy content). The length MUST then
386/// be set to point to the length of the message up to, and including,
387/// the MESSAGE-INTEGRITY attribute itself, but excluding any attributes
388/// after it. Once the computation is performed, the value of the
389/// MESSAGE-INTEGRITY attribute can be filled in, and the value of the
390/// length in the STUN header can be set to its correct value -- the
391/// length of the entire message. Similarly, when validating the
392/// MESSAGE-INTEGRITY, the length field should be adjusted to point to
393/// the end of the MESSAGE-INTEGRITY attribute prior to calculating the
394/// HMAC. Such adjustment is necessary when attributes, such as
395/// FINGERPRINT, appear after MESSAGE-INTEGRITY.
396#[inline(always)]
397pub(crate) async fn verify_message<'a>(
398 ctx: &Context,
399 reader: &MessageReader<'a, '_>,
400) -> Option<(&'a str, Arc<[u8; 16]>)> {
401 let username = reader.get::<UserName>()?;
402 let key = ctx
403 .env
404 .router
405 .get_key(&ctx.addr, &ctx.env.interface, &ctx.env.external, username)
406 .await?;
407
408 reader.integrity(&key).ok()?;
409 Some((username, key))
410}
411
412/// Check if the ip address belongs to the current turn server.
413#[inline(always)]
414pub(crate) fn ip_is_local(ctx: &Context, addr: &SocketAddr) -> bool {
415 ctx.env.externals.iter().any(|item| item.ip() == addr.ip())
416}