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}