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