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}