Remove some Unpin requirements on Futures (#1384)

* Remove lots of Unpin requirements

* Make Transport::and_then accept pinned futures

* Finish the PR

* Work on secio

* Fix BandwidthTransport

* Adjust ListenersStrema

* Fix nodes/tasks

* Fix nodes

* Various more fixes

* Fix yamux

* Fix Swarm

* Fix WebSockets

* Fix rw-stream-sink
This commit is contained in:
Pierre Krieger
2020-01-14 12:03:10 +01:00
committed by GitHub
parent 42a45e2630
commit 3f968cbf92
23 changed files with 249 additions and 216 deletions

View File

@ -18,6 +18,7 @@ hmac = "0.7.0"
lazy_static = "1.2.0"
libp2p-core = { version = "0.14.0-alpha.1", path = "../../core" }
log = "0.4.6"
pin-project = "0.4.6"
protobuf = "=2.8.1" # note: see https://github.com/libp2p/rust-libp2p/issues/1363
quicksink = "0.1"
rand = "0.7"

View File

@ -35,9 +35,11 @@ use std::{cmp::min, pin::Pin, task::Context, task::Poll};
/// frames isn't handled by this module.
///
/// Also implements `Sink` for convenience.
#[pin_project::pin_project]
pub struct DecoderMiddleware<S> {
cipher_state: StreamCipher,
hmac: Hmac,
#[pin]
raw_stream: S,
nonce: Vec<u8>
}
@ -59,29 +61,31 @@ impl<S> DecoderMiddleware<S> {
impl<S> Stream for DecoderMiddleware<S>
where
S: TryStream<Ok = Vec<u8>> + Unpin,
S: TryStream<Ok = Vec<u8>>,
S::Error: Into<SecioError>,
{
type Item = Result<Vec<u8>, SecioError>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
let frame = match TryStream::try_poll_next(Pin::new(&mut self.raw_stream), cx) {
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
let this = self.project();
let frame = match TryStream::try_poll_next(this.raw_stream, cx) {
Poll::Ready(Some(Ok(t))) => t,
Poll::Ready(None) => return Poll::Ready(None),
Poll::Pending => return Poll::Pending,
Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(err.into()))),
};
if frame.len() < self.hmac.num_bytes() {
if frame.len() < this.hmac.num_bytes() {
debug!("frame too short when decoding secio frame");
return Poll::Ready(Some(Err(SecioError::FrameTooShort)));
}
let content_length = frame.len() - self.hmac.num_bytes();
let content_length = frame.len() - this.hmac.num_bytes();
{
let (crypted_data, expected_hash) = frame.split_at(content_length);
debug_assert_eq!(expected_hash.len(), self.hmac.num_bytes());
debug_assert_eq!(expected_hash.len(), this.hmac.num_bytes());
if self.hmac.verify(crypted_data, expected_hash).is_err() {
if this.hmac.verify(crypted_data, expected_hash).is_err() {
debug!("hmac mismatch when decoding secio frame");
return Poll::Ready(Some(Err(SecioError::HmacNotMatching)));
}
@ -89,14 +93,14 @@ where
let mut data_buf = frame;
data_buf.truncate(content_length);
self.cipher_state.decrypt(&mut data_buf);
this.cipher_state.decrypt(&mut data_buf);
if !self.nonce.is_empty() {
let n = min(data_buf.len(), self.nonce.len());
if data_buf[.. n] != self.nonce[.. n] {
if !this.nonce.is_empty() {
let n = min(data_buf.len(), this.nonce.len());
if data_buf[.. n] != this.nonce[.. n] {
return Poll::Ready(Some(Err(SecioError::NonceVerificationFailed)))
}
self.nonce.drain(.. n);
this.nonce.drain(.. n);
data_buf.drain(.. n);
}
@ -106,23 +110,27 @@ where
impl<S, I> Sink<I> for DecoderMiddleware<S>
where
S: Sink<I> + Unpin,
S: Sink<I>,
{
type Error = S::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Sink::poll_ready(Pin::new(&mut self.raw_stream), cx)
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
let this = self.project();
Sink::poll_ready(this.raw_stream, cx)
}
fn start_send(mut self: Pin<&mut Self>, item: I) -> Result<(), Self::Error> {
Sink::start_send(Pin::new(&mut self.raw_stream), item)
fn start_send(self: Pin<&mut Self>, item: I) -> Result<(), Self::Error> {
let this = self.project();
Sink::start_send(this.raw_stream, item)
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Sink::poll_flush(Pin::new(&mut self.raw_stream), cx)
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
let this = self.project();
Sink::poll_flush(this.raw_stream, cx)
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Sink::poll_close(Pin::new(&mut self.raw_stream), cx)
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
let this = self.project();
Sink::poll_close(this.raw_stream, cx)
}
}

View File

@ -31,9 +31,11 @@ use std::{pin::Pin, task::Context, task::Poll};
/// prefix is not covered by this module.
///
/// Also implements `Stream` for convenience.
#[pin_project::pin_project]
pub struct EncoderMiddleware<S> {
cipher_state: StreamCipher,
hmac: Hmac,
#[pin]
raw_sink: S,
}
@ -49,38 +51,43 @@ impl<S> EncoderMiddleware<S> {
impl<S> Sink<Vec<u8>> for EncoderMiddleware<S>
where
S: Sink<Vec<u8>> + Unpin,
S: Sink<Vec<u8>>,
{
type Error = S::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Sink::poll_ready(Pin::new(&mut self.raw_sink), cx)
fn poll_ready(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
let this = self.project();
Sink::poll_ready(this.raw_sink, cx)
}
fn start_send(mut self: Pin<&mut Self>, mut data_buf: Vec<u8>) -> Result<(), Self::Error> {
fn start_send(self: Pin<&mut Self>, mut data_buf: Vec<u8>) -> Result<(), Self::Error> {
let this = self.project();
// TODO if SinkError gets refactor to SecioError, then use try_apply_keystream
self.cipher_state.encrypt(&mut data_buf[..]);
let signature = self.hmac.sign(&data_buf[..]);
this.cipher_state.encrypt(&mut data_buf[..]);
let signature = this.hmac.sign(&data_buf[..]);
data_buf.extend_from_slice(signature.as_ref());
Sink::start_send(Pin::new(&mut self.raw_sink), data_buf)
Sink::start_send(this.raw_sink, data_buf)
}
fn poll_flush(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Sink::poll_flush(Pin::new(&mut self.raw_sink), cx)
fn poll_flush(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
let this = self.project();
Sink::poll_flush(this.raw_sink, cx)
}
fn poll_close(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
Sink::poll_close(Pin::new(&mut self.raw_sink), cx)
fn poll_close(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Result<(), Self::Error>> {
let this = self.project();
Sink::poll_close(this.raw_sink, cx)
}
}
impl<S> Stream for EncoderMiddleware<S>
where
S: Stream + Unpin,
S: Stream,
{
type Item = S::Item;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
Stream::poll_next(Pin::new(&mut self.raw_sink), cx)
fn poll_next(self: Pin<&mut Self>, cx: &mut Context) -> Poll<Option<Self::Item>> {
let this = self.project();
Stream::poll_next(this.raw_sink, cx)
}
}

View File

@ -91,7 +91,7 @@ where
impl<T> Stream for LenPrefixCodec<T>
where
T: AsyncRead + AsyncWrite + Unpin + Send + 'static
T: AsyncRead + AsyncWrite + Send + 'static
{
type Item = io::Result<Vec<u8>>;
@ -102,7 +102,7 @@ where
impl<T> Sink<Vec<u8>> for LenPrefixCodec<T>
where
T: AsyncRead + AsyncWrite + Unpin + Send + 'static
T: AsyncRead + AsyncWrite + Send + 'static
{
type Error = io::Error;
@ -122,3 +122,6 @@ where
Pin::new(&mut self.sink).poll_close(cx)
}
}
impl<T> Unpin for LenPrefixCodec<T> {
}