2019-10-28 18:04:01 +01:00
|
|
|
// Copyright 2019 Parity Technologies (UK) Ltd.
|
2018-05-02 11:50:48 +02:00
|
|
|
//
|
|
|
|
// Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
// copy of this software and associated documentation files (the "Software"),
|
|
|
|
// to deal in the Software without restriction, including without limitation
|
|
|
|
// the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
// and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
// Software is furnished to do so, subject to the following conditions:
|
|
|
|
//
|
|
|
|
// The above copyright notice and this permission notice shall be included in
|
|
|
|
// all copies or substantial portions of the Software.
|
|
|
|
//
|
|
|
|
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
|
|
|
|
// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
|
|
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
// DEALINGS IN THE SOFTWARE.
|
|
|
|
|
2019-10-28 18:04:01 +01:00
|
|
|
use crate::error::PlainTextError;
|
|
|
|
|
2020-11-11 14:09:33 +01:00
|
|
|
use bytes::Bytes;
|
2019-11-19 11:15:35 +01:00
|
|
|
use futures::future::{self, Ready};
|
|
|
|
use futures::prelude::*;
|
2020-09-17 15:29:47 +02:00
|
|
|
use futures::future::BoxFuture;
|
2019-11-19 11:15:35 +01:00
|
|
|
use libp2p_core::{
|
|
|
|
identity,
|
|
|
|
InboundUpgrade,
|
|
|
|
OutboundUpgrade,
|
|
|
|
UpgradeInfo,
|
|
|
|
PeerId,
|
|
|
|
PublicKey,
|
|
|
|
};
|
|
|
|
use log::debug;
|
|
|
|
use std::{io, iter, pin::Pin, task::{Context, Poll}};
|
|
|
|
use void::Void;
|
|
|
|
|
2019-10-28 18:04:01 +01:00
|
|
|
mod error;
|
|
|
|
mod handshake;
|
2020-01-15 12:02:02 +01:00
|
|
|
mod structs_proto {
|
|
|
|
include!(concat!(env!("OUT_DIR"), "/structs.rs"));
|
|
|
|
}
|
|
|
|
|
2018-11-15 17:41:11 +01:00
|
|
|
|
2019-11-06 16:09:15 +01:00
|
|
|
/// `PlainText1Config` is an insecure connection handshake for testing purposes only.
|
|
|
|
///
|
|
|
|
/// > **Note**: Given that `PlainText1Config` has no notion of exchanging peer identity information it is not compatible
|
|
|
|
/// > with the `libp2p_core::transport::upgrade::Builder` pattern. See
|
|
|
|
/// > [`PlainText2Config`](struct.PlainText2Config.html) if compatibility is needed. Even though not compatible with the
|
|
|
|
/// > Builder pattern one can still do an upgrade *manually*:
|
|
|
|
///
|
|
|
|
/// ```
|
|
|
|
/// # use libp2p_core::transport::{ Transport, memory::MemoryTransport };
|
|
|
|
/// # use libp2p_plaintext::PlainText1Config;
|
|
|
|
/// #
|
|
|
|
/// MemoryTransport::default()
|
|
|
|
/// .and_then(move |io, endpoint| {
|
|
|
|
/// libp2p_core::upgrade::apply(
|
|
|
|
/// io,
|
|
|
|
/// PlainText1Config{},
|
|
|
|
/// endpoint,
|
|
|
|
/// libp2p_core::transport::upgrade::Version::V1,
|
|
|
|
/// )
|
|
|
|
/// })
|
|
|
|
/// .map(|plaintext, _endpoint| {
|
|
|
|
/// unimplemented!();
|
|
|
|
/// // let peer_id = somehow_derive_peer_id();
|
|
|
|
/// // return (peer_id, plaintext);
|
|
|
|
/// });
|
|
|
|
/// ```
|
2018-05-02 11:50:48 +02:00
|
|
|
#[derive(Debug, Copy, Clone)]
|
2019-10-28 18:04:01 +01:00
|
|
|
pub struct PlainText1Config;
|
2018-05-02 11:50:48 +02:00
|
|
|
|
2019-10-28 18:04:01 +01:00
|
|
|
impl UpgradeInfo for PlainText1Config {
|
2018-12-11 15:13:10 +01:00
|
|
|
type Info = &'static [u8];
|
|
|
|
type InfoIter = iter::Once<Self::Info>;
|
2018-11-15 17:41:11 +01:00
|
|
|
|
2018-12-11 15:13:10 +01:00
|
|
|
fn protocol_info(&self) -> Self::InfoIter {
|
|
|
|
iter::once(b"/plaintext/1.0.0")
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-10-28 18:04:01 +01:00
|
|
|
impl<C> InboundUpgrade<C> for PlainText1Config {
|
2020-01-13 14:34:43 +01:00
|
|
|
type Output = C;
|
2018-11-15 17:41:11 +01:00
|
|
|
type Error = Void;
|
2020-01-13 14:34:43 +01:00
|
|
|
type Future = Ready<Result<C, Self::Error>>;
|
2018-05-02 11:50:48 +02:00
|
|
|
|
2020-01-13 14:34:43 +01:00
|
|
|
fn upgrade_inbound(self, i: C, _: Self::Info) -> Self::Future {
|
2019-09-16 11:08:44 +02:00
|
|
|
future::ready(Ok(i))
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
2018-11-15 17:41:11 +01:00
|
|
|
}
|
2018-05-02 11:50:48 +02:00
|
|
|
|
2019-10-28 18:04:01 +01:00
|
|
|
impl<C> OutboundUpgrade<C> for PlainText1Config {
|
2020-01-13 14:34:43 +01:00
|
|
|
type Output = C;
|
2018-11-15 17:41:11 +01:00
|
|
|
type Error = Void;
|
2020-01-13 14:34:43 +01:00
|
|
|
type Future = Ready<Result<C, Self::Error>>;
|
2018-11-15 17:41:11 +01:00
|
|
|
|
2020-01-13 14:34:43 +01:00
|
|
|
fn upgrade_outbound(self, i: C, _: Self::Info) -> Self::Future {
|
2019-09-16 11:08:44 +02:00
|
|
|
future::ready(Ok(i))
|
2018-05-02 11:50:48 +02:00
|
|
|
}
|
|
|
|
}
|
2018-11-15 17:41:11 +01:00
|
|
|
|
2019-11-06 16:09:15 +01:00
|
|
|
/// `PlainText2Config` is an insecure connection handshake for testing purposes only, implementing
|
|
|
|
/// the libp2p plaintext connection handshake specification.
|
2019-10-28 18:04:01 +01:00
|
|
|
#[derive(Clone)]
|
|
|
|
pub struct PlainText2Config {
|
|
|
|
pub local_public_key: identity::PublicKey,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl UpgradeInfo for PlainText2Config {
|
|
|
|
type Info = &'static [u8];
|
|
|
|
type InfoIter = iter::Once<Self::Info>;
|
|
|
|
|
|
|
|
fn protocol_info(&self) -> Self::InfoIter {
|
|
|
|
iter::once(b"/plaintext/2.0.0")
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<C> InboundUpgrade<C> for PlainText2Config
|
|
|
|
where
|
2019-11-19 11:15:35 +01:00
|
|
|
C: AsyncRead + AsyncWrite + Send + Unpin + 'static
|
2019-10-28 18:04:01 +01:00
|
|
|
{
|
2020-01-13 14:34:43 +01:00
|
|
|
type Output = (PeerId, PlainTextOutput<C>);
|
2019-10-28 18:04:01 +01:00
|
|
|
type Error = PlainTextError;
|
2019-11-19 11:15:35 +01:00
|
|
|
type Future = BoxFuture<'static, Result<Self::Output, Self::Error>>;
|
2019-10-28 18:04:01 +01:00
|
|
|
|
2020-01-13 14:34:43 +01:00
|
|
|
fn upgrade_inbound(self, socket: C, _: Self::Info) -> Self::Future {
|
2019-11-19 11:15:35 +01:00
|
|
|
Box::pin(self.handshake(socket))
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<C> OutboundUpgrade<C> for PlainText2Config
|
|
|
|
where
|
2019-11-19 11:15:35 +01:00
|
|
|
C: AsyncRead + AsyncWrite + Send + Unpin + 'static
|
2019-10-28 18:04:01 +01:00
|
|
|
{
|
2020-01-13 14:34:43 +01:00
|
|
|
type Output = (PeerId, PlainTextOutput<C>);
|
2019-10-28 18:04:01 +01:00
|
|
|
type Error = PlainTextError;
|
2019-11-19 11:15:35 +01:00
|
|
|
type Future = BoxFuture<'static, Result<Self::Output, Self::Error>>;
|
2019-10-28 18:04:01 +01:00
|
|
|
|
2020-01-13 14:34:43 +01:00
|
|
|
fn upgrade_outbound(self, socket: C, _: Self::Info) -> Self::Future {
|
2019-11-19 11:15:35 +01:00
|
|
|
Box::pin(self.handshake(socket))
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl PlainText2Config {
|
2019-11-19 11:15:35 +01:00
|
|
|
async fn handshake<T>(self, socket: T) -> Result<(PeerId, PlainTextOutput<T>), PlainTextError>
|
2019-10-28 18:04:01 +01:00
|
|
|
where
|
2019-11-19 11:15:35 +01:00
|
|
|
T: AsyncRead + AsyncWrite + Send + Unpin + 'static
|
2019-10-28 18:04:01 +01:00
|
|
|
{
|
2020-09-16 09:08:45 +02:00
|
|
|
debug!("Starting plaintext handshake.");
|
2020-11-11 14:09:33 +01:00
|
|
|
let (socket, remote, read_buffer) = handshake::handshake(socket, self).await?;
|
2020-09-16 09:08:45 +02:00
|
|
|
debug!("Finished plaintext handshake.");
|
|
|
|
|
2019-11-19 11:15:35 +01:00
|
|
|
Ok((
|
|
|
|
remote.peer_id,
|
|
|
|
PlainTextOutput {
|
2020-09-17 15:29:47 +02:00
|
|
|
socket,
|
2019-11-19 11:15:35 +01:00
|
|
|
remote_key: remote.public_key,
|
2020-11-11 14:09:33 +01:00
|
|
|
read_buffer,
|
2019-11-19 11:15:35 +01:00
|
|
|
}
|
|
|
|
))
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// Output of the plaintext protocol.
|
|
|
|
pub struct PlainTextOutput<S>
|
|
|
|
where
|
2019-11-19 11:15:35 +01:00
|
|
|
S: AsyncRead + AsyncWrite + Unpin,
|
2019-10-28 18:04:01 +01:00
|
|
|
{
|
|
|
|
/// The plaintext stream.
|
2020-09-17 15:29:47 +02:00
|
|
|
pub socket: S,
|
2019-10-28 18:04:01 +01:00
|
|
|
/// The public key of the remote.
|
|
|
|
pub remote_key: PublicKey,
|
2020-11-11 14:09:33 +01:00
|
|
|
/// Remaining bytes that have been already buffered
|
|
|
|
/// during the handshake but are not part of the
|
|
|
|
/// handshake. These must be consumed first by `poll_read`.
|
|
|
|
read_buffer: Bytes,
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
|
2019-11-19 11:15:35 +01:00
|
|
|
impl<S: AsyncRead + AsyncWrite + Unpin> AsyncRead for PlainTextOutput<S> {
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8])
|
2019-11-19 11:15:35 +01:00
|
|
|
-> Poll<Result<usize, io::Error>>
|
|
|
|
{
|
2020-11-11 14:09:33 +01:00
|
|
|
if !self.read_buffer.is_empty() {
|
|
|
|
let n = std::cmp::min(buf.len(), self.read_buffer.len());
|
|
|
|
let b = self.read_buffer.split_to(n);
|
|
|
|
buf[..n].copy_from_slice(&b[..]);
|
|
|
|
return Poll::Ready(Ok(n))
|
|
|
|
}
|
2020-09-17 15:29:47 +02:00
|
|
|
AsyncRead::poll_read(Pin::new(&mut self.socket), cx, buf)
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-19 11:15:35 +01:00
|
|
|
impl<S: AsyncRead + AsyncWrite + Unpin> AsyncWrite for PlainTextOutput<S> {
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8])
|
2019-11-19 11:15:35 +01:00
|
|
|
-> Poll<Result<usize, io::Error>>
|
|
|
|
{
|
2020-09-17 15:29:47 +02:00
|
|
|
AsyncWrite::poll_write(Pin::new(&mut self.socket), cx, buf)
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
|
2019-11-19 11:15:35 +01:00
|
|
|
-> Poll<Result<(), io::Error>>
|
|
|
|
{
|
2020-09-17 15:29:47 +02:00
|
|
|
AsyncWrite::poll_flush(Pin::new(&mut self.socket), cx)
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
|
2020-07-27 20:27:33 +00:00
|
|
|
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
|
2019-11-19 11:15:35 +01:00
|
|
|
-> Poll<Result<(), io::Error>>
|
|
|
|
{
|
2020-09-17 15:29:47 +02:00
|
|
|
AsyncWrite::poll_close(Pin::new(&mut self.socket), cx)
|
2019-10-28 18:04:01 +01:00
|
|
|
}
|
|
|
|
}
|