libp2prs_plaintext/
lib.rs1mod error;
23mod handshake;
24use crate::error::PlaintextError;
27use crate::handshake::handshake_plaintext::Remote;
28use futures::{AsyncRead, AsyncWrite};
30use libp2prs_core::identity::Keypair;
31use libp2prs_core::secure_io::SecureInfo;
32use libp2prs_core::transport::{ConnectionInfo, TransportError};
33use libp2prs_core::upgrade::{UpgradeInfo, Upgrader};
34use libp2prs_core::{Multiaddr, PeerId, PublicKey};
35use std::{
36 io,
37 pin::Pin,
38 task::{Context, Poll},
39};
40
41use async_trait::async_trait;
42
43pub mod structs_proto {
44 include!(concat!(env!("OUT_DIR"), "/structs_proto.rs"));
45}
46
47const MAX_FRAME_SIZE: usize = 1024 * 1024 * 8;
48
49#[derive(Clone)]
51pub struct PlainTextConfig {
52 pub(crate) key: Keypair,
53 pub(crate) max_frame_length: usize,
54}
55
56impl PlainTextConfig {
57 pub fn new(key: Keypair) -> Self {
59 PlainTextConfig {
60 key,
61 max_frame_length: MAX_FRAME_SIZE,
62 }
63 }
64
65 pub async fn handshake<T>(self, socket: T) -> Result<(T, Remote), PlaintextError>
70 where
71 T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
72 {
73 handshake::handshake_plaintext::handshake(socket, self).await
74 }
75}
76
77impl UpgradeInfo for PlainTextConfig {
78 type Info = &'static [u8];
79
80 fn protocol_info(&self) -> Vec<Self::Info> {
81 vec![b"/plaintext/1.0.0"]
82 }
83}
84
85#[async_trait]
86impl<T> Upgrader<T> for PlainTextConfig
87where
88 T: ConnectionInfo + AsyncRead + AsyncWrite + Send + Unpin + 'static,
89{
90 type Output = PlainTextOutput<T>;
91
92 async fn upgrade_inbound(self, socket: T, _info: <Self as UpgradeInfo>::Info) -> Result<Self::Output, TransportError> {
93 make_secure_output(self, socket).await
94 }
95
96 async fn upgrade_outbound(self, socket: T, _info: <Self as UpgradeInfo>::Info) -> Result<Self::Output, TransportError> {
97 make_secure_output(self, socket).await
98 }
99}
100
101async fn make_secure_output<T>(config: PlainTextConfig, socket: T) -> Result<PlainTextOutput<T>, TransportError>
102where
103 T: ConnectionInfo + AsyncRead + AsyncWrite + Send + Unpin + 'static,
104{
105 let pri_key = config.key.clone();
106 let la = socket.local_multiaddr();
107 let ra = socket.remote_multiaddr();
108 let (secure_stream, remote) = config.handshake(socket).await?;
109 let output = PlainTextOutput {
110 stream: secure_stream,
111 local_priv_key: pri_key.clone(),
112 local_peer_id: pri_key.public().into_peer_id(),
113 remote_pub_key: remote.public_key,
114 remote_peer_id: remote.peer_id,
115 la,
116 ra,
117 };
118 Ok(output)
119}
120
121#[pin_project::pin_project]
123pub struct PlainTextOutput<T> {
124 #[pin]
126 pub stream: T,
127 pub local_priv_key: Keypair,
129 pub local_peer_id: PeerId,
131 pub remote_pub_key: PublicKey,
133 pub remote_peer_id: PeerId,
135 la: Multiaddr,
137 ra: Multiaddr,
139}
140
141impl<T> SecureInfo for PlainTextOutput<T> {
142 fn local_peer(&self) -> PeerId {
143 self.local_peer_id
144 }
145
146 fn remote_peer(&self) -> PeerId {
147 self.remote_peer_id
148 }
149
150 fn local_priv_key(&self) -> Keypair {
151 self.local_priv_key.clone()
152 }
153
154 fn remote_pub_key(&self) -> PublicKey {
155 self.remote_pub_key.clone()
156 }
157}
158
159impl<T: Send> ConnectionInfo for PlainTextOutput<T> {
160 fn local_multiaddr(&self) -> Multiaddr {
161 self.la.clone()
162 }
163 fn remote_multiaddr(&self) -> Multiaddr {
164 self.ra.clone()
165 }
166}
167
168impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> AsyncRead for PlainTextOutput<T> {
169 fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<io::Result<usize>> {
170 let this = self.project();
171 this.stream.poll_read(cx, buf)
172 }
173}
174
175impl<T: AsyncRead + AsyncWrite + Send + Unpin + 'static> AsyncWrite for PlainTextOutput<T> {
176 fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<io::Result<usize>> {
177 let this = self.project();
178 this.stream.poll_write(cx, buf)
179 }
180
181 fn poll_flush(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
182 let this = self.project();
183 this.stream.poll_flush(cx)
184 }
185
186 fn poll_close(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<io::Result<()>> {
187 let this = self.project();
188 this.stream.poll_close(cx)
189 }
190}
191
192impl From<PlaintextError> for TransportError {
193 fn from(e: PlaintextError) -> Self {
194 TransportError::SecurityError(Box::new(e))
195 }
196}