xref: /webrtc/ice/src/agent/agent_transport.rs (revision 5b79f08a)
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