1 use super::*; 2 use crate::error::*; 3 4 use arc_swap::ArcSwapOption; 5 use async_trait::async_trait; 6 use std::io; 7 use std::sync::atomic::{AtomicBool, Ordering}; 8 use util::Conn; 9 10 impl Agent { 11 /// Connects to the remote agent, acting as the controlling ice agent. 12 /// The method blocks until at least one ice candidate pair has successfully connected. 13 /// 14 /// The operation will be cancelled if `cancel_rx` either receives a message or its channel 15 /// closes. dial( &self, mut cancel_rx: mpsc::Receiver<()>, remote_ufrag: String, remote_pwd: String, ) -> Result<Arc<impl Conn>>16 pub async fn dial( 17 &self, 18 mut cancel_rx: mpsc::Receiver<()>, 19 remote_ufrag: String, 20 remote_pwd: String, 21 ) -> Result<Arc<impl Conn>> { 22 let (on_connected_rx, agent_conn) = { 23 self.internal 24 .start_connectivity_checks(true, remote_ufrag, remote_pwd) 25 .await?; 26 27 let mut on_connected_rx = self.internal.on_connected_rx.lock().await; 28 ( 29 on_connected_rx.take(), 30 Arc::clone(&self.internal.agent_conn), 31 ) 32 }; 33 34 if let Some(mut on_connected_rx) = on_connected_rx { 35 // block until pair selected 36 tokio::select! { 37 _ = on_connected_rx.recv() => {}, 38 _ = cancel_rx.recv() => { 39 return Err(Error::ErrCanceledByCaller); 40 } 41 } 42 } 43 Ok(agent_conn) 44 } 45 46 /// Connects to the remote agent, acting as the controlled ice agent. 47 /// The method blocks until at least one ice candidate pair has successfully connected. 48 /// 49 /// The operation will be cancelled if `cancel_rx` either receives a message or its channel 50 /// closes. accept( &self, mut cancel_rx: mpsc::Receiver<()>, remote_ufrag: String, remote_pwd: String, ) -> Result<Arc<impl Conn>>51 pub async fn accept( 52 &self, 53 mut cancel_rx: mpsc::Receiver<()>, 54 remote_ufrag: String, 55 remote_pwd: String, 56 ) -> Result<Arc<impl Conn>> { 57 let (on_connected_rx, agent_conn) = { 58 self.internal 59 .start_connectivity_checks(false, remote_ufrag, remote_pwd) 60 .await?; 61 62 let mut on_connected_rx = self.internal.on_connected_rx.lock().await; 63 ( 64 on_connected_rx.take(), 65 Arc::clone(&self.internal.agent_conn), 66 ) 67 }; 68 69 if let Some(mut on_connected_rx) = on_connected_rx { 70 // block until pair selected 71 tokio::select! { 72 _ = on_connected_rx.recv() => {}, 73 _ = cancel_rx.recv() => { 74 return Err(Error::ErrCanceledByCaller); 75 } 76 } 77 } 78 79 Ok(agent_conn) 80 } 81 } 82 83 pub(crate) struct AgentConn { 84 pub(crate) selected_pair: ArcSwapOption<CandidatePair>, 85 pub(crate) checklist: Mutex<Vec<Arc<CandidatePair>>>, 86 87 pub(crate) buffer: Buffer, 88 pub(crate) bytes_received: AtomicUsize, 89 pub(crate) bytes_sent: AtomicUsize, 90 pub(crate) done: AtomicBool, 91 } 92 93 impl AgentConn { new() -> Self94 pub(crate) fn new() -> Self { 95 Self { 96 selected_pair: ArcSwapOption::empty(), 97 checklist: Mutex::new(vec![]), 98 // Make sure the buffer doesn't grow indefinitely. 99 // NOTE: We actually won't get anywhere close to this limit. 100 // SRTP will constantly read from the endpoint and drop packets if it's full. 101 buffer: Buffer::new(0, MAX_BUFFER_SIZE), 102 bytes_received: AtomicUsize::new(0), 103 bytes_sent: AtomicUsize::new(0), 104 done: AtomicBool::new(false), 105 } 106 } get_selected_pair(&self) -> Option<Arc<CandidatePair>>107 pub(crate) fn get_selected_pair(&self) -> Option<Arc<CandidatePair>> { 108 self.selected_pair.load().clone() 109 } 110 get_best_available_candidate_pair(&self) -> Option<Arc<CandidatePair>>111 pub(crate) async fn get_best_available_candidate_pair(&self) -> Option<Arc<CandidatePair>> { 112 let mut best: Option<&Arc<CandidatePair>> = None; 113 114 let checklist = self.checklist.lock().await; 115 for p in &*checklist { 116 if p.state.load(Ordering::SeqCst) == CandidatePairState::Failed as u8 { 117 continue; 118 } 119 120 if let Some(b) = &mut best { 121 if b.priority() < p.priority() { 122 *b = p; 123 } 124 } else { 125 best = Some(p); 126 } 127 } 128 129 best.cloned() 130 } 131 get_best_valid_candidate_pair(&self) -> Option<Arc<CandidatePair>>132 pub(crate) async fn get_best_valid_candidate_pair(&self) -> Option<Arc<CandidatePair>> { 133 let mut best: Option<&Arc<CandidatePair>> = None; 134 135 let checklist = self.checklist.lock().await; 136 for p in &*checklist { 137 if p.state.load(Ordering::SeqCst) != CandidatePairState::Succeeded as u8 { 138 continue; 139 } 140 141 if let Some(b) = &mut best { 142 if b.priority() < p.priority() { 143 *b = p; 144 } 145 } else { 146 best = Some(p); 147 } 148 } 149 150 best.cloned() 151 } 152 153 /// Returns the number of bytes sent. bytes_sent(&self) -> usize154 pub fn bytes_sent(&self) -> usize { 155 self.bytes_sent.load(Ordering::SeqCst) 156 } 157 158 /// Returns the number of bytes received. bytes_received(&self) -> usize159 pub fn bytes_received(&self) -> usize { 160 self.bytes_received.load(Ordering::SeqCst) 161 } 162 } 163 164 #[async_trait] 165 impl Conn for AgentConn { connect(&self, _addr: SocketAddr) -> std::result::Result<(), util::Error>166 async fn connect(&self, _addr: SocketAddr) -> std::result::Result<(), util::Error> { 167 Err(io::Error::new(io::ErrorKind::Other, "Not applicable").into()) 168 } 169 recv(&self, buf: &mut [u8]) -> std::result::Result<usize, util::Error>170 async fn recv(&self, buf: &mut [u8]) -> std::result::Result<usize, util::Error> { 171 if self.done.load(Ordering::SeqCst) { 172 return Err(io::Error::new(io::ErrorKind::Other, "Conn is closed").into()); 173 } 174 175 let n = match self.buffer.read(buf, None).await { 176 Ok(n) => n, 177 Err(err) => return Err(io::Error::new(io::ErrorKind::Other, err.to_string()).into()), 178 }; 179 self.bytes_received.fetch_add(n, Ordering::SeqCst); 180 181 Ok(n) 182 } 183 recv_from( &self, buf: &mut [u8], ) -> std::result::Result<(usize, SocketAddr), util::Error>184 async fn recv_from( 185 &self, 186 buf: &mut [u8], 187 ) -> std::result::Result<(usize, SocketAddr), util::Error> { 188 if let Some(raddr) = self.remote_addr() { 189 let n = self.recv(buf).await?; 190 Ok((n, raddr)) 191 } else { 192 Err(io::Error::new(io::ErrorKind::Other, "Not applicable").into()) 193 } 194 } 195 send(&self, buf: &[u8]) -> std::result::Result<usize, util::Error>196 async fn send(&self, buf: &[u8]) -> std::result::Result<usize, util::Error> { 197 if self.done.load(Ordering::SeqCst) { 198 return Err(io::Error::new(io::ErrorKind::Other, "Conn is closed").into()); 199 } 200 201 if is_message(buf) { 202 return Err(util::Error::Other("ErrIceWriteStunMessage".into())); 203 } 204 205 let result = if let Some(pair) = self.get_selected_pair() { 206 pair.write(buf).await 207 } else if let Some(pair) = self.get_best_available_candidate_pair().await { 208 pair.write(buf).await 209 } else { 210 Ok(0) 211 }; 212 213 match result { 214 Ok(n) => { 215 self.bytes_sent.fetch_add(buf.len(), Ordering::SeqCst); 216 Ok(n) 217 } 218 Err(err) => Err(io::Error::new(io::ErrorKind::Other, err.to_string()).into()), 219 } 220 } 221 send_to( &self, _buf: &[u8], _target: SocketAddr, ) -> std::result::Result<usize, util::Error>222 async fn send_to( 223 &self, 224 _buf: &[u8], 225 _target: SocketAddr, 226 ) -> std::result::Result<usize, util::Error> { 227 Err(io::Error::new(io::ErrorKind::Other, "Not applicable").into()) 228 } 229 local_addr(&self) -> std::result::Result<SocketAddr, util::Error>230 fn local_addr(&self) -> std::result::Result<SocketAddr, util::Error> { 231 if let Some(pair) = self.get_selected_pair() { 232 Ok(pair.local.addr()) 233 } else { 234 Err(io::Error::new(io::ErrorKind::AddrNotAvailable, "Addr Not Available").into()) 235 } 236 } 237 remote_addr(&self) -> Option<SocketAddr>238 fn remote_addr(&self) -> Option<SocketAddr> { 239 self.get_selected_pair().map(|pair| pair.remote.addr()) 240 } 241 close(&self) -> std::result::Result<(), util::Error>242 async fn close(&self) -> std::result::Result<(), util::Error> { 243 Ok(()) 244 } 245 } 246