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