1 #[cfg(test)] 2 mod server_test; 3 4 pub mod config; 5 pub mod request; 6 7 use crate::{ 8 allocation::{allocation_manager::*, five_tuple::FiveTuple, AllocationInfo}, 9 auth::AuthHandler, 10 error::*, 11 proto::lifetime::DEFAULT_LIFETIME, 12 }; 13 use config::*; 14 use request::*; 15 16 use std::{collections::HashMap, sync::Arc}; 17 18 use tokio::{ 19 sync::{ 20 broadcast::{self, error::RecvError}, 21 mpsc, oneshot, Mutex, 22 }, 23 time::{Duration, Instant}, 24 }; 25 use util::Conn; 26 27 const INBOUND_MTU: usize = 1500; 28 29 /// Server is an instance of the TURN Server 30 pub struct Server { 31 auth_handler: Arc<dyn AuthHandler + Send + Sync>, 32 realm: String, 33 channel_bind_timeout: Duration, 34 pub(crate) nonces: Arc<Mutex<HashMap<String, Instant>>>, 35 command_tx: Mutex<Option<broadcast::Sender<Command>>>, 36 } 37 38 impl Server { 39 /// creates the TURN server 40 pub async fn new(config: ServerConfig) -> Result<Self> { 41 config.validate()?; 42 43 let (command_tx, _) = broadcast::channel(16); 44 let mut s = Server { 45 auth_handler: config.auth_handler, 46 realm: config.realm, 47 channel_bind_timeout: config.channel_bind_timeout, 48 nonces: Arc::new(Mutex::new(HashMap::new())), 49 command_tx: Mutex::new(Some(command_tx.clone())), 50 }; 51 52 if s.channel_bind_timeout == Duration::from_secs(0) { 53 s.channel_bind_timeout = DEFAULT_LIFETIME; 54 } 55 56 for p in config.conn_configs.into_iter() { 57 let nonces = Arc::clone(&s.nonces); 58 let auth_handler = Arc::clone(&s.auth_handler); 59 let realm = s.realm.clone(); 60 let channel_bind_timeout = s.channel_bind_timeout; 61 let handle_rx = command_tx.subscribe(); 62 let conn = p.conn; 63 let allocation_manager = Arc::new(Manager::new(ManagerConfig { 64 relay_addr_generator: p.relay_addr_generator, 65 })); 66 67 tokio::spawn(Server::read_loop( 68 conn, 69 allocation_manager, 70 nonces, 71 auth_handler, 72 realm, 73 channel_bind_timeout, 74 handle_rx, 75 )); 76 } 77 78 Ok(s) 79 } 80 81 /// Deletes all existing [`crate::allocation::Allocation`]s by the provided `username`. 82 pub async fn delete_allocations_by_username(&self, username: String) -> Result<()> { 83 let tx = { 84 let command_tx = self.command_tx.lock().await; 85 command_tx.clone() 86 }; 87 if let Some(tx) = tx { 88 let (closed_tx, closed_rx) = mpsc::channel(1); 89 tx.send(Command::DeleteAllocations(username, Arc::new(closed_rx))) 90 .map_err(|_| Error::ErrClosed)?; 91 92 closed_tx.closed().await; 93 94 Ok(()) 95 } else { 96 Err(Error::ErrClosed) 97 } 98 } 99 100 /// Get information of [`Allocation`]s by specified [`FiveTuple`]s. 101 /// 102 /// If `five_tuples` is: 103 /// - [`None`]: It returns information about the all 104 /// [`Allocation`]s. 105 /// - [`Some`] and not empty: It returns information about 106 /// the [`Allocation`]s associated with 107 /// the specified [`FiveTuples`]. 108 /// - [`Some`], but empty: It returns an empty [`HashMap`]. 109 /// 110 /// [`Allocation`]: crate::allocation::Allocation 111 pub async fn get_allocations_info( 112 &self, 113 five_tuples: Option<Vec<FiveTuple>>, 114 ) -> Result<HashMap<FiveTuple, AllocationInfo>> { 115 if let Some(five_tuples) = &five_tuples { 116 if five_tuples.is_empty() { 117 return Ok(HashMap::new()); 118 } 119 } 120 121 let tx = { 122 let command_tx = self.command_tx.lock().await; 123 command_tx.clone() 124 }; 125 if let Some(tx) = tx { 126 let (infos_tx, mut infos_rx) = mpsc::channel(1); 127 tx.send(Command::GetAllocationsInfo(five_tuples, infos_tx)) 128 .map_err(|_| Error::ErrClosed)?; 129 130 let mut info: HashMap<FiveTuple, AllocationInfo> = HashMap::new(); 131 132 for _ in 0..tx.receiver_count() { 133 info.extend(infos_rx.recv().await.ok_or(Error::ErrClosed)?); 134 } 135 136 Ok(info) 137 } else { 138 Err(Error::ErrClosed) 139 } 140 } 141 142 async fn read_loop( 143 conn: Arc<dyn Conn + Send + Sync>, 144 allocation_manager: Arc<Manager>, 145 nonces: Arc<Mutex<HashMap<String, Instant>>>, 146 auth_handler: Arc<dyn AuthHandler + Send + Sync>, 147 realm: String, 148 channel_bind_timeout: Duration, 149 mut handle_rx: broadcast::Receiver<Command>, 150 ) { 151 let mut buf = vec![0u8; INBOUND_MTU]; 152 153 let (mut close_tx, mut close_rx) = oneshot::channel::<()>(); 154 155 tokio::spawn({ 156 let allocation_manager = Arc::clone(&allocation_manager); 157 158 async move { 159 loop { 160 match handle_rx.recv().await { 161 Ok(Command::DeleteAllocations(name, _)) => { 162 allocation_manager 163 .delete_allocations_by_username(name.as_str()) 164 .await; 165 continue; 166 } 167 Ok(Command::GetAllocationsInfo(five_tuples, tx)) => { 168 let infos = allocation_manager.get_allocations_info(five_tuples).await; 169 let _ = tx.send(infos).await; 170 171 continue; 172 } 173 Err(RecvError::Closed) | Ok(Command::Close(_)) => { 174 close_rx.close(); 175 break; 176 } 177 Err(RecvError::Lagged(n)) => { 178 log::warn!("Turn server has lagged by {} messages", n); 179 continue; 180 } 181 } 182 } 183 } 184 }); 185 186 loop { 187 let (n, addr) = tokio::select! { 188 v = conn.recv_from(&mut buf) => { 189 match v { 190 Ok(v) => v, 191 Err(err) => { 192 log::debug!("exit read loop on error: {}", err); 193 break; 194 } 195 } 196 }, 197 _ = close_tx.closed() => break 198 }; 199 200 let mut r = Request { 201 conn: Arc::clone(&conn), 202 src_addr: addr, 203 buff: buf[..n].to_vec(), 204 allocation_manager: Arc::clone(&allocation_manager), 205 nonces: Arc::clone(&nonces), 206 auth_handler: Arc::clone(&auth_handler), 207 realm: realm.clone(), 208 channel_bind_timeout, 209 }; 210 211 if let Err(err) = r.handle_request().await { 212 log::error!("error when handling datagram: {}", err); 213 } 214 } 215 216 let _ = allocation_manager.close().await; 217 let _ = conn.close().await; 218 } 219 220 /// Close stops the TURN Server. It cleans up any associated state and closes all connections it is managing 221 pub async fn close(&self) -> Result<()> { 222 let tx = { 223 let mut command_tx = self.command_tx.lock().await; 224 command_tx.take() 225 }; 226 227 if let Some(tx) = tx { 228 if tx.receiver_count() == 0 { 229 return Ok(()); 230 } 231 232 let (closed_tx, closed_rx) = mpsc::channel(1); 233 let _ = tx.send(Command::Close(Arc::new(closed_rx))); 234 closed_tx.closed().await 235 } 236 237 Ok(()) 238 } 239 } 240 241 /// The protocol to communicate between the [`Server`]'s public methods 242 /// and the tasks spawned in the [`read_loop`] method. 243 #[derive(Clone)] 244 enum Command { 245 /// Command to delete [`crate::allocation::Allocation`] by provided 246 /// `username`. 247 DeleteAllocations(String, Arc<mpsc::Receiver<()>>), 248 249 /// Command to get information of [`Allocation`]s by provided [`FiveTuple`]s. 250 /// 251 /// [`Allocation`]: [`crate::allocation::Allocation`] 252 GetAllocationsInfo( 253 Option<Vec<FiveTuple>>, 254 mpsc::Sender<HashMap<FiveTuple, AllocationInfo>>, 255 ), 256 257 /// Command to close the [`Server`]. 258 Close(Arc<mpsc::Receiver<()>>), 259 } 260