Skip to main content

volans_bridge/
transport.rs

1use std::{
2    collections::VecDeque,
3    io,
4    pin::Pin,
5    task::{Context, Poll, Waker},
6};
7
8use futures::{
9    AsyncRead, AsyncWrite, FutureExt, SinkExt, StreamExt,
10    channel::{mpsc, oneshot},
11    future::{self, BoxFuture},
12    ready,
13};
14use volans_codec::Bytes;
15use volans_core::{
16    Listener, ListenerEvent, Multiaddr, PeerId, Transport, TransportError, multiaddr::Protocol,
17};
18use volans_swarm::Substream;
19
20use crate::{
21    MultiaddrExt,
22    protocol::{Circuit, ConnectError},
23};
24
25pub struct Config {
26    behavior_sender: mpsc::Sender<TransportRequest>,
27}
28
29impl Config {
30    pub fn new() -> (Self, mpsc::Receiver<TransportRequest>) {
31        let (behavior_sender, behavior_receiver) = mpsc::channel(1000);
32        (Self { behavior_sender }, behavior_receiver)
33    }
34}
35
36// pub(crate) struct DialRequest {
37//     relay_addr: Multiaddr,
38//     relay_peer_id: PeerId,
39//     dst_addr: Option<Multiaddr>,
40//     dst_peer_id: PeerId,
41//     send_back: oneshot::Sender<Result<Connection, io::Error>>,
42// }
43
44impl Transport for Config {
45    type Output = Connection;
46    type Error = Error;
47    type Dial = future::BoxFuture<'static, Result<Self::Output, Self::Error>>;
48    type Incoming = future::Ready<Result<Self::Output, Self::Error>>;
49    type Listener = ListenerBackend;
50
51    fn dial(&self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
52        // 解析地址,获取中继地址和目标地址, 地址类型
53        // /ip4/127.0.0.1/udp/10088/quic-v1/peer/{relay-server-peer}/circuit/peer/{backend-peer}
54        let RelayedMultiaddr {
55            relay_peer_id,
56            relay_addr,
57            dst_peer_id,
58        } = parse_relayed_multiaddr(addr)?;
59        let relay_peer_id = relay_peer_id.ok_or(Error::MissingRelayPeerId)?;
60        let dst_peer_id = dst_peer_id.ok_or(Error::MissingDstPeerId)?;
61        let relay_addr = relay_addr.ok_or(Error::InvalidMultiaddr)?;
62
63        let mut behavior_sender = self.behavior_sender.clone();
64
65        Ok(async move {
66            let (tx, rx) = oneshot::channel();
67            let request = TransportRequest::DialRequest {
68                relay_addr,
69                relay_peer_id,
70                dst_peer_id,
71                send_back: tx,
72            };
73            behavior_sender.send(request).await?;
74            let stream = rx.await??;
75            tracing::info!("Dialed relay peer: {}", dst_peer_id);
76            Ok(stream)
77        }
78        .boxed())
79    }
80    fn listen(&self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
81        if !addr.is_circuit() {
82            return Err(TransportError::NotSupported(addr));
83        }
84
85        let (listener_sender, incoming_stream) = mpsc::channel(100);
86
87        let listen_request = TransportRequest::ListenRequest {
88            local_addr: addr.clone(),
89            listener_sender,
90        };
91        tracing::trace!("new circuit listener addr: {}", addr);
92
93        let listener = ListenerBackend {
94            local_addr: addr,
95            pending_request: Some(listen_request),
96            behavior_sender: self.behavior_sender.clone(),
97            incoming_stream,
98            closed: false,
99            waker: None,
100            pending_events: VecDeque::new(),
101        };
102        Ok(listener)
103    }
104}
105
106pub struct ListenerBackend {
107    local_addr: Multiaddr,
108    pending_request: Option<TransportRequest>,
109    behavior_sender: mpsc::Sender<TransportRequest>,
110    incoming_stream: mpsc::Receiver<IncomingRelayedConnection>,
111    closed: bool,
112    waker: Option<Waker>,
113    pending_events: VecDeque<ListenerEvent<<Self as Listener>::Upgrade, <Self as Listener>::Error>>,
114}
115
116impl Listener for ListenerBackend {
117    type Output = Connection;
118    type Error = Error;
119    type Upgrade = future::Ready<Result<Self::Output, Self::Error>>;
120
121    fn poll_event(
122        mut self: Pin<&mut Self>,
123        cx: &mut Context<'_>,
124    ) -> Poll<ListenerEvent<Self::Upgrade, Self::Error>> {
125        loop {
126            if let Some(event) = self.pending_events.pop_front() {
127                return Poll::Ready(event);
128            }
129            if self.closed {
130                self.waker = None;
131                return Poll::Ready(ListenerEvent::Closed(Ok(())));
132            }
133
134            if self.pending_request.is_some() {
135                if self.behavior_sender.poll_ready(cx).is_ready() {
136                    if let Some(request) = self.pending_request.take() {
137                        let _ = self.behavior_sender.start_send(request);
138                        let addr = self.local_addr.clone();
139                        self.pending_events
140                            .push_back(ListenerEvent::NewAddress(addr));
141                        continue;
142                    }
143                }
144            }
145
146            match self.incoming_stream.poll_next_unpin(cx) {
147                Poll::Ready(Some(IncomingRelayedConnection {
148                    stream,
149                    src_peer_id,
150                    _relay_peer_id: _,
151                    relay_addr,
152                })) => {
153                    tracing::info!("Received incoming relayed connection from: {}", src_peer_id);
154                    self.pending_events.push_back(ListenerEvent::Incoming {
155                        local_addr: relay_addr.with(Protocol::Circuit),
156                        remote_addr: Protocol::Peer(src_peer_id).into(),
157                        upgrade: future::ready(Ok(stream)),
158                    });
159                    continue;
160                }
161                Poll::Ready(None) => {
162                    self.pending_events.push_back(ListenerEvent::Closed(Ok(())));
163                    self.closed = true;
164                    continue;
165                }
166                Poll::Pending => {
167                    self.waker = Some(cx.waker().clone());
168                }
169            };
170            return Poll::Pending;
171        }
172    }
173
174    fn poll_close(
175        mut self: Pin<&mut Self>,
176        _cx: &mut Context<'_>,
177    ) -> Poll<Result<(), Self::Error>> {
178        self.pending_events.push_back(ListenerEvent::Closed(Ok(())));
179        self.closed = true;
180        if let Some(waker) = self.waker.take() {
181            waker.wake();
182        }
183        Poll::Ready(Ok(()))
184    }
185}
186
187pub struct IncomingRelayedConnection {
188    stream: Connection,
189    /// 源端的 PeerId
190    src_peer_id: PeerId,
191    /// 中继端的 PeerId
192    _relay_peer_id: PeerId,
193    /// 中继端的地址
194    relay_addr: Multiaddr,
195}
196
197impl IncomingRelayedConnection {
198    pub fn new(
199        stream: Connection,
200        src_peer_id: PeerId,
201        relay_peer_id: PeerId,
202        relay_addr: Multiaddr,
203    ) -> Self {
204        Self {
205            stream,
206            src_peer_id,
207            _relay_peer_id: relay_peer_id,
208            relay_addr,
209        }
210    }
211}
212
213pub enum TransportRequest {
214    DialRequest {
215        relay_addr: Multiaddr,
216        relay_peer_id: PeerId,
217        dst_peer_id: PeerId,
218        send_back: oneshot::Sender<Result<Connection, ConnectError>>,
219    },
220    ListenRequest {
221        local_addr: Multiaddr,
222        listener_sender: mpsc::Sender<IncomingRelayedConnection>,
223    },
224}
225
226#[derive(Debug, thiserror::Error)]
227pub enum Error {
228    #[error("Missing relay peer id")]
229    MissingRelayPeerId,
230    #[error("Missing destination peer id")]
231    MissingDstPeerId,
232    #[error("Multiple circuit addresses found")]
233    MultipleCircuit,
234    #[error("Invalid circuit multiaddr format")]
235    InvalidMultiaddr,
236    #[error("Transport not supported for address: {0}")]
237    BehaviorSend(#[from] mpsc::SendError),
238    #[error("Transport error: {0}")]
239    BehaviorResponse(#[from] oneshot::Canceled),
240    #[error("Transport error: {0}")]
241    ConnectError(#[from] ConnectError),
242    #[error("I/O error: {0}")]
243    Io(#[from] io::Error),
244}
245
246#[derive(Default)]
247struct RelayedMultiaddr {
248    relay_peer_id: Option<PeerId>,
249    relay_addr: Option<Multiaddr>,
250    dst_peer_id: Option<PeerId>,
251}
252
253fn parse_relayed_multiaddr(addr: Multiaddr) -> Result<RelayedMultiaddr, TransportError<Error>> {
254    if !addr.is_circuit() {
255        return Err(TransportError::NotSupported(addr));
256    }
257
258    let mut relayed_multiaddr = RelayedMultiaddr::default();
259    let mut before_circuit = true;
260    for protocol in addr.into_iter() {
261        match protocol {
262            Protocol::Circuit => {
263                if before_circuit {
264                    before_circuit = false;
265                } else {
266                    return Err(Error::MultipleCircuit.into());
267                }
268            }
269            Protocol::Peer(peer_id) if before_circuit => {
270                if relayed_multiaddr.relay_peer_id.is_some() {
271                    return Err(Error::InvalidMultiaddr.into());
272                }
273                relayed_multiaddr.relay_peer_id = Some(peer_id);
274            }
275            Protocol::Peer(peer_id) if !before_circuit => {
276                if relayed_multiaddr.dst_peer_id.is_some() {
277                    return Err(Error::InvalidMultiaddr.into());
278                }
279                relayed_multiaddr.dst_peer_id = Some(peer_id);
280            }
281            p => {
282                if before_circuit {
283                    relayed_multiaddr
284                        .relay_addr
285                        .get_or_insert(Multiaddr::empty())
286                        .push(p);
287                } else {
288                    return Err(Error::InvalidMultiaddr.into());
289                }
290            }
291        }
292    }
293    Ok(relayed_multiaddr)
294}
295
296pub struct Connection {
297    pub(crate) state: ConnectionState,
298}
299
300impl Connection {
301    pub(crate) fn new_accepting(circuit: Circuit) -> Self {
302        Connection {
303            state: ConnectionState::Accepting {
304                accept: async {
305                    let (substream, read_buffer) = circuit.accept().await?;
306                    Ok(ConnectionState::Accepted {
307                        read_buffer,
308                        substream,
309                    })
310                }
311                .boxed(),
312            },
313        }
314    }
315
316    pub(crate) fn new_accepted(substream: Substream, read_buffer: Bytes) -> Self {
317        Connection {
318            state: ConnectionState::Accepted {
319                read_buffer,
320                substream,
321            },
322        }
323    }
324}
325
326pub(crate) enum ConnectionState {
327    Accepting {
328        accept: BoxFuture<'static, Result<ConnectionState, io::Error>>,
329    },
330    Accepted {
331        read_buffer: Bytes,
332        substream: Substream,
333    },
334}
335
336impl Unpin for ConnectionState {}
337
338impl AsyncWrite for Connection {
339    fn poll_write(
340        mut self: Pin<&mut Self>,
341        cx: &mut Context<'_>,
342        buf: &[u8],
343    ) -> Poll<io::Result<usize>> {
344        loop {
345            match &mut self.state {
346                ConnectionState::Accepting { accept } => {
347                    *self = Connection {
348                        state: ready!(accept.poll_unpin(cx))?,
349                    };
350                }
351                ConnectionState::Accepted { substream, .. } => {
352                    return Pin::new(substream).poll_write(cx, buf);
353                }
354            }
355        }
356    }
357
358    fn poll_write_vectored(
359        mut self: Pin<&mut Self>,
360        cx: &mut Context<'_>,
361        bufs: &[io::IoSlice<'_>],
362    ) -> Poll<io::Result<usize>> {
363        loop {
364            match &mut self.state {
365                ConnectionState::Accepting { accept } => {
366                    *self = Connection {
367                        state: ready!(accept.poll_unpin(cx))?,
368                    };
369                }
370                ConnectionState::Accepted { substream, .. } => {
371                    return Pin::new(substream).poll_write_vectored(cx, bufs);
372                }
373            }
374        }
375    }
376
377    fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
378        loop {
379            match &mut self.state {
380                ConnectionState::Accepting { accept } => {
381                    *self = Connection {
382                        state: ready!(accept.poll_unpin(cx))?,
383                    };
384                }
385                ConnectionState::Accepted { substream, .. } => {
386                    return Pin::new(substream).poll_flush(cx);
387                }
388            }
389        }
390    }
391
392    fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
393        loop {
394            match &mut self.state {
395                ConnectionState::Accepting { accept } => {
396                    *self = Connection {
397                        state: ready!(accept.poll_unpin(cx))?,
398                    };
399                }
400                ConnectionState::Accepted { substream, .. } => {
401                    return Pin::new(substream).poll_close(cx);
402                }
403            }
404        }
405    }
406}
407
408impl AsyncRead for Connection {
409    fn poll_read(
410        mut self: Pin<&mut Self>,
411        cx: &mut Context<'_>,
412        buf: &mut [u8],
413    ) -> Poll<io::Result<usize>> {
414        loop {
415            match &mut self.state {
416                ConnectionState::Accepting { accept } => {
417                    *self = Connection {
418                        state: ready!(accept.poll_unpin(cx))?,
419                    };
420                }
421                ConnectionState::Accepted {
422                    read_buffer,
423                    substream,
424                } => {
425                    // 先从 read_buffer 中读取数据
426                    if !read_buffer.is_empty() {
427                        let n = read_buffer.len().min(buf.len());
428                        let data = read_buffer.split_to(n);
429                        buf[0..n].copy_from_slice(&data[..]);
430                        return Poll::Ready(Ok(n));
431                    }
432                    return Pin::new(substream).poll_read(cx, buf);
433                }
434            }
435        }
436    }
437}