use crate::{
Multiaddr,
connection::{
ConnectionId,
ConnectedPoint,
ConnectionError,
ConnectionHandler,
ConnectionInfo,
ConnectionLimit,
Connected,
EstablishedConnection,
IncomingInfo,
IntoConnectionHandler,
ListenerId,
PendingConnectionError,
Substream,
pool::Pool,
},
muxing::StreamMuxer,
transport::{Transport, TransportError},
};
use futures::prelude::*;
use std::{error, fmt, hash::Hash, num::NonZeroU32};
pub enum NetworkEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
where
TTrans: Transport,
THandler: IntoConnectionHandler<TConnInfo>,
{
ListenerClosed {
listener_id: ListenerId,
addresses: Vec<Multiaddr>,
reason: Result<(), TTrans::Error>,
},
ListenerError {
listener_id: ListenerId,
error: TTrans::Error
},
NewListenerAddress {
listener_id: ListenerId,
listen_addr: Multiaddr
},
ExpiredListenerAddress {
listener_id: ListenerId,
listen_addr: Multiaddr
},
IncomingConnection(IncomingConnectionEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>),
IncomingConnectionError {
local_addr: Multiaddr,
send_back_addr: Multiaddr,
error: PendingConnectionError<TTrans::Error>,
},
ConnectionEstablished {
connection: EstablishedConnection<'a, TInEvent, TConnInfo, TPeerId>,
num_established: NonZeroU32,
},
ConnectionError {
id: ConnectionId,
connected: Connected<TConnInfo>,
error: ConnectionError<<THandler::Handler as ConnectionHandler>::Error>,
num_established: u32,
},
DialError {
attempts_remaining: u32,
peer_id: TPeerId,
multiaddr: Multiaddr,
error: PendingConnectionError<TTrans::Error>,
},
UnknownPeerDialError {
multiaddr: Multiaddr,
error: PendingConnectionError<TTrans::Error>,
},
ConnectionEvent {
connection: EstablishedConnection<'a, TInEvent, TConnInfo, TPeerId>,
event: TOutEvent,
},
}
impl<TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId> fmt::Debug for
NetworkEvent<'_, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
where
TInEvent: fmt::Debug,
TOutEvent: fmt::Debug,
TTrans: Transport,
TTrans::Error: fmt::Debug,
THandler: IntoConnectionHandler<TConnInfo>,
<THandler::Handler as ConnectionHandler>::Error: fmt::Debug,
TConnInfo: fmt::Debug,
TPeerId: fmt::Debug,
{
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(event) => {
f.debug_struct("IncomingConnection")
.field("local_addr", &event.local_addr)
.field("send_back_addr", &event.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::ConnectionError { connected, error, .. } => {
f.debug_struct("ConnectionError")
.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()
}
}
}
}
pub struct IncomingConnectionEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
where
TTrans: Transport,
THandler: IntoConnectionHandler<TConnInfo>,
{
pub(super) listener_id: ListenerId,
pub(super) upgrade: TTrans::ListenerUpgrade,
pub(super) local_addr: Multiaddr,
pub(super) send_back_addr: Multiaddr,
pub(super) pool: &'a mut Pool<
TInEvent,
TOutEvent,
THandler,
TTrans::Error,
<THandler::Handler as ConnectionHandler>::Error,
TConnInfo,
TPeerId
>,
}
impl<'a, TTrans, TInEvent, TOutEvent, TMuxer, THandler, TConnInfo, TPeerId>
IncomingConnectionEvent<'a, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
where
TTrans: Transport<Output = (TConnInfo, TMuxer)>,
TTrans::Error: Send + 'static,
TTrans::ListenerUpgrade: Send + 'static,
THandler: IntoConnectionHandler<TConnInfo> + Send + 'static,
THandler::Handler: ConnectionHandler<Substream = Substream<TMuxer>, InEvent = TInEvent, OutEvent = TOutEvent> + Send + 'static,
<THandler::Handler as ConnectionHandler>::OutboundOpenInfo: Send + 'static,
<THandler::Handler as ConnectionHandler>::Error: error::Error + Send + 'static,
TMuxer: StreamMuxer + Send + Sync + 'static,
TMuxer::OutboundSubstream: Send,
TMuxer::Substream: Send,
TInEvent: Send + 'static,
TOutEvent: Send + 'static,
TConnInfo: fmt::Debug + ConnectionInfo<PeerId = TPeerId> + Send + 'static,
TPeerId: Eq + Hash + Clone + Send + 'static,
{
pub fn listener_id(&self) -> ListenerId {
self.listener_id
}
pub fn accept(self, handler: THandler) -> Result<ConnectionId, ConnectionLimit> {
self.accept_with_builder(|_| handler)
}
pub fn accept_with_builder<TBuilder>(self, builder: TBuilder)
-> Result<ConnectionId, ConnectionLimit>
where
TBuilder: FnOnce(IncomingInfo<'_>) -> THandler
{
let handler = builder(self.info());
let upgrade = self.upgrade
.map_err(|err| PendingConnectionError::Transport(TransportError::Other(err)));
let info = IncomingInfo {
local_addr: &self.local_addr,
send_back_addr: &self.send_back_addr,
};
self.pool.add_incoming(upgrade, handler, info)
}
}
impl<TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
IncomingConnectionEvent<'_, TTrans, TInEvent, TOutEvent, THandler, TConnInfo, TPeerId>
where
TTrans: Transport,
THandler: IntoConnectionHandler<TConnInfo>,
{
pub fn info(&self) -> IncomingInfo<'_> {
IncomingInfo {
local_addr: &self.local_addr,
send_back_addr: &self.send_back_addr,
}
}
pub fn local_addr(&self) -> &Multiaddr {
&self.local_addr
}
pub fn send_back_addr(&self) -> &Multiaddr {
&self.send_back_addr
}
pub fn to_connected_point(&self) -> ConnectedPoint {
self.info().to_connected_point()
}
}