xref: /webrtc/turn/src/allocation/mod.rs (revision 603f4064)
1 #[cfg(test)]
2 mod allocation_test;
3 
4 pub mod allocation_manager;
5 pub mod channel_bind;
6 pub mod five_tuple;
7 pub mod permission;
8 
9 use crate::error::*;
10 use crate::proto::{chandata::*, channum::*, data::*, peeraddr::*, *};
11 use channel_bind::*;
12 use five_tuple::*;
13 use permission::*;
14 
15 use stun::{agent::*, message::*, textattrs::Username};
16 
17 use util::Conn;
18 
19 use std::sync::atomic::AtomicUsize;
20 use std::{
21     collections::HashMap,
22     marker::{Send, Sync},
23     net::SocketAddr,
24     sync::{atomic::AtomicBool, atomic::Ordering, Arc, Mutex as StdMutex},
25 };
26 use tokio::{
27     sync::{mpsc, Mutex},
28     time::{Duration, Instant},
29 };
30 
31 const RTP_MTU: usize = 1500;
32 
33 pub type AllocationMap = Arc<Mutex<HashMap<FiveTuple, Arc<Allocation>>>>;
34 
35 /// Information about an [`Allocation`].
36 #[derive(Debug, Clone)]
37 pub struct AllocationInfo {
38     /// [`FiveTuple`] of this [`Allocation`].
39     pub five_tuple: FiveTuple,
40 
41     /// Username of this [`Allocation`].
42     pub username: String,
43 
44     /// Relayed bytes with this [`Allocation`].
45     #[cfg(feature = "metrics")]
46     pub relayed_bytes: usize,
47 }
48 
49 impl AllocationInfo {
50     // Creates a new `AllocationInfo`
51     pub fn new(
52         five_tuple: FiveTuple,
53         username: String,
54         #[cfg(feature = "metrics")] relayed_bytes: usize,
55     ) -> Self {
56         Self {
57             five_tuple,
58             username,
59             #[cfg(feature = "metrics")]
60             relayed_bytes,
61         }
62     }
63 }
64 
65 // Allocation is tied to a FiveTuple and relays traffic
66 // use create_allocation and get_allocation to operate
67 pub struct Allocation {
68     protocol: Protocol,
69     turn_socket: Arc<dyn Conn + Send + Sync>,
70     pub(crate) relay_addr: SocketAddr,
71     pub(crate) relay_socket: Arc<dyn Conn + Send + Sync>,
72     five_tuple: FiveTuple,
73     username: Username,
74     permissions: Arc<Mutex<HashMap<String, Permission>>>,
75     channel_bindings: Arc<Mutex<HashMap<ChannelNumber, ChannelBind>>>,
76     pub(crate) allocations: Option<AllocationMap>,
77     reset_tx: StdMutex<Option<mpsc::Sender<Duration>>>,
78     timer_expired: Arc<AtomicBool>,
79     closed: AtomicBool, // Option<mpsc::Receiver<()>>,
80     pub(crate) relayed_bytes: AtomicUsize,
81 }
82 
83 fn addr2ipfingerprint(addr: &SocketAddr) -> String {
84     addr.ip().to_string()
85 }
86 
87 impl Allocation {
88     // creates a new instance of NewAllocation.
89     pub fn new(
90         turn_socket: Arc<dyn Conn + Send + Sync>,
91         relay_socket: Arc<dyn Conn + Send + Sync>,
92         relay_addr: SocketAddr,
93         five_tuple: FiveTuple,
94         username: Username,
95     ) -> Self {
96         Allocation {
97             protocol: PROTO_UDP,
98             turn_socket,
99             relay_addr,
100             relay_socket,
101             five_tuple,
102             username,
103             permissions: Arc::new(Mutex::new(HashMap::new())),
104             channel_bindings: Arc::new(Mutex::new(HashMap::new())),
105             allocations: None,
106             reset_tx: StdMutex::new(None),
107             timer_expired: Arc::new(AtomicBool::new(false)),
108             closed: AtomicBool::new(false),
109             relayed_bytes: Default::default(),
110         }
111     }
112 
113     // has_permission gets the Permission from the allocation
114     pub async fn has_permission(&self, addr: &SocketAddr) -> bool {
115         let permissions = self.permissions.lock().await;
116         permissions.get(&addr2ipfingerprint(addr)).is_some()
117     }
118 
119     // add_permission adds a new permission to the allocation
120     pub async fn add_permission(&self, mut p: Permission) {
121         let fingerprint = addr2ipfingerprint(&p.addr);
122 
123         {
124             let permissions = self.permissions.lock().await;
125             if let Some(existed_permission) = permissions.get(&fingerprint) {
126                 existed_permission.refresh(PERMISSION_TIMEOUT).await;
127                 return;
128             }
129         }
130 
131         p.permissions = Some(Arc::clone(&self.permissions));
132         p.start(PERMISSION_TIMEOUT).await;
133 
134         {
135             let mut permissions = self.permissions.lock().await;
136             permissions.insert(fingerprint, p);
137         }
138     }
139 
140     // remove_permission removes the net.Addr's fingerprint from the allocation's permissions
141     pub async fn remove_permission(&self, addr: &SocketAddr) -> bool {
142         let mut permissions = self.permissions.lock().await;
143         permissions.remove(&addr2ipfingerprint(addr)).is_some()
144     }
145 
146     // add_channel_bind adds a new ChannelBind to the allocation, it also updates the
147     // permissions needed for this ChannelBind
148     pub async fn add_channel_bind(&self, mut c: ChannelBind, lifetime: Duration) -> Result<()> {
149         {
150             if let Some(addr) = self.get_channel_addr(&c.number).await {
151                 if addr != c.peer {
152                     return Err(Error::ErrSameChannelDifferentPeer);
153                 }
154             }
155 
156             if let Some(number) = self.get_channel_number(&c.peer).await {
157                 if number != c.number {
158                     return Err(Error::ErrSameChannelDifferentPeer);
159                 }
160             }
161         }
162 
163         {
164             let channel_bindings = self.channel_bindings.lock().await;
165             if let Some(cb) = channel_bindings.get(&c.number) {
166                 cb.refresh(lifetime).await;
167 
168                 // Channel binds also refresh permissions.
169                 self.add_permission(Permission::new(cb.peer)).await;
170 
171                 return Ok(());
172             }
173         }
174 
175         let peer = c.peer;
176 
177         // Add or refresh this channel.
178         c.channel_bindings = Some(Arc::clone(&self.channel_bindings));
179         c.start(lifetime).await;
180 
181         {
182             let mut channel_bindings = self.channel_bindings.lock().await;
183             channel_bindings.insert(c.number, c);
184         }
185 
186         // Channel binds also refresh permissions.
187         self.add_permission(Permission::new(peer)).await;
188 
189         Ok(())
190     }
191 
192     // remove_channel_bind removes the ChannelBind from this allocation by id
193     pub async fn remove_channel_bind(&self, number: ChannelNumber) -> bool {
194         let mut channel_bindings = self.channel_bindings.lock().await;
195         channel_bindings.remove(&number).is_some()
196     }
197 
198     // get_channel_addr gets the ChannelBind's addr
199     pub async fn get_channel_addr(&self, number: &ChannelNumber) -> Option<SocketAddr> {
200         let channel_bindings = self.channel_bindings.lock().await;
201         channel_bindings.get(number).map(|cb| cb.peer)
202     }
203 
204     // GetChannelByAddr gets the ChannelBind's number from this allocation by net.Addr
205     pub async fn get_channel_number(&self, addr: &SocketAddr) -> Option<ChannelNumber> {
206         let channel_bindings = self.channel_bindings.lock().await;
207         for cb in channel_bindings.values() {
208             if cb.peer == *addr {
209                 return Some(cb.number);
210             }
211         }
212         None
213     }
214 
215     // Close closes the allocation
216     pub async fn close(&self) -> Result<()> {
217         if self.closed.load(Ordering::Acquire) {
218             return Err(Error::ErrClosed);
219         }
220 
221         self.closed.store(true, Ordering::Release);
222         self.stop();
223 
224         {
225             let mut permissions = self.permissions.lock().await;
226             for p in permissions.values_mut() {
227                 p.stop();
228             }
229         }
230 
231         {
232             let mut channel_bindings = self.channel_bindings.lock().await;
233             for c in channel_bindings.values_mut() {
234                 c.stop();
235             }
236         }
237 
238         log::trace!("allocation with {} closed!", self.five_tuple);
239 
240         let _ = self.turn_socket.close().await;
241         let _ = self.relay_socket.close().await;
242 
243         Ok(())
244     }
245 
246     pub async fn start(&self, lifetime: Duration) {
247         let (reset_tx, mut reset_rx) = mpsc::channel(1);
248         self.reset_tx.lock().unwrap().replace(reset_tx);
249 
250         let allocations = self.allocations.clone();
251         let five_tuple = self.five_tuple;
252         let timer_expired = Arc::clone(&self.timer_expired);
253 
254         tokio::spawn(async move {
255             let timer = tokio::time::sleep(lifetime);
256             tokio::pin!(timer);
257             let mut done = false;
258 
259             while !done {
260                 tokio::select! {
261                     _ = &mut timer => {
262                         if let Some(allocs) = &allocations{
263                             let mut alls = allocs.lock().await;
264                             if let Some(a) = alls.remove(&five_tuple) {
265                                 let _ = a.close().await;
266                             }
267                         }
268                         done = true;
269                     },
270                     result = reset_rx.recv() => {
271                         if let Some(d) = result {
272                             timer.as_mut().reset(Instant::now() + d);
273                         } else {
274                             done = true;
275                         }
276                     },
277                 }
278             }
279 
280             timer_expired.store(true, Ordering::SeqCst);
281         });
282     }
283 
284     fn stop(&self) -> bool {
285         let mut reset_tx = self.reset_tx.lock().unwrap();
286         let expired = reset_tx.is_none() || self.timer_expired.load(Ordering::SeqCst);
287         reset_tx.take();
288         expired
289     }
290 
291     // Refresh updates the allocations lifetime
292     pub async fn refresh(&self, lifetime: Duration) {
293         let reset_tx = self.reset_tx.lock().unwrap().clone();
294         if let Some(tx) = reset_tx {
295             let _ = tx.send(lifetime).await;
296         }
297     }
298 
299     //  https://tools.ietf.org/html/rfc5766#section-10.3
300     //  When the server receives a UDP datagram at a currently allocated
301     //  relayed transport address, the server looks up the allocation
302     //  associated with the relayed transport address.  The server then
303     //  checks to see whether the set of permissions for the allocation allow
304     //  the relaying of the UDP datagram as described in Section 8.
305     //
306     //  If relaying is permitted, then the server checks if there is a
307     //  channel bound to the peer that sent the UDP datagram (see
308     //  Section 11).  If a channel is bound, then processing proceeds as
309     //  described in Section 11.7.
310     //
311     //  If relaying is permitted but no channel is bound to the peer, then
312     //  the server forms and sends a Data indication.  The Data indication
313     //  MUST contain both an XOR-PEER-ADDRESS and a DATA attribute.  The DATA
314     //  attribute is set to the value of the 'data octets' field from the
315     //  datagram, and the XOR-PEER-ADDRESS attribute is set to the source
316     //  transport address of the received UDP datagram.  The Data indication
317     //  is then sent on the 5-tuple associated with the allocation.
318     async fn packet_handler(&self) {
319         let five_tuple = self.five_tuple;
320         let relay_addr = self.relay_addr;
321         let relay_socket = Arc::clone(&self.relay_socket);
322         let turn_socket = Arc::clone(&self.turn_socket);
323         let allocations = self.allocations.clone();
324         let channel_bindings = Arc::clone(&self.channel_bindings);
325         let permissions = Arc::clone(&self.permissions);
326 
327         tokio::spawn(async move {
328             let mut buffer = vec![0u8; RTP_MTU];
329 
330             loop {
331                 let (n, src_addr) = match relay_socket.recv_from(&mut buffer).await {
332                     Ok((n, src_addr)) => (n, src_addr),
333                     Err(_) => {
334                         if let Some(allocs) = &allocations {
335                             let mut alls = allocs.lock().await;
336                             alls.remove(&five_tuple);
337                         }
338                         break;
339                     }
340                 };
341 
342                 log::debug!(
343                     "relay socket {:?} received {} bytes from {}",
344                     relay_socket.local_addr().await,
345                     n,
346                     src_addr
347                 );
348 
349                 let cb_number = {
350                     let mut cb_number = None;
351                     let cbs = channel_bindings.lock().await;
352                     for cb in cbs.values() {
353                         if cb.peer == src_addr {
354                             cb_number = Some(cb.number);
355                             break;
356                         }
357                     }
358                     cb_number
359                 };
360 
361                 if let Some(number) = cb_number {
362                     let mut channel_data = ChannelData {
363                         data: buffer[..n].to_vec(),
364                         number,
365                         raw: vec![],
366                     };
367                     channel_data.encode();
368 
369                     if let Err(err) = turn_socket
370                         .send_to(&channel_data.raw, five_tuple.src_addr)
371                         .await
372                     {
373                         log::error!(
374                             "Failed to send ChannelData from allocation {} {}",
375                             src_addr,
376                             err
377                         );
378                     }
379                 } else {
380                     let exist = {
381                         let ps = permissions.lock().await;
382                         ps.get(&addr2ipfingerprint(&src_addr)).is_some()
383                     };
384 
385                     if exist {
386                         let msg = {
387                             let peer_address_attr = PeerAddress {
388                                 ip: src_addr.ip(),
389                                 port: src_addr.port(),
390                             };
391                             let data_attr = Data(buffer[..n].to_vec());
392 
393                             let mut msg = Message::new();
394                             if let Err(err) = msg.build(&[
395                                 Box::new(TransactionId::new()),
396                                 Box::new(MessageType::new(METHOD_DATA, CLASS_INDICATION)),
397                                 Box::new(peer_address_attr),
398                                 Box::new(data_attr),
399                             ]) {
400                                 log::error!(
401                                     "Failed to send DataIndication from allocation {} {}",
402                                     src_addr,
403                                     err
404                                 );
405                                 None
406                             } else {
407                                 Some(msg)
408                             }
409                         };
410 
411                         if let Some(msg) = msg {
412                             log::debug!(
413                                 "relaying message from {} to client at {}",
414                                 src_addr,
415                                 five_tuple.src_addr
416                             );
417                             if let Err(err) =
418                                 turn_socket.send_to(&msg.raw, five_tuple.src_addr).await
419                             {
420                                 log::error!(
421                                     "Failed to send DataIndication from allocation {} {}",
422                                     src_addr,
423                                     err
424                                 );
425                             }
426                         }
427                     } else {
428                         log::info!(
429                             "No Permission or Channel exists for {} on allocation {}",
430                             src_addr,
431                             relay_addr
432                         );
433                     }
434                 }
435             }
436         });
437     }
438 }
439