mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-27 00:31:35 +00:00
New core (#568)
* New core * Fix lifetime requirements * Remove identify transport * Address &mut & ref ref mut * Fix whitespaces
This commit is contained in:
@ -29,9 +29,9 @@ use upgrade::{ConnectionUpgrade, Endpoint};
|
||||
///
|
||||
/// Returns a `Future` that returns the outcome of the connection upgrade.
|
||||
#[inline]
|
||||
pub fn apply<C, U, Maf>(conn: C, upgrade: U, e: Endpoint, remote: Maf) -> UpgradeApplyFuture<C, U, Maf>
|
||||
pub fn apply<C, U>(conn: C, upgrade: U, e: Endpoint) -> UpgradeApplyFuture<C, U>
|
||||
where
|
||||
U: ConnectionUpgrade<C, Maf>,
|
||||
U: ConnectionUpgrade<C>,
|
||||
U::NamesIter: Clone, // TODO: not elegant
|
||||
C: AsyncRead + AsyncWrite,
|
||||
{
|
||||
@ -40,31 +40,28 @@ where
|
||||
future: negotiate(conn, &upgrade, e),
|
||||
upgrade,
|
||||
endpoint: e,
|
||||
remote
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Future, returned from `apply` which performs a connection upgrade.
|
||||
pub struct UpgradeApplyFuture<C, U, Maf>
|
||||
pub struct UpgradeApplyFuture<C, U>
|
||||
where
|
||||
U: ConnectionUpgrade<C, Maf>,
|
||||
U: ConnectionUpgrade<C>,
|
||||
C: AsyncRead + AsyncWrite
|
||||
{
|
||||
inner: UpgradeApplyState<C, U, Maf>
|
||||
inner: UpgradeApplyState<C, U>
|
||||
}
|
||||
|
||||
|
||||
enum UpgradeApplyState<C, U, Maf>
|
||||
enum UpgradeApplyState<C, U>
|
||||
where
|
||||
U: ConnectionUpgrade<C, Maf>,
|
||||
U: ConnectionUpgrade<C>,
|
||||
C: AsyncRead + AsyncWrite
|
||||
{
|
||||
Init {
|
||||
future: NegotiationFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeIdentifier>,
|
||||
upgrade: U,
|
||||
endpoint: Endpoint,
|
||||
remote: Maf
|
||||
endpoint: Endpoint
|
||||
},
|
||||
Upgrade {
|
||||
future: U::Future
|
||||
@ -72,28 +69,28 @@ where
|
||||
Undefined
|
||||
}
|
||||
|
||||
impl<C, U, Maf> Future for UpgradeApplyFuture<C, U, Maf>
|
||||
impl<C, U> Future for UpgradeApplyFuture<C, U>
|
||||
where
|
||||
U: ConnectionUpgrade<C, Maf>,
|
||||
U: ConnectionUpgrade<C>,
|
||||
U::NamesIter: Clone,
|
||||
C: AsyncRead + AsyncWrite
|
||||
{
|
||||
type Item = (U::Output, U::MultiaddrFuture);
|
||||
type Item = U::Output;
|
||||
type Error = IoError;
|
||||
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
loop {
|
||||
match mem::replace(&mut self.inner, UpgradeApplyState::Undefined) {
|
||||
UpgradeApplyState::Init { mut future, upgrade, endpoint, remote } => {
|
||||
UpgradeApplyState::Init { mut future, upgrade, endpoint } => {
|
||||
let (upgrade_id, connection) = match future.poll()? {
|
||||
Async::Ready(x) => x,
|
||||
Async::NotReady => {
|
||||
self.inner = UpgradeApplyState::Init { future, upgrade, endpoint, remote };
|
||||
self.inner = UpgradeApplyState::Init { future, upgrade, endpoint };
|
||||
return Ok(Async::NotReady)
|
||||
}
|
||||
};
|
||||
self.inner = UpgradeApplyState::Upgrade {
|
||||
future: upgrade.upgrade(connection, upgrade_id, endpoint, remote)
|
||||
future: upgrade.upgrade(connection, upgrade_id, endpoint)
|
||||
};
|
||||
}
|
||||
UpgradeApplyState::Upgrade { mut future } => {
|
||||
@ -124,13 +121,13 @@ where
|
||||
///
|
||||
/// Returns a `Future` that returns the negotiated protocol and the stream.
|
||||
#[inline]
|
||||
pub fn negotiate<C, I, U, Maf>(
|
||||
pub fn negotiate<C, I, U>(
|
||||
connection: C,
|
||||
upgrade: &U,
|
||||
endpoint: Endpoint,
|
||||
) -> NegotiationFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeIdentifier>
|
||||
where
|
||||
U: ConnectionUpgrade<I, Maf>,
|
||||
U: ConnectionUpgrade<I>,
|
||||
U::NamesIter: Clone, // TODO: not elegant
|
||||
C: AsyncRead + AsyncWrite,
|
||||
{
|
||||
@ -144,7 +141,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Future, returned by `negotiate`, which negotiates a protocol and stream.
|
||||
pub struct NegotiationFuture<R: AsyncRead + AsyncWrite, I, P> {
|
||||
inner: Either<ListenerSelectFuture<R, I, P>, DialerSelectFuture<R, I, P>>
|
||||
@ -175,7 +171,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// Iterator adapter which adds equality matching predicates to items.
|
||||
/// Used in `NegotiationFuture`.
|
||||
#[derive(Clone)]
|
||||
|
@ -19,8 +19,7 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::{future, prelude::*};
|
||||
use std::io::Error as IoError;
|
||||
use futures::future;
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
use upgrade::{ConnectionUpgrade, Endpoint};
|
||||
|
||||
@ -37,11 +36,11 @@ pub fn or<A, B>(me: A, other: B) -> OrUpgrade<A, B> {
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct OrUpgrade<A, B>(A, B);
|
||||
|
||||
impl<C, A, B, O, Maf> ConnectionUpgrade<C, Maf> for OrUpgrade<A, B>
|
||||
impl<C, A, B, O> ConnectionUpgrade<C> for OrUpgrade<A, B>
|
||||
where
|
||||
C: AsyncRead + AsyncWrite,
|
||||
A: ConnectionUpgrade<C, Maf, Output = O>,
|
||||
B: ConnectionUpgrade<C, Maf, Output = O>,
|
||||
A: ConnectionUpgrade<C, Output = O>,
|
||||
B: ConnectionUpgrade<C, Output = O>,
|
||||
{
|
||||
type NamesIter = NamesIterChain<A::NamesIter, B::NamesIter>;
|
||||
type UpgradeIdentifier = EitherUpgradeIdentifier<A::UpgradeIdentifier, B::UpgradeIdentifier>;
|
||||
@ -55,8 +54,7 @@ where
|
||||
}
|
||||
|
||||
type Output = O;
|
||||
type MultiaddrFuture = future::Either<A::MultiaddrFuture, B::MultiaddrFuture>;
|
||||
type Future = EitherConnUpgrFuture<A::Future, B::Future>;
|
||||
type Future = future::Either<A::Future, B::Future>;
|
||||
|
||||
#[inline]
|
||||
fn upgrade(
|
||||
@ -64,14 +62,13 @@ where
|
||||
socket: C,
|
||||
id: Self::UpgradeIdentifier,
|
||||
ty: Endpoint,
|
||||
remote_addr: Maf,
|
||||
) -> Self::Future {
|
||||
match id {
|
||||
EitherUpgradeIdentifier::First(id) => {
|
||||
EitherConnUpgrFuture::First(self.0.upgrade(socket, id, ty, remote_addr))
|
||||
future::Either::A(self.0.upgrade(socket, id, ty))
|
||||
}
|
||||
EitherUpgradeIdentifier::Second(id) => {
|
||||
EitherConnUpgrFuture::Second(self.1.upgrade(socket, id, ty, remote_addr))
|
||||
future::Either::B(self.1.upgrade(socket, id, ty))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -84,43 +81,6 @@ pub enum EitherUpgradeIdentifier<A, B> {
|
||||
Second(B),
|
||||
}
|
||||
|
||||
/// Implements `Future` and redirects calls to either `First` or `Second`.
|
||||
///
|
||||
/// Additionally, the output will be wrapped inside a `EitherOutput`.
|
||||
///
|
||||
// TODO: This type is needed because of the lack of `impl Trait` in stable Rust.
|
||||
// If Rust had impl Trait we could use the Either enum from the futures crate and add some
|
||||
// modifiers to it. This custom enum is a combination of Either and these modifiers.
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
#[must_use = "futures do nothing unless polled"]
|
||||
pub enum EitherConnUpgrFuture<A, B> {
|
||||
First(A),
|
||||
Second(B),
|
||||
}
|
||||
|
||||
impl<A, B, O, Ma, Mb> Future for EitherConnUpgrFuture<A, B>
|
||||
where
|
||||
A: Future<Error = IoError, Item = (O, Ma)>,
|
||||
B: Future<Error = IoError, Item = (O, Mb)>,
|
||||
{
|
||||
type Item = (O, future::Either<Ma, Mb>);
|
||||
type Error = IoError;
|
||||
|
||||
#[inline]
|
||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||
match self {
|
||||
&mut EitherConnUpgrFuture::First(ref mut a) => {
|
||||
let (item, fut) = try_ready!(a.poll());
|
||||
Ok(Async::Ready((item, future::Either::A(fut))))
|
||||
}
|
||||
&mut EitherConnUpgrFuture::Second(ref mut b) => {
|
||||
let (item, fut) = try_ready!(b.poll());
|
||||
Ok(Async::Ready((item, future::Either::B(fut))))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Internal type used by the `OrUpgrade` struct.
|
||||
///
|
||||
/// > **Note**: This type is needed because of the lack of `-> impl Trait` in Rust. It can be
|
||||
|
@ -20,7 +20,6 @@
|
||||
|
||||
use bytes::Bytes;
|
||||
use futures::prelude::*;
|
||||
use multiaddr::Multiaddr;
|
||||
use std::{io, iter};
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
use upgrade::{ConnectionUpgrade, Endpoint};
|
||||
@ -29,15 +28,14 @@ use upgrade::{ConnectionUpgrade, Endpoint};
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct DeniedConnectionUpgrade;
|
||||
|
||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for DeniedConnectionUpgrade
|
||||
impl<C> ConnectionUpgrade<C> for DeniedConnectionUpgrade
|
||||
where
|
||||
C: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type NamesIter = iter::Empty<(Bytes, ())>;
|
||||
type UpgradeIdentifier = (); // TODO: could use `!`
|
||||
type Output = (); // TODO: could use `!`
|
||||
type MultiaddrFuture = Box<Future<Item = Multiaddr, Error = io::Error> + Send + Sync>; // TODO: could use `!`
|
||||
type Future = Box<Future<Item = ((), Self::MultiaddrFuture), Error = io::Error> + Send + Sync>; // TODO: could use `!`
|
||||
type Future = Box<Future<Item = (), Error = io::Error> + Send + Sync>; // TODO: could use `!`
|
||||
|
||||
#[inline]
|
||||
fn protocol_names(&self) -> Self::NamesIter {
|
||||
@ -45,7 +43,7 @@ where
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn upgrade(self, _: C, _: Self::UpgradeIdentifier, _: Endpoint, _: Maf) -> Self::Future {
|
||||
fn upgrade(self, _: C, _: Self::UpgradeIdentifier, _: Endpoint) -> Self::Future {
|
||||
unreachable!("the denied connection upgrade always fails to negotiate")
|
||||
}
|
||||
}
|
||||
|
@ -61,23 +61,20 @@ pub struct LoopUpg<Inner> {
|
||||
}
|
||||
|
||||
// TODO: 'static :-/
|
||||
impl<State, Socket, Inner, Out, AddrFut> ConnectionUpgrade<(State, Socket), AddrFut>
|
||||
impl<State, Socket, Inner, Out> ConnectionUpgrade<(State, Socket)>
|
||||
for LoopUpg<Inner>
|
||||
where
|
||||
State: Send + 'static,
|
||||
Socket: AsyncRead + AsyncWrite + Send + 'static,
|
||||
Inner: ConnectionUpgrade<
|
||||
(State, Socket),
|
||||
AddrFut,
|
||||
Output = Loop<State, Socket, Out>,
|
||||
MultiaddrFuture = AddrFut,
|
||||
> + Clone
|
||||
+ Send
|
||||
+ 'static,
|
||||
Inner::NamesIter: Clone + Send + 'static,
|
||||
Inner::UpgradeIdentifier: Send,
|
||||
Inner::Future: Send,
|
||||
AddrFut: Send + 'static,
|
||||
Out: Send + 'static,
|
||||
{
|
||||
type NamesIter = Inner::NamesIter;
|
||||
@ -88,29 +85,27 @@ where
|
||||
}
|
||||
|
||||
type Output = Out;
|
||||
type MultiaddrFuture = AddrFut;
|
||||
type Future = Box<Future<Item = (Out, Self::MultiaddrFuture), Error = IoError> + Send>;
|
||||
type Future = Box<Future<Item = Out, Error = IoError> + Send>;
|
||||
|
||||
fn upgrade(
|
||||
self,
|
||||
(state, socket): (State, Socket),
|
||||
id: Self::UpgradeIdentifier,
|
||||
endpoint: Endpoint,
|
||||
remote_addr: AddrFut,
|
||||
) -> Self::Future {
|
||||
let inner = self.inner;
|
||||
|
||||
let fut = future::loop_fn(
|
||||
(state, socket, id, remote_addr, MAX_LOOPS),
|
||||
move |(state, socket, id, remote_addr, loops_remaining)| {
|
||||
(state, socket, id, MAX_LOOPS),
|
||||
move |(state, socket, id, loops_remaining)| {
|
||||
// When we enter a recursion of the `loop_fn`, a protocol has already been
|
||||
// negotiated. So what we have to do is upgrade then negotiate the next protocol
|
||||
// (if necessary), and then only continue iteration in the `future::loop_fn`.
|
||||
let inner = inner.clone();
|
||||
inner
|
||||
.clone()
|
||||
.upgrade((state, socket), id, endpoint, remote_addr)
|
||||
.and_then(move |(loop_out, remote_addr)| match loop_out {
|
||||
.upgrade((state, socket), id, endpoint)
|
||||
.and_then(move |loop_out| match loop_out {
|
||||
Loop::Continue(state, socket) => {
|
||||
// Produce an error if we reached the recursion limit.
|
||||
if loops_remaining == 0 {
|
||||
@ -126,14 +121,13 @@ where
|
||||
state,
|
||||
socket,
|
||||
id,
|
||||
remote_addr,
|
||||
loops_remaining - 1,
|
||||
))
|
||||
});
|
||||
future::Either::A(fut)
|
||||
}
|
||||
Loop::Break(fin) => {
|
||||
future::Either::B(future::ok(FutLoop::Break((fin, remote_addr))))
|
||||
future::Either::B(future::ok(FutLoop::Break(fin)))
|
||||
}
|
||||
})
|
||||
},
|
||||
|
@ -36,9 +36,9 @@ pub struct Map<U, F> {
|
||||
map: F,
|
||||
}
|
||||
|
||||
impl<C, U, F, O, Maf> ConnectionUpgrade<C, Maf> for Map<U, F>
|
||||
impl<C, U, F, O> ConnectionUpgrade<C> for Map<U, F>
|
||||
where
|
||||
U: ConnectionUpgrade<C, Maf>,
|
||||
U: ConnectionUpgrade<C>,
|
||||
U::Future: Send + 'static, // TODO: 'static :(
|
||||
C: AsyncRead + AsyncWrite,
|
||||
F: FnOnce(U::Output) -> O + Send + 'static, // TODO: 'static :(
|
||||
@ -51,20 +51,18 @@ where
|
||||
}
|
||||
|
||||
type Output = O;
|
||||
type MultiaddrFuture = U::MultiaddrFuture;
|
||||
type Future = Box<Future<Item = (O, Self::MultiaddrFuture), Error = IoError> + Send>;
|
||||
type Future = Box<Future<Item = O, Error = IoError> + Send>;
|
||||
|
||||
fn upgrade(
|
||||
self,
|
||||
socket: C,
|
||||
id: Self::UpgradeIdentifier,
|
||||
ty: Endpoint,
|
||||
remote_addr: Maf,
|
||||
) -> Self::Future {
|
||||
let map = self.map;
|
||||
let fut = self.upgrade
|
||||
.upgrade(socket, id, ty, remote_addr)
|
||||
.map(move |(out, maf)| (map(out), maf));
|
||||
.upgrade(socket, id, ty)
|
||||
.map(map);
|
||||
Box::new(fut) as Box<_>
|
||||
}
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ pub mod choice;
|
||||
pub mod denied;
|
||||
pub mod loop_upg;
|
||||
pub mod map;
|
||||
pub mod map_addr;
|
||||
pub mod plaintext;
|
||||
pub mod toggleable;
|
||||
pub mod traits;
|
||||
@ -33,7 +32,6 @@ pub use self::choice::{or, OrUpgrade};
|
||||
pub use self::denied::DeniedConnectionUpgrade;
|
||||
pub use self::loop_upg::{loop_upg, Loop};
|
||||
pub use self::map::map;
|
||||
pub use self::map_addr::map_with_addr;
|
||||
pub use self::plaintext::PlainTextConfig;
|
||||
pub use self::toggleable::toggleable;
|
||||
pub use self::traits::{ConnectionUpgrade, Endpoint};
|
||||
|
@ -32,19 +32,18 @@ use upgrade::{ConnectionUpgrade, Endpoint};
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub struct PlainTextConfig;
|
||||
|
||||
impl<C, F> ConnectionUpgrade<C, F> for PlainTextConfig
|
||||
impl<C> ConnectionUpgrade<C> for PlainTextConfig
|
||||
where
|
||||
C: AsyncRead + AsyncWrite,
|
||||
{
|
||||
type Output = C;
|
||||
type Future = FutureResult<(C, F), IoError>;
|
||||
type Future = FutureResult<C, IoError>;
|
||||
type UpgradeIdentifier = ();
|
||||
type MultiaddrFuture = F;
|
||||
type NamesIter = iter::Once<(Bytes, ())>;
|
||||
|
||||
#[inline]
|
||||
fn upgrade(self, i: C, _: (), _: Endpoint, remote_addr: F) -> Self::Future {
|
||||
future::ok((i, remote_addr))
|
||||
fn upgrade(self, i: C, _: (), _: Endpoint) -> Self::Future {
|
||||
future::ok(i)
|
||||
}
|
||||
|
||||
#[inline]
|
||||
|
@ -65,10 +65,10 @@ impl<U> Toggleable<U> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<C, U, Maf> ConnectionUpgrade<C, Maf> for Toggleable<U>
|
||||
impl<C, U> ConnectionUpgrade<C> for Toggleable<U>
|
||||
where
|
||||
C: AsyncRead + AsyncWrite,
|
||||
U: ConnectionUpgrade<C, Maf>,
|
||||
U: ConnectionUpgrade<C>,
|
||||
{
|
||||
type NamesIter = ToggleableIter<U::NamesIter>;
|
||||
type UpgradeIdentifier = U::UpgradeIdentifier;
|
||||
@ -82,8 +82,7 @@ where
|
||||
}
|
||||
|
||||
type Output = U::Output;
|
||||
type MultiaddrFuture = U::MultiaddrFuture;
|
||||
type Future = future::Either<future::Empty<(U::Output, U::MultiaddrFuture), IoError>, U::Future>;
|
||||
type Future = future::Either<future::Empty<U::Output, IoError>, U::Future>;
|
||||
|
||||
#[inline]
|
||||
fn upgrade(
|
||||
@ -91,10 +90,9 @@ where
|
||||
socket: C,
|
||||
id: Self::UpgradeIdentifier,
|
||||
ty: Endpoint,
|
||||
remote_addr: Maf,
|
||||
) -> Self::Future {
|
||||
if self.enabled {
|
||||
future::Either::B(self.inner.upgrade(socket, id, ty, remote_addr))
|
||||
future::Either::B(self.inner.upgrade(socket, id, ty))
|
||||
} else {
|
||||
future::Either::A(future::empty())
|
||||
}
|
||||
|
@ -50,7 +50,7 @@ impl Not for Endpoint {
|
||||
/// > **Note**: The `upgrade` method of this trait uses `self` and not `&self` or `&mut self`.
|
||||
/// > This has been designed so that you would implement this trait on `&Foo` or
|
||||
/// > `&mut Foo` instead of directly on `Foo`.
|
||||
pub trait ConnectionUpgrade<C, TAddrFut> {
|
||||
pub trait ConnectionUpgrade<C> {
|
||||
/// Iterator returned by `protocol_names`.
|
||||
type NamesIter: Iterator<Item = (Bytes, Self::UpgradeIdentifier)>;
|
||||
/// Type that serves as an identifier for the protocol. This type only exists to be returned
|
||||
@ -68,10 +68,8 @@ pub trait ConnectionUpgrade<C, TAddrFut> {
|
||||
/// > **Note**: For upgrades that add an intermediary layer (such as `secio` or `multiplex`),
|
||||
/// > this associated type must implement `AsyncRead + AsyncWrite`.
|
||||
type Output;
|
||||
/// Type of the future that will resolve to the remote's multiaddr.
|
||||
type MultiaddrFuture;
|
||||
/// Type of the future that will resolve to `Self::Output`.
|
||||
type Future: Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError>;
|
||||
type Future: Future<Item = Self::Output, Error = IoError>;
|
||||
|
||||
/// This method is called after protocol negotiation has been performed.
|
||||
///
|
||||
@ -82,6 +80,5 @@ pub trait ConnectionUpgrade<C, TAddrFut> {
|
||||
socket: C,
|
||||
id: Self::UpgradeIdentifier,
|
||||
ty: Endpoint,
|
||||
remote_addr: TAddrFut,
|
||||
) -> Self::Future;
|
||||
}
|
||||
|
Reference in New Issue
Block a user