mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-13 18:11:22 +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:
@ -18,10 +18,11 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use futures::{prelude::*, future};
|
use futures::prelude::*;
|
||||||
use muxing::{Shutdown, StreamMuxer};
|
use muxing::{Shutdown, StreamMuxer};
|
||||||
use std::io::{Error as IoError, Read, Write};
|
use std::io::{Error as IoError, Read, Write};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
|
use Multiaddr;
|
||||||
|
|
||||||
/// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
|
/// Implements `AsyncRead` and `AsyncWrite` and dispatches all method calls to
|
||||||
/// either `First` or `Second`.
|
/// either `First` or `Second`.
|
||||||
@ -39,8 +40,8 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
|
unsafe fn prepare_uninitialized_buffer(&self, buf: &mut [u8]) -> bool {
|
||||||
match self {
|
match self {
|
||||||
&EitherOutput::First(ref a) => a.prepare_uninitialized_buffer(buf),
|
EitherOutput::First(a) => a.prepare_uninitialized_buffer(buf),
|
||||||
&EitherOutput::Second(ref b) => b.prepare_uninitialized_buffer(buf),
|
EitherOutput::Second(b) => b.prepare_uninitialized_buffer(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -53,8 +54,8 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
|
fn read(&mut self, buf: &mut [u8]) -> Result<usize, IoError> {
|
||||||
match self {
|
match self {
|
||||||
&mut EitherOutput::First(ref mut a) => a.read(buf),
|
EitherOutput::First(a) => a.read(buf),
|
||||||
&mut EitherOutput::Second(ref mut b) => b.read(buf),
|
EitherOutput::Second(b) => b.read(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -67,8 +68,8 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn shutdown(&mut self) -> Poll<(), IoError> {
|
fn shutdown(&mut self) -> Poll<(), IoError> {
|
||||||
match self {
|
match self {
|
||||||
&mut EitherOutput::First(ref mut a) => a.shutdown(),
|
EitherOutput::First(a) => a.shutdown(),
|
||||||
&mut EitherOutput::Second(ref mut b) => b.shutdown(),
|
EitherOutput::Second(b) => b.shutdown(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -81,16 +82,16 @@ where
|
|||||||
#[inline]
|
#[inline]
|
||||||
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
fn write(&mut self, buf: &[u8]) -> Result<usize, IoError> {
|
||||||
match self {
|
match self {
|
||||||
&mut EitherOutput::First(ref mut a) => a.write(buf),
|
EitherOutput::First(a) => a.write(buf),
|
||||||
&mut EitherOutput::Second(ref mut b) => b.write(buf),
|
EitherOutput::Second(b) => b.write(buf),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> Result<(), IoError> {
|
fn flush(&mut self) -> Result<(), IoError> {
|
||||||
match self {
|
match self {
|
||||||
&mut EitherOutput::First(ref mut a) => a.flush(),
|
EitherOutput::First(a) => a.flush(),
|
||||||
&mut EitherOutput::Second(ref mut b) => b.flush(),
|
EitherOutput::Second(b) => b.flush(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -104,16 +105,16 @@ where
|
|||||||
type OutboundSubstream = EitherOutbound<A, B>;
|
type OutboundSubstream = EitherOutbound<A, B>;
|
||||||
|
|
||||||
fn poll_inbound(&self) -> Poll<Option<Self::Substream>, IoError> {
|
fn poll_inbound(&self) -> Poll<Option<Self::Substream>, IoError> {
|
||||||
match *self {
|
match self {
|
||||||
EitherOutput::First(ref inner) => inner.poll_inbound().map(|p| p.map(|o| o.map(EitherOutput::First))),
|
EitherOutput::First(inner) => inner.poll_inbound().map(|p| p.map(|o| o.map(EitherOutput::First))),
|
||||||
EitherOutput::Second(ref inner) => inner.poll_inbound().map(|p| p.map(|o| o.map(EitherOutput::Second))),
|
EitherOutput::Second(inner) => inner.poll_inbound().map(|p| p.map(|o| o.map(EitherOutput::Second))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn open_outbound(&self) -> Self::OutboundSubstream {
|
fn open_outbound(&self) -> Self::OutboundSubstream {
|
||||||
match *self {
|
match self {
|
||||||
EitherOutput::First(ref inner) => EitherOutbound::A(inner.open_outbound()),
|
EitherOutput::First(inner) => EitherOutbound::A(inner.open_outbound()),
|
||||||
EitherOutput::Second(ref inner) => EitherOutbound::B(inner.open_outbound()),
|
EitherOutput::Second(inner) => EitherOutbound::B(inner.open_outbound()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,14 +131,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
|
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
|
||||||
match *self {
|
match self {
|
||||||
EitherOutput::First(ref inner) => {
|
EitherOutput::First(inner) => {
|
||||||
match substream {
|
match substream {
|
||||||
EitherOutbound::A(substream) => inner.destroy_outbound(substream),
|
EitherOutbound::A(substream) => inner.destroy_outbound(substream),
|
||||||
_ => panic!("Wrong API usage")
|
_ => panic!("Wrong API usage")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
EitherOutput::Second(ref inner) => {
|
EitherOutput::Second(inner) => {
|
||||||
match substream {
|
match substream {
|
||||||
EitherOutbound::B(substream) => inner.destroy_outbound(substream),
|
EitherOutbound::B(substream) => inner.destroy_outbound(substream),
|
||||||
_ => panic!("Wrong API usage")
|
_ => panic!("Wrong API usage")
|
||||||
@ -195,14 +196,14 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn destroy_substream(&self, substream: Self::Substream) {
|
fn destroy_substream(&self, substream: Self::Substream) {
|
||||||
match *self {
|
match self {
|
||||||
EitherOutput::First(ref inner) => {
|
EitherOutput::First(inner) => {
|
||||||
match substream {
|
match substream {
|
||||||
EitherOutput::First(substream) => inner.destroy_substream(substream),
|
EitherOutput::First(substream) => inner.destroy_substream(substream),
|
||||||
_ => panic!("Wrong API usage")
|
_ => panic!("Wrong API usage")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
EitherOutput::Second(ref inner) => {
|
EitherOutput::Second(inner) => {
|
||||||
match substream {
|
match substream {
|
||||||
EitherOutput::Second(substream) => inner.destroy_substream(substream),
|
EitherOutput::Second(substream) => inner.destroy_substream(substream),
|
||||||
_ => panic!("Wrong API usage")
|
_ => panic!("Wrong API usage")
|
||||||
@ -212,16 +213,16 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn shutdown(&self, kind: Shutdown) -> Poll<(), IoError> {
|
fn shutdown(&self, kind: Shutdown) -> Poll<(), IoError> {
|
||||||
match *self {
|
match self {
|
||||||
EitherOutput::First(ref inner) => inner.shutdown(kind),
|
EitherOutput::First(inner) => inner.shutdown(kind),
|
||||||
EitherOutput::Second(ref inner) => inner.shutdown(kind)
|
EitherOutput::Second(inner) => inner.shutdown(kind)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn flush_all(&self) -> Poll<(), IoError> {
|
fn flush_all(&self) -> Poll<(), IoError> {
|
||||||
match *self {
|
match self {
|
||||||
EitherOutput::First(ref inner) => inner.flush_all(),
|
EitherOutput::First(inner) => inner.flush_all(),
|
||||||
EitherOutput::Second(ref inner) => inner.flush_all()
|
EitherOutput::Second(inner) => inner.flush_all()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -243,52 +244,44 @@ pub enum EitherListenStream<A, B> {
|
|||||||
|
|
||||||
impl<AStream, BStream, AInner, BInner> Stream for EitherListenStream<AStream, BStream>
|
impl<AStream, BStream, AInner, BInner> Stream for EitherListenStream<AStream, BStream>
|
||||||
where
|
where
|
||||||
AStream: Stream<Item = AInner, Error = IoError>,
|
AStream: Stream<Item = (AInner, Multiaddr), Error = IoError>,
|
||||||
BStream: Stream<Item = BInner, Error = IoError>,
|
BStream: Stream<Item = (BInner, Multiaddr), Error = IoError>,
|
||||||
{
|
{
|
||||||
type Item = EitherListenUpgrade<AInner, BInner>;
|
type Item = (EitherFuture<AInner, BInner>, Multiaddr);
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
match self {
|
match self {
|
||||||
&mut EitherListenStream::First(ref mut a) => a.poll()
|
EitherListenStream::First(a) => a.poll()
|
||||||
.map(|i| i.map(|v| v.map(EitherListenUpgrade::First))),
|
.map(|i| (i.map(|v| (v.map(|(o, addr)| (EitherFuture::First(o), addr)))))),
|
||||||
&mut EitherListenStream::Second(ref mut a) => a.poll()
|
EitherListenStream::Second(a) => a.poll()
|
||||||
.map(|i| i.map(|v| v.map(EitherListenUpgrade::Second))),
|
.map(|i| (i.map(|v| (v.map(|(o, addr)| (EitherFuture::Second(o), addr)))))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: This type is needed because of the lack of `impl Trait` in stable Rust.
|
/// Implements `Future` and dispatches all method calls to either `First` or `Second`.
|
||||||
// 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)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
#[must_use = "futures do nothing unless polled"]
|
#[must_use = "futures do nothing unless polled"]
|
||||||
pub enum EitherListenUpgrade<A, B> {
|
pub enum EitherFuture<A, B> {
|
||||||
First(A),
|
First(A),
|
||||||
Second(B),
|
Second(B),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B, Ao, Bo, Af, Bf> Future for EitherListenUpgrade<A, B>
|
impl<AFuture, BFuture, AInner, BInner> Future for EitherFuture<AFuture, BFuture>
|
||||||
where
|
where
|
||||||
A: Future<Item = (Ao, Af), Error = IoError>,
|
AFuture: Future<Item = AInner, Error = IoError>,
|
||||||
B: Future<Item = (Bo, Bf), Error = IoError>,
|
BFuture: Future<Item = BInner, Error = IoError>,
|
||||||
{
|
{
|
||||||
type Item = (EitherOutput<Ao, Bo>, future::Either<Af, Bf>);
|
type Item = EitherOutput<AInner, BInner>;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
match self {
|
match self {
|
||||||
&mut EitherListenUpgrade::First(ref mut a) => {
|
EitherFuture::First(a) => a.poll().map(|v| v.map(EitherOutput::First)),
|
||||||
let (item, addr) = try_ready!(a.poll());
|
EitherFuture::Second(a) => a.poll().map(|v| v.map(EitherOutput::Second)),
|
||||||
Ok(Async::Ready((EitherOutput::First(item), future::Either::A(addr))))
|
|
||||||
}
|
|
||||||
&mut EitherListenUpgrade::Second(ref mut b) => {
|
|
||||||
let (item, addr) = try_ready!(b.poll());
|
|
||||||
Ok(Async::Ready((EitherOutput::Second(item), future::Either::B(addr))))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -142,7 +142,7 @@
|
|||||||
//! // TODO: right now the only available protocol is ping, but we want to replace it with
|
//! // TODO: right now the only available protocol is ping, but we want to replace it with
|
||||||
//! // something that is more simple to use
|
//! // something that is more simple to use
|
||||||
//! .dial("127.0.0.1:12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
//! .dial("127.0.0.1:12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
||||||
//! .and_then(|(out, _)| {
|
//! .and_then(|out| {
|
||||||
//! match out {
|
//! match out {
|
||||||
//! PingOutput::Ponger(processing) => Box::new(processing) as Box<Future<Item = _, Error = _>>,
|
//! PingOutput::Ponger(processing) => Box::new(processing) as Box<Future<Item = _, Error = _>>,
|
||||||
//! PingOutput::Pinger(mut pinger) => {
|
//! PingOutput::Pinger(mut pinger) => {
|
||||||
@ -220,5 +220,5 @@ pub use self::multiaddr::Multiaddr;
|
|||||||
pub use self::muxing::StreamMuxer;
|
pub use self::muxing::StreamMuxer;
|
||||||
pub use self::peer_id::PeerId;
|
pub use self::peer_id::PeerId;
|
||||||
pub use self::public_key::PublicKey;
|
pub use self::public_key::PublicKey;
|
||||||
pub use self::transport::{MuxedTransport, Transport};
|
pub use self::transport::Transport;
|
||||||
pub use self::upgrade::{ConnectionUpgrade, Endpoint};
|
pub use self::upgrade::{ConnectionUpgrade, Endpoint};
|
||||||
|
@ -25,16 +25,15 @@ use nodes::node::Substream;
|
|||||||
use nodes::handled_node_tasks::{HandledNodesEvent, HandledNodesTasks};
|
use nodes::handled_node_tasks::{HandledNodesEvent, HandledNodesTasks};
|
||||||
use nodes::handled_node_tasks::{Task as HandledNodesTask, TaskId};
|
use nodes::handled_node_tasks::{Task as HandledNodesTask, TaskId};
|
||||||
use nodes::handled_node::NodeHandler;
|
use nodes::handled_node::NodeHandler;
|
||||||
use std::{collections::hash_map::Entry, fmt, mem};
|
use std::{collections::hash_map::Entry, fmt, io, mem};
|
||||||
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
use PeerId;
|
||||||
use {Multiaddr, PeerId};
|
|
||||||
|
|
||||||
// TODO: make generic over PeerId
|
// TODO: make generic over PeerId
|
||||||
|
|
||||||
/// Implementation of `Stream` that handles a collection of nodes.
|
/// Implementation of `Stream` that handles a collection of nodes.
|
||||||
pub struct CollectionStream<TInEvent, TOutEvent> {
|
pub struct CollectionStream<TInEvent, TOutEvent, THandler> {
|
||||||
/// Object that handles the tasks.
|
/// Object that handles the tasks.
|
||||||
inner: HandledNodesTasks<TInEvent, TOutEvent>,
|
inner: HandledNodesTasks<TInEvent, TOutEvent, THandler>,
|
||||||
/// List of nodes, with the task id that handles this node. The corresponding entry in `tasks`
|
/// List of nodes, with the task id that handles this node. The corresponding entry in `tasks`
|
||||||
/// must always be in the `Connected` state.
|
/// must always be in the `Connected` state.
|
||||||
nodes: FnvHashMap<PeerId, TaskId>,
|
nodes: FnvHashMap<PeerId, TaskId>,
|
||||||
@ -43,7 +42,7 @@ pub struct CollectionStream<TInEvent, TOutEvent> {
|
|||||||
tasks: FnvHashMap<TaskId, TaskState>,
|
tasks: FnvHashMap<TaskId, TaskState>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TInEvent, TOutEvent> fmt::Debug for CollectionStream<TInEvent, TOutEvent> {
|
impl<TInEvent, TOutEvent, THandler> fmt::Debug for CollectionStream<TInEvent, TOutEvent, THandler> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
let mut list = f.debug_list();
|
let mut list = f.debug_list();
|
||||||
for (id, task) in &self.tasks {
|
for (id, task) in &self.tasks {
|
||||||
@ -70,10 +69,10 @@ enum TaskState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Event that can happen on the `CollectionStream`.
|
/// Event that can happen on the `CollectionStream`.
|
||||||
pub enum CollectionEvent<'a, TInEvent:'a , TOutEvent: 'a> {
|
pub enum CollectionEvent<'a, TInEvent:'a , TOutEvent: 'a, THandler: 'a> {
|
||||||
/// A connection to a node has succeeded. You must use the provided event in order to accept
|
/// A connection to a node has succeeded. You must use the provided event in order to accept
|
||||||
/// the connection.
|
/// the connection.
|
||||||
NodeReached(CollectionReachEvent<'a, TInEvent, TOutEvent>),
|
NodeReached(CollectionReachEvent<'a, TInEvent, TOutEvent, THandler>),
|
||||||
|
|
||||||
/// A connection to a node has been closed.
|
/// A connection to a node has been closed.
|
||||||
///
|
///
|
||||||
@ -85,11 +84,13 @@ pub enum CollectionEvent<'a, TInEvent:'a , TOutEvent: 'a> {
|
|||||||
},
|
},
|
||||||
|
|
||||||
/// A connection to a node has errored.
|
/// A connection to a node has errored.
|
||||||
|
///
|
||||||
|
/// Can only happen after a node has been successfully reached.
|
||||||
NodeError {
|
NodeError {
|
||||||
/// Identifier of the node.
|
/// Identifier of the node.
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
/// The error that happened.
|
/// The error that happened.
|
||||||
error: IoError,
|
error: io::Error,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// An error happened on the future that was trying to reach a node.
|
/// An error happened on the future that was trying to reach a node.
|
||||||
@ -97,7 +98,9 @@ pub enum CollectionEvent<'a, TInEvent:'a , TOutEvent: 'a> {
|
|||||||
/// Identifier of the reach attempt that failed.
|
/// Identifier of the reach attempt that failed.
|
||||||
id: ReachAttemptId,
|
id: ReachAttemptId,
|
||||||
/// Error that happened on the future.
|
/// Error that happened on the future.
|
||||||
error: IoError,
|
error: io::Error,
|
||||||
|
/// The handler that was passed to `add_reach_attempt`.
|
||||||
|
handler: THandler,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A node has produced an event.
|
/// A node has produced an event.
|
||||||
@ -109,7 +112,7 @@ pub enum CollectionEvent<'a, TInEvent:'a , TOutEvent: 'a> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TInEvent, TOutEvent> fmt::Debug for CollectionEvent<'a, TInEvent, TOutEvent>
|
impl<'a, TInEvent, TOutEvent, THandler> fmt::Debug for CollectionEvent<'a, TInEvent, TOutEvent, THandler>
|
||||||
where TOutEvent: fmt::Debug
|
where TOutEvent: fmt::Debug
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
@ -130,7 +133,7 @@ where TOutEvent: fmt::Debug
|
|||||||
.field("error", error)
|
.field("error", error)
|
||||||
.finish()
|
.finish()
|
||||||
},
|
},
|
||||||
CollectionEvent::ReachError { ref id, ref error } => {
|
CollectionEvent::ReachError { ref id, ref error, .. } => {
|
||||||
f.debug_struct("CollectionEvent::ReachError")
|
f.debug_struct("CollectionEvent::ReachError")
|
||||||
.field("id", id)
|
.field("id", id)
|
||||||
.field("error", error)
|
.field("error", error)
|
||||||
@ -148,16 +151,16 @@ where TOutEvent: fmt::Debug
|
|||||||
|
|
||||||
/// Event that happens when we reach a node.
|
/// Event that happens when we reach a node.
|
||||||
#[must_use = "The node reached event is used to accept the newly-opened connection"]
|
#[must_use = "The node reached event is used to accept the newly-opened connection"]
|
||||||
pub struct CollectionReachEvent<'a, TInEvent: 'a, TOutEvent: 'a> {
|
pub struct CollectionReachEvent<'a, TInEvent: 'a, TOutEvent: 'a, THandler: 'a> {
|
||||||
/// Peer id we connected to.
|
/// Peer id we connected to.
|
||||||
peer_id: PeerId,
|
peer_id: PeerId,
|
||||||
/// The task id that reached the node.
|
/// The task id that reached the node.
|
||||||
id: TaskId,
|
id: TaskId,
|
||||||
/// The `CollectionStream` we are referencing.
|
/// The `CollectionStream` we are referencing.
|
||||||
parent: &'a mut CollectionStream<TInEvent, TOutEvent>,
|
parent: &'a mut CollectionStream<TInEvent, TOutEvent, THandler>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TInEvent, TOutEvent> CollectionReachEvent<'a, TInEvent, TOutEvent> {
|
impl<'a, TInEvent, TOutEvent, THandler> CollectionReachEvent<'a, TInEvent, TOutEvent, THandler> {
|
||||||
/// Returns the peer id the node that has been reached.
|
/// Returns the peer id the node that has been reached.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn peer_id(&self) -> &PeerId {
|
pub fn peer_id(&self) -> &PeerId {
|
||||||
@ -220,7 +223,7 @@ impl<'a, TInEvent, TOutEvent> CollectionReachEvent<'a, TInEvent, TOutEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TInEvent, TOutEvent> fmt::Debug for CollectionReachEvent<'a, TInEvent, TOutEvent> {
|
impl<'a, TInEvent, TOutEvent, THandler> fmt::Debug for CollectionReachEvent<'a, TInEvent, TOutEvent, THandler> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
f.debug_struct("CollectionReachEvent")
|
f.debug_struct("CollectionReachEvent")
|
||||||
.field("peer_id", &self.peer_id)
|
.field("peer_id", &self.peer_id)
|
||||||
@ -229,7 +232,7 @@ impl<'a, TInEvent, TOutEvent> fmt::Debug for CollectionReachEvent<'a, TInEvent,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, TInEvent, TOutEvent> Drop for CollectionReachEvent<'a, TInEvent, TOutEvent> {
|
impl<'a, TInEvent, TOutEvent, THandler> Drop for CollectionReachEvent<'a, TInEvent, TOutEvent, THandler> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let task_state = self.parent.tasks.remove(&self.id);
|
let task_state = self.parent.tasks.remove(&self.id);
|
||||||
debug_assert!(if let Some(TaskState::Pending) = task_state { true } else { false });
|
debug_assert!(if let Some(TaskState::Pending) = task_state { true } else { false });
|
||||||
@ -255,7 +258,7 @@ pub enum CollectionNodeAccept {
|
|||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct ReachAttemptId(TaskId);
|
pub struct ReachAttemptId(TaskId);
|
||||||
|
|
||||||
impl<TInEvent, TOutEvent> CollectionStream<TInEvent, TOutEvent> {
|
impl<TInEvent, TOutEvent, THandler> CollectionStream<TInEvent, TOutEvent, THandler> {
|
||||||
/// Creates a new empty collection.
|
/// Creates a new empty collection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -270,12 +273,11 @@ impl<TInEvent, TOutEvent> CollectionStream<TInEvent, TOutEvent> {
|
|||||||
///
|
///
|
||||||
/// This method spawns a task dedicated to resolving this future and processing the node's
|
/// This method spawns a task dedicated to resolving this future and processing the node's
|
||||||
/// events.
|
/// events.
|
||||||
pub fn add_reach_attempt<TFut, TMuxer, TAddrFut, THandler>(&mut self, future: TFut, handler: THandler)
|
pub fn add_reach_attempt<TFut, TMuxer>(&mut self, future: TFut, handler: THandler)
|
||||||
-> ReachAttemptId
|
-> ReachAttemptId
|
||||||
where
|
where
|
||||||
TFut: Future<Item = ((PeerId, TMuxer), TAddrFut), Error = IoError> + Send + 'static,
|
TFut: Future<Item = (PeerId, TMuxer), Error = io::Error> + Send + 'static,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError> + Send + 'static,
|
THandler: NodeHandler<Substream = Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent> + Send + 'static,
|
||||||
THandler: NodeHandler<Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent> + Send + 'static,
|
|
||||||
TInEvent: Send + 'static,
|
TInEvent: Send + 'static,
|
||||||
TOutEvent: Send + 'static,
|
TOutEvent: Send + 'static,
|
||||||
THandler::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be required?
|
THandler::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be required?
|
||||||
@ -362,44 +364,44 @@ impl<TInEvent, TOutEvent> CollectionStream<TInEvent, TOutEvent> {
|
|||||||
/// > **Note**: we use a regular `poll` method instead of implementing `Stream` in order to
|
/// > **Note**: we use a regular `poll` method instead of implementing `Stream` in order to
|
||||||
/// > remove the `Err` variant, but also because we want the `CollectionStream` to stay
|
/// > remove the `Err` variant, but also because we want the `CollectionStream` to stay
|
||||||
/// > borrowed if necessary.
|
/// > borrowed if necessary.
|
||||||
pub fn poll(&mut self) -> Async<Option<CollectionEvent<TInEvent, TOutEvent>>> {
|
pub fn poll(&mut self) -> Async<CollectionEvent<TInEvent, TOutEvent, THandler>> {
|
||||||
let item = match self.inner.poll() {
|
let item = match self.inner.poll() {
|
||||||
Async::Ready(item) => item,
|
Async::Ready(item) => item,
|
||||||
Async::NotReady => return Async::NotReady,
|
Async::NotReady => return Async::NotReady,
|
||||||
};
|
};
|
||||||
|
|
||||||
match item {
|
match item {
|
||||||
Some(HandledNodesEvent::TaskClosed { id, result }) => {
|
HandledNodesEvent::TaskClosed { id, result, handler } => {
|
||||||
match (self.tasks.remove(&id), result) {
|
match (self.tasks.remove(&id), result, handler) {
|
||||||
(Some(TaskState::Pending), Err(err)) => {
|
(Some(TaskState::Pending), Err(err), Some(handler)) => {
|
||||||
Async::Ready(Some(CollectionEvent::ReachError {
|
Async::Ready(CollectionEvent::ReachError {
|
||||||
id: ReachAttemptId(id),
|
id: ReachAttemptId(id),
|
||||||
error: err,
|
error: err,
|
||||||
}))
|
handler,
|
||||||
|
})
|
||||||
},
|
},
|
||||||
(Some(TaskState::Pending), Ok(())) => {
|
(Some(TaskState::Pending), _, _) => {
|
||||||
// TODO: this variant shouldn't happen ; prove this
|
// TODO: this variant shouldn't happen ; prove this
|
||||||
Async::Ready(Some(CollectionEvent::ReachError {
|
panic!()
|
||||||
id: ReachAttemptId(id),
|
|
||||||
error: IoError::new(IoErrorKind::Other, "couldn't reach the node"),
|
|
||||||
}))
|
|
||||||
},
|
},
|
||||||
(Some(TaskState::Connected(peer_id)), Ok(())) => {
|
(Some(TaskState::Connected(peer_id)), Ok(()), _handler) => {
|
||||||
|
debug_assert!(_handler.is_none());
|
||||||
let _node_task_id = self.nodes.remove(&peer_id);
|
let _node_task_id = self.nodes.remove(&peer_id);
|
||||||
debug_assert_eq!(_node_task_id, Some(id));
|
debug_assert_eq!(_node_task_id, Some(id));
|
||||||
Async::Ready(Some(CollectionEvent::NodeClosed {
|
Async::Ready(CollectionEvent::NodeClosed {
|
||||||
peer_id,
|
peer_id,
|
||||||
}))
|
})
|
||||||
},
|
},
|
||||||
(Some(TaskState::Connected(peer_id)), Err(err)) => {
|
(Some(TaskState::Connected(peer_id)), Err(err), _handler) => {
|
||||||
|
debug_assert!(_handler.is_none());
|
||||||
let _node_task_id = self.nodes.remove(&peer_id);
|
let _node_task_id = self.nodes.remove(&peer_id);
|
||||||
debug_assert_eq!(_node_task_id, Some(id));
|
debug_assert_eq!(_node_task_id, Some(id));
|
||||||
Async::Ready(Some(CollectionEvent::NodeError {
|
Async::Ready(CollectionEvent::NodeError {
|
||||||
peer_id,
|
peer_id,
|
||||||
error: err,
|
error: err,
|
||||||
}))
|
})
|
||||||
},
|
},
|
||||||
(None, _) => {
|
(None, _, _) => {
|
||||||
panic!("self.tasks is always kept in sync with the tasks in self.inner ; \
|
panic!("self.tasks is always kept in sync with the tasks in self.inner ; \
|
||||||
when we add a task in self.inner we add a corresponding entry in \
|
when we add a task in self.inner we add a corresponding entry in \
|
||||||
self.tasks, and remove the entry only when the task is closed ; \
|
self.tasks, and remove the entry only when the task is closed ; \
|
||||||
@ -407,14 +409,14 @@ impl<TInEvent, TOutEvent> CollectionStream<TInEvent, TOutEvent> {
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
Some(HandledNodesEvent::NodeReached { id, peer_id }) => {
|
HandledNodesEvent::NodeReached { id, peer_id } => {
|
||||||
Async::Ready(Some(CollectionEvent::NodeReached(CollectionReachEvent {
|
Async::Ready(CollectionEvent::NodeReached(CollectionReachEvent {
|
||||||
parent: self,
|
parent: self,
|
||||||
id,
|
id,
|
||||||
peer_id,
|
peer_id,
|
||||||
})))
|
}))
|
||||||
},
|
},
|
||||||
Some(HandledNodesEvent::NodeEvent { id, event }) => {
|
HandledNodesEvent::NodeEvent { id, event } => {
|
||||||
let peer_id = match self.tasks.get(&id) {
|
let peer_id = match self.tasks.get(&id) {
|
||||||
Some(TaskState::Connected(peer_id)) => peer_id.clone(),
|
Some(TaskState::Connected(peer_id)) => peer_id.clone(),
|
||||||
_ => panic!("we can only receive NodeEvent events from a task after we \
|
_ => panic!("we can only receive NodeEvent events from a task after we \
|
||||||
@ -423,12 +425,11 @@ impl<TInEvent, TOutEvent> CollectionStream<TInEvent, TOutEvent> {
|
|||||||
self.tasks is switched to the Connected state ; qed"),
|
self.tasks is switched to the Connected state ; qed"),
|
||||||
};
|
};
|
||||||
|
|
||||||
Async::Ready(Some(CollectionEvent::NodeEvent {
|
Async::Ready(CollectionEvent::NodeEvent {
|
||||||
peer_id,
|
peer_id,
|
||||||
event,
|
event,
|
||||||
}))
|
})
|
||||||
}
|
}
|
||||||
None => Async::Ready(None),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,20 +22,18 @@ use muxing::StreamMuxer;
|
|||||||
use nodes::node::{NodeEvent, NodeStream, Substream};
|
use nodes::node::{NodeEvent, NodeStream, Substream};
|
||||||
use futures::{prelude::*, stream::Fuse};
|
use futures::{prelude::*, stream::Fuse};
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use Multiaddr;
|
|
||||||
|
|
||||||
/// Handler for the substreams of a node.
|
/// Handler for the substreams of a node.
|
||||||
///
|
|
||||||
/// > Note: When implementing the various methods, don't forget that you have to register the
|
|
||||||
/// > task that was the latest to poll and notify it.
|
|
||||||
// TODO: right now it is possible for a node handler to be built, then shut down right after if we
|
// TODO: right now it is possible for a node handler to be built, then shut down right after if we
|
||||||
// realize we dialed the wrong peer for example ; this could be surprising and should either
|
// realize we dialed the wrong peer for example ; this could be surprising and should either
|
||||||
// be documented or changed (favouring the "documented" right now)
|
// be documented or changed (favouring the "documented" right now)
|
||||||
pub trait NodeHandler<TSubstream> {
|
pub trait NodeHandler {
|
||||||
/// Custom event that can be received from the outside.
|
/// Custom event that can be received from the outside.
|
||||||
type InEvent;
|
type InEvent;
|
||||||
/// Custom event that can be produced by the handler and that will be returned by the swarm.
|
/// Custom event that can be produced by the handler and that will be returned by the swarm.
|
||||||
type OutEvent;
|
type OutEvent;
|
||||||
|
/// The type of the substream containing the data.
|
||||||
|
type Substream;
|
||||||
/// Information about a substream. Can be sent to the handler through a `NodeHandlerEndpoint`,
|
/// Information about a substream. Can be sent to the handler through a `NodeHandlerEndpoint`,
|
||||||
/// and will be passed back in `inject_substream` or `inject_outbound_closed`.
|
/// and will be passed back in `inject_substream` or `inject_outbound_closed`.
|
||||||
type OutboundOpenInfo;
|
type OutboundOpenInfo;
|
||||||
@ -43,7 +41,7 @@ pub trait NodeHandler<TSubstream> {
|
|||||||
/// Sends a new substream to the handler.
|
/// Sends a new substream to the handler.
|
||||||
///
|
///
|
||||||
/// The handler is responsible for upgrading the substream to whatever protocol it wants.
|
/// The handler is responsible for upgrading the substream to whatever protocol it wants.
|
||||||
fn inject_substream(&mut self, substream: TSubstream, endpoint: NodeHandlerEndpoint<Self::OutboundOpenInfo>);
|
fn inject_substream(&mut self, substream: Self::Substream, endpoint: NodeHandlerEndpoint<Self::OutboundOpenInfo>);
|
||||||
|
|
||||||
/// Indicates to the handler that the inbound part of the muxer has been closed, and that
|
/// Indicates to the handler that the inbound part of the muxer has been closed, and that
|
||||||
/// therefore no more inbound substream will be produced.
|
/// therefore no more inbound substream will be produced.
|
||||||
@ -53,9 +51,6 @@ pub trait NodeHandler<TSubstream> {
|
|||||||
/// part of the muxer has been closed.
|
/// part of the muxer has been closed.
|
||||||
fn inject_outbound_closed(&mut self, user_data: Self::OutboundOpenInfo);
|
fn inject_outbound_closed(&mut self, user_data: Self::OutboundOpenInfo);
|
||||||
|
|
||||||
/// Indicates to the handler that the multiaddr future has resolved.
|
|
||||||
fn inject_multiaddr(&mut self, multiaddr: Result<Multiaddr, IoError>);
|
|
||||||
|
|
||||||
/// Injects an event coming from the outside into the handler.
|
/// Injects an event coming from the outside into the handler.
|
||||||
fn inject_event(&mut self, event: Self::InEvent);
|
fn inject_event(&mut self, event: Self::InEvent);
|
||||||
|
|
||||||
@ -78,6 +73,26 @@ pub enum NodeHandlerEndpoint<TOutboundOpenInfo> {
|
|||||||
Listener,
|
Listener,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<TOutboundOpenInfo> NodeHandlerEndpoint<TOutboundOpenInfo> {
|
||||||
|
/// Returns true for `Dialer`.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_dialer(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
NodeHandlerEndpoint::Dialer(_) => true,
|
||||||
|
NodeHandlerEndpoint::Listener => false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Returns true for `Listener`.
|
||||||
|
#[inline]
|
||||||
|
pub fn is_listener(&self) -> bool {
|
||||||
|
match self {
|
||||||
|
NodeHandlerEndpoint::Dialer(_) => false,
|
||||||
|
NodeHandlerEndpoint::Listener => true,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// Event produced by a handler.
|
/// Event produced by a handler.
|
||||||
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
|
||||||
pub enum NodeHandlerEvent<TOutboundOpenInfo, TCustom> {
|
pub enum NodeHandlerEvent<TOutboundOpenInfo, TCustom> {
|
||||||
@ -119,30 +134,29 @@ impl<TOutboundOpenInfo, TCustom> NodeHandlerEvent<TOutboundOpenInfo, TCustom> {
|
|||||||
|
|
||||||
/// A node combined with an implementation of `NodeHandler`.
|
/// A node combined with an implementation of `NodeHandler`.
|
||||||
// TODO: impl Debug
|
// TODO: impl Debug
|
||||||
pub struct HandledNode<TMuxer, TAddrFut, THandler>
|
pub struct HandledNode<TMuxer, THandler>
|
||||||
where
|
where
|
||||||
TMuxer: StreamMuxer,
|
TMuxer: StreamMuxer,
|
||||||
THandler: NodeHandler<Substream<TMuxer>>,
|
THandler: NodeHandler<Substream = Substream<TMuxer>>,
|
||||||
{
|
{
|
||||||
/// Node that handles the muxing.
|
/// Node that handles the muxing.
|
||||||
node: Fuse<NodeStream<TMuxer, TAddrFut, THandler::OutboundOpenInfo>>,
|
node: Fuse<NodeStream<TMuxer, THandler::OutboundOpenInfo>>,
|
||||||
/// Handler that processes substreams.
|
/// Handler that processes substreams.
|
||||||
handler: THandler,
|
handler: THandler,
|
||||||
// True, if the node is shutting down.
|
// True, if the node is shutting down.
|
||||||
is_shutting_down: bool
|
is_shutting_down: bool
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TMuxer, TAddrFut, THandler> HandledNode<TMuxer, TAddrFut, THandler>
|
impl<TMuxer, THandler> HandledNode<TMuxer, THandler>
|
||||||
where
|
where
|
||||||
TMuxer: StreamMuxer,
|
TMuxer: StreamMuxer,
|
||||||
THandler: NodeHandler<Substream<TMuxer>>,
|
THandler: NodeHandler<Substream = Substream<TMuxer>>,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
{
|
{
|
||||||
/// Builds a new `HandledNode`.
|
/// Builds a new `HandledNode`.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(muxer: TMuxer, multiaddr_future: TAddrFut, handler: THandler) -> Self {
|
pub fn new(muxer: TMuxer, handler: THandler) -> Self {
|
||||||
HandledNode {
|
HandledNode {
|
||||||
node: NodeStream::new(muxer, multiaddr_future).fuse(),
|
node: NodeStream::new(muxer).fuse(),
|
||||||
handler,
|
handler,
|
||||||
is_shutting_down: false
|
is_shutting_down: false
|
||||||
}
|
}
|
||||||
@ -192,11 +206,10 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TMuxer, TAddrFut, THandler> Stream for HandledNode<TMuxer, TAddrFut, THandler>
|
impl<TMuxer, THandler> Stream for HandledNode<TMuxer, THandler>
|
||||||
where
|
where
|
||||||
TMuxer: StreamMuxer,
|
TMuxer: StreamMuxer,
|
||||||
THandler: NodeHandler<Substream<TMuxer>>,
|
THandler: NodeHandler<Substream = Substream<TMuxer>>,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
{
|
{
|
||||||
type Item = THandler::OutEvent;
|
type Item = THandler::OutEvent;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
@ -220,9 +233,6 @@ where
|
|||||||
self.handler.shutdown()
|
self.handler.shutdown()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Async::Ready(Some(NodeEvent::Multiaddr(result))) => {
|
|
||||||
self.handler.inject_multiaddr(result)
|
|
||||||
}
|
|
||||||
Async::Ready(Some(NodeEvent::OutboundClosed { user_data })) => {
|
Async::Ready(Some(NodeEvent::OutboundClosed { user_data })) => {
|
||||||
self.handler.inject_outbound_closed(user_data)
|
self.handler.inject_outbound_closed(user_data)
|
||||||
}
|
}
|
||||||
@ -263,8 +273,8 @@ where
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use futures::future;
|
|
||||||
use muxing::{StreamMuxer, Shutdown};
|
use muxing::{StreamMuxer, Shutdown};
|
||||||
|
use std::marker::PhantomData;
|
||||||
use tokio::runtime::current_thread;
|
use tokio::runtime::current_thread;
|
||||||
|
|
||||||
// TODO: move somewhere? this could be useful as a dummy
|
// TODO: move somewhere? this could be useful as a dummy
|
||||||
@ -288,15 +298,17 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn proper_shutdown() {
|
fn proper_shutdown() {
|
||||||
// Test that `shutdown()` is properly called on the handler once a node stops.
|
// Test that `shutdown()` is properly called on the handler once a node stops.
|
||||||
struct Handler {
|
struct Handler<T> {
|
||||||
did_substream_attempt: bool,
|
did_substream_attempt: bool,
|
||||||
inbound_closed: bool,
|
inbound_closed: bool,
|
||||||
substream_attempt_cancelled: bool,
|
substream_attempt_cancelled: bool,
|
||||||
shutdown_called: bool,
|
shutdown_called: bool,
|
||||||
|
marker: PhantomData<T>,
|
||||||
};
|
};
|
||||||
impl<T> NodeHandler<T> for Handler {
|
impl<T> NodeHandler for Handler<T> {
|
||||||
type InEvent = ();
|
type InEvent = ();
|
||||||
type OutEvent = ();
|
type OutEvent = ();
|
||||||
|
type Substream = T;
|
||||||
type OutboundOpenInfo = ();
|
type OutboundOpenInfo = ();
|
||||||
fn inject_substream(&mut self, _: T, _: NodeHandlerEndpoint<()>) { panic!() }
|
fn inject_substream(&mut self, _: T, _: NodeHandlerEndpoint<()>) { panic!() }
|
||||||
fn inject_inbound_closed(&mut self) {
|
fn inject_inbound_closed(&mut self) {
|
||||||
@ -307,7 +319,6 @@ mod tests {
|
|||||||
assert!(!self.substream_attempt_cancelled);
|
assert!(!self.substream_attempt_cancelled);
|
||||||
self.substream_attempt_cancelled = true;
|
self.substream_attempt_cancelled = true;
|
||||||
}
|
}
|
||||||
fn inject_multiaddr(&mut self, _: Result<Multiaddr, IoError>) {}
|
|
||||||
fn inject_event(&mut self, _: Self::InEvent) { panic!() }
|
fn inject_event(&mut self, _: Self::InEvent) { panic!() }
|
||||||
fn shutdown(&mut self) {
|
fn shutdown(&mut self) {
|
||||||
assert!(self.inbound_closed);
|
assert!(self.inbound_closed);
|
||||||
@ -325,17 +336,18 @@ mod tests {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
impl Drop for Handler {
|
impl<T> Drop for Handler<T> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
assert!(self.shutdown_called);
|
assert!(self.shutdown_called);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let handled = HandledNode::new(InstaCloseMuxer, future::empty(), Handler {
|
let handled = HandledNode::new(InstaCloseMuxer, Handler {
|
||||||
did_substream_attempt: false,
|
did_substream_attempt: false,
|
||||||
inbound_closed: false,
|
inbound_closed: false,
|
||||||
substream_attempt_cancelled: false,
|
substream_attempt_cancelled: false,
|
||||||
shutdown_called: false,
|
shutdown_called: false,
|
||||||
|
marker: PhantomData,
|
||||||
});
|
});
|
||||||
|
|
||||||
current_thread::Runtime::new().unwrap().block_on(handled.for_each(|_| Ok(()))).unwrap();
|
current_thread::Runtime::new().unwrap().block_on(handled.for_each(|_| Ok(()))).unwrap();
|
||||||
|
@ -29,7 +29,7 @@ use std::io::Error as IoError;
|
|||||||
use std::{fmt, mem};
|
use std::{fmt, mem};
|
||||||
use tokio_executor;
|
use tokio_executor;
|
||||||
use void::Void;
|
use void::Void;
|
||||||
use {Multiaddr, PeerId};
|
use PeerId;
|
||||||
|
|
||||||
// TODO: make generic over PeerId
|
// TODO: make generic over PeerId
|
||||||
|
|
||||||
@ -51,7 +51,7 @@ use {Multiaddr, PeerId};
|
|||||||
|
|
||||||
/// Implementation of `Stream` that handles a collection of nodes.
|
/// Implementation of `Stream` that handles a collection of nodes.
|
||||||
// TODO: implement Debug
|
// TODO: implement Debug
|
||||||
pub struct HandledNodesTasks<TInEvent, TOutEvent> {
|
pub struct HandledNodesTasks<TInEvent, TOutEvent, THandler> {
|
||||||
/// For each active task, a sender allowing to transmit messages. Closing the sender interrupts
|
/// For each active task, a sender allowing to transmit messages. Closing the sender interrupts
|
||||||
/// the task. It is possible that we receive messages from tasks that used to be in this list
|
/// the task. It is possible that we receive messages from tasks that used to be in this list
|
||||||
/// but no longer are, in which case we should ignore them.
|
/// but no longer are, in which case we should ignore them.
|
||||||
@ -64,12 +64,12 @@ pub struct HandledNodesTasks<TInEvent, TOutEvent> {
|
|||||||
to_spawn: SmallVec<[Box<Future<Item = (), Error = ()> + Send>; 8]>,
|
to_spawn: SmallVec<[Box<Future<Item = (), Error = ()> + Send>; 8]>,
|
||||||
|
|
||||||
/// Sender to emit events to the outside. Meant to be cloned and sent to tasks.
|
/// Sender to emit events to the outside. Meant to be cloned and sent to tasks.
|
||||||
events_tx: mpsc::UnboundedSender<(InToExtMessage<TOutEvent>, TaskId)>,
|
events_tx: mpsc::UnboundedSender<(InToExtMessage<TOutEvent, THandler>, TaskId)>,
|
||||||
/// Receiver side for the events.
|
/// Receiver side for the events.
|
||||||
events_rx: mpsc::UnboundedReceiver<(InToExtMessage<TOutEvent>, TaskId)>,
|
events_rx: mpsc::UnboundedReceiver<(InToExtMessage<TOutEvent, THandler>, TaskId)>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TInEvent, TOutEvent> fmt::Debug for HandledNodesTasks<TInEvent, TOutEvent> {
|
impl<TInEvent, TOutEvent, THandler> fmt::Debug for HandledNodesTasks<TInEvent, TOutEvent, THandler> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
f.debug_list()
|
f.debug_list()
|
||||||
.entries(self.tasks.keys().cloned())
|
.entries(self.tasks.keys().cloned())
|
||||||
@ -79,15 +79,19 @@ impl<TInEvent, TOutEvent> fmt::Debug for HandledNodesTasks<TInEvent, TOutEvent>
|
|||||||
|
|
||||||
/// Event that can happen on the `HandledNodesTasks`.
|
/// Event that can happen on the `HandledNodesTasks`.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum HandledNodesEvent<TOutEvent> {
|
pub enum HandledNodesEvent<TOutEvent, THandler> {
|
||||||
/// A task has been closed.
|
/// A task has been closed.
|
||||||
///
|
///
|
||||||
/// This happens once the node handler closes or an error happens.
|
/// This happens once the node handler closes or an error happens.
|
||||||
|
// TODO: send back undelivered events?
|
||||||
TaskClosed {
|
TaskClosed {
|
||||||
/// Identifier of the task that closed.
|
/// Identifier of the task that closed.
|
||||||
id: TaskId,
|
id: TaskId,
|
||||||
/// What happened.
|
/// What happened.
|
||||||
result: Result<(), IoError>,
|
result: Result<(), IoError>,
|
||||||
|
/// If the task closed before reaching the node, this contains the handler that was passed
|
||||||
|
/// to `add_reach_attempt`.
|
||||||
|
handler: Option<THandler>,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A task has succeesfully connected to a node.
|
/// A task has succeesfully connected to a node.
|
||||||
@ -111,7 +115,7 @@ pub enum HandledNodesEvent<TOutEvent> {
|
|||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct TaskId(usize);
|
pub struct TaskId(usize);
|
||||||
|
|
||||||
impl<TInEvent, TOutEvent> HandledNodesTasks<TInEvent, TOutEvent> {
|
impl<TInEvent, TOutEvent, THandler> HandledNodesTasks<TInEvent, TOutEvent, THandler> {
|
||||||
/// Creates a new empty collection.
|
/// Creates a new empty collection.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@ -130,12 +134,11 @@ impl<TInEvent, TOutEvent> HandledNodesTasks<TInEvent, TOutEvent> {
|
|||||||
///
|
///
|
||||||
/// This method spawns a task dedicated to resolving this future and processing the node's
|
/// This method spawns a task dedicated to resolving this future and processing the node's
|
||||||
/// events.
|
/// events.
|
||||||
pub fn add_reach_attempt<TFut, TMuxer, TAddrFut, THandler>(&mut self, future: TFut, handler: THandler)
|
pub fn add_reach_attempt<TFut, TMuxer>(&mut self, future: TFut, handler: THandler)
|
||||||
-> TaskId
|
-> TaskId
|
||||||
where
|
where
|
||||||
TFut: Future<Item = ((PeerId, TMuxer), TAddrFut), Error = IoError> + Send + 'static,
|
TFut: Future<Item = (PeerId, TMuxer), Error = IoError> + Send + 'static,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError> + Send + 'static,
|
THandler: NodeHandler<Substream = Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent> + Send + 'static,
|
||||||
THandler: NodeHandler<Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent> + Send + 'static,
|
|
||||||
TInEvent: Send + 'static,
|
TInEvent: Send + 'static,
|
||||||
TOutEvent: Send + 'static,
|
TOutEvent: Send + 'static,
|
||||||
THandler::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be required?
|
THandler::OutboundOpenInfo: Send + 'static, // TODO: shouldn't be required?
|
||||||
@ -193,7 +196,7 @@ impl<TInEvent, TOutEvent> HandledNodesTasks<TInEvent, TOutEvent> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Provides an API similar to `Stream`, except that it cannot error.
|
/// Provides an API similar to `Stream`, except that it cannot error.
|
||||||
pub fn poll(&mut self) -> Async<Option<HandledNodesEvent<TOutEvent>>> {
|
pub fn poll(&mut self) -> Async<HandledNodesEvent<TOutEvent, THandler>> {
|
||||||
for to_spawn in self.to_spawn.drain() {
|
for to_spawn in self.to_spawn.drain() {
|
||||||
tokio_executor::spawn(to_spawn);
|
tokio_executor::spawn(to_spawn);
|
||||||
}
|
}
|
||||||
@ -210,22 +213,22 @@ impl<TInEvent, TOutEvent> HandledNodesTasks<TInEvent, TOutEvent> {
|
|||||||
|
|
||||||
match message {
|
match message {
|
||||||
InToExtMessage::NodeEvent(event) => {
|
InToExtMessage::NodeEvent(event) => {
|
||||||
break Async::Ready(Some(HandledNodesEvent::NodeEvent {
|
break Async::Ready(HandledNodesEvent::NodeEvent {
|
||||||
id: task_id,
|
id: task_id,
|
||||||
event,
|
event,
|
||||||
}));
|
});
|
||||||
},
|
},
|
||||||
InToExtMessage::NodeReached(peer_id) => {
|
InToExtMessage::NodeReached(peer_id) => {
|
||||||
break Async::Ready(Some(HandledNodesEvent::NodeReached {
|
break Async::Ready(HandledNodesEvent::NodeReached {
|
||||||
id: task_id,
|
id: task_id,
|
||||||
peer_id,
|
peer_id,
|
||||||
}));
|
});
|
||||||
},
|
},
|
||||||
InToExtMessage::TaskClosed(result) => {
|
InToExtMessage::TaskClosed(result, handler) => {
|
||||||
let _ = self.tasks.remove(&task_id);
|
let _ = self.tasks.remove(&task_id);
|
||||||
break Async::Ready(Some(HandledNodesEvent::TaskClosed {
|
break Async::Ready(HandledNodesEvent::TaskClosed {
|
||||||
id: task_id, result
|
id: task_id, result, handler
|
||||||
}));
|
});
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -249,6 +252,7 @@ pub struct Task<'a, TInEvent: 'a> {
|
|||||||
|
|
||||||
impl<'a, TInEvent> Task<'a, TInEvent> {
|
impl<'a, TInEvent> Task<'a, TInEvent> {
|
||||||
/// Sends an event to the given node.
|
/// Sends an event to the given node.
|
||||||
|
// TODO: report back on delivery
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn send_event(&mut self, event: TInEvent) {
|
pub fn send_event(&mut self, event: TInEvent) {
|
||||||
// It is possible that the sender is closed if the background task has already finished
|
// It is possible that the sender is closed if the background task has already finished
|
||||||
@ -279,48 +283,48 @@ impl<'a, TInEvent> fmt::Debug for Task<'a, TInEvent> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TInEvent, TOutEvent> Stream for HandledNodesTasks<TInEvent, TOutEvent> {
|
impl<TInEvent, TOutEvent, THandler> Stream for HandledNodesTasks<TInEvent, TOutEvent, THandler> {
|
||||||
type Item = HandledNodesEvent<TOutEvent>;
|
type Item = HandledNodesEvent<TOutEvent, THandler>;
|
||||||
type Error = Void; // TODO: use ! once stable
|
type Error = Void; // TODO: use ! once stable
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
Ok(self.poll())
|
Ok(self.poll().map(Option::Some))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Message to transmit from a task to the public API.
|
/// Message to transmit from a task to the public API.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
enum InToExtMessage<TOutEvent> {
|
enum InToExtMessage<TOutEvent, THandler> {
|
||||||
/// A connection to a node has succeeded.
|
/// A connection to a node has succeeded.
|
||||||
NodeReached(PeerId),
|
NodeReached(PeerId),
|
||||||
/// The task closed.
|
/// The task closed.
|
||||||
TaskClosed(Result<(), IoError>),
|
TaskClosed(Result<(), IoError>, Option<THandler>),
|
||||||
/// An event from the node.
|
/// An event from the node.
|
||||||
NodeEvent(TOutEvent),
|
NodeEvent(TOutEvent),
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Implementation of `Future` that handles a single node, and all the communications between
|
/// Implementation of `Future` that handles a single node, and all the communications between
|
||||||
/// the various components of the `HandledNodesTasks`.
|
/// the various components of the `HandledNodesTasks`.
|
||||||
struct NodeTask<TFut, TMuxer, TAddrFut, THandler, TInEvent, TOutEvent>
|
struct NodeTask<TFut, TMuxer, THandler, TInEvent, TOutEvent>
|
||||||
where
|
where
|
||||||
TMuxer: StreamMuxer,
|
TMuxer: StreamMuxer,
|
||||||
THandler: NodeHandler<Substream<TMuxer>>,
|
THandler: NodeHandler<Substream = Substream<TMuxer>>,
|
||||||
{
|
{
|
||||||
/// Sender to transmit events to the outside.
|
/// Sender to transmit events to the outside.
|
||||||
events_tx: mpsc::UnboundedSender<(InToExtMessage<TOutEvent>, TaskId)>,
|
events_tx: mpsc::UnboundedSender<(InToExtMessage<TOutEvent, THandler>, TaskId)>,
|
||||||
/// Receiving end for events sent from the main `HandledNodesTasks`.
|
/// Receiving end for events sent from the main `HandledNodesTasks`.
|
||||||
in_events_rx: stream::Fuse<mpsc::UnboundedReceiver<TInEvent>>,
|
in_events_rx: stream::Fuse<mpsc::UnboundedReceiver<TInEvent>>,
|
||||||
/// Inner state of the `NodeTask`.
|
/// Inner state of the `NodeTask`.
|
||||||
inner: NodeTaskInner<TFut, TMuxer, TAddrFut, THandler, TInEvent>,
|
inner: NodeTaskInner<TFut, TMuxer, THandler, TInEvent>,
|
||||||
/// Identifier of the attempt.
|
/// Identifier of the attempt.
|
||||||
id: TaskId,
|
id: TaskId,
|
||||||
}
|
}
|
||||||
|
|
||||||
enum NodeTaskInner<TFut, TMuxer, TAddrFut, THandler, TInEvent>
|
enum NodeTaskInner<TFut, TMuxer, THandler, TInEvent>
|
||||||
where
|
where
|
||||||
TMuxer: StreamMuxer,
|
TMuxer: StreamMuxer,
|
||||||
THandler: NodeHandler<Substream<TMuxer>>,
|
THandler: NodeHandler<Substream = Substream<TMuxer>>,
|
||||||
{
|
{
|
||||||
/// Future to resolve to connect to the node.
|
/// Future to resolve to connect to the node.
|
||||||
Future {
|
Future {
|
||||||
@ -335,19 +339,18 @@ where
|
|||||||
},
|
},
|
||||||
|
|
||||||
/// Fully functional node.
|
/// Fully functional node.
|
||||||
Node(HandledNode<TMuxer, TAddrFut, THandler>),
|
Node(HandledNode<TMuxer, THandler>),
|
||||||
|
|
||||||
/// A panic happened while polling.
|
/// A panic happened while polling.
|
||||||
Poisoned,
|
Poisoned,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TFut, TMuxer, TAddrFut, THandler, TInEvent, TOutEvent> Future for
|
impl<TFut, TMuxer, THandler, TInEvent, TOutEvent> Future for
|
||||||
NodeTask<TFut, TMuxer, TAddrFut, THandler, TInEvent, TOutEvent>
|
NodeTask<TFut, TMuxer, THandler, TInEvent, TOutEvent>
|
||||||
where
|
where
|
||||||
TMuxer: StreamMuxer,
|
TMuxer: StreamMuxer,
|
||||||
TFut: Future<Item = ((PeerId, TMuxer), TAddrFut), Error = IoError>,
|
TFut: Future<Item = (PeerId, TMuxer), Error = IoError>,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError>,
|
THandler: NodeHandler<Substream = Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent>,
|
||||||
THandler: NodeHandler<Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent>,
|
|
||||||
{
|
{
|
||||||
type Item = ();
|
type Item = ();
|
||||||
type Error = ();
|
type Error = ();
|
||||||
@ -369,9 +372,9 @@ where
|
|||||||
|
|
||||||
// Check whether dialing succeeded.
|
// Check whether dialing succeeded.
|
||||||
match future.poll() {
|
match future.poll() {
|
||||||
Ok(Async::Ready(((peer_id, muxer), addr_fut))) => {
|
Ok(Async::Ready((peer_id, muxer))) => {
|
||||||
let event = InToExtMessage::NodeReached(peer_id);
|
let event = InToExtMessage::NodeReached(peer_id);
|
||||||
let mut node = HandledNode::new(muxer, addr_fut, handler);
|
let mut node = HandledNode::new(muxer, handler);
|
||||||
for event in events_buffer {
|
for event in events_buffer {
|
||||||
node.inject_event(event);
|
node.inject_event(event);
|
||||||
}
|
}
|
||||||
@ -386,7 +389,7 @@ where
|
|||||||
},
|
},
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
// End the task
|
// End the task
|
||||||
let event = InToExtMessage::TaskClosed(Err(err));
|
let event = InToExtMessage::TaskClosed(Err(err), Some(handler));
|
||||||
let _ = self.events_tx.unbounded_send((event, self.id));
|
let _ = self.events_tx.unbounded_send((event, self.id));
|
||||||
return Ok(Async::Ready(()));
|
return Ok(Async::Ready(()));
|
||||||
}
|
}
|
||||||
@ -427,12 +430,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(Async::Ready(None)) => {
|
Ok(Async::Ready(None)) => {
|
||||||
let event = InToExtMessage::TaskClosed(Ok(()));
|
let event = InToExtMessage::TaskClosed(Ok(()), None);
|
||||||
let _ = self.events_tx.unbounded_send((event, self.id));
|
let _ = self.events_tx.unbounded_send((event, self.id));
|
||||||
return Ok(Async::Ready(())); // End the task.
|
return Ok(Async::Ready(())); // End the task.
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let event = InToExtMessage::TaskClosed(Err(err));
|
let event = InToExtMessage::TaskClosed(Err(err), None);
|
||||||
let _ = self.events_tx.unbounded_send((event, self.id));
|
let _ = self.events_tx.unbounded_send((event, self.id));
|
||||||
return Ok(Async::Ready(())); // End the task.
|
return Ok(Async::Ready(())); // End the task.
|
||||||
}
|
}
|
||||||
|
@ -60,7 +60,7 @@ use {Multiaddr, Transport};
|
|||||||
/// ListenersEvent::Closed { listen_addr, listener, result } => {
|
/// ListenersEvent::Closed { listen_addr, listener, result } => {
|
||||||
/// println!("Listener {} has been closed: {:?}", listen_addr, result);
|
/// println!("Listener {} has been closed: {:?}", listen_addr, result);
|
||||||
/// },
|
/// },
|
||||||
/// ListenersEvent::Incoming { upgrade, listen_addr } => {
|
/// ListenersEvent::Incoming { upgrade, listen_addr, .. } => {
|
||||||
/// println!("A connection has arrived on {}", listen_addr);
|
/// println!("A connection has arrived on {}", listen_addr);
|
||||||
/// // We don't do anything with the newly-opened connection, but in a real-life
|
/// // We don't do anything with the newly-opened connection, but in a real-life
|
||||||
/// // program you probably want to use it!
|
/// // program you probably want to use it!
|
||||||
@ -107,6 +107,8 @@ where
|
|||||||
upgrade: TTrans::ListenerUpgrade,
|
upgrade: TTrans::ListenerUpgrade,
|
||||||
/// Address of the listener which received the connection.
|
/// Address of the listener which received the connection.
|
||||||
listen_addr: Multiaddr,
|
listen_addr: Multiaddr,
|
||||||
|
/// Address used to send back data to the incoming client.
|
||||||
|
send_back_addr: Multiaddr,
|
||||||
},
|
},
|
||||||
|
|
||||||
/// A listener has closed, either gracefully or with an error.
|
/// A listener has closed, either gracefully or with an error.
|
||||||
@ -177,7 +179,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Provides an API similar to `Stream`, except that it cannot error.
|
/// Provides an API similar to `Stream`, except that it cannot error.
|
||||||
pub fn poll(&mut self) -> Async<Option<ListenersEvent<TTrans>>> {
|
pub fn poll(&mut self) -> Async<ListenersEvent<TTrans>> {
|
||||||
// We remove each element from `listeners` one by one and add them back.
|
// We remove each element from `listeners` one by one and add them back.
|
||||||
for n in (0..self.listeners.len()).rev() {
|
for n in (0..self.listeners.len()).rev() {
|
||||||
let mut listener = self.listeners.swap_remove(n);
|
let mut listener = self.listeners.swap_remove(n);
|
||||||
@ -185,27 +187,28 @@ where
|
|||||||
Ok(Async::NotReady) => {
|
Ok(Async::NotReady) => {
|
||||||
self.listeners.push(listener);
|
self.listeners.push(listener);
|
||||||
}
|
}
|
||||||
Ok(Async::Ready(Some(upgrade))) => {
|
Ok(Async::Ready(Some((upgrade, send_back_addr)))) => {
|
||||||
let listen_addr = listener.address.clone();
|
let listen_addr = listener.address.clone();
|
||||||
self.listeners.push(listener);
|
self.listeners.push(listener);
|
||||||
return Async::Ready(Some(ListenersEvent::Incoming {
|
return Async::Ready(ListenersEvent::Incoming {
|
||||||
upgrade,
|
upgrade,
|
||||||
listen_addr,
|
listen_addr,
|
||||||
}));
|
send_back_addr,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
Ok(Async::Ready(None)) => {
|
Ok(Async::Ready(None)) => {
|
||||||
return Async::Ready(Some(ListenersEvent::Closed {
|
return Async::Ready(ListenersEvent::Closed {
|
||||||
listen_addr: listener.address,
|
listen_addr: listener.address,
|
||||||
listener: listener.listener,
|
listener: listener.listener,
|
||||||
result: Ok(()),
|
result: Ok(()),
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
return Async::Ready(Some(ListenersEvent::Closed {
|
return Async::Ready(ListenersEvent::Closed {
|
||||||
listen_addr: listener.address,
|
listen_addr: listener.address,
|
||||||
listener: listener.listener,
|
listener: listener.listener,
|
||||||
result: Err(err),
|
result: Err(err),
|
||||||
}));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -224,7 +227,7 @@ where
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
Ok(self.poll())
|
Ok(self.poll().map(Option::Some))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +297,7 @@ mod tests {
|
|||||||
Async::Ready(Some(n)) => {
|
Async::Ready(Some(n)) => {
|
||||||
let addr = l.address.clone();
|
let addr = l.address.clone();
|
||||||
let stream = stream::iter_ok(n..)
|
let stream = stream::iter_ok(n..)
|
||||||
.map(move |stream| future::ok( (stream, future::ok(addr.clone())) ));
|
.map(move |stream| (future::ok(stream), addr.clone()));
|
||||||
Box::new(stream)
|
Box::new(stream)
|
||||||
}
|
}
|
||||||
Async::Ready(None) => {
|
Async::Ready(None) => {
|
||||||
@ -320,8 +323,9 @@ mod tests {
|
|||||||
.map_err(|(err, _)| err)
|
.map_err(|(err, _)| err)
|
||||||
.and_then(|(event, _)| {
|
.and_then(|(event, _)| {
|
||||||
match event {
|
match event {
|
||||||
Some(ListenersEvent::Incoming { listen_addr, upgrade }) => {
|
Some(ListenersEvent::Incoming { listen_addr, upgrade, send_back_addr }) => {
|
||||||
assert_eq!(listen_addr, "/memory".parse().unwrap());
|
assert_eq!(listen_addr, "/memory".parse().unwrap());
|
||||||
|
assert_eq!(send_back_addr, "/memory".parse().unwrap());
|
||||||
upgrade.map(|_| ()).map_err(|_| panic!())
|
upgrade.map(|_| ()).map_err(|_| panic!())
|
||||||
},
|
},
|
||||||
_ => panic!()
|
_ => panic!()
|
||||||
@ -384,11 +388,11 @@ mod tests {
|
|||||||
ls.listen_on(addr1).expect("listen_on failed");
|
ls.listen_on(addr1).expect("listen_on failed");
|
||||||
ls.listen_on(addr2).expect("listen_on failed");
|
ls.listen_on(addr2).expect("listen_on failed");
|
||||||
|
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(listeners_event)) => {
|
assert_matches!(ls.poll(), Async::Ready(listeners_event) => {
|
||||||
assert_matches!(listeners_event, ListenersEvent::Incoming{mut upgrade, listen_addr} => {
|
assert_matches!(listeners_event, ListenersEvent::Incoming{mut upgrade, listen_addr, ..} => {
|
||||||
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.2/tcp/4321");
|
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.2/tcp/4321");
|
||||||
assert_matches!(upgrade.poll().unwrap(), Async::Ready(tup) => {
|
assert_matches!(upgrade.poll().unwrap(), Async::Ready(tup) => {
|
||||||
assert_matches!(tup, (1, _))
|
assert_eq!(tup, 1)
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -407,11 +411,11 @@ mod tests {
|
|||||||
|
|
||||||
// Make the second listener return NotReady so we get the first listener next poll()
|
// Make the second listener return NotReady so we get the first listener next poll()
|
||||||
set_listener_state(&mut ls, 1, ListenerState::Ok(Async::NotReady));
|
set_listener_state(&mut ls, 1, ListenerState::Ok(Async::NotReady));
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(listeners_event)) => {
|
assert_matches!(ls.poll(), Async::Ready(listeners_event) => {
|
||||||
assert_matches!(listeners_event, ListenersEvent::Incoming{mut upgrade, listen_addr} => {
|
assert_matches!(listeners_event, ListenersEvent::Incoming{mut upgrade, listen_addr, ..} => {
|
||||||
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.1/tcp/1234");
|
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.1/tcp/1234");
|
||||||
assert_matches!(upgrade.poll().unwrap(), Async::Ready(tup) => {
|
assert_matches!(upgrade.poll().unwrap(), Async::Ready(tup) => {
|
||||||
assert_matches!(tup, (1, _))
|
assert_eq!(tup, 1)
|
||||||
});
|
});
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
@ -425,7 +429,7 @@ mod tests {
|
|||||||
let mut ls = ListenersStream::new(t);
|
let mut ls = ListenersStream::new(t);
|
||||||
ls.listen_on(addr).expect("listen_on failed");
|
ls.listen_on(addr).expect("listen_on failed");
|
||||||
set_listener_state(&mut ls, 0, ListenerState::Ok(Async::Ready(None)));
|
set_listener_state(&mut ls, 0, ListenerState::Ok(Async::Ready(None)));
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(listeners_event)) => {
|
assert_matches!(ls.poll(), Async::Ready(listeners_event) => {
|
||||||
assert_matches!(listeners_event, ListenersEvent::Closed{..})
|
assert_matches!(listeners_event, ListenersEvent::Closed{..})
|
||||||
});
|
});
|
||||||
assert_eq!(ls.listeners.len(), 0); // it's gone
|
assert_eq!(ls.listeners.len(), 0); // it's gone
|
||||||
@ -439,7 +443,7 @@ mod tests {
|
|||||||
let mut ls = ListenersStream::new(t);
|
let mut ls = ListenersStream::new(t);
|
||||||
ls.listen_on(addr).expect("listen_on failed");
|
ls.listen_on(addr).expect("listen_on failed");
|
||||||
set_listener_state(&mut ls, 0, ListenerState::Error); // simulate an error on the socket
|
set_listener_state(&mut ls, 0, ListenerState::Error); // simulate an error on the socket
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(listeners_event)) => {
|
assert_matches!(ls.poll(), Async::Ready(listeners_event) => {
|
||||||
assert_matches!(listeners_event, ListenersEvent::Closed{..})
|
assert_matches!(listeners_event, ListenersEvent::Closed{..})
|
||||||
});
|
});
|
||||||
assert_eq!(ls.listeners.len(), 0); // it's gone
|
assert_eq!(ls.listeners.len(), 0); // it's gone
|
||||||
@ -458,14 +462,14 @@ mod tests {
|
|||||||
// polling processes listeners in reverse order
|
// polling processes listeners in reverse order
|
||||||
// Only the last listener ever gets processed
|
// Only the last listener ever gets processed
|
||||||
for _n in 0..10 {
|
for _n in 0..10 {
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(ListenersEvent::Incoming{listen_addr, ..})) => {
|
assert_matches!(ls.poll(), Async::Ready(ListenersEvent::Incoming{listen_addr, ..}) => {
|
||||||
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.3/tcp/1233")
|
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.3/tcp/1233")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
// Make last listener NotReady so now only the third listener is processed
|
// Make last listener NotReady so now only the third listener is processed
|
||||||
set_listener_state(&mut ls, 3, ListenerState::Ok(Async::NotReady));
|
set_listener_state(&mut ls, 3, ListenerState::Ok(Async::NotReady));
|
||||||
for _n in 0..10 {
|
for _n in 0..10 {
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(ListenersEvent::Incoming{listen_addr, ..})) => {
|
assert_matches!(ls.poll(), Async::Ready(ListenersEvent::Incoming{listen_addr, ..}) => {
|
||||||
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.2/tcp/1232")
|
assert_eq!(listen_addr.to_string(), "/ip4/127.0.0.2/tcp/1232")
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -483,7 +487,7 @@ mod tests {
|
|||||||
// If the listeners do not yield items continuously (the normal case) we
|
// If the listeners do not yield items continuously (the normal case) we
|
||||||
// process them in the expected, reverse, order.
|
// process them in the expected, reverse, order.
|
||||||
for n in (0..4).rev() {
|
for n in (0..4).rev() {
|
||||||
assert_matches!(ls.poll(), Async::Ready(Some(ListenersEvent::Incoming{listen_addr, ..})) => {
|
assert_matches!(ls.poll(), Async::Ready(ListenersEvent::Incoming{listen_addr, ..}) => {
|
||||||
assert_eq!(listen_addr.to_string(), format!("/ip4/127.0.0.{}/tcp/123{}", n, n));
|
assert_eq!(listen_addr.to_string(), format!("/ip4/127.0.0.{}/tcp/123{}", n, n));
|
||||||
});
|
});
|
||||||
// kick the last listener (current) to NotReady state
|
// kick the last listener (current) to NotReady state
|
||||||
|
@ -18,10 +18,13 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
mod handled_node_tasks;
|
|
||||||
|
|
||||||
pub mod collection;
|
pub mod collection;
|
||||||
pub mod handled_node;
|
pub mod handled_node;
|
||||||
|
pub mod handled_node_tasks;
|
||||||
pub mod listeners;
|
pub mod listeners;
|
||||||
pub mod node;
|
pub mod node;
|
||||||
pub mod swarm;
|
pub mod raw_swarm;
|
||||||
|
|
||||||
|
pub use self::node::Substream;
|
||||||
|
pub use self::handled_node::{NodeHandlerEvent, NodeHandlerEndpoint};
|
||||||
|
pub use self::raw_swarm::{ConnectedPoint, Peer, RawSwarm, RawSwarmEvent};
|
||||||
|
@ -24,16 +24,12 @@ use smallvec::SmallVec;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use Multiaddr;
|
|
||||||
|
|
||||||
// Implementor notes
|
// Implementor notes
|
||||||
// =================
|
// =================
|
||||||
//
|
//
|
||||||
// In order to minimize the risk of bugs in higher-level code, we want to avoid as much as
|
// In order to minimize the risk of bugs in higher-level code, we want to avoid as much as
|
||||||
// possible having a racy API. The behaviour of methods should be well-defined and predictable.
|
// possible having a racy API. The behaviour of methods should be well-defined and predictable.
|
||||||
// As an example, calling the `multiaddr()` method should return `Some` only after a
|
|
||||||
// `MultiaddrResolved` event has been emitted and never before, even if we technically already
|
|
||||||
// know the address.
|
|
||||||
//
|
//
|
||||||
// In order to respect this coding practice, we should theoretically provide events such as "data
|
// In order to respect this coding practice, we should theoretically provide events such as "data
|
||||||
// incoming on a substream", or "a substream is ready to be written". This would however make the
|
// incoming on a substream", or "a substream is ready to be written". This would however make the
|
||||||
@ -53,7 +49,7 @@ use Multiaddr;
|
|||||||
///
|
///
|
||||||
/// The stream will close once both the inbound and outbound channels are closed, and no more
|
/// The stream will close once both the inbound and outbound channels are closed, and no more
|
||||||
/// outbound substream attempt is pending.
|
/// outbound substream attempt is pending.
|
||||||
pub struct NodeStream<TMuxer, TAddrFut, TUserData>
|
pub struct NodeStream<TMuxer, TUserData>
|
||||||
where
|
where
|
||||||
TMuxer: muxing::StreamMuxer,
|
TMuxer: muxing::StreamMuxer,
|
||||||
{
|
{
|
||||||
@ -63,23 +59,10 @@ where
|
|||||||
inbound_state: StreamState,
|
inbound_state: StreamState,
|
||||||
/// Tracks the state of the muxers outbound direction.
|
/// Tracks the state of the muxers outbound direction.
|
||||||
outbound_state: StreamState,
|
outbound_state: StreamState,
|
||||||
/// Address of the node ; can be empty if the address hasn't been resolved yet.
|
|
||||||
address: Addr<TAddrFut>,
|
|
||||||
/// List of substreams we are currently opening.
|
/// List of substreams we are currently opening.
|
||||||
outbound_substreams: SmallVec<[(TUserData, TMuxer::OutboundSubstream); 8]>,
|
outbound_substreams: SmallVec<[(TUserData, TMuxer::OutboundSubstream); 8]>,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Address of the node.
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
enum Addr<TAddrFut> {
|
|
||||||
/// Future that will resolve the address.
|
|
||||||
Future(TAddrFut),
|
|
||||||
/// The address is now known.
|
|
||||||
Resolved(Multiaddr),
|
|
||||||
/// An error happened while resolving the future.
|
|
||||||
Errored,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A successfully opened substream.
|
/// A successfully opened substream.
|
||||||
pub type Substream<TMuxer> = muxing::SubstreamRef<Arc<TMuxer>>;
|
pub type Substream<TMuxer> = muxing::SubstreamRef<Arc<TMuxer>>;
|
||||||
|
|
||||||
@ -102,12 +85,6 @@ pub enum NodeEvent<TMuxer, TUserData>
|
|||||||
where
|
where
|
||||||
TMuxer: muxing::StreamMuxer,
|
TMuxer: muxing::StreamMuxer,
|
||||||
{
|
{
|
||||||
/// The multiaddress future of the node has been resolved.
|
|
||||||
///
|
|
||||||
/// If this succeeded, after this event has been emitted calling `multiaddr()` will return
|
|
||||||
/// `Some`.
|
|
||||||
Multiaddr(Result<Multiaddr, IoError>),
|
|
||||||
|
|
||||||
/// A new inbound substream arrived.
|
/// A new inbound substream arrived.
|
||||||
InboundSubstream {
|
InboundSubstream {
|
||||||
/// The newly-opened substream.
|
/// The newly-opened substream.
|
||||||
@ -137,35 +114,21 @@ where
|
|||||||
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub struct OutboundSubstreamId(usize);
|
pub struct OutboundSubstreamId(usize);
|
||||||
|
|
||||||
impl<TMuxer, TAddrFut, TUserData> NodeStream<TMuxer, TAddrFut, TUserData>
|
impl<TMuxer, TUserData> NodeStream<TMuxer, TUserData>
|
||||||
where
|
where
|
||||||
TMuxer: muxing::StreamMuxer,
|
TMuxer: muxing::StreamMuxer,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
{
|
{
|
||||||
/// Creates a new node events stream.
|
/// Creates a new node events stream.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new(muxer: TMuxer, multiaddr_future: TAddrFut) -> Self {
|
pub fn new(muxer: TMuxer) -> Self {
|
||||||
NodeStream {
|
NodeStream {
|
||||||
muxer: Arc::new(muxer),
|
muxer: Arc::new(muxer),
|
||||||
inbound_state: StreamState::Open,
|
inbound_state: StreamState::Open,
|
||||||
outbound_state: StreamState::Open,
|
outbound_state: StreamState::Open,
|
||||||
address: Addr::Future(multiaddr_future),
|
|
||||||
outbound_substreams: SmallVec::new(),
|
outbound_substreams: SmallVec::new(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the multiaddress of the node, if already known.
|
|
||||||
///
|
|
||||||
/// This method will always return `None` before a successful `Multiaddr` event has been
|
|
||||||
/// returned by `poll()`, and will always return `Some` afterwards.
|
|
||||||
#[inline]
|
|
||||||
pub fn multiaddr(&self) -> Option<&Multiaddr> {
|
|
||||||
match self.address {
|
|
||||||
Addr::Resolved(ref addr) => Some(addr),
|
|
||||||
Addr::Future(_) | Addr::Errored => None,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Starts the process of opening a new outbound substream.
|
/// Starts the process of opening a new outbound substream.
|
||||||
///
|
///
|
||||||
/// Returns an error if the outbound side of the muxer is closed.
|
/// Returns an error if the outbound side of the muxer is closed.
|
||||||
@ -286,10 +249,9 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TMuxer, TAddrFut, TUserData> Stream for NodeStream<TMuxer, TAddrFut, TUserData>
|
impl<TMuxer, TUserData> Stream for NodeStream<TMuxer, TUserData>
|
||||||
where
|
where
|
||||||
TMuxer: muxing::StreamMuxer,
|
TMuxer: muxing::StreamMuxer,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
{
|
{
|
||||||
type Item = NodeEvent<TMuxer, TUserData>;
|
type Item = NodeEvent<TMuxer, TUserData>;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
@ -345,26 +307,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check whether the multiaddress is resolved.
|
|
||||||
{
|
|
||||||
let poll = match self.address {
|
|
||||||
Addr::Future(ref mut fut) => Some(fut.poll()),
|
|
||||||
Addr::Resolved(_) | Addr::Errored => None,
|
|
||||||
};
|
|
||||||
|
|
||||||
match poll {
|
|
||||||
Some(Ok(Async::NotReady)) | None => {}
|
|
||||||
Some(Ok(Async::Ready(addr))) => {
|
|
||||||
self.address = Addr::Resolved(addr.clone());
|
|
||||||
return Ok(Async::Ready(Some(NodeEvent::Multiaddr(Ok(addr)))));
|
|
||||||
}
|
|
||||||
Some(Err(err)) => {
|
|
||||||
self.address = Addr::Errored;
|
|
||||||
return Ok(Async::Ready(Some(NodeEvent::Multiaddr(Err(err)))));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Closing the node if there's no way we can do anything more.
|
// Closing the node if there's no way we can do anything more.
|
||||||
if self.inbound_state == StreamState::Closed
|
if self.inbound_state == StreamState::Closed
|
||||||
&& self.outbound_state == StreamState::Closed
|
&& self.outbound_state == StreamState::Closed
|
||||||
@ -378,14 +320,12 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TMuxer, TAddrFut, TUserData> fmt::Debug for NodeStream<TMuxer, TAddrFut, TUserData>
|
impl<TMuxer, TUserData> fmt::Debug for NodeStream<TMuxer, TUserData>
|
||||||
where
|
where
|
||||||
TMuxer: muxing::StreamMuxer,
|
TMuxer: muxing::StreamMuxer,
|
||||||
TAddrFut: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
{
|
{
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
|
||||||
f.debug_struct("NodeStream")
|
f.debug_struct("NodeStream")
|
||||||
.field("address", &self.multiaddr())
|
|
||||||
.field("inbound_state", &self.inbound_state)
|
.field("inbound_state", &self.inbound_state)
|
||||||
.field("outbound_state", &self.outbound_state)
|
.field("outbound_state", &self.outbound_state)
|
||||||
.field("outbound_substreams", &self.outbound_substreams.len())
|
.field("outbound_substreams", &self.outbound_substreams.len())
|
||||||
@ -393,7 +333,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TMuxer, TAddrFut, TUserData> Drop for NodeStream<TMuxer, TAddrFut, TUserData>
|
impl<TMuxer, TUserData> Drop for NodeStream<TMuxer, TUserData>
|
||||||
where
|
where
|
||||||
TMuxer: muxing::StreamMuxer,
|
TMuxer: muxing::StreamMuxer,
|
||||||
{
|
{
|
||||||
@ -436,40 +376,22 @@ where TTrans: Transport,
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod node_stream {
|
mod node_stream {
|
||||||
use multiaddr::Multiaddr;
|
|
||||||
use super::NodeStream;
|
use super::NodeStream;
|
||||||
use futures::{future::self, prelude::*, Future};
|
use futures::prelude::*;
|
||||||
use tokio_mock_task::MockTask;
|
use tokio_mock_task::MockTask;
|
||||||
use super::NodeEvent;
|
use super::NodeEvent;
|
||||||
use tests::dummy_muxer::{DummyMuxer, DummyConnectionState};
|
use tests::dummy_muxer::{DummyMuxer, DummyConnectionState};
|
||||||
use std::io::Error as IoError;
|
|
||||||
|
|
||||||
|
fn build_node_stream() -> NodeStream<DummyMuxer, Vec<u8>> {
|
||||||
fn build_node_stream() -> NodeStream<DummyMuxer, impl Future<Item=Multiaddr, Error=IoError>, Vec<u8>> {
|
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad maddr"));
|
|
||||||
let muxer = DummyMuxer::new();
|
let muxer = DummyMuxer::new();
|
||||||
NodeStream::<_, _, Vec<u8>>::new(muxer, addr)
|
NodeStream::<_, Vec<u8>>::new(muxer)
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn multiaddr_is_available_once_polled() {
|
|
||||||
let mut node_stream = build_node_stream();
|
|
||||||
assert!(node_stream.multiaddr().is_none());
|
|
||||||
match node_stream.poll() {
|
|
||||||
Ok(Async::Ready(Some(NodeEvent::Multiaddr(Ok(addr))))) => {
|
|
||||||
assert_eq!(addr.to_string(), "/ip4/127.0.0.1/tcp/1234")
|
|
||||||
}
|
|
||||||
_ => panic!("unexpected poll return value" )
|
|
||||||
}
|
|
||||||
assert!(node_stream.multiaddr().is_some());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn can_open_outbound_substreams_until_an_outbound_channel_is_closed() {
|
fn can_open_outbound_substreams_until_an_outbound_channel_is_closed() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad maddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
|
|
||||||
// open first substream works
|
// open first substream works
|
||||||
assert!(ns.open_substream(vec![1,2,3]).is_ok());
|
assert!(ns.open_substream(vec![1,2,3]).is_ok());
|
||||||
@ -498,10 +420,9 @@ mod node_stream {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn query_inbound_state() {
|
fn query_inbound_state() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad maddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
|
|
||||||
assert_matches!(ns.poll(), Ok(Async::Ready(Some(node_event))) => {
|
assert_matches!(ns.poll(), Ok(Async::Ready(Some(node_event))) => {
|
||||||
assert_matches!(node_event, NodeEvent::InboundClosed)
|
assert_matches!(node_event, NodeEvent::InboundClosed)
|
||||||
@ -512,10 +433,9 @@ mod node_stream {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn query_outbound_state() {
|
fn query_outbound_state() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad multiaddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
|
|
||||||
assert!(ns.is_outbound_open());
|
assert!(ns.is_outbound_open());
|
||||||
|
|
||||||
@ -548,13 +468,12 @@ mod node_stream {
|
|||||||
let mut task = MockTask::new();
|
let mut task = MockTask::new();
|
||||||
task.enter(|| {
|
task.enter(|| {
|
||||||
// ensure the address never resolves
|
// ensure the address never resolves
|
||||||
let addr = future::empty();
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
// ensure muxer.poll_inbound() returns Async::NotReady
|
// ensure muxer.poll_inbound() returns Async::NotReady
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Pending);
|
muxer.set_inbound_connection_state(DummyConnectionState::Pending);
|
||||||
// ensure muxer.poll_outbound() returns Async::NotReady
|
// ensure muxer.poll_outbound() returns Async::NotReady
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Pending);
|
muxer.set_outbound_connection_state(DummyConnectionState::Pending);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
|
|
||||||
assert_matches!(ns.poll(), Ok(Async::NotReady));
|
assert_matches!(ns.poll(), Ok(Async::NotReady));
|
||||||
});
|
});
|
||||||
@ -562,13 +481,12 @@ mod node_stream {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn poll_closes_the_node_stream_when_no_more_work_can_be_done() {
|
fn poll_closes_the_node_stream_when_no_more_work_can_be_done() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad multiaddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
||||||
// ensure muxer.poll_outbound() returns Async::Ready(None)
|
// ensure muxer.poll_outbound() returns Async::Ready(None)
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
ns.open_substream(vec![]).unwrap();
|
ns.open_substream(vec![]).unwrap();
|
||||||
ns.poll().unwrap(); // poll_inbound()
|
ns.poll().unwrap(); // poll_inbound()
|
||||||
ns.poll().unwrap(); // poll_outbound()
|
ns.poll().unwrap(); // poll_outbound()
|
||||||
@ -577,32 +495,14 @@ mod node_stream {
|
|||||||
assert_matches!(ns.poll(), Ok(Async::Ready(None)));
|
assert_matches!(ns.poll(), Ok(Async::Ready(None)));
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
|
||||||
fn poll_resolves_the_address() {
|
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad multiaddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
|
||||||
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
|
||||||
// ensure muxer.poll_outbound() returns Async::Ready(None)
|
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Closed);
|
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
|
||||||
ns.open_substream(vec![]).unwrap();
|
|
||||||
ns.poll().unwrap(); // poll_inbound()
|
|
||||||
ns.poll().unwrap(); // poll_outbound()
|
|
||||||
assert_matches!(ns.poll(), Ok(Async::Ready(Some(node_event))) => {
|
|
||||||
assert_matches!(node_event, NodeEvent::Multiaddr(Ok(_)))
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn poll_sets_up_substreams_yielding_them_in_reverse_order() {
|
fn poll_sets_up_substreams_yielding_them_in_reverse_order() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad multiaddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
||||||
// ensure muxer.poll_outbound() returns Async::Ready(Some(substream))
|
// ensure muxer.poll_outbound() returns Async::Ready(Some(substream))
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Opened);
|
muxer.set_outbound_connection_state(DummyConnectionState::Opened);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
ns.open_substream(vec![1]).unwrap();
|
ns.open_substream(vec![1]).unwrap();
|
||||||
ns.open_substream(vec![2]).unwrap();
|
ns.open_substream(vec![2]).unwrap();
|
||||||
ns.poll().unwrap(); // poll_inbound()
|
ns.poll().unwrap(); // poll_inbound()
|
||||||
@ -623,13 +523,12 @@ mod node_stream {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn poll_keeps_outbound_substreams_when_the_outgoing_connection_is_not_ready() {
|
fn poll_keeps_outbound_substreams_when_the_outgoing_connection_is_not_ready() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad multiaddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
// ensure muxer.poll_inbound() returns Async::Ready(None)
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
muxer.set_inbound_connection_state(DummyConnectionState::Closed);
|
||||||
// ensure muxer.poll_outbound() returns Async::NotReady
|
// ensure muxer.poll_outbound() returns Async::NotReady
|
||||||
muxer.set_outbound_connection_state(DummyConnectionState::Pending);
|
muxer.set_outbound_connection_state(DummyConnectionState::Pending);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
ns.open_substream(vec![1]).unwrap();
|
ns.open_substream(vec![1]).unwrap();
|
||||||
ns.poll().unwrap(); // poll past inbound
|
ns.poll().unwrap(); // poll past inbound
|
||||||
ns.poll().unwrap(); // poll outbound
|
ns.poll().unwrap(); // poll outbound
|
||||||
@ -639,11 +538,10 @@ mod node_stream {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn poll_returns_incoming_substream() {
|
fn poll_returns_incoming_substream() {
|
||||||
let addr = future::ok("/ip4/127.0.0.1/tcp/1234".parse::<Multiaddr>().expect("bad multiaddr"));
|
|
||||||
let mut muxer = DummyMuxer::new();
|
let mut muxer = DummyMuxer::new();
|
||||||
// ensure muxer.poll_inbound() returns Async::Ready(Some(subs))
|
// ensure muxer.poll_inbound() returns Async::Ready(Some(subs))
|
||||||
muxer.set_inbound_connection_state(DummyConnectionState::Opened);
|
muxer.set_inbound_connection_state(DummyConnectionState::Opened);
|
||||||
let mut ns = NodeStream::<_, _, Vec<u8>>::new(muxer, addr);
|
let mut ns = NodeStream::<_, Vec<u8>>::new(muxer);
|
||||||
assert_matches!(ns.poll(), Ok(Async::Ready(Some(node_event))) => {
|
assert_matches!(ns.poll(), Ok(Async::Ready(Some(node_event))) => {
|
||||||
assert_matches!(node_event, NodeEvent::InboundSubstream{ substream: _ });
|
assert_matches!(node_event, NodeEvent::InboundSubstream{ substream: _ });
|
||||||
});
|
});
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -47,10 +47,9 @@ impl DummyTransport {
|
|||||||
}
|
}
|
||||||
impl Transport for DummyTransport {
|
impl Transport for DummyTransport {
|
||||||
type Output = usize;
|
type Output = usize;
|
||||||
type Listener = Box<Stream<Item=Self::ListenerUpgrade, Error=io::Error> + Send>;
|
type Listener = Box<Stream<Item=(Self::ListenerUpgrade, Multiaddr), Error=io::Error> + Send>;
|
||||||
type ListenerUpgrade = FutureResult<(Self::Output, Self::MultiaddrFuture), io::Error>;
|
type ListenerUpgrade = FutureResult<Self::Output, io::Error>;
|
||||||
type MultiaddrFuture = FutureResult<Multiaddr, io::Error>;
|
type Dial = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type Dial = Box<Future<Item=(Self::Output, Self::MultiaddrFuture), Error=io::Error> + Send>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)>
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)>
|
||||||
where
|
where
|
||||||
@ -59,7 +58,7 @@ impl Transport for DummyTransport {
|
|||||||
let addr2 = addr.clone();
|
let addr2 = addr.clone();
|
||||||
match self.listener_state {
|
match self.listener_state {
|
||||||
ListenerState::Ok(async) => {
|
ListenerState::Ok(async) => {
|
||||||
let tupelize = move |stream| future::ok( (stream, future::ok(addr.clone())) );
|
let tupelize = move |stream| (future::ok(stream), addr.clone());
|
||||||
Ok(match async {
|
Ok(match async {
|
||||||
Async::NotReady => {
|
Async::NotReady => {
|
||||||
let stream = stream::poll_fn(|| Ok(Async::NotReady)).map(tupelize);
|
let stream = stream::poll_fn(|| Ok(Async::NotReady)).map(tupelize);
|
||||||
|
@ -20,9 +20,9 @@
|
|||||||
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
|
use nodes::raw_swarm::ConnectedPoint;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
use upgrade::Endpoint;
|
|
||||||
|
|
||||||
/// See the `Transport::and_then` method.
|
/// See the `Transport::and_then` method.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -37,21 +37,19 @@ pub struct AndThen<T, C> {
|
|||||||
upgrade: C,
|
upgrade: C,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, C, F, O, Maf> Transport for AndThen<T, C>
|
impl<T, C, F, O> Transport for AndThen<T, C>
|
||||||
where
|
where
|
||||||
T: Transport + 'static,
|
T: Transport + 'static,
|
||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
C: FnOnce(T::Output, Endpoint, T::MultiaddrFuture) -> F + Clone + Send + 'static,
|
C: FnOnce(T::Output, ConnectedPoint) -> F + Clone + Send + 'static,
|
||||||
F: Future<Item = (O, Maf), Error = IoError> + Send + 'static,
|
F: Future<Item = O, Error = IoError> + Send + 'static,
|
||||||
Maf: Future<Item = Multiaddr, Error = IoError> + 'static,
|
|
||||||
{
|
{
|
||||||
type Output = O;
|
type Output = O;
|
||||||
type MultiaddrFuture = Maf;
|
type Listener = Box<Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = IoError> + Send>;
|
||||||
type Listener = Box<Stream<Item = Self::ListenerUpgrade, Error = IoError> + Send>;
|
type ListenerUpgrade = Box<Future<Item = O, Error = IoError> + Send>;
|
||||||
type ListenerUpgrade = Box<Future<Item = (O, Self::MultiaddrFuture), Error = IoError> + Send>;
|
type Dial = Box<Future<Item = O, Error = IoError> + Send>;
|
||||||
type Dial = Box<Future<Item = (O, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
@ -69,17 +67,24 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let listen_addr = new_addr.clone();
|
||||||
|
|
||||||
// Try to negotiate the protocol.
|
// Try to negotiate the protocol.
|
||||||
// Note that failing to negotiate a protocol will never produce a future with an error.
|
// Note that failing to negotiate a protocol will never produce a future with an error.
|
||||||
// Instead the `stream` will produce `Ok(Err(...))`.
|
// Instead the `stream` will produce `Ok(Err(...))`.
|
||||||
// `stream` can only produce an `Err` if `listening_stream` produces an `Err`.
|
// `stream` can only produce an `Err` if `listening_stream` produces an `Err`.
|
||||||
let stream = listening_stream.map(move |connection| {
|
let stream = listening_stream.map(move |(connection, client_addr)| {
|
||||||
let upgrade = upgrade.clone();
|
let upgrade = upgrade.clone();
|
||||||
let future = connection.and_then(move |(stream, client_addr)| {
|
let connected_point = ConnectedPoint::Listener {
|
||||||
upgrade(stream, Endpoint::Listener, client_addr)
|
listen_addr: listen_addr.clone(),
|
||||||
|
send_back_addr: client_addr.clone(),
|
||||||
|
};
|
||||||
|
|
||||||
|
let future = connection.and_then(move |stream| {
|
||||||
|
upgrade(stream, connected_point)
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(future) as Box<_>
|
(Box::new(future) as Box<_>, client_addr)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok((Box::new(stream), new_addr))
|
Ok((Box::new(stream), new_addr))
|
||||||
@ -101,10 +106,14 @@ where
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let connected_point = ConnectedPoint::Dialer {
|
||||||
|
address: addr,
|
||||||
|
};
|
||||||
|
|
||||||
let future = dialed_fut
|
let future = dialed_fut
|
||||||
// Try to negotiate the protocol.
|
// Try to negotiate the protocol.
|
||||||
.and_then(move |(connection, client_addr)| {
|
.and_then(move |connection| {
|
||||||
upgrade(connection, Endpoint::Dialer, client_addr)
|
upgrade(connection, connected_point)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Box::new(future))
|
Ok(Box::new(future))
|
||||||
@ -115,36 +124,3 @@ where
|
|||||||
self.transport.nat_traversal(server, observed)
|
self.transport.nat_traversal(server, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, C, F, O, Maf> MuxedTransport for AndThen<T, C>
|
|
||||||
where
|
|
||||||
T: MuxedTransport + 'static,
|
|
||||||
T::Dial: Send,
|
|
||||||
T::Listener: Send,
|
|
||||||
T::ListenerUpgrade: Send,
|
|
||||||
T::Incoming: Send,
|
|
||||||
T::IncomingUpgrade: Send,
|
|
||||||
C: FnOnce(T::Output, Endpoint, T::MultiaddrFuture) -> F + Clone + Send + 'static,
|
|
||||||
F: Future<Item = (O, Maf), Error = IoError> + Send + 'static,
|
|
||||||
Maf: Future<Item = Multiaddr, Error = IoError> + 'static,
|
|
||||||
{
|
|
||||||
type Incoming = Box<Future<Item = Self::IncomingUpgrade, Error = IoError> + Send>;
|
|
||||||
type IncomingUpgrade = Box<Future<Item = (O, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
let upgrade = self.upgrade;
|
|
||||||
|
|
||||||
let future = self.transport.next_incoming().map(|future| {
|
|
||||||
// Try to negotiate the protocol.
|
|
||||||
let future = future.and_then(move |(connection, client_addr)| {
|
|
||||||
let upgrade = upgrade.clone();
|
|
||||||
upgrade(connection, Endpoint::Listener, client_addr)
|
|
||||||
});
|
|
||||||
|
|
||||||
Box::new(future) as Box<Future<Item = _, Error = _> + Send>
|
|
||||||
});
|
|
||||||
|
|
||||||
Box::new(future) as Box<_>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -23,7 +23,7 @@ use multiaddr::Multiaddr;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
|
|
||||||
/// See the `Transport::boxed` method.
|
/// See the `Transport::boxed` method.
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -33,35 +33,17 @@ where
|
|||||||
T::Dial: Send + 'static,
|
T::Dial: Send + 'static,
|
||||||
T::Listener: Send + 'static,
|
T::Listener: Send + 'static,
|
||||||
T::ListenerUpgrade: Send + 'static,
|
T::ListenerUpgrade: Send + 'static,
|
||||||
T::MultiaddrFuture: Send + 'static,
|
|
||||||
{
|
{
|
||||||
Boxed {
|
Boxed {
|
||||||
inner: Arc::new(transport) as Arc<_>,
|
inner: Arc::new(transport) as Arc<_>,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// See the `Transport::boxed_muxed` method.
|
|
||||||
#[inline]
|
|
||||||
pub fn boxed_muxed<T>(transport: T) -> BoxedMuxed<T::Output>
|
|
||||||
where
|
|
||||||
T: MuxedTransport + Clone + Send + Sync + 'static,
|
|
||||||
T::Dial: Send + 'static,
|
|
||||||
T::Listener: Send + 'static,
|
|
||||||
T::ListenerUpgrade: Send + 'static,
|
|
||||||
T::MultiaddrFuture: Send + 'static,
|
|
||||||
T::Incoming: Send + 'static,
|
|
||||||
T::IncomingUpgrade: Send + 'static,
|
|
||||||
{
|
|
||||||
BoxedMuxed {
|
|
||||||
inner: Arc::new(transport) as Arc<_>,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
pub type MultiaddrFuture = Box<Future<Item = Multiaddr, Error = IoError> + Send>;
|
pub type Dial<O> = Box<Future<Item = O, Error = IoError> + Send>;
|
||||||
pub type Dial<O> = Box<Future<Item = (O, MultiaddrFuture), Error = IoError> + Send>;
|
pub type Listener<O> = Box<Stream<Item = (ListenerUpgrade<O>, Multiaddr), Error = IoError> + Send>;
|
||||||
pub type Listener<O> = Box<Stream<Item = ListenerUpgrade<O>, Error = IoError> + Send>;
|
pub type ListenerUpgrade<O> = Box<Future<Item = O, Error = IoError> + Send>;
|
||||||
pub type ListenerUpgrade<O> = Box<Future<Item = (O, MultiaddrFuture), Error = IoError> + Send>;
|
pub type Incoming<O> = Box<Future<Item = (IncomingUpgrade<O>, Multiaddr), Error = IoError> + Send>;
|
||||||
pub type Incoming<O> = Box<Future<Item = IncomingUpgrade<O>, Error = IoError> + Send>;
|
pub type IncomingUpgrade<O> = Box<Future<Item = O, Error = IoError> + Send>;
|
||||||
pub type IncomingUpgrade<O> = Box<Future<Item = (O, MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
trait Abstract<O> {
|
trait Abstract<O> {
|
||||||
fn listen_on(&self, addr: Multiaddr) -> Result<(Listener<O>, Multiaddr), Multiaddr>;
|
fn listen_on(&self, addr: Multiaddr) -> Result<(Listener<O>, Multiaddr), Multiaddr>;
|
||||||
@ -75,22 +57,19 @@ where
|
|||||||
T::Dial: Send + 'static,
|
T::Dial: Send + 'static,
|
||||||
T::Listener: Send + 'static,
|
T::Listener: Send + 'static,
|
||||||
T::ListenerUpgrade: Send + 'static,
|
T::ListenerUpgrade: Send + 'static,
|
||||||
T::MultiaddrFuture: Send + 'static,
|
|
||||||
{
|
{
|
||||||
fn listen_on(&self, addr: Multiaddr) -> Result<(Listener<O>, Multiaddr), Multiaddr> {
|
fn listen_on(&self, addr: Multiaddr) -> Result<(Listener<O>, Multiaddr), Multiaddr> {
|
||||||
let (listener, new_addr) =
|
let (listener, new_addr) =
|
||||||
Transport::listen_on(self.clone(), addr).map_err(|(_, addr)| addr)?;
|
Transport::listen_on(self.clone(), addr).map_err(|(_, addr)| addr)?;
|
||||||
let fut = listener.map(|upgrade| {
|
let fut = listener.map(|(upgrade, addr)| {
|
||||||
let fut = upgrade.map(|(out, addr)| (out, Box::new(addr) as MultiaddrFuture));
|
(Box::new(upgrade) as ListenerUpgrade<O>, addr)
|
||||||
Box::new(fut) as ListenerUpgrade<O>
|
|
||||||
});
|
});
|
||||||
Ok((Box::new(fut) as Box<_>, new_addr))
|
Ok((Box::new(fut) as Box<_>, new_addr))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn dial(&self, addr: Multiaddr) -> Result<Dial<O>, Multiaddr> {
|
fn dial(&self, addr: Multiaddr) -> Result<Dial<O>, Multiaddr> {
|
||||||
let fut = Transport::dial(self.clone(), addr)
|
let fut = Transport::dial(self.clone(), addr)
|
||||||
.map_err(|(_, addr)| addr)?
|
.map_err(|(_, addr)| addr)?;
|
||||||
.map(|(out, addr)| (out, Box::new(addr) as MultiaddrFuture));
|
|
||||||
Ok(Box::new(fut) as Box<_>)
|
Ok(Box::new(fut) as Box<_>)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,29 +79,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trait AbstractMuxed<O>: Abstract<O> {
|
|
||||||
fn next_incoming(&self) -> Incoming<O>;
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, O> AbstractMuxed<O> for T
|
|
||||||
where
|
|
||||||
T: MuxedTransport<Output = O> + Clone + 'static,
|
|
||||||
T::Dial: Send + 'static,
|
|
||||||
T::Listener: Send + 'static,
|
|
||||||
T::ListenerUpgrade: Send + 'static,
|
|
||||||
T::MultiaddrFuture: Send + 'static,
|
|
||||||
T::Incoming: Send + 'static,
|
|
||||||
T::IncomingUpgrade: Send + 'static,
|
|
||||||
{
|
|
||||||
fn next_incoming(&self) -> Incoming<O> {
|
|
||||||
let fut = MuxedTransport::next_incoming(self.clone()).map(|upgrade| {
|
|
||||||
let fut = upgrade.map(|(out, addr)| (out, Box::new(addr) as MultiaddrFuture));
|
|
||||||
Box::new(fut) as IncomingUpgrade<O>
|
|
||||||
});
|
|
||||||
Box::new(fut) as Box<_>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// See the `Transport::boxed` method.
|
/// See the `Transport::boxed` method.
|
||||||
pub struct Boxed<O> {
|
pub struct Boxed<O> {
|
||||||
inner: Arc<Abstract<O> + Send + Sync>,
|
inner: Arc<Abstract<O> + Send + Sync>,
|
||||||
@ -145,7 +101,6 @@ impl<O> Clone for Boxed<O> {
|
|||||||
|
|
||||||
impl<O> Transport for Boxed<O> {
|
impl<O> Transport for Boxed<O> {
|
||||||
type Output = O;
|
type Output = O;
|
||||||
type MultiaddrFuture = MultiaddrFuture;
|
|
||||||
type Listener = Listener<O>;
|
type Listener = Listener<O>;
|
||||||
type ListenerUpgrade = ListenerUpgrade<O>;
|
type ListenerUpgrade = ListenerUpgrade<O>;
|
||||||
type Dial = Dial<O>;
|
type Dial = Dial<O>;
|
||||||
@ -171,62 +126,3 @@ impl<O> Transport for Boxed<O> {
|
|||||||
self.inner.nat_traversal(server, observed)
|
self.inner.nat_traversal(server, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// See the `Transport::boxed_muxed` method.
|
|
||||||
pub struct BoxedMuxed<O> {
|
|
||||||
inner: Arc<AbstractMuxed<O> + Send + Sync>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O> fmt::Debug for BoxedMuxed<O> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
||||||
write!(f, "BoxedMuxedTransport")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O> Clone for BoxedMuxed<O> {
|
|
||||||
#[inline]
|
|
||||||
fn clone(&self) -> Self {
|
|
||||||
BoxedMuxed {
|
|
||||||
inner: self.inner.clone(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O> Transport for BoxedMuxed<O> {
|
|
||||||
type Output = O;
|
|
||||||
type MultiaddrFuture = MultiaddrFuture;
|
|
||||||
type Listener = Listener<O>;
|
|
||||||
type ListenerUpgrade = ListenerUpgrade<O>;
|
|
||||||
type Dial = Dial<O>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
|
||||||
match self.inner.listen_on(addr) {
|
|
||||||
Ok(listen) => Ok(listen),
|
|
||||||
Err(addr) => Err((self, addr)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, (Self, Multiaddr)> {
|
|
||||||
match self.inner.dial(addr) {
|
|
||||||
Ok(dial) => Ok(dial),
|
|
||||||
Err(addr) => Err((self, addr)),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn nat_traversal(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
|
|
||||||
self.inner.nat_traversal(server, observed)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<O> MuxedTransport for BoxedMuxed<O> {
|
|
||||||
type Incoming = Incoming<O>;
|
|
||||||
type IncomingUpgrade = IncomingUpgrade<O>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
self.inner.next_incoming()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use either::{EitherListenStream, EitherListenUpgrade, EitherOutput};
|
use either::{EitherListenStream, EitherOutput, EitherFuture};
|
||||||
use futures::{prelude::*, future};
|
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::io::Error as IoError;
|
use transport::Transport;
|
||||||
use transport::{MuxedTransport, Transport};
|
|
||||||
|
|
||||||
/// Struct returned by `or_transport()`.
|
/// Struct returned by `or_transport()`.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@ -41,10 +39,8 @@ where
|
|||||||
{
|
{
|
||||||
type Output = EitherOutput<A::Output, B::Output>;
|
type Output = EitherOutput<A::Output, B::Output>;
|
||||||
type Listener = EitherListenStream<A::Listener, B::Listener>;
|
type Listener = EitherListenStream<A::Listener, B::Listener>;
|
||||||
type ListenerUpgrade = EitherListenUpgrade<A::ListenerUpgrade, B::ListenerUpgrade>;
|
type ListenerUpgrade = EitherFuture<A::ListenerUpgrade, B::ListenerUpgrade>;
|
||||||
type MultiaddrFuture = future::Either<A::MultiaddrFuture, B::MultiaddrFuture>;
|
type Dial = EitherFuture<A::Dial, B::Dial>;
|
||||||
type Dial =
|
|
||||||
EitherListenUpgrade<<A::Dial as IntoFuture>::Future, <B::Dial as IntoFuture>::Future>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
let (first, addr) = match self.0.listen_on(addr) {
|
let (first, addr) = match self.0.listen_on(addr) {
|
||||||
@ -60,12 +56,12 @@ where
|
|||||||
|
|
||||||
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, (Self, Multiaddr)> {
|
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, (Self, Multiaddr)> {
|
||||||
let (first, addr) = match self.0.dial(addr) {
|
let (first, addr) = match self.0.dial(addr) {
|
||||||
Ok(connec) => return Ok(EitherListenUpgrade::First(connec)),
|
Ok(connec) => return Ok(EitherFuture::First(connec)),
|
||||||
Err(err) => err,
|
Err(err) => err,
|
||||||
};
|
};
|
||||||
|
|
||||||
match self.1.dial(addr) {
|
match self.1.dial(addr) {
|
||||||
Ok(connec) => Ok(EitherListenUpgrade::Second(connec)),
|
Ok(connec) => Ok(EitherFuture::Second(connec)),
|
||||||
Err((second, addr)) => Err((OrTransport(first, second), addr)),
|
Err((second, addr)) => Err((OrTransport(first, second), addr)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,33 +76,3 @@ where
|
|||||||
self.1.nat_traversal(server, observed)
|
self.1.nat_traversal(server, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<A, B> MuxedTransport for OrTransport<A, B>
|
|
||||||
where
|
|
||||||
A: MuxedTransport,
|
|
||||||
B: MuxedTransport,
|
|
||||||
A::Incoming: Send + 'static, // TODO: meh :-/
|
|
||||||
B::Incoming: Send + 'static, // TODO: meh :-/
|
|
||||||
A::IncomingUpgrade: Send + 'static, // TODO: meh :-/
|
|
||||||
B::IncomingUpgrade: Send + 'static, // TODO: meh :-/
|
|
||||||
A::Output: 'static, // TODO: meh :-/
|
|
||||||
B::Output: 'static, // TODO: meh :-/
|
|
||||||
{
|
|
||||||
type Incoming = Box<Future<Item = Self::IncomingUpgrade, Error = IoError> + Send>;
|
|
||||||
type IncomingUpgrade =
|
|
||||||
Box<Future<Item = (EitherOutput<A::Output, B::Output>, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
let first = self.0.next_incoming().map(|out| {
|
|
||||||
let fut = out.map(move |(v, addr)| (EitherOutput::First(v), future::Either::A(addr)));
|
|
||||||
Box::new(fut) as Box<Future<Item = _, Error = _> + Send>
|
|
||||||
});
|
|
||||||
let second = self.1.next_incoming().map(|out| {
|
|
||||||
let fut = out.map(move |(v, addr)| (EitherOutput::Second(v), future::Either::B(addr)));
|
|
||||||
Box::new(fut) as Box<Future<Item = _, Error = _> + Send>
|
|
||||||
});
|
|
||||||
let future = first.select(second).map(|(i, _)| i).map_err(|(e, _)| e);
|
|
||||||
Box::new(future) as Box<_>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -18,11 +18,9 @@
|
|||||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use futures::future;
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::io::{self, Cursor};
|
use std::io::{self, Cursor};
|
||||||
use transport::MuxedTransport;
|
|
||||||
use transport::Transport;
|
use transport::Transport;
|
||||||
|
|
||||||
/// Dummy implementation of `Transport` that just denies every single attempt.
|
/// Dummy implementation of `Transport` that just denies every single attempt.
|
||||||
@ -32,10 +30,9 @@ pub struct DeniedTransport;
|
|||||||
impl Transport for DeniedTransport {
|
impl Transport for DeniedTransport {
|
||||||
// TODO: could use `!` for associated types once stable
|
// TODO: could use `!` for associated types once stable
|
||||||
type Output = Cursor<Vec<u8>>;
|
type Output = Cursor<Vec<u8>>;
|
||||||
type MultiaddrFuture = Box<Future<Item = Multiaddr, Error = io::Error> + Send + Sync>;
|
type Listener = Box<Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = io::Error> + Send + Sync>;
|
||||||
type Listener = Box<Stream<Item = Self::ListenerUpgrade, Error = io::Error> + Send + Sync>;
|
type ListenerUpgrade = Box<Future<Item = Self::Output, Error = io::Error> + Send + Sync>;
|
||||||
type ListenerUpgrade = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = io::Error> + Send + Sync>;
|
type Dial = Box<Future<Item = Self::Output, Error = io::Error> + Send + Sync>;
|
||||||
type Dial = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = io::Error> + Send + Sync>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
@ -52,13 +49,3 @@ impl Transport for DeniedTransport {
|
|||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MuxedTransport for DeniedTransport {
|
|
||||||
type Incoming = future::Empty<Self::IncomingUpgrade, io::Error>;
|
|
||||||
type IncomingUpgrade = future::Empty<(Self::Output, Self::MultiaddrFuture), io::Error>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
future::empty()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
use futures::{future, prelude::*, sync::oneshot};
|
use futures::{future, prelude::*, sync::oneshot};
|
||||||
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
use Multiaddr;
|
use Multiaddr;
|
||||||
|
|
||||||
/// See `Transport::interruptible`.
|
/// See `Transport::interruptible`.
|
||||||
@ -46,7 +46,6 @@ where
|
|||||||
T: Transport,
|
T: Transport,
|
||||||
{
|
{
|
||||||
type Output = T::Output;
|
type Output = T::Output;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
|
||||||
type Listener = T::Listener;
|
type Listener = T::Listener;
|
||||||
type ListenerUpgrade = T::ListenerUpgrade;
|
type ListenerUpgrade = T::ListenerUpgrade;
|
||||||
type Dial = InterruptibleDial<T::Dial>;
|
type Dial = InterruptibleDial<T::Dial>;
|
||||||
@ -78,19 +77,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> MuxedTransport for Interruptible<T>
|
|
||||||
where
|
|
||||||
T: MuxedTransport,
|
|
||||||
{
|
|
||||||
type Incoming = T::Incoming;
|
|
||||||
type IncomingUpgrade = T::IncomingUpgrade;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
self.transport.next_incoming()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Dropping this object interrupts the dialing of the corresponding `Interruptible`.
|
/// Dropping this object interrupts the dialing of the corresponding `Interruptible`.
|
||||||
pub struct Interrupt {
|
pub struct Interrupt {
|
||||||
_tx: oneshot::Sender<()>,
|
_tx: oneshot::Sender<()>,
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
use Endpoint;
|
use Endpoint;
|
||||||
|
|
||||||
/// See `Transport::map`.
|
/// See `Transport::map`.
|
||||||
@ -48,22 +48,21 @@ where
|
|||||||
F: FnOnce(T::Output, Endpoint) -> D + Clone + Send + 'static, // TODO: 'static :-/
|
F: FnOnce(T::Output, Endpoint) -> D + Clone + Send + 'static, // TODO: 'static :-/
|
||||||
{
|
{
|
||||||
type Output = D;
|
type Output = D;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
type Listener = Box<Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = IoError> + Send>;
|
||||||
type Listener = Box<Stream<Item = Self::ListenerUpgrade, Error = IoError> + Send>;
|
type ListenerUpgrade = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
type ListenerUpgrade = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
type Dial = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
type Dial = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
let map = self.map;
|
let map = self.map;
|
||||||
|
|
||||||
match self.transport.listen_on(addr) {
|
match self.transport.listen_on(addr) {
|
||||||
Ok((stream, listen_addr)) => {
|
Ok((stream, listen_addr)) => {
|
||||||
let stream = stream.map(move |future| {
|
let stream = stream.map(move |(future, addr)| {
|
||||||
let map = map.clone();
|
let map = map.clone();
|
||||||
let future = future
|
let future = future
|
||||||
.into_future()
|
.into_future()
|
||||||
.map(move |(output, addr)| (map(output, Endpoint::Listener), addr));
|
.map(move |output| map(output, Endpoint::Listener));
|
||||||
Box::new(future) as Box<_>
|
(Box::new(future) as Box<_>, addr)
|
||||||
});
|
});
|
||||||
Ok((Box::new(stream), listen_addr))
|
Ok((Box::new(stream), listen_addr))
|
||||||
}
|
}
|
||||||
@ -78,7 +77,7 @@ where
|
|||||||
Ok(future) => {
|
Ok(future) => {
|
||||||
let future = future
|
let future = future
|
||||||
.into_future()
|
.into_future()
|
||||||
.map(move |(output, addr)| (map(output, Endpoint::Dialer), addr));
|
.map(move |output| map(output, Endpoint::Dialer));
|
||||||
Ok(Box::new(future))
|
Ok(Box::new(future))
|
||||||
}
|
}
|
||||||
Err((transport, addr)) => Err((Map { transport, map }, addr)),
|
Err((transport, addr)) => Err((Map { transport, map }, addr)),
|
||||||
@ -90,28 +89,3 @@ where
|
|||||||
self.transport.nat_traversal(server, observed)
|
self.transport.nat_traversal(server, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F, D> MuxedTransport for Map<T, F>
|
|
||||||
where
|
|
||||||
T: MuxedTransport + 'static, // TODO: 'static :-/
|
|
||||||
T::Dial: Send,
|
|
||||||
T::Listener: Send,
|
|
||||||
T::ListenerUpgrade: Send,
|
|
||||||
T::Incoming: Send,
|
|
||||||
T::IncomingUpgrade: Send,
|
|
||||||
F: FnOnce(T::Output, Endpoint) -> D + Clone + Send + 'static, // TODO: 'static :-/
|
|
||||||
{
|
|
||||||
type Incoming = Box<Future<Item = Self::IncomingUpgrade, Error = IoError> + Send>;
|
|
||||||
type IncomingUpgrade = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
let map = self.map;
|
|
||||||
let future = self.transport.next_incoming().map(move |upgrade| {
|
|
||||||
let future = upgrade.map(move |(output, addr)| {
|
|
||||||
(map(output, Endpoint::Listener), addr)
|
|
||||||
});
|
|
||||||
Box::new(future) as Box<_>
|
|
||||||
});
|
|
||||||
Box::new(future)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
|
|
||||||
/// See `Transport::map_err`.
|
/// See `Transport::map_err`.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@ -44,7 +44,6 @@ where
|
|||||||
F: FnOnce(IoError) -> IoError + Clone,
|
F: FnOnce(IoError) -> IoError + Clone,
|
||||||
{
|
{
|
||||||
type Output = T::Output;
|
type Output = T::Output;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
|
||||||
type Listener = MapErrListener<T, F>;
|
type Listener = MapErrListener<T, F>;
|
||||||
type ListenerUpgrade = MapErrListenerUpgrade<T, F>;
|
type ListenerUpgrade = MapErrListenerUpgrade<T, F>;
|
||||||
type Dial = MapErrDial<T, F>;
|
type Dial = MapErrDial<T, F>;
|
||||||
@ -76,23 +75,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F> MuxedTransport for MapErr<T, F>
|
|
||||||
where
|
|
||||||
T: MuxedTransport,
|
|
||||||
F: FnOnce(IoError) -> IoError + Clone,
|
|
||||||
{
|
|
||||||
type Incoming = MapErrIncoming<T, F>;
|
|
||||||
type IncomingUpgrade = MapErrIncomingUpgrade<T, F>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
MapErrIncoming {
|
|
||||||
inner: self.transport.next_incoming(),
|
|
||||||
map: Some(self.map),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Listening stream for `MapErr`.
|
/// Listening stream for `MapErr`.
|
||||||
pub struct MapErrListener<T, F>
|
pub struct MapErrListener<T, F>
|
||||||
where T: Transport {
|
where T: Transport {
|
||||||
@ -104,14 +86,14 @@ impl<T, F> Stream for MapErrListener<T, F>
|
|||||||
where T: Transport,
|
where T: Transport,
|
||||||
F: FnOnce(IoError) -> IoError + Clone,
|
F: FnOnce(IoError) -> IoError + Clone,
|
||||||
{
|
{
|
||||||
type Item = MapErrListenerUpgrade<T, F>;
|
type Item = (MapErrListenerUpgrade<T, F>, Multiaddr);
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
match try_ready!(self.inner.poll()) {
|
match try_ready!(self.inner.poll()) {
|
||||||
Some(value) => Ok(Async::Ready(
|
Some((value, addr)) => Ok(Async::Ready(
|
||||||
Some(MapErrListenerUpgrade { inner: value, map: Some(self.map.clone()) }))),
|
Some((MapErrListenerUpgrade { inner: value, map: Some(self.map.clone()) }, addr)))),
|
||||||
None => Ok(Async::Ready(None))
|
None => Ok(Async::Ready(None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +110,7 @@ impl<T, F> Future for MapErrListenerUpgrade<T, F>
|
|||||||
where T: Transport,
|
where T: Transport,
|
||||||
F: FnOnce(IoError) -> IoError,
|
F: FnOnce(IoError) -> IoError,
|
||||||
{
|
{
|
||||||
type Item = (T::Output, T::MultiaddrFuture);
|
type Item = T::Output;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@ -159,72 +141,7 @@ impl<T, F> Future for MapErrDial<T, F>
|
|||||||
where T: Transport,
|
where T: Transport,
|
||||||
F: FnOnce(IoError) -> IoError,
|
F: FnOnce(IoError) -> IoError,
|
||||||
{
|
{
|
||||||
type Item = (T::Output, T::MultiaddrFuture);
|
type Item = T::Output;
|
||||||
type Error = IoError;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
match self.inner.poll() {
|
|
||||||
Ok(Async::Ready(value)) => {
|
|
||||||
Ok(Async::Ready(value))
|
|
||||||
},
|
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
||||||
Err(err) => {
|
|
||||||
let map = self.map.take().expect("poll() called again after error");
|
|
||||||
Err(map(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Incoming future for `MapErr`.
|
|
||||||
pub struct MapErrIncoming<T, F>
|
|
||||||
where T: MuxedTransport
|
|
||||||
{
|
|
||||||
inner: T::Incoming,
|
|
||||||
map: Option<F>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, F> Future for MapErrIncoming<T, F>
|
|
||||||
where T: MuxedTransport,
|
|
||||||
F: FnOnce(IoError) -> IoError,
|
|
||||||
{
|
|
||||||
type Item = MapErrIncomingUpgrade<T, F>;
|
|
||||||
type Error = IoError;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
match self.inner.poll() {
|
|
||||||
Ok(Async::Ready(value)) => {
|
|
||||||
let map = self.map.take().expect("poll() called again after error");
|
|
||||||
let value = MapErrIncomingUpgrade {
|
|
||||||
inner: value,
|
|
||||||
map: Some(map),
|
|
||||||
};
|
|
||||||
Ok(Async::Ready(value))
|
|
||||||
},
|
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
||||||
Err(err) => {
|
|
||||||
let map = self.map.take().expect("poll() called again after error");
|
|
||||||
Err(map(err))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Incoming upgrade future for `MapErr`.
|
|
||||||
pub struct MapErrIncomingUpgrade<T, F>
|
|
||||||
where T: MuxedTransport
|
|
||||||
{
|
|
||||||
inner: T::IncomingUpgrade,
|
|
||||||
map: Option<F>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<T, F> Future for MapErrIncomingUpgrade<T, F>
|
|
||||||
where T: MuxedTransport,
|
|
||||||
F: FnOnce(IoError) -> IoError,
|
|
||||||
{
|
|
||||||
type Item = (T::Output, T::MultiaddrFuture);
|
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -21,7 +21,7 @@
|
|||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
|
|
||||||
/// See `Transport::map_err_dial`.
|
/// See `Transport::map_err_dial`.
|
||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
@ -45,10 +45,9 @@ where
|
|||||||
F: FnOnce(IoError, Multiaddr) -> IoError + Clone + Send + 'static, // TODO: 'static :-/
|
F: FnOnce(IoError, Multiaddr) -> IoError + Clone + Send + 'static, // TODO: 'static :-/
|
||||||
{
|
{
|
||||||
type Output = T::Output;
|
type Output = T::Output;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
|
||||||
type Listener = T::Listener;
|
type Listener = T::Listener;
|
||||||
type ListenerUpgrade = T::ListenerUpgrade;
|
type ListenerUpgrade = T::ListenerUpgrade;
|
||||||
type Dial = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
type Dial = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
match self.transport.listen_on(addr) {
|
match self.transport.listen_on(addr) {
|
||||||
@ -74,18 +73,3 @@ where
|
|||||||
self.transport.nat_traversal(server, observed)
|
self.transport.nat_traversal(server, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, F> MuxedTransport for MapErrDial<T, F>
|
|
||||||
where
|
|
||||||
T: MuxedTransport + 'static, // TODO: 'static :-/
|
|
||||||
T::Dial: Send,
|
|
||||||
F: FnOnce(IoError, Multiaddr) -> IoError + Clone + Send + 'static, // TODO: 'static :-/
|
|
||||||
{
|
|
||||||
type Incoming = T::Incoming;
|
|
||||||
type IncomingUpgrade = T::IncomingUpgrade;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
self.transport.next_incoming()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -52,10 +52,9 @@ impl<T> Clone for Dialer<T> {
|
|||||||
|
|
||||||
impl<T: IntoBuf + Send + 'static> Transport for Dialer<T> {
|
impl<T: IntoBuf + Send + 'static> Transport for Dialer<T> {
|
||||||
type Output = Channel<T>;
|
type Output = Channel<T>;
|
||||||
type Listener = Box<Stream<Item=Self::ListenerUpgrade, Error=io::Error> + Send>;
|
type Listener = Box<Stream<Item=(Self::ListenerUpgrade, Multiaddr), Error=io::Error> + Send>;
|
||||||
type ListenerUpgrade = FutureResult<(Self::Output, Self::MultiaddrFuture), io::Error>;
|
type ListenerUpgrade = FutureResult<Self::Output, io::Error>;
|
||||||
type MultiaddrFuture = FutureResult<Multiaddr, io::Error>;
|
type Dial = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type Dial = Box<Future<Item=(Self::Output, Self::MultiaddrFuture), Error=io::Error> + Send>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
Err((self, addr))
|
Err((self, addr))
|
||||||
@ -70,7 +69,7 @@ impl<T: IntoBuf + Send + 'static> Transport for Dialer<T> {
|
|||||||
let a = Chan { incoming: a_rx, outgoing: b_tx };
|
let a = Chan { incoming: a_rx, outgoing: b_tx };
|
||||||
let b = Chan { incoming: b_rx, outgoing: a_tx };
|
let b = Chan { incoming: b_rx, outgoing: a_tx };
|
||||||
let future = self.0.send(b)
|
let future = self.0.send(b)
|
||||||
.map(move |_| (a.into(), future::ok(addr)))
|
.map(move |_| a.into())
|
||||||
.map_err(|_| io::ErrorKind::ConnectionRefused.into());
|
.map_err(|_| io::ErrorKind::ConnectionRefused.into());
|
||||||
Ok(Box::new(future))
|
Ok(Box::new(future))
|
||||||
}
|
}
|
||||||
@ -95,10 +94,9 @@ impl<T> Clone for Listener<T> {
|
|||||||
|
|
||||||
impl<T: IntoBuf + Send + 'static> Transport for Listener<T> {
|
impl<T: IntoBuf + Send + 'static> Transport for Listener<T> {
|
||||||
type Output = Channel<T>;
|
type Output = Channel<T>;
|
||||||
type Listener = Box<Stream<Item=Self::ListenerUpgrade, Error=io::Error> + Send>;
|
type Listener = Box<Stream<Item=(Self::ListenerUpgrade, Multiaddr), Error=io::Error> + Send>;
|
||||||
type ListenerUpgrade = FutureResult<(Self::Output, Self::MultiaddrFuture), io::Error>;
|
type ListenerUpgrade = FutureResult<Self::Output, io::Error>;
|
||||||
type MultiaddrFuture = FutureResult<Multiaddr, io::Error>;
|
type Dial = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type Dial = Box<Future<Item=(Self::Output, Self::MultiaddrFuture), Error=io::Error> + Send>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
if !is_memory_addr(&addr) {
|
if !is_memory_addr(&addr) {
|
||||||
@ -108,7 +106,7 @@ impl<T: IntoBuf + Send + 'static> Transport for Listener<T> {
|
|||||||
let receiver = self.0.clone();
|
let receiver = self.0.clone();
|
||||||
let stream = stream::poll_fn(move || receiver.lock().poll())
|
let stream = stream::poll_fn(move || receiver.lock().poll())
|
||||||
.map(move |channel| {
|
.map(move |channel| {
|
||||||
future::ok((channel.into(), future::ok(addr.clone())))
|
(future::ok(channel.into()), addr.clone())
|
||||||
})
|
})
|
||||||
.map_err(|()| unreachable!());
|
.map_err(|()| unreachable!());
|
||||||
Ok((Box::new(stream), addr2))
|
Ok((Box::new(stream), addr2))
|
||||||
|
@ -31,6 +31,7 @@
|
|||||||
|
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
|
use nodes::raw_swarm::ConnectedPoint;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use upgrade::{ConnectionUpgrade, Endpoint};
|
use upgrade::{ConnectionUpgrade, Endpoint};
|
||||||
@ -39,21 +40,16 @@ pub mod and_then;
|
|||||||
pub mod boxed;
|
pub mod boxed;
|
||||||
pub mod choice;
|
pub mod choice;
|
||||||
pub mod denied;
|
pub mod denied;
|
||||||
pub mod dummy;
|
|
||||||
pub mod interruptible;
|
pub mod interruptible;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
pub mod map_err;
|
pub mod map_err;
|
||||||
pub mod map_err_dial;
|
pub mod map_err_dial;
|
||||||
pub mod memory;
|
pub mod memory;
|
||||||
pub mod muxed;
|
|
||||||
pub mod upgrade;
|
pub mod upgrade;
|
||||||
|
|
||||||
pub use self::boxed::BoxedMuxed;
|
|
||||||
pub use self::choice::OrTransport;
|
pub use self::choice::OrTransport;
|
||||||
pub use self::denied::DeniedTransport;
|
pub use self::denied::DeniedTransport;
|
||||||
pub use self::dummy::DummyMuxing;
|
|
||||||
pub use self::memory::connector;
|
pub use self::memory::connector;
|
||||||
pub use self::muxed::MuxedTransport;
|
|
||||||
pub use self::upgrade::UpgradedNode;
|
pub use self::upgrade::UpgradedNode;
|
||||||
|
|
||||||
/// A transport is an object that can be used to produce connections by listening or dialing a
|
/// A transport is an object that can be used to produce connections by listening or dialing a
|
||||||
@ -75,19 +71,15 @@ pub trait Transport {
|
|||||||
/// An item should be produced whenever a connection is received at the lowest level of the
|
/// An item should be produced whenever a connection is received at the lowest level of the
|
||||||
/// transport stack. The item is a `Future` that is signalled once some pre-processing has
|
/// transport stack. The item is a `Future` that is signalled once some pre-processing has
|
||||||
/// taken place, and that connection has been upgraded to the wanted protocols.
|
/// taken place, and that connection has been upgraded to the wanted protocols.
|
||||||
type Listener: Stream<Item = Self::ListenerUpgrade, Error = IoError>;
|
type Listener: Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = IoError>;
|
||||||
|
|
||||||
/// Future that produces the multiaddress of the remote.
|
|
||||||
type MultiaddrFuture: Future<Item = Multiaddr, Error = IoError>;
|
|
||||||
|
|
||||||
/// After a connection has been received, we may need to do some asynchronous pre-processing
|
/// After a connection has been received, we may need to do some asynchronous pre-processing
|
||||||
/// on it (eg. an intermediary protocol negotiation). While this pre-processing takes place, we
|
/// on it (eg. an intermediary protocol negotiation). While this pre-processing takes place, we
|
||||||
/// want to be able to continue polling on the listener.
|
/// want to be able to continue polling on the listener.
|
||||||
// TODO: we could move the `MultiaddrFuture` to the `Listener` trait
|
type ListenerUpgrade: Future<Item = Self::Output, Error = IoError>;
|
||||||
type ListenerUpgrade: Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError>;
|
|
||||||
|
|
||||||
/// A future which indicates that we are currently dialing to a peer.
|
/// A future which indicates that we are currently dialing to a peer.
|
||||||
type Dial: Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError>;
|
type Dial: Future<Item = Self::Output, Error = IoError>;
|
||||||
|
|
||||||
/// Listen on the given multiaddr. Returns a stream of incoming connections, plus a modified
|
/// Listen on the given multiaddr. Returns a stream of incoming connections, plus a modified
|
||||||
/// version of the `Multiaddr`. This new `Multiaddr` is the one that that should be advertised
|
/// version of the `Multiaddr`. This new `Multiaddr` is the one that that should be advertised
|
||||||
@ -132,27 +124,10 @@ pub trait Transport {
|
|||||||
Self::Dial: Send + 'static,
|
Self::Dial: Send + 'static,
|
||||||
Self::Listener: Send + 'static,
|
Self::Listener: Send + 'static,
|
||||||
Self::ListenerUpgrade: Send + 'static,
|
Self::ListenerUpgrade: Send + 'static,
|
||||||
Self::MultiaddrFuture: Send + 'static,
|
|
||||||
{
|
{
|
||||||
boxed::boxed(self)
|
boxed::boxed(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Turns this `Transport` into an abstract boxed transport.
|
|
||||||
///
|
|
||||||
/// This is the version if the transport supports muxing.
|
|
||||||
#[inline]
|
|
||||||
fn boxed_muxed(self) -> boxed::BoxedMuxed<Self::Output>
|
|
||||||
where Self: Sized + MuxedTransport + Clone + Send + Sync + 'static,
|
|
||||||
Self::Dial: Send + 'static,
|
|
||||||
Self::Listener: Send + 'static,
|
|
||||||
Self::ListenerUpgrade: Send + 'static,
|
|
||||||
Self::MultiaddrFuture: Send + 'static,
|
|
||||||
Self::Incoming: Send + 'static,
|
|
||||||
Self::IncomingUpgrade: Send + 'static,
|
|
||||||
{
|
|
||||||
boxed::boxed_muxed(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Applies a function on the output of the `Transport`.
|
/// Applies a function on the output of the `Transport`.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn map<F, O>(self, map: F) -> map::Map<Self, F>
|
fn map<F, O>(self, map: F) -> map::Map<Self, F>
|
||||||
@ -207,7 +182,7 @@ pub trait Transport {
|
|||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
Self::Output: AsyncRead + AsyncWrite,
|
Self::Output: AsyncRead + AsyncWrite,
|
||||||
U: ConnectionUpgrade<Self::Output, Self::MultiaddrFuture>,
|
U: ConnectionUpgrade<Self::Output>,
|
||||||
{
|
{
|
||||||
UpgradedNode::new(self, upgrade)
|
UpgradedNode::new(self, upgrade)
|
||||||
}
|
}
|
||||||
@ -218,29 +193,15 @@ pub trait Transport {
|
|||||||
/// > **Note**: The concept of an *upgrade* for example includes middlewares such *secio*
|
/// > **Note**: The concept of an *upgrade* for example includes middlewares such *secio*
|
||||||
/// > (communication encryption), *multiplex*, but also a protocol handler.
|
/// > (communication encryption), *multiplex*, but also a protocol handler.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn and_then<C, F, O, Maf>(self, upgrade: C) -> and_then::AndThen<Self, C>
|
fn and_then<C, F, O>(self, upgrade: C) -> and_then::AndThen<Self, C>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
C: FnOnce(Self::Output, Endpoint, Self::MultiaddrFuture) -> F + Clone + 'static,
|
C: FnOnce(Self::Output, ConnectedPoint) -> F + Clone + 'static,
|
||||||
F: Future<Item = (O, Maf), Error = IoError> + 'static,
|
F: Future<Item = O, Error = IoError> + 'static,
|
||||||
Maf: Future<Item = Multiaddr, Error = IoError> + 'static,
|
|
||||||
{
|
{
|
||||||
and_then::and_then(self, upgrade)
|
and_then::and_then(self, upgrade)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Builds a dummy implementation of `MuxedTransport` that uses this transport.
|
|
||||||
///
|
|
||||||
/// The resulting object will not actually use muxing. This means that dialing the same node
|
|
||||||
/// twice will result in two different connections instead of two substreams on the same
|
|
||||||
/// connection.
|
|
||||||
#[inline]
|
|
||||||
fn with_dummy_muxing(self) -> DummyMuxing<Self>
|
|
||||||
where
|
|
||||||
Self: Sized,
|
|
||||||
{
|
|
||||||
DummyMuxing::new(self)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wraps around the `Transport` and makes it interruptible.
|
/// Wraps around the `Transport` and makes it interruptible.
|
||||||
#[inline]
|
#[inline]
|
||||||
fn interruptible(self) -> (interruptible::Interruptible<Self>, interruptible::Interrupt)
|
fn interruptible(self) -> (interruptible::Interruptible<Self>, interruptible::Interrupt)
|
||||||
|
@ -22,7 +22,7 @@ use futures::prelude::*;
|
|||||||
use multiaddr::Multiaddr;
|
use multiaddr::Multiaddr;
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use transport::{MuxedTransport, Transport};
|
use transport::Transport;
|
||||||
use upgrade::{apply, ConnectionUpgrade, Endpoint};
|
use upgrade::{apply, ConnectionUpgrade, Endpoint};
|
||||||
|
|
||||||
/// Implements the `Transport` trait. Dials or listens, then upgrades any dialed or received
|
/// Implements the `Transport` trait. Dials or listens, then upgrades any dialed or received
|
||||||
@ -50,9 +50,8 @@ where
|
|||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: Send + AsyncRead + AsyncWrite,
|
T::Output: Send + AsyncRead + AsyncWrite,
|
||||||
C: ConnectionUpgrade<T::Output, T::MultiaddrFuture> + Send + 'a,
|
C: ConnectionUpgrade<T::Output> + Send + 'a,
|
||||||
C::NamesIter: Send,
|
C::NamesIter: Send,
|
||||||
C::Future: Send,
|
C::Future: Send,
|
||||||
C::UpgradeIdentifier: Send,
|
C::UpgradeIdentifier: Send,
|
||||||
@ -72,7 +71,7 @@ where
|
|||||||
pub fn dial(
|
pub fn dial(
|
||||||
self,
|
self,
|
||||||
addr: Multiaddr,
|
addr: Multiaddr,
|
||||||
) -> Result<Box<Future<Item = (C::Output, C::MultiaddrFuture), Error = IoError> + Send + 'a>, (Self, Multiaddr)>
|
) -> Result<Box<Future<Item = C::Output, Error = IoError> + Send + 'a>, (Self, Multiaddr)>
|
||||||
where
|
where
|
||||||
C::NamesIter: Clone, // TODO: not elegant
|
C::NamesIter: Clone, // TODO: not elegant
|
||||||
{
|
{
|
||||||
@ -92,48 +91,13 @@ where
|
|||||||
|
|
||||||
let future = dialed_fut
|
let future = dialed_fut
|
||||||
// Try to negotiate the protocol.
|
// Try to negotiate the protocol.
|
||||||
.and_then(move |(connection, client_addr)| {
|
.and_then(move |connection| {
|
||||||
apply(connection, upgrade, Endpoint::Dialer, client_addr)
|
apply(connection, upgrade, Endpoint::Dialer)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Box::new(future))
|
Ok(Box::new(future))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// If the underlying transport is a `MuxedTransport`, then after calling `dial` we may receive
|
|
||||||
/// substreams opened by the dialed nodes.
|
|
||||||
///
|
|
||||||
/// This function returns the next incoming substream. You are strongly encouraged to call it
|
|
||||||
/// if you have a muxed transport.
|
|
||||||
pub fn next_incoming(
|
|
||||||
self,
|
|
||||||
) -> Box<
|
|
||||||
Future<
|
|
||||||
Item = Box<Future<Item = (C::Output, C::MultiaddrFuture), Error = IoError> + Send + 'a>,
|
|
||||||
Error = IoError,
|
|
||||||
>
|
|
||||||
+ Send + 'a,
|
|
||||||
>
|
|
||||||
where
|
|
||||||
T: MuxedTransport,
|
|
||||||
T::Incoming: Send,
|
|
||||||
T::IncomingUpgrade: Send,
|
|
||||||
C::NamesIter: Clone, // TODO: not elegant
|
|
||||||
C: Clone,
|
|
||||||
{
|
|
||||||
let upgrade = self.upgrade;
|
|
||||||
|
|
||||||
let future = self.transports.next_incoming().map(|future| {
|
|
||||||
// Try to negotiate the protocol.
|
|
||||||
let future = future.and_then(move |(connection, client_addr)| {
|
|
||||||
apply(connection, upgrade, Endpoint::Listener, client_addr)
|
|
||||||
});
|
|
||||||
|
|
||||||
Box::new(future) as Box<Future<Item = _, Error = _> + Send>
|
|
||||||
});
|
|
||||||
|
|
||||||
Box::new(future) as Box<_>
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Start listening on the multiaddr using the transport that was passed to `new`.
|
/// Start listening on the multiaddr using the transport that was passed to `new`.
|
||||||
/// Then whenever a connection is opened, it is upgraded.
|
/// Then whenever a connection is opened, it is upgraded.
|
||||||
///
|
///
|
||||||
@ -147,7 +111,7 @@ where
|
|||||||
(
|
(
|
||||||
Box<
|
Box<
|
||||||
Stream<
|
Stream<
|
||||||
Item = Box<Future<Item = (C::Output, C::MultiaddrFuture), Error = IoError> + Send + 'a>,
|
Item = (Box<Future<Item = C::Output, Error = IoError> + Send + 'a>, Multiaddr),
|
||||||
Error = IoError,
|
Error = IoError,
|
||||||
>
|
>
|
||||||
+ Send
|
+ Send
|
||||||
@ -179,15 +143,15 @@ where
|
|||||||
// Note that failing to negotiate a protocol will never produce a future with an error.
|
// Note that failing to negotiate a protocol will never produce a future with an error.
|
||||||
// Instead the `stream` will produce `Ok(Err(...))`.
|
// Instead the `stream` will produce `Ok(Err(...))`.
|
||||||
// `stream` can only produce an `Err` if `listening_stream` produces an `Err`.
|
// `stream` can only produce an `Err` if `listening_stream` produces an `Err`.
|
||||||
let stream = listening_stream.map(move |connection| {
|
let stream = listening_stream.map(move |(connection, client_addr)| {
|
||||||
let upgrade = upgrade.clone();
|
let upgrade = upgrade.clone();
|
||||||
let connection = connection
|
let connection = connection
|
||||||
// Try to negotiate the protocol.
|
// Try to negotiate the protocol.
|
||||||
.and_then(move |(connection, client_addr)| {
|
.and_then(move |connection| {
|
||||||
apply(connection, upgrade, Endpoint::Listener, client_addr)
|
apply(connection, upgrade, Endpoint::Listener)
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(connection) as Box<_>
|
(Box::new(connection) as Box<_>, client_addr)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok((Box::new(stream), new_addr))
|
Ok((Box::new(stream), new_addr))
|
||||||
@ -200,19 +164,16 @@ where
|
|||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: Send + AsyncRead + AsyncWrite,
|
T::Output: Send + AsyncRead + AsyncWrite,
|
||||||
C: ConnectionUpgrade<T::Output, T::MultiaddrFuture> + Clone + Send + 'static,
|
C: ConnectionUpgrade<T::Output> + Clone + Send + 'static,
|
||||||
C::MultiaddrFuture: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
C::NamesIter: Clone + Send,
|
C::NamesIter: Clone + Send,
|
||||||
C::Future: Send,
|
C::Future: Send,
|
||||||
C::UpgradeIdentifier: Send,
|
C::UpgradeIdentifier: Send,
|
||||||
{
|
{
|
||||||
type Output = C::Output;
|
type Output = C::Output;
|
||||||
type MultiaddrFuture = C::MultiaddrFuture;
|
type Listener = Box<Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = IoError> + Send>;
|
||||||
type Listener = Box<Stream<Item = Self::ListenerUpgrade, Error = IoError> + Send>;
|
type ListenerUpgrade = Box<Future<Item = C::Output, Error = IoError> + Send>;
|
||||||
type ListenerUpgrade = Box<Future<Item = (C::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
type Dial = Box<Future<Item = C::Output, Error = IoError> + Send>;
|
||||||
type Dial = Box<Future<Item = (C::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
@ -229,28 +190,3 @@ where
|
|||||||
self.transports.nat_traversal(server, observed)
|
self.transports.nat_traversal(server, observed)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T, C> MuxedTransport for UpgradedNode<T, C>
|
|
||||||
where
|
|
||||||
T: MuxedTransport + 'static,
|
|
||||||
T::Dial: Send,
|
|
||||||
T::Listener: Send,
|
|
||||||
T::ListenerUpgrade: Send,
|
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: Send + AsyncRead + AsyncWrite,
|
|
||||||
T::Incoming: Send,
|
|
||||||
T::IncomingUpgrade: Send,
|
|
||||||
C: ConnectionUpgrade<T::Output, T::MultiaddrFuture> + Clone + Send + 'static,
|
|
||||||
C::MultiaddrFuture: Future<Item = Multiaddr, Error = IoError>,
|
|
||||||
C::NamesIter: Clone + Send,
|
|
||||||
C::Future: Send,
|
|
||||||
C::UpgradeIdentifier: Send,
|
|
||||||
{
|
|
||||||
type Incoming = Box<Future<Item = Self::IncomingUpgrade, Error = IoError> + Send>;
|
|
||||||
type IncomingUpgrade = Box<Future<Item = (C::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
self.next_incoming()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -29,9 +29,9 @@ use upgrade::{ConnectionUpgrade, Endpoint};
|
|||||||
///
|
///
|
||||||
/// Returns a `Future` that returns the outcome of the connection upgrade.
|
/// Returns a `Future` that returns the outcome of the connection upgrade.
|
||||||
#[inline]
|
#[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
|
where
|
||||||
U: ConnectionUpgrade<C, Maf>,
|
U: ConnectionUpgrade<C>,
|
||||||
U::NamesIter: Clone, // TODO: not elegant
|
U::NamesIter: Clone, // TODO: not elegant
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
@ -40,31 +40,28 @@ where
|
|||||||
future: negotiate(conn, &upgrade, e),
|
future: negotiate(conn, &upgrade, e),
|
||||||
upgrade,
|
upgrade,
|
||||||
endpoint: e,
|
endpoint: e,
|
||||||
remote
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Future, returned from `apply` which performs a connection upgrade.
|
/// Future, returned from `apply` which performs a connection upgrade.
|
||||||
pub struct UpgradeApplyFuture<C, U, Maf>
|
pub struct UpgradeApplyFuture<C, U>
|
||||||
where
|
where
|
||||||
U: ConnectionUpgrade<C, Maf>,
|
U: ConnectionUpgrade<C>,
|
||||||
C: AsyncRead + AsyncWrite
|
C: AsyncRead + AsyncWrite
|
||||||
{
|
{
|
||||||
inner: UpgradeApplyState<C, U, Maf>
|
inner: UpgradeApplyState<C, U>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
enum UpgradeApplyState<C, U>
|
||||||
enum UpgradeApplyState<C, U, Maf>
|
|
||||||
where
|
where
|
||||||
U: ConnectionUpgrade<C, Maf>,
|
U: ConnectionUpgrade<C>,
|
||||||
C: AsyncRead + AsyncWrite
|
C: AsyncRead + AsyncWrite
|
||||||
{
|
{
|
||||||
Init {
|
Init {
|
||||||
future: NegotiationFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeIdentifier>,
|
future: NegotiationFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeIdentifier>,
|
||||||
upgrade: U,
|
upgrade: U,
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint
|
||||||
remote: Maf
|
|
||||||
},
|
},
|
||||||
Upgrade {
|
Upgrade {
|
||||||
future: U::Future
|
future: U::Future
|
||||||
@ -72,28 +69,28 @@ where
|
|||||||
Undefined
|
Undefined
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, U, Maf> Future for UpgradeApplyFuture<C, U, Maf>
|
impl<C, U> Future for UpgradeApplyFuture<C, U>
|
||||||
where
|
where
|
||||||
U: ConnectionUpgrade<C, Maf>,
|
U: ConnectionUpgrade<C>,
|
||||||
U::NamesIter: Clone,
|
U::NamesIter: Clone,
|
||||||
C: AsyncRead + AsyncWrite
|
C: AsyncRead + AsyncWrite
|
||||||
{
|
{
|
||||||
type Item = (U::Output, U::MultiaddrFuture);
|
type Item = U::Output;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
loop {
|
loop {
|
||||||
match mem::replace(&mut self.inner, UpgradeApplyState::Undefined) {
|
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()? {
|
let (upgrade_id, connection) = match future.poll()? {
|
||||||
Async::Ready(x) => x,
|
Async::Ready(x) => x,
|
||||||
Async::NotReady => {
|
Async::NotReady => {
|
||||||
self.inner = UpgradeApplyState::Init { future, upgrade, endpoint, remote };
|
self.inner = UpgradeApplyState::Init { future, upgrade, endpoint };
|
||||||
return Ok(Async::NotReady)
|
return Ok(Async::NotReady)
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
self.inner = UpgradeApplyState::Upgrade {
|
self.inner = UpgradeApplyState::Upgrade {
|
||||||
future: upgrade.upgrade(connection, upgrade_id, endpoint, remote)
|
future: upgrade.upgrade(connection, upgrade_id, endpoint)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
UpgradeApplyState::Upgrade { mut future } => {
|
UpgradeApplyState::Upgrade { mut future } => {
|
||||||
@ -124,13 +121,13 @@ where
|
|||||||
///
|
///
|
||||||
/// Returns a `Future` that returns the negotiated protocol and the stream.
|
/// Returns a `Future` that returns the negotiated protocol and the stream.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn negotiate<C, I, U, Maf>(
|
pub fn negotiate<C, I, U>(
|
||||||
connection: C,
|
connection: C,
|
||||||
upgrade: &U,
|
upgrade: &U,
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint,
|
||||||
) -> NegotiationFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeIdentifier>
|
) -> NegotiationFuture<C, ProtocolNames<U::NamesIter>, U::UpgradeIdentifier>
|
||||||
where
|
where
|
||||||
U: ConnectionUpgrade<I, Maf>,
|
U: ConnectionUpgrade<I>,
|
||||||
U::NamesIter: Clone, // TODO: not elegant
|
U::NamesIter: Clone, // TODO: not elegant
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
@ -144,7 +141,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Future, returned by `negotiate`, which negotiates a protocol and stream.
|
/// Future, returned by `negotiate`, which negotiates a protocol and stream.
|
||||||
pub struct NegotiationFuture<R: AsyncRead + AsyncWrite, I, P> {
|
pub struct NegotiationFuture<R: AsyncRead + AsyncWrite, I, P> {
|
||||||
inner: Either<ListenerSelectFuture<R, I, P>, DialerSelectFuture<R, 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.
|
/// Iterator adapter which adds equality matching predicates to items.
|
||||||
/// Used in `NegotiationFuture`.
|
/// Used in `NegotiationFuture`.
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
@ -19,8 +19,7 @@
|
|||||||
// DEALINGS IN THE SOFTWARE.
|
// DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
use bytes::Bytes;
|
use bytes::Bytes;
|
||||||
use futures::{future, prelude::*};
|
use futures::future;
|
||||||
use std::io::Error as IoError;
|
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use upgrade::{ConnectionUpgrade, Endpoint};
|
use upgrade::{ConnectionUpgrade, Endpoint};
|
||||||
|
|
||||||
@ -37,11 +36,11 @@ pub fn or<A, B>(me: A, other: B) -> OrUpgrade<A, B> {
|
|||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct OrUpgrade<A, B>(A, B);
|
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
|
where
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
A: ConnectionUpgrade<C, Maf, Output = O>,
|
A: ConnectionUpgrade<C, Output = O>,
|
||||||
B: ConnectionUpgrade<C, Maf, Output = O>,
|
B: ConnectionUpgrade<C, Output = O>,
|
||||||
{
|
{
|
||||||
type NamesIter = NamesIterChain<A::NamesIter, B::NamesIter>;
|
type NamesIter = NamesIterChain<A::NamesIter, B::NamesIter>;
|
||||||
type UpgradeIdentifier = EitherUpgradeIdentifier<A::UpgradeIdentifier, B::UpgradeIdentifier>;
|
type UpgradeIdentifier = EitherUpgradeIdentifier<A::UpgradeIdentifier, B::UpgradeIdentifier>;
|
||||||
@ -55,8 +54,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = O;
|
type Output = O;
|
||||||
type MultiaddrFuture = future::Either<A::MultiaddrFuture, B::MultiaddrFuture>;
|
type Future = future::Either<A::Future, B::Future>;
|
||||||
type Future = EitherConnUpgrFuture<A::Future, B::Future>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(
|
fn upgrade(
|
||||||
@ -64,14 +62,13 @@ where
|
|||||||
socket: C,
|
socket: C,
|
||||||
id: Self::UpgradeIdentifier,
|
id: Self::UpgradeIdentifier,
|
||||||
ty: Endpoint,
|
ty: Endpoint,
|
||||||
remote_addr: Maf,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
match id {
|
match id {
|
||||||
EitherUpgradeIdentifier::First(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) => {
|
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),
|
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.
|
/// Internal type used by the `OrUpgrade` struct.
|
||||||
///
|
///
|
||||||
/// > **Note**: This type is needed because of the lack of `-> impl Trait` in Rust. It can be
|
/// > **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 bytes::Bytes;
|
||||||
use futures::prelude::*;
|
use futures::prelude::*;
|
||||||
use multiaddr::Multiaddr;
|
|
||||||
use std::{io, iter};
|
use std::{io, iter};
|
||||||
use tokio_io::{AsyncRead, AsyncWrite};
|
use tokio_io::{AsyncRead, AsyncWrite};
|
||||||
use upgrade::{ConnectionUpgrade, Endpoint};
|
use upgrade::{ConnectionUpgrade, Endpoint};
|
||||||
@ -29,15 +28,14 @@ use upgrade::{ConnectionUpgrade, Endpoint};
|
|||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct DeniedConnectionUpgrade;
|
pub struct DeniedConnectionUpgrade;
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for DeniedConnectionUpgrade
|
impl<C> ConnectionUpgrade<C> for DeniedConnectionUpgrade
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type NamesIter = iter::Empty<(Bytes, ())>;
|
type NamesIter = iter::Empty<(Bytes, ())>;
|
||||||
type UpgradeIdentifier = (); // TODO: could use `!`
|
type UpgradeIdentifier = (); // TODO: could use `!`
|
||||||
type Output = (); // 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 = (), Error = io::Error> + Send + Sync>; // TODO: could use `!`
|
||||||
type Future = Box<Future<Item = ((), Self::MultiaddrFuture), Error = io::Error> + Send + Sync>; // TODO: could use `!`
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn protocol_names(&self) -> Self::NamesIter {
|
fn protocol_names(&self) -> Self::NamesIter {
|
||||||
@ -45,7 +43,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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")
|
unreachable!("the denied connection upgrade always fails to negotiate")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,23 +61,20 @@ pub struct LoopUpg<Inner> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// TODO: 'static :-/
|
// TODO: 'static :-/
|
||||||
impl<State, Socket, Inner, Out, AddrFut> ConnectionUpgrade<(State, Socket), AddrFut>
|
impl<State, Socket, Inner, Out> ConnectionUpgrade<(State, Socket)>
|
||||||
for LoopUpg<Inner>
|
for LoopUpg<Inner>
|
||||||
where
|
where
|
||||||
State: Send + 'static,
|
State: Send + 'static,
|
||||||
Socket: AsyncRead + AsyncWrite + Send + 'static,
|
Socket: AsyncRead + AsyncWrite + Send + 'static,
|
||||||
Inner: ConnectionUpgrade<
|
Inner: ConnectionUpgrade<
|
||||||
(State, Socket),
|
(State, Socket),
|
||||||
AddrFut,
|
|
||||||
Output = Loop<State, Socket, Out>,
|
Output = Loop<State, Socket, Out>,
|
||||||
MultiaddrFuture = AddrFut,
|
|
||||||
> + Clone
|
> + Clone
|
||||||
+ Send
|
+ Send
|
||||||
+ 'static,
|
+ 'static,
|
||||||
Inner::NamesIter: Clone + Send + 'static,
|
Inner::NamesIter: Clone + Send + 'static,
|
||||||
Inner::UpgradeIdentifier: Send,
|
Inner::UpgradeIdentifier: Send,
|
||||||
Inner::Future: Send,
|
Inner::Future: Send,
|
||||||
AddrFut: Send + 'static,
|
|
||||||
Out: Send + 'static,
|
Out: Send + 'static,
|
||||||
{
|
{
|
||||||
type NamesIter = Inner::NamesIter;
|
type NamesIter = Inner::NamesIter;
|
||||||
@ -88,29 +85,27 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = Out;
|
type Output = Out;
|
||||||
type MultiaddrFuture = AddrFut;
|
type Future = Box<Future<Item = Out, Error = IoError> + Send>;
|
||||||
type Future = Box<Future<Item = (Out, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
fn upgrade(
|
fn upgrade(
|
||||||
self,
|
self,
|
||||||
(state, socket): (State, Socket),
|
(state, socket): (State, Socket),
|
||||||
id: Self::UpgradeIdentifier,
|
id: Self::UpgradeIdentifier,
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint,
|
||||||
remote_addr: AddrFut,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
let inner = self.inner;
|
let inner = self.inner;
|
||||||
|
|
||||||
let fut = future::loop_fn(
|
let fut = future::loop_fn(
|
||||||
(state, socket, id, remote_addr, MAX_LOOPS),
|
(state, socket, id, MAX_LOOPS),
|
||||||
move |(state, socket, id, remote_addr, loops_remaining)| {
|
move |(state, socket, id, loops_remaining)| {
|
||||||
// When we enter a recursion of the `loop_fn`, a protocol has already been
|
// 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
|
// 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`.
|
// (if necessary), and then only continue iteration in the `future::loop_fn`.
|
||||||
let inner = inner.clone();
|
let inner = inner.clone();
|
||||||
inner
|
inner
|
||||||
.clone()
|
.clone()
|
||||||
.upgrade((state, socket), id, endpoint, remote_addr)
|
.upgrade((state, socket), id, endpoint)
|
||||||
.and_then(move |(loop_out, remote_addr)| match loop_out {
|
.and_then(move |loop_out| match loop_out {
|
||||||
Loop::Continue(state, socket) => {
|
Loop::Continue(state, socket) => {
|
||||||
// Produce an error if we reached the recursion limit.
|
// Produce an error if we reached the recursion limit.
|
||||||
if loops_remaining == 0 {
|
if loops_remaining == 0 {
|
||||||
@ -126,14 +121,13 @@ where
|
|||||||
state,
|
state,
|
||||||
socket,
|
socket,
|
||||||
id,
|
id,
|
||||||
remote_addr,
|
|
||||||
loops_remaining - 1,
|
loops_remaining - 1,
|
||||||
))
|
))
|
||||||
});
|
});
|
||||||
future::Either::A(fut)
|
future::Either::A(fut)
|
||||||
}
|
}
|
||||||
Loop::Break(fin) => {
|
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,
|
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
|
where
|
||||||
U: ConnectionUpgrade<C, Maf>,
|
U: ConnectionUpgrade<C>,
|
||||||
U::Future: Send + 'static, // TODO: 'static :(
|
U::Future: Send + 'static, // TODO: 'static :(
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
F: FnOnce(U::Output) -> O + Send + 'static, // TODO: 'static :(
|
F: FnOnce(U::Output) -> O + Send + 'static, // TODO: 'static :(
|
||||||
@ -51,20 +51,18 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = O;
|
type Output = O;
|
||||||
type MultiaddrFuture = U::MultiaddrFuture;
|
type Future = Box<Future<Item = O, Error = IoError> + Send>;
|
||||||
type Future = Box<Future<Item = (O, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
fn upgrade(
|
fn upgrade(
|
||||||
self,
|
self,
|
||||||
socket: C,
|
socket: C,
|
||||||
id: Self::UpgradeIdentifier,
|
id: Self::UpgradeIdentifier,
|
||||||
ty: Endpoint,
|
ty: Endpoint,
|
||||||
remote_addr: Maf,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
let map = self.map;
|
let map = self.map;
|
||||||
let fut = self.upgrade
|
let fut = self.upgrade
|
||||||
.upgrade(socket, id, ty, remote_addr)
|
.upgrade(socket, id, ty)
|
||||||
.map(move |(out, maf)| (map(out), maf));
|
.map(map);
|
||||||
Box::new(fut) as Box<_>
|
Box::new(fut) as Box<_>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,6 @@ pub mod choice;
|
|||||||
pub mod denied;
|
pub mod denied;
|
||||||
pub mod loop_upg;
|
pub mod loop_upg;
|
||||||
pub mod map;
|
pub mod map;
|
||||||
pub mod map_addr;
|
|
||||||
pub mod plaintext;
|
pub mod plaintext;
|
||||||
pub mod toggleable;
|
pub mod toggleable;
|
||||||
pub mod traits;
|
pub mod traits;
|
||||||
@ -33,7 +32,6 @@ pub use self::choice::{or, OrUpgrade};
|
|||||||
pub use self::denied::DeniedConnectionUpgrade;
|
pub use self::denied::DeniedConnectionUpgrade;
|
||||||
pub use self::loop_upg::{loop_upg, Loop};
|
pub use self::loop_upg::{loop_upg, Loop};
|
||||||
pub use self::map::map;
|
pub use self::map::map;
|
||||||
pub use self::map_addr::map_with_addr;
|
|
||||||
pub use self::plaintext::PlainTextConfig;
|
pub use self::plaintext::PlainTextConfig;
|
||||||
pub use self::toggleable::toggleable;
|
pub use self::toggleable::toggleable;
|
||||||
pub use self::traits::{ConnectionUpgrade, Endpoint};
|
pub use self::traits::{ConnectionUpgrade, Endpoint};
|
||||||
|
@ -32,19 +32,18 @@ use upgrade::{ConnectionUpgrade, Endpoint};
|
|||||||
#[derive(Debug, Copy, Clone)]
|
#[derive(Debug, Copy, Clone)]
|
||||||
pub struct PlainTextConfig;
|
pub struct PlainTextConfig;
|
||||||
|
|
||||||
impl<C, F> ConnectionUpgrade<C, F> for PlainTextConfig
|
impl<C> ConnectionUpgrade<C> for PlainTextConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Output = C;
|
type Output = C;
|
||||||
type Future = FutureResult<(C, F), IoError>;
|
type Future = FutureResult<C, IoError>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
type MultiaddrFuture = F;
|
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(self, i: C, _: (), _: Endpoint, remote_addr: F) -> Self::Future {
|
fn upgrade(self, i: C, _: (), _: Endpoint) -> Self::Future {
|
||||||
future::ok((i, remote_addr))
|
future::ok(i)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[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
|
where
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
U: ConnectionUpgrade<C, Maf>,
|
U: ConnectionUpgrade<C>,
|
||||||
{
|
{
|
||||||
type NamesIter = ToggleableIter<U::NamesIter>;
|
type NamesIter = ToggleableIter<U::NamesIter>;
|
||||||
type UpgradeIdentifier = U::UpgradeIdentifier;
|
type UpgradeIdentifier = U::UpgradeIdentifier;
|
||||||
@ -82,8 +82,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = U::Output;
|
type Output = U::Output;
|
||||||
type MultiaddrFuture = U::MultiaddrFuture;
|
type Future = future::Either<future::Empty<U::Output, IoError>, U::Future>;
|
||||||
type Future = future::Either<future::Empty<(U::Output, U::MultiaddrFuture), IoError>, U::Future>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(
|
fn upgrade(
|
||||||
@ -91,10 +90,9 @@ where
|
|||||||
socket: C,
|
socket: C,
|
||||||
id: Self::UpgradeIdentifier,
|
id: Self::UpgradeIdentifier,
|
||||||
ty: Endpoint,
|
ty: Endpoint,
|
||||||
remote_addr: Maf,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
if self.enabled {
|
if self.enabled {
|
||||||
future::Either::B(self.inner.upgrade(socket, id, ty, remote_addr))
|
future::Either::B(self.inner.upgrade(socket, id, ty))
|
||||||
} else {
|
} else {
|
||||||
future::Either::A(future::empty())
|
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`.
|
/// > **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
|
/// > This has been designed so that you would implement this trait on `&Foo` or
|
||||||
/// > `&mut Foo` instead of directly on `Foo`.
|
/// > `&mut Foo` instead of directly on `Foo`.
|
||||||
pub trait ConnectionUpgrade<C, TAddrFut> {
|
pub trait ConnectionUpgrade<C> {
|
||||||
/// Iterator returned by `protocol_names`.
|
/// Iterator returned by `protocol_names`.
|
||||||
type NamesIter: Iterator<Item = (Bytes, Self::UpgradeIdentifier)>;
|
type NamesIter: Iterator<Item = (Bytes, Self::UpgradeIdentifier)>;
|
||||||
/// Type that serves as an identifier for the protocol. This type only exists to be returned
|
/// 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`),
|
/// > **Note**: For upgrades that add an intermediary layer (such as `secio` or `multiplex`),
|
||||||
/// > this associated type must implement `AsyncRead + AsyncWrite`.
|
/// > this associated type must implement `AsyncRead + AsyncWrite`.
|
||||||
type Output;
|
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 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.
|
/// This method is called after protocol negotiation has been performed.
|
||||||
///
|
///
|
||||||
@ -82,6 +80,5 @@ pub trait ConnectionUpgrade<C, TAddrFut> {
|
|||||||
socket: C,
|
socket: C,
|
||||||
id: Self::UpgradeIdentifier,
|
id: Self::UpgradeIdentifier,
|
||||||
ty: Endpoint,
|
ty: Endpoint,
|
||||||
remote_addr: TAddrFut,
|
|
||||||
) -> Self::Future;
|
) -> Self::Future;
|
||||||
}
|
}
|
||||||
|
@ -117,18 +117,17 @@ pub enum MaxBufferBehaviour {
|
|||||||
Block,
|
Block,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for MplexConfig
|
impl<C> ConnectionUpgrade<C> for MplexConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Output = Multiplex<C>;
|
type Output = Multiplex<C>;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = future::FutureResult<Self::Output, IoError>;
|
||||||
type Future = future::FutureResult<(Self::Output, Self::MultiaddrFuture), IoError>;
|
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(self, i: C, _: (), endpoint: Endpoint, remote_addr: Maf) -> Self::Future {
|
fn upgrade(self, i: C, _: (), endpoint: Endpoint) -> Self::Future {
|
||||||
let max_buffer_len = self.max_buffer_len;
|
let max_buffer_len = self.max_buffer_len;
|
||||||
|
|
||||||
let out = Multiplex {
|
let out = Multiplex {
|
||||||
@ -149,7 +148,7 @@ where
|
|||||||
})
|
})
|
||||||
};
|
};
|
||||||
|
|
||||||
future::ok((out, remote_addr))
|
future::ok(out)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
|
@ -52,8 +52,8 @@ fn client_to_server_outbound() {
|
|||||||
let future = listener
|
let future = listener
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(err, _)| err)
|
.map_err(|(err, _)| err)
|
||||||
.and_then(|(client, _)| client.unwrap().map(|v| Arc::new(v.0)))
|
.and_then(|(client, _)| client.unwrap().0)
|
||||||
.and_then(|client| muxing::outbound_from_ref_and_wrap(client))
|
.and_then(|client| muxing::outbound_from_ref_and_wrap(Arc::new(client)))
|
||||||
.map(|client| Framed::<_, bytes::BytesMut>::new(client.unwrap()))
|
.map(|client| Framed::<_, bytes::BytesMut>::new(client.unwrap()))
|
||||||
.and_then(|client| {
|
.and_then(|client| {
|
||||||
client
|
client
|
||||||
@ -75,7 +75,7 @@ fn client_to_server_outbound() {
|
|||||||
let future = transport
|
let future = transport
|
||||||
.dial(rx.recv().unwrap())
|
.dial(rx.recv().unwrap())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.and_then(|client| muxing::inbound_from_ref_and_wrap(Arc::new(client.0)))
|
.and_then(|client| muxing::inbound_from_ref_and_wrap(Arc::new(client)))
|
||||||
.map(|server| Framed::<_, bytes::BytesMut>::new(server.unwrap()))
|
.map(|server| Framed::<_, bytes::BytesMut>::new(server.unwrap()))
|
||||||
.and_then(|server| server.send("hello world".into()))
|
.and_then(|server| server.send("hello world".into()))
|
||||||
.map(|_| ());
|
.map(|_| ());
|
||||||
@ -102,7 +102,7 @@ fn client_to_server_inbound() {
|
|||||||
let future = listener
|
let future = listener
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(err, _)| err)
|
.map_err(|(err, _)| err)
|
||||||
.and_then(|(client, _)| client.unwrap().map(|v| v.0))
|
.and_then(|(client, _)| client.unwrap().0)
|
||||||
.and_then(|client| muxing::inbound_from_ref_and_wrap(Arc::new(client)))
|
.and_then(|client| muxing::inbound_from_ref_and_wrap(Arc::new(client)))
|
||||||
.map(|client| Framed::<_, bytes::BytesMut>::new(client.unwrap()))
|
.map(|client| Framed::<_, bytes::BytesMut>::new(client.unwrap()))
|
||||||
.and_then(|client| {
|
.and_then(|client| {
|
||||||
@ -125,7 +125,7 @@ fn client_to_server_inbound() {
|
|||||||
let future = transport
|
let future = transport
|
||||||
.dial(rx.recv().unwrap())
|
.dial(rx.recv().unwrap())
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.and_then(|(client, _)| muxing::outbound_from_ref_and_wrap(Arc::new(client)))
|
.and_then(|client| muxing::outbound_from_ref_and_wrap(Arc::new(client)))
|
||||||
.map(|server| Framed::<_, bytes::BytesMut>::new(server.unwrap()))
|
.map(|server| Framed::<_, bytes::BytesMut>::new(server.unwrap()))
|
||||||
.and_then(|server| server.send("hello world".into()))
|
.and_then(|server| server.send("hello world".into()))
|
||||||
.map(|_| ());
|
.map(|_| ());
|
||||||
|
@ -134,10 +134,9 @@ impl Default for Config {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, M> core::ConnectionUpgrade<C, M> for Config
|
impl<C> core::ConnectionUpgrade<C> for Config
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + 'static,
|
C: AsyncRead + AsyncWrite + 'static,
|
||||||
M: 'static
|
|
||||||
{
|
{
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
@ -147,15 +146,15 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = Yamux<C>;
|
type Output = Yamux<C>;
|
||||||
type MultiaddrFuture = M;
|
type Future = FutureResult<Yamux<C>, io::Error>;
|
||||||
type Future = FutureResult<(Yamux<C>, M), io::Error>;
|
|
||||||
|
|
||||||
fn upgrade(self, i: C, _: (), end: Endpoint, remote: M) -> Self::Future {
|
fn upgrade(self, i: C, _: (), end: Endpoint) -> Self::Future {
|
||||||
let mode = match end {
|
let mode = match end {
|
||||||
Endpoint::Dialer => yamux::Mode::Client,
|
Endpoint::Dialer => yamux::Mode::Client,
|
||||||
Endpoint::Listener => yamux::Mode::Server
|
Endpoint::Listener => yamux::Mode::Server
|
||||||
};
|
};
|
||||||
future::ok((Yamux::new(i, self.0, mode), remote))
|
|
||||||
|
future::ok(Yamux::new(i, self.0, mode))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,10 +89,9 @@ impl FloodSubUpgrade {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for FloodSubUpgrade
|
impl<C> ConnectionUpgrade<C> for FloodSubUpgrade
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static,
|
C: AsyncRead + AsyncWrite + Send + 'static,
|
||||||
Maf: Future<Item = Multiaddr, Error = IoError> + Send + 'static,
|
|
||||||
{
|
{
|
||||||
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
@ -103,8 +102,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = FloodSubFuture;
|
type Output = FloodSubFuture;
|
||||||
type MultiaddrFuture = future::FutureResult<Multiaddr, IoError>;
|
type Future = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
type Future = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(
|
fn upgrade(
|
||||||
@ -112,11 +110,13 @@ where
|
|||||||
socket: C,
|
socket: C,
|
||||||
_: Self::UpgradeIdentifier,
|
_: Self::UpgradeIdentifier,
|
||||||
_: Endpoint,
|
_: Endpoint,
|
||||||
remote_addr: Maf,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
debug!("Upgrading connection as floodsub");
|
debug!("Upgrading connection as floodsub");
|
||||||
|
|
||||||
let future = remote_addr.and_then(move |remote_addr| {
|
let future = {
|
||||||
|
// FIXME: WRONG
|
||||||
|
let remote_addr: Multiaddr = "/ip4/127.0.0.1/tcp/5000".parse().unwrap();
|
||||||
|
|
||||||
// Whenever a new node connects, we send to it a message containing the topics we are
|
// Whenever a new node connects, we send to it a message containing the topics we are
|
||||||
// already subscribed to.
|
// already subscribed to.
|
||||||
let init_msg: Vec<u8> = {
|
let init_msg: Vec<u8> = {
|
||||||
@ -168,7 +168,6 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
let inner = self.inner.clone();
|
let inner = self.inner.clone();
|
||||||
let remote_addr_ret = future::ok(remote_addr.clone());
|
|
||||||
let future = future::loop_fn(
|
let future = future::loop_fn(
|
||||||
(floodsub_sink, messages),
|
(floodsub_sink, messages),
|
||||||
move |(floodsub_sink, messages)| {
|
move |(floodsub_sink, messages)| {
|
||||||
@ -215,10 +214,10 @@ where
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
future::ok((FloodSubFuture {
|
future::ok(FloodSubFuture {
|
||||||
inner: Box::new(future) as Box<_>,
|
inner: Box::new(future) as Box<_>,
|
||||||
}, remote_addr_ret))
|
})
|
||||||
});
|
};
|
||||||
|
|
||||||
Box::new(future) as Box<_>
|
Box::new(future) as Box<_>
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,9 @@ parking_lot = "0.6"
|
|||||||
protobuf = "2.0.2"
|
protobuf = "2.0.2"
|
||||||
tokio-codec = "0.1"
|
tokio-codec = "0.1"
|
||||||
tokio-io = "0.1.0"
|
tokio-io = "0.1.0"
|
||||||
|
tokio-timer = "0.2.6"
|
||||||
unsigned-varint = { version = "0.2.1", features = ["codec"] }
|
unsigned-varint = { version = "0.2.1", features = ["codec"] }
|
||||||
|
void = "1.0"
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
libp2p-tcp-transport = { path = "../../transports/tcp" }
|
libp2p-tcp-transport = { path = "../../transports/tcp" }
|
||||||
|
@ -77,14 +77,12 @@ extern crate parking_lot;
|
|||||||
extern crate protobuf;
|
extern crate protobuf;
|
||||||
extern crate tokio_codec;
|
extern crate tokio_codec;
|
||||||
extern crate tokio_io;
|
extern crate tokio_io;
|
||||||
|
extern crate tokio_timer;
|
||||||
extern crate unsigned_varint;
|
extern crate unsigned_varint;
|
||||||
|
extern crate void;
|
||||||
|
|
||||||
pub use self::identify_transport::IdentifyTransportOutcome;
|
|
||||||
pub use self::peer_id_transport::{PeerIdTransport, PeerIdTransportOutput};
|
|
||||||
pub use self::protocol::{IdentifyInfo, IdentifyOutput};
|
pub use self::protocol::{IdentifyInfo, IdentifyOutput};
|
||||||
pub use self::protocol::{IdentifyProtocolConfig, IdentifySender};
|
pub use self::protocol::{IdentifyProtocolConfig, IdentifySender};
|
||||||
|
|
||||||
mod identify_transport;
|
|
||||||
mod peer_id_transport;
|
|
||||||
mod protocol;
|
mod protocol;
|
||||||
mod structs_proto;
|
mod structs_proto;
|
||||||
|
@ -20,8 +20,7 @@
|
|||||||
|
|
||||||
use bytes::{Bytes, BytesMut};
|
use bytes::{Bytes, BytesMut};
|
||||||
use futures::{future, Future, Sink, Stream};
|
use futures::{future, Future, Sink, Stream};
|
||||||
use libp2p_core::{ConnectionUpgrade, Endpoint, PublicKey};
|
use libp2p_core::{ConnectionUpgrade, Endpoint, Multiaddr, PublicKey};
|
||||||
use multiaddr::Multiaddr;
|
|
||||||
use protobuf::Message as ProtobufMessage;
|
use protobuf::Message as ProtobufMessage;
|
||||||
use protobuf::parse_from_bytes as protobuf_parse_from_bytes;
|
use protobuf::parse_from_bytes as protobuf_parse_from_bytes;
|
||||||
use protobuf::RepeatedField;
|
use protobuf::RepeatedField;
|
||||||
@ -111,23 +110,21 @@ pub struct IdentifyInfo {
|
|||||||
pub protocols: Vec<String>,
|
pub protocols: Vec<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for IdentifyProtocolConfig
|
impl<C> ConnectionUpgrade<C> for IdentifyProtocolConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static,
|
C: AsyncRead + AsyncWrite + Send + 'static,
|
||||||
Maf: Future<Item = Multiaddr, Error = IoError> + Send + 'static,
|
|
||||||
{
|
{
|
||||||
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
type Output = IdentifyOutput<C>;
|
type Output = IdentifyOutput<C>;
|
||||||
type MultiaddrFuture = future::Either<future::FutureResult<Multiaddr, IoError>, Maf>;
|
type Future = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
type Future = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn protocol_names(&self) -> Self::NamesIter {
|
fn protocol_names(&self) -> Self::NamesIter {
|
||||||
iter::once((Bytes::from("/ipfs/id/1.0.0"), ()))
|
iter::once((Bytes::from("/ipfs/id/1.0.0"), ()))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn upgrade(self, socket: C, _: (), ty: Endpoint, remote_addr: Maf) -> Self::Future {
|
fn upgrade(self, socket: C, _: (), ty: Endpoint) -> Self::Future {
|
||||||
trace!("Upgrading connection as {:?}", ty);
|
trace!("Upgrading connection as {:?}", ty);
|
||||||
|
|
||||||
let socket = Framed::new(socket, codec::UviBytes::default());
|
let socket = Framed::new(socket, codec::UviBytes::default());
|
||||||
@ -153,12 +150,10 @@ where
|
|||||||
trace!("Remote observes us as {:?}", observed_addr);
|
trace!("Remote observes us as {:?}", observed_addr);
|
||||||
trace!("Information received: {:?}", info);
|
trace!("Information received: {:?}", info);
|
||||||
|
|
||||||
let out = IdentifyOutput::RemoteInfo {
|
Ok(IdentifyOutput::RemoteInfo {
|
||||||
info,
|
info,
|
||||||
observed_addr: observed_addr.clone(),
|
observed_addr: observed_addr.clone(),
|
||||||
};
|
})
|
||||||
|
|
||||||
Ok((out, future::Either::A(future::ok(observed_addr))))
|
|
||||||
} else {
|
} else {
|
||||||
debug!("Identify protocol stream closed before receiving info");
|
debug!("Identify protocol stream closed before receiving info");
|
||||||
Err(IoErrorKind::InvalidData.into())
|
Err(IoErrorKind::InvalidData.into())
|
||||||
@ -170,15 +165,7 @@ where
|
|||||||
|
|
||||||
Endpoint::Listener => {
|
Endpoint::Listener => {
|
||||||
let sender = IdentifySender { inner: socket };
|
let sender = IdentifySender { inner: socket };
|
||||||
|
let future = future::ok(IdentifyOutput::Sender { sender });
|
||||||
let future = future::ok({
|
|
||||||
let io = IdentifyOutput::Sender {
|
|
||||||
sender,
|
|
||||||
};
|
|
||||||
|
|
||||||
(io, future::Either::B(remote_addr))
|
|
||||||
});
|
|
||||||
|
|
||||||
Box::new(future) as Box<_>
|
Box::new(future) as Box<_>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,7 +238,7 @@ mod tests {
|
|||||||
let future = listener
|
let future = listener
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(err, _)| err)
|
.map_err(|(err, _)| err)
|
||||||
.and_then(|(client, _)| client.unwrap().map(|v| v.0))
|
.and_then(|(client, _)| client.unwrap().0)
|
||||||
.and_then(|identify| match identify {
|
.and_then(|identify| match identify {
|
||||||
IdentifyOutput::Sender { sender, .. } => sender.send(
|
IdentifyOutput::Sender { sender, .. } => sender.send(
|
||||||
IdentifyInfo {
|
IdentifyInfo {
|
||||||
@ -277,7 +264,7 @@ mod tests {
|
|||||||
let future = transport
|
let future = transport
|
||||||
.dial(rx.recv().unwrap())
|
.dial(rx.recv().unwrap())
|
||||||
.unwrap_or_else(|_| panic!())
|
.unwrap_or_else(|_| panic!())
|
||||||
.and_then(|(identify, _)| match identify {
|
.and_then(|identify| match identify {
|
||||||
IdentifyOutput::RemoteInfo {
|
IdentifyOutput::RemoteInfo {
|
||||||
info,
|
info,
|
||||||
observed_addr,
|
observed_addr,
|
||||||
|
@ -64,7 +64,7 @@ impl KadConnecConfig {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for KadConnecConfig
|
impl<C> ConnectionUpgrade<C> for KadConnecConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static, // TODO: 'static :-/
|
C: AsyncRead + AsyncWrite + Send + 'static, // TODO: 'static :-/
|
||||||
{
|
{
|
||||||
@ -72,22 +72,21 @@ where
|
|||||||
KadConnecController,
|
KadConnecController,
|
||||||
Box<Stream<Item = KadIncomingRequest, Error = IoError> + Send>,
|
Box<Stream<Item = KadIncomingRequest, Error = IoError> + Send>,
|
||||||
);
|
);
|
||||||
type MultiaddrFuture = Maf;
|
type Future = future::Map<<KademliaProtocolConfig as ConnectionUpgrade<C>>::Future, fn(<KademliaProtocolConfig as ConnectionUpgrade<C>>::Output) -> Self::Output>;
|
||||||
type Future = future::Map<<KademliaProtocolConfig as ConnectionUpgrade<C, Maf>>::Future, fn((<KademliaProtocolConfig as ConnectionUpgrade<C, Maf>>::Output, Maf)) -> (Self::Output, Maf)>;
|
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn protocol_names(&self) -> Self::NamesIter {
|
fn protocol_names(&self) -> Self::NamesIter {
|
||||||
ConnectionUpgrade::<C, Maf>::protocol_names(&self.raw_proto)
|
ConnectionUpgrade::<C>::protocol_names(&self.raw_proto)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(self, incoming: C, id: (), endpoint: Endpoint, addr: Maf) -> Self::Future {
|
fn upgrade(self, incoming: C, id: (), endpoint: Endpoint) -> Self::Future {
|
||||||
self.raw_proto
|
self.raw_proto
|
||||||
.upgrade(incoming, id, endpoint, addr)
|
.upgrade(incoming, id, endpoint)
|
||||||
.map::<fn(_) -> _, _>(move |(connec, addr)| {
|
.map::<fn(_) -> _, _>(move |connec| {
|
||||||
(build_from_sink_stream(connec), addr)
|
build_from_sink_stream(connec)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,13 +128,12 @@ impl Into<protobuf_structs::dht::Message_Peer> for KadPeer {
|
|||||||
#[derive(Debug, Default, Copy, Clone)]
|
#[derive(Debug, Default, Copy, Clone)]
|
||||||
pub struct KademliaProtocolConfig;
|
pub struct KademliaProtocolConfig;
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for KademliaProtocolConfig
|
impl<C> ConnectionUpgrade<C> for KademliaProtocolConfig
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + 'static, // TODO: 'static :-/
|
C: AsyncRead + AsyncWrite + 'static, // TODO: 'static :-/
|
||||||
{
|
{
|
||||||
type Output = KadStreamSink<C>;
|
type Output = KadStreamSink<C>;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = future::FutureResult<Self::Output, IoError>;
|
||||||
type Future = future::FutureResult<(Self::Output, Self::MultiaddrFuture), IoError>;
|
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
|
|
||||||
@ -144,8 +143,8 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(self, incoming: C, _: (), _: Endpoint, addr: Maf) -> Self::Future {
|
fn upgrade(self, incoming: C, _: (), _: Endpoint) -> Self::Future {
|
||||||
future::ok((kademlia_protocol(incoming), addr))
|
future::ok(kademlia_protocol(incoming))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -489,7 +488,7 @@ mod tests {
|
|||||||
let future = listener
|
let future = listener
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(err, _)| err)
|
.map_err(|(err, _)| err)
|
||||||
.and_then(|(client, _)| client.unwrap().map(|v| v.0))
|
.and_then(|(client, _)| client.unwrap().0)
|
||||||
.and_then(|proto| proto.into_future().map_err(|(err, _)| err).map(|(v, _)| v))
|
.and_then(|proto| proto.into_future().map_err(|(err, _)| err).map(|(v, _)| v))
|
||||||
.map(|recv_msg| {
|
.map(|recv_msg| {
|
||||||
assert_eq!(recv_msg.unwrap(), msg_server);
|
assert_eq!(recv_msg.unwrap(), msg_server);
|
||||||
@ -504,7 +503,7 @@ mod tests {
|
|||||||
let future = transport
|
let future = transport
|
||||||
.dial(rx.recv().unwrap())
|
.dial(rx.recv().unwrap())
|
||||||
.unwrap_or_else(|_| panic!())
|
.unwrap_or_else(|_| panic!())
|
||||||
.and_then(|proto| proto.0.send(msg_client))
|
.and_then(|proto| proto.send(msg_client))
|
||||||
.map(|_| ());
|
.map(|_| ());
|
||||||
|
|
||||||
let _ = tokio_current_thread::block_on_all(future).unwrap();
|
let _ = tokio_current_thread::block_on_all(future).unwrap();
|
||||||
|
@ -63,7 +63,7 @@
|
|||||||
//! let ping_finished_future = libp2p_tcp_transport::TcpConfig::new()
|
//! let ping_finished_future = libp2p_tcp_transport::TcpConfig::new()
|
||||||
//! .with_upgrade(Ping::default())
|
//! .with_upgrade(Ping::default())
|
||||||
//! .dial("127.0.0.1:12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
//! .dial("127.0.0.1:12345".parse::<libp2p_core::Multiaddr>().unwrap()).unwrap_or_else(|_| panic!())
|
||||||
//! .and_then(|(out, _)| {
|
//! .and_then(|out| {
|
||||||
//! match out {
|
//! match out {
|
||||||
//! PingOutput::Ponger(processing) => Box::new(processing) as Box<Future<Item = _, Error = _> + Send>,
|
//! PingOutput::Ponger(processing) => Box::new(processing) as Box<Future<Item = _, Error = _> + Send>,
|
||||||
//! PingOutput::Pinger(mut pinger) => {
|
//! PingOutput::Pinger(mut pinger) => {
|
||||||
@ -123,7 +123,7 @@ pub enum PingOutput<TSocket, TUserData> {
|
|||||||
Ponger(PingListener<TSocket>),
|
Ponger(PingListener<TSocket>),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<TSocket, TUserData, Maf> ConnectionUpgrade<TSocket, Maf> for Ping<TUserData>
|
impl<TSocket, TUserData> ConnectionUpgrade<TSocket> for Ping<TUserData>
|
||||||
where
|
where
|
||||||
TSocket: AsyncRead + AsyncWrite,
|
TSocket: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
@ -136,8 +136,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = PingOutput<TSocket, TUserData>;
|
type Output = PingOutput<TSocket, TUserData>;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = FutureResult<Self::Output, IoError>;
|
||||||
type Future = FutureResult<(Self::Output, Self::MultiaddrFuture), IoError>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(
|
fn upgrade(
|
||||||
@ -145,14 +144,13 @@ where
|
|||||||
socket: TSocket,
|
socket: TSocket,
|
||||||
_: Self::UpgradeIdentifier,
|
_: Self::UpgradeIdentifier,
|
||||||
endpoint: Endpoint,
|
endpoint: Endpoint,
|
||||||
remote_addr: Maf,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
let out = match endpoint {
|
let out = match endpoint {
|
||||||
Endpoint::Dialer => upgrade_as_dialer(socket),
|
Endpoint::Dialer => upgrade_as_dialer(socket),
|
||||||
Endpoint::Listener => upgrade_as_listener(socket),
|
Endpoint::Listener => upgrade_as_listener(socket),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok((out, remote_addr)).into_future()
|
Ok(out).into_future()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -399,9 +397,8 @@ mod tests {
|
|||||||
use self::tokio_tcp::TcpListener;
|
use self::tokio_tcp::TcpListener;
|
||||||
use self::tokio_tcp::TcpStream;
|
use self::tokio_tcp::TcpStream;
|
||||||
use super::{Ping, PingOutput};
|
use super::{Ping, PingOutput};
|
||||||
use futures::{future, Future, Stream};
|
use futures::{Future, Stream};
|
||||||
use libp2p_core::{ConnectionUpgrade, Endpoint, Multiaddr};
|
use libp2p_core::{ConnectionUpgrade, Endpoint};
|
||||||
use std::io::Error as IoError;
|
|
||||||
|
|
||||||
// TODO: rewrite tests with the MemoryTransport
|
// TODO: rewrite tests with the MemoryTransport
|
||||||
|
|
||||||
@ -419,10 +416,9 @@ mod tests {
|
|||||||
c.unwrap(),
|
c.unwrap(),
|
||||||
(),
|
(),
|
||||||
Endpoint::Listener,
|
Endpoint::Listener,
|
||||||
future::ok::<Multiaddr, IoError>("/ip4/127.0.0.1/tcp/10000".parse().unwrap()),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|(out, _)| match out {
|
.and_then(|out| match out {
|
||||||
PingOutput::Ponger(service) => service,
|
PingOutput::Ponger(service) => service,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
});
|
});
|
||||||
@ -434,10 +430,9 @@ mod tests {
|
|||||||
c,
|
c,
|
||||||
(),
|
(),
|
||||||
Endpoint::Dialer,
|
Endpoint::Dialer,
|
||||||
future::ok::<Multiaddr, IoError>("/ip4/127.0.0.1/tcp/10000".parse().unwrap()),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|(out, _)| match out {
|
.and_then(|out| match out {
|
||||||
PingOutput::Pinger(mut pinger) => {
|
PingOutput::Pinger(mut pinger) => {
|
||||||
pinger.ping(());
|
pinger.ping(());
|
||||||
pinger.into_future().map(|_| ()).map_err(|_| panic!())
|
pinger.into_future().map(|_| ()).map_err(|_| panic!())
|
||||||
@ -464,10 +459,9 @@ mod tests {
|
|||||||
c.unwrap(),
|
c.unwrap(),
|
||||||
(),
|
(),
|
||||||
Endpoint::Listener,
|
Endpoint::Listener,
|
||||||
future::ok::<Multiaddr, IoError>("/ip4/127.0.0.1/tcp/10000".parse().unwrap()),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|(out, _)| match out {
|
.and_then(|out| match out {
|
||||||
PingOutput::Ponger(service) => service,
|
PingOutput::Ponger(service) => service,
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
});
|
});
|
||||||
@ -479,10 +473,9 @@ mod tests {
|
|||||||
c,
|
c,
|
||||||
(),
|
(),
|
||||||
Endpoint::Dialer,
|
Endpoint::Dialer,
|
||||||
future::ok::<Multiaddr, IoError>("/ip4/127.0.0.1/tcp/10000".parse().unwrap()),
|
|
||||||
)
|
)
|
||||||
})
|
})
|
||||||
.and_then(|(out, _)| match out {
|
.and_then(|out| match out {
|
||||||
PingOutput::Pinger(mut pinger) => {
|
PingOutput::Pinger(mut pinger) => {
|
||||||
for n in 0..20 {
|
for n in 0..20 {
|
||||||
pinger.ping(n);
|
pinger.ping(n);
|
||||||
|
@ -58,7 +58,7 @@
|
|||||||
//!
|
//!
|
||||||
//! let future = transport.dial("/ip4/127.0.0.1/tcp/12345".parse::<Multiaddr>().unwrap())
|
//! let future = transport.dial("/ip4/127.0.0.1/tcp/12345".parse::<Multiaddr>().unwrap())
|
||||||
//! .unwrap_or_else(|_| panic!("Unable to dial node"))
|
//! .unwrap_or_else(|_| panic!("Unable to dial node"))
|
||||||
//! .and_then(|(connection, _)| {
|
//! .and_then(|connection| {
|
||||||
//! // Sends "hello world" on the connection, will be encrypted.
|
//! // Sends "hello world" on the connection, will be encrypted.
|
||||||
//! write_all(connection, "hello world")
|
//! write_all(connection, "hello world")
|
||||||
//! });
|
//! });
|
||||||
@ -349,14 +349,12 @@ where
|
|||||||
pub ephemeral_public_key: Vec<u8>,
|
pub ephemeral_public_key: Vec<u8>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<S, Maf> libp2p_core::ConnectionUpgrade<S, Maf> for SecioConfig
|
impl<S> libp2p_core::ConnectionUpgrade<S> for SecioConfig
|
||||||
where
|
where
|
||||||
S: AsyncRead + AsyncWrite + Send + 'static, // TODO: 'static :(
|
S: AsyncRead + AsyncWrite + Send + 'static, // TODO: 'static :(
|
||||||
Maf: Send + 'static, // TODO: 'static :(
|
|
||||||
{
|
{
|
||||||
type Output = SecioOutput<S>;
|
type Output = SecioOutput<S>;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
type Future = Box<Future<Item = (Self::Output, Maf), Error = IoError> + Send>;
|
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
|
|
||||||
@ -371,7 +369,6 @@ where
|
|||||||
incoming: S,
|
incoming: S,
|
||||||
_: (),
|
_: (),
|
||||||
_: libp2p_core::Endpoint,
|
_: libp2p_core::Endpoint,
|
||||||
remote_addr: Maf,
|
|
||||||
) -> Self::Future {
|
) -> Self::Future {
|
||||||
debug!("Starting secio upgrade");
|
debug!("Starting secio upgrade");
|
||||||
|
|
||||||
@ -384,7 +381,7 @@ where
|
|||||||
ephemeral_public_key: ephemeral,
|
ephemeral_public_key: ephemeral,
|
||||||
}
|
}
|
||||||
}).map_err(map_err);
|
}).map_err(map_err);
|
||||||
Box::new(wrapped.map(move |out| (out, remote_addr)))
|
Box::new(wrapped)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,7 +212,6 @@ impl CommonTransport {
|
|||||||
|
|
||||||
impl Transport for CommonTransport {
|
impl Transport for CommonTransport {
|
||||||
type Output = <InnerImplementation as Transport>::Output;
|
type Output = <InnerImplementation as Transport>::Output;
|
||||||
type MultiaddrFuture = <InnerImplementation as Transport>::MultiaddrFuture;
|
|
||||||
type Listener = <InnerImplementation as Transport>::Listener;
|
type Listener = <InnerImplementation as Transport>::Listener;
|
||||||
type ListenerUpgrade = <InnerImplementation as Transport>::ListenerUpgrade;
|
type ListenerUpgrade = <InnerImplementation as Transport>::ListenerUpgrade;
|
||||||
type Dial = <InnerImplementation as Transport>::Dial;
|
type Dial = <InnerImplementation as Transport>::Dial;
|
||||||
|
@ -57,13 +57,12 @@ impl<F> Clone for SimpleProtocol<F> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, F, O, Maf> ConnectionUpgrade<C, Maf> for SimpleProtocol<F>
|
impl<C, F, O> ConnectionUpgrade<C> for SimpleProtocol<F>
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite,
|
C: AsyncRead + AsyncWrite,
|
||||||
F: Fn(C) -> O,
|
F: Fn(C) -> O,
|
||||||
O: IntoFuture<Error = IoError>,
|
O: IntoFuture<Error = IoError>,
|
||||||
O::Future: Send + 'static,
|
O::Future: Send + 'static,
|
||||||
Maf: Send + 'static,
|
|
||||||
{
|
{
|
||||||
type NamesIter = iter::Once<(Bytes, ())>;
|
type NamesIter = iter::Once<(Bytes, ())>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
@ -74,13 +73,12 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = O::Item;
|
type Output = O::Item;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = Box<Future<Item = O::Item, Error = IoError> + Send>;
|
||||||
type Future = Box<Future<Item = (O::Item, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn upgrade(self, socket: C, _: (), _: Endpoint, client_addr: Maf) -> Self::Future {
|
fn upgrade(self, socket: C, _: (), _: Endpoint) -> Self::Future {
|
||||||
let upgrade = &self.upgrade;
|
let upgrade = &self.upgrade;
|
||||||
let fut = upgrade(socket).into_future().from_err().map(move |out| (out, client_addr));
|
let fut = upgrade(socket).into_future().from_err();
|
||||||
Box::new(fut) as Box<_>
|
Box::new(fut) as Box<_>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -98,10 +98,9 @@ where
|
|||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
{
|
{
|
||||||
type Output = T::Output;
|
type Output = T::Output;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
|
||||||
type Listener = T::Listener;
|
type Listener = T::Listener;
|
||||||
type ListenerUpgrade = T::ListenerUpgrade;
|
type ListenerUpgrade = T::ListenerUpgrade;
|
||||||
type Dial = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
type Dial = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
@ -227,9 +226,9 @@ mod tests {
|
|||||||
extern crate libp2p_tcp_transport;
|
extern crate libp2p_tcp_transport;
|
||||||
use self::libp2p_tcp_transport::TcpConfig;
|
use self::libp2p_tcp_transport::TcpConfig;
|
||||||
use futures::future;
|
use futures::future;
|
||||||
|
use swarm::Transport;
|
||||||
use multiaddr::{Protocol, Multiaddr};
|
use multiaddr::{Protocol, Multiaddr};
|
||||||
use std::io::Error as IoError;
|
use std::io::Error as IoError;
|
||||||
use swarm::Transport;
|
|
||||||
use DnsConfig;
|
use DnsConfig;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
@ -238,10 +237,9 @@ mod tests {
|
|||||||
struct CustomTransport;
|
struct CustomTransport;
|
||||||
impl Transport for CustomTransport {
|
impl Transport for CustomTransport {
|
||||||
type Output = <TcpConfig as Transport>::Output;
|
type Output = <TcpConfig as Transport>::Output;
|
||||||
type MultiaddrFuture = <TcpConfig as Transport>::MultiaddrFuture;
|
|
||||||
type Listener = <TcpConfig as Transport>::Listener;
|
type Listener = <TcpConfig as Transport>::Listener;
|
||||||
type ListenerUpgrade = <TcpConfig as Transport>::ListenerUpgrade;
|
type ListenerUpgrade = <TcpConfig as Transport>::ListenerUpgrade;
|
||||||
type Dial = future::Empty<(Self::Output, Self::MultiaddrFuture), IoError>;
|
type Dial = future::Empty<Self::Output, IoError>;
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn listen_on(
|
fn listen_on(
|
||||||
|
@ -119,16 +119,16 @@ impl<C: AsyncRead + AsyncWrite> AsyncWrite for Connection<C> {
|
|||||||
pub struct Listener<T: Transport>(RateLimited<T::Listener>);
|
pub struct Listener<T: Transport>(RateLimited<T::Listener>);
|
||||||
|
|
||||||
impl<T: Transport> Stream for Listener<T> {
|
impl<T: Transport> Stream for Listener<T> {
|
||||||
type Item = ListenerUpgrade<T>;
|
type Item = (ListenerUpgrade<T>, Multiaddr);
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
match try_ready!(self.0.value.poll()) {
|
match try_ready!(self.0.value.poll()) {
|
||||||
Some(upgrade) => {
|
Some((upgrade, addr)) => {
|
||||||
let r = self.0.rlimiter.clone();
|
let r = self.0.rlimiter.clone();
|
||||||
let w = self.0.wlimiter.clone();
|
let w = self.0.wlimiter.clone();
|
||||||
let u = ListenerUpgrade(RateLimited::from_parts(upgrade, r, w));
|
let u = ListenerUpgrade(RateLimited::from_parts(upgrade, r, w));
|
||||||
Ok(Async::Ready(Some(u)))
|
Ok(Async::Ready(Some((u, addr))))
|
||||||
}
|
}
|
||||||
None => Ok(Async::Ready(None)),
|
None => Ok(Async::Ready(None)),
|
||||||
}
|
}
|
||||||
@ -143,14 +143,14 @@ where
|
|||||||
T: Transport + 'static,
|
T: Transport + 'static,
|
||||||
T::Output: AsyncRead + AsyncWrite,
|
T::Output: AsyncRead + AsyncWrite,
|
||||||
{
|
{
|
||||||
type Item = (Connection<T::Output>, T::MultiaddrFuture);
|
type Item = Connection<T::Output>;
|
||||||
type Error = io::Error;
|
type Error = io::Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
||||||
let (conn, addr) = try_ready!(self.0.value.poll());
|
let conn = try_ready!(self.0.value.poll());
|
||||||
let r = self.0.rlimiter.clone();
|
let r = self.0.rlimiter.clone();
|
||||||
let w = self.0.wlimiter.clone();
|
let w = self.0.wlimiter.clone();
|
||||||
Ok(Async::Ready((Connection::new(conn, r, w)?, addr)))
|
Ok(Async::Ready(Connection::new(conn, r, w)?))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,14 +158,12 @@ impl<T> Transport for RateLimited<T>
|
|||||||
where
|
where
|
||||||
T: Transport + 'static,
|
T: Transport + 'static,
|
||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: AsyncRead + AsyncWrite + Send,
|
T::Output: AsyncRead + AsyncWrite + Send,
|
||||||
{
|
{
|
||||||
type Output = Connection<T::Output>;
|
type Output = Connection<T::Output>;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
|
||||||
type Listener = Listener<T>;
|
type Listener = Listener<T>;
|
||||||
type ListenerUpgrade = ListenerUpgrade<T>;
|
type ListenerUpgrade = ListenerUpgrade<T>;
|
||||||
type Dial = Box<Future<Item = (Connection<T::Output>, Self::MultiaddrFuture), Error = io::Error> + Send>;
|
type Dial = Box<Future<Item = Connection<T::Output>, Error = io::Error> + Send>;
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)>
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)>
|
||||||
where
|
where
|
||||||
@ -197,7 +195,7 @@ where
|
|||||||
.dial(addr)
|
.dial(addr)
|
||||||
.map(move |dial| {
|
.map(move |dial| {
|
||||||
let future = dial
|
let future = dial
|
||||||
.and_then(move |(conn, addr)| Ok((Connection::new(conn, r, w)?, addr)));
|
.and_then(move |conn| Ok(Connection::new(conn, r, w)?));
|
||||||
Box::new(future) as Box<_>
|
Box::new(future) as Box<_>
|
||||||
})
|
})
|
||||||
.map_err(|(transport, a)| (RateLimited::from_parts(transport, r2, w2), a))
|
.map_err(|(transport, a)| (RateLimited::from_parts(transport, r2, w2), a))
|
||||||
|
@ -49,18 +49,16 @@ pub enum Output<C> {
|
|||||||
Sealed(Box<Future<Item=(), Error=io::Error> + Send>)
|
Sealed(Box<Future<Item=(), Error=io::Error> + Send>)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<C, T, P, S, Maf> ConnectionUpgrade<C, Maf> for RelayConfig<T, P>
|
impl<C, T, P, S> ConnectionUpgrade<C> for RelayConfig<T, P>
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static,
|
C: AsyncRead + AsyncWrite + Send + 'static,
|
||||||
T: Transport + Clone + Send + 'static,
|
T: Transport + Clone + Send + 'static,
|
||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: AsyncRead + AsyncWrite + Send,
|
T::Output: AsyncRead + AsyncWrite + Send,
|
||||||
P: Deref<Target=S> + Clone + Send + 'static,
|
P: Deref<Target=S> + Clone + Send + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
Maf: Send + 'static,
|
|
||||||
for<'a> &'a S: Peerstore
|
for<'a> &'a S: Peerstore
|
||||||
{
|
{
|
||||||
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
||||||
@ -71,10 +69,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = Output<C>;
|
type Output = Output<C>;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type Future = Box<Future<Item=(Self::Output, Maf), Error=io::Error> + Send>;
|
|
||||||
|
|
||||||
fn upgrade(self, conn: C, _: (), _: Endpoint, remote_addr: Maf) -> Self::Future {
|
fn upgrade(self, conn: C, _: (), _: Endpoint) -> Self::Future {
|
||||||
let future = Io::new(conn).recv().and_then(move |(message, io)| {
|
let future = Io::new(conn).recv().and_then(move |(message, io)| {
|
||||||
let msg = if let Some(m) = message {
|
let msg = if let Some(m) = message {
|
||||||
m
|
m
|
||||||
@ -95,7 +92,7 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Box::new(future.map(move |out| (out, remote_addr)))
|
Box::new(future)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,7 +102,6 @@ where
|
|||||||
T::Dial: Send, // TODO: remove
|
T::Dial: Send, // TODO: remove
|
||||||
T::Listener: Send, // TODO: remove
|
T::Listener: Send, // TODO: remove
|
||||||
T::ListenerUpgrade: Send, // TODO: remove
|
T::ListenerUpgrade: Send, // TODO: remove
|
||||||
T::MultiaddrFuture: Send, // TODO: remove
|
|
||||||
T::Output: Send + AsyncRead + AsyncWrite,
|
T::Output: Send + AsyncRead + AsyncWrite,
|
||||||
P: Deref<Target = S> + Clone + 'static,
|
P: Deref<Target = S> + Clone + 'static,
|
||||||
for<'a> &'a S: Peerstore,
|
for<'a> &'a S: Peerstore,
|
||||||
@ -158,7 +154,7 @@ where
|
|||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(err, _stream)| err)
|
.map_err(|(err, _stream)| err)
|
||||||
.and_then(move |(ok, _stream)| {
|
.and_then(move |(ok, _stream)| {
|
||||||
if let Some((c, a)) = ok {
|
if let Some(c) = ok {
|
||||||
// send STOP message to destination and expect back a SUCCESS message
|
// send STOP message to destination and expect back a SUCCESS message
|
||||||
let future = Io::new(c).send(stop)
|
let future = Io::new(c).send(stop)
|
||||||
.and_then(Io::recv)
|
.and_then(Io::recv)
|
||||||
@ -168,7 +164,7 @@ where
|
|||||||
None => return Err(io_err("no message from destination"))
|
None => return Err(io_err("no message from destination"))
|
||||||
};
|
};
|
||||||
if is_success(&rsp) {
|
if is_success(&rsp) {
|
||||||
Ok((io.into(), a))
|
Ok(io.into())
|
||||||
} else {
|
} else {
|
||||||
Err(io_err("no success response from relay"))
|
Err(io_err("no success response from relay"))
|
||||||
}
|
}
|
||||||
@ -181,7 +177,7 @@ where
|
|||||||
// signal success or failure to source
|
// signal success or failure to source
|
||||||
.then(move |result| {
|
.then(move |result| {
|
||||||
match result {
|
match result {
|
||||||
Ok((c, _)) => {
|
Ok(c) => {
|
||||||
let msg = status(CircuitRelay_Status::SUCCESS);
|
let msg = status(CircuitRelay_Status::SUCCESS);
|
||||||
A(io.send(msg).map(|io| (io.into(), c)))
|
A(io.send(msg).map(|io| (io.into(), c)))
|
||||||
}
|
}
|
||||||
@ -251,7 +247,7 @@ fn stop_message(from: &Peer, dest: &Peer) -> CircuitRelay {
|
|||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
struct TrivialUpgrade;
|
struct TrivialUpgrade;
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for TrivialUpgrade
|
impl<C> ConnectionUpgrade<C> for TrivialUpgrade
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + 'static
|
C: AsyncRead + AsyncWrite + 'static
|
||||||
{
|
{
|
||||||
@ -263,21 +259,19 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = C;
|
type Output = C;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = FutureResult<Self::Output, io::Error>;
|
||||||
type Future = FutureResult<(Self::Output, Maf), io::Error>;
|
|
||||||
|
|
||||||
fn upgrade(self, conn: C, _: (), _: Endpoint, remote_addr: Maf) -> Self::Future {
|
fn upgrade(self, conn: C, _: (), _: Endpoint) -> Self::Future {
|
||||||
future::ok((conn, remote_addr))
|
future::ok(conn)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) struct Source(pub(crate) CircuitRelay);
|
pub(crate) struct Source(pub(crate) CircuitRelay);
|
||||||
|
|
||||||
impl<C, Maf> ConnectionUpgrade<C, Maf> for Source
|
impl<C> ConnectionUpgrade<C> for Source
|
||||||
where
|
where
|
||||||
C: AsyncRead + AsyncWrite + Send + 'static,
|
C: AsyncRead + AsyncWrite + Send + 'static,
|
||||||
Maf: Send + 'static,
|
|
||||||
{
|
{
|
||||||
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
type NamesIter = iter::Once<(Bytes, Self::UpgradeIdentifier)>;
|
||||||
type UpgradeIdentifier = ();
|
type UpgradeIdentifier = ();
|
||||||
@ -287,10 +281,9 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
type Output = C;
|
type Output = C;
|
||||||
type MultiaddrFuture = Maf;
|
type Future = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type Future = Box<Future<Item=(Self::Output, Maf), Error=io::Error> + Send>;
|
|
||||||
|
|
||||||
fn upgrade(self, conn: C, _: (), _: Endpoint, remote_addr: Maf) -> Self::Future {
|
fn upgrade(self, conn: C, _: (), _: Endpoint) -> Self::Future {
|
||||||
let future = Io::new(conn)
|
let future = Io::new(conn)
|
||||||
.send(self.0)
|
.send(self.0)
|
||||||
.and_then(Io::recv)
|
.and_then(Io::recv)
|
||||||
@ -305,7 +298,7 @@ where
|
|||||||
Err(io_err("no success response from relay"))
|
Err(io_err("no success response from relay"))
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
Box::new(future.map(move |out| (out, remote_addr)))
|
Box::new(future)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,17 +43,15 @@ where
|
|||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: AsyncRead + AsyncWrite + Send,
|
T::Output: AsyncRead + AsyncWrite + Send,
|
||||||
P: Deref<Target=S> + Clone + 'static,
|
P: Deref<Target=S> + Clone + 'static,
|
||||||
S: 'static,
|
S: 'static,
|
||||||
for<'a> &'a S: Peerstore
|
for<'a> &'a S: Peerstore
|
||||||
{
|
{
|
||||||
type Output = T::Output;
|
type Output = T::Output;
|
||||||
type MultiaddrFuture = T::MultiaddrFuture;
|
type Listener = Box<Stream<Item=(Self::ListenerUpgrade, Multiaddr), Error=io::Error> + Send>;
|
||||||
type Listener = Box<Stream<Item=Self::ListenerUpgrade, Error=io::Error> + Send>;
|
type ListenerUpgrade = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type ListenerUpgrade = Box<Future<Item=(Self::Output, Self::MultiaddrFuture), Error=io::Error> + Send>;
|
type Dial = Box<Future<Item=Self::Output, Error=io::Error> + Send>;
|
||||||
type Dial = Box<Future<Item=(Self::Output, Self::MultiaddrFuture), Error=io::Error> + Send>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
Err((self, addr))
|
Err((self, addr))
|
||||||
@ -92,7 +90,6 @@ where
|
|||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Output: AsyncRead + AsyncWrite + Send,
|
T::Output: AsyncRead + AsyncWrite + Send,
|
||||||
P: Deref<Target=S> + Clone + 'static,
|
P: Deref<Target=S> + Clone + 'static,
|
||||||
for<'a> &'a S: Peerstore
|
for<'a> &'a S: Peerstore
|
||||||
@ -114,7 +111,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relay to destination over any available relay node.
|
// Relay to destination over any available relay node.
|
||||||
fn relay_to(self, destination: &Peer) -> Result<impl Future<Item=(T::Output, T::MultiaddrFuture), Error=io::Error>, Self> {
|
fn relay_to(self, destination: &Peer) -> Result<impl Future<Item=T::Output, Error=io::Error>, Self> {
|
||||||
trace!("relay_to {:?}", destination.id);
|
trace!("relay_to {:?}", destination.id);
|
||||||
let mut dials = Vec::new();
|
let mut dials = Vec::new();
|
||||||
for relay in &*self.relays {
|
for relay in &*self.relays {
|
||||||
@ -152,7 +149,7 @@ where
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Relay to destination via the given peer.
|
// Relay to destination via the given peer.
|
||||||
fn relay_via(self, relay: &Peer, destination: &Peer) -> Result<impl Future<Item=(T::Output, T::MultiaddrFuture), Error=io::Error>, Self> {
|
fn relay_via(self, relay: &Peer, destination: &Peer) -> Result<impl Future<Item=T::Output, Error=io::Error>, Self> {
|
||||||
trace!("relay_via {:?} to {:?}", relay.id, destination.id);
|
trace!("relay_via {:?} to {:?}", relay.id, destination.id);
|
||||||
let mut addresses = Vec::new();
|
let mut addresses = Vec::new();
|
||||||
|
|
||||||
@ -183,9 +180,9 @@ where
|
|||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(err, _stream)| err)
|
.map_err(|(err, _stream)| err)
|
||||||
.and_then(move |(ok, _stream)| match ok {
|
.and_then(move |(ok, _stream)| match ok {
|
||||||
Some((out, addr)) => {
|
Some(out) => {
|
||||||
debug!("connected");
|
debug!("connected");
|
||||||
Ok((out, addr))
|
Ok(out)
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
info!("failed to dial to {:?}", relay.id);
|
info!("failed to dial to {:?}", relay.id);
|
||||||
|
@ -134,8 +134,7 @@ impl TcpConfig {
|
|||||||
impl Transport for TcpConfig {
|
impl Transport for TcpConfig {
|
||||||
type Output = TcpTransStream;
|
type Output = TcpTransStream;
|
||||||
type Listener = TcpListenStream;
|
type Listener = TcpListenStream;
|
||||||
type ListenerUpgrade = FutureResult<(Self::Output, Self::MultiaddrFuture), IoError>;
|
type ListenerUpgrade = FutureResult<Self::Output, IoError>;
|
||||||
type MultiaddrFuture = FutureResult<Multiaddr, IoError>;
|
|
||||||
type Dial = TcpDialFut;
|
type Dial = TcpDialFut;
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
@ -181,7 +180,6 @@ impl Transport for TcpConfig {
|
|||||||
Ok(TcpDialFut {
|
Ok(TcpDialFut {
|
||||||
inner: TcpStream::connect(&socket_addr),
|
inner: TcpStream::connect(&socket_addr),
|
||||||
config: self,
|
config: self,
|
||||||
addr: Some(addr),
|
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
debug!("Instantly refusing dialing {}, as it is invalid", addr);
|
debug!("Instantly refusing dialing {}, as it is invalid", addr);
|
||||||
@ -260,32 +258,21 @@ pub struct TcpDialFut {
|
|||||||
inner: ConnectFuture,
|
inner: ConnectFuture,
|
||||||
/// Original configuration.
|
/// Original configuration.
|
||||||
config: TcpConfig,
|
config: TcpConfig,
|
||||||
/// Address we're dialing. Extracted when the `Future` finishes.
|
|
||||||
addr: Option<Multiaddr>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Future for TcpDialFut {
|
impl Future for TcpDialFut {
|
||||||
type Item = (TcpTransStream, FutureResult<Multiaddr, IoError>);
|
type Item = TcpTransStream;
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<(TcpTransStream, FutureResult<Multiaddr, IoError>), IoError> {
|
fn poll(&mut self) -> Poll<TcpTransStream, IoError> {
|
||||||
match self.inner.poll() {
|
match self.inner.poll() {
|
||||||
Ok(Async::Ready(stream)) => {
|
Ok(Async::Ready(stream)) => {
|
||||||
apply_config(&self.config, &stream)?;
|
apply_config(&self.config, &stream)?;
|
||||||
let addr = self
|
Ok(Async::Ready(TcpTransStream { inner: stream }))
|
||||||
.addr
|
|
||||||
.take()
|
|
||||||
.expect("TcpDialFut polled again after finished");
|
|
||||||
let out = TcpTransStream { inner: stream };
|
|
||||||
Ok(Async::Ready((out, future::ok(addr))))
|
|
||||||
}
|
}
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
Ok(Async::NotReady) => Ok(Async::NotReady),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let addr = self
|
debug!("Error while dialing => {:?}", err);
|
||||||
.addr
|
|
||||||
.as_ref()
|
|
||||||
.expect("TcpDialFut polled again after finished");
|
|
||||||
debug!("Error while dialing {:?} => {:?}", addr, err);
|
|
||||||
Err(err)
|
Err(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -300,13 +287,13 @@ pub struct TcpListenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Stream for TcpListenStream {
|
impl Stream for TcpListenStream {
|
||||||
type Item = FutureResult<(TcpTransStream, FutureResult<Multiaddr, IoError>), IoError>;
|
type Item = (FutureResult<TcpTransStream, IoError>, Multiaddr);
|
||||||
type Error = IoError;
|
type Error = IoError;
|
||||||
|
|
||||||
fn poll(
|
fn poll(
|
||||||
&mut self,
|
&mut self,
|
||||||
) -> Poll<
|
) -> Poll<
|
||||||
Option<FutureResult<(TcpTransStream, FutureResult<Multiaddr, IoError>), IoError>>,
|
Option<(FutureResult<TcpTransStream, IoError>, Multiaddr)>,
|
||||||
IoError,
|
IoError,
|
||||||
> {
|
> {
|
||||||
let inner = match self.inner {
|
let inner = match self.inner {
|
||||||
@ -316,28 +303,36 @@ impl Stream for TcpListenStream {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match inner.poll() {
|
loop {
|
||||||
Ok(Async::Ready(Some(sock))) => {
|
match inner.poll() {
|
||||||
match apply_config(&self.config, &sock) {
|
Ok(Async::Ready(Some(sock))) => {
|
||||||
Ok(()) => (),
|
let addr = match sock.peer_addr() {
|
||||||
Err(err) => return Ok(Async::Ready(Some(future::err(err)))),
|
// TODO: remove this expect()
|
||||||
};
|
Ok(addr) => addr
|
||||||
|
.to_multiaddr()
|
||||||
|
.expect("generating a multiaddr from a socket addr never fails"),
|
||||||
|
Err(err) => {
|
||||||
|
// If we can't get the address of the newly-opened socket, there's
|
||||||
|
// nothing we can except ignore this connection attempt.
|
||||||
|
error!("Ignored incoming because could't determine its \
|
||||||
|
address: {:?}", err);
|
||||||
|
continue
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
let addr = match sock.peer_addr() {
|
match apply_config(&self.config, &sock) {
|
||||||
// TODO: remove this expect()
|
Ok(()) => (),
|
||||||
Ok(addr) => addr
|
Err(err) => return Ok(Async::Ready(Some((future::err(err), addr)))),
|
||||||
.to_multiaddr()
|
};
|
||||||
.expect("generating a multiaddr from a socket addr never fails"),
|
|
||||||
Err(err) => return Ok(Async::Ready(Some(future::err(err)))),
|
|
||||||
};
|
|
||||||
|
|
||||||
debug!("Incoming connection from {}", addr);
|
debug!("Incoming connection from {}", addr);
|
||||||
let ret = future::ok((TcpTransStream { inner: sock }, future::ok(addr)));
|
let ret = future::ok(TcpTransStream { inner: sock });
|
||||||
Ok(Async::Ready(Some(ret)))
|
break Ok(Async::Ready(Some((ret, addr))))
|
||||||
|
}
|
||||||
|
Ok(Async::Ready(None)) => break Ok(Async::Ready(None)),
|
||||||
|
Ok(Async::NotReady) => break Ok(Async::NotReady),
|
||||||
|
Err(()) => unreachable!("sleep_on_error never produces an error"),
|
||||||
}
|
}
|
||||||
Ok(Async::Ready(None)) => Ok(Async::Ready(None)),
|
|
||||||
Ok(Async::NotReady) => Ok(Async::NotReady),
|
|
||||||
Err(()) => unreachable!("sleep_on_error never produces an error"),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -465,8 +460,8 @@ mod tests {
|
|||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let addr = "/ip4/127.0.0.1/tcp/12345".parse::<Multiaddr>().unwrap();
|
let addr = "/ip4/127.0.0.1/tcp/12345".parse::<Multiaddr>().unwrap();
|
||||||
let tcp = TcpConfig::new();
|
let tcp = TcpConfig::new();
|
||||||
let listener = tcp.listen_on(addr).unwrap().0.for_each(|sock| {
|
let listener = tcp.listen_on(addr).unwrap().0.for_each(|(sock, _)| {
|
||||||
sock.and_then(|(sock, _)| {
|
sock.and_then(|sock| {
|
||||||
// Define what to do with the socket that just connected to us
|
// Define what to do with the socket that just connected to us
|
||||||
// Which in this case is read 3 bytes
|
// Which in this case is read 3 bytes
|
||||||
let handle_conn = tokio_io::io::read_exact(sock, [0; 3])
|
let handle_conn = tokio_io::io::read_exact(sock, [0; 3])
|
||||||
@ -489,7 +484,7 @@ mod tests {
|
|||||||
let socket = tcp.dial(addr.clone()).unwrap();
|
let socket = tcp.dial(addr.clone()).unwrap();
|
||||||
// Define what to do with the socket once it's obtained
|
// Define what to do with the socket once it's obtained
|
||||||
let action = socket.then(|sock| -> Result<(), ()> {
|
let action = socket.then(|sock| -> Result<(), ()> {
|
||||||
sock.unwrap().0.write(&[0x1, 0x2, 0x3]).unwrap();
|
sock.unwrap().write(&[0x1, 0x2, 0x3]).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
// Execute the future in our event loop
|
// Execute the future in our event loop
|
||||||
|
@ -31,7 +31,7 @@ extern crate log;
|
|||||||
extern crate tokio_timer;
|
extern crate tokio_timer;
|
||||||
|
|
||||||
use futures::{Async, Future, Poll, Stream};
|
use futures::{Async, Future, Poll, Stream};
|
||||||
use libp2p_core::{Multiaddr, MuxedTransport, Transport};
|
use libp2p_core::{Multiaddr, Transport};
|
||||||
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio_timer::Timeout;
|
use tokio_timer::Timeout;
|
||||||
@ -85,7 +85,6 @@ where
|
|||||||
InnerTrans: Transport,
|
InnerTrans: Transport,
|
||||||
{
|
{
|
||||||
type Output = InnerTrans::Output;
|
type Output = InnerTrans::Output;
|
||||||
type MultiaddrFuture = InnerTrans::MultiaddrFuture;
|
|
||||||
type Listener = TimeoutListener<InnerTrans::Listener>;
|
type Listener = TimeoutListener<InnerTrans::Listener>;
|
||||||
type ListenerUpgrade = TokioTimerMapErr<Timeout<InnerTrans::ListenerUpgrade>>;
|
type ListenerUpgrade = TokioTimerMapErr<Timeout<InnerTrans::ListenerUpgrade>>;
|
||||||
type Dial = TokioTimerMapErr<Timeout<InnerTrans::Dial>>;
|
type Dial = TokioTimerMapErr<Timeout<InnerTrans::Dial>>;
|
||||||
@ -135,22 +134,6 @@ where
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<InnerTrans> MuxedTransport for TransportTimeout<InnerTrans>
|
|
||||||
where
|
|
||||||
InnerTrans: MuxedTransport,
|
|
||||||
{
|
|
||||||
type Incoming = TimeoutIncoming<InnerTrans::Incoming>;
|
|
||||||
type IncomingUpgrade = TokioTimerMapErr<Timeout<InnerTrans::IncomingUpgrade>>;
|
|
||||||
|
|
||||||
#[inline]
|
|
||||||
fn next_incoming(self) -> Self::Incoming {
|
|
||||||
TimeoutIncoming {
|
|
||||||
inner: self.inner.next_incoming(),
|
|
||||||
timeout: self.incoming_timeout,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: can be removed and replaced with an `impl Stream` once impl Trait is fully stable
|
// TODO: can be removed and replaced with an `impl Stream` once impl Trait is fully stable
|
||||||
// in Rust (https://github.com/rust-lang/rust/issues/34511)
|
// in Rust (https://github.com/rust-lang/rust/issues/34511)
|
||||||
pub struct TimeoutListener<InnerStream> {
|
pub struct TimeoutListener<InnerStream> {
|
||||||
@ -158,50 +141,26 @@ pub struct TimeoutListener<InnerStream> {
|
|||||||
timeout: Duration,
|
timeout: Duration,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<InnerStream> Stream for TimeoutListener<InnerStream>
|
impl<InnerStream, O> Stream for TimeoutListener<InnerStream>
|
||||||
where
|
where
|
||||||
InnerStream: Stream,
|
InnerStream: Stream<Item = (O, Multiaddr)>,
|
||||||
{
|
{
|
||||||
type Item = TokioTimerMapErr<Timeout<InnerStream::Item>>;
|
type Item = (TokioTimerMapErr<Timeout<O>>, Multiaddr);
|
||||||
type Error = InnerStream::Error;
|
type Error = InnerStream::Error;
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
fn poll(&mut self) -> Poll<Option<Self::Item>, Self::Error> {
|
||||||
let inner_fut = try_ready!(self.inner.poll());
|
let poll_out = try_ready!(self.inner.poll());
|
||||||
if let Some(inner_fut) = inner_fut {
|
if let Some((inner_fut, addr)) = poll_out {
|
||||||
let fut = TokioTimerMapErr {
|
let fut = TokioTimerMapErr {
|
||||||
inner: Timeout::new(inner_fut, self.timeout),
|
inner: Timeout::new(inner_fut, self.timeout),
|
||||||
};
|
};
|
||||||
Ok(Async::Ready(Some(fut)))
|
Ok(Async::Ready(Some((fut, addr))))
|
||||||
} else {
|
} else {
|
||||||
Ok(Async::Ready(None))
|
Ok(Async::Ready(None))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: can be removed and replaced with an `impl Future` once impl Trait is fully stable
|
|
||||||
// in Rust (https://github.com/rust-lang/rust/issues/34511)
|
|
||||||
#[must_use = "futures do nothing unless polled"]
|
|
||||||
pub struct TimeoutIncoming<InnerFut> {
|
|
||||||
inner: InnerFut,
|
|
||||||
timeout: Duration,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<InnerFut> Future for TimeoutIncoming<InnerFut>
|
|
||||||
where
|
|
||||||
InnerFut: Future,
|
|
||||||
{
|
|
||||||
type Item = TokioTimerMapErr<Timeout<InnerFut::Item>>;
|
|
||||||
type Error = InnerFut::Error;
|
|
||||||
|
|
||||||
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
||||||
let inner_fut = try_ready!(self.inner.poll());
|
|
||||||
let fut = TokioTimerMapErr {
|
|
||||||
inner: Timeout::new(inner_fut, self.timeout),
|
|
||||||
};
|
|
||||||
Ok(Async::Ready(fut))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Wraps around a `Future`. Turns the error type from `TimeoutError<IoError>` to `IoError`.
|
/// Wraps around a `Future`. Turns the error type from `TimeoutError<IoError>` to `IoError`.
|
||||||
// TODO: can be replaced with `impl Future` once `impl Trait` are fully stable in Rust
|
// TODO: can be replaced with `impl Future` once `impl Trait` are fully stable in Rust
|
||||||
// (https://github.com/rust-lang/rust/issues/34511)
|
// (https://github.com/rust-lang/rust/issues/34511)
|
||||||
|
@ -86,10 +86,9 @@ impl UdsConfig {
|
|||||||
|
|
||||||
impl Transport for UdsConfig {
|
impl Transport for UdsConfig {
|
||||||
type Output = UnixStream;
|
type Output = UnixStream;
|
||||||
type Listener = Box<Stream<Item = Self::ListenerUpgrade, Error = IoError> + Send + Sync>;
|
type Listener = Box<Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = IoError> + Send + Sync>;
|
||||||
type ListenerUpgrade = FutureResult<(Self::Output, Self::MultiaddrFuture), IoError>;
|
type ListenerUpgrade = FutureResult<Self::Output, IoError>;
|
||||||
type MultiaddrFuture = FutureResult<Multiaddr, IoError>;
|
type Dial = Box<Future<Item = UnixStream, Error = IoError> + Send + Sync>; // TODO: name this type
|
||||||
type Dial = Box<Future<Item = (UnixStream, Self::MultiaddrFuture), Error = IoError> + Send + Sync>;
|
|
||||||
|
|
||||||
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, addr: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
if let Ok(path) = multiaddr_to_path(&addr) {
|
if let Ok(path) = multiaddr_to_path(&addr) {
|
||||||
@ -109,7 +108,7 @@ impl Transport for UdsConfig {
|
|||||||
// Pull out a stream of sockets for incoming connections
|
// Pull out a stream of sockets for incoming connections
|
||||||
listener.incoming().map(move |sock| {
|
listener.incoming().map(move |sock| {
|
||||||
debug!("Incoming connection on {}", addr);
|
debug!("Incoming connection on {}", addr);
|
||||||
future::ok((sock, future::ok(addr.clone())))
|
(future::ok(sock), addr.clone())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
.flatten_stream();
|
.flatten_stream();
|
||||||
@ -122,7 +121,7 @@ impl Transport for UdsConfig {
|
|||||||
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, (Self, Multiaddr)> {
|
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, (Self, Multiaddr)> {
|
||||||
if let Ok(path) = multiaddr_to_path(&addr) {
|
if let Ok(path) = multiaddr_to_path(&addr) {
|
||||||
debug!("Dialing {}", addr);
|
debug!("Dialing {}", addr);
|
||||||
let fut = UnixStream::connect(&path).map(|t| (t, future::ok(addr)));
|
let fut = UnixStream::connect(&path);
|
||||||
Ok(Box::new(fut) as Box<_>)
|
Ok(Box::new(fut) as Box<_>)
|
||||||
} else {
|
} else {
|
||||||
Err((self, addr))
|
Err((self, addr))
|
||||||
@ -203,8 +202,8 @@ mod tests {
|
|||||||
|
|
||||||
std::thread::spawn(move || {
|
std::thread::spawn(move || {
|
||||||
let tcp = UdsConfig::new();
|
let tcp = UdsConfig::new();
|
||||||
let listener = tcp.listen_on(addr2).unwrap().0.for_each(|sock| {
|
let listener = tcp.listen_on(addr2).unwrap().0.for_each(|(sock, _)| {
|
||||||
sock.and_then(|(sock, _)| {
|
sock.and_then(|sock| {
|
||||||
// Define what to do with the socket that just connected to us
|
// Define what to do with the socket that just connected to us
|
||||||
// Which in this case is read 3 bytes
|
// Which in this case is read 3 bytes
|
||||||
let handle_conn = tokio_io::io::read_exact(sock, [0; 3])
|
let handle_conn = tokio_io::io::read_exact(sock, [0; 3])
|
||||||
@ -226,7 +225,7 @@ mod tests {
|
|||||||
let socket = tcp.dial(addr.clone()).unwrap();
|
let socket = tcp.dial(addr.clone()).unwrap();
|
||||||
// Define what to do with the socket once it's obtained
|
// Define what to do with the socket once it's obtained
|
||||||
let action = socket.then(|sock| -> Result<(), ()> {
|
let action = socket.then(|sock| -> Result<(), ()> {
|
||||||
sock.unwrap().0.write(&[0x1, 0x2, 0x3]).unwrap();
|
sock.unwrap().write(&[0x1, 0x2, 0x3]).unwrap();
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
// Execute the future in our event loop
|
// Execute the future in our event loop
|
||||||
|
@ -20,7 +20,7 @@
|
|||||||
|
|
||||||
use futures::stream::Then as StreamThen;
|
use futures::stream::Then as StreamThen;
|
||||||
use futures::sync::{mpsc, oneshot};
|
use futures::sync::{mpsc, oneshot};
|
||||||
use futures::{future, future::FutureResult, Async, Future, Poll, Stream};
|
use futures::{Async, Future, Poll, Stream};
|
||||||
use multiaddr::{Protocol, Multiaddr};
|
use multiaddr::{Protocol, Multiaddr};
|
||||||
use rw_stream_sink::RwStreamSink;
|
use rw_stream_sink::RwStreamSink;
|
||||||
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
use std::io::{Error as IoError, ErrorKind as IoErrorKind};
|
||||||
@ -53,11 +53,9 @@ impl BrowserWsConfig {
|
|||||||
|
|
||||||
impl Transport for BrowserWsConfig {
|
impl Transport for BrowserWsConfig {
|
||||||
type Output = BrowserWsConn;
|
type Output = BrowserWsConn;
|
||||||
type MultiaddrFuture = FutureResult<Multiaddr, IoError>;
|
type Listener = Box<Stream<Item = (Self::ListenerUpgrade, Multiaddr), Error = IoError> + Send>; // TODO: use `!`
|
||||||
type Listener = Box<Stream<Item = Self::ListenerUpgrade, Error = IoError> + Send>; // TODO: use `!`
|
type ListenerUpgrade = Box<Future<Item = Self::Output, Error = IoError> + Send>; // TODO: use `!`
|
||||||
type ListenerUpgrade =
|
type Dial = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>; // TODO: use `!`
|
|
||||||
type Dial = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn listen_on(self, a: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
fn listen_on(self, a: Multiaddr) -> Result<(Self::Listener, Multiaddr), (Self, Multiaddr)> {
|
||||||
@ -196,7 +194,7 @@ impl Transport for BrowserWsConfig {
|
|||||||
|
|
||||||
Ok(Box::new(open_rx.then(|result| {
|
Ok(Box::new(open_rx.then(|result| {
|
||||||
match result {
|
match result {
|
||||||
Ok(Ok(r)) => Ok((r, future::ok(original_addr))),
|
Ok(Ok(r)) => Ok(r),
|
||||||
Ok(Err(e)) => Err(e),
|
Ok(Err(e)) => Err(e),
|
||||||
// `Err` would happen here if `open_tx` is destroyed. `open_tx` is captured by
|
// `Err` would happen here if `open_tx` is destroyed. `open_tx` is captured by
|
||||||
// the `WebSocket`, and the `WebSocket` is captured by `open_cb`, which is itself
|
// the `WebSocket`, and the `WebSocket` is captured by `open_cb`, which is itself
|
||||||
|
@ -60,19 +60,16 @@ where
|
|||||||
// TODO: this 'static is pretty arbitrary and is necessary because of the websocket library
|
// TODO: this 'static is pretty arbitrary and is necessary because of the websocket library
|
||||||
T: Transport + 'static,
|
T: Transport + 'static,
|
||||||
T::Dial: Send,
|
T::Dial: Send,
|
||||||
T::MultiaddrFuture: Send,
|
|
||||||
T::Listener: Send,
|
T::Listener: Send,
|
||||||
T::ListenerUpgrade: Send,
|
T::ListenerUpgrade: Send,
|
||||||
// TODO: this Send is pretty arbitrary and is necessary because of the websocket library
|
// TODO: this Send is pretty arbitrary and is necessary because of the websocket library
|
||||||
T::Output: AsyncRead + AsyncWrite + Send,
|
T::Output: AsyncRead + AsyncWrite + Send,
|
||||||
{
|
{
|
||||||
type Output = Box<AsyncStream + Send>;
|
type Output = Box<AsyncStream + Send>;
|
||||||
type MultiaddrFuture = Box<Future<Item = Multiaddr, Error = IoError> + Send>;
|
|
||||||
type Listener =
|
type Listener =
|
||||||
stream::Map<T::Listener, fn(<T as Transport>::ListenerUpgrade) -> Self::ListenerUpgrade>;
|
stream::Map<T::Listener, fn((<T as Transport>::ListenerUpgrade, Multiaddr)) -> (Self::ListenerUpgrade, Multiaddr)>;
|
||||||
type ListenerUpgrade =
|
type ListenerUpgrade = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
type Dial = Box<Future<Item = Self::Output, Error = IoError> + Send>;
|
||||||
type Dial = Box<Future<Item = (Self::Output, Self::MultiaddrFuture), Error = IoError> + Send>;
|
|
||||||
|
|
||||||
fn listen_on(
|
fn listen_on(
|
||||||
self,
|
self,
|
||||||
@ -102,14 +99,12 @@ where
|
|||||||
|
|
||||||
debug!("Listening on {}", new_addr);
|
debug!("Listening on {}", new_addr);
|
||||||
|
|
||||||
let listen = inner_listen.map::<_, fn(_) -> _>(|stream| {
|
let listen = inner_listen.map::<_, fn(_) -> _>(|(stream, mut client_addr)| {
|
||||||
|
// Need to suffix `/ws` to each client address.
|
||||||
|
client_addr.append(Protocol::Ws);
|
||||||
|
|
||||||
// Upgrade the listener to websockets like the websockets library requires us to do.
|
// Upgrade the listener to websockets like the websockets library requires us to do.
|
||||||
let upgraded = stream.and_then(|(stream, client_addr)| {
|
let upgraded = stream.and_then(move |stream| {
|
||||||
// Need to suffix `/ws` to each client address.
|
|
||||||
let client_addr = client_addr.map(|mut addr| {
|
|
||||||
addr.append(Protocol::Ws);
|
|
||||||
addr
|
|
||||||
});
|
|
||||||
debug!("Incoming connection");
|
debug!("Incoming connection");
|
||||||
|
|
||||||
stream
|
stream
|
||||||
@ -149,10 +144,9 @@ where
|
|||||||
.map(|s| Box::new(Ok(s).into_future()) as Box<Future<Item = _, Error = _> + Send>)
|
.map(|s| Box::new(Ok(s).into_future()) as Box<Future<Item = _, Error = _> + Send>)
|
||||||
.into_future()
|
.into_future()
|
||||||
.flatten()
|
.flatten()
|
||||||
.map(move |v| (v, Box::new(client_addr) as Box<Future<Item = _, Error = _> + Send>))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Box::new(upgraded) as Box<Future<Item = _, Error = _> + Send>
|
(Box::new(upgraded) as Box<Future<Item = _, Error = _> + Send>, client_addr)
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok((listen, new_addr))
|
Ok((listen, new_addr))
|
||||||
@ -194,16 +188,7 @@ where
|
|||||||
|
|
||||||
let dial = inner_dial
|
let dial = inner_dial
|
||||||
.into_future()
|
.into_future()
|
||||||
.and_then(move |(connec, client_addr)| {
|
.and_then(move |connec| {
|
||||||
let client_addr = Box::new(client_addr.map(move |mut addr| {
|
|
||||||
if is_wss {
|
|
||||||
addr.append(Protocol::Wss);
|
|
||||||
} else {
|
|
||||||
addr.append(Protocol::Ws);
|
|
||||||
};
|
|
||||||
addr
|
|
||||||
})) as Box<Future<Item = _, Error = _> + Send>;
|
|
||||||
|
|
||||||
ClientBuilder::new(&ws_addr)
|
ClientBuilder::new(&ws_addr)
|
||||||
.expect("generated ws address is always valid")
|
.expect("generated ws address is always valid")
|
||||||
.async_connect_on(connec)
|
.async_connect_on(connec)
|
||||||
@ -229,7 +214,6 @@ where
|
|||||||
let read_write = RwStreamSink::new(framed_data);
|
let read_write = RwStreamSink::new(framed_data);
|
||||||
Box::new(read_write) as Box<AsyncStream + Send>
|
Box::new(read_write) as Box<AsyncStream + Send>
|
||||||
})
|
})
|
||||||
.map(move |c| (c, client_addr))
|
|
||||||
});
|
});
|
||||||
|
|
||||||
Ok(Box::new(dial) as Box<_>)
|
Ok(Box::new(dial) as Box<_>)
|
||||||
@ -294,8 +278,8 @@ mod tests {
|
|||||||
let listener = listener
|
let listener = listener
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(e, _)| e)
|
.map_err(|(e, _)| e)
|
||||||
.and_then(|(c, _)| c.unwrap().map(|v| v.0));
|
.and_then(|(c, _)| c.unwrap().0);
|
||||||
let dialer = ws_config.clone().dial(addr).unwrap().map(|v| v.0);
|
let dialer = ws_config.clone().dial(addr).unwrap();
|
||||||
|
|
||||||
let future = listener
|
let future = listener
|
||||||
.select(dialer)
|
.select(dialer)
|
||||||
@ -317,8 +301,8 @@ mod tests {
|
|||||||
let listener = listener
|
let listener = listener
|
||||||
.into_future()
|
.into_future()
|
||||||
.map_err(|(e, _)| e)
|
.map_err(|(e, _)| e)
|
||||||
.and_then(|(c, _)| c.unwrap().map(|v| v.0));
|
.and_then(|(c, _)| c.unwrap().0);
|
||||||
let dialer = ws_config.clone().dial(addr).unwrap().map(|v| v.0);
|
let dialer = ws_config.clone().dial(addr).unwrap();
|
||||||
|
|
||||||
let future = listener
|
let future = listener
|
||||||
.select(dialer)
|
.select(dialer)
|
||||||
|
Reference in New Issue
Block a user