xref: /webrtc/util/src/conn/conn_bridge.rs (revision 5b79f08a)
1 use super::*;
2 
3 use bytes::Bytes;
4 use std::collections::VecDeque;
5 use std::io::{Error, ErrorKind};
6 use std::str::FromStr;
7 use std::sync::atomic::{AtomicUsize, Ordering};
8 use std::sync::Arc;
9 use tokio::sync::{mpsc, Mutex};
10 use tokio::time::Duration;
11 
12 const TICK_WAIT: Duration = Duration::from_micros(10);
13 
14 /// BridgeConn is a Conn that represents an endpoint of the bridge.
15 struct BridgeConn {
16     br: Arc<Bridge>,
17     id: usize,
18     rd_rx: Mutex<mpsc::Receiver<Bytes>>,
19     loss_chance: u8,
20 }
21 
22 #[async_trait]
23 impl Conn for BridgeConn {
connect(&self, _addr: SocketAddr) -> Result<()>24     async fn connect(&self, _addr: SocketAddr) -> Result<()> {
25         Err(Error::new(ErrorKind::Other, "Not applicable").into())
26     }
27 
recv(&self, b: &mut [u8]) -> Result<usize>28     async fn recv(&self, b: &mut [u8]) -> Result<usize> {
29         let mut rd_rx = self.rd_rx.lock().await;
30         let v = match rd_rx.recv().await {
31             Some(v) => v,
32             None => return Err(Error::new(ErrorKind::UnexpectedEof, "Unexpected EOF").into()),
33         };
34         let l = std::cmp::min(v.len(), b.len());
35         b[..l].copy_from_slice(&v[..l]);
36         Ok(l)
37     }
38 
recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)>39     async fn recv_from(&self, buf: &mut [u8]) -> Result<(usize, SocketAddr)> {
40         let n = self.recv(buf).await?;
41         Ok((n, SocketAddr::from_str("0.0.0.0:0")?))
42     }
43 
send(&self, b: &[u8]) -> Result<usize>44     async fn send(&self, b: &[u8]) -> Result<usize> {
45         if rand::random::<u8>() % 100 < self.loss_chance {
46             return Ok(b.len());
47         }
48 
49         self.br.push(b, self.id).await
50     }
51 
send_to(&self, _buf: &[u8], _target: SocketAddr) -> Result<usize>52     async fn send_to(&self, _buf: &[u8], _target: SocketAddr) -> Result<usize> {
53         Err(Error::new(ErrorKind::Other, "Not applicable").into())
54     }
55 
local_addr(&self) -> Result<SocketAddr>56     fn local_addr(&self) -> Result<SocketAddr> {
57         Err(Error::new(ErrorKind::AddrNotAvailable, "Addr Not Available").into())
58     }
59 
remote_addr(&self) -> Option<SocketAddr>60     fn remote_addr(&self) -> Option<SocketAddr> {
61         None
62     }
63 
close(&self) -> Result<()>64     async fn close(&self) -> Result<()> {
65         Ok(())
66     }
67 }
68 
69 pub type FilterCbFn = Box<dyn Fn(&Bytes) -> bool + Send + Sync>;
70 
71 /// Bridge represents a network between the two endpoints.
72 #[derive(Default)]
73 pub struct Bridge {
74     drop_nwrites: [AtomicUsize; 2],
75     reorder_nwrites: [AtomicUsize; 2],
76 
77     stack: [Mutex<VecDeque<Bytes>>; 2],
78     queue: [Mutex<VecDeque<Bytes>>; 2],
79 
80     wr_tx: [Option<mpsc::Sender<Bytes>>; 2],
81     filter_cb: [Option<FilterCbFn>; 2],
82 }
83 
84 impl Bridge {
new( loss_chance: u8, filter_cb0: Option<FilterCbFn>, filter_cb1: Option<FilterCbFn>, ) -> (Arc<Bridge>, impl Conn, impl Conn)85     pub fn new(
86         loss_chance: u8,
87         filter_cb0: Option<FilterCbFn>,
88         filter_cb1: Option<FilterCbFn>,
89     ) -> (Arc<Bridge>, impl Conn, impl Conn) {
90         let (wr_tx0, rd_rx0) = mpsc::channel(1024);
91         let (wr_tx1, rd_rx1) = mpsc::channel(1024);
92 
93         let br = Arc::new(Bridge {
94             wr_tx: [Some(wr_tx0), Some(wr_tx1)],
95             filter_cb: [filter_cb0, filter_cb1],
96             ..Default::default()
97         });
98         let conn0 = BridgeConn {
99             br: Arc::clone(&br),
100             id: 0,
101             rd_rx: Mutex::new(rd_rx0),
102             loss_chance,
103         };
104         let conn1 = BridgeConn {
105             br: Arc::clone(&br),
106             id: 1,
107             rd_rx: Mutex::new(rd_rx1),
108             loss_chance,
109         };
110 
111         (br, conn0, conn1)
112     }
113 
114     /// Len returns number of queued packets.
115     #[allow(clippy::len_without_is_empty)]
len(&self, id: usize) -> usize116     pub async fn len(&self, id: usize) -> usize {
117         let q = self.queue[id].lock().await;
118         q.len()
119     }
120 
push(&self, b: &[u8], id: usize) -> Result<usize>121     pub async fn push(&self, b: &[u8], id: usize) -> Result<usize> {
122         // Push rate should be limited as same as Tick rate.
123         // Otherwise, queue grows too fast on free running Write.
124         tokio::time::sleep(TICK_WAIT).await;
125 
126         let d = Bytes::from(b.to_vec());
127         if self.drop_nwrites[id].load(Ordering::SeqCst) > 0 {
128             self.drop_nwrites[id].fetch_sub(1, Ordering::SeqCst);
129         } else if self.reorder_nwrites[id].load(Ordering::SeqCst) > 0 {
130             let mut stack = self.stack[id].lock().await;
131             stack.push_back(d);
132             if self.reorder_nwrites[id].fetch_sub(1, Ordering::SeqCst) == 1 {
133                 let ok = inverse(&mut stack);
134                 if ok {
135                     let mut queue = self.queue[id].lock().await;
136                     queue.append(&mut stack);
137                 }
138             }
139         } else if let Some(filter_cb) = &self.filter_cb[id] {
140             if filter_cb(&d) {
141                 let mut queue = self.queue[id].lock().await;
142                 queue.push_back(d);
143             }
144         } else {
145             //log::debug!("queue [{}] enter lock", id);
146             let mut queue = self.queue[id].lock().await;
147             queue.push_back(d);
148             //log::debug!("queue [{}] exit lock", id);
149         }
150 
151         Ok(b.len())
152     }
153 
154     /// Reorder inverses the order of packets currently in the specified queue.
reorder(&self, id: usize) -> bool155     pub async fn reorder(&self, id: usize) -> bool {
156         let mut queue = self.queue[id].lock().await;
157         inverse(&mut queue)
158     }
159 
160     /// Drop drops the specified number of packets from the given offset index
161     /// of the specified queue.
drop_offset(&self, id: usize, offset: usize, n: usize)162     pub async fn drop_offset(&self, id: usize, offset: usize, n: usize) {
163         let mut queue = self.queue[id].lock().await;
164         queue.drain(offset..offset + n);
165     }
166 
167     /// drop_next_nwrites drops the next n packets that will be written
168     /// to the specified queue.
drop_next_nwrites(&self, id: usize, n: usize)169     pub fn drop_next_nwrites(&self, id: usize, n: usize) {
170         self.drop_nwrites[id].store(n, Ordering::SeqCst);
171     }
172 
173     /// reorder_next_nwrites drops the next n packets that will be written
174     /// to the specified queue.
reorder_next_nwrites(&self, id: usize, n: usize)175     pub fn reorder_next_nwrites(&self, id: usize, n: usize) {
176         self.reorder_nwrites[id].store(n, Ordering::SeqCst);
177     }
178 
clear(&self)179     pub async fn clear(&self) {
180         for id in 0..2 {
181             let mut queue = self.queue[id].lock().await;
182             queue.clear();
183         }
184     }
185 
186     /// Tick attempts to hand a packet from the queue for each directions, to readers,
187     /// if there are waiting on the queue. If there's no reader, it will return
188     /// immediately.
tick(&self) -> usize189     pub async fn tick(&self) -> usize {
190         let mut n = 0;
191 
192         for id in 0..2 {
193             let mut queue = self.queue[id].lock().await;
194             if let Some(d) = queue.pop_front() {
195                 n += 1;
196                 if let Some(wr_tx) = &self.wr_tx[1 - id] {
197                     let _ = wr_tx.send(d).await;
198                 }
199             }
200         }
201 
202         n
203     }
204 
205     /// Process repeats tick() calls until no more outstanding packet in the queues.
process(&self)206     pub async fn process(&self) {
207         loop {
208             tokio::time::sleep(TICK_WAIT).await;
209             self.tick().await;
210             if self.len(0).await == 0 && self.len(1).await == 0 {
211                 break;
212             }
213         }
214     }
215 }
216 
inverse(s: &mut VecDeque<Bytes>) -> bool217 pub(crate) fn inverse(s: &mut VecDeque<Bytes>) -> bool {
218     if s.len() < 2 {
219         return false;
220     }
221 
222     let (mut i, mut j) = (0, s.len() - 1);
223     while i < j {
224         s.swap(i, j);
225         i += 1;
226         j -= 1;
227     }
228 
229     true
230 }
231