*: Format with rustfmt (#2188)

Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
Max Inden
2021-08-11 13:12:12 +02:00
committed by GitHub
parent 008561283e
commit f701b24ec0
171 changed files with 10051 additions and 7193 deletions

View File

@ -28,16 +28,16 @@ pub(crate) mod pool;
pub use error::{ConnectionError, PendingConnectionError};
pub use handler::{ConnectionHandler, ConnectionHandlerEvent, IntoConnectionHandler};
pub use listeners::{ListenerId, ListenersStream, ListenersEvent};
pub use listeners::{ListenerId, ListenersEvent, ListenersStream};
pub use manager::ConnectionId;
pub use substream::{Substream, SubstreamEndpoint, Close};
pub use pool::{ConnectionCounters, ConnectionLimits};
pub use pool::{EstablishedConnection, EstablishedConnectionIter, PendingConnection};
pub use pool::{ConnectionLimits, ConnectionCounters};
pub use substream::{Close, Substream, SubstreamEndpoint};
use crate::muxing::StreamMuxer;
use crate::{Multiaddr, PeerId};
use std::{error::Error, fmt, pin::Pin, task::Context, task::Poll};
use std::hash::Hash;
use std::{error::Error, fmt, pin::Pin, task::Context, task::Poll};
use substream::{Muxing, SubstreamEvent};
/// The endpoint roles associated with a peer-to-peer communication channel.
@ -55,7 +55,7 @@ impl std::ops::Not for Endpoint {
fn not(self) -> Self::Output {
match self {
Endpoint::Dialer => Endpoint::Listener,
Endpoint::Listener => Endpoint::Dialer
Endpoint::Listener => Endpoint::Dialer,
}
}
}
@ -86,7 +86,7 @@ pub enum ConnectedPoint {
local_addr: Multiaddr,
/// Stack of protocols used to send back data to the remote.
send_back_addr: Multiaddr,
}
},
}
impl From<&'_ ConnectedPoint> for Endpoint {
@ -106,7 +106,7 @@ impl ConnectedPoint {
pub fn to_endpoint(&self) -> Endpoint {
match self {
ConnectedPoint::Dialer { .. } => Endpoint::Dialer,
ConnectedPoint::Listener { .. } => Endpoint::Listener
ConnectedPoint::Listener { .. } => Endpoint::Listener,
}
}
@ -114,7 +114,7 @@ impl ConnectedPoint {
pub fn is_dialer(&self) -> bool {
match self {
ConnectedPoint::Dialer { .. } => true,
ConnectedPoint::Listener { .. } => false
ConnectedPoint::Listener { .. } => false,
}
}
@ -122,7 +122,7 @@ impl ConnectedPoint {
pub fn is_listener(&self) -> bool {
match self {
ConnectedPoint::Dialer { .. } => false,
ConnectedPoint::Listener { .. } => true
ConnectedPoint::Listener { .. } => true,
}
}
@ -237,9 +237,10 @@ where
/// Polls the connection for events produced by the associated handler
/// as a result of I/O activity on the substream multiplexer.
pub fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>)
-> Poll<Result<Event<THandler::OutEvent>, ConnectionError<THandler::Error>>>
{
pub fn poll(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
) -> Poll<Result<Event<THandler::OutEvent>, ConnectionError<THandler::Error>>> {
loop {
let mut io_pending = false;
@ -247,10 +248,13 @@ where
// of new substreams.
match self.muxing.poll(cx) {
Poll::Pending => io_pending = true,
Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream })) => {
self.handler.inject_substream(substream, SubstreamEndpoint::Listener)
}
Poll::Ready(Ok(SubstreamEvent::OutboundSubstream { user_data, substream })) => {
Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream })) => self
.handler
.inject_substream(substream, SubstreamEndpoint::Listener),
Poll::Ready(Ok(SubstreamEvent::OutboundSubstream {
user_data,
substream,
})) => {
let endpoint = SubstreamEndpoint::Dialer(user_data);
self.handler.inject_substream(substream, endpoint)
}
@ -265,7 +269,7 @@ where
match self.handler.poll(cx) {
Poll::Pending => {
if io_pending {
return Poll::Pending // Nothing to do
return Poll::Pending; // Nothing to do
}
}
Poll::Ready(Ok(ConnectionHandlerEvent::OutboundSubstreamRequest(user_data))) => {
@ -310,7 +314,7 @@ impl<'a> OutgoingInfo<'a> {
/// Builds a `ConnectedPoint` corresponding to the outgoing connection.
pub fn to_connected_point(&self) -> ConnectedPoint {
ConnectedPoint::Dialer {
address: self.address.clone()
address: self.address.clone(),
}
}
}

View File

@ -20,7 +20,7 @@
use crate::connection::ConnectionLimit;
use crate::transport::TransportError;
use std::{io, fmt};
use std::{fmt, io};
/// Errors that can occur in the context of an established `Connection`.
#[derive(Debug)]
@ -33,23 +33,19 @@ pub enum ConnectionError<THandlerErr> {
Handler(THandlerErr),
}
impl<THandlerErr> fmt::Display
for ConnectionError<THandlerErr>
impl<THandlerErr> fmt::Display for ConnectionError<THandlerErr>
where
THandlerErr: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
ConnectionError::IO(err) =>
write!(f, "Connection error: I/O error: {}", err),
ConnectionError::Handler(err) =>
write!(f, "Connection error: Handler error: {}", err),
ConnectionError::IO(err) => write!(f, "Connection error: I/O error: {}", err),
ConnectionError::Handler(err) => write!(f, "Connection error: Handler error: {}", err),
}
}
}
impl<THandlerErr> std::error::Error
for ConnectionError<THandlerErr>
impl<THandlerErr> std::error::Error for ConnectionError<THandlerErr>
where
THandlerErr: std::error::Error + 'static,
{
@ -80,29 +76,29 @@ pub enum PendingConnectionError<TTransErr> {
IO(io::Error),
}
impl<TTransErr> fmt::Display
for PendingConnectionError<TTransErr>
impl<TTransErr> fmt::Display for PendingConnectionError<TTransErr>
where
TTransErr: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
PendingConnectionError::IO(err) =>
write!(f, "Pending connection: I/O error: {}", err),
PendingConnectionError::Transport(err) =>
write!(f, "Pending connection: Transport error: {}", err),
PendingConnectionError::InvalidPeerId =>
write!(f, "Pending connection: Invalid peer ID."),
PendingConnectionError::ConnectionLimit(l) =>
write!(f, "Connection error: Connection limit: {}.", l),
PendingConnectionError::IO(err) => write!(f, "Pending connection: I/O error: {}", err),
PendingConnectionError::Transport(err) => {
write!(f, "Pending connection: Transport error: {}", err)
}
PendingConnectionError::InvalidPeerId => {
write!(f, "Pending connection: Invalid peer ID.")
}
PendingConnectionError::ConnectionLimit(l) => {
write!(f, "Connection error: Connection limit: {}.", l)
}
}
}
}
impl<TTransErr> std::error::Error
for PendingConnectionError<TTransErr>
impl<TTransErr> std::error::Error for PendingConnectionError<TTransErr>
where
TTransErr: std::error::Error + 'static
TTransErr: std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {

View File

@ -18,9 +18,9 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use super::{Connected, SubstreamEndpoint};
use crate::Multiaddr;
use std::{fmt::Debug, task::Context, task::Poll};
use super::{Connected, SubstreamEndpoint};
/// The interface of a connection handler.
///
@ -53,7 +53,11 @@ pub trait ConnectionHandler {
/// Implementations are allowed to panic in the case of dialing if the `user_data` in
/// `endpoint` doesn't correspond to what was returned earlier when polling, or is used
/// multiple times.
fn inject_substream(&mut self, substream: Self::Substream, endpoint: SubstreamEndpoint<Self::OutboundOpenInfo>);
fn inject_substream(
&mut self,
substream: Self::Substream,
endpoint: SubstreamEndpoint<Self::OutboundOpenInfo>,
);
/// Notifies the handler of an event.
fn inject_event(&mut self, event: Self::InEvent);
@ -64,8 +68,10 @@ pub trait ConnectionHandler {
/// Polls the handler for events.
///
/// Returning an error will close the connection to the remote.
fn poll(&mut self, cx: &mut Context<'_>)
-> Poll<Result<ConnectionHandlerEvent<Self::OutboundOpenInfo, Self::OutEvent>, Self::Error>>;
fn poll(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Result<ConnectionHandlerEvent<Self::OutboundOpenInfo, Self::OutEvent>, Self::Error>>;
}
/// Prototype for a `ConnectionHandler`.
@ -82,7 +88,7 @@ pub trait IntoConnectionHandler {
impl<T> IntoConnectionHandler for T
where
T: ConnectionHandler
T: ConnectionHandler,
{
type Handler = Self;
@ -91,9 +97,12 @@ where
}
}
pub(crate) type THandlerInEvent<THandler> = <<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent;
pub(crate) type THandlerOutEvent<THandler> = <<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent;
pub(crate) type THandlerError<THandler> = <<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::Error;
pub(crate) type THandlerInEvent<THandler> =
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::InEvent;
pub(crate) type THandlerOutEvent<THandler> =
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::OutEvent;
pub(crate) type THandlerError<THandler> =
<<THandler as IntoConnectionHandler>::Handler as ConnectionHandler>::Error;
/// Event produced by a handler.
#[derive(Debug, Copy, Clone, PartialEq, Eq)]
@ -109,24 +118,26 @@ pub enum ConnectionHandlerEvent<TOutboundOpenInfo, TCustom> {
impl<TOutboundOpenInfo, TCustom> ConnectionHandlerEvent<TOutboundOpenInfo, TCustom> {
/// If this is `OutboundSubstreamRequest`, maps the content to something else.
pub fn map_outbound_open_info<F, I>(self, map: F) -> ConnectionHandlerEvent<I, TCustom>
where F: FnOnce(TOutboundOpenInfo) -> I
where
F: FnOnce(TOutboundOpenInfo) -> I,
{
match self {
ConnectionHandlerEvent::OutboundSubstreamRequest(val) => {
ConnectionHandlerEvent::OutboundSubstreamRequest(map(val))
},
}
ConnectionHandlerEvent::Custom(val) => ConnectionHandlerEvent::Custom(val),
}
}
/// If this is `Custom`, maps the content to something else.
pub fn map_custom<F, I>(self, map: F) -> ConnectionHandlerEvent<TOutboundOpenInfo, I>
where F: FnOnce(TCustom) -> I
where
F: FnOnce(TCustom) -> I,
{
match self {
ConnectionHandlerEvent::OutboundSubstreamRequest(val) => {
ConnectionHandlerEvent::OutboundSubstreamRequest(val)
},
}
ConnectionHandlerEvent::Custom(val) => ConnectionHandlerEvent::Custom(map(val)),
}
}

View File

@ -20,7 +20,10 @@
//! Manage listening on multiple multiaddresses at once.
use crate::{Multiaddr, Transport, transport::{TransportError, ListenerEvent}};
use crate::{
transport::{ListenerEvent, TransportError},
Multiaddr, Transport,
};
use futures::{prelude::*, task::Context, task::Poll};
use log::debug;
use smallvec::SmallVec;
@ -86,7 +89,7 @@ where
/// can be resized, the only way is to use a `Pin<Box<>>`.
listeners: VecDeque<Pin<Box<Listener<TTrans>>>>,
/// The next listener ID to assign.
next_id: ListenerId
next_id: ListenerId,
}
/// The ID of a single listener.
@ -109,7 +112,7 @@ where
#[pin]
listener: TTrans::Listener,
/// Addresses it is listening on.
addresses: SmallVec<[Multiaddr; 4]>
addresses: SmallVec<[Multiaddr; 4]>,
}
/// Event that can happen on the `ListenersStream`.
@ -122,14 +125,14 @@ where
/// The listener that is listening on the new address.
listener_id: ListenerId,
/// The new address that is being listened on.
listen_addr: Multiaddr
listen_addr: Multiaddr,
},
/// An address is no longer being listened on.
AddressExpired {
/// The listener that is no longer listening on the address.
listener_id: ListenerId,
/// The new address that is being listened on.
listen_addr: Multiaddr
listen_addr: Multiaddr,
},
/// A connection is incoming on one of the listeners.
Incoming {
@ -161,7 +164,7 @@ where
listener_id: ListenerId,
/// The error value.
error: TTrans::Error,
}
},
}
impl<TTrans> ListenersStream<TTrans>
@ -173,7 +176,7 @@ where
ListenersStream {
transport,
listeners: VecDeque::new(),
next_id: ListenerId(1)
next_id: ListenerId(1),
}
}
@ -183,14 +186,17 @@ where
ListenersStream {
transport,
listeners: VecDeque::with_capacity(capacity),
next_id: ListenerId(1)
next_id: ListenerId(1),
}
}
/// Start listening on a multiaddress.
///
/// Returns an error if the transport doesn't support the given multiaddress.
pub fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<TTrans::Error>>
pub fn listen_on(
&mut self,
addr: Multiaddr,
) -> Result<ListenerId, TransportError<TTrans::Error>>
where
TTrans: Clone,
{
@ -198,7 +204,7 @@ where
self.listeners.push_back(Box::pin(Listener {
id: self.next_id,
listener,
addresses: SmallVec::new()
addresses: SmallVec::new(),
}));
let id = self.next_id;
self.next_id = ListenerId(self.next_id.0 + 1);
@ -237,17 +243,23 @@ where
Poll::Pending => {
self.listeners.push_front(listener);
remaining -= 1;
if remaining == 0 { break }
if remaining == 0 {
break;
}
}
Poll::Ready(Some(Ok(ListenerEvent::Upgrade { upgrade, local_addr, remote_addr }))) => {
Poll::Ready(Some(Ok(ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
}))) => {
let id = *listener_project.id;
self.listeners.push_front(listener);
return Poll::Ready(ListenersEvent::Incoming {
listener_id: id,
upgrade,
local_addr,
send_back_addr: remote_addr
})
send_back_addr: remote_addr,
});
}
Poll::Ready(Some(Ok(ListenerEvent::NewAddress(a)))) => {
if listener_project.addresses.contains(&a) {
@ -260,8 +272,8 @@ where
self.listeners.push_front(listener);
return Poll::Ready(ListenersEvent::NewAddress {
listener_id: id,
listen_addr: a
})
listen_addr: a,
});
}
Poll::Ready(Some(Ok(ListenerEvent::AddressExpired(a)))) => {
listener_project.addresses.retain(|x| x != &a);
@ -269,8 +281,8 @@ where
self.listeners.push_front(listener);
return Poll::Ready(ListenersEvent::AddressExpired {
listener_id: id,
listen_addr: a
})
listen_addr: a,
});
}
Poll::Ready(Some(Ok(ListenerEvent::Error(error)))) => {
let id = *listener_project.id;
@ -278,7 +290,7 @@ where
return Poll::Ready(ListenersEvent::Error {
listener_id: id,
error,
})
});
}
Poll::Ready(None) => {
return Poll::Ready(ListenersEvent::Closed {
@ -313,11 +325,7 @@ where
}
}
impl<TTrans> Unpin for ListenersStream<TTrans>
where
TTrans: Transport,
{
}
impl<TTrans> Unpin for ListenersStream<TTrans> where TTrans: Transport {}
impl<TTrans> fmt::Debug for ListenersStream<TTrans>
where
@ -338,22 +346,36 @@ where
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
ListenersEvent::NewAddress { listener_id, listen_addr } => f
ListenersEvent::NewAddress {
listener_id,
listen_addr,
} => f
.debug_struct("ListenersEvent::NewAddress")
.field("listener_id", listener_id)
.field("listen_addr", listen_addr)
.finish(),
ListenersEvent::AddressExpired { listener_id, listen_addr } => f
ListenersEvent::AddressExpired {
listener_id,
listen_addr,
} => f
.debug_struct("ListenersEvent::AddressExpired")
.field("listener_id", listener_id)
.field("listen_addr", listen_addr)
.finish(),
ListenersEvent::Incoming { listener_id, local_addr, .. } => f
ListenersEvent::Incoming {
listener_id,
local_addr,
..
} => f
.debug_struct("ListenersEvent::Incoming")
.field("listener_id", listener_id)
.field("local_addr", local_addr)
.finish(),
ListenersEvent::Closed { listener_id, addresses, reason } => f
ListenersEvent::Closed {
listener_id,
addresses,
reason,
} => f
.debug_struct("ListenersEvent::Closed")
.field("listener_id", listener_id)
.field("addresses", addresses)
@ -363,13 +385,15 @@ where
.debug_struct("ListenersEvent::Error")
.field("listener_id", listener_id)
.field("error", error)
.finish()
.finish(),
}
}
}
#[cfg(test)]
mod tests {
use futures::{future::BoxFuture, stream::BoxStream};
use super::*;
use crate::transport;
@ -396,11 +420,15 @@ mod tests {
});
match listeners.next().await.unwrap() {
ListenersEvent::Incoming { local_addr, send_back_addr, .. } => {
ListenersEvent::Incoming {
local_addr,
send_back_addr,
..
} => {
assert_eq!(local_addr, address);
assert!(send_back_addr != address);
},
_ => panic!()
}
_ => panic!(),
}
});
}
@ -415,21 +443,37 @@ mod tests {
impl transport::Transport for DummyTrans {
type Output = ();
type Error = std::io::Error;
type Listener = Pin<Box<dyn Stream<Item = Result<ListenerEvent<Self::ListenerUpgrade, std::io::Error>, std::io::Error>>>>;
type ListenerUpgrade = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>>>>;
type Dial = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>>>>;
type Listener = BoxStream<
'static,
Result<ListenerEvent<Self::ListenerUpgrade, std::io::Error>, std::io::Error>,
>;
type ListenerUpgrade = BoxFuture<'static, Result<Self::Output, Self::Error>>;
type Dial = BoxFuture<'static, Result<Self::Output, Self::Error>>;
fn listen_on(self, _: Multiaddr) -> Result<Self::Listener, transport::TransportError<Self::Error>> {
fn listen_on(
self,
_: Multiaddr,
) -> Result<Self::Listener, transport::TransportError<Self::Error>> {
Ok(Box::pin(stream::unfold((), |()| async move {
Some((Ok(ListenerEvent::Error(std::io::Error::from(std::io::ErrorKind::Other))), ()))
Some((
Ok(ListenerEvent::Error(std::io::Error::from(
std::io::ErrorKind::Other,
))),
(),
))
})))
}
fn dial(self, _: Multiaddr) -> Result<Self::Dial, transport::TransportError<Self::Error>> {
fn dial(
self,
_: Multiaddr,
) -> Result<Self::Dial, transport::TransportError<Self::Error>> {
panic!()
}
fn address_translation(&self, _: &Multiaddr, _: &Multiaddr) -> Option<Multiaddr> { None }
fn address_translation(&self, _: &Multiaddr, _: &Multiaddr) -> Option<Multiaddr> {
None
}
}
async_std::task::block_on(async move {
@ -439,8 +483,8 @@ mod tests {
for _ in 0..10 {
match listeners.next().await.unwrap() {
ListenersEvent::Error { .. } => {},
_ => panic!()
ListenersEvent::Error { .. } => {}
_ => panic!(),
}
}
});
@ -455,21 +499,32 @@ mod tests {
impl transport::Transport for DummyTrans {
type Output = ();
type Error = std::io::Error;
type Listener = Pin<Box<dyn Stream<Item = Result<ListenerEvent<Self::ListenerUpgrade, std::io::Error>, std::io::Error>>>>;
type ListenerUpgrade = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>>>>;
type Dial = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>>>>;
type Listener = BoxStream<
'static,
Result<ListenerEvent<Self::ListenerUpgrade, std::io::Error>, std::io::Error>,
>;
type ListenerUpgrade = BoxFuture<'static, Result<Self::Output, Self::Error>>;
type Dial = BoxFuture<'static, Result<Self::Output, Self::Error>>;
fn listen_on(self, _: Multiaddr) -> Result<Self::Listener, transport::TransportError<Self::Error>> {
fn listen_on(
self,
_: Multiaddr,
) -> Result<Self::Listener, transport::TransportError<Self::Error>> {
Ok(Box::pin(stream::unfold((), |()| async move {
Some((Err(std::io::Error::from(std::io::ErrorKind::Other)), ()))
})))
}
fn dial(self, _: Multiaddr) -> Result<Self::Dial, transport::TransportError<Self::Error>> {
fn dial(
self,
_: Multiaddr,
) -> Result<Self::Dial, transport::TransportError<Self::Error>> {
panic!()
}
fn address_translation(&self, _: &Multiaddr, _: &Multiaddr) -> Option<Multiaddr> { None }
fn address_translation(&self, _: &Multiaddr, _: &Multiaddr) -> Option<Multiaddr> {
None
}
}
async_std::task::block_on(async move {
@ -478,8 +533,8 @@ mod tests {
listeners.listen_on("/memory/0".parse().unwrap()).unwrap();
match listeners.next().await.unwrap() {
ListenersEvent::Closed { .. } => {},
_ => panic!()
ListenersEvent::Closed { .. } => {}
_ => panic!(),
}
});
}

View File

@ -18,39 +18,20 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::{
Executor,
muxing::StreamMuxer,
use super::{
handler::{THandlerError, THandlerInEvent, THandlerOutEvent},
Connected, ConnectedPoint, Connection, ConnectionError, ConnectionHandler,
IntoConnectionHandler, PendingConnectionError, Substream,
};
use crate::{muxing::StreamMuxer, Executor};
use fnv::FnvHashMap;
use futures::{
prelude::*,
channel::mpsc,
stream::FuturesUnordered
};
use futures::{channel::mpsc, prelude::*, stream::FuturesUnordered};
use std::{
collections::hash_map,
error,
fmt,
mem,
error, fmt, mem,
pin::Pin,
task::{Context, Poll},
};
use super::{
Connected,
ConnectedPoint,
Connection,
ConnectionError,
ConnectionHandler,
IntoConnectionHandler,
PendingConnectionError,
Substream,
handler::{
THandlerInEvent,
THandlerOutEvent,
THandlerError,
},
};
use task::{Task, TaskId};
mod task;
@ -123,11 +104,10 @@ pub struct Manager<H: IntoConnectionHandler, E> {
events_tx: mpsc::Sender<task::Event<H, E>>,
/// Receiver for events reported from managed tasks.
events_rx: mpsc::Receiver<task::Event<H, E>>
events_rx: mpsc::Receiver<task::Event<H, E>>,
}
impl<H: IntoConnectionHandler, E> fmt::Debug for Manager<H, E>
{
impl<H: IntoConnectionHandler, E> fmt::Debug for Manager<H, E> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_map()
.entries(self.tasks.iter().map(|(id, task)| (id, &task.state)))
@ -196,7 +176,7 @@ pub enum Event<'a, H: IntoConnectionHandler, TE> {
/// What happened.
error: PendingConnectionError<TE>,
/// The handler that was supposed to handle the failed connection.
handler: H
handler: H,
},
/// An established connection has been closed.
@ -225,7 +205,7 @@ pub enum Event<'a, H: IntoConnectionHandler, TE> {
/// The entry associated with the connection that produced the event.
entry: EstablishedEntry<'a, THandlerInEvent<H>>,
/// The produced event.
event: THandlerOutEvent<H>
event: THandlerOutEvent<H>,
},
/// A connection to a node has changed its address.
@ -250,7 +230,7 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
executor: config.executor,
local_spawns: FuturesUnordered::new(),
events_tx: tx,
events_rx: rx
events_rx: rx,
}
}
@ -265,18 +245,28 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
M::OutboundSubstream: Send + 'static,
F: Future<Output = ConnectResult<M, TE>> + Send + 'static,
H: IntoConnectionHandler + Send + 'static,
H::Handler: ConnectionHandler<
Substream = Substream<M>,
> + Send + 'static,
H::Handler: ConnectionHandler<Substream = Substream<M>> + Send + 'static,
<H::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
{
let task_id = self.next_task_id;
self.next_task_id.0 += 1;
let (tx, rx) = mpsc::channel(self.task_command_buffer_size);
self.tasks.insert(task_id, TaskInfo { sender: tx, state: TaskState::Pending });
self.tasks.insert(
task_id,
TaskInfo {
sender: tx,
state: TaskState::Pending,
},
);
let task = Box::pin(Task::pending(task_id, self.events_tx.clone(), rx, future, handler));
let task = Box::pin(Task::pending(
task_id,
self.events_tx.clone(),
rx,
future,
handler,
));
if let Some(executor) = &mut self.executor {
executor.exec(task);
} else {
@ -290,9 +280,7 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
pub fn add<M>(&mut self, conn: Connection<M, H::Handler>, info: Connected) -> ConnectionId
where
H: IntoConnectionHandler + Send + 'static,
H::Handler: ConnectionHandler<
Substream = Substream<M>,
> + Send + 'static,
H::Handler: ConnectionHandler<Substream = Substream<M>> + Send + 'static,
<H::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
TE: error::Error + Send + 'static,
M: StreamMuxer + Send + Sync + 'static,
@ -302,9 +290,13 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
self.next_task_id.0 += 1;
let (tx, rx) = mpsc::channel(self.task_command_buffer_size);
self.tasks.insert(task_id, TaskInfo {
sender: tx, state: TaskState::Established(info)
});
self.tasks.insert(
task_id,
TaskInfo {
sender: tx,
state: TaskState::Established(info),
},
);
let task: Pin<Box<Task<Pin<Box<future::Pending<_>>>, _, _, _>>> =
Box::pin(Task::established(task_id, self.events_tx.clone(), rx, conn));
@ -329,7 +321,13 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
/// Checks whether an established connection with the given ID is currently managed.
pub fn is_established(&self, id: &ConnectionId) -> bool {
matches!(self.tasks.get(&id.0), Some(TaskInfo { state: TaskState::Established(..), .. }))
matches!(
self.tasks.get(&id.0),
Some(TaskInfo {
state: TaskState::Established(..),
..
})
)
}
/// Polls the manager for events relating to the managed connections.
@ -341,8 +339,9 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
let event = loop {
match self.events_rx.poll_next_unpin(cx) {
Poll::Ready(Some(event)) => {
if self.tasks.contains_key(event.id()) { // (1)
break event
if self.tasks.contains_key(event.id()) {
// (1)
break event;
}
}
Poll::Pending => return Poll::Pending,
@ -352,12 +351,12 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
if let hash_map::Entry::Occupied(mut task) = self.tasks.entry(*event.id()) {
Poll::Ready(match event {
task::Event::Notify { id: _, event } =>
Event::ConnectionEvent {
entry: EstablishedEntry { task },
event
},
task::Event::Established { id: _, info } => { // (2)
task::Event::Notify { id: _, event } => Event::ConnectionEvent {
entry: EstablishedEntry { task },
event,
},
task::Event::Established { id: _, info } => {
// (2)
task.get_mut().state = TaskState::Established(info); // (3)
Event::ConnectionEstablished {
entry: EstablishedEntry { task },
@ -389,11 +388,14 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
let id = ConnectionId(id);
let task = task.remove();
match task.state {
TaskState::Established(connected) =>
Event::ConnectionClosed { id, connected, error },
TaskState::Established(connected) => Event::ConnectionClosed {
id,
connected,
error,
},
TaskState::Pending => unreachable!(
"`Event::Closed` implies (2) occurred on that task and thus (3)."
),
),
}
}
})
@ -407,14 +409,14 @@ impl<H: IntoConnectionHandler, TE> Manager<H, TE> {
#[derive(Debug)]
pub enum Entry<'a, I> {
Pending(PendingEntry<'a, I>),
Established(EstablishedEntry<'a, I>)
Established(EstablishedEntry<'a, I>),
}
impl<'a, I> Entry<'a, I> {
fn new(task: hash_map::OccupiedEntry<'a, TaskId, TaskInfo<I>>) -> Self {
match &task.get().state {
TaskState::Pending => Entry::Pending(PendingEntry { task }),
TaskState::Established(_) => Entry::Established(EstablishedEntry { task })
TaskState::Established(_) => Entry::Established(EstablishedEntry { task }),
}
}
}
@ -442,10 +444,13 @@ impl<'a, I> EstablishedEntry<'a, I> {
/// > the connection handler not being ready at this time.
pub fn notify_handler(&mut self, event: I) -> Result<(), I> {
let cmd = task::Command::NotifyHandler(event); // (*)
self.task.get_mut().sender.try_send(cmd)
self.task
.get_mut()
.sender
.try_send(cmd)
.map_err(|e| match e.into_inner() {
task::Command::NotifyHandler(event) => event,
_ => panic!("Unexpected command. Expected `NotifyHandler`") // see (*)
_ => panic!("Unexpected command. Expected `NotifyHandler`"), // see (*)
})
}
@ -455,7 +460,7 @@ impl<'a, I> EstablishedEntry<'a, I> {
///
/// Returns `Err(())` if the background task associated with the connection
/// is terminating and the connection is about to close.
pub fn poll_ready_notify_handler(&mut self, cx: &mut Context<'_>) -> Poll<Result<(),()>> {
pub fn poll_ready_notify_handler(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ()>> {
self.task.get_mut().sender.poll_ready(cx).map_err(|_| ())
}
@ -469,9 +474,15 @@ impl<'a, I> EstablishedEntry<'a, I> {
pub fn start_close(mut self) {
// Clone the sender so that we are guaranteed to have
// capacity for the close command (every sender gets a slot).
match self.task.get_mut().sender.clone().try_send(task::Command::Close) {
Ok(()) => {},
Err(e) => assert!(e.is_disconnected(), "No capacity for close command.")
match self
.task
.get_mut()
.sender
.clone()
.try_send(task::Command::Close)
{
Ok(()) => {}
Err(e) => assert!(e.is_disconnected(), "No capacity for close command."),
}
}
@ -479,7 +490,7 @@ impl<'a, I> EstablishedEntry<'a, I> {
pub fn connected(&self) -> &Connected {
match &self.task.get().state {
TaskState::Established(c) => c,
TaskState::Pending => unreachable!("By Entry::new()")
TaskState::Pending => unreachable!("By Entry::new()"),
}
}
@ -490,7 +501,7 @@ impl<'a, I> EstablishedEntry<'a, I> {
pub fn remove(self) -> Connected {
match self.task.remove().state {
TaskState::Established(c) => c,
TaskState::Pending => unreachable!("By Entry::new()")
TaskState::Pending => unreachable!("By Entry::new()"),
}
}
@ -504,7 +515,7 @@ impl<'a, I> EstablishedEntry<'a, I> {
/// (i.e. pending).
#[derive(Debug)]
pub struct PendingEntry<'a, I> {
task: hash_map::OccupiedEntry<'a, TaskId, TaskInfo<I>>
task: hash_map::OccupiedEntry<'a, TaskId, TaskInfo<I>>,
}
impl<'a, I> PendingEntry<'a, I> {
@ -514,7 +525,7 @@ impl<'a, I> PendingEntry<'a, I> {
}
/// Aborts the pending connection attempt.
pub fn abort(self) {
pub fn abort(self) {
self.task.remove();
}
}

View File

@ -18,29 +18,19 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use super::ConnectResult;
use crate::{
Multiaddr,
muxing::StreamMuxer,
connection::{
self,
Close,
Connected,
Connection,
ConnectionError,
ConnectionHandler,
IntoConnectionHandler,
PendingConnectionError,
Substream,
handler::{
THandlerInEvent,
THandlerOutEvent,
THandlerError,
},
handler::{THandlerError, THandlerInEvent, THandlerOutEvent},
Close, Connected, Connection, ConnectionError, ConnectionHandler, IntoConnectionHandler,
PendingConnectionError, Substream,
},
muxing::StreamMuxer,
Multiaddr,
};
use futures::{prelude::*, channel::mpsc, stream};
use futures::{channel::mpsc, prelude::*, stream};
use std::{pin::Pin, task::Context, task::Poll};
use super::ConnectResult;
/// Identifier of a [`Task`] in a [`Manager`](super::Manager).
#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)]
@ -62,16 +52,26 @@ pub enum Event<H: IntoConnectionHandler, TE> {
/// A connection to a node has succeeded.
Established { id: TaskId, info: Connected },
/// A pending connection failed.
Failed { id: TaskId, error: PendingConnectionError<TE>, handler: H },
Failed {
id: TaskId,
error: PendingConnectionError<TE>,
handler: H,
},
/// A node we are connected to has changed its address.
AddressChange { id: TaskId, new_address: Multiaddr },
/// Notify the manager of an event from the connection.
Notify { id: TaskId, event: THandlerOutEvent<H> },
Notify {
id: TaskId,
event: THandlerOutEvent<H>,
},
/// A connection closed, possibly due to an error.
///
/// If `error` is `None`, the connection has completed
/// an active orderly close.
Closed { id: TaskId, error: Option<ConnectionError<THandlerError<H>>> }
Closed {
id: TaskId,
error: Option<ConnectionError<THandlerError<H>>>,
},
}
impl<H: IntoConnectionHandler, TE> Event<H, TE> {
@ -91,7 +91,7 @@ pub struct Task<F, M, H, E>
where
M: StreamMuxer,
H: IntoConnectionHandler,
H::Handler: ConnectionHandler<Substream = Substream<M>>
H::Handler: ConnectionHandler<Substream = Substream<M>>,
{
/// The ID of this task.
id: TaskId,
@ -110,7 +110,7 @@ impl<F, M, H, E> Task<F, M, H, E>
where
M: StreamMuxer,
H: IntoConnectionHandler,
H::Handler: ConnectionHandler<Substream = Substream<M>>
H::Handler: ConnectionHandler<Substream = Substream<M>>,
{
/// Create a new task to connect and handle some node.
pub fn pending(
@ -118,7 +118,7 @@ where
events: mpsc::Sender<Event<H, E>>,
commands: mpsc::Receiver<Command<THandlerInEvent<H>>>,
future: F,
handler: H
handler: H,
) -> Self {
Task {
id,
@ -136,13 +136,16 @@ where
id: TaskId,
events: mpsc::Sender<Event<H, E>>,
commands: mpsc::Receiver<Command<THandlerInEvent<H>>>,
connection: Connection<M, H::Handler>
connection: Connection<M, H::Handler>,
) -> Self {
Task {
id,
events,
commands: commands.fuse(),
state: State::Established { connection, event: None },
state: State::Established {
connection,
event: None,
},
}
}
}
@ -152,7 +155,7 @@ enum State<F, M, H, E>
where
M: StreamMuxer,
H: IntoConnectionHandler,
H::Handler: ConnectionHandler<Substream = Substream<M>>
H::Handler: ConnectionHandler<Substream = Substream<M>>,
{
/// The connection is being negotiated.
Pending {
@ -180,14 +183,14 @@ where
Terminating(Event<H, E>),
/// The task has finished.
Done
Done,
}
impl<F, M, H, E> Unpin for Task<F, M, H, E>
where
M: StreamMuxer,
H: IntoConnectionHandler,
H::Handler: ConnectionHandler<Substream = Substream<M>>
H::Handler: ConnectionHandler<Substream = Substream<M>>,
{
}
@ -196,9 +199,7 @@ where
M: StreamMuxer,
F: Future<Output = ConnectResult<M, E>>,
H: IntoConnectionHandler,
H::Handler: ConnectionHandler<
Substream = Substream<M>,
> + Send + 'static,
H::Handler: ConnectionHandler<Substream = Substream<M>> + Send + 'static,
{
type Output = ();
@ -211,33 +212,33 @@ where
'poll: loop {
match std::mem::replace(&mut this.state, State::Done) {
State::Pending { mut future, handler } => {
State::Pending {
mut future,
handler,
} => {
// Check whether the task is still registered with a `Manager`
// by polling the commands channel.
match this.commands.poll_next_unpin(cx) {
Poll::Pending => {},
Poll::Pending => {}
Poll::Ready(None) => {
// The manager has dropped the task; abort.
return Poll::Ready(())
return Poll::Ready(());
}
Poll::Ready(Some(_)) => {
panic!("Task received command while the connection is pending.")
}
Poll::Ready(Some(_)) => panic!(
"Task received command while the connection is pending."
)
}
// Check if the connection succeeded.
match future.poll_unpin(cx) {
Poll::Ready(Ok((info, muxer))) => {
this.state = State::Established {
connection: Connection::new(
muxer,
handler.into_handler(&info),
),
event: Some(Event::Established { id, info })
connection: Connection::new(muxer, handler.into_handler(&info)),
event: Some(Event::Established { id, info }),
}
}
Poll::Pending => {
this.state = State::Pending { future, handler };
return Poll::Pending
return Poll::Pending;
}
Poll::Ready(Err(error)) => {
// Don't accept any further commands and terminate the
@ -249,23 +250,27 @@ where
}
}
State::Established { mut connection, event } => {
State::Established {
mut connection,
event,
} => {
// Check for commands from the `Manager`.
loop {
match this.commands.poll_next_unpin(cx) {
Poll::Pending => break,
Poll::Ready(Some(Command::NotifyHandler(event))) =>
connection.inject_event(event),
Poll::Ready(Some(Command::NotifyHandler(event))) => {
connection.inject_event(event)
}
Poll::Ready(Some(Command::Close)) => {
// Don't accept any further commands.
this.commands.get_mut().close();
// Discard the event, if any, and start a graceful close.
this.state = State::Closing(connection.close());
continue 'poll
continue 'poll;
}
Poll::Ready(None) => {
// The manager has dropped the task or disappeared; abort.
return Poll::Ready(())
return Poll::Ready(());
}
}
}
@ -274,44 +279,56 @@ where
// Send the event to the manager.
match this.events.poll_ready(cx) {
Poll::Pending => {
this.state = State::Established { connection, event: Some(event) };
return Poll::Pending
this.state = State::Established {
connection,
event: Some(event),
};
return Poll::Pending;
}
Poll::Ready(result) => {
if result.is_ok() {
if let Ok(()) = this.events.start_send(event) {
this.state = State::Established { connection, event: None };
continue 'poll
this.state = State::Established {
connection,
event: None,
};
continue 'poll;
}
}
// The manager is no longer reachable; abort.
return Poll::Ready(())
return Poll::Ready(());
}
}
} else {
// Poll the connection for new events.
match Connection::poll(Pin::new(&mut connection), cx) {
Poll::Pending => {
this.state = State::Established { connection, event: None };
return Poll::Pending
this.state = State::Established {
connection,
event: None,
};
return Poll::Pending;
}
Poll::Ready(Ok(connection::Event::Handler(event))) => {
this.state = State::Established {
connection,
event: Some(Event::Notify { id, event })
event: Some(Event::Notify { id, event }),
};
}
Poll::Ready(Ok(connection::Event::AddressChange(new_address))) => {
this.state = State::Established {
connection,
event: Some(Event::AddressChange { id, new_address })
event: Some(Event::AddressChange { id, new_address }),
};
}
Poll::Ready(Err(error)) => {
// Don't accept any further commands.
this.commands.get_mut().close();
// Terminate the task with the error, dropping the connection.
let event = Event::Closed { id, error: Some(error) };
let event = Event::Closed {
id,
error: Some(error),
};
this.state = State::Terminating(event);
}
}
@ -322,19 +339,22 @@ where
// Try to gracefully close the connection.
match closing.poll_unpin(cx) {
Poll::Ready(Ok(())) => {
let event = Event::Closed { id: this.id, error: None };
let event = Event::Closed {
id: this.id,
error: None,
};
this.state = State::Terminating(event);
}
Poll::Ready(Err(e)) => {
let event = Event::Closed {
id: this.id,
error: Some(ConnectionError::IO(e))
error: Some(ConnectionError::IO(e)),
};
this.state = State::Terminating(event);
}
Poll::Pending => {
this.state = State::Closing(closing);
return Poll::Pending
return Poll::Pending;
}
}
}
@ -344,18 +364,18 @@ where
match this.events.poll_ready(cx) {
Poll::Pending => {
self.state = State::Terminating(event);
return Poll::Pending
return Poll::Pending;
}
Poll::Ready(result) => {
if result.is_ok() {
let _ = this.events.start_send(event);
}
return Poll::Ready(())
return Poll::Ready(());
}
}
}
State::Done => panic!("`Task::poll()` called after completion.")
State::Done => panic!("`Task::poll()` called after completion."),
}
}
}

View File

@ -19,29 +19,15 @@
// DEALINGS IN THE SOFTWARE.
use crate::{
ConnectedPoint,
PeerId,
connection::{
self,
Connected,
Connection,
ConnectionId,
ConnectionLimit,
ConnectionError,
ConnectionHandler,
IncomingInfo,
IntoConnectionHandler,
OutgoingInfo,
Substream,
PendingConnectionError,
handler::{
THandlerInEvent,
THandlerOutEvent,
THandlerError,
},
handler::{THandlerError, THandlerInEvent, THandlerOutEvent},
manager::{self, Manager, ManagerConfig},
Connected, Connection, ConnectionError, ConnectionHandler, ConnectionId, ConnectionLimit,
IncomingInfo, IntoConnectionHandler, OutgoingInfo, PendingConnectionError, Substream,
},
muxing::StreamMuxer,
ConnectedPoint, PeerId,
};
use either::Either;
use fnv::FnvHashMap;
@ -76,9 +62,7 @@ pub struct Pool<THandler: IntoConnectionHandler, TTransErr> {
disconnected: Vec<Disconnected>,
}
impl<THandler: IntoConnectionHandler, TTransErr> fmt::Debug
for Pool<THandler, TTransErr>
{
impl<THandler: IntoConnectionHandler, TTransErr> fmt::Debug for Pool<THandler, TTransErr> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("Pool")
.field("counters", &self.counters)
@ -86,8 +70,7 @@ for Pool<THandler, TTransErr>
}
}
impl<THandler: IntoConnectionHandler, TTransErr> Unpin
for Pool<THandler, TTransErr> {}
impl<THandler: IntoConnectionHandler, TTransErr> Unpin for Pool<THandler, TTransErr> {}
/// Event that can happen on the `Pool`.
pub enum PoolEvent<'a, THandler: IntoConnectionHandler, TTransErr> {
@ -157,56 +140,60 @@ pub enum PoolEvent<'a, THandler: IntoConnectionHandler, TTransErr> {
},
}
impl<'a, THandler: IntoConnectionHandler, TTransErr> fmt::Debug for PoolEvent<'a, THandler, TTransErr>
impl<'a, THandler: IntoConnectionHandler, TTransErr> fmt::Debug
for PoolEvent<'a, THandler, TTransErr>
where
TTransErr: fmt::Debug,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match *self {
PoolEvent::ConnectionEstablished { ref connection, .. } => {
f.debug_tuple("PoolEvent::ConnectionEstablished")
.field(connection)
.finish()
},
PoolEvent::ConnectionClosed { ref id, ref connected, ref error, .. } => {
f.debug_struct("PoolEvent::ConnectionClosed")
.field("id", id)
.field("connected", connected)
.field("error", error)
.finish()
},
PoolEvent::PendingConnectionError { ref id, ref error, .. } => {
f.debug_struct("PoolEvent::PendingConnectionError")
.field("id", id)
.field("error", error)
.finish()
},
PoolEvent::ConnectionEvent { ref connection, ref event } => {
f.debug_struct("PoolEvent::ConnectionEvent")
.field("peer", &connection.peer_id())
.field("event", event)
.finish()
},
PoolEvent::AddressChange { ref connection, ref new_endpoint, ref old_endpoint } => {
f.debug_struct("PoolEvent::AddressChange")
.field("peer", &connection.peer_id())
.field("new_endpoint", new_endpoint)
.field("old_endpoint", old_endpoint)
.finish()
},
PoolEvent::ConnectionEstablished { ref connection, .. } => f
.debug_tuple("PoolEvent::ConnectionEstablished")
.field(connection)
.finish(),
PoolEvent::ConnectionClosed {
ref id,
ref connected,
ref error,
..
} => f
.debug_struct("PoolEvent::ConnectionClosed")
.field("id", id)
.field("connected", connected)
.field("error", error)
.finish(),
PoolEvent::PendingConnectionError {
ref id, ref error, ..
} => f
.debug_struct("PoolEvent::PendingConnectionError")
.field("id", id)
.field("error", error)
.finish(),
PoolEvent::ConnectionEvent {
ref connection,
ref event,
} => f
.debug_struct("PoolEvent::ConnectionEvent")
.field("peer", &connection.peer_id())
.field("event", event)
.finish(),
PoolEvent::AddressChange {
ref connection,
ref new_endpoint,
ref old_endpoint,
} => f
.debug_struct("PoolEvent::AddressChange")
.field("peer", &connection.peer_id())
.field("new_endpoint", new_endpoint)
.field("old_endpoint", old_endpoint)
.finish(),
}
}
}
impl<THandler: IntoConnectionHandler, TTransErr>
Pool<THandler, TTransErr>
{
impl<THandler: IntoConnectionHandler, TTransErr> Pool<THandler, TTransErr> {
/// Creates a new empty `Pool`.
pub fn new(
local_id: PeerId,
manager_config: ManagerConfig,
limits: ConnectionLimits
) -> Self {
pub fn new(local_id: PeerId, manager_config: ManagerConfig, limits: ConnectionLimits) -> Self {
Pool {
local_id,
counters: ConnectionCounters::new(limits),
@ -234,13 +221,11 @@ impl<THandler: IntoConnectionHandler, TTransErr>
info: IncomingInfo<'_>,
) -> Result<ConnectionId, ConnectionLimit>
where
TFut: Future<
Output = Result<(PeerId, TMuxer), PendingConnectionError<TTransErr>>
> + Send + 'static,
TFut: Future<Output = Result<(PeerId, TMuxer), PendingConnectionError<TTransErr>>>
+ Send
+ 'static,
THandler: IntoConnectionHandler + Send + 'static,
THandler::Handler: ConnectionHandler<
Substream = Substream<TMuxer>,
> + Send + 'static,
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send + 'static,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
TTransErr: error::Error + Send + 'static,
TMuxer: StreamMuxer + Send + Sync + 'static,
@ -263,13 +248,11 @@ impl<THandler: IntoConnectionHandler, TTransErr>
info: OutgoingInfo<'_>,
) -> Result<ConnectionId, ConnectionLimit>
where
TFut: Future<
Output = Result<(PeerId, TMuxer), PendingConnectionError<TTransErr>>
> + Send + 'static,
TFut: Future<Output = Result<(PeerId, TMuxer), PendingConnectionError<TTransErr>>>
+ Send
+ 'static,
THandler: IntoConnectionHandler + Send + 'static,
THandler::Handler: ConnectionHandler<
Substream = Substream<TMuxer>,
> + Send + 'static,
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send + 'static,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
TTransErr: error::Error + Send + 'static,
TMuxer: StreamMuxer + Send + Sync + 'static,
@ -290,13 +273,11 @@ impl<THandler: IntoConnectionHandler, TTransErr>
peer: Option<PeerId>,
) -> ConnectionId
where
TFut: Future<
Output = Result<(PeerId, TMuxer), PendingConnectionError<TTransErr>>
> + Send + 'static,
TFut: Future<Output = Result<(PeerId, TMuxer), PendingConnectionError<TTransErr>>>
+ Send
+ 'static,
THandler: IntoConnectionHandler + Send + 'static,
THandler::Handler: ConnectionHandler<
Substream = Substream<TMuxer>,
> + Send + 'static,
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send + 'static,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
TTransErr: error::Error + Send + 'static,
TMuxer: StreamMuxer + Send + Sync + 'static,
@ -313,12 +294,12 @@ impl<THandler: IntoConnectionHandler, TTransErr>
move |(peer_id, muxer)| {
if let Some(peer) = expected_peer {
if peer != peer_id {
return future::err(PendingConnectionError::InvalidPeerId)
return future::err(PendingConnectionError::InvalidPeerId);
}
}
if local_id == peer_id {
return future::err(PendingConnectionError::InvalidPeerId)
return future::err(PendingConnectionError::InvalidPeerId);
}
let connected = Connected { peer_id, endpoint };
@ -337,73 +318,80 @@ impl<THandler: IntoConnectionHandler, TTransErr>
/// Returns the assigned connection ID on success. An error is returned
/// if the configured maximum number of established connections for the
/// connected peer has been reached.
pub fn add<TMuxer>(&mut self, c: Connection<TMuxer, THandler::Handler>, i: Connected)
-> Result<ConnectionId, ConnectionLimit>
pub fn add<TMuxer>(
&mut self,
c: Connection<TMuxer, THandler::Handler>,
i: Connected,
) -> Result<ConnectionId, ConnectionLimit>
where
THandler: IntoConnectionHandler + Send + 'static,
THandler::Handler: ConnectionHandler<
Substream = connection::Substream<TMuxer>,
> + Send + 'static,
THandler::Handler:
ConnectionHandler<Substream = connection::Substream<TMuxer>> + Send + 'static,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
TTransErr: error::Error + Send + 'static,
TMuxer: StreamMuxer + Send + Sync + 'static,
TMuxer::OutboundSubstream: Send + 'static,
{
self.counters.check_max_established(&i.endpoint)?;
self.counters.check_max_established_per_peer(self.num_peer_established(&i.peer_id))?;
self.counters
.check_max_established_per_peer(self.num_peer_established(&i.peer_id))?;
let id = self.manager.add(c, i.clone());
self.counters.inc_established(&i.endpoint);
self.established.entry(i.peer_id).or_default().insert(id, i.endpoint);
self.established
.entry(i.peer_id)
.or_default()
.insert(id, i.endpoint);
Ok(id)
}
/// Gets an entry representing a connection in the pool.
///
/// Returns `None` if the pool has no connection with the given ID.
pub fn get(&mut self, id: ConnectionId)
-> Option<PoolConnection<'_, THandlerInEvent<THandler>>>
{
pub fn get(
&mut self,
id: ConnectionId,
) -> Option<PoolConnection<'_, THandlerInEvent<THandler>>> {
match self.manager.entry(id) {
Some(manager::Entry::Established(entry)) =>
Some(PoolConnection::Established(EstablishedConnection {
entry
})),
Some(manager::Entry::Pending(entry)) =>
Some(manager::Entry::Established(entry)) => {
Some(PoolConnection::Established(EstablishedConnection { entry }))
}
Some(manager::Entry::Pending(entry)) => {
Some(PoolConnection::Pending(PendingConnection {
entry,
pending: &mut self.pending,
counters: &mut self.counters,
})),
None => None
}))
}
None => None,
}
}
/// Gets an established connection from the pool by ID.
pub fn get_established(&mut self, id: ConnectionId)
-> Option<EstablishedConnection<'_, THandlerInEvent<THandler>>>
{
pub fn get_established(
&mut self,
id: ConnectionId,
) -> Option<EstablishedConnection<'_, THandlerInEvent<THandler>>> {
match self.get(id) {
Some(PoolConnection::Established(c)) => Some(c),
_ => None
_ => None,
}
}
/// Gets a pending outgoing connection by ID.
pub fn get_outgoing(&mut self, id: ConnectionId)
-> Option<PendingConnection<'_, THandlerInEvent<THandler>>>
{
pub fn get_outgoing(
&mut self,
id: ConnectionId,
) -> Option<PendingConnection<'_, THandlerInEvent<THandler>>> {
match self.pending.get(&id) {
Some((ConnectedPoint::Dialer { .. }, _peer)) =>
match self.manager.entry(id) {
Some(manager::Entry::Pending(entry)) =>
Some(PendingConnection {
entry,
pending: &mut self.pending,
counters: &mut self.counters,
}),
_ => unreachable!("by consistency of `self.pending` with `self.manager`")
}
_ => None
Some((ConnectedPoint::Dialer { .. }, _peer)) => match self.manager.entry(id) {
Some(manager::Entry::Pending(entry)) => Some(PendingConnection {
entry,
pending: &mut self.pending,
counters: &mut self.counters,
}),
_ => unreachable!("by consistency of `self.pending` with `self.manager`"),
},
_ => None,
}
}
@ -437,7 +425,9 @@ impl<THandler: IntoConnectionHandler, TTransErr>
if let Some(manager::Entry::Established(e)) = self.manager.entry(id) {
let connected = e.remove();
self.disconnected.push(Disconnected {
id, connected, num_established
id,
connected,
num_established,
});
num_established += 1;
}
@ -468,14 +458,13 @@ impl<THandler: IntoConnectionHandler, TTransErr>
}
/// Returns an iterator over all established connections of `peer`.
pub fn iter_peer_established<'a>(&'a mut self, peer: &PeerId)
-> EstablishedConnectionIter<'a,
impl Iterator<Item = ConnectionId>,
THandler,
TTransErr,
>
pub fn iter_peer_established<'a>(
&'a mut self,
peer: &PeerId,
) -> EstablishedConnectionIter<'a, impl Iterator<Item = ConnectionId>, THandler, TTransErr>
{
let ids = self.iter_peer_established_info(peer)
let ids = self
.iter_peer_established_info(peer)
.map(|(id, _endpoint)| *id)
.collect::<SmallVec<[ConnectionId; 10]>>()
.into_iter();
@ -486,45 +475,50 @@ impl<THandler: IntoConnectionHandler, TTransErr>
/// Returns an iterator for information on all pending incoming connections.
pub fn iter_pending_incoming(&self) -> impl Iterator<Item = IncomingInfo<'_>> {
self.iter_pending_info()
.filter_map(|(_, ref endpoint, _)| {
match endpoint {
ConnectedPoint::Listener { local_addr, send_back_addr } => {
Some(IncomingInfo { local_addr, send_back_addr })
},
ConnectedPoint::Dialer { .. } => None,
}
.filter_map(|(_, ref endpoint, _)| match endpoint {
ConnectedPoint::Listener {
local_addr,
send_back_addr,
} => Some(IncomingInfo {
local_addr,
send_back_addr,
}),
ConnectedPoint::Dialer { .. } => None,
})
}
/// Returns an iterator for information on all pending outgoing connections.
pub fn iter_pending_outgoing(&self) -> impl Iterator<Item = OutgoingInfo<'_>> {
self.iter_pending_info()
.filter_map(|(_, ref endpoint, ref peer_id)| {
match endpoint {
ConnectedPoint::Listener { .. } => None,
ConnectedPoint::Dialer { address } =>
Some(OutgoingInfo { address, peer_id: peer_id.as_ref() }),
}
.filter_map(|(_, ref endpoint, ref peer_id)| match endpoint {
ConnectedPoint::Listener { .. } => None,
ConnectedPoint::Dialer { address } => Some(OutgoingInfo {
address,
peer_id: peer_id.as_ref(),
}),
})
}
/// Returns an iterator over all connection IDs and associated endpoints
/// of established connections to `peer` known to the pool.
pub fn iter_peer_established_info(&self, peer: &PeerId)
-> impl Iterator<Item = (&ConnectionId, &ConnectedPoint)> + fmt::Debug + '_
{
pub fn iter_peer_established_info(
&self,
peer: &PeerId,
) -> impl Iterator<Item = (&ConnectionId, &ConnectedPoint)> + fmt::Debug + '_ {
match self.established.get(peer) {
Some(conns) => Either::Left(conns.iter()),
None => Either::Right(std::iter::empty())
None => Either::Right(std::iter::empty()),
}
}
/// Returns an iterator over all pending connection IDs together
/// with associated endpoints and expected peer IDs in the pool.
pub fn iter_pending_info(&self)
-> impl Iterator<Item = (&ConnectionId, &ConnectedPoint, &Option<PeerId>)> + '_
{
self.pending.iter().map(|(id, (endpoint, info))| (id, endpoint, info))
pub fn iter_pending_info(
&self,
) -> impl Iterator<Item = (&ConnectionId, &ConnectedPoint, &Option<PeerId>)> + '_ {
self.pending
.iter()
.map(|(id, (endpoint, info))| (id, endpoint, info))
}
/// Returns an iterator over all connected peers, i.e. those that have
@ -537,9 +531,10 @@ impl<THandler: IntoConnectionHandler, TTransErr>
///
/// > **Note**: We use a regular `poll` method instead of implementing `Stream`,
/// > because we want the `Pool` to stay borrowed if necessary.
pub fn poll<'a>(&'a mut self, cx: &mut Context<'_>) -> Poll<
PoolEvent<'a, THandler, TTransErr>
> {
pub fn poll<'a>(
&'a mut self,
cx: &mut Context<'_>,
) -> Poll<PoolEvent<'a, THandler, TTransErr>> {
// Drain events resulting from forced disconnections.
//
// Note: The `Disconnected` entries in `self.disconnected`
@ -548,15 +543,18 @@ impl<THandler: IntoConnectionHandler, TTransErr>
// events in an order that properly counts down `num_established`.
// See also `Pool::disconnect`.
if let Some(Disconnected {
id, connected, num_established
}) = self.disconnected.pop() {
id,
connected,
num_established,
}) = self.disconnected.pop()
{
return Poll::Ready(PoolEvent::ConnectionClosed {
id,
connected,
num_established,
error: None,
pool: self,
})
});
}
// Poll the connection `Manager`.
@ -576,11 +574,15 @@ impl<THandler: IntoConnectionHandler, TTransErr>
error,
handler: Some(handler),
peer,
pool: self
})
pool: self,
});
}
},
manager::Event::ConnectionClosed { id, connected, error } => {
}
manager::Event::ConnectionClosed {
id,
connected,
error,
} => {
let num_established =
if let Some(conns) = self.established.get_mut(&connected.peer_id) {
if let Some(endpoint) = conns.remove(&id) {
@ -594,8 +596,12 @@ impl<THandler: IntoConnectionHandler, TTransErr>
self.established.remove(&connected.peer_id);
}
return Poll::Ready(PoolEvent::ConnectionClosed {
id, connected, error, num_established, pool: self
})
id,
connected,
error,
num_established,
pool: self,
});
}
manager::Event::ConnectionEstablished { entry } => {
let id = entry.id();
@ -611,12 +617,13 @@ impl<THandler: IntoConnectionHandler, TTransErr>
error: PendingConnectionError::ConnectionLimit(e),
handler: None,
peer,
pool: self
})
pool: self,
});
}
// Check per-peer established connection limit.
let current = num_peer_established(&self.established, &entry.connected().peer_id);
let current =
num_peer_established(&self.established, &entry.connected().peer_id);
if let Err(e) = self.counters.check_max_established_per_peer(current) {
let connected = entry.remove();
return Poll::Ready(PoolEvent::PendingConnectionError {
@ -625,8 +632,8 @@ impl<THandler: IntoConnectionHandler, TTransErr>
error: PendingConnectionError::ConnectionLimit(e),
handler: None,
peer,
pool: self
})
pool: self,
});
}
// Peer ID checks must already have happened. See `add_pending`.
@ -644,54 +651,62 @@ impl<THandler: IntoConnectionHandler, TTransErr>
// Add the connection to the pool.
let peer = entry.connected().peer_id;
let conns = self.established.entry(peer).or_default();
let num_established = NonZeroU32::new(u32::try_from(conns.len() + 1).unwrap())
.expect("n + 1 is always non-zero; qed");
let num_established =
NonZeroU32::new(u32::try_from(conns.len() + 1).unwrap())
.expect("n + 1 is always non-zero; qed");
self.counters.inc_established(&endpoint);
conns.insert(id, endpoint);
match self.get(id) {
Some(PoolConnection::Established(connection)) =>
Some(PoolConnection::Established(connection)) => {
return Poll::Ready(PoolEvent::ConnectionEstablished {
connection, num_established
}),
_ => unreachable!("since `entry` is an `EstablishedEntry`.")
connection,
num_established,
})
}
_ => unreachable!("since `entry` is an `EstablishedEntry`."),
}
}
},
}
manager::Event::ConnectionEvent { entry, event } => {
let id = entry.id();
match self.get(id) {
Some(PoolConnection::Established(connection)) =>
return Poll::Ready(PoolEvent::ConnectionEvent {
connection,
event,
}),
_ => unreachable!("since `entry` is an `EstablishedEntry`.")
Some(PoolConnection::Established(connection)) => {
return Poll::Ready(PoolEvent::ConnectionEvent { connection, event })
}
_ => unreachable!("since `entry` is an `EstablishedEntry`."),
}
},
manager::Event::AddressChange { entry, new_endpoint, old_endpoint } => {
}
manager::Event::AddressChange {
entry,
new_endpoint,
old_endpoint,
} => {
let id = entry.id();
match self.established.get_mut(&entry.connected().peer_id) {
Some(list) => *list.get_mut(&id)
.expect("state inconsistency: entry is `EstablishedEntry` but absent \
from `established`") = new_endpoint.clone(),
None => unreachable!("since `entry` is an `EstablishedEntry`.")
Some(list) => {
*list.get_mut(&id).expect(
"state inconsistency: entry is `EstablishedEntry` but absent \
from `established`",
) = new_endpoint.clone()
}
None => unreachable!("since `entry` is an `EstablishedEntry`."),
};
match self.get(id) {
Some(PoolConnection::Established(connection)) =>
Some(PoolConnection::Established(connection)) => {
return Poll::Ready(PoolEvent::AddressChange {
connection,
new_endpoint,
old_endpoint,
}),
_ => unreachable!("since `entry` is an `EstablishedEntry`.")
})
}
_ => unreachable!("since `entry` is an `EstablishedEntry`."),
}
},
}
}
}
}
}
/// A connection in a [`Pool`].
@ -707,9 +722,7 @@ pub struct PendingConnection<'a, TInEvent> {
counters: &'a mut ConnectionCounters,
}
impl<TInEvent>
PendingConnection<'_, TInEvent>
{
impl<TInEvent> PendingConnection<'_, TInEvent> {
/// Returns the local connection ID.
pub fn id(&self) -> ConnectionId {
self.entry.id()
@ -717,17 +730,29 @@ impl<TInEvent>
/// Returns the (expected) identity of the remote peer, if known.
pub fn peer_id(&self) -> &Option<PeerId> {
&self.pending.get(&self.entry.id()).expect("`entry` is a pending entry").1
&self
.pending
.get(&self.entry.id())
.expect("`entry` is a pending entry")
.1
}
/// Returns information about this endpoint of the connection.
pub fn endpoint(&self) -> &ConnectedPoint {
&self.pending.get(&self.entry.id()).expect("`entry` is a pending entry").0
&self
.pending
.get(&self.entry.id())
.expect("`entry` is a pending entry")
.0
}
/// Aborts the connection attempt, closing the connection.
pub fn abort(self) {
let endpoint = self.pending.remove(&self.entry.id()).expect("`entry` is a pending entry").0;
let endpoint = self
.pending
.remove(&self.entry.id())
.expect("`entry` is a pending entry")
.0;
self.counters.dec_pending(&endpoint);
self.entry.abort();
}
@ -738,8 +763,7 @@ pub struct EstablishedConnection<'a, TInEvent> {
entry: manager::EstablishedEntry<'a, TInEvent>,
}
impl<TInEvent> fmt::Debug
for EstablishedConnection<'_, TInEvent>
impl<TInEvent> fmt::Debug for EstablishedConnection<'_, TInEvent>
where
TInEvent: fmt::Debug,
{
@ -790,7 +814,7 @@ impl<TInEvent> EstablishedConnection<'_, TInEvent> {
///
/// Returns `Err(())` if the background task associated with the connection
/// is terminating and the connection is about to close.
pub fn poll_ready_notify_handler(&mut self, cx: &mut Context<'_>) -> Poll<Result<(),()>> {
pub fn poll_ready_notify_handler(&mut self, cx: &mut Context<'_>) -> Poll<Result<(), ()>> {
self.entry.poll_ready_notify_handler(cx)
}
@ -811,21 +835,22 @@ pub struct EstablishedConnectionIter<'a, I, THandler: IntoConnectionHandler, TTr
// Note: Ideally this would be an implementation of `Iterator`, but that
// requires GATs (cf. https://github.com/rust-lang/rust/issues/44265) and
// a different definition of `Iterator`.
impl<'a, I, THandler: IntoConnectionHandler, TTransErr> EstablishedConnectionIter<'a, I, THandler, TTransErr>
impl<'a, I, THandler: IntoConnectionHandler, TTransErr>
EstablishedConnectionIter<'a, I, THandler, TTransErr>
where
I: Iterator<Item = ConnectionId>
I: Iterator<Item = ConnectionId>,
{
/// Obtains the next connection, if any.
#[allow(clippy::should_implement_trait)]
pub fn next(&mut self) -> Option<EstablishedConnection<'_, THandlerInEvent<THandler>>>
{
pub fn next(&mut self) -> Option<EstablishedConnection<'_, THandlerInEvent<THandler>>> {
while let Some(id) = self.ids.next() {
if self.pool.manager.is_established(&id) { // (*)
if self.pool.manager.is_established(&id) {
// (*)
match self.pool.manager.entry(id) {
Some(manager::Entry::Established(entry)) => {
return Some(EstablishedConnection { entry })
}
_ => panic!("Established entry not found in manager.") // see (*)
_ => panic!("Established entry not found in manager."), // see (*)
}
}
}
@ -838,17 +863,18 @@ where
}
/// Returns the first connection, if any, consuming the iterator.
pub fn into_first<'b>(mut self)
-> Option<EstablishedConnection<'b, THandlerInEvent<THandler>>>
where 'a: 'b
pub fn into_first<'b>(mut self) -> Option<EstablishedConnection<'b, THandlerInEvent<THandler>>>
where
'a: 'b,
{
while let Some(id) = self.ids.next() {
if self.pool.manager.is_established(&id) { // (*)
if self.pool.manager.is_established(&id) {
// (*)
match self.pool.manager.entry(id) {
Some(manager::Entry::Established(entry)) => {
return Some(EstablishedConnection { entry })
}
_ => panic!("Established entry not found in manager.") // see (*)
_ => panic!("Established entry not found in manager."), // see (*)
}
}
}
@ -924,29 +950,45 @@ impl ConnectionCounters {
fn inc_pending(&mut self, endpoint: &ConnectedPoint) {
match endpoint {
ConnectedPoint::Dialer { .. } => { self.pending_outgoing += 1; }
ConnectedPoint::Listener { .. } => { self.pending_incoming += 1; }
ConnectedPoint::Dialer { .. } => {
self.pending_outgoing += 1;
}
ConnectedPoint::Listener { .. } => {
self.pending_incoming += 1;
}
}
}
fn dec_pending(&mut self, endpoint: &ConnectedPoint) {
match endpoint {
ConnectedPoint::Dialer { .. } => { self.pending_outgoing -= 1; }
ConnectedPoint::Listener { .. } => { self.pending_incoming -= 1; }
ConnectedPoint::Dialer { .. } => {
self.pending_outgoing -= 1;
}
ConnectedPoint::Listener { .. } => {
self.pending_incoming -= 1;
}
}
}
fn inc_established(&mut self, endpoint: &ConnectedPoint) {
match endpoint {
ConnectedPoint::Dialer { .. } => { self.established_outgoing += 1; }
ConnectedPoint::Listener { .. } => { self.established_incoming += 1; }
ConnectedPoint::Dialer { .. } => {
self.established_outgoing += 1;
}
ConnectedPoint::Listener { .. } => {
self.established_incoming += 1;
}
}
}
fn dec_established(&mut self, endpoint: &ConnectedPoint) {
match endpoint {
ConnectedPoint::Dialer { .. } => { self.established_outgoing -= 1; }
ConnectedPoint::Listener { .. } => { self.established_incoming -= 1; }
ConnectedPoint::Dialer { .. } => {
self.established_outgoing -= 1;
}
ConnectedPoint::Listener { .. } => {
self.established_incoming -= 1;
}
}
}
@ -958,18 +1000,19 @@ impl ConnectionCounters {
Self::check(self.pending_incoming, self.limits.max_pending_incoming)
}
fn check_max_established(&self, endpoint: &ConnectedPoint)
-> Result<(), ConnectionLimit>
{
fn check_max_established(&self, endpoint: &ConnectedPoint) -> Result<(), ConnectionLimit> {
// Check total connection limit.
Self::check(self.num_established(), self.limits.max_established_total)?;
// Check incoming/outgoing connection limits
match endpoint {
ConnectedPoint::Dialer { .. } =>
Self::check(self.established_outgoing, self.limits.max_established_outgoing),
ConnectedPoint::Listener { .. } => {
Self::check(self.established_incoming, self.limits.max_established_incoming)
}
ConnectedPoint::Dialer { .. } => Self::check(
self.established_outgoing,
self.limits.max_established_outgoing,
),
ConnectedPoint::Listener { .. } => Self::check(
self.established_incoming,
self.limits.max_established_incoming,
),
}
}
@ -980,22 +1023,21 @@ impl ConnectionCounters {
fn check(current: u32, limit: Option<u32>) -> Result<(), ConnectionLimit> {
if let Some(limit) = limit {
if current >= limit {
return Err(ConnectionLimit { limit, current })
return Err(ConnectionLimit { limit, current });
}
}
Ok(())
}
}
/// Counts the number of established connections to the given peer.
fn num_peer_established(
established: &FnvHashMap<PeerId, FnvHashMap<ConnectionId, ConnectedPoint>>,
peer: &PeerId
peer: &PeerId,
) -> u32 {
established.get(peer).map_or(0, |conns|
u32::try_from(conns.len())
.expect("Unexpectedly large number of connections for a peer."))
established.get(peer).map_or(0, |conns| {
u32::try_from(conns.len()).expect("Unexpectedly large number of connections for a peer.")
})
}
/// The configurable connection limits.

View File

@ -18,7 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::muxing::{StreamMuxer, StreamMuxerEvent, SubstreamRef, substream_from_ref};
use crate::muxing::{substream_from_ref, StreamMuxer, StreamMuxerEvent, SubstreamRef};
use futures::prelude::*;
use multiaddr::Multiaddr;
use smallvec::SmallVec;
@ -135,7 +135,9 @@ where
#[must_use]
pub fn close(mut self) -> (Close<TMuxer>, Vec<TUserData>) {
let substreams = self.cancel_outgoing();
let close = Close { muxer: self.inner.clone() };
let close = Close {
muxer: self.inner.clone(),
};
(close, substreams)
}
@ -150,17 +152,19 @@ where
}
/// Provides an API similar to `Future`.
pub fn poll(&mut self, cx: &mut Context<'_>) -> Poll<Result<SubstreamEvent<TMuxer, TUserData>, IoError>> {
pub fn poll(
&mut self,
cx: &mut Context<'_>,
) -> Poll<Result<SubstreamEvent<TMuxer, TUserData>, IoError>> {
// Polling inbound substream.
match self.inner.poll_event(cx) {
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(substream))) => {
let substream = substream_from_ref(self.inner.clone(), substream);
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream {
substream,
}));
return Poll::Ready(Ok(SubstreamEvent::InboundSubstream { substream }));
}
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) => {
return Poll::Ready(Ok(SubstreamEvent::AddressChange(addr)))
}
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(addr))) =>
return Poll::Ready(Ok(SubstreamEvent::AddressChange(addr))),
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => {}
}
@ -238,8 +242,7 @@ where
TMuxer: StreamMuxer,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("Close")
.finish()
f.debug_struct("Close").finish()
}
}
@ -251,22 +254,22 @@ where
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
SubstreamEvent::InboundSubstream { substream } => {
f.debug_struct("SubstreamEvent::OutboundClosed")
.field("substream", substream)
.finish()
},
SubstreamEvent::OutboundSubstream { user_data, substream } => {
f.debug_struct("SubstreamEvent::OutboundSubstream")
.field("user_data", user_data)
.field("substream", substream)
.finish()
},
SubstreamEvent::AddressChange(address) => {
f.debug_struct("SubstreamEvent::AddressChange")
.field("address", address)
.finish()
},
SubstreamEvent::InboundSubstream { substream } => f
.debug_struct("SubstreamEvent::OutboundClosed")
.field("substream", substream)
.finish(),
SubstreamEvent::OutboundSubstream {
user_data,
substream,
} => f
.debug_struct("SubstreamEvent::OutboundSubstream")
.field("user_data", user_data)
.field("substream", substream)
.finish(),
SubstreamEvent::AddressChange(address) => f
.debug_struct("SubstreamEvent::AddressChange")
.field("address", address)
.finish(),
}
}
}

View File

@ -20,29 +20,31 @@
use crate::{
muxing::{StreamMuxer, StreamMuxerEvent},
ProtocolName,
transport::{Transport, ListenerEvent, TransportError},
Multiaddr
transport::{ListenerEvent, Transport, TransportError},
Multiaddr, ProtocolName,
};
use futures::{
io::{IoSlice, IoSliceMut},
prelude::*,
};
use futures::{prelude::*, io::{IoSlice, IoSliceMut}};
use pin_project::pin_project;
use std::{fmt, io::{Error as IoError}, pin::Pin, task::Context, task::Poll};
use std::{fmt, io::Error as IoError, pin::Pin, task::Context, task::Poll};
#[derive(Debug, Copy, Clone)]
pub enum EitherError<A, B> {
A(A),
B(B)
B(B),
}
impl<A, B> fmt::Display for EitherError<A, B>
where
A: fmt::Display,
B: fmt::Display
B: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
EitherError::A(a) => a.fmt(f),
EitherError::B(b) => b.fmt(f)
EitherError::B(b) => b.fmt(f),
}
}
}
@ -50,12 +52,12 @@ where
impl<A, B> std::error::Error for EitherError<A, B>
where
A: std::error::Error,
B: std::error::Error
B: std::error::Error,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
EitherError::A(a) => a.source(),
EitherError::B(b) => b.source()
EitherError::B(b) => b.source(),
}
}
}
@ -74,16 +76,22 @@ where
A: AsyncRead,
B: AsyncRead,
{
fn poll_read(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize, IoError>> {
fn poll_read(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, IoError>> {
match self.project() {
EitherOutputProj::First(a) => AsyncRead::poll_read(a, cx, buf),
EitherOutputProj::Second(b) => AsyncRead::poll_read(b, cx, buf),
}
}
fn poll_read_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &mut [IoSliceMut<'_>])
-> Poll<Result<usize, IoError>>
{
fn poll_read_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &mut [IoSliceMut<'_>],
) -> Poll<Result<usize, IoError>> {
match self.project() {
EitherOutputProj::First(a) => AsyncRead::poll_read_vectored(a, cx, bufs),
EitherOutputProj::Second(b) => AsyncRead::poll_read_vectored(b, cx, bufs),
@ -96,16 +104,22 @@ where
A: AsyncWrite,
B: AsyncWrite,
{
fn poll_write(self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, IoError>> {
fn poll_write(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, IoError>> {
match self.project() {
EitherOutputProj::First(a) => AsyncWrite::poll_write(a, cx, buf),
EitherOutputProj::Second(b) => AsyncWrite::poll_write(b, cx, buf),
}
}
fn poll_write_vectored(self: Pin<&mut Self>, cx: &mut Context<'_>, bufs: &[IoSlice<'_>])
-> Poll<Result<usize, IoError>>
{
fn poll_write_vectored(
self: Pin<&mut Self>,
cx: &mut Context<'_>,
bufs: &[IoSlice<'_>],
) -> Poll<Result<usize, IoError>> {
match self.project() {
EitherOutputProj::First(a) => AsyncWrite::poll_write_vectored(a, cx, bufs),
EitherOutputProj::Second(b) => AsyncWrite::poll_write_vectored(b, cx, bufs),
@ -136,10 +150,12 @@ where
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match self.project() {
EitherOutputProj::First(a) => TryStream::try_poll_next(a, cx)
.map(|v| v.map(|r| r.map_err(EitherError::A))),
EitherOutputProj::Second(b) => TryStream::try_poll_next(b, cx)
.map(|v| v.map(|r| r.map_err(EitherError::B))),
EitherOutputProj::First(a) => {
TryStream::try_poll_next(a, cx).map(|v| v.map(|r| r.map_err(EitherError::A)))
}
EitherOutputProj::Second(b) => {
TryStream::try_poll_next(b, cx).map(|v| v.map(|r| r.map_err(EitherError::B)))
}
}
}
}
@ -189,23 +205,24 @@ where
type OutboundSubstream = EitherOutbound<A, B>;
type Error = IoError;
fn poll_event(&self, cx: &mut Context<'_>) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
fn poll_event(
&self,
cx: &mut Context<'_>,
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
match self {
EitherOutput::First(inner) => inner.poll_event(cx).map(|result| {
result.map_err(|e| e.into()).map(|event| {
match event {
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
StreamMuxerEvent::InboundSubstream(substream) =>
StreamMuxerEvent::InboundSubstream(EitherOutput::First(substream))
result.map_err(|e| e.into()).map(|event| match event {
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
StreamMuxerEvent::InboundSubstream(substream) => {
StreamMuxerEvent::InboundSubstream(EitherOutput::First(substream))
}
})
}),
EitherOutput::Second(inner) => inner.poll_event(cx).map(|result| {
result.map_err(|e| e.into()).map(|event| {
match event {
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
StreamMuxerEvent::InboundSubstream(substream) =>
StreamMuxerEvent::InboundSubstream(EitherOutput::Second(substream))
result.map_err(|e| e.into()).map(|event| match event {
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
StreamMuxerEvent::InboundSubstream(substream) => {
StreamMuxerEvent::InboundSubstream(EitherOutput::Second(substream))
}
})
}),
@ -219,96 +236,112 @@ where
}
}
fn poll_outbound(&self, cx: &mut Context<'_>, substream: &mut Self::OutboundSubstream) -> Poll<Result<Self::Substream, Self::Error>> {
fn poll_outbound(
&self,
cx: &mut Context<'_>,
substream: &mut Self::OutboundSubstream,
) -> Poll<Result<Self::Substream, Self::Error>> {
match (self, substream) {
(EitherOutput::First(ref inner), EitherOutbound::A(ref mut substream)) => {
inner.poll_outbound(cx, substream).map(|p| p.map(EitherOutput::First)).map_err(|e| e.into())
},
(EitherOutput::Second(ref inner), EitherOutbound::B(ref mut substream)) => {
inner.poll_outbound(cx, substream).map(|p| p.map(EitherOutput::Second)).map_err(|e| e.into())
},
_ => panic!("Wrong API usage")
(EitherOutput::First(ref inner), EitherOutbound::A(ref mut substream)) => inner
.poll_outbound(cx, substream)
.map(|p| p.map(EitherOutput::First))
.map_err(|e| e.into()),
(EitherOutput::Second(ref inner), EitherOutbound::B(ref mut substream)) => inner
.poll_outbound(cx, substream)
.map(|p| p.map(EitherOutput::Second))
.map_err(|e| e.into()),
_ => panic!("Wrong API usage"),
}
}
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
match self {
EitherOutput::First(inner) => {
match substream {
EitherOutbound::A(substream) => inner.destroy_outbound(substream),
_ => panic!("Wrong API usage")
}
EitherOutput::First(inner) => match substream {
EitherOutbound::A(substream) => inner.destroy_outbound(substream),
_ => panic!("Wrong API usage"),
},
EitherOutput::Second(inner) => {
match substream {
EitherOutbound::B(substream) => inner.destroy_outbound(substream),
_ => panic!("Wrong API usage")
}
EitherOutput::Second(inner) => match substream {
EitherOutbound::B(substream) => inner.destroy_outbound(substream),
_ => panic!("Wrong API usage"),
},
}
}
fn read_substream(&self, cx: &mut Context<'_>, sub: &mut Self::Substream, buf: &mut [u8]) -> Poll<Result<usize, Self::Error>> {
fn read_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
},
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.read_substream(cx, sub, buf).map_err(|e| e.into())
},
_ => panic!("Wrong API usage")
}
_ => panic!("Wrong API usage"),
}
}
fn write_substream(&self, cx: &mut Context<'_>, sub: &mut Self::Substream, buf: &[u8]) -> Poll<Result<usize, Self::Error>> {
fn write_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
},
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.write_substream(cx, sub, buf).map_err(|e| e.into())
},
_ => panic!("Wrong API usage")
}
_ => panic!("Wrong API usage"),
}
}
fn flush_substream(&self, cx: &mut Context<'_>, sub: &mut Self::Substream) -> Poll<Result<(), Self::Error>> {
fn flush_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.flush_substream(cx, sub).map_err(|e| e.into())
},
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.flush_substream(cx, sub).map_err(|e| e.into())
},
_ => panic!("Wrong API usage")
}
_ => panic!("Wrong API usage"),
}
}
fn shutdown_substream(&self, cx: &mut Context<'_>, sub: &mut Self::Substream) -> Poll<Result<(), Self::Error>> {
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
sub: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
match (self, sub) {
(EitherOutput::First(ref inner), EitherOutput::First(ref mut sub)) => {
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
},
}
(EitherOutput::Second(ref inner), EitherOutput::Second(ref mut sub)) => {
inner.shutdown_substream(cx, sub).map_err(|e| e.into())
},
_ => panic!("Wrong API usage")
}
_ => panic!("Wrong API usage"),
}
}
fn destroy_substream(&self, substream: Self::Substream) {
match self {
EitherOutput::First(inner) => {
match substream {
EitherOutput::First(substream) => inner.destroy_substream(substream),
_ => panic!("Wrong API usage")
}
EitherOutput::First(inner) => match substream {
EitherOutput::First(substream) => inner.destroy_substream(substream),
_ => panic!("Wrong API usage"),
},
EitherOutput::Second(inner) => {
match substream {
EitherOutput::Second(substream) => inner.destroy_substream(substream),
_ => panic!("Wrong API usage")
}
EitherOutput::Second(inner) => match substream {
EitherOutput::Second(substream) => inner.destroy_substream(substream),
_ => panic!("Wrong API usage"),
},
}
}
@ -344,25 +377,33 @@ pub enum EitherListenStream<A, B> {
Second(#[pin] B),
}
impl<AStream, BStream, AInner, BInner, AError, BError> Stream for EitherListenStream<AStream, BStream>
impl<AStream, BStream, AInner, BInner, AError, BError> Stream
for EitherListenStream<AStream, BStream>
where
AStream: TryStream<Ok = ListenerEvent<AInner, AError>, Error = AError>,
BStream: TryStream<Ok = ListenerEvent<BInner, BError>, Error = BError>,
{
type Item = Result<ListenerEvent<EitherFuture<AInner, BInner>, EitherError<AError, BError>>, EitherError<AError, BError>>;
type Item = Result<
ListenerEvent<EitherFuture<AInner, BInner>, EitherError<AError, BError>>,
EitherError<AError, BError>,
>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match self.project() {
EitherListenStreamProj::First(a) => match TryStream::try_poll_next(a, cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(None) => Poll::Ready(None),
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le.map(EitherFuture::First).map_err(EitherError::A)))),
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le
.map(EitherFuture::First)
.map_err(EitherError::A)))),
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::A(err)))),
},
EitherListenStreamProj::Second(a) => match TryStream::try_poll_next(a, cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(None) => Poll::Ready(None),
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le.map(EitherFuture::Second).map_err(EitherError::B)))),
Poll::Ready(Some(Ok(le))) => Poll::Ready(Some(Ok(le
.map(EitherFuture::Second)
.map_err(EitherError::B)))),
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::B(err)))),
},
}
@ -388,9 +429,11 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherFutureProj::First(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::First).map_err(EitherError::A),
.map_ok(EitherOutput::First)
.map_err(EitherError::A),
EitherFutureProj::Second(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::Second).map_err(EitherError::B),
.map_ok(EitherOutput::Second)
.map_err(EitherError::B),
}
}
}
@ -398,7 +441,10 @@ where
#[pin_project(project = EitherFuture2Proj)]
#[derive(Debug, Copy, Clone)]
#[must_use = "futures do nothing unless polled"]
pub enum EitherFuture2<A, B> { A(#[pin] A), B(#[pin] B) }
pub enum EitherFuture2<A, B> {
A(#[pin] A),
B(#[pin] B),
}
impl<AFut, BFut, AItem, BItem, AError, BError> Future for EitherFuture2<AFut, BFut>
where
@ -410,21 +456,26 @@ where
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.project() {
EitherFuture2Proj::A(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::First).map_err(EitherError::A),
.map_ok(EitherOutput::First)
.map_err(EitherError::A),
EitherFuture2Proj::B(a) => TryFuture::try_poll(a, cx)
.map_ok(EitherOutput::Second).map_err(EitherError::B),
.map_ok(EitherOutput::Second)
.map_err(EitherError::B),
}
}
}
#[derive(Debug, Clone)]
pub enum EitherName<A, B> { A(A), B(B) }
pub enum EitherName<A, B> {
A(A),
B(B),
}
impl<A: ProtocolName, B: ProtocolName> ProtocolName for EitherName<A, B> {
fn protocol_name(&self) -> &[u8] {
match self {
EitherName::A(a) => a.protocol_name(),
EitherName::B(b) => b.protocol_name()
EitherName::B(b) => b.protocol_name(),
}
}
}

View File

@ -41,7 +41,7 @@ pub mod secp256k1;
pub mod error;
use self::error::*;
use crate::{PeerId, keys_proto};
use crate::{keys_proto, PeerId};
/// Identity keypair of a node.
///
@ -69,7 +69,7 @@ pub enum Keypair {
Rsa(rsa::Keypair),
/// A Secp256k1 keypair.
#[cfg(feature = "secp256k1")]
Secp256k1(secp256k1::Keypair)
Secp256k1(secp256k1::Keypair),
}
impl Keypair {
@ -112,7 +112,7 @@ impl Keypair {
#[cfg(not(target_arch = "wasm32"))]
Rsa(ref pair) => pair.sign(msg),
#[cfg(feature = "secp256k1")]
Secp256k1(ref pair) => pair.secret().sign(msg)
Secp256k1(ref pair) => pair.secret().sign(msg),
}
}
@ -154,7 +154,6 @@ impl Keypair {
Ok(pk.encode_to_vec())
}
/// Decode a private key from a protobuf structure and parse it as a [`Keypair`].
pub fn from_protobuf_encoding(bytes: &[u8]) -> Result<Keypair, DecodingError> {
use prost::Message;
@ -163,19 +162,20 @@ impl Keypair {
.map_err(|e| DecodingError::new("Protobuf").source(e))
.map(zeroize::Zeroizing::new)?;
let key_type = keys_proto::KeyType::from_i32(private_key.r#type)
.ok_or_else(|| DecodingError::new(format!("unknown key type: {}", private_key.r#type)))?;
let key_type = keys_proto::KeyType::from_i32(private_key.r#type).ok_or_else(|| {
DecodingError::new(format!("unknown key type: {}", private_key.r#type))
})?;
match key_type {
keys_proto::KeyType::Ed25519 => {
ed25519::Keypair::decode(&mut private_key.data).map(Keypair::Ed25519)
},
keys_proto::KeyType::Rsa => {
Err(DecodingError::new("Decoding RSA key from Protobuf is unsupported."))
},
keys_proto::KeyType::Secp256k1 => {
Err(DecodingError::new("Decoding Secp256k1 key from Protobuf is unsupported."))
},
}
keys_proto::KeyType::Rsa => Err(DecodingError::new(
"Decoding RSA key from Protobuf is unsupported.",
)),
keys_proto::KeyType::Secp256k1 => Err(DecodingError::new(
"Decoding Secp256k1 key from Protobuf is unsupported.",
)),
}
}
}
@ -197,7 +197,7 @@ pub enum PublicKey {
Rsa(rsa::PublicKey),
#[cfg(feature = "secp256k1")]
/// A public Secp256k1 key.
Secp256k1(secp256k1::PublicKey)
Secp256k1(secp256k1::PublicKey),
}
impl PublicKey {
@ -212,7 +212,7 @@ impl PublicKey {
#[cfg(not(target_arch = "wasm32"))]
Rsa(pk) => pk.verify(msg, sig),
#[cfg(feature = "secp256k1")]
Secp256k1(pk) => pk.verify(msg, sig)
Secp256k1(pk) => pk.verify(msg, sig),
}
}
@ -222,27 +222,26 @@ impl PublicKey {
use prost::Message;
let public_key = match self {
PublicKey::Ed25519(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ed25519 as i32,
data: key.encode().to_vec()
},
PublicKey::Ed25519(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Ed25519 as i32,
data: key.encode().to_vec(),
},
#[cfg(not(target_arch = "wasm32"))]
PublicKey::Rsa(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Rsa as i32,
data: key.encode_x509()
},
PublicKey::Rsa(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Rsa as i32,
data: key.encode_x509(),
},
#[cfg(feature = "secp256k1")]
PublicKey::Secp256k1(key) =>
keys_proto::PublicKey {
r#type: keys_proto::KeyType::Secp256k1 as i32,
data: key.encode().to_vec()
}
PublicKey::Secp256k1(key) => keys_proto::PublicKey {
r#type: keys_proto::KeyType::Secp256k1 as i32,
data: key.encode().to_vec(),
},
};
let mut buf = Vec::with_capacity(public_key.encoded_len());
public_key.encode(&mut buf).expect("Vec<u8> provides capacity as needed");
public_key
.encode(&mut buf)
.expect("Vec<u8> provides capacity as needed");
buf
}
@ -261,7 +260,7 @@ impl PublicKey {
match key_type {
keys_proto::KeyType::Ed25519 => {
ed25519::PublicKey::decode(&pubkey.data).map(PublicKey::Ed25519)
},
}
#[cfg(not(target_arch = "wasm32"))]
keys_proto::KeyType::Rsa => {
rsa::PublicKey::decode_x509(&pubkey.data).map(PublicKey::Rsa)
@ -270,7 +269,7 @@ impl PublicKey {
keys_proto::KeyType::Rsa => {
log::debug!("support for RSA was disabled at compile-time");
Err(DecodingError::new("Unsupported"))
},
}
#[cfg(feature = "secp256k1")]
keys_proto::KeyType::Secp256k1 => {
secp256k1::PublicKey::decode(&pubkey.data).map(PublicKey::Secp256k1)
@ -311,7 +310,8 @@ mod tests {
fn keypair_from_protobuf_encoding() {
// E.g. retrieved from an IPFS config file.
let base_64_encoded = "CAESQL6vdKQuznQosTrW7FWI9At+XX7EBf0BnZLhb6w+N+XSQSdfInl6c7U4NuxXJlhKcRBlBw9d0tj2dfBIVf6mcPA=";
let expected_peer_id = PeerId::from_str("12D3KooWEChVMMMzV8acJ53mJHrw1pQ27UAGkCxWXLJutbeUMvVu").unwrap();
let expected_peer_id =
PeerId::from_str("12D3KooWEChVMMMzV8acJ53mJHrw1pQ27UAGkCxWXLJutbeUMvVu").unwrap();
let encoded = base64::decode(base_64_encoded).unwrap();

View File

@ -20,12 +20,12 @@
//! Ed25519 keys.
use super::error::DecodingError;
use core::fmt;
use ed25519_dalek::{self as ed25519, Signer as _, Verifier as _};
use rand::RngCore;
use std::convert::TryFrom;
use super::error::DecodingError;
use zeroize::Zeroize;
use core::fmt;
/// An Ed25519 keypair.
pub struct Keypair(ed25519::Keypair);
@ -49,7 +49,10 @@ impl Keypair {
/// Note that this binary format is the same as `ed25519_dalek`'s and `ed25519_zebra`'s.
pub fn decode(kp: &mut [u8]) -> Result<Keypair, DecodingError> {
ed25519::Keypair::from_bytes(kp)
.map(|k| { kp.zeroize(); Keypair(k) })
.map(|k| {
kp.zeroize();
Keypair(k)
})
.map_err(|e| DecodingError::new("Ed25519 keypair").source(e))
}
@ -72,7 +75,9 @@ impl Keypair {
impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Keypair").field("public", &self.0.public).finish()
f.debug_struct("Keypair")
.field("public", &self.0.public)
.finish()
}
}
@ -80,7 +85,8 @@ impl Clone for Keypair {
fn clone(&self) -> Keypair {
let mut sk_bytes = self.0.secret.to_bytes();
let secret = SecretKey::from_bytes(&mut sk_bytes)
.expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k").0;
.expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k")
.0;
let public = ed25519::PublicKey::from_bytes(&self.0.public.to_bytes())
.expect("ed25519::PublicKey::from_bytes(to_bytes(k)) != k");
Keypair(ed25519::Keypair { secret, public })
@ -99,7 +105,10 @@ impl From<SecretKey> for Keypair {
fn from(sk: SecretKey) -> Keypair {
let secret: ed25519::ExpandedSecretKey = (&sk.0).into();
let public = ed25519::PublicKey::from(&secret);
Keypair(ed25519::Keypair { secret: sk.0, public })
Keypair(ed25519::Keypair {
secret: sk.0,
public,
})
}
}
@ -120,7 +129,9 @@ impl fmt::Debug for PublicKey {
impl PublicKey {
/// Verify the Ed25519 signature on a message using the public key.
pub fn verify(&self, msg: &[u8], sig: &[u8]) -> bool {
ed25519::Signature::try_from(sig).and_then(|s| self.0.verify(msg, &s)).is_ok()
ed25519::Signature::try_from(sig)
.and_then(|s| self.0.verify(msg, &s))
.is_ok()
}
/// Encode the public key into a byte array in compressed form, i.e.
@ -150,8 +161,7 @@ impl AsRef<[u8]> for SecretKey {
impl Clone for SecretKey {
fn clone(&self) -> SecretKey {
let mut sk_bytes = self.0.to_bytes();
Self::from_bytes(&mut sk_bytes)
.expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k")
Self::from_bytes(&mut sk_bytes).expect("ed25519::SecretKey::from_bytes(to_bytes(k)) != k")
}
}
@ -166,8 +176,11 @@ impl SecretKey {
pub fn generate() -> SecretKey {
let mut bytes = [0u8; 32];
rand::thread_rng().fill_bytes(&mut bytes);
SecretKey(ed25519::SecretKey::from_bytes(&bytes)
.expect("this returns `Err` only if the length is wrong; the length is correct; qed"))
SecretKey(
ed25519::SecretKey::from_bytes(&bytes).expect(
"this returns `Err` only if the length is wrong; the length is correct; qed",
),
)
}
/// Create an Ed25519 secret key from a byte slice, zeroing the input on success.
@ -188,9 +201,7 @@ mod tests {
use quickcheck::*;
fn eq_keypairs(kp1: &Keypair, kp2: &Keypair) -> bool {
kp1.public() == kp2.public()
&&
kp1.0.secret.as_bytes() == kp2.0.secret.as_bytes()
kp1.public() == kp2.public() && kp1.0.secret.as_bytes() == kp2.0.secret.as_bytes()
}
#[test]
@ -199,9 +210,7 @@ mod tests {
let kp1 = Keypair::generate();
let mut kp1_enc = kp1.encode();
let kp2 = Keypair::decode(&mut kp1_enc).unwrap();
eq_keypairs(&kp1, &kp2)
&&
kp1_enc.iter().all(|b| *b == 0)
eq_keypairs(&kp1, &kp2) && kp1_enc.iter().all(|b| *b == 0)
}
QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
}
@ -212,9 +221,7 @@ mod tests {
let kp1 = Keypair::generate();
let mut sk = kp1.0.secret.to_bytes();
let kp2 = Keypair::from(SecretKey::from_bytes(&mut sk).unwrap());
eq_keypairs(&kp1, &kp2)
&&
sk == [0u8; 32]
eq_keypairs(&kp1, &kp2) && sk == [0u8; 32]
}
QuickCheck::new().tests(10).quickcheck(prop as fn() -> _);
}

View File

@ -27,16 +27,22 @@ use std::fmt;
#[derive(Debug)]
pub struct DecodingError {
msg: String,
source: Option<Box<dyn Error + Send + Sync>>
source: Option<Box<dyn Error + Send + Sync>>,
}
impl DecodingError {
pub(crate) fn new<S: ToString>(msg: S) -> Self {
Self { msg: msg.to_string(), source: None }
Self {
msg: msg.to_string(),
source: None,
}
}
pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self {
Self { source: Some(Box::new(source)), .. self }
Self {
source: Some(Box::new(source)),
..self
}
}
}
@ -56,17 +62,23 @@ impl Error for DecodingError {
#[derive(Debug)]
pub struct SigningError {
msg: String,
source: Option<Box<dyn Error + Send + Sync>>
source: Option<Box<dyn Error + Send + Sync>>,
}
/// An error during encoding of key material.
impl SigningError {
pub(crate) fn new<S: ToString>(msg: S) -> Self {
Self { msg: msg.to_string(), source: None }
Self {
msg: msg.to_string(),
source: None,
}
}
pub(crate) fn source(self, source: impl Error + Send + Sync + 'static) -> Self {
Self { source: Some(Box::new(source)), .. self }
Self {
source: Some(Box::new(source)),
..self
}
}
}
@ -81,4 +93,3 @@ impl Error for SigningError {
self.source.as_ref().map(|s| &**s as &dyn Error)
}
}

View File

@ -20,12 +20,12 @@
//! RSA keys.
use asn1_der::typed::{DerEncodable, DerDecodable, DerTypeView, Sequence};
use asn1_der::{DerObject, Asn1DerError, Asn1DerErrorVariant, Sink, VecBacking};
use super::error::*;
use asn1_der::typed::{DerDecodable, DerEncodable, DerTypeView, Sequence};
use asn1_der::{Asn1DerError, Asn1DerErrorVariant, DerObject, Sink, VecBacking};
use ring::rand::SystemRandom;
use ring::signature::{self, RsaKeyPair, RSA_PKCS1_SHA256, RSA_PKCS1_2048_8192_SHA256};
use ring::signature::KeyPair;
use ring::signature::{self, RsaKeyPair, RSA_PKCS1_2048_8192_SHA256, RSA_PKCS1_SHA256};
use std::{fmt, sync::Arc};
use zeroize::Zeroize;
@ -56,7 +56,7 @@ impl Keypair {
let rng = SystemRandom::new();
match self.0.sign(&RSA_PKCS1_SHA256, &rng, &data, &mut signature) {
Ok(()) => Ok(signature),
Err(e) => Err(SigningError::new("RSA").source(e))
Err(e) => Err(SigningError::new("RSA").source(e)),
}
}
}
@ -89,12 +89,14 @@ impl PublicKey {
let spki = Asn1SubjectPublicKeyInfo {
algorithmIdentifier: Asn1RsaEncryption {
algorithm: Asn1OidRsaEncryption,
parameters: ()
parameters: (),
},
subjectPublicKey: Asn1SubjectPublicKey(self.clone())
subjectPublicKey: Asn1SubjectPublicKey(self.clone()),
};
let mut buf = Vec::new();
let buf = spki.encode(&mut buf).map(|_| buf)
let buf = spki
.encode(&mut buf)
.map(|_| buf)
.expect("RSA X.509 public key encoding failed.");
buf
}
@ -127,7 +129,7 @@ impl fmt::Debug for PublicKey {
/// A raw ASN1 OID.
#[derive(Copy, Clone)]
struct Asn1RawOid<'a> {
object: DerObject<'a>
object: DerObject<'a>,
}
impl<'a> Asn1RawOid<'a> {
@ -179,7 +181,7 @@ impl Asn1OidRsaEncryption {
///
/// [RFC-3279]: https://tools.ietf.org/html/rfc3279#section-2.3.1
/// [RFC-5280]: https://tools.ietf.org/html/rfc5280#section-4.1
const OID: [u8;9] = [ 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01 ];
const OID: [u8; 9] = [0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0D, 0x01, 0x01, 0x01];
}
impl DerEncodable for Asn1OidRsaEncryption {
@ -194,7 +196,7 @@ impl DerDecodable<'_> for Asn1OidRsaEncryption {
oid if oid == Self::OID => Ok(Self),
_ => Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData(
"DER object is not the 'rsaEncryption' identifier.",
)))
))),
}
}
}
@ -202,7 +204,7 @@ impl DerDecodable<'_> for Asn1OidRsaEncryption {
/// The ASN.1 AlgorithmIdentifier for "rsaEncryption".
struct Asn1RsaEncryption {
algorithm: Asn1OidRsaEncryption,
parameters: ()
parameters: (),
}
impl DerEncodable for Asn1RsaEncryption {
@ -211,7 +213,9 @@ impl DerEncodable for Asn1RsaEncryption {
let algorithm = self.algorithm.der_object(VecBacking(&mut algorithm_buf))?;
let mut parameters_buf = Vec::new();
let parameters = self.parameters.der_object(VecBacking(&mut parameters_buf))?;
let parameters = self
.parameters
.der_object(VecBacking(&mut parameters_buf))?;
Sequence::write(&[algorithm, parameters], sink)
}
@ -221,7 +225,7 @@ impl DerDecodable<'_> for Asn1RsaEncryption {
fn load(object: DerObject<'_>) -> Result<Self, Asn1DerError> {
let seq: Sequence = Sequence::load(object)?;
Ok(Self{
Ok(Self {
algorithm: seq.get_as(0)?,
parameters: seq.get_as(1)?,
})
@ -248,9 +252,9 @@ impl DerEncodable for Asn1SubjectPublicKey {
impl DerDecodable<'_> for Asn1SubjectPublicKey {
fn load(object: DerObject<'_>) -> Result<Self, Asn1DerError> {
if object.tag() != 3 {
return Err(Asn1DerError::new(
Asn1DerErrorVariant::InvalidData("DER object tag is not the bit string tag."),
));
return Err(Asn1DerError::new(Asn1DerErrorVariant::InvalidData(
"DER object tag is not the bit string tag.",
)));
}
let pk_der: Vec<u8> = object.value().into_iter().skip(1).cloned().collect();
@ -264,13 +268,15 @@ impl DerDecodable<'_> for Asn1SubjectPublicKey {
#[allow(non_snake_case)]
struct Asn1SubjectPublicKeyInfo {
algorithmIdentifier: Asn1RsaEncryption,
subjectPublicKey: Asn1SubjectPublicKey
subjectPublicKey: Asn1SubjectPublicKey,
}
impl DerEncodable for Asn1SubjectPublicKeyInfo {
fn encode<S: Sink>(&self, sink: &mut S) -> Result<(), Asn1DerError> {
let mut identifier_buf = Vec::new();
let identifier = self.algorithmIdentifier.der_object(VecBacking(&mut identifier_buf))?;
let identifier = self
.algorithmIdentifier
.der_object(VecBacking(&mut identifier_buf))?;
let mut key_buf = Vec::new();
let key = self.subjectPublicKey.der_object(VecBacking(&mut key_buf))?;
@ -340,6 +346,8 @@ mod tests {
fn prop(SomeKeypair(kp): SomeKeypair, msg: Vec<u8>) -> Result<bool, SigningError> {
kp.sign(&msg).map(|s| kp.public().verify(&msg, &s))
}
QuickCheck::new().tests(10).quickcheck(prop as fn(_,_) -> _);
QuickCheck::new()
.tests(10)
.quickcheck(prop as fn(_, _) -> _);
}
}

View File

@ -20,18 +20,18 @@
//! Secp256k1 keys.
use asn1_der::typed::{DerDecodable, Sequence};
use sha2::{Digest as ShaDigestTrait, Sha256};
use libsecp256k1::{Message, Signature};
use super::error::{DecodingError, SigningError};
use zeroize::Zeroize;
use asn1_der::typed::{DerDecodable, Sequence};
use core::fmt;
use libsecp256k1::{Message, Signature};
use sha2::{Digest as ShaDigestTrait, Sha256};
use zeroize::Zeroize;
/// A Secp256k1 keypair.
#[derive(Clone)]
pub struct Keypair {
secret: SecretKey,
public: PublicKey
public: PublicKey,
}
impl Keypair {
@ -53,7 +53,9 @@ impl Keypair {
impl fmt::Debug for Keypair {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_struct("Keypair").field("public", &self.public).finish()
f.debug_struct("Keypair")
.field("public", &self.public)
.finish()
}
}
@ -110,10 +112,11 @@ impl SecretKey {
let der_obj = der.as_mut();
let obj: Sequence = DerDecodable::decode(der_obj)
.map_err(|e| DecodingError::new("Secp256k1 DER ECPrivateKey").source(e))?;
let sk_obj = obj.get(1)
let sk_obj = obj
.get(1)
.map_err(|e| DecodingError::new("Not enough elements in DER").source(e))?;
let mut sk_bytes: Vec<u8> = asn1_der::typed::DerDecodable::load(sk_obj)
.map_err(DecodingError::new)?;
let mut sk_bytes: Vec<u8> =
asn1_der::typed::DerDecodable::load(sk_obj).map_err(DecodingError::new)?;
let sk = SecretKey::from_bytes(&mut sk_bytes)?;
sk_bytes.zeroize();
der_obj.zeroize();
@ -138,7 +141,11 @@ impl SecretKey {
pub fn sign_hash(&self, msg: &[u8]) -> Result<Vec<u8>, SigningError> {
let m = Message::parse_slice(msg)
.map_err(|_| SigningError::new("failed to parse secp256k1 digest"))?;
Ok(libsecp256k1::sign(&m, &self.0).0.serialize_der().as_ref().into())
Ok(libsecp256k1::sign(&m, &self.0)
.0
.serialize_der()
.as_ref()
.into())
}
}

View File

@ -54,16 +54,16 @@ pub mod network;
pub mod transport;
pub mod upgrade;
pub use connection::{Connected, ConnectedPoint, Endpoint};
pub use identity::PublicKey;
pub use multiaddr::Multiaddr;
pub use multihash;
pub use muxing::StreamMuxer;
pub use peer_id::PeerId;
pub use identity::PublicKey;
pub use transport::Transport;
pub use translation::address_translation;
pub use upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo, UpgradeError, ProtocolName};
pub use connection::{Connected, Endpoint, ConnectedPoint};
pub use network::Network;
pub use peer_id::PeerId;
pub use translation::address_translation;
pub use transport::Transport;
pub use upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeError, UpgradeInfo};
use std::{future::Future, pin::Pin};

View File

@ -55,7 +55,12 @@ use fnv::FnvHashMap;
use futures::{future, prelude::*, task::Context, task::Poll};
use multiaddr::Multiaddr;
use parking_lot::Mutex;
use std::{io, ops::Deref, fmt, pin::Pin, sync::atomic::{AtomicUsize, Ordering}};
use std::{
fmt, io,
ops::Deref,
pin::Pin,
sync::atomic::{AtomicUsize, Ordering},
};
pub use self::singleton::SingletonMuxer;
@ -95,7 +100,10 @@ pub trait StreamMuxer {
/// work, such as processing incoming packets and polling timers.
///
/// An error can be generated if the connection has been closed.
fn poll_event(&self, cx: &mut Context<'_>) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>>;
fn poll_event(
&self,
cx: &mut Context<'_>,
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>>;
/// Opens a new outgoing substream, and produces the equivalent to a future that will be
/// resolved when it becomes available.
@ -113,8 +121,11 @@ pub trait StreamMuxer {
///
/// May panic or produce an undefined result if an earlier polling of the same substream
/// returned `Ready` or `Err`.
fn poll_outbound(&self, cx: &mut Context<'_>, s: &mut Self::OutboundSubstream)
-> Poll<Result<Self::Substream, Self::Error>>;
fn poll_outbound(
&self,
cx: &mut Context<'_>,
s: &mut Self::OutboundSubstream,
) -> Poll<Result<Self::Substream, Self::Error>>;
/// Destroys an outbound substream future. Use this after the outbound substream has finished,
/// or if you want to interrupt it.
@ -131,8 +142,12 @@ pub trait StreamMuxer {
///
/// An error can be generated if the connection has been closed, or if a protocol misbehaviour
/// happened.
fn read_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream, buf: &mut [u8])
-> Poll<Result<usize, Self::Error>>;
fn read_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>>;
/// Write data to a substream. The behaviour is the same as `futures::AsyncWrite::poll_write`.
///
@ -145,8 +160,12 @@ pub trait StreamMuxer {
///
/// It is incorrect to call this method on a substream if you called `shutdown_substream` on
/// this substream earlier.
fn write_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream, buf: &[u8])
-> Poll<Result<usize, Self::Error>>;
fn write_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>>;
/// Flushes a substream. The behaviour is the same as `futures::AsyncWrite::poll_flush`.
///
@ -158,8 +177,11 @@ pub trait StreamMuxer {
/// call this method may be notified.
///
/// > **Note**: This method may be implemented as a call to `flush_all`.
fn flush_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream)
-> Poll<Result<(), Self::Error>>;
fn flush_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>>;
/// Attempts to shut down the writing side of a substream. The behaviour is similar to
/// `AsyncWrite::poll_close`.
@ -172,8 +194,11 @@ pub trait StreamMuxer {
///
/// An error can be generated if the connection has been closed, or if a protocol misbehaviour
/// happened.
fn shutdown_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream)
-> Poll<Result<(), Self::Error>>;
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>>;
/// Destroys a substream.
fn destroy_substream(&self, s: Self::Substream);
@ -246,14 +271,12 @@ where
P::Target: StreamMuxer,
{
let muxer2 = muxer.clone();
future::poll_fn(move |cx| muxer.poll_event(cx))
.map_ok(|event| {
match event {
StreamMuxerEvent::InboundSubstream(substream) =>
StreamMuxerEvent::InboundSubstream(substream_from_ref(muxer2, substream)),
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
}
})
future::poll_fn(move |cx| muxer.poll_event(cx)).map_ok(|event| match event {
StreamMuxerEvent::InboundSubstream(substream) => {
StreamMuxerEvent::InboundSubstream(substream_from_ref(muxer2, substream))
}
StreamMuxerEvent::AddressChange(addr) => StreamMuxerEvent::AddressChange(addr),
})
}
/// Same as `outbound_from_ref`, but wraps the output in an object that
@ -336,7 +359,8 @@ where
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
this.muxer.poll_outbound(cx, this.outbound.as_mut().expect("outbound was empty"))
this.muxer
.poll_outbound(cx, this.outbound.as_mut().expect("outbound was empty"))
}
}
@ -408,7 +432,11 @@ where
P: Deref,
P::Target: StreamMuxer,
{
fn poll_read(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &mut [u8]) -> Poll<Result<usize, io::Error>> {
fn poll_read(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
@ -423,7 +451,11 @@ where
P: Deref,
P::Target: StreamMuxer,
{
fn poll_write(mut self: Pin<&mut Self>, cx: &mut Context<'_>, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
fn poll_write(
mut self: Pin<&mut Self>,
cx: &mut Context<'_>,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
// We use a `this` because the compiler isn't smart enough to allow mutably borrowing
// multiple different fields from the `Pin` at the same time.
let this = &mut *self;
@ -440,20 +472,16 @@ where
let s = this.substream.as_mut().expect("substream was empty");
loop {
match this.shutdown_state {
ShutdownState::Shutdown => {
match this.muxer.shutdown_substream(cx, s) {
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Flush,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => return Poll::Pending,
}
}
ShutdownState::Flush => {
match this.muxer.flush_substream(cx, s) {
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Done,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => return Poll::Pending,
}
}
ShutdownState::Shutdown => match this.muxer.shutdown_substream(cx, s) {
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Flush,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => return Poll::Pending,
},
ShutdownState::Flush => match this.muxer.flush_substream(cx, s) {
Poll::Ready(Ok(())) => this.shutdown_state = ShutdownState::Done,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
Poll::Pending => return Poll::Pending,
},
ShutdownState::Done => {
return Poll::Ready(Ok(()));
}
@ -477,13 +505,18 @@ where
P::Target: StreamMuxer,
{
fn drop(&mut self) {
self.muxer.destroy_substream(self.substream.take().expect("substream was empty"))
self.muxer
.destroy_substream(self.substream.take().expect("substream was empty"))
}
}
/// Abstract `StreamMuxer`.
pub struct StreamMuxerBox {
inner: Box<dyn StreamMuxer<Substream = usize, OutboundSubstream = usize, Error = io::Error> + Send + Sync>,
inner: Box<
dyn StreamMuxer<Substream = usize, OutboundSubstream = usize, Error = io::Error>
+ Send
+ Sync,
>,
}
impl StreamMuxerBox {
@ -514,7 +547,10 @@ impl StreamMuxer for StreamMuxerBox {
type Error = io::Error;
#[inline]
fn poll_event(&self, cx: &mut Context<'_>) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
fn poll_event(
&self,
cx: &mut Context<'_>,
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
self.inner.poll_event(cx)
}
@ -524,7 +560,11 @@ impl StreamMuxer for StreamMuxerBox {
}
#[inline]
fn poll_outbound(&self, cx: &mut Context<'_>, s: &mut Self::OutboundSubstream) -> Poll<Result<Self::Substream, Self::Error>> {
fn poll_outbound(
&self,
cx: &mut Context<'_>,
s: &mut Self::OutboundSubstream,
) -> Poll<Result<Self::Substream, Self::Error>> {
self.inner.poll_outbound(cx, s)
}
@ -534,22 +574,40 @@ impl StreamMuxer for StreamMuxerBox {
}
#[inline]
fn read_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream, buf: &mut [u8]) -> Poll<Result<usize, Self::Error>> {
fn read_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>> {
self.inner.read_substream(cx, s, buf)
}
#[inline]
fn write_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream, buf: &[u8]) -> Poll<Result<usize, Self::Error>> {
fn write_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
self.inner.write_substream(cx, s, buf)
}
#[inline]
fn flush_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream) -> Poll<Result<(), Self::Error>> {
fn flush_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
self.inner.flush_substream(cx, s)
}
#[inline]
fn shutdown_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream) -> Poll<Result<(), Self::Error>> {
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
self.inner.shutdown_substream(cx, s)
}
@ -569,7 +627,10 @@ impl StreamMuxer for StreamMuxerBox {
}
}
struct Wrap<T> where T: StreamMuxer {
struct Wrap<T>
where
T: StreamMuxer,
{
inner: T,
substreams: Mutex<FnvHashMap<usize, T::Substream>>,
next_substream: AtomicUsize,
@ -586,11 +647,15 @@ where
type Error = io::Error;
#[inline]
fn poll_event(&self, cx: &mut Context<'_>) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
fn poll_event(
&self,
cx: &mut Context<'_>,
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, Self::Error>> {
let substream = match self.inner.poll_event(cx) {
Poll::Pending => return Poll::Pending,
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(a))) =>
return Poll::Ready(Ok(StreamMuxerEvent::AddressChange(a))),
Poll::Ready(Ok(StreamMuxerEvent::AddressChange(a))) => {
return Poll::Ready(Ok(StreamMuxerEvent::AddressChange(a)))
}
Poll::Ready(Ok(StreamMuxerEvent::InboundSubstream(s))) => s,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
};
@ -615,7 +680,10 @@ where
substream: &mut Self::OutboundSubstream,
) -> Poll<Result<Self::Substream, Self::Error>> {
let mut list = self.outbound.lock();
let substream = match self.inner.poll_outbound(cx, list.get_mut(substream).unwrap()) {
let substream = match self
.inner
.poll_outbound(cx, list.get_mut(substream).unwrap())
{
Poll::Pending => return Poll::Pending,
Poll::Ready(Ok(s)) => s,
Poll::Ready(Err(err)) => return Poll::Ready(Err(err.into())),
@ -628,37 +696,65 @@ where
#[inline]
fn destroy_outbound(&self, substream: Self::OutboundSubstream) {
let mut list = self.outbound.lock();
self.inner.destroy_outbound(list.remove(&substream).unwrap())
self.inner
.destroy_outbound(list.remove(&substream).unwrap())
}
#[inline]
fn read_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream, buf: &mut [u8]) -> Poll<Result<usize, Self::Error>> {
fn read_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, Self::Error>> {
let mut list = self.substreams.lock();
self.inner.read_substream(cx, list.get_mut(s).unwrap(), buf).map_err(|e| e.into())
self.inner
.read_substream(cx, list.get_mut(s).unwrap(), buf)
.map_err(|e| e.into())
}
#[inline]
fn write_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream, buf: &[u8]) -> Poll<Result<usize, Self::Error>> {
fn write_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, Self::Error>> {
let mut list = self.substreams.lock();
self.inner.write_substream(cx, list.get_mut(s).unwrap(), buf).map_err(|e| e.into())
self.inner
.write_substream(cx, list.get_mut(s).unwrap(), buf)
.map_err(|e| e.into())
}
#[inline]
fn flush_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream) -> Poll<Result<(), Self::Error>> {
fn flush_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
let mut list = self.substreams.lock();
self.inner.flush_substream(cx, list.get_mut(s).unwrap()).map_err(|e| e.into())
self.inner
.flush_substream(cx, list.get_mut(s).unwrap())
.map_err(|e| e.into())
}
#[inline]
fn shutdown_substream(&self, cx: &mut Context<'_>, s: &mut Self::Substream) -> Poll<Result<(), Self::Error>> {
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
s: &mut Self::Substream,
) -> Poll<Result<(), Self::Error>> {
let mut list = self.substreams.lock();
self.inner.shutdown_substream(cx, list.get_mut(s).unwrap()).map_err(|e| e.into())
self.inner
.shutdown_substream(cx, list.get_mut(s).unwrap())
.map_err(|e| e.into())
}
#[inline]
fn destroy_substream(&self, substream: Self::Substream) {
let mut list = self.substreams.lock();
self.inner.destroy_substream(list.remove(&substream).unwrap())
self.inner
.destroy_substream(list.remove(&substream).unwrap())
}
#[inline]

View File

@ -18,11 +18,20 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::{connection::Endpoint, muxing::{StreamMuxer, StreamMuxerEvent}};
use crate::{
connection::Endpoint,
muxing::{StreamMuxer, StreamMuxerEvent},
};
use futures::prelude::*;
use parking_lot::Mutex;
use std::{io, pin::Pin, sync::atomic::{AtomicBool, Ordering}, task::Context, task::Poll};
use std::{
io,
pin::Pin,
sync::atomic::{AtomicBool, Ordering},
task::Context,
task::Poll,
};
/// Implementation of `StreamMuxer` that allows only one substream on top of a connection,
/// yielding the connection itself.
@ -65,7 +74,10 @@ where
type OutboundSubstream = OutboundSubstream;
type Error = io::Error;
fn poll_event(&self, _: &mut Context<'_>) -> Poll<Result<StreamMuxerEvent<Self::Substream>, io::Error>> {
fn poll_event(
&self,
_: &mut Context<'_>,
) -> Poll<Result<StreamMuxerEvent<Self::Substream>, io::Error>> {
match self.endpoint {
Endpoint::Dialer => return Poll::Pending,
Endpoint::Listener => {}
@ -82,7 +94,11 @@ where
OutboundSubstream {}
}
fn poll_outbound(&self, _: &mut Context<'_>, _: &mut Self::OutboundSubstream) -> Poll<Result<Self::Substream, io::Error>> {
fn poll_outbound(
&self,
_: &mut Context<'_>,
_: &mut Self::OutboundSubstream,
) -> Poll<Result<Self::Substream, io::Error>> {
match self.endpoint {
Endpoint::Listener => return Poll::Pending,
Endpoint::Dialer => {}
@ -95,27 +111,43 @@ where
}
}
fn destroy_outbound(&self, _: Self::OutboundSubstream) {
}
fn destroy_outbound(&self, _: Self::OutboundSubstream) {}
fn read_substream(&self, cx: &mut Context<'_>, _: &mut Self::Substream, buf: &mut [u8]) -> Poll<Result<usize, io::Error>> {
fn read_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
buf: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
AsyncRead::poll_read(Pin::new(&mut *self.inner.lock()), cx, buf)
}
fn write_substream(&self, cx: &mut Context<'_>, _: &mut Self::Substream, buf: &[u8]) -> Poll<Result<usize, io::Error>> {
fn write_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
buf: &[u8],
) -> Poll<Result<usize, io::Error>> {
AsyncWrite::poll_write(Pin::new(&mut *self.inner.lock()), cx, buf)
}
fn flush_substream(&self, cx: &mut Context<'_>, _: &mut Self::Substream) -> Poll<Result<(), io::Error>> {
fn flush_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
) -> Poll<Result<(), io::Error>> {
AsyncWrite::poll_flush(Pin::new(&mut *self.inner.lock()), cx)
}
fn shutdown_substream(&self, cx: &mut Context<'_>, _: &mut Self::Substream) -> Poll<Result<(), io::Error>> {
fn shutdown_substream(
&self,
cx: &mut Context<'_>,
_: &mut Self::Substream,
) -> Poll<Result<(), io::Error>> {
AsyncWrite::poll_close(Pin::new(&mut *self.inner.lock()), cx)
}
fn destroy_substream(&self, _: Self::Substream) {
}
fn destroy_substream(&self, _: Self::Substream) {}
fn close(&self, cx: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
// The `StreamMuxer` trait requires that `close()` implies `flush_all()`.

View File

@ -21,45 +21,30 @@
mod event;
pub mod peer;
pub use crate::connection::{ConnectionLimits, ConnectionCounters};
pub use event::{NetworkEvent, IncomingConnection};
pub use crate::connection::{ConnectionCounters, ConnectionLimits};
pub use event::{IncomingConnection, NetworkEvent};
pub use peer::Peer;
use crate::{
ConnectedPoint,
Executor,
Multiaddr,
PeerId,
connection::{
ConnectionId,
ConnectionLimit,
ConnectionHandler,
IntoConnectionHandler,
IncomingInfo,
OutgoingInfo,
ListenersEvent,
ListenerId,
ListenersStream,
PendingConnectionError,
Substream,
handler::{
THandlerInEvent,
THandlerOutEvent,
},
handler::{THandlerInEvent, THandlerOutEvent},
manager::ManagerConfig,
pool::{Pool, PoolEvent},
ConnectionHandler, ConnectionId, ConnectionLimit, IncomingInfo, IntoConnectionHandler,
ListenerId, ListenersEvent, ListenersStream, OutgoingInfo, PendingConnectionError,
Substream,
},
muxing::StreamMuxer,
transport::{Transport, TransportError},
ConnectedPoint, Executor, Multiaddr, PeerId,
};
use fnv::{FnvHashMap};
use futures::{prelude::*, future};
use fnv::FnvHashMap;
use futures::{future, prelude::*};
use smallvec::SmallVec;
use std::{
collections::hash_map,
convert::TryFrom as _,
error,
fmt,
error, fmt,
num::NonZeroUsize,
pin::Pin,
task::{Context, Poll},
@ -95,8 +80,7 @@ where
dialing: FnvHashMap<PeerId, SmallVec<[peer::DialingState; 10]>>,
}
impl<TTrans, THandler> fmt::Debug for
Network<TTrans, THandler>
impl<TTrans, THandler> fmt::Debug for Network<TTrans, THandler>
where
TTrans: fmt::Debug + Transport,
THandler: fmt::Debug + ConnectionHandler,
@ -111,16 +95,14 @@ where
}
}
impl<TTrans, THandler> Unpin for
Network<TTrans, THandler>
impl<TTrans, THandler> Unpin for Network<TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
{
}
impl<TTrans, THandler>
Network<TTrans, THandler>
impl<TTrans, THandler> Network<TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -131,8 +113,7 @@ where
}
}
impl<TTrans, TMuxer, THandler>
Network<TTrans, THandler>
impl<TTrans, TMuxer, THandler> Network<TTrans, THandler>
where
TTrans: Transport + Clone,
TMuxer: StreamMuxer,
@ -142,11 +123,7 @@ where
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send,
{
/// Creates a new node events stream.
pub fn new(
transport: TTrans,
local_peer_id: PeerId,
config: NetworkConfig,
) -> Self {
pub fn new(transport: TTrans, local_peer_id: PeerId, config: NetworkConfig) -> Self {
Network {
local_peer_id,
listeners: ListenersStream::new(transport),
@ -161,7 +138,10 @@ where
}
/// Start listening on the given multiaddress.
pub fn listen_on(&mut self, addr: Multiaddr) -> Result<ListenerId, TransportError<TTrans::Error>> {
pub fn listen_on(
&mut self,
addr: Multiaddr,
) -> Result<ListenerId, TransportError<TTrans::Error>> {
self.listeners.listen_on(addr)
}
@ -189,14 +169,14 @@ where
/// other than the peer who reported the `observed_addr`.
///
/// The translation is transport-specific. See [`Transport::address_translation`].
pub fn address_translation<'a>(&'a self, observed_addr: &'a Multiaddr)
-> Vec<Multiaddr>
pub fn address_translation<'a>(&'a self, observed_addr: &'a Multiaddr) -> Vec<Multiaddr>
where
TMuxer: 'a,
THandler: 'a,
{
let transport = self.listeners.transport();
let mut addrs: Vec<_> = self.listen_addrs()
let mut addrs: Vec<_> = self
.listen_addrs()
.filter_map(move |server| transport.address_translation(server, observed_addr))
.collect();
@ -218,8 +198,11 @@ where
/// The given `handler` will be used to create the
/// [`Connection`](crate::connection::Connection) upon success and the
/// connection ID is returned.
pub fn dial(&mut self, address: &Multiaddr, handler: THandler)
-> Result<ConnectionId, DialError>
pub fn dial(
&mut self,
address: &Multiaddr,
handler: THandler,
) -> Result<ConnectionId, DialError>
where
TTrans: Transport<Output = (PeerId, TMuxer)>,
TTrans::Error: Send + 'static,
@ -238,21 +221,29 @@ where
address: address.clone(),
handler,
remaining: Vec::new(),
})
});
}
}
// The address does not specify an expected peer, so just try to dial it as-is,
// accepting any peer ID that the remote identifies as.
let info = OutgoingInfo { address, peer_id: None };
let info = OutgoingInfo {
address,
peer_id: None,
};
match self.transport().clone().dial(address.clone()) {
Ok(f) => {
let f = f.map_err(|err| PendingConnectionError::Transport(TransportError::Other(err)));
self.pool.add_outgoing(f, handler, info).map_err(DialError::ConnectionLimit)
let f =
f.map_err(|err| PendingConnectionError::Transport(TransportError::Other(err)));
self.pool
.add_outgoing(f, handler, info)
.map_err(DialError::ConnectionLimit)
}
Err(err) => {
let f = future::err(PendingConnectionError::Transport(err));
self.pool.add_outgoing(f, handler, info).map_err(DialError::ConnectionLimit)
self.pool
.add_outgoing(f, handler, info)
.map_err(DialError::ConnectionLimit)
}
}
}
@ -274,14 +265,13 @@ where
/// Returns the list of addresses we're currently dialing without knowing the `PeerId` of.
pub fn unknown_dials(&self) -> impl Iterator<Item = &Multiaddr> {
self.pool.iter_pending_outgoing()
.filter_map(|info| {
if info.peer_id.is_none() {
Some(info.address)
} else {
None
}
})
self.pool.iter_pending_outgoing().filter_map(|info| {
if info.peer_id.is_none() {
Some(info.address)
} else {
None
}
})
}
/// Returns a list of all connected peers, i.e. peers to whom the `Network`
@ -313,9 +303,7 @@ where
}
/// Obtains a view of a [`Peer`] with the given ID in the network.
pub fn peer(&mut self, peer_id: PeerId)
-> Peer<'_, TTrans, THandler>
{
pub fn peer(&mut self, peer_id: PeerId) -> Peer<'_, TTrans, THandler> {
Peer::new(self, peer_id)
}
@ -336,8 +324,9 @@ where
TTrans::Error: Send + 'static,
TTrans::ListenerUpgrade: Send + 'static,
{
let upgrade = connection.upgrade.map_err(|err|
PendingConnectionError::Transport(TransportError::Other(err)));
let upgrade = connection
.upgrade
.map_err(|err| PendingConnectionError::Transport(TransportError::Other(err)));
let info = IncomingInfo {
local_addr: &connection.local_addr,
send_back_addr: &connection.send_back_addr,
@ -346,7 +335,12 @@ where
}
/// Provides an API similar to `Stream`, except that it cannot error.
pub fn poll<'a>(&'a mut self, cx: &mut Context<'_>) -> Poll<NetworkEvent<'a, TTrans, THandlerInEvent<THandler>, THandlerOutEvent<THandler>, THandler>>
pub fn poll<'a>(
&'a mut self,
cx: &mut Context<'_>,
) -> Poll<
NetworkEvent<'a, TTrans, THandlerInEvent<THandler>, THandlerOutEvent<THandler>, THandler>,
>
where
TTrans: Transport<Output = (PeerId, TMuxer)>,
TTrans::Error: Send + 'static,
@ -364,7 +358,7 @@ where
listener_id,
upgrade,
local_addr,
send_back_addr
send_back_addr,
}) => {
return Poll::Ready(NetworkEvent::IncomingConnection {
listener_id,
@ -372,17 +366,37 @@ where
upgrade,
local_addr,
send_back_addr,
}
},
})
}
Poll::Ready(ListenersEvent::NewAddress { listener_id, listen_addr }) => {
return Poll::Ready(NetworkEvent::NewListenerAddress { listener_id, listen_addr })
Poll::Ready(ListenersEvent::NewAddress {
listener_id,
listen_addr,
}) => {
return Poll::Ready(NetworkEvent::NewListenerAddress {
listener_id,
listen_addr,
})
}
Poll::Ready(ListenersEvent::AddressExpired { listener_id, listen_addr }) => {
return Poll::Ready(NetworkEvent::ExpiredListenerAddress { listener_id, listen_addr })
Poll::Ready(ListenersEvent::AddressExpired {
listener_id,
listen_addr,
}) => {
return Poll::Ready(NetworkEvent::ExpiredListenerAddress {
listener_id,
listen_addr,
})
}
Poll::Ready(ListenersEvent::Closed { listener_id, addresses, reason }) => {
return Poll::Ready(NetworkEvent::ListenerClosed { listener_id, addresses, reason })
Poll::Ready(ListenersEvent::Closed {
listener_id,
addresses,
reason,
}) => {
return Poll::Ready(NetworkEvent::ListenerClosed {
listener_id,
addresses,
reason,
})
}
Poll::Ready(ListenersEvent::Error { listener_id, error }) => {
return Poll::Ready(NetworkEvent::ListenerError { listener_id, error })
@ -392,7 +406,10 @@ where
// Poll the known peers.
let event = match self.pool.poll(cx) {
Poll::Pending => return Poll::Pending,
Poll::Ready(PoolEvent::ConnectionEstablished { connection, num_established }) => {
Poll::Ready(PoolEvent::ConnectionEstablished {
connection,
num_established,
}) => {
if let hash_map::Entry::Occupied(mut e) = self.dialing.entry(connection.peer_id()) {
e.get_mut().retain(|s| s.current.0 != connection.id());
if e.get().is_empty() {
@ -405,7 +422,14 @@ where
num_established,
}
}
Poll::Ready(PoolEvent::PendingConnectionError { id, endpoint, error, handler, pool, .. }) => {
Poll::Ready(PoolEvent::PendingConnectionError {
id,
endpoint,
error,
handler,
pool,
..
}) => {
let dialing = &mut self.dialing;
let (next, event) = on_connection_failed(dialing, id, endpoint, error, handler);
if let Some(dial) = next {
@ -416,35 +440,37 @@ where
}
event
}
Poll::Ready(PoolEvent::ConnectionClosed { id, connected, error, num_established, .. }) => {
NetworkEvent::ConnectionClosed {
id,
connected,
num_established,
error,
}
}
Poll::Ready(PoolEvent::ConnectionClosed {
id,
connected,
error,
num_established,
..
}) => NetworkEvent::ConnectionClosed {
id,
connected,
num_established,
error,
},
Poll::Ready(PoolEvent::ConnectionEvent { connection, event }) => {
NetworkEvent::ConnectionEvent {
connection,
event,
}
}
Poll::Ready(PoolEvent::AddressChange { connection, new_endpoint, old_endpoint }) => {
NetworkEvent::AddressChange {
connection,
new_endpoint,
old_endpoint,
}
NetworkEvent::ConnectionEvent { connection, event }
}
Poll::Ready(PoolEvent::AddressChange {
connection,
new_endpoint,
old_endpoint,
}) => NetworkEvent::AddressChange {
connection,
new_endpoint,
old_endpoint,
},
};
Poll::Ready(event)
}
/// Initiates a connection attempt to a known peer.
fn dial_peer(&mut self, opts: DialingOpts<PeerId, THandler>)
-> Result<ConnectionId, DialError>
fn dial_peer(&mut self, opts: DialingOpts<PeerId, THandler>) -> Result<ConnectionId, DialError>
where
TTrans: Transport<Output = (PeerId, TMuxer)>,
TTrans::Dial: Send + 'static,
@ -452,7 +478,12 @@ where
TMuxer: Send + Sync + 'static,
TMuxer::OutboundSubstream: Send,
{
dial_peer_impl(self.transport().clone(), &mut self.pool, &mut self.dialing, opts)
dial_peer_impl(
self.transport().clone(),
&mut self.pool,
&mut self.dialing,
opts,
)
}
}
@ -470,15 +501,13 @@ fn dial_peer_impl<TMuxer, THandler, TTrans>(
transport: TTrans,
pool: &mut Pool<THandler, TTrans::Error>,
dialing: &mut FnvHashMap<PeerId, SmallVec<[peer::DialingState; 10]>>,
opts: DialingOpts<PeerId, THandler>
opts: DialingOpts<PeerId, THandler>,
) -> Result<ConnectionId, DialError>
where
THandler: IntoConnectionHandler + Send + 'static,
<THandler::Handler as ConnectionHandler>::Error: error::Error + Send + 'static,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
THandler::Handler: ConnectionHandler<
Substream = Substream<TMuxer>,
> + Send + 'static,
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send + 'static,
TTrans: Transport<Output = (PeerId, TMuxer)>,
TTrans::Dial: Send + 'static,
TTrans::Error: error::Error + Send + 'static,
@ -493,23 +522,32 @@ where
let result = match transport.dial(addr.clone()) {
Ok(fut) => {
let fut = fut.map_err(|e| PendingConnectionError::Transport(TransportError::Other(e)));
let info = OutgoingInfo { address: &addr, peer_id: Some(&opts.peer) };
pool.add_outgoing(fut, opts.handler, info).map_err(DialError::ConnectionLimit)
},
let info = OutgoingInfo {
address: &addr,
peer_id: Some(&opts.peer),
};
pool.add_outgoing(fut, opts.handler, info)
.map_err(DialError::ConnectionLimit)
}
Err(err) => {
let fut = future::err(PendingConnectionError::Transport(err));
let info = OutgoingInfo { address: &addr, peer_id: Some(&opts.peer) };
pool.add_outgoing(fut, opts.handler, info).map_err(DialError::ConnectionLimit)
},
let info = OutgoingInfo {
address: &addr,
peer_id: Some(&opts.peer),
};
pool.add_outgoing(fut, opts.handler, info)
.map_err(DialError::ConnectionLimit)
}
};
if let Ok(id) = &result {
dialing.entry(opts.peer).or_default().push(
peer::DialingState {
dialing
.entry(opts.peer)
.or_default()
.push(peer::DialingState {
current: (*id, addr),
remaining: opts.remaining,
},
);
});
}
result
@ -526,22 +564,24 @@ fn on_connection_failed<'a, TTrans, THandler>(
endpoint: ConnectedPoint,
error: PendingConnectionError<TTrans::Error>,
handler: Option<THandler>,
) -> (Option<DialingOpts<PeerId, THandler>>, NetworkEvent<'a, TTrans, THandlerInEvent<THandler>, THandlerOutEvent<THandler>, THandler>)
) -> (
Option<DialingOpts<PeerId, THandler>>,
NetworkEvent<'a, TTrans, THandlerInEvent<THandler>, THandlerOutEvent<THandler>, THandler>,
)
where
TTrans: Transport,
THandler: IntoConnectionHandler,
{
// Check if the failed connection is associated with a dialing attempt.
let dialing_failed = dialing.iter_mut()
.find_map(|(peer, attempts)| {
if let Some(pos) = attempts.iter().position(|s| s.current.0 == id) {
let attempt = attempts.remove(pos);
let last = attempts.is_empty();
Some((*peer, attempt, last))
} else {
None
}
});
let dialing_failed = dialing.iter_mut().find_map(|(peer, attempts)| {
if let Some(pos) = attempts.iter().position(|s| s.current.0 == id) {
let attempt = attempts.remove(pos);
let last = attempts.is_empty();
Some((*peer, attempt, last))
} else {
None
}
});
if let Some((peer_id, mut attempt, last)) = dialing_failed {
if last {
@ -551,47 +591,56 @@ where
let num_remain = u32::try_from(attempt.remaining.len()).unwrap();
let failed_addr = attempt.current.1.clone();
let (opts, attempts_remaining) =
if num_remain > 0 {
if let Some(handler) = handler {
let next_attempt = attempt.remaining.remove(0);
let opts = DialingOpts {
peer: peer_id,
handler,
address: next_attempt,
remaining: attempt.remaining
};
(Some(opts), num_remain)
} else {
// The error is "fatal" for the dialing attempt, since
// the handler was already consumed. All potential
// remaining connection attempts are thus void.
(None, 0)
}
let (opts, attempts_remaining) = if num_remain > 0 {
if let Some(handler) = handler {
let next_attempt = attempt.remaining.remove(0);
let opts = DialingOpts {
peer: peer_id,
handler,
address: next_attempt,
remaining: attempt.remaining,
};
(Some(opts), num_remain)
} else {
// The error is "fatal" for the dialing attempt, since
// the handler was already consumed. All potential
// remaining connection attempts are thus void.
(None, 0)
};
}
} else {
(None, 0)
};
(opts, NetworkEvent::DialError {
attempts_remaining,
peer_id,
multiaddr: failed_addr,
error,
})
(
opts,
NetworkEvent::DialError {
attempts_remaining,
peer_id,
multiaddr: failed_addr,
error,
},
)
} else {
// A pending incoming connection or outgoing connection to an unknown peer failed.
match endpoint {
ConnectedPoint::Dialer { address } =>
(None, NetworkEvent::UnknownPeerDialError {
ConnectedPoint::Dialer { address } => (
None,
NetworkEvent::UnknownPeerDialError {
multiaddr: address,
error,
}),
ConnectedPoint::Listener { local_addr, send_back_addr } =>
(None, NetworkEvent::IncomingConnectionError {
},
),
ConnectedPoint::Listener {
local_addr,
send_back_addr,
} => (
None,
NetworkEvent::IncomingConnectionError {
local_addr,
send_back_addr,
error
})
error,
},
),
}
}
}
@ -644,7 +693,7 @@ impl NetworkConfig {
/// only if no executor has already been configured.
pub fn or_else_with_executor<F>(mut self, f: F) -> Self
where
F: FnOnce() -> Option<Box<dyn Executor + Send>>
F: FnOnce() -> Option<Box<dyn Executor + Send>>,
{
self.manager_config.executor = self.manager_config.executor.or_else(f);
self
@ -693,7 +742,7 @@ impl NetworkConfig {
fn p2p_addr(peer: PeerId, addr: Multiaddr) -> Result<Multiaddr, Multiaddr> {
if let Some(multiaddr::Protocol::P2p(hash)) = addr.iter().last() {
if &hash != peer.as_ref() {
return Err(addr)
return Err(addr);
}
Ok(addr)
} else {
@ -718,7 +767,7 @@ mod tests {
struct Dummy;
impl Executor for Dummy {
fn exec(&self, _: Pin<Box<dyn Future<Output=()> + Send>>) { }
fn exec(&self, _: Pin<Box<dyn Future<Output = ()> + Send>>) {}
}
#[test]

View File

@ -21,20 +21,12 @@
//! Network events and associated information.
use crate::{
Multiaddr,
connection::{
ConnectionId,
ConnectedPoint,
ConnectionError,
ConnectionHandler,
Connected,
EstablishedConnection,
IntoConnectionHandler,
ListenerId,
PendingConnectionError,
Connected, ConnectedPoint, ConnectionError, ConnectionHandler, ConnectionId,
EstablishedConnection, IntoConnectionHandler, ListenerId, PendingConnectionError,
},
transport::Transport,
PeerId
Multiaddr, PeerId,
};
use std::{fmt, num::NonZeroU32};
@ -60,7 +52,7 @@ where
/// The listener that errored.
listener_id: ListenerId,
/// The listener error.
error: TTrans::Error
error: TTrans::Error,
},
/// One of the listeners is now listening on an additional address.
@ -68,7 +60,7 @@ where
/// The listener that is listening on the new address.
listener_id: ListenerId,
/// The new address the listener is now also listening on.
listen_addr: Multiaddr
listen_addr: Multiaddr,
},
/// One of the listeners is no longer listening on some address.
@ -76,7 +68,7 @@ where
/// The listener that is no longer listening on some address.
listener_id: ListenerId,
/// The expired address.
listen_addr: Multiaddr
listen_addr: Multiaddr,
},
/// A new connection arrived on a listener.
@ -177,8 +169,8 @@ where
},
}
impl<TTrans, TInEvent, TOutEvent, THandler> fmt::Debug for
NetworkEvent<'_, TTrans, TInEvent, TOutEvent, THandler>
impl<TTrans, TInEvent, TOutEvent, THandler> fmt::Debug
for NetworkEvent<'_, TTrans, TInEvent, TOutEvent, THandler>
where
TInEvent: fmt::Debug,
TOutEvent: fmt::Debug,
@ -189,83 +181,101 @@ where
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
NetworkEvent::NewListenerAddress { listener_id, listen_addr } => {
f.debug_struct("NewListenerAddress")
.field("listener_id", listener_id)
.field("listen_addr", listen_addr)
.finish()
}
NetworkEvent::ExpiredListenerAddress { listener_id, listen_addr } => {
f.debug_struct("ExpiredListenerAddress")
.field("listener_id", listener_id)
.field("listen_addr", listen_addr)
.finish()
}
NetworkEvent::ListenerClosed { listener_id, addresses, reason } => {
f.debug_struct("ListenerClosed")
.field("listener_id", listener_id)
.field("addresses", addresses)
.field("reason", reason)
.finish()
}
NetworkEvent::ListenerError { listener_id, error } => {
f.debug_struct("ListenerError")
.field("listener_id", listener_id)
.field("error", error)
.finish()
}
NetworkEvent::IncomingConnection { connection, .. } => {
f.debug_struct("IncomingConnection")
.field("local_addr", &connection.local_addr)
.field("send_back_addr", &connection.send_back_addr)
.finish()
}
NetworkEvent::IncomingConnectionError { local_addr, send_back_addr, error } => {
f.debug_struct("IncomingConnectionError")
.field("local_addr", local_addr)
.field("send_back_addr", send_back_addr)
.field("error", error)
.finish()
}
NetworkEvent::ConnectionEstablished { connection, .. } => {
f.debug_struct("ConnectionEstablished")
.field("connection", connection)
.finish()
}
NetworkEvent::ConnectionClosed { id, connected, error, .. } => {
f.debug_struct("ConnectionClosed")
.field("id", id)
.field("connected", connected)
.field("error", error)
.finish()
}
NetworkEvent::DialError { attempts_remaining, peer_id, multiaddr, error } => {
f.debug_struct("DialError")
.field("attempts_remaining", attempts_remaining)
.field("peer_id", peer_id)
.field("multiaddr", multiaddr)
.field("error", error)
.finish()
}
NetworkEvent::UnknownPeerDialError { multiaddr, error, .. } => {
f.debug_struct("UnknownPeerDialError")
.field("multiaddr", multiaddr)
.field("error", error)
.finish()
}
NetworkEvent::ConnectionEvent { connection, event } => {
f.debug_struct("ConnectionEvent")
.field("connection", connection)
.field("event", event)
.finish()
}
NetworkEvent::AddressChange { connection, new_endpoint, old_endpoint } => {
f.debug_struct("AddressChange")
.field("connection", connection)
.field("new_endpoint", new_endpoint)
.field("old_endpoint", old_endpoint)
.finish()
}
NetworkEvent::NewListenerAddress {
listener_id,
listen_addr,
} => f
.debug_struct("NewListenerAddress")
.field("listener_id", listener_id)
.field("listen_addr", listen_addr)
.finish(),
NetworkEvent::ExpiredListenerAddress {
listener_id,
listen_addr,
} => f
.debug_struct("ExpiredListenerAddress")
.field("listener_id", listener_id)
.field("listen_addr", listen_addr)
.finish(),
NetworkEvent::ListenerClosed {
listener_id,
addresses,
reason,
} => f
.debug_struct("ListenerClosed")
.field("listener_id", listener_id)
.field("addresses", addresses)
.field("reason", reason)
.finish(),
NetworkEvent::ListenerError { listener_id, error } => f
.debug_struct("ListenerError")
.field("listener_id", listener_id)
.field("error", error)
.finish(),
NetworkEvent::IncomingConnection { connection, .. } => f
.debug_struct("IncomingConnection")
.field("local_addr", &connection.local_addr)
.field("send_back_addr", &connection.send_back_addr)
.finish(),
NetworkEvent::IncomingConnectionError {
local_addr,
send_back_addr,
error,
} => f
.debug_struct("IncomingConnectionError")
.field("local_addr", local_addr)
.field("send_back_addr", send_back_addr)
.field("error", error)
.finish(),
NetworkEvent::ConnectionEstablished { connection, .. } => f
.debug_struct("ConnectionEstablished")
.field("connection", connection)
.finish(),
NetworkEvent::ConnectionClosed {
id,
connected,
error,
..
} => f
.debug_struct("ConnectionClosed")
.field("id", id)
.field("connected", connected)
.field("error", error)
.finish(),
NetworkEvent::DialError {
attempts_remaining,
peer_id,
multiaddr,
error,
} => f
.debug_struct("DialError")
.field("attempts_remaining", attempts_remaining)
.field("peer_id", peer_id)
.field("multiaddr", multiaddr)
.field("error", error)
.finish(),
NetworkEvent::UnknownPeerDialError {
multiaddr, error, ..
} => f
.debug_struct("UnknownPeerDialError")
.field("multiaddr", multiaddr)
.field("error", error)
.finish(),
NetworkEvent::ConnectionEvent { connection, event } => f
.debug_struct("ConnectionEvent")
.field("connection", connection)
.field("event", event)
.finish(),
NetworkEvent::AddressChange {
connection,
new_endpoint,
old_endpoint,
} => f
.debug_struct("AddressChange")
.field("connection", connection)
.field("new_endpoint", new_endpoint)
.field("old_endpoint", old_endpoint)
.finish(),
}
}
}

View File

@ -18,35 +18,18 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use super::{DialError, DialingOpts, Network};
use crate::{
Multiaddr,
Transport,
StreamMuxer,
connection::{
Connected,
ConnectedPoint,
ConnectionHandler,
Connection,
ConnectionId,
ConnectionLimit,
EstablishedConnection,
EstablishedConnectionIter,
IntoConnectionHandler,
PendingConnection,
Substream,
handler::THandlerInEvent,
pool::Pool,
handler::THandlerInEvent, pool::Pool, Connected, ConnectedPoint, Connection,
ConnectionHandler, ConnectionId, ConnectionLimit, EstablishedConnection,
EstablishedConnectionIter, IntoConnectionHandler, PendingConnection, Substream,
},
PeerId
Multiaddr, PeerId, StreamMuxer, Transport,
};
use fnv::FnvHashMap;
use smallvec::SmallVec;
use std::{
collections::hash_map,
error,
fmt,
};
use super::{Network, DialingOpts, DialError};
use std::{collections::hash_map, error, fmt};
/// The possible representations of a peer in a [`Network`], as
/// seen by the local node.
@ -57,7 +40,7 @@ use super::{Network, DialingOpts, DialError};
pub enum Peer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler
THandler: IntoConnectionHandler,
{
/// At least one established connection exists to the peer.
Connected(ConnectedPeer<'a, TTrans, THandler>),
@ -76,53 +59,33 @@ where
Local,
}
impl<'a, TTrans, THandler> fmt::Debug for
Peer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> fmt::Debug for Peer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
match self {
Peer::Connected(p) => {
f.debug_struct("Connected")
.field("peer", &p)
.finish()
}
Peer::Dialing(p) => {
f.debug_struct("Dialing")
.field("peer", &p)
.finish()
}
Peer::Disconnected(p) => {
f.debug_struct("Disconnected")
.field("peer", &p)
.finish()
}
Peer::Local => {
f.debug_struct("Local")
.finish()
}
Peer::Connected(p) => f.debug_struct("Connected").field("peer", &p).finish(),
Peer::Dialing(p) => f.debug_struct("Dialing").field("peer", &p).finish(),
Peer::Disconnected(p) => f.debug_struct("Disconnected").field("peer", &p).finish(),
Peer::Local => f.debug_struct("Local").finish(),
}
}
}
impl<'a, TTrans, THandler>
Peer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> Peer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
{
pub(super) fn new(
network: &'a mut Network<TTrans, THandler>,
peer_id: PeerId
) -> Self {
pub(super) fn new(network: &'a mut Network<TTrans, THandler>, peer_id: PeerId) -> Self {
if peer_id == network.local_peer_id {
return Peer::Local;
}
if network.pool.is_connected(&peer_id) {
return Self::connected(network, peer_id)
return Self::connected(network, peer_id);
}
if network.dialing.get_mut(&peer_id).is_some() {
@ -132,31 +95,20 @@ where
Self::disconnected(network, peer_id)
}
fn disconnected(
network: &'a mut Network<TTrans, THandler>,
peer_id: PeerId
) -> Self {
fn disconnected(network: &'a mut Network<TTrans, THandler>, peer_id: PeerId) -> Self {
Peer::Disconnected(DisconnectedPeer { network, peer_id })
}
fn connected(
network: &'a mut Network<TTrans, THandler>,
peer_id: PeerId
) -> Self {
fn connected(network: &'a mut Network<TTrans, THandler>, peer_id: PeerId) -> Self {
Peer::Connected(ConnectedPeer { network, peer_id })
}
fn dialing(
network: &'a mut Network<TTrans, THandler>,
peer_id: PeerId
) -> Self {
fn dialing(network: &'a mut Network<TTrans, THandler>, peer_id: PeerId) -> Self {
Peer::Dialing(DialingPeer { network, peer_id })
}
}
impl<'a, TTrans, TMuxer, THandler>
Peer<'a, TTrans, THandler>
impl<'a, TTrans, TMuxer, THandler> Peer<'a, TTrans, THandler>
where
TTrans: Transport<Output = (PeerId, TMuxer)> + Clone,
TTrans::Error: Send + 'static,
@ -176,7 +128,7 @@ where
Peer::Connected(..) => true,
Peer::Dialing(peer) => peer.is_connected(),
Peer::Disconnected(..) => false,
Peer::Local => false
Peer::Local => false,
}
}
@ -188,7 +140,7 @@ where
Peer::Dialing(_) => true,
Peer::Connected(peer) => peer.is_dialing(),
Peer::Disconnected(..) => false,
Peer::Local => false
Peer::Local => false,
}
}
@ -206,11 +158,12 @@ where
/// `remaining` addresses are tried in order in subsequent connection
/// attempts in the context of the same dialing attempt, if the connection
/// attempt to the first address fails.
pub fn dial<I>(self, address: Multiaddr, remaining: I, handler: THandler)
-> Result<
(ConnectionId, DialingPeer<'a, TTrans, THandler>),
DialError
>
pub fn dial<I>(
self,
address: Multiaddr,
remaining: I,
handler: THandler,
) -> Result<(ConnectionId, DialingPeer<'a, TTrans, THandler>), DialError>
where
I: IntoIterator<Item = Multiaddr>,
{
@ -218,9 +171,12 @@ where
Peer::Connected(p) => (p.peer_id, p.network),
Peer::Dialing(p) => (p.peer_id, p.network),
Peer::Disconnected(p) => (p.peer_id, p.network),
Peer::Local => return Err(DialError::ConnectionLimit(ConnectionLimit {
current: 0, limit: 0
}))
Peer::Local => {
return Err(DialError::ConnectionLimit(ConnectionLimit {
current: 0,
limit: 0,
}))
}
};
let id = network.dial_peer(DialingOpts {
@ -236,9 +192,7 @@ where
/// Converts the peer into a `ConnectedPeer`, if an established connection exists.
///
/// Succeeds if the there is at least one established connection to the peer.
pub fn into_connected(self) -> Option<
ConnectedPeer<'a, TTrans, THandler>
> {
pub fn into_connected(self) -> Option<ConnectedPeer<'a, TTrans, THandler>> {
match self {
Peer::Connected(peer) => Some(peer),
Peer::Dialing(peer) => peer.into_connected(),
@ -250,22 +204,18 @@ where
/// Converts the peer into a `DialingPeer`, if a dialing attempt exists.
///
/// Succeeds if the there is at least one pending outgoing connection to the peer.
pub fn into_dialing(self) -> Option<
DialingPeer<'a, TTrans, THandler>
> {
pub fn into_dialing(self) -> Option<DialingPeer<'a, TTrans, THandler>> {
match self {
Peer::Dialing(peer) => Some(peer),
Peer::Connected(peer) => peer.into_dialing(),
Peer::Disconnected(..) => None,
Peer::Local => None
Peer::Local => None,
}
}
/// Converts the peer into a `DisconnectedPeer`, if neither an established connection
/// nor a dialing attempt exists.
pub fn into_disconnected(self) -> Option<
DisconnectedPeer<'a, TTrans, THandler>
> {
pub fn into_disconnected(self) -> Option<DisconnectedPeer<'a, TTrans, THandler>> {
match self {
Peer::Disconnected(peer) => Some(peer),
_ => None,
@ -285,8 +235,7 @@ where
peer_id: PeerId,
}
impl<'a, TTrans, THandler>
ConnectedPeer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> ConnectedPeer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -301,9 +250,10 @@ where
}
/// Obtains an established connection to the peer by ID.
pub fn connection(&mut self, id: ConnectionId)
-> Option<EstablishedConnection<THandlerInEvent<THandler>>>
{
pub fn connection(
&mut self,
id: ConnectionId,
) -> Option<EstablishedConnection<THandlerInEvent<THandler>>> {
self.network.pool.get_established(id)
}
@ -321,47 +271,43 @@ where
/// Converts this peer into a [`DialingPeer`], if there is an ongoing
/// dialing attempt, `None` otherwise.
pub fn into_dialing(self) -> Option<
DialingPeer<'a, TTrans, THandler>
> {
pub fn into_dialing(self) -> Option<DialingPeer<'a, TTrans, THandler>> {
if self.network.dialing.contains_key(&self.peer_id) {
Some(DialingPeer { network: self.network, peer_id: self.peer_id })
Some(DialingPeer {
network: self.network,
peer_id: self.peer_id,
})
} else {
None
}
}
/// Gets an iterator over all established connections to the peer.
pub fn connections(&mut self) ->
EstablishedConnectionIter<
impl Iterator<Item = ConnectionId>,
THandler,
TTrans::Error,
>
pub fn connections(
&mut self,
) -> EstablishedConnectionIter<impl Iterator<Item = ConnectionId>, THandler, TTrans::Error>
{
self.network.pool.iter_peer_established(&self.peer_id)
}
/// Obtains some established connection to the peer.
pub fn some_connection(&mut self)
-> EstablishedConnection<THandlerInEvent<THandler>>
{
pub fn some_connection(&mut self) -> EstablishedConnection<THandlerInEvent<THandler>> {
self.connections()
.into_first()
.expect("By `Peer::new` and the definition of `ConnectedPeer`.")
}
/// Disconnects from the peer, closing all connections.
pub fn disconnect(self)
-> DisconnectedPeer<'a, TTrans, THandler>
{
pub fn disconnect(self) -> DisconnectedPeer<'a, TTrans, THandler> {
self.network.disconnect(&self.peer_id);
DisconnectedPeer { network: self.network, peer_id: self.peer_id }
DisconnectedPeer {
network: self.network,
peer_id: self.peer_id,
}
}
}
impl<'a, TTrans, THandler> fmt::Debug for
ConnectedPeer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> fmt::Debug for ConnectedPeer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -369,7 +315,10 @@ where
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("ConnectedPeer")
.field("peer_id", &self.peer_id)
.field("established", &self.network.pool.iter_peer_established_info(&self.peer_id))
.field(
"established",
&self.network.pool.iter_peer_established_info(&self.peer_id),
)
.field("attempts", &self.network.dialing.get(&self.peer_id))
.finish()
}
@ -387,8 +336,7 @@ where
peer_id: PeerId,
}
impl<'a, TTrans, THandler>
DialingPeer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> DialingPeer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -404,11 +352,12 @@ where
/// Disconnects from this peer, closing all established connections and
/// aborting all dialing attempts.
pub fn disconnect(self)
-> DisconnectedPeer<'a, TTrans, THandler>
{
pub fn disconnect(self) -> DisconnectedPeer<'a, TTrans, THandler> {
self.network.disconnect(&self.peer_id);
DisconnectedPeer { network: self.network, peer_id: self.peer_id }
DisconnectedPeer {
network: self.network,
peer_id: self.peer_id,
}
}
/// Checks whether there is an established connection to the peer.
@ -419,11 +368,12 @@ where
}
/// Converts the peer into a `ConnectedPeer`, if an established connection exists.
pub fn into_connected(self)
-> Option<ConnectedPeer<'a, TTrans, THandler>>
{
pub fn into_connected(self) -> Option<ConnectedPeer<'a, TTrans, THandler>> {
if self.is_connected() {
Some(ConnectedPeer { peer_id: self.peer_id, network: self.network })
Some(ConnectedPeer {
peer_id: self.peer_id,
network: self.network,
})
} else {
None
}
@ -431,13 +381,18 @@ where
/// Obtains a dialing attempt to the peer by connection ID of
/// the current connection attempt.
pub fn attempt(&mut self, id: ConnectionId)
-> Option<DialingAttempt<'_, THandlerInEvent<THandler>>>
{
pub fn attempt(
&mut self,
id: ConnectionId,
) -> Option<DialingAttempt<'_, THandlerInEvent<THandler>>> {
if let hash_map::Entry::Occupied(attempts) = self.network.dialing.entry(self.peer_id) {
if let Some(pos) = attempts.get().iter().position(|s| s.current.0 == id) {
if let Some(inner) = self.network.pool.get_outgoing(id) {
return Some(DialingAttempt { pos, inner, attempts })
return Some(DialingAttempt {
pos,
inner,
attempts,
});
}
}
}
@ -445,25 +400,25 @@ where
}
/// Gets an iterator over all dialing (i.e. pending outgoing) connections to the peer.
pub fn attempts(&mut self) -> DialingAttemptIter<'_, THandler, TTrans::Error>
{
DialingAttemptIter::new(&self.peer_id, &mut self.network.pool, &mut self.network.dialing)
pub fn attempts(&mut self) -> DialingAttemptIter<'_, THandler, TTrans::Error> {
DialingAttemptIter::new(
&self.peer_id,
&mut self.network.pool,
&mut self.network.dialing,
)
}
/// Obtains some dialing connection to the peer.
///
/// At least one dialing connection is guaranteed to exist on a `DialingPeer`.
pub fn some_attempt(&mut self)
-> DialingAttempt<'_, THandlerInEvent<THandler>>
{
pub fn some_attempt(&mut self) -> DialingAttempt<'_, THandlerInEvent<THandler>> {
self.attempts()
.into_first()
.expect("By `Peer::new` and the definition of `DialingPeer`.")
}
}
impl<'a, TTrans, THandler> fmt::Debug for
DialingPeer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> fmt::Debug for DialingPeer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -471,7 +426,10 @@ where
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
f.debug_struct("DialingPeer")
.field("peer_id", &self.peer_id)
.field("established", &self.network.pool.iter_peer_established_info(&self.peer_id))
.field(
"established",
&self.network.pool.iter_peer_established_info(&self.peer_id),
)
.field("attempts", &self.network.dialing.get(&self.peer_id))
.finish()
}
@ -489,8 +447,7 @@ where
network: &'a mut Network<TTrans, THandler>,
}
impl<'a, TTrans, THandler> fmt::Debug for
DisconnectedPeer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> fmt::Debug for DisconnectedPeer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -502,8 +459,7 @@ where
}
}
impl<'a, TTrans, THandler>
DisconnectedPeer<'a, TTrans, THandler>
impl<'a, TTrans, THandler> DisconnectedPeer<'a, TTrans, THandler>
where
TTrans: Transport,
THandler: IntoConnectionHandler,
@ -529,10 +485,8 @@ where
self,
connected: Connected,
connection: Connection<TMuxer, THandler::Handler>,
) -> Result<
ConnectedPeer<'a, TTrans, THandler>,
ConnectionLimit
> where
) -> Result<ConnectedPeer<'a, TTrans, THandler>, ConnectionLimit>
where
THandler: Send + 'static,
TTrans::Error: Send + 'static,
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>> + Send,
@ -542,10 +496,15 @@ where
TMuxer::OutboundSubstream: Send,
{
if connected.peer_id != self.peer_id {
panic!("Invalid peer ID given: {:?}. Expected: {:?}", connected.peer_id, self.peer_id)
panic!(
"Invalid peer ID given: {:?}. Expected: {:?}",
connected.peer_id, self.peer_id
)
}
self.network.pool.add(connection, connected)
self.network
.pool
.add(connection, connected)
.map(move |_id| ConnectedPeer {
network: self.network,
peer_id: self.peer_id,
@ -575,9 +534,7 @@ pub struct DialingAttempt<'a, TInEvent> {
pos: usize,
}
impl<'a, TInEvent>
DialingAttempt<'a, TInEvent>
{
impl<'a, TInEvent> DialingAttempt<'a, TInEvent> {
/// Returns the ID of the current connection attempt.
pub fn id(&self) -> ConnectionId {
self.inner.id()
@ -592,7 +549,7 @@ impl<'a, TInEvent>
pub fn address(&self) -> &Multiaddr {
match self.inner.endpoint() {
ConnectedPoint::Dialer { address } => address,
ConnectedPoint::Listener { .. } => unreachable!("by definition of a `DialingAttempt`.")
ConnectedPoint::Listener { .. } => unreachable!("by definition of a `DialingAttempt`."),
}
}
@ -640,16 +597,20 @@ pub struct DialingAttemptIter<'a, THandler: IntoConnectionHandler, TTransErr> {
// Note: Ideally this would be an implementation of `Iterator`, but that
// requires GATs (cf. https://github.com/rust-lang/rust/issues/44265) and
// a different definition of `Iterator`.
impl<'a, THandler: IntoConnectionHandler, TTransErr>
DialingAttemptIter<'a, THandler, TTransErr>
{
impl<'a, THandler: IntoConnectionHandler, TTransErr> DialingAttemptIter<'a, THandler, TTransErr> {
fn new(
peer_id: &'a PeerId,
pool: &'a mut Pool<THandler, TTransErr>,
dialing: &'a mut FnvHashMap<PeerId, SmallVec<[DialingState; 10]>>,
) -> Self {
let end = dialing.get(peer_id).map_or(0, |conns| conns.len());
Self { pos: 0, end, pool, dialing, peer_id }
Self {
pos: 0,
end,
pool,
dialing,
peer_id,
}
}
/// Obtains the next dialing connection, if any.
@ -658,22 +619,29 @@ impl<'a, THandler: IntoConnectionHandler, TTransErr>
// If the number of elements reduced, the current `DialingAttempt` has been
// aborted and iteration needs to continue from the previous position to
// account for the removed element.
let end = self.dialing.get(self.peer_id).map_or(0, |conns| conns.len());
let end = self
.dialing
.get(self.peer_id)
.map_or(0, |conns| conns.len());
if self.end > end {
self.end = end;
self.pos -= 1;
}
if self.pos == self.end {
return None
return None;
}
if let hash_map::Entry::Occupied(attempts) = self.dialing.entry(*self.peer_id) {
let id = attempts.get()[self.pos].current.0;
if let Some(inner) = self.pool.get_outgoing(id) {
let conn = DialingAttempt { pos: self.pos, inner, attempts };
let conn = DialingAttempt {
pos: self.pos,
inner,
attempts,
};
self.pos += 1;
return Some(conn)
return Some(conn);
}
}
@ -681,18 +649,22 @@ impl<'a, THandler: IntoConnectionHandler, TTransErr>
}
/// Returns the first connection, if any, consuming the iterator.
pub fn into_first<'b>(self)
-> Option<DialingAttempt<'b, THandlerInEvent<THandler>>>
where 'a: 'b
pub fn into_first<'b>(self) -> Option<DialingAttempt<'b, THandlerInEvent<THandler>>>
where
'a: 'b,
{
if self.pos == self.end {
return None
return None;
}
if let hash_map::Entry::Occupied(attempts) = self.dialing.entry(*self.peer_id) {
let id = attempts.get()[self.pos].current.0;
if let Some(inner) = self.pool.get_outgoing(id) {
return Some(DialingAttempt { pos: self.pos, inner, attempts })
return Some(DialingAttempt {
pos: self.pos,
inner,
attempts,
});
}
}

View File

@ -38,9 +38,7 @@ pub struct PeerId {
impl fmt::Debug for PeerId {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.debug_tuple("PeerId")
.field(&self.to_base58())
.finish()
f.debug_tuple("PeerId").field(&self.to_base58()).finish()
}
}
@ -80,9 +78,10 @@ impl PeerId {
pub fn from_multihash(multihash: Multihash) -> Result<PeerId, Multihash> {
match Code::try_from(multihash.code()) {
Ok(Code::Sha2_256) => Ok(PeerId { multihash }),
Ok(Code::Identity) if multihash.digest().len() <= MAX_INLINE_KEY_LENGTH
=> Ok(PeerId { multihash }),
_ => Err(multihash)
Ok(Code::Identity) if multihash.digest().len() <= MAX_INLINE_KEY_LENGTH => {
Ok(PeerId { multihash })
}
_ => Err(multihash),
}
}
@ -93,7 +92,7 @@ impl PeerId {
let peer_id = rand::thread_rng().gen::<[u8; 32]>();
PeerId {
multihash: Multihash::wrap(Code::Identity.into(), &peer_id)
.expect("The digest size is never too large")
.expect("The digest size is never too large"),
}
}
@ -185,7 +184,7 @@ impl FromStr for PeerId {
#[cfg(test)]
mod tests {
use crate::{PeerId, identity};
use crate::{identity, PeerId};
#[test]
fn peer_id_is_public_key() {
@ -210,7 +209,7 @@ mod tests {
#[test]
fn random_peer_id_is_valid() {
for _ in 0 .. 5000 {
for _ in 0..5000 {
let peer_id = PeerId::random();
assert_eq!(peer_id, PeerId::from_bytes(&peer_id.to_bytes()).unwrap());
}

View File

@ -94,7 +94,9 @@ pub trait Transport {
///
/// If this stream produces an error, it is considered fatal and the listener is killed. It
/// is possible to report non-fatal errors by producing a [`ListenerEvent::Error`].
type Listener: Stream<Item = Result<ListenerEvent<Self::ListenerUpgrade, Self::Error>, Self::Error>>;
type Listener: Stream<
Item = Result<ListenerEvent<Self::ListenerUpgrade, Self::Error>, Self::Error>,
>;
/// A pending [`Output`](Transport::Output) for an inbound connection,
/// obtained from the [`Listener`](Transport::Listener) stream.
@ -149,7 +151,7 @@ pub trait Transport {
fn map<F, O>(self, f: F) -> map::Map<Self, F>
where
Self: Sized,
F: FnOnce(Self::Output, ConnectedPoint) -> O + Clone
F: FnOnce(Self::Output, ConnectedPoint) -> O + Clone,
{
map::Map::new(self, f)
}
@ -158,7 +160,7 @@ pub trait Transport {
fn map_err<F, E>(self, f: F) -> map_err::MapErr<Self, F>
where
Self: Sized,
F: FnOnce(Self::Error) -> E + Clone
F: FnOnce(Self::Error) -> E + Clone,
{
map_err::MapErr::new(self, f)
}
@ -172,7 +174,7 @@ pub trait Transport {
where
Self: Sized,
U: Transport,
<U as Transport>::Error: 'static
<U as Transport>::Error: 'static,
{
OrTransport::new(self, other)
}
@ -189,7 +191,7 @@ pub trait Transport {
Self: Sized,
C: FnOnce(Self::Output, ConnectedPoint) -> F + Clone,
F: TryFuture<Ok = O>,
<F as TryFuture>::Error: Error + 'static
<F as TryFuture>::Error: Error + 'static,
{
and_then::AndThen::new(self, f)
}
@ -199,7 +201,7 @@ pub trait Transport {
fn upgrade(self, version: upgrade::Version) -> upgrade::Builder<Self>
where
Self: Sized,
Self::Error: 'static
Self::Error: 'static,
{
upgrade::Builder::new(self, version)
}
@ -222,7 +224,7 @@ pub enum ListenerEvent<TUpgr, TErr> {
/// The local address which produced this upgrade.
local_addr: Multiaddr,
/// The remote address which produced this upgrade.
remote_addr: Multiaddr
remote_addr: Multiaddr,
},
/// A [`Multiaddr`] is no longer used for listening.
AddressExpired(Multiaddr),
@ -239,9 +241,15 @@ impl<TUpgr, TErr> ListenerEvent<TUpgr, TErr> {
/// based the the function's result.
pub fn map<U>(self, f: impl FnOnce(TUpgr) -> U) -> ListenerEvent<U, TErr> {
match self {
ListenerEvent::Upgrade { upgrade, local_addr, remote_addr } => {
ListenerEvent::Upgrade { upgrade: f(upgrade), local_addr, remote_addr }
}
ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
} => ListenerEvent::Upgrade {
upgrade: f(upgrade),
local_addr,
remote_addr,
},
ListenerEvent::NewAddress(a) => ListenerEvent::NewAddress(a),
ListenerEvent::AddressExpired(a) => ListenerEvent::AddressExpired(a),
ListenerEvent::Error(e) => ListenerEvent::Error(e),
@ -253,8 +261,15 @@ impl<TUpgr, TErr> ListenerEvent<TUpgr, TErr> {
/// function's result.
pub fn map_err<U>(self, f: impl FnOnce(TErr) -> U) -> ListenerEvent<TUpgr, U> {
match self {
ListenerEvent::Upgrade { upgrade, local_addr, remote_addr } =>
ListenerEvent::Upgrade { upgrade, local_addr, remote_addr },
ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
} => ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
},
ListenerEvent::NewAddress(a) => ListenerEvent::NewAddress(a),
ListenerEvent::AddressExpired(a) => ListenerEvent::AddressExpired(a),
ListenerEvent::Error(e) => ListenerEvent::Error(f(e)),
@ -263,7 +278,7 @@ impl<TUpgr, TErr> ListenerEvent<TUpgr, TErr> {
/// Returns `true` if this is an `Upgrade` listener event.
pub fn is_upgrade(&self) -> bool {
matches!(self, ListenerEvent::Upgrade {..})
matches!(self, ListenerEvent::Upgrade { .. })
}
/// Try to turn this listener event into upgrade parts.
@ -271,7 +286,12 @@ impl<TUpgr, TErr> ListenerEvent<TUpgr, TErr> {
/// Returns `None` if the event is not actually an upgrade,
/// otherwise the upgrade and the remote address.
pub fn into_upgrade(self) -> Option<(TUpgr, Multiaddr)> {
if let ListenerEvent::Upgrade { upgrade, remote_addr, .. } = self {
if let ListenerEvent::Upgrade {
upgrade,
remote_addr,
..
} = self
{
Some((upgrade, remote_addr))
} else {
None
@ -347,25 +367,31 @@ impl<TErr> TransportError<TErr> {
/// Applies a function to the the error in [`TransportError::Other`].
pub fn map<TNewErr>(self, map: impl FnOnce(TErr) -> TNewErr) -> TransportError<TNewErr> {
match self {
TransportError::MultiaddrNotSupported(addr) => TransportError::MultiaddrNotSupported(addr),
TransportError::MultiaddrNotSupported(addr) => {
TransportError::MultiaddrNotSupported(addr)
}
TransportError::Other(err) => TransportError::Other(map(err)),
}
}
}
impl<TErr> fmt::Display for TransportError<TErr>
where TErr: fmt::Display,
where
TErr: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
TransportError::MultiaddrNotSupported(addr) => write!(f, "Multiaddr is not supported: {}", addr),
TransportError::MultiaddrNotSupported(addr) => {
write!(f, "Multiaddr is not supported: {}", addr)
}
TransportError::Other(err) => write!(f, "{}", err),
}
}
}
impl<TErr> Error for TransportError<TErr>
where TErr: Error + 'static,
where
TErr: Error + 'static,
{
fn source(&self) -> Option<&(dyn Error + 'static)> {
match self {

View File

@ -19,9 +19,9 @@
// DEALINGS IN THE SOFTWARE.
use crate::{
ConnectedPoint,
either::EitherError,
transport::{Transport, TransportError, ListenerEvent}
transport::{ListenerEvent, Transport, TransportError},
ConnectedPoint,
};
use futures::{future::Either, prelude::*};
use multiaddr::Multiaddr;
@ -29,7 +29,10 @@ use std::{error, marker::PhantomPinned, pin::Pin, task::Context, task::Poll};
/// See the `Transport::and_then` method.
#[derive(Debug, Clone)]
pub struct AndThen<T, C> { transport: T, fun: C }
pub struct AndThen<T, C> {
transport: T,
fun: C,
}
impl<T, C> AndThen<T, C> {
pub(crate) fn new(transport: T, fun: C) -> Self {
@ -51,17 +54,26 @@ where
type Dial = AndThenFuture<T::Dial, C, F>;
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
let listener = self.transport.listen_on(addr).map_err(|err| err.map(EitherError::A))?;
let listener = self
.transport
.listen_on(addr)
.map_err(|err| err.map(EitherError::A))?;
// Try to negotiate the protocol.
// Note that failing to negotiate a protocol will never produce a future with an error.
// Instead the `stream` will produce `Ok(Err(...))`.
// `stream` can only produce an `Err` if `listening_stream` produces an `Err`.
let stream = AndThenStream { stream: listener, fun: self.fun };
let stream = AndThenStream {
stream: listener,
fun: self.fun,
};
Ok(stream)
}
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
let dialed_fut = self.transport.dial(addr.clone()).map_err(|err| err.map(EitherError::A))?;
let dialed_fut = self
.transport
.dial(addr.clone())
.map_err(|err| err.map(EitherError::A))?;
let future = AndThenFuture {
inner: Either::Left(Box::pin(dialed_fut)),
args: Some((self.fun, ConnectedPoint::Dialer { address: addr })),
@ -83,19 +95,23 @@ where
pub struct AndThenStream<TListener, TMap> {
#[pin]
stream: TListener,
fun: TMap
fun: TMap,
}
impl<TListener, TMap, TTransOut, TMapOut, TListUpgr, TTransErr> Stream for AndThenStream<TListener, TMap>
impl<TListener, TMap, TTransOut, TMapOut, TListUpgr, TTransErr> Stream
for AndThenStream<TListener, TMap>
where
TListener: TryStream<Ok = ListenerEvent<TListUpgr, TTransErr>, Error = TTransErr>,
TListUpgr: TryFuture<Ok = TTransOut, Error = TTransErr>,
TMap: FnOnce(TTransOut, ConnectedPoint) -> TMapOut + Clone,
TMapOut: TryFuture
TMapOut: TryFuture,
{
type Item = Result<
ListenerEvent<AndThenFuture<TListUpgr, TMap, TMapOut>, EitherError<TTransErr, TMapOut::Error>>,
EitherError<TTransErr, TMapOut::Error>
ListenerEvent<
AndThenFuture<TListUpgr, TMap, TMapOut>,
EitherError<TTransErr, TMapOut::Error>,
>,
EitherError<TTransErr, TMapOut::Error>,
>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
@ -103,10 +119,14 @@ where
match TryStream::try_poll_next(this.stream, cx) {
Poll::Ready(Some(Ok(event))) => {
let event = match event {
ListenerEvent::Upgrade { upgrade, local_addr, remote_addr } => {
ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
} => {
let point = ConnectedPoint::Listener {
local_addr: local_addr.clone(),
send_back_addr: remote_addr.clone()
send_back_addr: remote_addr.clone(),
};
ListenerEvent::Upgrade {
upgrade: AndThenFuture {
@ -115,7 +135,7 @@ where
marker: PhantomPinned,
},
local_addr,
remote_addr
remote_addr,
}
}
ListenerEvent::NewAddress(a) => ListenerEvent::NewAddress(a),
@ -127,7 +147,7 @@ where
}
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(EitherError::A(err)))),
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending
Poll::Pending => Poll::Pending,
}
}
}
@ -159,7 +179,10 @@ where
Poll::Ready(Err(err)) => return Poll::Ready(Err(EitherError::A(err))),
Poll::Pending => return Poll::Pending,
};
let (f, a) = self.args.take().expect("AndThenFuture has already finished.");
let (f, a) = self
.args
.take()
.expect("AndThenFuture has already finished.");
f(item, a)
}
Either::Right(future) => {
@ -176,5 +199,4 @@ where
}
}
impl<TFut, TMap, TMapOut> Unpin for AndThenFuture<TFut, TMap, TMapOut> {
}
impl<TFut, TMap, TMapOut> Unpin for AndThenFuture<TFut, TMap, TMapOut> {}

View File

@ -45,7 +45,8 @@ pub struct Boxed<O> {
}
type Dial<O> = Pin<Box<dyn Future<Output = io::Result<O>> + Send>>;
type Listener<O> = Pin<Box<dyn Stream<Item = io::Result<ListenerEvent<ListenerUpgrade<O>, io::Error>>> + Send>>;
type Listener<O> =
Pin<Box<dyn Stream<Item = io::Result<ListenerEvent<ListenerUpgrade<O>, io::Error>>> + Send>>;
type ListenerUpgrade<O> = Pin<Box<dyn Future<Output = io::Result<O>> + Send>>;
trait Abstract<O> {
@ -64,12 +65,16 @@ where
{
fn listen_on(&self, addr: Multiaddr) -> Result<Listener<O>, TransportError<io::Error>> {
let listener = Transport::listen_on(self.clone(), addr).map_err(|e| e.map(box_err))?;
let fut = listener.map_ok(|event|
event.map(|upgrade| {
let up = upgrade.map_err(box_err);
Box::pin(up) as ListenerUpgrade<O>
}).map_err(box_err)
).map_err(box_err);
let fut = listener
.map_ok(|event| {
event
.map(|upgrade| {
let up = upgrade.map_err(box_err);
Box::pin(up) as ListenerUpgrade<O>
})
.map_err(box_err)
})
.map_err(box_err);
Ok(Box::pin(fut))
}

View File

@ -18,7 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::either::{EitherListenStream, EitherOutput, EitherError, EitherFuture};
use crate::either::{EitherError, EitherFuture, EitherListenStream, EitherOutput};
use crate::transport::{Transport, TransportError};
use multiaddr::Multiaddr;
@ -47,13 +47,17 @@ where
let addr = match self.0.listen_on(addr) {
Ok(listener) => return Ok(EitherListenStream::First(listener)),
Err(TransportError::MultiaddrNotSupported(addr)) => addr,
Err(TransportError::Other(err)) => return Err(TransportError::Other(EitherError::A(err))),
Err(TransportError::Other(err)) => {
return Err(TransportError::Other(EitherError::A(err)))
}
};
let addr = match self.1.listen_on(addr) {
Ok(listener) => return Ok(EitherListenStream::Second(listener)),
Err(TransportError::MultiaddrNotSupported(addr)) => addr,
Err(TransportError::Other(err)) => return Err(TransportError::Other(EitherError::B(err))),
Err(TransportError::Other(err)) => {
return Err(TransportError::Other(EitherError::B(err)))
}
};
Err(TransportError::MultiaddrNotSupported(addr))
@ -63,13 +67,17 @@ where
let addr = match self.0.dial(addr) {
Ok(connec) => return Ok(EitherFuture::First(connec)),
Err(TransportError::MultiaddrNotSupported(addr)) => addr,
Err(TransportError::Other(err)) => return Err(TransportError::Other(EitherError::A(err))),
Err(TransportError::Other(err)) => {
return Err(TransportError::Other(EitherError::A(err)))
}
};
let addr = match self.1.dial(addr) {
Ok(connec) => return Ok(EitherFuture::Second(connec)),
Err(TransportError::MultiaddrNotSupported(addr)) => addr,
Err(TransportError::Other(err)) => return Err(TransportError::Other(EitherError::B(err))),
Err(TransportError::Other(err)) => {
return Err(TransportError::Other(EitherError::B(err)))
}
};
Err(TransportError::MultiaddrNotSupported(addr))

View File

@ -18,7 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::transport::{Transport, TransportError, ListenerEvent};
use crate::transport::{ListenerEvent, Transport, TransportError};
use crate::Multiaddr;
use futures::{prelude::*, task::Context, task::Poll};
use std::{fmt, io, marker::PhantomData, pin::Pin};
@ -56,7 +56,9 @@ impl<TOut> Clone for DummyTransport<TOut> {
impl<TOut> Transport for DummyTransport<TOut> {
type Output = TOut;
type Error = io::Error;
type Listener = futures::stream::Pending<Result<ListenerEvent<Self::ListenerUpgrade, Self::Error>, Self::Error>>;
type Listener = futures::stream::Pending<
Result<ListenerEvent<Self::ListenerUpgrade, Self::Error>, Self::Error>,
>;
type ListenerUpgrade = futures::future::Pending<Result<Self::Output, io::Error>>;
type Dial = futures::future::Pending<Result<Self::Output, io::Error>>;
@ -83,29 +85,29 @@ impl fmt::Debug for DummyStream {
}
impl AsyncRead for DummyStream {
fn poll_read(self: Pin<&mut Self>, _: &mut Context<'_>, _: &mut [u8])
-> Poll<Result<usize, io::Error>>
{
fn poll_read(
self: Pin<&mut Self>,
_: &mut Context<'_>,
_: &mut [u8],
) -> Poll<Result<usize, io::Error>> {
Poll::Ready(Err(io::ErrorKind::Other.into()))
}
}
impl AsyncWrite for DummyStream {
fn poll_write(self: Pin<&mut Self>, _: &mut Context<'_>, _: &[u8])
-> Poll<Result<usize, io::Error>>
{
fn poll_write(
self: Pin<&mut Self>,
_: &mut Context<'_>,
_: &[u8],
) -> Poll<Result<usize, io::Error>> {
Poll::Ready(Err(io::ErrorKind::Other.into()))
}
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>)
-> Poll<Result<(), io::Error>>
{
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Poll::Ready(Err(io::ErrorKind::Other.into()))
}
fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>)
-> Poll<Result<(), io::Error>>
{
fn poll_close(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), io::Error>> {
Poll::Ready(Err(io::ErrorKind::Other.into()))
}
}

View File

@ -19,8 +19,8 @@
// DEALINGS IN THE SOFTWARE.
use crate::{
transport::{ListenerEvent, Transport, TransportError},
ConnectedPoint,
transport::{Transport, TransportError, ListenerEvent}
};
use futures::prelude::*;
use multiaddr::Multiaddr;
@ -28,7 +28,10 @@ use std::{pin::Pin, task::Context, task::Poll};
/// See `Transport::map`.
#[derive(Debug, Copy, Clone)]
pub struct Map<T, F> { transport: T, fun: F }
pub struct Map<T, F> {
transport: T,
fun: F,
}
impl<T, F> Map<T, F> {
pub(crate) fn new(transport: T, fun: F) -> Self {
@ -39,7 +42,7 @@ impl<T, F> Map<T, F> {
impl<T, F, D> Transport for Map<T, F>
where
T: Transport,
F: FnOnce(T::Output, ConnectedPoint) -> D + Clone
F: FnOnce(T::Output, ConnectedPoint) -> D + Clone,
{
type Output = D;
type Error = T::Error;
@ -49,13 +52,19 @@ where
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
let stream = self.transport.listen_on(addr)?;
Ok(MapStream { stream, fun: self.fun })
Ok(MapStream {
stream,
fun: self.fun,
})
}
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
let future = self.transport.dial(addr.clone())?;
let p = ConnectedPoint::Dialer { address: addr };
Ok(MapFuture { inner: future, args: Some((self.fun, p)) })
Ok(MapFuture {
inner: future,
args: Some((self.fun, p)),
})
}
fn address_translation(&self, server: &Multiaddr, observed: &Multiaddr) -> Option<Multiaddr> {
@ -68,13 +77,17 @@ where
/// Maps a function over every stream item.
#[pin_project::pin_project]
#[derive(Clone, Debug)]
pub struct MapStream<T, F> { #[pin] stream: T, fun: F }
pub struct MapStream<T, F> {
#[pin]
stream: T,
fun: F,
}
impl<T, F, A, B, X, E> Stream for MapStream<T, F>
where
T: TryStream<Ok = ListenerEvent<X, E>, Error = E>,
X: TryFuture<Ok = A>,
F: FnOnce(A, ConnectedPoint) -> B + Clone
F: FnOnce(A, ConnectedPoint) -> B + Clone,
{
type Item = Result<ListenerEvent<MapFuture<X, F>, E>, E>;
@ -83,18 +96,22 @@ where
match TryStream::try_poll_next(this.stream, cx) {
Poll::Ready(Some(Ok(event))) => {
let event = match event {
ListenerEvent::Upgrade { upgrade, local_addr, remote_addr } => {
ListenerEvent::Upgrade {
upgrade,
local_addr,
remote_addr,
} => {
let point = ConnectedPoint::Listener {
local_addr: local_addr.clone(),
send_back_addr: remote_addr.clone()
send_back_addr: remote_addr.clone(),
};
ListenerEvent::Upgrade {
upgrade: MapFuture {
inner: upgrade,
args: Some((this.fun.clone(), point))
args: Some((this.fun.clone(), point)),
},
local_addr,
remote_addr
remote_addr,
}
}
ListenerEvent::NewAddress(a) => ListenerEvent::NewAddress(a),
@ -105,7 +122,7 @@ where
}
Poll::Ready(Some(Err(err))) => Poll::Ready(Some(Err(err))),
Poll::Ready(None) => Poll::Ready(None),
Poll::Pending => Poll::Pending
Poll::Pending => Poll::Pending,
}
}
}
@ -118,13 +135,13 @@ where
pub struct MapFuture<T, F> {
#[pin]
inner: T,
args: Option<(F, ConnectedPoint)>
args: Option<(F, ConnectedPoint)>,
}
impl<T, A, F, B> Future for MapFuture<T, F>
where
T: TryFuture<Ok = A>,
F: FnOnce(A, ConnectedPoint) -> B
F: FnOnce(A, ConnectedPoint) -> B,
{
type Output = Result<B, T::Error>;

View File

@ -18,7 +18,7 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::transport::{Transport, TransportError, ListenerEvent};
use crate::transport::{ListenerEvent, Transport, TransportError};
use futures::prelude::*;
use multiaddr::Multiaddr;
use std::{error, pin::Pin, task::Context, task::Poll};
@ -53,14 +53,17 @@ where
let map = self.map;
match self.transport.listen_on(addr) {
Ok(stream) => Ok(MapErrListener { inner: stream, map }),
Err(err) => Err(err.map(map))
Err(err) => Err(err.map(map)),
}
}
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
let map = self.map;
match self.transport.dial(addr) {
Ok(future) => Ok(MapErrDial { inner: future, map: Some(map) }),
Ok(future) => Ok(MapErrDial {
inner: future,
map: Some(map),
}),
Err(err) => Err(err.map(map)),
}
}
@ -92,11 +95,9 @@ where
Poll::Ready(Some(Ok(event))) => {
let map = &*this.map;
let event = event
.map(move |value| {
MapErrListenerUpgrade {
inner: value,
map: Some(map.clone())
}
.map(move |value| MapErrListenerUpgrade {
inner: value,
map: Some(map.clone()),
})
.map_err(|err| (map.clone())(err));
Poll::Ready(Some(Ok(event)))
@ -117,7 +118,8 @@ pub struct MapErrListenerUpgrade<T: Transport, F> {
}
impl<T, F, TErr> Future for MapErrListenerUpgrade<T, F>
where T: Transport,
where
T: Transport,
F: FnOnce(T::Error) -> TErr,
{
type Output = Result<T::Output, TErr>;

View File

@ -18,11 +18,20 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::{Transport, transport::{TransportError, ListenerEvent}};
use crate::{
transport::{ListenerEvent, TransportError},
Transport,
};
use fnv::FnvHashMap;
use futures::{future::{self, Ready}, prelude::*, channel::mpsc, task::Context, task::Poll};
use futures::{
channel::mpsc,
future::{self, Ready},
prelude::*,
task::Context,
task::Poll,
};
use lazy_static::lazy_static;
use multiaddr::{Protocol, Multiaddr};
use multiaddr::{Multiaddr, Protocol};
use parking_lot::Mutex;
use rw_stream_sink::RwStreamSink;
use std::{collections::hash_map::Entry, error, fmt, io, num::NonZeroU64, pin::Pin};
@ -66,7 +75,7 @@ impl Hub {
let (tx, rx) = mpsc::channel(2);
match hub.entry(port) {
Entry::Occupied(_) => return None,
Entry::Vacant(e) => e.insert(tx)
Entry::Vacant(e) => e.insert(tx),
};
Some((rx, port))
@ -103,7 +112,8 @@ impl DialFuture {
fn new(port: NonZeroU64) -> Option<Self> {
let sender = HUB.get(&port)?;
let (_dial_port_channel, dial_port) = HUB.register_port(0)
let (_dial_port_channel, dial_port) = HUB
.register_port(0)
.expect("there to be some random unoccupied port.");
let (a_tx, a_rx) = mpsc::channel(4096);
@ -129,14 +139,15 @@ impl Future for DialFuture {
type Output = Result<Channel<Vec<u8>>, MemoryTransportError>;
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
match self.sender.poll_ready(cx) {
Poll::Pending => return Poll::Pending,
Poll::Ready(Ok(())) => {},
Poll::Ready(Ok(())) => {}
Poll::Ready(Err(_)) => return Poll::Ready(Err(MemoryTransportError::Unreachable)),
}
let channel_to_send = self.channel_to_send.take()
let channel_to_send = self
.channel_to_send
.take()
.expect("Future should not be polled again once complete");
let dial_port = self.dial_port;
match self.sender.start_send((channel_to_send, dial_port)) {
@ -144,8 +155,10 @@ impl Future for DialFuture {
Ok(()) => {}
}
Poll::Ready(Ok(self.channel_to_return.take()
.expect("Future should not be polled again once complete")))
Poll::Ready(Ok(self
.channel_to_return
.take()
.expect("Future should not be polled again once complete")))
}
}
@ -172,7 +185,7 @@ impl Transport for MemoryTransport {
port,
addr: Protocol::Memory(port.get()).into(),
receiver: rx,
tell_listen_addr: true
tell_listen_addr: true,
};
Ok(listener)
@ -226,16 +239,19 @@ pub struct Listener {
/// Receives incoming connections.
receiver: ChannelReceiver,
/// Generate `ListenerEvent::NewAddress` to inform about our listen address.
tell_listen_addr: bool
tell_listen_addr: bool,
}
impl Stream for Listener {
type Item = Result<ListenerEvent<Ready<Result<Channel<Vec<u8>>, MemoryTransportError>>, MemoryTransportError>, MemoryTransportError>;
type Item = Result<
ListenerEvent<Ready<Result<Channel<Vec<u8>>, MemoryTransportError>>, MemoryTransportError>,
MemoryTransportError,
>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
if self.tell_listen_addr {
self.tell_listen_addr = false;
return Poll::Ready(Some(Ok(ListenerEvent::NewAddress(self.addr.clone()))))
return Poll::Ready(Some(Ok(ListenerEvent::NewAddress(self.addr.clone()))));
}
let (channel, dial_port) = match Stream::poll_next(Pin::new(&mut self.receiver), cx) {
@ -247,7 +263,7 @@ impl Stream for Listener {
let event = ListenerEvent::Upgrade {
upgrade: future::ready(Ok(channel)),
local_addr: self.addr.clone(),
remote_addr: Protocol::Memory(dial_port.get()).into()
remote_addr: Protocol::Memory(dial_port.get()).into(),
};
Poll::Ready(Some(Ok(event)))
@ -267,9 +283,9 @@ fn parse_memory_addr(a: &Multiaddr) -> Result<u64, ()> {
match protocols.next() {
Some(Protocol::Memory(port)) => match protocols.next() {
None | Some(Protocol::P2p(_)) => Ok(port),
_ => Err(())
}
_ => Err(())
_ => Err(()),
},
_ => Err(()),
}
}
@ -294,8 +310,7 @@ pub struct Chan<T = Vec<u8>> {
dial_port: Option<NonZeroU64>,
}
impl<T> Unpin for Chan<T> {
}
impl<T> Unpin for Chan<T> {}
impl<T> Stream for Chan<T> {
type Item = Result<T, io::Error>;
@ -313,12 +328,15 @@ impl<T> Sink<T> for Chan<T> {
type Error = io::Error;
fn poll_ready(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
self.outgoing.poll_ready(cx)
self.outgoing
.poll_ready(cx)
.map(|v| v.map_err(|_| io::ErrorKind::BrokenPipe.into()))
}
fn start_send(mut self: Pin<&mut Self>, item: T) -> Result<(), Self::Error> {
self.outgoing.start_send(item).map_err(|_| io::ErrorKind::BrokenPipe.into())
self.outgoing
.start_send(item)
.map_err(|_| io::ErrorKind::BrokenPipe.into())
}
fn poll_flush(self: Pin<&mut Self>, _: &mut Context<'_>) -> Poll<Result<(), Self::Error>> {
@ -354,30 +372,59 @@ mod tests {
assert_eq!(parse_memory_addr(&"/memory/5".parse().unwrap()), Ok(5));
assert_eq!(parse_memory_addr(&"/tcp/150".parse().unwrap()), Err(()));
assert_eq!(parse_memory_addr(&"/memory/0".parse().unwrap()), Ok(0));
assert_eq!(parse_memory_addr(&"/memory/5/tcp/150".parse().unwrap()), Err(()));
assert_eq!(parse_memory_addr(&"/tcp/150/memory/5".parse().unwrap()), Err(()));
assert_eq!(parse_memory_addr(&"/memory/1234567890".parse().unwrap()), Ok(1_234_567_890));
assert_eq!(
parse_memory_addr(&"/memory/5/tcp/150".parse().unwrap()),
Err(())
);
assert_eq!(
parse_memory_addr(&"/tcp/150/memory/5".parse().unwrap()),
Err(())
);
assert_eq!(
parse_memory_addr(&"/memory/1234567890".parse().unwrap()),
Ok(1_234_567_890)
);
}
#[test]
fn listening_twice() {
let transport = MemoryTransport::default();
assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
let _listener = transport.listen_on("/memory/1639174018481".parse().unwrap()).unwrap();
assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_err());
assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_err());
assert!(transport
.listen_on("/memory/1639174018481".parse().unwrap())
.is_ok());
assert!(transport
.listen_on("/memory/1639174018481".parse().unwrap())
.is_ok());
let _listener = transport
.listen_on("/memory/1639174018481".parse().unwrap())
.unwrap();
assert!(transport
.listen_on("/memory/1639174018481".parse().unwrap())
.is_err());
assert!(transport
.listen_on("/memory/1639174018481".parse().unwrap())
.is_err());
drop(_listener);
assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
assert!(transport.listen_on("/memory/1639174018481".parse().unwrap()).is_ok());
assert!(transport
.listen_on("/memory/1639174018481".parse().unwrap())
.is_ok());
assert!(transport
.listen_on("/memory/1639174018481".parse().unwrap())
.is_ok());
}
#[test]
fn port_not_in_use() {
let transport = MemoryTransport::default();
assert!(transport.dial("/memory/810172461024613".parse().unwrap()).is_err());
let _listener = transport.listen_on("/memory/810172461024613".parse().unwrap()).unwrap();
assert!(transport.dial("/memory/810172461024613".parse().unwrap()).is_ok());
assert!(transport
.dial("/memory/810172461024613".parse().unwrap())
.is_err());
let _listener = transport
.listen_on("/memory/810172461024613".parse().unwrap())
.unwrap();
assert!(transport
.dial("/memory/810172461024613".parse().unwrap())
.is_ok());
}
#[test]
@ -395,9 +442,11 @@ mod tests {
let listener = async move {
let listener = t1.listen_on(t1_addr.clone()).unwrap();
let upgrade = listener.filter_map(|ev| futures::future::ready(
ListenerEvent::into_upgrade(ev.unwrap())
)).next().await.unwrap();
let upgrade = listener
.filter_map(|ev| futures::future::ready(ListenerEvent::into_upgrade(ev.unwrap())))
.next()
.await
.unwrap();
let mut socket = upgrade.0.await.unwrap();
@ -422,16 +471,14 @@ mod tests {
#[test]
fn dialer_address_unequal_to_listener_address() {
let listener_addr: Multiaddr = Protocol::Memory(
rand::random::<u64>().saturating_add(1),
).into();
let listener_addr: Multiaddr =
Protocol::Memory(rand::random::<u64>().saturating_add(1)).into();
let listener_addr_cloned = listener_addr.clone();
let listener_transport = MemoryTransport::default();
let listener = async move {
let mut listener = listener_transport.listen_on(listener_addr.clone())
.unwrap();
let mut listener = listener_transport.listen_on(listener_addr.clone()).unwrap();
while let Some(ev) = listener.next().await {
if let ListenerEvent::Upgrade { remote_addr, .. } = ev.unwrap() {
assert!(
@ -444,7 +491,8 @@ mod tests {
};
let dialer = async move {
MemoryTransport::default().dial(listener_addr_cloned)
MemoryTransport::default()
.dial(listener_addr_cloned)
.unwrap()
.await
.unwrap();
@ -458,21 +506,18 @@ mod tests {
let (terminate, should_terminate) = futures::channel::oneshot::channel();
let (terminated, is_terminated) = futures::channel::oneshot::channel();
let listener_addr: Multiaddr = Protocol::Memory(
rand::random::<u64>().saturating_add(1),
).into();
let listener_addr: Multiaddr =
Protocol::Memory(rand::random::<u64>().saturating_add(1)).into();
let listener_addr_cloned = listener_addr.clone();
let listener_transport = MemoryTransport::default();
let listener = async move {
let mut listener = listener_transport.listen_on(listener_addr.clone())
.unwrap();
let mut listener = listener_transport.listen_on(listener_addr.clone()).unwrap();
while let Some(ev) = listener.next().await {
if let ListenerEvent::Upgrade { remote_addr, .. } = ev.unwrap() {
let dialer_port = NonZeroU64::new(
parse_memory_addr(&remote_addr).unwrap(),
).unwrap();
let dialer_port =
NonZeroU64::new(parse_memory_addr(&remote_addr).unwrap()).unwrap();
assert!(
HUB.get(&dialer_port).is_some(),
@ -493,7 +538,8 @@ mod tests {
};
let dialer = async move {
let _chan = MemoryTransport::default().dial(listener_addr_cloned)
let _chan = MemoryTransport::default()
.dial(listener_addr_cloned)
.unwrap()
.await
.unwrap();

View File

@ -24,7 +24,10 @@
//! underlying `Transport`.
// TODO: add example
use crate::{Multiaddr, Transport, transport::{TransportError, ListenerEvent}};
use crate::{
transport::{ListenerEvent, TransportError},
Multiaddr, Transport,
};
use futures::prelude::*;
use futures_timer::Delay;
use std::{error, fmt, io, pin::Pin, task::Context, task::Poll, time::Duration};
@ -82,7 +85,9 @@ where
type Dial = Timeout<InnerTrans::Dial>;
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
let listener = self.inner.listen_on(addr)
let listener = self
.inner
.listen_on(addr)
.map_err(|err| err.map(TransportTimeoutError::Other))?;
let listener = TimeoutListener {
@ -94,7 +99,9 @@ where
}
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
let dial = self.inner.dial(addr)
let dial = self
.inner
.dial(addr)
.map_err(|err| err.map(TransportTimeoutError::Other))?;
Ok(Timeout {
inner: dial,
@ -120,13 +127,16 @@ impl<InnerStream, O, E> Stream for TimeoutListener<InnerStream>
where
InnerStream: TryStream<Ok = ListenerEvent<O, E>, Error = E>,
{
type Item = Result<ListenerEvent<Timeout<O>, TransportTimeoutError<E>>, TransportTimeoutError<E>>;
type Item =
Result<ListenerEvent<Timeout<O>, TransportTimeoutError<E>>, TransportTimeoutError<E>>;
fn poll_next(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
let this = self.project();
let poll_out = match TryStream::try_poll_next(this.inner, cx) {
Poll::Ready(Some(Err(err))) => return Poll::Ready(Some(Err(TransportTimeoutError::Other(err)))),
Poll::Ready(Some(Err(err))) => {
return Poll::Ready(Some(Err(TransportTimeoutError::Other(err))))
}
Poll::Ready(Some(Ok(v))) => v,
Poll::Ready(None) => return Poll::Ready(None),
Poll::Pending => return Poll::Pending,
@ -134,11 +144,9 @@ where
let timeout = *this.timeout;
let event = poll_out
.map(move |inner_fut| {
Timeout {
inner: inner_fut,
timer: Delay::new(timeout),
}
.map(move |inner_fut| Timeout {
inner: inner_fut,
timer: Delay::new(timeout),
})
.map_err(TransportTimeoutError::Other);
@ -173,14 +181,14 @@ where
let mut this = self.project();
match TryFuture::try_poll(this.inner, cx) {
Poll::Pending => {},
Poll::Pending => {}
Poll::Ready(Ok(v)) => return Poll::Ready(Ok(v)),
Poll::Ready(Err(err)) => return Poll::Ready(Err(TransportTimeoutError::Other(err))),
}
match Pin::new(&mut this.timer).poll(cx) {
Poll::Pending => Poll::Pending,
Poll::Ready(()) => Poll::Ready(Err(TransportTimeoutError::Timeout))
Poll::Ready(()) => Poll::Ready(Err(TransportTimeoutError::Timeout)),
}
}
}
@ -197,7 +205,8 @@ pub enum TransportTimeoutError<TErr> {
}
impl<TErr> fmt::Display for TransportTimeoutError<TErr>
where TErr: fmt::Display,
where
TErr: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@ -209,7 +218,8 @@ where TErr: fmt::Display,
}
impl<TErr> error::Error for TransportTimeoutError<TErr>
where TErr: error::Error + 'static,
where
TErr: error::Error + 'static,
{
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
match self {

View File

@ -23,28 +23,16 @@
pub use crate::upgrade::Version;
use crate::{
ConnectedPoint,
Negotiated,
transport::{
Transport,
TransportError,
ListenerEvent,
and_then::AndThen,
boxed::boxed,
timeout::TransportTimeout,
},
muxing::{StreamMuxer, StreamMuxerBox},
upgrade::{
self,
OutboundUpgrade,
InboundUpgrade,
apply_inbound,
apply_outbound,
UpgradeError,
OutboundUpgradeApply,
InboundUpgradeApply
transport::{
and_then::AndThen, boxed::boxed, timeout::TransportTimeout, ListenerEvent, Transport,
TransportError,
},
PeerId
upgrade::{
self, apply_inbound, apply_outbound, InboundUpgrade, InboundUpgradeApply, OutboundUpgrade,
OutboundUpgradeApply, UpgradeError,
},
ConnectedPoint, Negotiated, PeerId,
};
use futures::{prelude::*, ready};
use multiaddr::Multiaddr;
@ -53,7 +41,7 @@ use std::{
fmt,
pin::Pin,
task::{Context, Poll},
time::Duration
time::Duration,
};
/// A `Builder` facilitates upgrading of a [`Transport`] for use with
@ -105,9 +93,11 @@ where
///
/// * I/O upgrade: `C -> (PeerId, D)`.
/// * Transport output: `C -> (PeerId, D)`
pub fn authenticate<C, D, U, E>(self, upgrade: U) -> Authenticated<
AndThen<T, impl FnOnce(C, ConnectedPoint) -> Authenticate<C, U> + Clone>
> where
pub fn authenticate<C, D, U, E>(
self,
upgrade: U,
) -> Authenticated<AndThen<T, impl FnOnce(C, ConnectedPoint) -> Authenticate<C, U> + Clone>>
where
T: Transport<Output = C>,
C: AsyncRead + AsyncWrite + Unpin,
D: AsyncRead + AsyncWrite + Unpin,
@ -116,11 +106,12 @@ where
E: Error + 'static,
{
let version = self.version;
Authenticated(Builder::new(self.inner.and_then(move |conn, endpoint| {
Authenticate {
inner: upgrade::apply(conn, upgrade, endpoint, version)
}
}), version))
Authenticated(Builder::new(
self.inner.and_then(move |conn, endpoint| Authenticate {
inner: upgrade::apply(conn, upgrade, endpoint, version),
}),
version,
))
}
}
@ -132,19 +123,21 @@ where
pub struct Authenticate<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>> + OutboundUpgrade<Negotiated<C>>
U: InboundUpgrade<Negotiated<C>> + OutboundUpgrade<Negotiated<C>>,
{
#[pin]
inner: EitherUpgrade<C, U>
inner: EitherUpgrade<C, U>,
}
impl<C, U> Future for Authenticate<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>> + OutboundUpgrade<Negotiated<C>,
Output = <U as InboundUpgrade<Negotiated<C>>>::Output,
Error = <U as InboundUpgrade<Negotiated<C>>>::Error
>
U: InboundUpgrade<Negotiated<C>>
+ OutboundUpgrade<
Negotiated<C>,
Output = <U as InboundUpgrade<Negotiated<C>>>::Output,
Error = <U as InboundUpgrade<Negotiated<C>>>::Error,
>,
{
type Output = <EitherUpgrade<C, U> as Future>::Output;
@ -173,7 +166,7 @@ impl<C, U, M, E> Future for Multiplex<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>, Output = M, Error = E>,
U: OutboundUpgrade<Negotiated<C>, Output = M, Error = E>
U: OutboundUpgrade<Negotiated<C>, Output = M, Error = E>,
{
type Output = Result<(PeerId, M), UpgradeError<E>>;
@ -183,7 +176,10 @@ where
Ok(m) => m,
Err(err) => return Poll::Ready(Err(err)),
};
let i = this.peer_id.take().expect("Multiplex future polled after completion.");
let i = this
.peer_id
.take()
.expect("Multiplex future polled after completion.");
Poll::Ready(Ok((i, m)))
}
}
@ -195,7 +191,7 @@ pub struct Authenticated<T>(Builder<T>);
impl<T> Authenticated<T>
where
T: Transport,
T::Error: 'static
T::Error: 'static,
{
/// Applies an arbitrary upgrade.
///
@ -216,7 +212,10 @@ where
U: OutboundUpgrade<Negotiated<C>, Output = D, Error = E> + Clone,
E: Error + 'static,
{
Authenticated(Builder::new(Upgrade::new(self.0.inner, upgrade), self.0.version))
Authenticated(Builder::new(
Upgrade::new(self.0.inner, upgrade),
self.0.version,
))
}
/// Upgrades the transport with a (sub)stream multiplexer.
@ -229,9 +228,11 @@ where
///
/// * I/O upgrade: `C -> M`.
/// * Transport output: `(PeerId, C) -> (PeerId, M)`.
pub fn multiplex<C, M, U, E>(self, upgrade: U) -> Multiplexed<
AndThen<T, impl FnOnce((PeerId, C), ConnectedPoint) -> Multiplex<C, U> + Clone>
> where
pub fn multiplex<C, M, U, E>(
self,
upgrade: U,
) -> Multiplexed<AndThen<T, impl FnOnce((PeerId, C), ConnectedPoint) -> Multiplex<C, U> + Clone>>
where
T: Transport<Output = (PeerId, C)>,
C: AsyncRead + AsyncWrite + Unpin,
M: StreamMuxer,
@ -242,7 +243,10 @@ where
let version = self.0.version;
Multiplexed(self.0.inner.and_then(move |(i, c), endpoint| {
let upgrade = upgrade::apply(c, upgrade, endpoint, version);
Multiplex { peer_id: Some(i), upgrade }
Multiplex {
peer_id: Some(i),
upgrade,
}
}))
}
@ -257,21 +261,26 @@ where
///
/// * I/O upgrade: `C -> M`.
/// * Transport output: `(PeerId, C) -> (PeerId, M)`.
pub fn multiplex_ext<C, M, U, E, F>(self, up: F) -> Multiplexed<
AndThen<T, impl FnOnce((PeerId, C), ConnectedPoint) -> Multiplex<C, U> + Clone>
> where
pub fn multiplex_ext<C, M, U, E, F>(
self,
up: F,
) -> Multiplexed<AndThen<T, impl FnOnce((PeerId, C), ConnectedPoint) -> Multiplex<C, U> + Clone>>
where
T: Transport<Output = (PeerId, C)>,
C: AsyncRead + AsyncWrite + Unpin,
M: StreamMuxer,
U: InboundUpgrade<Negotiated<C>, Output = M, Error = E>,
U: OutboundUpgrade<Negotiated<C>, Output = M, Error = E> + Clone,
E: Error + 'static,
F: for<'a> FnOnce(&'a PeerId, &'a ConnectedPoint) -> U + Clone
F: for<'a> FnOnce(&'a PeerId, &'a ConnectedPoint) -> U + Clone,
{
let version = self.0.version;
Multiplexed(self.0.inner.and_then(move |(peer_id, c), endpoint| {
let upgrade = upgrade::apply(c, up(&peer_id, &endpoint), endpoint, version);
Multiplex { peer_id: Some(peer_id), upgrade }
Multiplex {
peer_id: Some(peer_id),
upgrade,
}
}))
}
}
@ -293,7 +302,7 @@ impl<T> Multiplexed<T> {
T::Error: Send + Sync,
M: StreamMuxer + Send + Sync + 'static,
M::Substream: Send + 'static,
M::OutboundSubstream: Send + 'static
M::OutboundSubstream: Send + 'static,
{
boxed(self.map(|(i, m), _| (i, StreamMuxerBox::new(m))))
}
@ -347,7 +356,10 @@ type EitherUpgrade<C, U> = future::Either<InboundUpgradeApply<C, U>, OutboundUpg
///
/// See [`Transport::upgrade`]
#[derive(Debug, Copy, Clone)]
pub struct Upgrade<T, U> { inner: T, upgrade: U }
pub struct Upgrade<T, U> {
inner: T,
upgrade: U,
}
impl<T, U> Upgrade<T, U> {
pub fn new(inner: T, upgrade: U) -> Self {
@ -362,7 +374,7 @@ where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>, Output = D, Error = E>,
U: OutboundUpgrade<Negotiated<C>, Output = D, Error = E> + Clone,
E: Error + 'static
E: Error + 'static,
{
type Output = (PeerId, D);
type Error = TransportUpgradeError<T::Error, E>;
@ -371,20 +383,24 @@ where
type Dial = DialUpgradeFuture<T::Dial, U, C>;
fn dial(self, addr: Multiaddr) -> Result<Self::Dial, TransportError<Self::Error>> {
let future = self.inner.dial(addr)
let future = self
.inner
.dial(addr)
.map_err(|err| err.map(TransportUpgradeError::Transport))?;
Ok(DialUpgradeFuture {
future: Box::pin(future),
upgrade: future::Either::Left(Some(self.upgrade))
upgrade: future::Either::Left(Some(self.upgrade)),
})
}
fn listen_on(self, addr: Multiaddr) -> Result<Self::Listener, TransportError<Self::Error>> {
let stream = self.inner.listen_on(addr)
let stream = self
.inner
.listen_on(addr)
.map_err(|err| err.map(TransportUpgradeError::Transport))?;
Ok(ListenerStream {
stream: Box::pin(stream),
upgrade: self.upgrade
upgrade: self.upgrade,
})
}
@ -435,7 +451,7 @@ where
C: AsyncRead + AsyncWrite + Unpin,
{
future: Pin<Box<F>>,
upgrade: future::Either<Option<U>, (Option<PeerId>, OutboundUpgradeApply<C, U>)>
upgrade: future::Either<Option<U>, (Option<PeerId>, OutboundUpgradeApply<C, U>)>,
}
impl<F, U, C, D> Future for DialUpgradeFuture<F, U, C>
@ -443,7 +459,7 @@ where
F: TryFuture<Ok = (PeerId, C)>,
C: AsyncRead + AsyncWrite + Unpin,
U: OutboundUpgrade<Negotiated<C>, Output = D>,
U::Error: Error
U::Error: Error,
{
type Output = Result<(PeerId, D), TransportUpgradeError<F::Error, U::Error>>;
@ -455,20 +471,28 @@ where
loop {
this.upgrade = match this.upgrade {
future::Either::Left(ref mut up) => {
let (i, c) = match ready!(TryFuture::try_poll(this.future.as_mut(), cx).map_err(TransportUpgradeError::Transport)) {
let (i, c) = match ready!(TryFuture::try_poll(this.future.as_mut(), cx)
.map_err(TransportUpgradeError::Transport))
{
Ok(v) => v,
Err(err) => return Poll::Ready(Err(err)),
};
let u = up.take().expect("DialUpgradeFuture is constructed with Either::Left(Some).");
let u = up
.take()
.expect("DialUpgradeFuture is constructed with Either::Left(Some).");
future::Either::Right((Some(i), apply_outbound(c, u, upgrade::Version::V1)))
}
future::Either::Right((ref mut i, ref mut up)) => {
let d = match ready!(Future::poll(Pin::new(up), cx).map_err(TransportUpgradeError::Upgrade)) {
let d = match ready!(
Future::poll(Pin::new(up), cx).map_err(TransportUpgradeError::Upgrade)
) {
Ok(d) => d,
Err(err) => return Poll::Ready(Err(err)),
};
let i = i.take().expect("DialUpgradeFuture polled after completion.");
return Poll::Ready(Ok((i, d)))
let i = i
.take()
.expect("DialUpgradeFuture polled after completion.");
return Poll::Ready(Ok((i, d)));
}
}
}
@ -485,7 +509,7 @@ where
/// The [`Transport::Listener`] stream of an [`Upgrade`]d transport.
pub struct ListenerStream<S, U> {
stream: Pin<Box<S>>,
upgrade: U
upgrade: U,
}
impl<S, U, F, C, D, E> Stream for ListenerStream<S, U>
@ -493,42 +517,40 @@ where
S: TryStream<Ok = ListenerEvent<F, E>, Error = E>,
F: TryFuture<Ok = (PeerId, C)>,
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>, Output = D> + Clone
U: InboundUpgrade<Negotiated<C>, Output = D> + Clone,
{
type Item = Result<ListenerEvent<ListenerUpgradeFuture<F, U, C>, TransportUpgradeError<E, U::Error>>, TransportUpgradeError<E, U::Error>>;
type Item = Result<
ListenerEvent<ListenerUpgradeFuture<F, U, C>, TransportUpgradeError<E, U::Error>>,
TransportUpgradeError<E, U::Error>,
>;
fn poll_next(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Option<Self::Item>> {
match ready!(TryStream::try_poll_next(self.stream.as_mut(), cx)) {
Some(Ok(event)) => {
let event = event
.map(move |future| {
ListenerUpgradeFuture {
future: Box::pin(future),
upgrade: future::Either::Left(Some(self.upgrade.clone()))
}
.map(move |future| ListenerUpgradeFuture {
future: Box::pin(future),
upgrade: future::Either::Left(Some(self.upgrade.clone())),
})
.map_err(TransportUpgradeError::Transport);
Poll::Ready(Some(Ok(event)))
}
Some(Err(err)) => {
Poll::Ready(Some(Err(TransportUpgradeError::Transport(err))))
}
None => Poll::Ready(None)
Some(Err(err)) => Poll::Ready(Some(Err(TransportUpgradeError::Transport(err)))),
None => Poll::Ready(None),
}
}
}
impl<S, U> Unpin for ListenerStream<S, U> {
}
impl<S, U> Unpin for ListenerStream<S, U> {}
/// The [`Transport::ListenerUpgrade`] future of an [`Upgrade`]d transport.
pub struct ListenerUpgradeFuture<F, U, C>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>>
U: InboundUpgrade<Negotiated<C>>,
{
future: Pin<Box<F>>,
upgrade: future::Either<Option<U>, (Option<PeerId>, InboundUpgradeApply<C, U>)>
upgrade: future::Either<Option<U>, (Option<PeerId>, InboundUpgradeApply<C, U>)>,
}
impl<F, U, C, D> Future for ListenerUpgradeFuture<F, U, C>
@ -536,7 +558,7 @@ where
F: TryFuture<Ok = (PeerId, C)>,
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>, Output = D>,
U::Error: Error
U::Error: Error,
{
type Output = Result<(PeerId, D), TransportUpgradeError<F::Error, U::Error>>;
@ -548,20 +570,28 @@ where
loop {
this.upgrade = match this.upgrade {
future::Either::Left(ref mut up) => {
let (i, c) = match ready!(TryFuture::try_poll(this.future.as_mut(), cx).map_err(TransportUpgradeError::Transport)) {
let (i, c) = match ready!(TryFuture::try_poll(this.future.as_mut(), cx)
.map_err(TransportUpgradeError::Transport))
{
Ok(v) => v,
Err(err) => return Poll::Ready(Err(err))
Err(err) => return Poll::Ready(Err(err)),
};
let u = up.take().expect("ListenerUpgradeFuture is constructed with Either::Left(Some).");
let u = up
.take()
.expect("ListenerUpgradeFuture is constructed with Either::Left(Some).");
future::Either::Right((Some(i), apply_inbound(c, u)))
}
future::Either::Right((ref mut i, ref mut up)) => {
let d = match ready!(TryFuture::try_poll(Pin::new(up), cx).map_err(TransportUpgradeError::Upgrade)) {
let d = match ready!(TryFuture::try_poll(Pin::new(up), cx)
.map_err(TransportUpgradeError::Upgrade))
{
Ok(v) => v,
Err(err) => return Poll::Ready(Err(err))
Err(err) => return Poll::Ready(Err(err)),
};
let i = i.take().expect("ListenerUpgradeFuture polled after completion.");
return Poll::Ready(Ok((i, d)))
let i = i
.take()
.expect("ListenerUpgradeFuture polled after completion.");
return Poll::Ready(Ok((i, d)));
}
}
}
@ -571,6 +601,6 @@ where
impl<F, U, C> Unpin for ListenerUpgradeFuture<F, U, C>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>>
U: InboundUpgrade<Negotiated<C>>,
{
}

View File

@ -69,21 +69,21 @@ mod transfer;
use futures::future::Future;
pub use crate::Negotiated;
pub use multistream_select::{Version, NegotiatedComplete, NegotiationError, ProtocolError};
#[allow(deprecated)]
pub use self::transfer::ReadOneError;
pub use self::{
apply::{apply, apply_inbound, apply_outbound, InboundUpgradeApply, OutboundUpgradeApply},
denied::DeniedUpgrade,
either::EitherUpgrade,
error::UpgradeError,
from_fn::{from_fn, FromFnUpgrade},
map::{MapInboundUpgrade, MapOutboundUpgrade, MapInboundUpgradeErr, MapOutboundUpgradeErr},
map::{MapInboundUpgrade, MapInboundUpgradeErr, MapOutboundUpgrade, MapOutboundUpgradeErr},
optional::OptionalUpgrade,
select::SelectUpgrade,
transfer::{write_length_prefixed, write_varint, read_length_prefixed, read_varint},
transfer::{read_length_prefixed, read_varint, write_length_prefixed, write_varint},
};
#[allow(deprecated)]
pub use self::transfer::ReadOneError;
pub use crate::Negotiated;
pub use multistream_select::{NegotiatedComplete, NegotiationError, ProtocolError, Version};
/// Types serving as protocol names.
///
@ -167,7 +167,7 @@ pub trait InboundUpgradeExt<C>: InboundUpgrade<C> {
fn map_inbound<F, T>(self, f: F) -> MapInboundUpgrade<Self, F>
where
Self: Sized,
F: FnOnce(Self::Output) -> T
F: FnOnce(Self::Output) -> T,
{
MapInboundUpgrade::new(self, f)
}
@ -176,7 +176,7 @@ pub trait InboundUpgradeExt<C>: InboundUpgrade<C> {
fn map_inbound_err<F, T>(self, f: F) -> MapInboundUpgradeErr<Self, F>
where
Self: Sized,
F: FnOnce(Self::Error) -> T
F: FnOnce(Self::Error) -> T,
{
MapInboundUpgradeErr::new(self, f)
}
@ -207,7 +207,7 @@ pub trait OutboundUpgradeExt<C>: OutboundUpgrade<C> {
fn map_outbound<F, T>(self, f: F) -> MapOutboundUpgrade<Self, F>
where
Self: Sized,
F: FnOnce(Self::Output) -> T
F: FnOnce(Self::Output) -> T,
{
MapOutboundUpgrade::new(self, f)
}
@ -216,11 +216,10 @@ pub trait OutboundUpgradeExt<C>: OutboundUpgrade<C> {
fn map_outbound_err<F, T>(self, f: F) -> MapOutboundUpgradeErr<Self, F>
where
Self: Sized,
F: FnOnce(Self::Error) -> T
F: FnOnce(Self::Error) -> T,
{
MapOutboundUpgradeErr::new(self, f)
}
}
impl<C, U: OutboundUpgrade<C>> OutboundUpgradeExt<C> for U {}

View File

@ -18,8 +18,8 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeError};
use crate::{ConnectedPoint, Negotiated};
use crate::upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeError, ProtocolName};
use futures::{future::Either, prelude::*};
use log::debug;
use multistream_select::{self, DialerSelectFuture, ListenerSelectFuture};
@ -28,8 +28,12 @@ use std::{iter, mem, pin::Pin, task::Context, task::Poll};
pub use multistream_select::Version;
/// Applies an upgrade to the inbound and outbound direction of a connection or substream.
pub fn apply<C, U>(conn: C, up: U, cp: ConnectedPoint, v: Version)
-> Either<InboundUpgradeApply<C, U>, OutboundUpgradeApply<C, U>>
pub fn apply<C, U>(
conn: C,
up: U,
cp: ConnectedPoint,
v: Version,
) -> Either<InboundUpgradeApply<C, U>, OutboundUpgradeApply<C, U>>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>> + OutboundUpgrade<Negotiated<C>>,
@ -47,10 +51,16 @@ where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>>,
{
let iter = up.protocol_info().into_iter().map(NameWrap as fn(_) -> NameWrap<_>);
let iter = up
.protocol_info()
.into_iter()
.map(NameWrap as fn(_) -> NameWrap<_>);
let future = multistream_select::listener_select_proto(conn, iter);
InboundUpgradeApply {
inner: InboundUpgradeApplyState::Init { future, upgrade: up }
inner: InboundUpgradeApplyState::Init {
future,
upgrade: up,
},
}
}
@ -58,12 +68,18 @@ where
pub fn apply_outbound<C, U>(conn: C, up: U, v: Version) -> OutboundUpgradeApply<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: OutboundUpgrade<Negotiated<C>>
U: OutboundUpgrade<Negotiated<C>>,
{
let iter = up.protocol_info().into_iter().map(NameWrap as fn(_) -> NameWrap<_>);
let iter = up
.protocol_info()
.into_iter()
.map(NameWrap as fn(_) -> NameWrap<_>);
let future = multistream_select::dialer_select_proto(conn, iter, v);
OutboundUpgradeApply {
inner: OutboundUpgradeApplyState::Init { future, upgrade: up }
inner: OutboundUpgradeApplyState::Init {
future,
upgrade: up,
},
}
}
@ -71,9 +87,9 @@ where
pub struct InboundUpgradeApply<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: InboundUpgrade<Negotiated<C>>
U: InboundUpgrade<Negotiated<C>>,
{
inner: InboundUpgradeApplyState<C, U>
inner: InboundUpgradeApplyState<C, U>,
}
enum InboundUpgradeApplyState<C, U>
@ -86,9 +102,9 @@ where
upgrade: U,
},
Upgrade {
future: Pin<Box<U::Future>>
future: Pin<Box<U::Future>>,
},
Undefined
Undefined,
}
impl<C, U> Unpin for InboundUpgradeApply<C, U>
@ -108,36 +124,40 @@ where
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop {
match mem::replace(&mut self.inner, InboundUpgradeApplyState::Undefined) {
InboundUpgradeApplyState::Init { mut future, upgrade } => {
InboundUpgradeApplyState::Init {
mut future,
upgrade,
} => {
let (info, io) = match Future::poll(Pin::new(&mut future), cx)? {
Poll::Ready(x) => x,
Poll::Pending => {
self.inner = InboundUpgradeApplyState::Init { future, upgrade };
return Poll::Pending
return Poll::Pending;
}
};
self.inner = InboundUpgradeApplyState::Upgrade {
future: Box::pin(upgrade.upgrade_inbound(io, info.0))
future: Box::pin(upgrade.upgrade_inbound(io, info.0)),
};
}
InboundUpgradeApplyState::Upgrade { mut future } => {
match Future::poll(Pin::new(&mut future), cx) {
Poll::Pending => {
self.inner = InboundUpgradeApplyState::Upgrade { future };
return Poll::Pending
return Poll::Pending;
}
Poll::Ready(Ok(x)) => {
debug!("Successfully applied negotiated protocol");
return Poll::Ready(Ok(x))
return Poll::Ready(Ok(x));
}
Poll::Ready(Err(e)) => {
debug!("Failed to apply negotiated protocol");
return Poll::Ready(Err(UpgradeError::Apply(e)))
return Poll::Ready(Err(UpgradeError::Apply(e)));
}
}
}
InboundUpgradeApplyState::Undefined =>
InboundUpgradeApplyState::Undefined => {
panic!("InboundUpgradeApplyState::poll called after completion")
}
}
}
}
@ -147,24 +167,24 @@ where
pub struct OutboundUpgradeApply<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: OutboundUpgrade<Negotiated<C>>
U: OutboundUpgrade<Negotiated<C>>,
{
inner: OutboundUpgradeApplyState<C, U>
inner: OutboundUpgradeApplyState<C, U>,
}
enum OutboundUpgradeApplyState<C, U>
where
C: AsyncRead + AsyncWrite + Unpin,
U: OutboundUpgrade<Negotiated<C>>
U: OutboundUpgrade<Negotiated<C>>,
{
Init {
future: DialerSelectFuture<C, NameWrapIter<<U::InfoIter as IntoIterator>::IntoIter>>,
upgrade: U
upgrade: U,
},
Upgrade {
future: Pin<Box<U::Future>>
future: Pin<Box<U::Future>>,
},
Undefined
Undefined,
}
impl<C, U> Unpin for OutboundUpgradeApply<C, U>
@ -184,27 +204,30 @@ where
fn poll(mut self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
loop {
match mem::replace(&mut self.inner, OutboundUpgradeApplyState::Undefined) {
OutboundUpgradeApplyState::Init { mut future, upgrade } => {
OutboundUpgradeApplyState::Init {
mut future,
upgrade,
} => {
let (info, connection) = match Future::poll(Pin::new(&mut future), cx)? {
Poll::Ready(x) => x,
Poll::Pending => {
self.inner = OutboundUpgradeApplyState::Init { future, upgrade };
return Poll::Pending
return Poll::Pending;
}
};
self.inner = OutboundUpgradeApplyState::Upgrade {
future: Box::pin(upgrade.upgrade_outbound(connection, info.0))
future: Box::pin(upgrade.upgrade_outbound(connection, info.0)),
};
}
OutboundUpgradeApplyState::Upgrade { mut future } => {
match Future::poll(Pin::new(&mut future), cx) {
Poll::Pending => {
self.inner = OutboundUpgradeApplyState::Upgrade { future };
return Poll::Pending
return Poll::Pending;
}
Poll::Ready(Ok(x)) => {
debug!("Successfully applied negotiated protocol");
return Poll::Ready(Ok(x))
return Poll::Ready(Ok(x));
}
Poll::Ready(Err(e)) => {
debug!("Failed to apply negotiated protocol");
@ -212,8 +235,9 @@ where
}
}
}
OutboundUpgradeApplyState::Undefined =>
OutboundUpgradeApplyState::Undefined => {
panic!("OutboundUpgradeApplyState::poll called after completion")
}
}
}
}
@ -230,4 +254,3 @@ impl<N: ProtocolName> AsRef<[u8]> for NameWrap<N> {
self.0.protocol_name()
}
}

View File

@ -19,29 +19,32 @@
// DEALINGS IN THE SOFTWARE.
use crate::{
either::{EitherOutput, EitherError, EitherFuture2, EitherName},
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}
either::{EitherError, EitherFuture2, EitherName, EitherOutput},
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo},
};
/// A type to represent two possible upgrade types (inbound or outbound).
#[derive(Debug, Clone)]
pub enum EitherUpgrade<A, B> { A(A), B(B) }
pub enum EitherUpgrade<A, B> {
A(A),
B(B),
}
impl<A, B> UpgradeInfo for EitherUpgrade<A, B>
where
A: UpgradeInfo,
B: UpgradeInfo
B: UpgradeInfo,
{
type Info = EitherName<A::Info, B::Info>;
type InfoIter = EitherIter<
<A::InfoIter as IntoIterator>::IntoIter,
<B::InfoIter as IntoIterator>::IntoIter
<B::InfoIter as IntoIterator>::IntoIter,
>;
fn protocol_info(&self) -> Self::InfoIter {
match self {
EitherUpgrade::A(a) => EitherIter::A(a.protocol_info().into_iter()),
EitherUpgrade::B(b) => EitherIter::B(b.protocol_info().into_iter())
EitherUpgrade::B(b) => EitherIter::B(b.protocol_info().into_iter()),
}
}
}
@ -57,9 +60,13 @@ where
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
match (self, info) {
(EitherUpgrade::A(a), EitherName::A(info)) => EitherFuture2::A(a.upgrade_inbound(sock, info)),
(EitherUpgrade::B(b), EitherName::B(info)) => EitherFuture2::B(b.upgrade_inbound(sock, info)),
_ => panic!("Invalid invocation of EitherUpgrade::upgrade_inbound")
(EitherUpgrade::A(a), EitherName::A(info)) => {
EitherFuture2::A(a.upgrade_inbound(sock, info))
}
(EitherUpgrade::B(b), EitherName::B(info)) => {
EitherFuture2::B(b.upgrade_inbound(sock, info))
}
_ => panic!("Invalid invocation of EitherUpgrade::upgrade_inbound"),
}
}
}
@ -75,36 +82,42 @@ where
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
match (self, info) {
(EitherUpgrade::A(a), EitherName::A(info)) => EitherFuture2::A(a.upgrade_outbound(sock, info)),
(EitherUpgrade::B(b), EitherName::B(info)) => EitherFuture2::B(b.upgrade_outbound(sock, info)),
_ => panic!("Invalid invocation of EitherUpgrade::upgrade_outbound")
(EitherUpgrade::A(a), EitherName::A(info)) => {
EitherFuture2::A(a.upgrade_outbound(sock, info))
}
(EitherUpgrade::B(b), EitherName::B(info)) => {
EitherFuture2::B(b.upgrade_outbound(sock, info))
}
_ => panic!("Invalid invocation of EitherUpgrade::upgrade_outbound"),
}
}
}
/// A type to represent two possible `Iterator` types.
#[derive(Debug, Clone)]
pub enum EitherIter<A, B> { A(A), B(B) }
pub enum EitherIter<A, B> {
A(A),
B(B),
}
impl<A, B> Iterator for EitherIter<A, B>
where
A: Iterator,
B: Iterator
B: Iterator,
{
type Item = EitherName<A::Item, B::Item>;
fn next(&mut self) -> Option<Self::Item> {
match self {
EitherIter::A(a) => a.next().map(EitherName::A),
EitherIter::B(b) => b.next().map(EitherName::B)
EitherIter::B(b) => b.next().map(EitherName::B),
}
}
fn size_hint(&self) -> (usize, Option<usize>) {
match self {
EitherIter::A(a) => a.size_hint(),
EitherIter::B(b) => b.size_hint()
EitherIter::B(b) => b.size_hint(),
}
}
}

View File

@ -33,7 +33,7 @@ pub enum UpgradeError<E> {
impl<E> UpgradeError<E> {
pub fn map_err<F, T>(self, f: F) -> UpgradeError<T>
where
F: FnOnce(E) -> T
F: FnOnce(E) -> T,
{
match self {
UpgradeError::Select(e) => UpgradeError::Select(e),
@ -43,7 +43,7 @@ impl<E> UpgradeError<E> {
pub fn into_err<T>(self) -> UpgradeError<T>
where
T: From<E>
T: From<E>,
{
self.map_err(Into::into)
}
@ -51,7 +51,7 @@ impl<E> UpgradeError<E> {
impl<E> fmt::Display for UpgradeError<E>
where
E: fmt::Display
E: fmt::Display,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self {
@ -63,7 +63,7 @@ where
impl<E> std::error::Error for UpgradeError<E>
where
E: std::error::Error + 'static
E: std::error::Error + 'static,
{
fn source(&self) -> Option<&(dyn std::error::Error + 'static)> {
match self {
@ -78,4 +78,3 @@ impl<E> From<NegotiationError> for UpgradeError<E> {
UpgradeError::Select(e)
}
}

View File

@ -18,7 +18,10 @@
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
// DEALINGS IN THE SOFTWARE.
use crate::{Endpoint, upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeInfo}};
use crate::{
upgrade::{InboundUpgrade, OutboundUpgrade, ProtocolName, UpgradeInfo},
Endpoint,
};
use futures::prelude::*;
use std::iter;

View File

@ -24,7 +24,10 @@ use std::{pin::Pin, task::Context, task::Poll};
/// Wraps around an upgrade and applies a closure to the output.
#[derive(Debug, Clone)]
pub struct MapInboundUpgrade<U, F> { upgrade: U, fun: F }
pub struct MapInboundUpgrade<U, F> {
upgrade: U,
fun: F,
}
impl<U, F> MapInboundUpgrade<U, F> {
pub fn new(upgrade: U, fun: F) -> Self {
@ -34,7 +37,7 @@ impl<U, F> MapInboundUpgrade<U, F> {
impl<U, F> UpgradeInfo for MapInboundUpgrade<U, F>
where
U: UpgradeInfo
U: UpgradeInfo,
{
type Info = U::Info;
type InfoIter = U::InfoIter;
@ -47,7 +50,7 @@ where
impl<C, U, F, T> InboundUpgrade<C> for MapInboundUpgrade<U, F>
where
U: InboundUpgrade<C>,
F: FnOnce(U::Output) -> T
F: FnOnce(U::Output) -> T,
{
type Output = T;
type Error = U::Error;
@ -56,7 +59,7 @@ where
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
MapFuture {
inner: self.upgrade.upgrade_inbound(sock, info),
map: Some(self.fun)
map: Some(self.fun),
}
}
}
@ -76,7 +79,10 @@ where
/// Wraps around an upgrade and applies a closure to the output.
#[derive(Debug, Clone)]
pub struct MapOutboundUpgrade<U, F> { upgrade: U, fun: F }
pub struct MapOutboundUpgrade<U, F> {
upgrade: U,
fun: F,
}
impl<U, F> MapOutboundUpgrade<U, F> {
pub fn new(upgrade: U, fun: F) -> Self {
@ -86,7 +92,7 @@ impl<U, F> MapOutboundUpgrade<U, F> {
impl<U, F> UpgradeInfo for MapOutboundUpgrade<U, F>
where
U: UpgradeInfo
U: UpgradeInfo,
{
type Info = U::Info;
type InfoIter = U::InfoIter;
@ -112,7 +118,7 @@ where
impl<C, U, F, T> OutboundUpgrade<C> for MapOutboundUpgrade<U, F>
where
U: OutboundUpgrade<C>,
F: FnOnce(U::Output) -> T
F: FnOnce(U::Output) -> T,
{
type Output = T;
type Error = U::Error;
@ -121,14 +127,17 @@ where
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
MapFuture {
inner: self.upgrade.upgrade_outbound(sock, info),
map: Some(self.fun)
map: Some(self.fun),
}
}
}
/// Wraps around an upgrade and applies a closure to the error.
#[derive(Debug, Clone)]
pub struct MapInboundUpgradeErr<U, F> { upgrade: U, fun: F }
pub struct MapInboundUpgradeErr<U, F> {
upgrade: U,
fun: F,
}
impl<U, F> MapInboundUpgradeErr<U, F> {
pub fn new(upgrade: U, fun: F) -> Self {
@ -138,7 +147,7 @@ impl<U, F> MapInboundUpgradeErr<U, F> {
impl<U, F> UpgradeInfo for MapInboundUpgradeErr<U, F>
where
U: UpgradeInfo
U: UpgradeInfo,
{
type Info = U::Info;
type InfoIter = U::InfoIter;
@ -151,7 +160,7 @@ where
impl<C, U, F, T> InboundUpgrade<C> for MapInboundUpgradeErr<U, F>
where
U: InboundUpgrade<C>,
F: FnOnce(U::Error) -> T
F: FnOnce(U::Error) -> T,
{
type Output = U::Output;
type Error = T;
@ -160,7 +169,7 @@ where
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
MapErrFuture {
fut: self.upgrade.upgrade_inbound(sock, info),
fun: Some(self.fun)
fun: Some(self.fun),
}
}
}
@ -180,7 +189,10 @@ where
/// Wraps around an upgrade and applies a closure to the error.
#[derive(Debug, Clone)]
pub struct MapOutboundUpgradeErr<U, F> { upgrade: U, fun: F }
pub struct MapOutboundUpgradeErr<U, F> {
upgrade: U,
fun: F,
}
impl<U, F> MapOutboundUpgradeErr<U, F> {
pub fn new(upgrade: U, fun: F) -> Self {
@ -190,7 +202,7 @@ impl<U, F> MapOutboundUpgradeErr<U, F> {
impl<U, F> UpgradeInfo for MapOutboundUpgradeErr<U, F>
where
U: UpgradeInfo
U: UpgradeInfo,
{
type Info = U::Info;
type InfoIter = U::InfoIter;
@ -203,7 +215,7 @@ where
impl<C, U, F, T> OutboundUpgrade<C> for MapOutboundUpgradeErr<U, F>
where
U: OutboundUpgrade<C>,
F: FnOnce(U::Error) -> T
F: FnOnce(U::Error) -> T,
{
type Output = U::Output;
type Error = T;
@ -212,14 +224,14 @@ where
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
MapErrFuture {
fut: self.upgrade.upgrade_outbound(sock, info),
fun: Some(self.fun)
fun: Some(self.fun),
}
}
}
impl<C, U, F> InboundUpgrade<C> for MapOutboundUpgradeErr<U, F>
where
U: InboundUpgrade<C>
U: InboundUpgrade<C>,
{
type Output = U::Output;
type Error = U::Error;
@ -283,4 +295,3 @@ where
}
}
}

View File

@ -112,8 +112,4 @@ where
}
}
impl<T> ExactSizeIterator for Iter<T>
where
T: ExactSizeIterator
{
}
impl<T> ExactSizeIterator for Iter<T> where T: ExactSizeIterator {}

View File

@ -19,8 +19,8 @@
// DEALINGS IN THE SOFTWARE.
use crate::{
either::{EitherOutput, EitherError, EitherFuture2, EitherName},
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo}
either::{EitherError, EitherFuture2, EitherName, EitherOutput},
upgrade::{InboundUpgrade, OutboundUpgrade, UpgradeInfo},
};
/// Upgrade that combines two upgrades into one. Supports all the protocols supported by either
@ -42,16 +42,19 @@ impl<A, B> SelectUpgrade<A, B> {
impl<A, B> UpgradeInfo for SelectUpgrade<A, B>
where
A: UpgradeInfo,
B: UpgradeInfo
B: UpgradeInfo,
{
type Info = EitherName<A::Info, B::Info>;
type InfoIter = InfoIterChain<
<A::InfoIter as IntoIterator>::IntoIter,
<B::InfoIter as IntoIterator>::IntoIter
<B::InfoIter as IntoIterator>::IntoIter,
>;
fn protocol_info(&self) -> Self::InfoIter {
InfoIterChain(self.0.protocol_info().into_iter(), self.1.protocol_info().into_iter())
InfoIterChain(
self.0.protocol_info().into_iter(),
self.1.protocol_info().into_iter(),
)
}
}
@ -67,7 +70,7 @@ where
fn upgrade_inbound(self, sock: C, info: Self::Info) -> Self::Future {
match info {
EitherName::A(info) => EitherFuture2::A(self.0.upgrade_inbound(sock, info)),
EitherName::B(info) => EitherFuture2::B(self.1.upgrade_inbound(sock, info))
EitherName::B(info) => EitherFuture2::B(self.1.upgrade_inbound(sock, info)),
}
}
}
@ -84,7 +87,7 @@ where
fn upgrade_outbound(self, sock: C, info: Self::Info) -> Self::Future {
match info {
EitherName::A(info) => EitherFuture2::A(self.0.upgrade_outbound(sock, info)),
EitherName::B(info) => EitherFuture2::B(self.1.upgrade_outbound(sock, info))
EitherName::B(info) => EitherFuture2::B(self.1.upgrade_outbound(sock, info)),
}
}
}
@ -96,16 +99,16 @@ pub struct InfoIterChain<A, B>(A, B);
impl<A, B> Iterator for InfoIterChain<A, B>
where
A: Iterator,
B: Iterator
B: Iterator,
{
type Item = EitherName<A::Item, B::Item>;
fn next(&mut self) -> Option<Self::Item> {
if let Some(info) = self.0.next() {
return Some(EitherName::A(info))
return Some(EitherName::A(info));
}
if let Some(info) = self.1.next() {
return Some(EitherName::B(info))
return Some(EitherName::B(info));
}
None
}
@ -117,4 +120,3 @@ where
(min1.saturating_add(min2), max)
}
}

View File

@ -29,9 +29,10 @@ use std::{error, fmt, io};
///
/// > **Note**: Prepends a variable-length prefix indicate the length of the message. This is
/// > compatible with what [`read_length_prefixed`] expects.
pub async fn write_length_prefixed(socket: &mut (impl AsyncWrite + Unpin), data: impl AsRef<[u8]>)
-> Result<(), io::Error>
{
pub async fn write_length_prefixed(
socket: &mut (impl AsyncWrite + Unpin),
data: impl AsRef<[u8]>,
) -> Result<(), io::Error> {
write_varint(socket, data.as_ref().len()).await?;
socket.write_all(data.as_ref()).await?;
socket.flush().await?;
@ -44,11 +45,15 @@ pub async fn write_length_prefixed(socket: &mut (impl AsyncWrite + Unpin), data:
/// > **Note**: Prepends a variable-length prefix indicate the length of the message. This is
/// > compatible with what `read_one` expects.
///
#[deprecated(since = "0.29.0", note = "Use `write_length_prefixed` instead. You will need to manually close the stream using `socket.close().await`.")]
#[deprecated(
since = "0.29.0",
note = "Use `write_length_prefixed` instead. You will need to manually close the stream using `socket.close().await`."
)]
#[allow(dead_code)]
pub async fn write_one(socket: &mut (impl AsyncWrite + Unpin), data: impl AsRef<[u8]>)
-> Result<(), io::Error>
{
pub async fn write_one(
socket: &mut (impl AsyncWrite + Unpin),
data: impl AsRef<[u8]>,
) -> Result<(), io::Error> {
write_varint(socket, data.as_ref().len()).await?;
socket.write_all(data.as_ref()).await?;
socket.close().await?;
@ -61,9 +66,10 @@ pub async fn write_one(socket: &mut (impl AsyncWrite + Unpin), data: impl AsRef<
/// > compatible with what `read_one` expects.
#[deprecated(since = "0.29.0", note = "Use `write_length_prefixed` instead.")]
#[allow(dead_code)]
pub async fn write_with_len_prefix(socket: &mut (impl AsyncWrite + Unpin), data: impl AsRef<[u8]>)
-> Result<(), io::Error>
{
pub async fn write_with_len_prefix(
socket: &mut (impl AsyncWrite + Unpin),
data: impl AsRef<[u8]>,
) -> Result<(), io::Error> {
write_varint(socket, data.as_ref().len()).await?;
socket.write_all(data.as_ref()).await?;
socket.flush().await?;
@ -73,9 +79,10 @@ pub async fn write_with_len_prefix(socket: &mut (impl AsyncWrite + Unpin), data:
/// Writes a variable-length integer to the `socket`.
///
/// > **Note**: Does **NOT** flush the socket.
pub async fn write_varint(socket: &mut (impl AsyncWrite + Unpin), len: usize)
-> Result<(), io::Error>
{
pub async fn write_varint(
socket: &mut (impl AsyncWrite + Unpin),
len: usize,
) -> Result<(), io::Error> {
let mut len_data = unsigned_varint::encode::usize_buffer();
let encoded_len = unsigned_varint::encode::usize(len, &mut len_data).len();
socket.write_all(&len_data[..encoded_len]).await?;
@ -95,7 +102,7 @@ pub async fn read_varint(socket: &mut (impl AsyncRead + Unpin)) -> Result<usize,
let mut buffer_len = 0;
loop {
match socket.read(&mut buffer[buffer_len..buffer_len+1]).await? {
match socket.read(&mut buffer[buffer_len..buffer_len + 1]).await? {
0 => {
// Reaching EOF before finishing to read the length is an error, unless the EOF is
// at the very beginning of the substream, in which case we assume that the data is
@ -116,7 +123,7 @@ pub async fn read_varint(socket: &mut (impl AsyncRead + Unpin)) -> Result<usize,
Err(unsigned_varint::decode::Error::Overflow) => {
return Err(io::Error::new(
io::ErrorKind::InvalidData,
"overflow in variable-length integer"
"overflow in variable-length integer",
));
}
// TODO: why do we have a `__Nonexhaustive` variant in the error? I don't know how to process it
@ -134,11 +141,19 @@ pub async fn read_varint(socket: &mut (impl AsyncRead + Unpin)) -> Result<usize,
///
/// > **Note**: Assumes that a variable-length prefix indicates the length of the message. This is
/// > compatible with what [`write_length_prefixed`] does.
pub async fn read_length_prefixed(socket: &mut (impl AsyncRead + Unpin), max_size: usize) -> io::Result<Vec<u8>>
{
pub async fn read_length_prefixed(
socket: &mut (impl AsyncRead + Unpin),
max_size: usize,
) -> io::Result<Vec<u8>> {
let len = read_varint(socket).await?;
if len > max_size {
return Err(io::Error::new(io::ErrorKind::InvalidData, format!("Received data size ({} bytes) exceeds maximum ({} bytes)", len, max_size)))
return Err(io::Error::new(
io::ErrorKind::InvalidData,
format!(
"Received data size ({} bytes) exceeds maximum ({} bytes)",
len, max_size
),
));
}
let mut buf = vec![0; len];
@ -157,9 +172,10 @@ pub async fn read_length_prefixed(socket: &mut (impl AsyncRead + Unpin), max_siz
/// > compatible with what `write_one` does.
#[deprecated(since = "0.29.0", note = "Use `read_length_prefixed` instead.")]
#[allow(dead_code, deprecated)]
pub async fn read_one(socket: &mut (impl AsyncRead + Unpin), max_size: usize)
-> Result<Vec<u8>, ReadOneError>
{
pub async fn read_one(
socket: &mut (impl AsyncRead + Unpin),
max_size: usize,
) -> Result<Vec<u8>, ReadOneError> {
let len = read_varint(socket).await?;
if len > max_size {
return Err(ReadOneError::TooLarge {
@ -175,7 +191,10 @@ pub async fn read_one(socket: &mut (impl AsyncRead + Unpin), max_size: usize)
/// Error while reading one message.
#[derive(Debug)]
#[deprecated(since = "0.29.0", note = "Use `read_length_prefixed` instead of `read_one` to avoid depending on this type.")]
#[deprecated(
since = "0.29.0",
note = "Use `read_length_prefixed` instead of `read_one` to avoid depending on this type."
)]
pub enum ReadOneError {
/// Error on the socket.
Io(std::io::Error),
@ -239,7 +258,7 @@ mod tests {
}
// TODO: rewrite these tests
/*
/*
#[test]
fn read_one_works() {
let original_data = (0..rand::random::<usize>() % 10_000)