1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
use futures::Async;
use std::net::SocketAddr;
use {ErrorKind, PeerAddr, PollRecv, PollSend, Result, TcpTransport, Transport, UdpTransport};
#[derive(Debug)]
pub struct FixedPeerTransporter<T: Transport, P = <T as Transport>::PeerAddr> {
exterior_peer: P,
interior_peer: T::PeerAddr,
inner: T,
}
impl<T: Transport, P> FixedPeerTransporter<T, P> {
pub fn new(exterior_peer: P, interior_peer: T::PeerAddr, inner: T) -> Self {
FixedPeerTransporter {
exterior_peer,
interior_peer,
inner,
}
}
pub fn inner_ref(&self) -> &T {
&self.inner
}
pub fn inner_mut(&mut self) -> &mut T {
&mut self.inner
}
pub fn exterior_peer(&self) -> &P {
&self.exterior_peer
}
pub fn interior_peer(&self) -> &T::PeerAddr {
&self.interior_peer
}
}
impl<T: Transport, P: PeerAddr> Transport for FixedPeerTransporter<T, P> {
type PeerAddr = P;
type SendItem = T::SendItem;
type RecvItem = T::RecvItem;
fn start_send(&mut self, peer: Self::PeerAddr, item: Self::SendItem) -> Result<()> {
track_assert_eq!(
peer,
self.exterior_peer,
ErrorKind::InvalidInput,
"Unexpected destination peer"
);
self.inner.start_send(self.interior_peer.clone(), item)
}
fn poll_send(&mut self) -> PollSend {
self.inner.poll_send()
}
fn poll_recv(&mut self) -> PollRecv<(Self::PeerAddr, Self::RecvItem)> {
loop {
match self.inner.poll_recv()? {
Async::NotReady => return Ok(Async::NotReady),
Async::Ready(None) => return Ok(Async::Ready(None)),
Async::Ready(Some((peer, item))) => if peer == self.interior_peer {
return Ok(Async::Ready(Some((self.exterior_peer.clone(), item))));
},
}
}
}
}
impl<T: UdpTransport> UdpTransport for FixedPeerTransporter<T, SocketAddr> {
fn local_addr(&self) -> SocketAddr {
self.inner.local_addr()
}
}
impl<T: TcpTransport> From<T> for FixedPeerTransporter<T, SocketAddr> {
fn from(f: T) -> Self {
FixedPeerTransporter::new(f.peer_addr(), (), f)
}
}