cuprate_p2p_core/network_zones/
clear.rs1use std::{
2 net::{IpAddr, SocketAddr},
3 pin::Pin,
4 task::{Context, Poll},
5};
6
7use futures::Stream;
8use tokio::net::{
9 tcp::{OwnedReadHalf, OwnedWriteHalf},
10 TcpListener, TcpStream,
11};
12use tokio_util::codec::{FramedRead, FramedWrite};
13
14use cuprate_wire::MoneroWireCodec;
15
16use crate::{NetZoneAddress, NetworkZone};
17
18impl NetZoneAddress for SocketAddr {
19 type BanID = IpAddr;
20
21 fn set_port(&mut self, port: u16) {
22 Self::set_port(self, port);
23 }
24
25 fn ban_id(&self) -> Self::BanID {
26 self.ip()
27 }
28
29 fn make_canonical(&mut self) {
30 let ip = self.ip().to_canonical();
31 self.set_ip(ip);
32 }
33
34 fn should_add_to_peer_list(&self) -> bool {
35 true
37 }
38}
39
40#[derive(Debug, Clone)]
41pub struct ClearNetServerCfg {
42 pub ip: IpAddr,
43}
44
45#[derive(Clone, Copy)]
46pub enum ClearNet {}
47
48#[async_trait::async_trait]
49impl NetworkZone for ClearNet {
50 const NAME: &'static str = "ClearNet";
51
52 const CHECK_NODE_ID: bool = true;
53
54 type Addr = SocketAddr;
55 type Stream = FramedRead<OwnedReadHalf, MoneroWireCodec>;
56 type Sink = FramedWrite<OwnedWriteHalf, MoneroWireCodec>;
57 type Listener = InBoundStream;
58
59 type ServerCfg = ClearNetServerCfg;
60
61 async fn connect_to_peer(
62 addr: Self::Addr,
63 ) -> Result<(Self::Stream, Self::Sink), std::io::Error> {
64 let (read, write) = TcpStream::connect(addr).await?.into_split();
65 Ok((
66 FramedRead::new(read, MoneroWireCodec::default()),
67 FramedWrite::new(write, MoneroWireCodec::default()),
68 ))
69 }
70
71 async fn incoming_connection_listener(
72 config: Self::ServerCfg,
73 port: u16,
74 ) -> Result<Self::Listener, std::io::Error> {
75 let listener = TcpListener::bind(SocketAddr::new(config.ip, port)).await?;
76 Ok(InBoundStream { listener })
77 }
78}
79
80pub struct InBoundStream {
81 listener: TcpListener,
82}
83
84impl Stream for InBoundStream {
85 type Item = Result<
86 (
87 Option<SocketAddr>,
88 FramedRead<OwnedReadHalf, MoneroWireCodec>,
89 FramedWrite<OwnedWriteHalf, MoneroWireCodec>,
90 ),
91 std::io::Error,
92 >;
93
94 fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
95 self.listener
96 .poll_accept(cx)
97 .map_ok(|(stream, mut addr)| {
98 let ip = addr.ip().to_canonical();
99 addr.set_ip(ip);
100
101 let (read, write) = stream.into_split();
102 (
103 Some(addr),
104 FramedRead::new(read, MoneroWireCodec::default()),
105 FramedWrite::new(write, MoneroWireCodec::default()),
106 )
107 })
108 .map(Some)
109 }
110}