1use async_trait::async_trait;
23use fnv::FnvHashMap;
24use futures::{channel::mpsc, prelude::*, task::Context, task::Poll};
25use futures::{SinkExt, StreamExt};
26use pin_project::pin_project;
27use std::{collections::hash_map::Entry, fmt, io, num::NonZeroU64, pin::Pin};
28
29use lazy_static::lazy_static;
30use libp2prs_multiaddr::{protocol, Multiaddr, Protocol};
31use parking_lot::Mutex;
32use rw_stream_sink::RwStreamSink;
33
34use crate::muxing::{IReadWrite, ReadWriteEx, StreamInfo};
35use crate::transport::{ConnectionInfo, IListener, ITransport, ListenerEvent, TransportListener};
36use crate::{transport::TransportError, Transport};
37lazy_static! {
41 static ref HUB: Mutex<FnvHashMap<NonZeroU64, mpsc::Sender<Channel>>> = Mutex::new(FnvHashMap::default());
42}
43
44#[derive(Debug, Clone, Default)]
48pub struct MemoryTransport;
49
50#[async_trait]
51impl Transport for MemoryTransport {
52 type Output = Channel;
53
54 fn listen_on(&mut self, addr: Multiaddr) -> Result<IListener<Self::Output>, TransportError> {
55 let port = if let Ok(port) = parse_memory_addr(&addr) {
56 port
57 } else {
58 return Err(TransportError::MultiaddrNotSupported(addr));
59 };
60
61 let mut hub = (&*HUB).lock();
62
63 let port = if let Some(port) = NonZeroU64::new(port) {
64 port
65 } else {
66 loop {
67 let port = match NonZeroU64::new(rand::random()) {
68 Some(p) => p,
69 None => continue,
70 };
71 if !hub.contains_key(&port) {
72 break port;
73 }
74 }
75 };
76
77 let (tx, rx) = mpsc::channel(2);
78 match hub.entry(port) {
79 Entry::Occupied(_) => return Err(TransportError::Unreachable),
80 Entry::Vacant(e) => e.insert(tx),
81 };
82
83 let listener = Box::new(Listener {
84 port,
85 addr: Protocol::Memory(port.get()).into(),
86 receiver: rx,
87 });
88
89 Ok(listener)
90 }
91
92 async fn dial(&mut self, addr: Multiaddr) -> Result<Self::Output, TransportError> {
93 let port = if let Ok(port) = parse_memory_addr(&addr) {
94 if let Some(port) = NonZeroU64::new(port) {
95 port
96 } else {
97 return Err(TransportError::Unreachable);
98 }
99 } else {
100 return Err(TransportError::MultiaddrNotSupported(addr));
101 };
102
103 let mut sender = {
105 let hub = HUB.lock();
106 if let Some(sender) = hub.get(&port) {
107 sender.clone()
108 } else {
109 return Err(TransportError::Unreachable);
110 }
111 };
112
113 let (a_tx, a_rx) = mpsc::channel(4096);
114 let (b_tx, b_rx) = mpsc::channel(4096);
115
116 let la = Multiaddr::empty();
117 let ra = addr;
118
119 let channel_to_send = Channel {
120 io: RwStreamSink::new(Chan {
121 incoming: a_rx,
122 outgoing: b_tx,
123 }),
124 la: la.clone(),
125 ra: ra.clone(),
126 };
127 let channel_to_return = Channel {
128 io: RwStreamSink::new(Chan {
129 incoming: b_rx,
130 outgoing: a_tx,
131 }),
132 la: la.clone(),
133 ra: ra.clone(),
134 };
135 sender.send(channel_to_send).await.map_err(|_| TransportError::Unreachable)?;
136 Ok(channel_to_return)
137 }
138
139 fn box_clone(&self) -> ITransport<Self::Output> {
140 Box::new(self.clone())
141 }
142
143 fn protocols(&self) -> Vec<u32> {
144 vec![protocol::MEMORY]
145 }
146}
147
148pub struct Listener {
150 port: NonZeroU64,
152 addr: Multiaddr,
154 receiver: mpsc::Receiver<Channel>,
156}
157
158#[async_trait]
159impl TransportListener for Listener {
160 type Output = Channel;
161
162 async fn accept(&mut self) -> Result<ListenerEvent<Self::Output>, TransportError> {
163 self.receiver
164 .next()
165 .await
166 .map(ListenerEvent::Accepted)
167 .ok_or(TransportError::Unreachable)
168 }
169
170 fn multi_addr(&self) -> Option<&Multiaddr> {
171 Some(&self.addr)
172 }
173}
174
175impl Drop for Listener {
176 fn drop(&mut self) {
177 let val_in = HUB.lock().remove(&self.port);
178 debug_assert!(val_in.is_some());
179 }
180}
181
182fn parse_memory_addr(a: &Multiaddr) -> Result<u64, ()> {
184 let mut iter = a.iter();
185
186 let port = if let Some(Protocol::Memory(port)) = iter.next() {
187 port
188 } else {
189 return Err(());
190 };
191
192 if iter.next().is_some() {
193 return Err(());
194 }
195
196 Ok(port)
197}
198
199#[pin_project]
203pub struct Channel {
204 #[pin]
205 io: RwStreamSink<Chan<Vec<u8>>>,
206 la: Multiaddr,
207 ra: Multiaddr,
208}
209
210impl fmt::Debug for Channel {
211 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
212 f.debug_struct("Channel").field("la", &self.la).field("ra", &self.ra).finish()
213 }
214}
215
216impl AsyncRead for Channel {
218 fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<usize>> {
219 let this = self.project();
220 this.io.poll_read(cx, buf)
221 }
222}
223impl AsyncWrite for Channel {
224 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
225 let this = self.project();
226 this.io.poll_write(cx, buf)
227 }
228
229 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
230 let this = self.project();
231 this.io.poll_flush(cx)
232 }
233
234 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
235 let this = self.project();
236 this.io.poll_close(cx)
237 }
238}
239
240pub struct Chan<T = Vec<u8>> {
244 incoming: mpsc::Receiver<T>,
245 outgoing: mpsc::Sender<T>,
246}
247
248impl<T> Unpin for Chan<T> {}
249
250impl<T> Stream for Chan<T> {
251 type Item = Result<T, io::Error>;
252
253 fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
254 match Stream::poll_next(Pin::new(&mut self.incoming), cx) {
255 Poll::Pending => Poll::Pending,
256 Poll::Ready(None) => Poll::Ready(Some(Err(io::ErrorKind::BrokenPipe.into()))),
257 Poll::Ready(Some(v)) => Poll::Ready(Some(Ok(v))),
258 }
259 }
260}
261
262impl<T> Sink<T> for Chan<T> {
263 type Error = io::Error;
264
265 fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
266 self.outgoing
267 .poll_ready(cx)
268 .map(|v| v.map_err(|_| io::ErrorKind::BrokenPipe.into()))
269 }
270
271 fn start_send(mut self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> {
272 self.outgoing.start_send(item).map_err(|_| io::ErrorKind::BrokenPipe.into())
273 }
274
275 fn poll_flush(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<(), Self::Error>> {
276 Poll::Ready(Ok(()))
277 }
278
279 fn poll_close(self: Pin<&mut Self>, _: &mut Context) -> Poll<Result<(), Self::Error>> {
280 Poll::Ready(Ok(()))
281 }
282}
283
284impl ConnectionInfo for Channel {
285 fn local_multiaddr(&self) -> Multiaddr {
286 self.la.clone()
287 }
288
289 fn remote_multiaddr(&self) -> Multiaddr {
290 self.ra.clone()
291 }
292}
293
294impl StreamInfo for Channel {
295 fn id(&self) -> usize {
296 0
297 }
298}
299
300impl ReadWriteEx for Channel {
301 fn box_clone(&self) -> IReadWrite {
302 unimplemented!()
303 }
304}
305
306#[cfg(test)]
307mod tests {
308 use super::*;
309 use libp2prs_runtime::task;
310
311 #[test]
312 fn parse_memory_addr_works() {
313 assert_eq!(parse_memory_addr(&"/memory/5".parse().unwrap()), Ok(5));
314 assert_eq!(parse_memory_addr(&"/tcp/150".parse().unwrap()), Err(()));
315 assert_eq!(parse_memory_addr(&"/memory/0".parse().unwrap()), Ok(0));
316 assert_eq!(parse_memory_addr(&"/memory/5/tcp/150".parse().unwrap()), Err(()));
317 assert_eq!(parse_memory_addr(&"/tcp/150/memory/5".parse().unwrap()), Err(()));
318 assert_eq!(parse_memory_addr(&"/memory/1234567890".parse().unwrap()), Ok(1_234_567_890));
319 }
320
321 #[test]
322 fn listening_twice() {
323 let mut transport = MemoryTransport::default();
324 assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
325 assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
326 let _listener = transport.listen_on("/memory/1639174018481".parse().unwrap()).unwrap();
327 assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_err());
328 assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_err());
329 drop(_listener);
330 assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
331 assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
332 }
333
334 #[test]
335 fn port_not_in_use() {
336 task::block_on(async move {
337 let mut transport = MemoryTransport::default();
338 assert!(transport.dial("/memory/810172461024613".parse().unwrap()).await.is_err());
339 let _listener = transport.listen_on("/memory/810172461024613".parse().unwrap()).unwrap();
340 assert!(transport.dial("/memory/810172461024613".parse().unwrap()).await.is_ok());
341 });
342 }
343
344 #[test]
345 fn communicating_between_dialer_and_listener() {
346 let msg = [1, 2, 3];
347
348 let rand_port = rand::random::<u64>().saturating_add(1);
350 let t1_addr: Multiaddr = format!("/memory/{}", rand_port).parse().unwrap();
351 let cloned_t1_addr = t1_addr.clone();
352
353 let mut t1 = MemoryTransport::default();
354 let listener = async move {
355 let mut listener = t1.listen_on(t1_addr.clone()).unwrap();
356 let mut socket = match listener.accept().await.unwrap() {
357 ListenerEvent::Accepted(socket) => socket,
358 _ => panic!("unreachable"),
359 };
360
361 let mut buf = [0; 3];
362 socket.read_exact(&mut buf).await.unwrap();
363 assert_eq!(buf, msg);
364 };
365
366 let mut t2 = MemoryTransport::default();
368 let dialer = async move {
369 let mut socket = t2.dial(cloned_t1_addr).await.unwrap();
370 socket.write_all(&msg).await.unwrap();
371 };
372
373 task::block_on(futures::future::join(listener, dialer));
375 }
376}