mirror of
https://github.com/fluencelabs/rust-libp2p
synced 2025-06-26 16:21:39 +00:00
*: Format with rustfmt (#2188)
Co-authored-by: Thomas Eizinger <thomas@eizinger.io>
This commit is contained in:
@ -18,9 +18,12 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{AddressScore, AddressRecord};
|
||||
use crate::protocols_handler::{IntoProtocolsHandler, ProtocolsHandler};
|
||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId, connection::{ConnectionId, ListenerId}};
|
||||
use crate::{AddressRecord, AddressScore};
|
||||
use libp2p_core::{
|
||||
connection::{ConnectionId, ListenerId},
|
||||
ConnectedPoint, Multiaddr, PeerId,
|
||||
};
|
||||
use std::{error, task::Context, task::Poll};
|
||||
|
||||
/// A behaviour for the network. Allows customizing the swarm.
|
||||
@ -90,7 +93,7 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
///
|
||||
/// This method is only called when the first connection to the peer is established, preceded by
|
||||
/// [`inject_connection_established`](NetworkBehaviour::inject_connection_established).
|
||||
fn inject_connected(&mut self, _: &PeerId) { }
|
||||
fn inject_connected(&mut self, _: &PeerId) {}
|
||||
|
||||
/// Indicates to the behaviour that we disconnected from the node with the given peer id.
|
||||
///
|
||||
@ -99,19 +102,17 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
///
|
||||
/// This method is only called when the last established connection to the peer is closed,
|
||||
/// preceded by [`inject_connection_closed`](NetworkBehaviour::inject_connection_closed).
|
||||
fn inject_disconnected(&mut self, _: &PeerId) { }
|
||||
fn inject_disconnected(&mut self, _: &PeerId) {}
|
||||
|
||||
/// Informs the behaviour about a newly established connection to a peer.
|
||||
fn inject_connection_established(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint)
|
||||
{}
|
||||
fn inject_connection_established(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint) {}
|
||||
|
||||
/// Informs the behaviour about a closed connection to a peer.
|
||||
///
|
||||
/// A call to this method is always paired with an earlier call to
|
||||
/// `inject_connection_established` with the same peer ID, connection ID and
|
||||
/// endpoint.
|
||||
fn inject_connection_closed(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint)
|
||||
{}
|
||||
fn inject_connection_closed(&mut self, _: &PeerId, _: &ConnectionId, _: &ConnectedPoint) {}
|
||||
|
||||
/// Informs the behaviour that the [`ConnectedPoint`] of an existing connection has changed.
|
||||
fn inject_address_change(
|
||||
@ -119,8 +120,9 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
_: &PeerId,
|
||||
_: &ConnectionId,
|
||||
_old: &ConnectedPoint,
|
||||
_new: &ConnectedPoint
|
||||
) {}
|
||||
_new: &ConnectedPoint,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Informs the behaviour about an event generated by the handler dedicated to the peer identified by `peer_id`.
|
||||
/// for the behaviour.
|
||||
@ -131,14 +133,19 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
&mut self,
|
||||
peer_id: PeerId,
|
||||
connection: ConnectionId,
|
||||
event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent
|
||||
event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent,
|
||||
);
|
||||
|
||||
/// Indicates to the behaviour that we tried to reach an address, but failed.
|
||||
///
|
||||
/// If we were trying to reach a specific node, its ID is passed as parameter. If this is the
|
||||
/// last address to attempt for the given node, then `inject_dial_failure` is called afterwards.
|
||||
fn inject_addr_reach_failure(&mut self, _peer_id: Option<&PeerId>, _addr: &Multiaddr, _error: &dyn error::Error) {
|
||||
fn inject_addr_reach_failure(
|
||||
&mut self,
|
||||
_peer_id: Option<&PeerId>,
|
||||
_addr: &Multiaddr,
|
||||
_error: &dyn error::Error,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Indicates to the behaviour that we tried to dial all the addresses known for a node, but
|
||||
@ -146,37 +153,30 @@ pub trait NetworkBehaviour: Send + 'static {
|
||||
///
|
||||
/// The `peer_id` is guaranteed to be in a disconnected state. In other words,
|
||||
/// `inject_connected` has not been called, or `inject_disconnected` has been called since then.
|
||||
fn inject_dial_failure(&mut self, _peer_id: &PeerId) {
|
||||
}
|
||||
fn inject_dial_failure(&mut self, _peer_id: &PeerId) {}
|
||||
|
||||
/// Indicates to the behaviour that a new listener was created.
|
||||
fn inject_new_listener(&mut self, _id: ListenerId) {
|
||||
}
|
||||
fn inject_new_listener(&mut self, _id: ListenerId) {}
|
||||
|
||||
/// Indicates to the behaviour that we have started listening on a new multiaddr.
|
||||
fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {
|
||||
}
|
||||
fn inject_new_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {}
|
||||
|
||||
/// Indicates to the behaviour that a multiaddr we were listening on has expired,
|
||||
/// which means that we are no longer listening in it.
|
||||
fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {
|
||||
}
|
||||
fn inject_expired_listen_addr(&mut self, _id: ListenerId, _addr: &Multiaddr) {}
|
||||
|
||||
/// A listener experienced an error.
|
||||
fn inject_listener_error(&mut self, _id: ListenerId, _err: &(dyn std::error::Error + 'static)) {
|
||||
}
|
||||
|
||||
/// A listener closed.
|
||||
fn inject_listener_closed(&mut self, _id: ListenerId, _reason: Result<(), &std::io::Error>) {
|
||||
}
|
||||
fn inject_listener_closed(&mut self, _id: ListenerId, _reason: Result<(), &std::io::Error>) {}
|
||||
|
||||
/// Indicates to the behaviour that we have discovered a new external address for us.
|
||||
fn inject_new_external_addr(&mut self, _addr: &Multiaddr) {
|
||||
}
|
||||
fn inject_new_external_addr(&mut self, _addr: &Multiaddr) {}
|
||||
|
||||
/// Indicates to the behaviour that an external address was removed.
|
||||
fn inject_expired_external_addr(&mut self, _addr: &Multiaddr) {
|
||||
}
|
||||
fn inject_expired_external_addr(&mut self, _addr: &Multiaddr) {}
|
||||
|
||||
/// Polls for things that swarm should do.
|
||||
///
|
||||
@ -311,47 +311,71 @@ pub enum NetworkBehaviourAction<TInEvent, TOutEvent> {
|
||||
peer_id: PeerId,
|
||||
/// Whether to close a specific or all connections to the given peer.
|
||||
connection: CloseConnection,
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
impl<TInEvent, TOutEvent> NetworkBehaviourAction<TInEvent, TOutEvent> {
|
||||
/// Map the handler event.
|
||||
pub fn map_in<E>(self, f: impl FnOnce(TInEvent) -> E) -> NetworkBehaviourAction<E, TOutEvent> {
|
||||
match self {
|
||||
NetworkBehaviourAction::GenerateEvent(e) =>
|
||||
NetworkBehaviourAction::GenerateEvent(e),
|
||||
NetworkBehaviourAction::DialAddress { address } =>
|
||||
NetworkBehaviourAction::DialAddress { address },
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition } =>
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition },
|
||||
NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } =>
|
||||
NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
event: f(event)
|
||||
},
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score } =>
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score },
|
||||
NetworkBehaviourAction::CloseConnection { peer_id, connection } =>
|
||||
NetworkBehaviourAction::CloseConnection { peer_id, connection }
|
||||
NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(e),
|
||||
NetworkBehaviourAction::DialAddress { address } => {
|
||||
NetworkBehaviourAction::DialAddress { address }
|
||||
}
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition } => {
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition }
|
||||
}
|
||||
NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
event,
|
||||
} => NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
event: f(event),
|
||||
},
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score } => {
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score }
|
||||
}
|
||||
NetworkBehaviourAction::CloseConnection {
|
||||
peer_id,
|
||||
connection,
|
||||
} => NetworkBehaviourAction::CloseConnection {
|
||||
peer_id,
|
||||
connection,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
/// Map the event the swarm will return.
|
||||
pub fn map_out<E>(self, f: impl FnOnce(TOutEvent) -> E) -> NetworkBehaviourAction<TInEvent, E> {
|
||||
match self {
|
||||
NetworkBehaviourAction::GenerateEvent(e) =>
|
||||
NetworkBehaviourAction::GenerateEvent(f(e)),
|
||||
NetworkBehaviourAction::DialAddress { address } =>
|
||||
NetworkBehaviourAction::DialAddress { address },
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition } =>
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition },
|
||||
NetworkBehaviourAction::NotifyHandler { peer_id, handler, event } =>
|
||||
NetworkBehaviourAction::NotifyHandler { peer_id, handler, event },
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score } =>
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score },
|
||||
NetworkBehaviourAction::CloseConnection { peer_id, connection } =>
|
||||
NetworkBehaviourAction::CloseConnection { peer_id, connection }
|
||||
NetworkBehaviourAction::GenerateEvent(e) => NetworkBehaviourAction::GenerateEvent(f(e)),
|
||||
NetworkBehaviourAction::DialAddress { address } => {
|
||||
NetworkBehaviourAction::DialAddress { address }
|
||||
}
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition } => {
|
||||
NetworkBehaviourAction::DialPeer { peer_id, condition }
|
||||
}
|
||||
NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
event,
|
||||
} => NetworkBehaviourAction::NotifyHandler {
|
||||
peer_id,
|
||||
handler,
|
||||
event,
|
||||
},
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score } => {
|
||||
NetworkBehaviourAction::ReportObservedAddr { address, score }
|
||||
}
|
||||
NetworkBehaviourAction::CloseConnection {
|
||||
peer_id,
|
||||
connection,
|
||||
} => NetworkBehaviourAction::CloseConnection {
|
||||
peer_id,
|
||||
connection,
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
705
swarm/src/lib.rs
705
swarm/src/lib.rs
File diff suppressed because it is too large
Load Diff
@ -40,23 +40,14 @@
|
||||
mod dummy;
|
||||
mod map_in;
|
||||
mod map_out;
|
||||
pub mod multi;
|
||||
mod node_handler;
|
||||
mod one_shot;
|
||||
mod select;
|
||||
pub mod multi;
|
||||
|
||||
pub use crate::upgrade::{
|
||||
InboundUpgradeSend,
|
||||
OutboundUpgradeSend,
|
||||
UpgradeInfoSend,
|
||||
};
|
||||
pub use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend};
|
||||
|
||||
use libp2p_core::{
|
||||
ConnectedPoint,
|
||||
Multiaddr,
|
||||
PeerId,
|
||||
upgrade::UpgradeError,
|
||||
};
|
||||
use libp2p_core::{upgrade::UpgradeError, ConnectedPoint, Multiaddr, PeerId};
|
||||
use std::{cmp::Ordering, error, fmt, task::Context, task::Poll, time::Duration};
|
||||
use wasm_timer::Instant;
|
||||
|
||||
@ -128,7 +119,7 @@ pub trait ProtocolsHandler: Send + 'static {
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
info: Self::InboundOpenInfo
|
||||
info: Self::InboundOpenInfo,
|
||||
);
|
||||
|
||||
/// Injects the output of a successful upgrade on a new outbound substream.
|
||||
@ -138,7 +129,7 @@ pub trait ProtocolsHandler: Send + 'static {
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
|
||||
info: Self::OutboundOpenInfo
|
||||
info: Self::OutboundOpenInfo,
|
||||
);
|
||||
|
||||
/// Injects an event coming from the outside in the handler.
|
||||
@ -151,17 +142,16 @@ pub trait ProtocolsHandler: Send + 'static {
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::OutboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<
|
||||
<Self::OutboundProtocol as OutboundUpgradeSend>::Error
|
||||
>
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
);
|
||||
|
||||
/// Indicates to the handler that upgrading an inbound substream to the given protocol has failed.
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
_: Self::InboundOpenInfo,
|
||||
_: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>
|
||||
) {}
|
||||
_: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>,
|
||||
) {
|
||||
}
|
||||
|
||||
/// Returns until when the connection should be kept alive.
|
||||
///
|
||||
@ -186,8 +176,16 @@ pub trait ProtocolsHandler: Send + 'static {
|
||||
fn connection_keep_alive(&self) -> KeepAlive;
|
||||
|
||||
/// Should behave like `Stream::poll()`.
|
||||
fn poll(&mut self, cx: &mut Context<'_>) -> Poll<
|
||||
ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>
|
||||
fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
>;
|
||||
|
||||
/// Adds a closure that turns the input event into something else.
|
||||
@ -315,7 +313,7 @@ pub enum ProtocolsHandlerEvent<TConnectionUpgrade, TOutboundOpenInfo, TCustom, T
|
||||
/// Request a new outbound substream to be opened with the remote.
|
||||
OutboundSubstreamRequest {
|
||||
/// The protocol(s) to apply on the substream.
|
||||
protocol: SubstreamProtocol<TConnectionUpgrade, TOutboundOpenInfo>
|
||||
protocol: SubstreamProtocol<TConnectionUpgrade, TOutboundOpenInfo>,
|
||||
},
|
||||
|
||||
/// Close the connection for the given reason.
|
||||
@ -341,7 +339,7 @@ impl<TConnectionUpgrade, TOutboundOpenInfo, TCustom, TErr>
|
||||
match self {
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol } => {
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol.map_info(map)
|
||||
protocol: protocol.map_info(map),
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerEvent::Custom(val) => ProtocolsHandlerEvent::Custom(val),
|
||||
@ -361,7 +359,7 @@ impl<TConnectionUpgrade, TOutboundOpenInfo, TCustom, TErr>
|
||||
match self {
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol } => {
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol.map_upgrade(map)
|
||||
protocol: protocol.map_upgrade(map),
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerEvent::Custom(val) => ProtocolsHandlerEvent::Custom(val),
|
||||
@ -419,12 +417,12 @@ impl<TUpgrErr> ProtocolsHandlerUpgrErr<TUpgrErr> {
|
||||
/// Map the inner [`UpgradeError`] type.
|
||||
pub fn map_upgrade_err<F, E>(self, f: F) -> ProtocolsHandlerUpgrErr<E>
|
||||
where
|
||||
F: FnOnce(UpgradeError<TUpgrErr>) -> UpgradeError<E>
|
||||
F: FnOnce(UpgradeError<TUpgrErr>) -> UpgradeError<E>,
|
||||
{
|
||||
match self {
|
||||
ProtocolsHandlerUpgrErr::Timeout => ProtocolsHandlerUpgrErr::Timeout,
|
||||
ProtocolsHandlerUpgrErr::Timer => ProtocolsHandlerUpgrErr::Timer,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(e) => ProtocolsHandlerUpgrErr::Upgrade(f(e))
|
||||
ProtocolsHandlerUpgrErr::Upgrade(e) => ProtocolsHandlerUpgrErr::Upgrade(f(e)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -437,10 +435,10 @@ where
|
||||
match self {
|
||||
ProtocolsHandlerUpgrErr::Timeout => {
|
||||
write!(f, "Timeout error while opening a substream")
|
||||
},
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Timer => {
|
||||
write!(f, "Timer error while opening a substream")
|
||||
},
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(err) => write!(f, "{}", err),
|
||||
}
|
||||
}
|
||||
@ -448,7 +446,7 @@ where
|
||||
|
||||
impl<TUpgrErr> error::Error for ProtocolsHandlerUpgrErr<TUpgrErr>
|
||||
where
|
||||
TUpgrErr: error::Error + 'static
|
||||
TUpgrErr: error::Error + 'static,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
match self {
|
||||
@ -467,7 +465,11 @@ pub trait IntoProtocolsHandler: Send + 'static {
|
||||
/// Builds the protocols handler.
|
||||
///
|
||||
/// The `PeerId` is the id of the node the handler is going to handle.
|
||||
fn into_handler(self, remote_peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler;
|
||||
fn into_handler(
|
||||
self,
|
||||
remote_peer_id: &PeerId,
|
||||
connected_point: &ConnectedPoint,
|
||||
) -> Self::Handler;
|
||||
|
||||
/// Return the handler's inbound protocol.
|
||||
fn inbound_protocol(&self) -> <Self::Handler as ProtocolsHandler>::InboundProtocol;
|
||||
@ -492,7 +494,8 @@ pub trait IntoProtocolsHandler: Send + 'static {
|
||||
}
|
||||
|
||||
impl<T> IntoProtocolsHandler for T
|
||||
where T: ProtocolsHandler
|
||||
where
|
||||
T: ProtocolsHandler,
|
||||
{
|
||||
type Handler = Self;
|
||||
|
||||
@ -537,9 +540,9 @@ impl Ord for KeepAlive {
|
||||
use self::KeepAlive::*;
|
||||
|
||||
match (self, other) {
|
||||
(No, No) | (Yes, Yes) => Ordering::Equal,
|
||||
(No, _) | (_, Yes) => Ordering::Less,
|
||||
(_, No) | (Yes, _) => Ordering::Greater,
|
||||
(No, No) | (Yes, Yes) => Ordering::Equal,
|
||||
(No, _) | (_, Yes) => Ordering::Less,
|
||||
(_, No) | (Yes, _) => Ordering::Greater,
|
||||
(Until(t1), Until(t2)) => t1.cmp(t2),
|
||||
}
|
||||
}
|
||||
|
@ -18,15 +18,14 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::NegotiatedSubstream;
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
SubstreamProtocol,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr
|
||||
KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::NegotiatedSubstream;
|
||||
use libp2p_core::{
|
||||
upgrade::{DeniedUpgrade, InboundUpgrade, OutboundUpgrade},
|
||||
Multiaddr,
|
||||
};
|
||||
use libp2p_core::{Multiaddr, upgrade::{InboundUpgrade, OutboundUpgrade, DeniedUpgrade}};
|
||||
use std::task::{Context, Poll};
|
||||
use void::Void;
|
||||
|
||||
@ -39,7 +38,7 @@ pub struct DummyProtocolsHandler {
|
||||
impl Default for DummyProtocolsHandler {
|
||||
fn default() -> Self {
|
||||
DummyProtocolsHandler {
|
||||
keep_alive: KeepAlive::No
|
||||
keep_alive: KeepAlive::No,
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -60,14 +59,14 @@ impl ProtocolsHandler for DummyProtocolsHandler {
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
_: <Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Output,
|
||||
_: Self::InboundOpenInfo
|
||||
_: Self::InboundOpenInfo,
|
||||
) {
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
_: <Self::OutboundProtocol as OutboundUpgrade<NegotiatedSubstream>>::Output,
|
||||
_: Self::OutboundOpenInfo
|
||||
_: Self::OutboundOpenInfo,
|
||||
) {
|
||||
}
|
||||
|
||||
@ -75,9 +74,23 @@ impl ProtocolsHandler for DummyProtocolsHandler {
|
||||
|
||||
fn inject_address_change(&mut self, _: &Multiaddr) {}
|
||||
|
||||
fn inject_dial_upgrade_error(&mut self, _: Self::OutboundOpenInfo, _: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgrade<NegotiatedSubstream>>::Error>) {}
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
_: Self::OutboundOpenInfo,
|
||||
_: ProtocolsHandlerUpgrErr<
|
||||
<Self::OutboundProtocol as OutboundUpgrade<NegotiatedSubstream>>::Error,
|
||||
>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn inject_listen_upgrade_error(&mut self, _: Self::InboundOpenInfo, _: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Error>) {}
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
_: Self::InboundOpenInfo,
|
||||
_: ProtocolsHandlerUpgrErr<
|
||||
<Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Error,
|
||||
>,
|
||||
) {
|
||||
}
|
||||
|
||||
fn connection_keep_alive(&self) -> KeepAlive {
|
||||
self.keep_alive
|
||||
@ -87,7 +100,12 @@ impl ProtocolsHandler for DummyProtocolsHandler {
|
||||
&mut self,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>,
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
Poll::Pending
|
||||
}
|
||||
|
@ -18,14 +18,10 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
SubstreamProtocol,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr
|
||||
KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use libp2p_core::Multiaddr;
|
||||
use std::{fmt::Debug, marker::PhantomData, task::Context, task::Poll};
|
||||
|
||||
@ -69,7 +65,7 @@ where
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
info: Self::InboundOpenInfo
|
||||
info: Self::InboundOpenInfo,
|
||||
) {
|
||||
self.inner.inject_fully_negotiated_inbound(protocol, info)
|
||||
}
|
||||
@ -77,7 +73,7 @@ where
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
|
||||
info: Self::OutboundOpenInfo
|
||||
info: Self::OutboundOpenInfo,
|
||||
) {
|
||||
self.inner.inject_fully_negotiated_outbound(protocol, info)
|
||||
}
|
||||
@ -92,11 +88,19 @@ where
|
||||
self.inner.inject_address_change(addr)
|
||||
}
|
||||
|
||||
fn inject_dial_upgrade_error(&mut self, info: Self::OutboundOpenInfo, error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>) {
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::OutboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
) {
|
||||
self.inner.inject_dial_upgrade_error(info, error)
|
||||
}
|
||||
|
||||
fn inject_listen_upgrade_error(&mut self, info: Self::InboundOpenInfo, error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>) {
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::InboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>,
|
||||
) {
|
||||
self.inner.inject_listen_upgrade_error(info, error)
|
||||
}
|
||||
|
||||
@ -108,7 +112,12 @@ where
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>,
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
self.inner.poll(cx)
|
||||
}
|
||||
|
@ -18,14 +18,10 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
SubstreamProtocol,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr
|
||||
KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use libp2p_core::Multiaddr;
|
||||
use std::fmt::Debug;
|
||||
use std::task::{Context, Poll};
|
||||
@ -39,10 +35,7 @@ pub struct MapOutEvent<TProtoHandler, TMap> {
|
||||
impl<TProtoHandler, TMap> MapOutEvent<TProtoHandler, TMap> {
|
||||
/// Creates a `MapOutEvent`.
|
||||
pub(crate) fn new(inner: TProtoHandler, map: TMap) -> Self {
|
||||
MapOutEvent {
|
||||
inner,
|
||||
map,
|
||||
}
|
||||
MapOutEvent { inner, map }
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,7 +61,7 @@ where
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
info: Self::InboundOpenInfo
|
||||
info: Self::InboundOpenInfo,
|
||||
) {
|
||||
self.inner.inject_fully_negotiated_inbound(protocol, info)
|
||||
}
|
||||
@ -76,7 +69,7 @@ where
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
|
||||
info: Self::OutboundOpenInfo
|
||||
info: Self::OutboundOpenInfo,
|
||||
) {
|
||||
self.inner.inject_fully_negotiated_outbound(protocol, info)
|
||||
}
|
||||
@ -89,11 +82,19 @@ where
|
||||
self.inner.inject_address_change(addr)
|
||||
}
|
||||
|
||||
fn inject_dial_upgrade_error(&mut self, info: Self::OutboundOpenInfo, error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>) {
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::OutboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
) {
|
||||
self.inner.inject_dial_upgrade_error(info, error)
|
||||
}
|
||||
|
||||
fn inject_listen_upgrade_error(&mut self, info: Self::InboundOpenInfo, error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>) {
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::InboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>,
|
||||
) {
|
||||
self.inner.inject_listen_upgrade_error(info, error)
|
||||
}
|
||||
|
||||
@ -105,15 +106,18 @@ where
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>,
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
self.inner.poll(cx).map(|ev| {
|
||||
match ev {
|
||||
ProtocolsHandlerEvent::Custom(ev) => ProtocolsHandlerEvent::Custom((self.map)(ev)),
|
||||
ProtocolsHandlerEvent::Close(err) => ProtocolsHandlerEvent::Close(err),
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol } => {
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }
|
||||
}
|
||||
self.inner.poll(cx).map(|ev| match ev {
|
||||
ProtocolsHandlerEvent::Custom(ev) => ProtocolsHandlerEvent::Custom((self.map)(ev)),
|
||||
ProtocolsHandlerEvent::Close(err) => ProtocolsHandlerEvent::Close(err),
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol } => {
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }
|
||||
}
|
||||
})
|
||||
}
|
||||
|
@ -21,23 +21,15 @@
|
||||
//! A [`ProtocolsHandler`] implementation that combines multiple other `ProtocolsHandler`s
|
||||
//! indexed by some key.
|
||||
|
||||
use crate::NegotiatedSubstream;
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
IntoProtocolsHandler,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
SubstreamProtocol
|
||||
};
|
||||
use crate::upgrade::{
|
||||
InboundUpgradeSend,
|
||||
OutboundUpgradeSend,
|
||||
UpgradeInfoSend
|
||||
IntoProtocolsHandler, KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend};
|
||||
use crate::NegotiatedSubstream;
|
||||
use futures::{future::BoxFuture, prelude::*};
|
||||
use libp2p_core::upgrade::{NegotiationError, ProtocolError, ProtocolName, UpgradeError};
|
||||
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId};
|
||||
use libp2p_core::upgrade::{ProtocolName, UpgradeError, NegotiationError, ProtocolError};
|
||||
use rand::Rng;
|
||||
use std::{
|
||||
cmp,
|
||||
@ -47,19 +39,19 @@ use std::{
|
||||
hash::Hash,
|
||||
iter::{self, FromIterator},
|
||||
task::{Context, Poll},
|
||||
time::Duration
|
||||
time::Duration,
|
||||
};
|
||||
|
||||
/// A [`ProtocolsHandler`] for multiple `ProtocolsHandler`s of the same type.
|
||||
#[derive(Clone)]
|
||||
pub struct MultiHandler<K, H> {
|
||||
handlers: HashMap<K, H>
|
||||
handlers: HashMap<K, H>,
|
||||
}
|
||||
|
||||
impl<K, H> fmt::Debug for MultiHandler<K, H>
|
||||
where
|
||||
K: fmt::Debug + Eq + Hash,
|
||||
H: fmt::Debug
|
||||
H: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("MultiHandler")
|
||||
@ -71,17 +63,23 @@ where
|
||||
impl<K, H> MultiHandler<K, H>
|
||||
where
|
||||
K: Hash + Eq,
|
||||
H: ProtocolsHandler
|
||||
H: ProtocolsHandler,
|
||||
{
|
||||
/// Create and populate a `MultiHandler` from the given handler iterator.
|
||||
///
|
||||
/// It is an error for any two protocols handlers to share the same protocol name.
|
||||
pub fn try_from_iter<I>(iter: I) -> Result<Self, DuplicateProtonameError>
|
||||
where
|
||||
I: IntoIterator<Item = (K, H)>
|
||||
I: IntoIterator<Item = (K, H)>,
|
||||
{
|
||||
let m = MultiHandler { handlers: HashMap::from_iter(iter) };
|
||||
uniq_proto_names(m.handlers.values().map(|h| h.listen_protocol().into_upgrade().0))?;
|
||||
let m = MultiHandler {
|
||||
handlers: HashMap::from_iter(iter),
|
||||
};
|
||||
uniq_proto_names(
|
||||
m.handlers
|
||||
.values()
|
||||
.map(|h| h.listen_protocol().into_upgrade().0),
|
||||
)?;
|
||||
Ok(m)
|
||||
}
|
||||
}
|
||||
@ -91,7 +89,7 @@ where
|
||||
K: Clone + Debug + Hash + Eq + Send + 'static,
|
||||
H: ProtocolsHandler,
|
||||
H::InboundProtocol: InboundUpgradeSend,
|
||||
H::OutboundProtocol: OutboundUpgradeSend
|
||||
H::OutboundProtocol: OutboundUpgradeSend,
|
||||
{
|
||||
type InEvent = (K, <H as ProtocolsHandler>::InEvent);
|
||||
type OutEvent = (K, <H as ProtocolsHandler>::OutEvent);
|
||||
@ -102,28 +100,31 @@ where
|
||||
type OutboundOpenInfo = (K, <H as ProtocolsHandler>::OutboundOpenInfo);
|
||||
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo> {
|
||||
let (upgrade, info, timeout) = self.handlers.iter()
|
||||
let (upgrade, info, timeout) = self
|
||||
.handlers
|
||||
.iter()
|
||||
.map(|(key, handler)| {
|
||||
let proto = handler.listen_protocol();
|
||||
let timeout = *proto.timeout();
|
||||
let (upgrade, info) = proto.into_upgrade();
|
||||
(key.clone(), (upgrade, info, timeout))
|
||||
})
|
||||
.fold((Upgrade::new(), Info::new(), Duration::from_secs(0)),
|
||||
.fold(
|
||||
(Upgrade::new(), Info::new(), Duration::from_secs(0)),
|
||||
|(mut upg, mut inf, mut timeout), (k, (u, i, t))| {
|
||||
upg.upgrades.push((k.clone(), u));
|
||||
inf.infos.push((k, i));
|
||||
timeout = cmp::max(timeout, t);
|
||||
(upg, inf, timeout)
|
||||
}
|
||||
},
|
||||
);
|
||||
SubstreamProtocol::new(upgrade, info).with_timeout(timeout)
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_outbound (
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
|
||||
(key, arg): Self::OutboundOpenInfo
|
||||
(key, arg): Self::OutboundOpenInfo,
|
||||
) {
|
||||
if let Some(h) = self.handlers.get_mut(&key) {
|
||||
h.inject_fully_negotiated_outbound(protocol, arg)
|
||||
@ -132,10 +133,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_inbound (
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
(key, arg): <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
mut info: Self::InboundOpenInfo
|
||||
mut info: Self::InboundOpenInfo,
|
||||
) {
|
||||
if let Some(h) = self.handlers.get_mut(&key) {
|
||||
if let Some(i) = info.take(&key) {
|
||||
@ -160,10 +161,10 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_dial_upgrade_error (
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
(key, arg): Self::OutboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
) {
|
||||
if let Some(h) = self.handlers.get_mut(&key) {
|
||||
h.inject_dial_upgrade_error(arg, error)
|
||||
@ -175,77 +176,118 @@ where
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
mut info: Self::InboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>
|
||||
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>,
|
||||
) {
|
||||
match error {
|
||||
ProtocolsHandlerUpgrErr::Timer =>
|
||||
ProtocolsHandlerUpgrErr::Timer => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Timer)
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Timeout =>
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Timeout => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Timeout)
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) =>
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)))
|
||||
h.inject_listen_upgrade_error(
|
||||
i,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(
|
||||
NegotiationError::Failed,
|
||||
)),
|
||||
)
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::ProtocolError(e))) =>
|
||||
match e {
|
||||
ProtocolError::IoError(e) =>
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::IoError(e.kind().into()));
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
|
||||
}
|
||||
}
|
||||
ProtocolError::InvalidMessage =>
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::InvalidMessage);
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
|
||||
}
|
||||
}
|
||||
ProtocolError::InvalidProtocol =>
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::InvalidProtocol);
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
|
||||
}
|
||||
}
|
||||
ProtocolError::TooManyProtocols =>
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::TooManyProtocols);
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(
|
||||
NegotiationError::ProtocolError(e),
|
||||
)) => match e {
|
||||
ProtocolError::IoError(e) => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::IoError(
|
||||
e.kind().into(),
|
||||
));
|
||||
h.inject_listen_upgrade_error(
|
||||
i,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply((k, e))) =>
|
||||
ProtocolError::InvalidMessage => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::InvalidMessage);
|
||||
h.inject_listen_upgrade_error(
|
||||
i,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtocolError::InvalidProtocol => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e = NegotiationError::ProtocolError(ProtocolError::InvalidProtocol);
|
||||
h.inject_listen_upgrade_error(
|
||||
i,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
ProtocolError::TooManyProtocols => {
|
||||
for (k, h) in &mut self.handlers {
|
||||
if let Some(i) = info.take(k) {
|
||||
let e =
|
||||
NegotiationError::ProtocolError(ProtocolError::TooManyProtocols);
|
||||
h.inject_listen_upgrade_error(
|
||||
i,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply((k, e))) => {
|
||||
if let Some(h) = self.handlers.get_mut(&k) {
|
||||
if let Some(i) = info.take(&k) {
|
||||
h.inject_listen_upgrade_error(i, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)))
|
||||
h.inject_listen_upgrade_error(
|
||||
i,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn connection_keep_alive(&self) -> KeepAlive {
|
||||
self.handlers.values()
|
||||
self.handlers
|
||||
.values()
|
||||
.map(|h| h.connection_keep_alive())
|
||||
.max()
|
||||
.unwrap_or(KeepAlive::No)
|
||||
}
|
||||
|
||||
fn poll(&mut self, cx: &mut Context<'_>)
|
||||
-> Poll<ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>>
|
||||
{
|
||||
fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
// Calling `gen_range(0, 0)` (see below) would panic, so we have return early to avoid
|
||||
// that situation.
|
||||
if self.handlers.is_empty() {
|
||||
@ -257,15 +299,19 @@ where
|
||||
|
||||
for (k, h) in self.handlers.iter_mut().skip(pos) {
|
||||
if let Poll::Ready(e) = h.poll(cx) {
|
||||
let e = e.map_outbound_open_info(|i| (k.clone(), i)).map_custom(|p| (k.clone(), p));
|
||||
return Poll::Ready(e)
|
||||
let e = e
|
||||
.map_outbound_open_info(|i| (k.clone(), i))
|
||||
.map_custom(|p| (k.clone(), p));
|
||||
return Poll::Ready(e);
|
||||
}
|
||||
}
|
||||
|
||||
for (k, h) in self.handlers.iter_mut().take(pos) {
|
||||
if let Poll::Ready(e) = h.poll(cx) {
|
||||
let e = e.map_outbound_open_info(|i| (k.clone(), i)).map_custom(|p| (k.clone(), p));
|
||||
return Poll::Ready(e)
|
||||
let e = e
|
||||
.map_outbound_open_info(|i| (k.clone(), i))
|
||||
.map_custom(|p| (k.clone(), p));
|
||||
return Poll::Ready(e);
|
||||
}
|
||||
}
|
||||
|
||||
@ -276,13 +322,13 @@ where
|
||||
/// A [`IntoProtocolsHandler`] for multiple other `IntoProtocolsHandler`s.
|
||||
#[derive(Clone)]
|
||||
pub struct IntoMultiHandler<K, H> {
|
||||
handlers: HashMap<K, H>
|
||||
handlers: HashMap<K, H>,
|
||||
}
|
||||
|
||||
impl<K, H> fmt::Debug for IntoMultiHandler<K, H>
|
||||
where
|
||||
K: fmt::Debug + Eq + Hash,
|
||||
H: fmt::Debug
|
||||
H: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("IntoMultiHandler")
|
||||
@ -291,20 +337,21 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
impl<K, H> IntoMultiHandler<K, H>
|
||||
where
|
||||
K: Hash + Eq,
|
||||
H: IntoProtocolsHandler
|
||||
H: IntoProtocolsHandler,
|
||||
{
|
||||
/// Create and populate an `IntoMultiHandler` from the given iterator.
|
||||
///
|
||||
/// It is an error for any two protocols handlers to share the same protocol name.
|
||||
pub fn try_from_iter<I>(iter: I) -> Result<Self, DuplicateProtonameError>
|
||||
where
|
||||
I: IntoIterator<Item = (K, H)>
|
||||
I: IntoIterator<Item = (K, H)>,
|
||||
{
|
||||
let m = IntoMultiHandler { handlers: HashMap::from_iter(iter) };
|
||||
let m = IntoMultiHandler {
|
||||
handlers: HashMap::from_iter(iter),
|
||||
};
|
||||
uniq_proto_names(m.handlers.values().map(|h| h.inbound_protocol()))?;
|
||||
Ok(m)
|
||||
}
|
||||
@ -313,23 +360,27 @@ where
|
||||
impl<K, H> IntoProtocolsHandler for IntoMultiHandler<K, H>
|
||||
where
|
||||
K: Debug + Clone + Eq + Hash + Send + 'static,
|
||||
H: IntoProtocolsHandler
|
||||
H: IntoProtocolsHandler,
|
||||
{
|
||||
type Handler = MultiHandler<K, H::Handler>;
|
||||
|
||||
fn into_handler(self, p: &PeerId, c: &ConnectedPoint) -> Self::Handler {
|
||||
MultiHandler {
|
||||
handlers: self.handlers.into_iter()
|
||||
handlers: self
|
||||
.handlers
|
||||
.into_iter()
|
||||
.map(|(k, h)| (k, h.into_handler(p, c)))
|
||||
.collect()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
|
||||
fn inbound_protocol(&self) -> <Self::Handler as ProtocolsHandler>::InboundProtocol {
|
||||
Upgrade {
|
||||
upgrades: self.handlers.iter()
|
||||
upgrades: self
|
||||
.handlers
|
||||
.iter()
|
||||
.map(|(k, h)| (k.clone(), h.inbound_protocol()))
|
||||
.collect()
|
||||
.collect(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -347,7 +398,7 @@ impl<H: ProtocolName> ProtocolName for IndexedProtoName<H> {
|
||||
/// The aggregated `InboundOpenInfo`s of supported inbound substream protocols.
|
||||
#[derive(Clone)]
|
||||
pub struct Info<K, I> {
|
||||
infos: Vec<(K, I)>
|
||||
infos: Vec<(K, I)>,
|
||||
}
|
||||
|
||||
impl<K: Eq, I> Info<K, I> {
|
||||
@ -357,7 +408,7 @@ impl<K: Eq, I> Info<K, I> {
|
||||
|
||||
pub fn take(&mut self, k: &K) -> Option<I> {
|
||||
if let Some(p) = self.infos.iter().position(|(key, _)| key == k) {
|
||||
return Some(self.infos.remove(p).1)
|
||||
return Some(self.infos.remove(p).1);
|
||||
}
|
||||
None
|
||||
}
|
||||
@ -366,19 +417,21 @@ impl<K: Eq, I> Info<K, I> {
|
||||
/// Inbound and outbound upgrade for all `ProtocolsHandler`s.
|
||||
#[derive(Clone)]
|
||||
pub struct Upgrade<K, H> {
|
||||
upgrades: Vec<(K, H)>
|
||||
upgrades: Vec<(K, H)>,
|
||||
}
|
||||
|
||||
impl<K, H> Upgrade<K, H> {
|
||||
fn new() -> Self {
|
||||
Upgrade { upgrades: Vec::new() }
|
||||
Upgrade {
|
||||
upgrades: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<K, H> fmt::Debug for Upgrade<K, H>
|
||||
where
|
||||
K: fmt::Debug + Eq + Hash,
|
||||
H: fmt::Debug
|
||||
H: fmt::Debug,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
f.debug_struct("Upgrade")
|
||||
@ -390,13 +443,15 @@ where
|
||||
impl<K, H> UpgradeInfoSend for Upgrade<K, H>
|
||||
where
|
||||
H: UpgradeInfoSend,
|
||||
K: Send + 'static
|
||||
K: Send + 'static,
|
||||
{
|
||||
type Info = IndexedProtoName<H::Info>;
|
||||
type InfoIter = std::vec::IntoIter<Self::Info>;
|
||||
|
||||
fn protocol_info(&self) -> Self::InfoIter {
|
||||
self.upgrades.iter().enumerate()
|
||||
self.upgrades
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(i, (_, h))| iter::repeat(i).zip(h.protocol_info()))
|
||||
.flatten()
|
||||
.map(|(i, h)| IndexedProtoName(i, h))
|
||||
@ -408,21 +463,20 @@ where
|
||||
impl<K, H> InboundUpgradeSend for Upgrade<K, H>
|
||||
where
|
||||
H: InboundUpgradeSend,
|
||||
K: Send + 'static
|
||||
K: Send + 'static,
|
||||
{
|
||||
type Output = (K, <H as InboundUpgradeSend>::Output);
|
||||
type Error = (K, <H as InboundUpgradeSend>::Error);
|
||||
type Error = (K, <H as InboundUpgradeSend>::Error);
|
||||
type Future = BoxFuture<'static, Result<Self::Output, Self::Error>>;
|
||||
|
||||
fn upgrade_inbound(mut self, resource: NegotiatedSubstream, info: Self::Info) -> Self::Future {
|
||||
let IndexedProtoName(index, info) = info;
|
||||
let (key, upgrade) = self.upgrades.remove(index);
|
||||
upgrade.upgrade_inbound(resource, info)
|
||||
.map(move |out| {
|
||||
match out {
|
||||
Ok(o) => Ok((key, o)),
|
||||
Err(e) => Err((key, e))
|
||||
}
|
||||
upgrade
|
||||
.upgrade_inbound(resource, info)
|
||||
.map(move |out| match out {
|
||||
Ok(o) => Ok((key, o)),
|
||||
Err(e) => Err((key, e)),
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
@ -431,21 +485,20 @@ where
|
||||
impl<K, H> OutboundUpgradeSend for Upgrade<K, H>
|
||||
where
|
||||
H: OutboundUpgradeSend,
|
||||
K: Send + 'static
|
||||
K: Send + 'static,
|
||||
{
|
||||
type Output = (K, <H as OutboundUpgradeSend>::Output);
|
||||
type Error = (K, <H as OutboundUpgradeSend>::Error);
|
||||
type Error = (K, <H as OutboundUpgradeSend>::Error);
|
||||
type Future = BoxFuture<'static, Result<Self::Output, Self::Error>>;
|
||||
|
||||
fn upgrade_outbound(mut self, resource: NegotiatedSubstream, info: Self::Info) -> Self::Future {
|
||||
let IndexedProtoName(index, info) = info;
|
||||
let (key, upgrade) = self.upgrades.remove(index);
|
||||
upgrade.upgrade_outbound(resource, info)
|
||||
.map(move |out| {
|
||||
match out {
|
||||
Ok(o) => Ok((key, o)),
|
||||
Err(e) => Err((key, e))
|
||||
}
|
||||
upgrade
|
||||
.upgrade_outbound(resource, info)
|
||||
.map(move |out| match out {
|
||||
Ok(o) => Ok((key, o)),
|
||||
Err(e) => Err((key, e)),
|
||||
})
|
||||
.boxed()
|
||||
}
|
||||
@ -455,14 +508,14 @@ where
|
||||
fn uniq_proto_names<I, T>(iter: I) -> Result<(), DuplicateProtonameError>
|
||||
where
|
||||
I: Iterator<Item = T>,
|
||||
T: UpgradeInfoSend
|
||||
T: UpgradeInfoSend,
|
||||
{
|
||||
let mut set = HashSet::new();
|
||||
for infos in iter {
|
||||
for i in infos.protocol_info() {
|
||||
let v = Vec::from(i.protocol_name());
|
||||
if set.contains(&v) {
|
||||
return Err(DuplicateProtonameError(v))
|
||||
return Err(DuplicateProtonameError(v));
|
||||
} else {
|
||||
set.insert(v);
|
||||
}
|
||||
|
@ -18,29 +18,22 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::upgrade::SendWrapper;
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
ProtocolsHandler,
|
||||
IntoProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr
|
||||
IntoProtocolsHandler, KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
};
|
||||
use crate::upgrade::SendWrapper;
|
||||
|
||||
use futures::prelude::*;
|
||||
use futures::stream::FuturesUnordered;
|
||||
use libp2p_core::{
|
||||
Multiaddr,
|
||||
Connected,
|
||||
connection::{
|
||||
ConnectionHandler,
|
||||
ConnectionHandlerEvent,
|
||||
IntoConnectionHandler,
|
||||
Substream,
|
||||
ConnectionHandler, ConnectionHandlerEvent, IntoConnectionHandler, Substream,
|
||||
SubstreamEndpoint,
|
||||
},
|
||||
muxing::StreamMuxerBox,
|
||||
upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError}
|
||||
upgrade::{self, InboundUpgradeApply, OutboundUpgradeApply, UpgradeError},
|
||||
Connected, Multiaddr,
|
||||
};
|
||||
use std::{error, fmt, pin::Pin, task::Context, task::Poll, time::Duration};
|
||||
use wasm_timer::{Delay, Instant};
|
||||
@ -55,7 +48,7 @@ pub struct NodeHandlerWrapperBuilder<TIntoProtoHandler> {
|
||||
|
||||
impl<TIntoProtoHandler> NodeHandlerWrapperBuilder<TIntoProtoHandler>
|
||||
where
|
||||
TIntoProtoHandler: IntoProtocolsHandler
|
||||
TIntoProtoHandler: IntoProtocolsHandler,
|
||||
{
|
||||
/// Builds a `NodeHandlerWrapperBuilder`.
|
||||
pub(crate) fn new(handler: TIntoProtoHandler) -> Self {
|
||||
@ -67,7 +60,7 @@ where
|
||||
|
||||
pub(crate) fn with_substream_upgrade_protocol_override(
|
||||
mut self,
|
||||
version: Option<upgrade::Version>
|
||||
version: Option<upgrade::Version>,
|
||||
) -> Self {
|
||||
self.substream_upgrade_protocol_override = version;
|
||||
self
|
||||
@ -84,7 +77,9 @@ where
|
||||
|
||||
fn into_handler(self, connected: &Connected) -> Self::Handler {
|
||||
NodeHandlerWrapper {
|
||||
handler: self.handler.into_handler(&connected.peer_id, &connected.endpoint),
|
||||
handler: self
|
||||
.handler
|
||||
.into_handler(&connected.peer_id, &connected.endpoint),
|
||||
negotiating_in: Default::default(),
|
||||
negotiating_out: Default::default(),
|
||||
queued_dial_upgrades: Vec::new(),
|
||||
@ -105,15 +100,25 @@ where
|
||||
/// The underlying handler.
|
||||
handler: TProtoHandler,
|
||||
/// Futures that upgrade incoming substreams.
|
||||
negotiating_in: FuturesUnordered<SubstreamUpgrade<
|
||||
TProtoHandler::InboundOpenInfo,
|
||||
InboundUpgradeApply<Substream<StreamMuxerBox>, SendWrapper<TProtoHandler::InboundProtocol>>,
|
||||
>>,
|
||||
negotiating_in: FuturesUnordered<
|
||||
SubstreamUpgrade<
|
||||
TProtoHandler::InboundOpenInfo,
|
||||
InboundUpgradeApply<
|
||||
Substream<StreamMuxerBox>,
|
||||
SendWrapper<TProtoHandler::InboundProtocol>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
/// Futures that upgrade outgoing substreams.
|
||||
negotiating_out: FuturesUnordered<SubstreamUpgrade<
|
||||
TProtoHandler::OutboundOpenInfo,
|
||||
OutboundUpgradeApply<Substream<StreamMuxerBox>, SendWrapper<TProtoHandler::OutboundProtocol>>,
|
||||
>>,
|
||||
negotiating_out: FuturesUnordered<
|
||||
SubstreamUpgrade<
|
||||
TProtoHandler::OutboundOpenInfo,
|
||||
OutboundUpgradeApply<
|
||||
Substream<StreamMuxerBox>,
|
||||
SendWrapper<TProtoHandler::OutboundProtocol>,
|
||||
>,
|
||||
>,
|
||||
>,
|
||||
/// For each outbound substream request, how to upgrade it. The first element of the tuple
|
||||
/// is the unique identifier (see `unique_dial_upgrade_id`).
|
||||
queued_dial_upgrades: Vec<(u64, SendWrapper<TProtoHandler::OutboundProtocol>)>,
|
||||
@ -137,28 +142,43 @@ impl<UserData, Upgrade, UpgradeOutput, TUpgradeError> Future for SubstreamUpgrad
|
||||
where
|
||||
Upgrade: Future<Output = Result<UpgradeOutput, UpgradeError<TUpgradeError>>> + Unpin,
|
||||
{
|
||||
type Output = (UserData, Result<UpgradeOutput, ProtocolsHandlerUpgrErr<TUpgradeError>>);
|
||||
type Output = (
|
||||
UserData,
|
||||
Result<UpgradeOutput, ProtocolsHandlerUpgrErr<TUpgradeError>>,
|
||||
);
|
||||
|
||||
fn poll(mut self: Pin<&mut Self>, cx: &mut Context) -> Poll<Self::Output> {
|
||||
match self.timeout.poll_unpin(cx) {
|
||||
Poll::Ready(Ok(_)) => return Poll::Ready((
|
||||
self.user_data.take().expect("Future not to be polled again once ready."),
|
||||
Err(ProtocolsHandlerUpgrErr::Timeout)),
|
||||
),
|
||||
Poll::Ready(Err(_)) => return Poll::Ready((
|
||||
self.user_data.take().expect("Future not to be polled again once ready."),
|
||||
Err(ProtocolsHandlerUpgrErr::Timer)),
|
||||
),
|
||||
Poll::Pending => {},
|
||||
Poll::Ready(Ok(_)) => {
|
||||
return Poll::Ready((
|
||||
self.user_data
|
||||
.take()
|
||||
.expect("Future not to be polled again once ready."),
|
||||
Err(ProtocolsHandlerUpgrErr::Timeout),
|
||||
))
|
||||
}
|
||||
Poll::Ready(Err(_)) => {
|
||||
return Poll::Ready((
|
||||
self.user_data
|
||||
.take()
|
||||
.expect("Future not to be polled again once ready."),
|
||||
Err(ProtocolsHandlerUpgrErr::Timer),
|
||||
))
|
||||
}
|
||||
Poll::Pending => {}
|
||||
}
|
||||
|
||||
match self.upgrade.poll_unpin(cx) {
|
||||
Poll::Ready(Ok(upgrade)) => Poll::Ready((
|
||||
self.user_data.take().expect("Future not to be polled again once ready."),
|
||||
self.user_data
|
||||
.take()
|
||||
.expect("Future not to be polled again once ready."),
|
||||
Ok(upgrade),
|
||||
)),
|
||||
Poll::Ready(Err(err)) => Poll::Ready((
|
||||
self.user_data.take().expect("Future not to be polled again once ready."),
|
||||
self.user_data
|
||||
.take()
|
||||
.expect("Future not to be polled again once ready."),
|
||||
Err(ProtocolsHandlerUpgrErr::Upgrade(err)),
|
||||
)),
|
||||
Poll::Pending => Poll::Pending,
|
||||
@ -166,7 +186,6 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// The options for a planned connection & handler shutdown.
|
||||
///
|
||||
/// A shutdown is planned anew based on the the return value of
|
||||
@ -182,7 +201,7 @@ enum Shutdown {
|
||||
/// A shut down is planned as soon as possible.
|
||||
Asap,
|
||||
/// A shut down is planned for when a `Delay` has elapsed.
|
||||
Later(Delay, Instant)
|
||||
Later(Delay, Instant),
|
||||
}
|
||||
|
||||
/// Error generated by the `NodeHandlerWrapper`.
|
||||
@ -202,20 +221,21 @@ impl<TErr> From<TErr> for NodeHandlerWrapperError<TErr> {
|
||||
|
||||
impl<TErr> fmt::Display for NodeHandlerWrapperError<TErr>
|
||||
where
|
||||
TErr: fmt::Display
|
||||
TErr: fmt::Display,
|
||||
{
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
match self {
|
||||
NodeHandlerWrapperError::Handler(err) => write!(f, "{}", err),
|
||||
NodeHandlerWrapperError::KeepAliveTimeout =>
|
||||
write!(f, "Connection closed due to expired keep-alive timeout."),
|
||||
NodeHandlerWrapperError::KeepAliveTimeout => {
|
||||
write!(f, "Connection closed due to expired keep-alive timeout.")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<TErr> error::Error for NodeHandlerWrapperError<TErr>
|
||||
where
|
||||
TErr: error::Error + 'static
|
||||
TErr: error::Error + 'static,
|
||||
{
|
||||
fn source(&self) -> Option<&(dyn error::Error + 'static)> {
|
||||
match self {
|
||||
@ -272,7 +292,11 @@ where
|
||||
let mut version = upgrade::Version::default();
|
||||
if let Some(v) = self.substream_upgrade_protocol_override {
|
||||
if v != version {
|
||||
log::debug!("Substream upgrade protocol override: {:?} -> {:?}", version, v);
|
||||
log::debug!(
|
||||
"Substream upgrade protocol override: {:?} -> {:?}",
|
||||
version,
|
||||
v
|
||||
);
|
||||
version = v;
|
||||
}
|
||||
}
|
||||
@ -295,19 +319,25 @@ where
|
||||
self.handler.inject_address_change(new_address);
|
||||
}
|
||||
|
||||
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>>
|
||||
{
|
||||
while let Poll::Ready(Some((user_data, res))) = self.negotiating_in.poll_next_unpin(cx) {
|
||||
match res {
|
||||
Ok(upgrade) => self.handler.inject_fully_negotiated_inbound(upgrade, user_data),
|
||||
Ok(upgrade) => self
|
||||
.handler
|
||||
.inject_fully_negotiated_inbound(upgrade, user_data),
|
||||
Err(err) => self.handler.inject_listen_upgrade_error(user_data, err),
|
||||
}
|
||||
}
|
||||
|
||||
while let Poll::Ready(Some((user_data, res))) = self.negotiating_out.poll_next_unpin(cx) {
|
||||
match res {
|
||||
Ok(upgrade) => self.handler.inject_fully_negotiated_outbound(upgrade, user_data),
|
||||
Ok(upgrade) => self
|
||||
.handler
|
||||
.inject_fully_negotiated_outbound(upgrade, user_data),
|
||||
Err(err) => self.handler.inject_dial_upgrade_error(user_data, err),
|
||||
}
|
||||
}
|
||||
@ -319,14 +349,15 @@ where
|
||||
// Ask the handler whether it wants the connection (and the handler itself)
|
||||
// to be kept alive, which determines the planned shutdown, if any.
|
||||
match (&mut self.shutdown, self.handler.connection_keep_alive()) {
|
||||
(Shutdown::Later(timer, deadline), KeepAlive::Until(t)) =>
|
||||
(Shutdown::Later(timer, deadline), KeepAlive::Until(t)) => {
|
||||
if *deadline != t {
|
||||
*deadline = t;
|
||||
timer.reset_at(t)
|
||||
},
|
||||
}
|
||||
}
|
||||
(_, KeepAlive::Until(t)) => self.shutdown = Shutdown::Later(Delay::new_at(t), t),
|
||||
(_, KeepAlive::No) => self.shutdown = Shutdown::Asap,
|
||||
(_, KeepAlive::Yes) => self.shutdown = Shutdown::None
|
||||
(_, KeepAlive::Yes) => self.shutdown = Shutdown::None,
|
||||
};
|
||||
|
||||
match poll_result {
|
||||
@ -339,9 +370,9 @@ where
|
||||
self.unique_dial_upgrade_id += 1;
|
||||
let (upgrade, info) = protocol.into_upgrade();
|
||||
self.queued_dial_upgrades.push((id, SendWrapper(upgrade)));
|
||||
return Poll::Ready(Ok(
|
||||
ConnectionHandlerEvent::OutboundSubstreamRequest((id, info, timeout)),
|
||||
));
|
||||
return Poll::Ready(Ok(ConnectionHandlerEvent::OutboundSubstreamRequest((
|
||||
id, info, timeout,
|
||||
))));
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::Close(err)) => return Poll::Ready(Err(err.into())),
|
||||
Poll::Pending => (),
|
||||
@ -351,12 +382,16 @@ where
|
||||
// As long as we're still negotiating substreams, shutdown is always postponed.
|
||||
if self.negotiating_in.is_empty() && self.negotiating_out.is_empty() {
|
||||
match self.shutdown {
|
||||
Shutdown::None => {},
|
||||
Shutdown::Asap => return Poll::Ready(Err(NodeHandlerWrapperError::KeepAliveTimeout)),
|
||||
Shutdown::Later(ref mut delay, _) => match Future::poll(Pin::new(delay), cx) {
|
||||
Poll::Ready(_) => return Poll::Ready(Err(NodeHandlerWrapperError::KeepAliveTimeout)),
|
||||
Poll::Pending => {}
|
||||
Shutdown::None => {}
|
||||
Shutdown::Asap => {
|
||||
return Poll::Ready(Err(NodeHandlerWrapperError::KeepAliveTimeout))
|
||||
}
|
||||
Shutdown::Later(ref mut delay, _) => match Future::poll(Pin::new(delay), cx) {
|
||||
Poll::Ready(_) => {
|
||||
return Poll::Ready(Err(NodeHandlerWrapperError::KeepAliveTimeout))
|
||||
}
|
||||
Poll::Pending => {}
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -18,14 +18,10 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
SubstreamProtocol
|
||||
KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent, ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend};
|
||||
|
||||
use smallvec::SmallVec;
|
||||
use std::{error, fmt::Debug, task::Context, task::Poll, time::Duration};
|
||||
@ -53,8 +49,7 @@ where
|
||||
config: OneShotHandlerConfig,
|
||||
}
|
||||
|
||||
impl<TInbound, TOutbound, TEvent>
|
||||
OneShotHandler<TInbound, TOutbound, TEvent>
|
||||
impl<TInbound, TOutbound, TEvent> OneShotHandler<TInbound, TOutbound, TEvent>
|
||||
where
|
||||
TOutbound: OutboundUpgradeSend,
|
||||
{
|
||||
@ -102,8 +97,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<TInbound, TOutbound, TEvent> Default
|
||||
for OneShotHandler<TInbound, TOutbound, TEvent>
|
||||
impl<TInbound, TOutbound, TEvent> Default for OneShotHandler<TInbound, TOutbound, TEvent>
|
||||
where
|
||||
TOutbound: OutboundUpgradeSend,
|
||||
TInbound: InboundUpgradeSend + Default,
|
||||
@ -111,7 +105,7 @@ where
|
||||
fn default() -> Self {
|
||||
OneShotHandler::new(
|
||||
SubstreamProtocol::new(Default::default(), ()),
|
||||
OneShotHandlerConfig::default()
|
||||
OneShotHandlerConfig::default(),
|
||||
)
|
||||
}
|
||||
}
|
||||
@ -128,9 +122,7 @@ where
|
||||
{
|
||||
type InEvent = TOutbound;
|
||||
type OutEvent = TEvent;
|
||||
type Error = ProtocolsHandlerUpgrErr<
|
||||
<Self::OutboundProtocol as OutboundUpgradeSend>::Error,
|
||||
>;
|
||||
type Error = ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>;
|
||||
type InboundProtocol = TInbound;
|
||||
type OutboundProtocol = TOutbound;
|
||||
type OutboundOpenInfo = ();
|
||||
@ -143,7 +135,7 @@ where
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
out: <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
(): Self::InboundOpenInfo
|
||||
(): Self::InboundOpenInfo,
|
||||
) {
|
||||
// If we're shutting down the connection for inactivity, reset the timeout.
|
||||
if !self.keep_alive.is_yes() {
|
||||
@ -169,9 +161,7 @@ where
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
_info: Self::OutboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<
|
||||
<Self::OutboundProtocol as OutboundUpgradeSend>::Error,
|
||||
>,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
) {
|
||||
if self.pending_error.is_none() {
|
||||
self.pending_error = Some(error);
|
||||
@ -186,16 +176,19 @@ where
|
||||
&mut self,
|
||||
_: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>,
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
if let Some(err) = self.pending_error.take() {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(err))
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(err));
|
||||
}
|
||||
|
||||
if !self.events_out.is_empty() {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Custom(
|
||||
self.events_out.remove(0)
|
||||
));
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Custom(self.events_out.remove(0)));
|
||||
} else {
|
||||
self.events_out.shrink_to_fit();
|
||||
}
|
||||
@ -204,12 +197,10 @@ where
|
||||
if self.dial_negotiated < self.config.max_dial_negotiated {
|
||||
self.dial_negotiated += 1;
|
||||
let upgrade = self.dial_queue.remove(0);
|
||||
return Poll::Ready(
|
||||
ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: SubstreamProtocol::new(upgrade, ())
|
||||
.with_timeout(self.config.outbound_substream_timeout)
|
||||
},
|
||||
);
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: SubstreamProtocol::new(upgrade, ())
|
||||
.with_timeout(self.config.outbound_substream_timeout),
|
||||
});
|
||||
}
|
||||
} else {
|
||||
self.dial_queue.shrink_to_fit();
|
||||
@ -256,18 +247,19 @@ mod tests {
|
||||
#[test]
|
||||
fn do_not_keep_idle_connection_alive() {
|
||||
let mut handler: OneShotHandler<_, DeniedUpgrade, Void> = OneShotHandler::new(
|
||||
SubstreamProtocol::new(DeniedUpgrade{}, ()),
|
||||
SubstreamProtocol::new(DeniedUpgrade {}, ()),
|
||||
Default::default(),
|
||||
);
|
||||
|
||||
block_on(poll_fn(|cx| {
|
||||
loop {
|
||||
if let Poll::Pending = handler.poll(cx) {
|
||||
return Poll::Ready(())
|
||||
}
|
||||
block_on(poll_fn(|cx| loop {
|
||||
if let Poll::Pending = handler.poll(cx) {
|
||||
return Poll::Ready(());
|
||||
}
|
||||
}));
|
||||
|
||||
assert!(matches!(handler.connection_keep_alive(), KeepAlive::Until(_)));
|
||||
assert!(matches!(
|
||||
handler.connection_keep_alive(),
|
||||
KeepAlive::Until(_)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -18,22 +18,16 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::upgrade::{SendWrapper, InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
SubstreamProtocol,
|
||||
IntoProtocolsHandler,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
IntoProtocolsHandler, KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper};
|
||||
|
||||
use libp2p_core::{
|
||||
ConnectedPoint,
|
||||
Multiaddr,
|
||||
PeerId,
|
||||
either::{EitherError, EitherOutput},
|
||||
upgrade::{EitherUpgrade, SelectUpgrade, UpgradeError, NegotiationError, ProtocolError}
|
||||
upgrade::{EitherUpgrade, NegotiationError, ProtocolError, SelectUpgrade, UpgradeError},
|
||||
ConnectedPoint, Multiaddr, PeerId,
|
||||
};
|
||||
use std::{cmp, task::Context, task::Poll};
|
||||
|
||||
@ -49,10 +43,7 @@ pub struct IntoProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
impl<TProto1, TProto2> IntoProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
/// Builds a `IntoProtocolsHandlerSelect`.
|
||||
pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self {
|
||||
IntoProtocolsHandlerSelect {
|
||||
proto1,
|
||||
proto2,
|
||||
}
|
||||
IntoProtocolsHandlerSelect { proto1, proto2 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -63,7 +54,11 @@ where
|
||||
{
|
||||
type Handler = ProtocolsHandlerSelect<TProto1::Handler, TProto2::Handler>;
|
||||
|
||||
fn into_handler(self, remote_peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler {
|
||||
fn into_handler(
|
||||
self,
|
||||
remote_peer_id: &PeerId,
|
||||
connected_point: &ConnectedPoint,
|
||||
) -> Self::Handler {
|
||||
ProtocolsHandlerSelect {
|
||||
proto1: self.proto1.into_handler(remote_peer_id, connected_point),
|
||||
proto2: self.proto2.into_handler(remote_peer_id, connected_point),
|
||||
@ -71,7 +66,10 @@ where
|
||||
}
|
||||
|
||||
fn inbound_protocol(&self) -> <Self::Handler as ProtocolsHandler>::InboundProtocol {
|
||||
SelectUpgrade::new(SendWrapper(self.proto1.inbound_protocol()), SendWrapper(self.proto2.inbound_protocol()))
|
||||
SelectUpgrade::new(
|
||||
SendWrapper(self.proto1.inbound_protocol()),
|
||||
SendWrapper(self.proto2.inbound_protocol()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@ -87,10 +85,7 @@ pub struct ProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
impl<TProto1, TProto2> ProtocolsHandlerSelect<TProto1, TProto2> {
|
||||
/// Builds a `ProtocolsHandlerSelect`.
|
||||
pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self {
|
||||
ProtocolsHandlerSelect {
|
||||
proto1,
|
||||
proto2,
|
||||
}
|
||||
ProtocolsHandlerSelect { proto1, proto2 }
|
||||
}
|
||||
}
|
||||
|
||||
@ -102,8 +97,14 @@ where
|
||||
type InEvent = EitherOutput<TProto1::InEvent, TProto2::InEvent>;
|
||||
type OutEvent = EitherOutput<TProto1::OutEvent, TProto2::OutEvent>;
|
||||
type Error = EitherError<TProto1::Error, TProto2::Error>;
|
||||
type InboundProtocol = SelectUpgrade<SendWrapper<<TProto1 as ProtocolsHandler>::InboundProtocol>, SendWrapper<<TProto2 as ProtocolsHandler>::InboundProtocol>>;
|
||||
type OutboundProtocol = EitherUpgrade<SendWrapper<TProto1::OutboundProtocol>, SendWrapper<TProto2::OutboundProtocol>>;
|
||||
type InboundProtocol = SelectUpgrade<
|
||||
SendWrapper<<TProto1 as ProtocolsHandler>::InboundProtocol>,
|
||||
SendWrapper<<TProto2 as ProtocolsHandler>::InboundProtocol>,
|
||||
>;
|
||||
type OutboundProtocol = EitherUpgrade<
|
||||
SendWrapper<TProto1::OutboundProtocol>,
|
||||
SendWrapper<TProto2::OutboundProtocol>,
|
||||
>;
|
||||
type OutboundOpenInfo = EitherOutput<TProto1::OutboundOpenInfo, TProto2::OutboundOpenInfo>;
|
||||
type InboundOpenInfo = (TProto1::InboundOpenInfo, TProto2::InboundOpenInfo);
|
||||
|
||||
@ -117,25 +118,39 @@ where
|
||||
SubstreamProtocol::new(choice, (i1, i2)).with_timeout(timeout)
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_outbound(&mut self, protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output, endpoint: Self::OutboundOpenInfo) {
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
|
||||
endpoint: Self::OutboundOpenInfo,
|
||||
) {
|
||||
match (protocol, endpoint) {
|
||||
(EitherOutput::First(protocol), EitherOutput::First(info)) =>
|
||||
self.proto1.inject_fully_negotiated_outbound(protocol, info),
|
||||
(EitherOutput::Second(protocol), EitherOutput::Second(info)) =>
|
||||
self.proto2.inject_fully_negotiated_outbound(protocol, info),
|
||||
(EitherOutput::First(_), EitherOutput::Second(_)) =>
|
||||
panic!("wrong API usage: the protocol doesn't match the upgrade info"),
|
||||
(EitherOutput::Second(_), EitherOutput::First(_)) =>
|
||||
(EitherOutput::First(protocol), EitherOutput::First(info)) => {
|
||||
self.proto1.inject_fully_negotiated_outbound(protocol, info)
|
||||
}
|
||||
(EitherOutput::Second(protocol), EitherOutput::Second(info)) => {
|
||||
self.proto2.inject_fully_negotiated_outbound(protocol, info)
|
||||
}
|
||||
(EitherOutput::First(_), EitherOutput::Second(_)) => {
|
||||
panic!("wrong API usage: the protocol doesn't match the upgrade info")
|
||||
}
|
||||
(EitherOutput::Second(_), EitherOutput::First(_)) => {
|
||||
panic!("wrong API usage: the protocol doesn't match the upgrade info")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_inbound(&mut self, protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output, (i1, i2): Self::InboundOpenInfo) {
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
(i1, i2): Self::InboundOpenInfo,
|
||||
) {
|
||||
match protocol {
|
||||
EitherOutput::First(protocol) =>
|
||||
self.proto1.inject_fully_negotiated_inbound(protocol, i1),
|
||||
EitherOutput::Second(protocol) =>
|
||||
EitherOutput::First(protocol) => {
|
||||
self.proto1.inject_fully_negotiated_inbound(protocol, i1)
|
||||
}
|
||||
EitherOutput::Second(protocol) => {
|
||||
self.proto2.inject_fully_negotiated_inbound(protocol, i2)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -151,60 +166,108 @@ where
|
||||
self.proto2.inject_address_change(new_address)
|
||||
}
|
||||
|
||||
fn inject_dial_upgrade_error(&mut self, info: Self::OutboundOpenInfo, error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>) {
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::OutboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
) {
|
||||
match (info, error) {
|
||||
(EitherOutput::First(info), ProtocolsHandlerUpgrErr::Timer) => {
|
||||
self.proto1.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timer)
|
||||
},
|
||||
(EitherOutput::First(info), ProtocolsHandlerUpgrErr::Timeout) => {
|
||||
self.proto1.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timeout)
|
||||
},
|
||||
(EitherOutput::First(info), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err))) => {
|
||||
self.proto1.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)))
|
||||
},
|
||||
(EitherOutput::First(info), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(err)))) => {
|
||||
self.proto1.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)))
|
||||
},
|
||||
(EitherOutput::First(_), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::B(_)))) => {
|
||||
(EitherOutput::First(info), ProtocolsHandlerUpgrErr::Timer) => self
|
||||
.proto1
|
||||
.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timer),
|
||||
(EitherOutput::First(info), ProtocolsHandlerUpgrErr::Timeout) => self
|
||||
.proto1
|
||||
.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timeout),
|
||||
(
|
||||
EitherOutput::First(info),
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)),
|
||||
) => self.proto1.inject_dial_upgrade_error(
|
||||
info,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)),
|
||||
),
|
||||
(
|
||||
EitherOutput::First(info),
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(err))),
|
||||
) => self.proto1.inject_dial_upgrade_error(
|
||||
info,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)),
|
||||
),
|
||||
(
|
||||
EitherOutput::First(_),
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::B(_))),
|
||||
) => {
|
||||
panic!("Wrong API usage; the upgrade error doesn't match the outbound open info");
|
||||
},
|
||||
(EitherOutput::Second(info), ProtocolsHandlerUpgrErr::Timeout) => {
|
||||
self.proto2.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timeout)
|
||||
},
|
||||
(EitherOutput::Second(info), ProtocolsHandlerUpgrErr::Timer) => {
|
||||
self.proto2.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timer)
|
||||
},
|
||||
(EitherOutput::Second(info), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err))) => {
|
||||
self.proto2.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)))
|
||||
},
|
||||
(EitherOutput::Second(info), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::B(err)))) => {
|
||||
self.proto2.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)))
|
||||
},
|
||||
(EitherOutput::Second(_), ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(_)))) => {
|
||||
}
|
||||
(EitherOutput::Second(info), ProtocolsHandlerUpgrErr::Timeout) => self
|
||||
.proto2
|
||||
.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timeout),
|
||||
(EitherOutput::Second(info), ProtocolsHandlerUpgrErr::Timer) => self
|
||||
.proto2
|
||||
.inject_dial_upgrade_error(info, ProtocolsHandlerUpgrErr::Timer),
|
||||
(
|
||||
EitherOutput::Second(info),
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)),
|
||||
) => self.proto2.inject_dial_upgrade_error(
|
||||
info,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(err)),
|
||||
),
|
||||
(
|
||||
EitherOutput::Second(info),
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::B(err))),
|
||||
) => self.proto2.inject_dial_upgrade_error(
|
||||
info,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)),
|
||||
),
|
||||
(
|
||||
EitherOutput::Second(_),
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(_))),
|
||||
) => {
|
||||
panic!("Wrong API usage; the upgrade error doesn't match the outbound open info");
|
||||
},
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_listen_upgrade_error(&mut self, (i1, i2): Self::InboundOpenInfo, error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>) {
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
(i1, i2): Self::InboundOpenInfo,
|
||||
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>,
|
||||
) {
|
||||
match error {
|
||||
ProtocolsHandlerUpgrErr::Timer => {
|
||||
self.proto1.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Timer);
|
||||
self.proto2.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Timer)
|
||||
self.proto1
|
||||
.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Timer);
|
||||
self.proto2
|
||||
.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Timer)
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Timeout => {
|
||||
self.proto1.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Timeout);
|
||||
self.proto2.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Timeout)
|
||||
self.proto1
|
||||
.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Timeout);
|
||||
self.proto2
|
||||
.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Timeout)
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) => {
|
||||
self.proto1.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)));
|
||||
self.proto2.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)));
|
||||
self.proto1.inject_listen_upgrade_error(
|
||||
i1,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(
|
||||
NegotiationError::Failed,
|
||||
)),
|
||||
);
|
||||
self.proto2.inject_listen_upgrade_error(
|
||||
i2,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(
|
||||
NegotiationError::Failed,
|
||||
)),
|
||||
);
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::ProtocolError(e))) => {
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(
|
||||
NegotiationError::ProtocolError(e),
|
||||
)) => {
|
||||
let (e1, e2);
|
||||
match e {
|
||||
ProtocolError::IoError(e) => {
|
||||
e1 = NegotiationError::ProtocolError(ProtocolError::IoError(e.kind().into()));
|
||||
e1 = NegotiationError::ProtocolError(ProtocolError::IoError(
|
||||
e.kind().into(),
|
||||
));
|
||||
e2 = NegotiationError::ProtocolError(ProtocolError::IoError(e))
|
||||
}
|
||||
ProtocolError::InvalidMessage => {
|
||||
@ -220,55 +283,80 @@ where
|
||||
e2 = NegotiationError::ProtocolError(ProtocolError::TooManyProtocols)
|
||||
}
|
||||
}
|
||||
self.proto1.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e1)));
|
||||
self.proto2.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e2)))
|
||||
self.proto1.inject_listen_upgrade_error(
|
||||
i1,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e1)),
|
||||
);
|
||||
self.proto2.inject_listen_upgrade_error(
|
||||
i2,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e2)),
|
||||
)
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(e))) => {
|
||||
self.proto1.inject_listen_upgrade_error(i1, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)))
|
||||
self.proto1.inject_listen_upgrade_error(
|
||||
i1,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)),
|
||||
)
|
||||
}
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::B(e))) => {
|
||||
self.proto2.inject_listen_upgrade_error(i2, ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)))
|
||||
self.proto2.inject_listen_upgrade_error(
|
||||
i2,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)),
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn connection_keep_alive(&self) -> KeepAlive {
|
||||
cmp::max(self.proto1.connection_keep_alive(), self.proto2.connection_keep_alive())
|
||||
cmp::max(
|
||||
self.proto1.connection_keep_alive(),
|
||||
self.proto2.connection_keep_alive(),
|
||||
)
|
||||
}
|
||||
|
||||
fn poll(&mut self, cx: &mut Context<'_>) -> Poll<ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>> {
|
||||
fn poll(
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
match self.proto1.poll(cx) {
|
||||
Poll::Ready(ProtocolsHandlerEvent::Custom(event)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Custom(EitherOutput::First(event)));
|
||||
},
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::Close(event)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(EitherError::A(event)));
|
||||
},
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol
|
||||
.map_upgrade(|u| EitherUpgrade::A(SendWrapper(u)))
|
||||
.map_info(EitherOutput::First)
|
||||
.map_info(EitherOutput::First),
|
||||
});
|
||||
},
|
||||
Poll::Pending => ()
|
||||
}
|
||||
Poll::Pending => (),
|
||||
};
|
||||
|
||||
match self.proto2.poll(cx) {
|
||||
Poll::Ready(ProtocolsHandlerEvent::Custom(event)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Custom(EitherOutput::Second(event)));
|
||||
},
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::Close(event)) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::Close(EitherError::B(event)));
|
||||
},
|
||||
}
|
||||
Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest { protocol }) => {
|
||||
return Poll::Ready(ProtocolsHandlerEvent::OutboundSubstreamRequest {
|
||||
protocol: protocol
|
||||
.map_upgrade(|u| EitherUpgrade::B(SendWrapper(u)))
|
||||
.map_info(EitherOutput::Second)
|
||||
.map_info(EitherOutput::Second),
|
||||
});
|
||||
},
|
||||
Poll::Pending => ()
|
||||
}
|
||||
Poll::Pending => (),
|
||||
};
|
||||
|
||||
Poll::Pending
|
||||
|
@ -20,8 +20,8 @@
|
||||
|
||||
use libp2p_core::Multiaddr;
|
||||
use smallvec::SmallVec;
|
||||
use std::{collections::VecDeque, cmp::Ordering, num::NonZeroUsize};
|
||||
use std::ops::{Add, Sub};
|
||||
use std::{cmp::Ordering, collections::VecDeque, num::NonZeroUsize};
|
||||
|
||||
/// A ranked collection of [`Multiaddr`] values.
|
||||
///
|
||||
@ -77,9 +77,7 @@ struct Report {
|
||||
|
||||
impl AddressRecord {
|
||||
fn new(addr: Multiaddr, score: AddressScore) -> Self {
|
||||
AddressRecord {
|
||||
addr, score,
|
||||
}
|
||||
AddressRecord { addr, score }
|
||||
}
|
||||
}
|
||||
|
||||
@ -117,14 +115,10 @@ impl Ord for AddressScore {
|
||||
fn cmp(&self, other: &AddressScore) -> Ordering {
|
||||
// Semantics of cardinal numbers with a single infinite cardinal.
|
||||
match (self, other) {
|
||||
(AddressScore::Infinite, AddressScore::Infinite) =>
|
||||
Ordering::Equal,
|
||||
(AddressScore::Infinite, AddressScore::Finite(_)) =>
|
||||
Ordering::Greater,
|
||||
(AddressScore::Finite(_), AddressScore::Infinite) =>
|
||||
Ordering::Less,
|
||||
(AddressScore::Finite(a), AddressScore::Finite(b)) =>
|
||||
a.cmp(b),
|
||||
(AddressScore::Infinite, AddressScore::Infinite) => Ordering::Equal,
|
||||
(AddressScore::Infinite, AddressScore::Finite(_)) => Ordering::Greater,
|
||||
(AddressScore::Finite(_), AddressScore::Infinite) => Ordering::Less,
|
||||
(AddressScore::Finite(a), AddressScore::Finite(b)) => a.cmp(b),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -135,14 +129,12 @@ impl Add for AddressScore {
|
||||
fn add(self, rhs: AddressScore) -> Self::Output {
|
||||
// Semantics of cardinal numbers with a single infinite cardinal.
|
||||
match (self, rhs) {
|
||||
(AddressScore::Infinite, AddressScore::Infinite) =>
|
||||
AddressScore::Infinite,
|
||||
(AddressScore::Infinite, AddressScore::Finite(_)) =>
|
||||
AddressScore::Infinite,
|
||||
(AddressScore::Finite(_), AddressScore::Infinite) =>
|
||||
AddressScore::Infinite,
|
||||
(AddressScore::Finite(a), AddressScore::Finite(b)) =>
|
||||
(AddressScore::Infinite, AddressScore::Infinite) => AddressScore::Infinite,
|
||||
(AddressScore::Infinite, AddressScore::Finite(_)) => AddressScore::Infinite,
|
||||
(AddressScore::Finite(_), AddressScore::Infinite) => AddressScore::Infinite,
|
||||
(AddressScore::Finite(a), AddressScore::Finite(b)) => {
|
||||
AddressScore::Finite(a.saturating_add(b))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -154,7 +146,7 @@ impl Sub<u32> for AddressScore {
|
||||
// Semantics of cardinal numbers with a single infinite cardinal.
|
||||
match self {
|
||||
AddressScore::Infinite => AddressScore::Infinite,
|
||||
AddressScore::Finite(score) => AddressScore::Finite(score.saturating_sub(rhs))
|
||||
AddressScore::Finite(score) => AddressScore::Finite(score.saturating_sub(rhs)),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -168,8 +160,12 @@ impl Default for Addresses {
|
||||
/// The result of adding an address to an ordered list of
|
||||
/// addresses with associated scores.
|
||||
pub enum AddAddressResult {
|
||||
Inserted { expired: SmallVec<[AddressRecord; 8]> },
|
||||
Updated { expired: SmallVec<[AddressRecord; 8]> },
|
||||
Inserted {
|
||||
expired: SmallVec<[AddressRecord; 8]>,
|
||||
},
|
||||
Updated {
|
||||
expired: SmallVec<[AddressRecord; 8]>,
|
||||
},
|
||||
}
|
||||
|
||||
impl Addresses {
|
||||
@ -207,7 +203,12 @@ impl Addresses {
|
||||
|
||||
// Remove addresses that have a score of 0.
|
||||
let mut expired = SmallVec::new();
|
||||
while self.registry.last().map(|e| e.score.is_zero()).unwrap_or(false) {
|
||||
while self
|
||||
.registry
|
||||
.last()
|
||||
.map(|e| e.score.is_zero())
|
||||
.unwrap_or(false)
|
||||
{
|
||||
if let Some(addr) = self.registry.pop() {
|
||||
expired.push(addr);
|
||||
}
|
||||
@ -215,7 +216,10 @@ impl Addresses {
|
||||
|
||||
// If the address score is finite, remember this report.
|
||||
if let AddressScore::Finite(score) = score {
|
||||
self.reports.push_back(Report { addr: addr.clone(), score });
|
||||
self.reports.push_back(Report {
|
||||
addr: addr.clone(),
|
||||
score,
|
||||
});
|
||||
}
|
||||
|
||||
// If the address is already in the collection, increase its score.
|
||||
@ -223,7 +227,7 @@ impl Addresses {
|
||||
if r.addr == addr {
|
||||
r.score = r.score + score;
|
||||
isort(&mut self.registry);
|
||||
return AddAddressResult::Updated { expired }
|
||||
return AddAddressResult::Updated { expired };
|
||||
}
|
||||
}
|
||||
|
||||
@ -249,14 +253,19 @@ impl Addresses {
|
||||
///
|
||||
/// The iteration is ordered by descending score.
|
||||
pub fn iter(&self) -> AddressIter<'_> {
|
||||
AddressIter { items: &self.registry, offset: 0 }
|
||||
AddressIter {
|
||||
items: &self.registry,
|
||||
offset: 0,
|
||||
}
|
||||
}
|
||||
|
||||
/// Return an iterator over all [`Multiaddr`] values.
|
||||
///
|
||||
/// The iteration is ordered by descending score.
|
||||
pub fn into_iter(self) -> AddressIntoIter {
|
||||
AddressIntoIter { items: self.registry }
|
||||
AddressIntoIter {
|
||||
items: self.registry,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -264,7 +273,7 @@ impl Addresses {
|
||||
#[derive(Clone)]
|
||||
pub struct AddressIter<'a> {
|
||||
items: &'a [AddressRecord],
|
||||
offset: usize
|
||||
offset: usize,
|
||||
}
|
||||
|
||||
impl<'a> Iterator for AddressIter<'a> {
|
||||
@ -272,7 +281,7 @@ impl<'a> Iterator for AddressIter<'a> {
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.offset == self.items.len() {
|
||||
return None
|
||||
return None;
|
||||
}
|
||||
let item = &self.items[self.offset];
|
||||
self.offset += 1;
|
||||
@ -314,10 +323,10 @@ impl ExactSizeIterator for AddressIntoIter {}
|
||||
|
||||
// Reverse insertion sort.
|
||||
fn isort(xs: &mut [AddressRecord]) {
|
||||
for i in 1 .. xs.len() {
|
||||
for j in (1 ..= i).rev() {
|
||||
for i in 1..xs.len() {
|
||||
for j in (1..=i).rev() {
|
||||
if xs[j].score <= xs[j - 1].score {
|
||||
break
|
||||
break;
|
||||
}
|
||||
xs.swap(j, j - 1)
|
||||
}
|
||||
@ -326,15 +335,16 @@ fn isort(xs: &mut [AddressRecord]) {
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use libp2p_core::multiaddr::{Multiaddr, Protocol};
|
||||
use quickcheck::*;
|
||||
use rand::Rng;
|
||||
use std::num::{NonZeroUsize, NonZeroU8};
|
||||
use super::*;
|
||||
use std::num::{NonZeroU8, NonZeroUsize};
|
||||
|
||||
impl Arbitrary for AddressScore {
|
||||
fn arbitrary<G: Gen>(g: &mut G) -> AddressScore {
|
||||
if g.gen_range(0, 10) == 0 { // ~10% "Infinitely" scored addresses
|
||||
if g.gen_range(0, 10) == 0 {
|
||||
// ~10% "Infinitely" scored addresses
|
||||
AddressScore::Infinite
|
||||
} else {
|
||||
AddressScore::Finite(g.gen())
|
||||
@ -353,13 +363,14 @@ mod tests {
|
||||
#[test]
|
||||
fn isort_sorts() {
|
||||
fn property(xs: Vec<AddressScore>) {
|
||||
let mut xs = xs.into_iter()
|
||||
let mut xs = xs
|
||||
.into_iter()
|
||||
.map(|score| AddressRecord::new(Multiaddr::empty(), score))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
isort(&mut xs);
|
||||
|
||||
for i in 1 .. xs.len() {
|
||||
for i in 1..xs.len() {
|
||||
assert!(xs[i - 1].score >= xs[i].score)
|
||||
}
|
||||
}
|
||||
@ -371,7 +382,7 @@ mod tests {
|
||||
fn score_retention() {
|
||||
fn prop(first: AddressRecord, other: AddressRecord) -> TestResult {
|
||||
if first.addr == other.addr {
|
||||
return TestResult::discard()
|
||||
return TestResult::discard();
|
||||
}
|
||||
|
||||
let mut addresses = Addresses::default();
|
||||
@ -383,7 +394,7 @@ mod tests {
|
||||
// Add another address so often that the initial report of
|
||||
// the first address may be purged and, since it was the
|
||||
// only report, the address removed.
|
||||
for _ in 0 .. addresses.limit.get() + 1 {
|
||||
for _ in 0..addresses.limit.get() + 1 {
|
||||
addresses.add(other.addr.clone(), other.score);
|
||||
}
|
||||
|
||||
@ -398,7 +409,7 @@ mod tests {
|
||||
TestResult::passed()
|
||||
}
|
||||
|
||||
quickcheck(prop as fn(_,_) -> _);
|
||||
quickcheck(prop as fn(_, _) -> _);
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -412,16 +423,22 @@ mod tests {
|
||||
}
|
||||
|
||||
// Count the finitely scored addresses.
|
||||
let num_finite = addresses.iter().filter(|r| match r {
|
||||
AddressRecord { score: AddressScore::Finite(_), .. } => true,
|
||||
_ => false,
|
||||
}).count();
|
||||
let num_finite = addresses
|
||||
.iter()
|
||||
.filter(|r| match r {
|
||||
AddressRecord {
|
||||
score: AddressScore::Finite(_),
|
||||
..
|
||||
} => true,
|
||||
_ => false,
|
||||
})
|
||||
.count();
|
||||
|
||||
// Check against the limit.
|
||||
assert!(num_finite <= limit.get() as usize);
|
||||
}
|
||||
|
||||
quickcheck(prop as fn(_,_));
|
||||
quickcheck(prop as fn(_, _));
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -438,16 +455,16 @@ mod tests {
|
||||
|
||||
// Check that each address in the registry has the expected score.
|
||||
for r in &addresses.registry {
|
||||
let expected_score = records.iter().fold(
|
||||
None::<AddressScore>, |sum, rec|
|
||||
if &rec.addr == &r.addr {
|
||||
sum.map_or(Some(rec.score), |s| Some(s + rec.score))
|
||||
} else {
|
||||
sum
|
||||
});
|
||||
let expected_score = records.iter().fold(None::<AddressScore>, |sum, rec| {
|
||||
if &rec.addr == &r.addr {
|
||||
sum.map_or(Some(rec.score), |s| Some(s + rec.score))
|
||||
} else {
|
||||
sum
|
||||
}
|
||||
});
|
||||
|
||||
if Some(r.score) != expected_score {
|
||||
return false
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,17 +19,13 @@
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{
|
||||
NetworkBehaviour,
|
||||
NetworkBehaviourAction,
|
||||
IntoProtocolsHandler, NetworkBehaviour, NetworkBehaviourAction, PollParameters,
|
||||
ProtocolsHandler,
|
||||
IntoProtocolsHandler,
|
||||
PollParameters
|
||||
};
|
||||
use libp2p_core::{
|
||||
ConnectedPoint,
|
||||
PeerId,
|
||||
connection::{ConnectionId, ListenerId},
|
||||
multiaddr::Multiaddr,
|
||||
ConnectedPoint, PeerId,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::task::{Context, Poll};
|
||||
@ -54,7 +50,7 @@ where
|
||||
|
||||
impl<THandler, TOutEvent> MockBehaviour<THandler, TOutEvent>
|
||||
where
|
||||
THandler: ProtocolsHandler
|
||||
THandler: ProtocolsHandler,
|
||||
{
|
||||
pub fn new(handler_proto: THandler) -> Self {
|
||||
MockBehaviour {
|
||||
@ -82,12 +78,13 @@ where
|
||||
self.addresses.get(p).map_or(Vec::new(), |v| v.clone())
|
||||
}
|
||||
|
||||
fn inject_event(&mut self, _: PeerId, _: ConnectionId, _: THandler::OutEvent) {
|
||||
}
|
||||
fn inject_event(&mut self, _: PeerId, _: ConnectionId, _: THandler::OutEvent) {}
|
||||
|
||||
fn poll(&mut self, _: &mut Context, _: &mut impl PollParameters) ->
|
||||
Poll<NetworkBehaviourAction<THandler::InEvent, Self::OutEvent>>
|
||||
{
|
||||
fn poll(
|
||||
&mut self,
|
||||
_: &mut Context,
|
||||
_: &mut impl PollParameters,
|
||||
) -> Poll<NetworkBehaviourAction<THandler::InEvent, Self::OutEvent>> {
|
||||
self.next_action.take().map_or(Poll::Pending, Poll::Ready)
|
||||
}
|
||||
}
|
||||
@ -106,7 +103,11 @@ where
|
||||
pub inject_disconnected: Vec<PeerId>,
|
||||
pub inject_connection_established: Vec<(PeerId, ConnectionId, ConnectedPoint)>,
|
||||
pub inject_connection_closed: Vec<(PeerId, ConnectionId, ConnectedPoint)>,
|
||||
pub inject_event: Vec<(PeerId, ConnectionId, <<TInner::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent)>,
|
||||
pub inject_event: Vec<(
|
||||
PeerId,
|
||||
ConnectionId,
|
||||
<<TInner::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent,
|
||||
)>,
|
||||
pub inject_addr_reach_failure: Vec<(Option<PeerId>, Multiaddr)>,
|
||||
pub inject_dial_failure: Vec<PeerId>,
|
||||
pub inject_new_listener: Vec<ListenerId>,
|
||||
@ -121,7 +122,7 @@ where
|
||||
|
||||
impl<TInner> CallTraceBehaviour<TInner>
|
||||
where
|
||||
TInner: NetworkBehaviour
|
||||
TInner: NetworkBehaviour,
|
||||
{
|
||||
pub fn new(inner: TInner) -> Self {
|
||||
Self {
|
||||
@ -162,13 +163,16 @@ where
|
||||
self.poll = 0;
|
||||
}
|
||||
|
||||
pub fn inner(&mut self) -> &mut TInner { &mut self.inner }
|
||||
pub fn inner(&mut self) -> &mut TInner {
|
||||
&mut self.inner
|
||||
}
|
||||
}
|
||||
|
||||
impl<TInner> NetworkBehaviour for CallTraceBehaviour<TInner>
|
||||
where
|
||||
TInner: NetworkBehaviour,
|
||||
<<TInner::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent: Clone,
|
||||
<<TInner::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent:
|
||||
Clone,
|
||||
{
|
||||
type ProtocolsHandler = TInner::ProtocolsHandler;
|
||||
type OutEvent = TInner::OutEvent;
|
||||
@ -188,7 +192,8 @@ where
|
||||
}
|
||||
|
||||
fn inject_connection_established(&mut self, p: &PeerId, c: &ConnectionId, e: &ConnectedPoint) {
|
||||
self.inject_connection_established.push((p.clone(), c.clone(), e.clone()));
|
||||
self.inject_connection_established
|
||||
.push((p.clone(), c.clone(), e.clone()));
|
||||
self.inner.inject_connection_established(p, c, e);
|
||||
}
|
||||
|
||||
@ -198,16 +203,27 @@ where
|
||||
}
|
||||
|
||||
fn inject_connection_closed(&mut self, p: &PeerId, c: &ConnectionId, e: &ConnectedPoint) {
|
||||
self.inject_connection_closed.push((p.clone(), c.clone(), e.clone()));
|
||||
self.inject_connection_closed
|
||||
.push((p.clone(), c.clone(), e.clone()));
|
||||
self.inner.inject_connection_closed(p, c, e);
|
||||
}
|
||||
|
||||
fn inject_event(&mut self, p: PeerId, c: ConnectionId, e: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent) {
|
||||
fn inject_event(
|
||||
&mut self,
|
||||
p: PeerId,
|
||||
c: ConnectionId,
|
||||
e: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent,
|
||||
) {
|
||||
self.inject_event.push((p.clone(), c.clone(), e.clone()));
|
||||
self.inner.inject_event(p, c, e);
|
||||
}
|
||||
|
||||
fn inject_addr_reach_failure(&mut self, p: Option<&PeerId>, a: &Multiaddr, e: &dyn std::error::Error) {
|
||||
fn inject_addr_reach_failure(
|
||||
&mut self,
|
||||
p: Option<&PeerId>,
|
||||
a: &Multiaddr,
|
||||
e: &dyn std::error::Error,
|
||||
) {
|
||||
self.inject_addr_reach_failure.push((p.cloned(), a.clone()));
|
||||
self.inner.inject_addr_reach_failure(p, a, e);
|
||||
}
|
||||
|
@ -18,24 +18,20 @@
|
||||
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
// DEALINGS IN THE SOFTWARE.
|
||||
|
||||
use crate::{NetworkBehaviour, NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters};
|
||||
use crate::upgrade::{SendWrapper, InboundUpgradeSend, OutboundUpgradeSend};
|
||||
use crate::protocols_handler::{
|
||||
KeepAlive,
|
||||
SubstreamProtocol,
|
||||
ProtocolsHandler,
|
||||
ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr,
|
||||
IntoProtocolsHandler
|
||||
IntoProtocolsHandler, KeepAlive, ProtocolsHandler, ProtocolsHandlerEvent,
|
||||
ProtocolsHandlerUpgrErr, SubstreamProtocol,
|
||||
};
|
||||
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, SendWrapper};
|
||||
use crate::{
|
||||
NetworkBehaviour, NetworkBehaviourAction, NetworkBehaviourEventProcess, PollParameters,
|
||||
};
|
||||
use either::Either;
|
||||
use libp2p_core::{
|
||||
ConnectedPoint,
|
||||
PeerId,
|
||||
Multiaddr,
|
||||
connection::{ConnectionId, ListenerId},
|
||||
either::{EitherError, EitherOutput},
|
||||
upgrade::{DeniedUpgrade, EitherUpgrade}
|
||||
upgrade::{DeniedUpgrade, EitherUpgrade},
|
||||
ConnectedPoint, Multiaddr, PeerId,
|
||||
};
|
||||
use std::{error, task::Context, task::Poll};
|
||||
|
||||
@ -71,19 +67,22 @@ impl<TBehaviour> From<Option<TBehaviour>> for Toggle<TBehaviour> {
|
||||
|
||||
impl<TBehaviour> NetworkBehaviour for Toggle<TBehaviour>
|
||||
where
|
||||
TBehaviour: NetworkBehaviour
|
||||
TBehaviour: NetworkBehaviour,
|
||||
{
|
||||
type ProtocolsHandler = ToggleIntoProtoHandler<TBehaviour::ProtocolsHandler>;
|
||||
type OutEvent = TBehaviour::OutEvent;
|
||||
|
||||
fn new_handler(&mut self) -> Self::ProtocolsHandler {
|
||||
ToggleIntoProtoHandler {
|
||||
inner: self.inner.as_mut().map(|i| i.new_handler())
|
||||
inner: self.inner.as_mut().map(|i| i.new_handler()),
|
||||
}
|
||||
}
|
||||
|
||||
fn addresses_of_peer(&mut self, peer_id: &PeerId) -> Vec<Multiaddr> {
|
||||
self.inner.as_mut().map(|b| b.addresses_of_peer(peer_id)).unwrap_or_else(Vec::new)
|
||||
self.inner
|
||||
.as_mut()
|
||||
.map(|b| b.addresses_of_peer(peer_id))
|
||||
.unwrap_or_else(Vec::new)
|
||||
}
|
||||
|
||||
fn inject_connected(&mut self, peer_id: &PeerId) {
|
||||
@ -98,19 +97,35 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_connection_established(&mut self, peer_id: &PeerId, connection: &ConnectionId, endpoint: &ConnectedPoint) {
|
||||
fn inject_connection_established(
|
||||
&mut self,
|
||||
peer_id: &PeerId,
|
||||
connection: &ConnectionId,
|
||||
endpoint: &ConnectedPoint,
|
||||
) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_connection_established(peer_id, connection, endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_connection_closed(&mut self, peer_id: &PeerId, connection: &ConnectionId, endpoint: &ConnectedPoint) {
|
||||
fn inject_connection_closed(
|
||||
&mut self,
|
||||
peer_id: &PeerId,
|
||||
connection: &ConnectionId,
|
||||
endpoint: &ConnectedPoint,
|
||||
) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_connection_closed(peer_id, connection, endpoint)
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_address_change(&mut self, peer_id: &PeerId, connection: &ConnectionId, old: &ConnectedPoint, new: &ConnectedPoint) {
|
||||
fn inject_address_change(
|
||||
&mut self,
|
||||
peer_id: &PeerId,
|
||||
connection: &ConnectionId,
|
||||
old: &ConnectedPoint,
|
||||
new: &ConnectedPoint,
|
||||
) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_address_change(peer_id, connection, old, new)
|
||||
}
|
||||
@ -120,14 +135,19 @@ where
|
||||
&mut self,
|
||||
peer_id: PeerId,
|
||||
connection: ConnectionId,
|
||||
event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent
|
||||
event: <<Self::ProtocolsHandler as IntoProtocolsHandler>::Handler as ProtocolsHandler>::OutEvent,
|
||||
) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_event(peer_id, connection, event);
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_addr_reach_failure(&mut self, peer_id: Option<&PeerId>, addr: &Multiaddr, error: &dyn error::Error) {
|
||||
fn inject_addr_reach_failure(
|
||||
&mut self,
|
||||
peer_id: Option<&PeerId>,
|
||||
addr: &Multiaddr,
|
||||
error: &dyn error::Error,
|
||||
) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.inject_addr_reach_failure(peer_id, addr, error)
|
||||
}
|
||||
@ -194,7 +214,7 @@ where
|
||||
|
||||
impl<TEvent, TBehaviour> NetworkBehaviourEventProcess<TEvent> for Toggle<TBehaviour>
|
||||
where
|
||||
TBehaviour: NetworkBehaviourEventProcess<TEvent>
|
||||
TBehaviour: NetworkBehaviourEventProcess<TEvent>,
|
||||
{
|
||||
fn inject_event(&mut self, event: TEvent) {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
@ -210,13 +230,19 @@ pub struct ToggleIntoProtoHandler<TInner> {
|
||||
|
||||
impl<TInner> IntoProtocolsHandler for ToggleIntoProtoHandler<TInner>
|
||||
where
|
||||
TInner: IntoProtocolsHandler
|
||||
TInner: IntoProtocolsHandler,
|
||||
{
|
||||
type Handler = ToggleProtoHandler<TInner::Handler>;
|
||||
|
||||
fn into_handler(self, remote_peer_id: &PeerId, connected_point: &ConnectedPoint) -> Self::Handler {
|
||||
fn into_handler(
|
||||
self,
|
||||
remote_peer_id: &PeerId,
|
||||
connected_point: &ConnectedPoint,
|
||||
) -> Self::Handler {
|
||||
ToggleProtoHandler {
|
||||
inner: self.inner.map(|h| h.into_handler(remote_peer_id, connected_point))
|
||||
inner: self
|
||||
.inner
|
||||
.map(|h| h.into_handler(remote_peer_id, connected_point)),
|
||||
}
|
||||
}
|
||||
|
||||
@ -241,25 +267,30 @@ where
|
||||
type InEvent = TInner::InEvent;
|
||||
type OutEvent = TInner::OutEvent;
|
||||
type Error = TInner::Error;
|
||||
type InboundProtocol = EitherUpgrade<SendWrapper<TInner::InboundProtocol>, SendWrapper<DeniedUpgrade>>;
|
||||
type InboundProtocol =
|
||||
EitherUpgrade<SendWrapper<TInner::InboundProtocol>, SendWrapper<DeniedUpgrade>>;
|
||||
type OutboundProtocol = TInner::OutboundProtocol;
|
||||
type OutboundOpenInfo = TInner::OutboundOpenInfo;
|
||||
type InboundOpenInfo = Either<TInner::InboundOpenInfo, ()>;
|
||||
|
||||
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol, Self::InboundOpenInfo> {
|
||||
if let Some(inner) = self.inner.as_ref() {
|
||||
inner.listen_protocol()
|
||||
inner
|
||||
.listen_protocol()
|
||||
.map_upgrade(|u| EitherUpgrade::A(SendWrapper(u)))
|
||||
.map_info(Either::Left)
|
||||
} else {
|
||||
SubstreamProtocol::new(EitherUpgrade::B(SendWrapper(DeniedUpgrade)), Either::Right(()))
|
||||
SubstreamProtocol::new(
|
||||
EitherUpgrade::B(SendWrapper(DeniedUpgrade)),
|
||||
Either::Right(()),
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_fully_negotiated_inbound(
|
||||
&mut self,
|
||||
out: <Self::InboundProtocol as InboundUpgradeSend>::Output,
|
||||
info: Self::InboundOpenInfo
|
||||
info: Self::InboundOpenInfo,
|
||||
) {
|
||||
let out = match out {
|
||||
EitherOutput::First(out) => out,
|
||||
@ -267,7 +298,8 @@ where
|
||||
};
|
||||
|
||||
if let Either::Left(info) = info {
|
||||
self.inner.as_mut()
|
||||
self.inner
|
||||
.as_mut()
|
||||
.expect("Can't receive an inbound substream if disabled; QED")
|
||||
.inject_fully_negotiated_inbound(out, info)
|
||||
} else {
|
||||
@ -278,14 +310,18 @@ where
|
||||
fn inject_fully_negotiated_outbound(
|
||||
&mut self,
|
||||
out: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
|
||||
info: Self::OutboundOpenInfo
|
||||
info: Self::OutboundOpenInfo,
|
||||
) {
|
||||
self.inner.as_mut().expect("Can't receive an outbound substream if disabled; QED")
|
||||
self.inner
|
||||
.as_mut()
|
||||
.expect("Can't receive an outbound substream if disabled; QED")
|
||||
.inject_fully_negotiated_outbound(out, info)
|
||||
}
|
||||
|
||||
fn inject_event(&mut self, event: Self::InEvent) {
|
||||
self.inner.as_mut().expect("Can't receive events if disabled; QED")
|
||||
self.inner
|
||||
.as_mut()
|
||||
.expect("Can't receive events if disabled; QED")
|
||||
.inject_event(event)
|
||||
}
|
||||
|
||||
@ -295,12 +331,22 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
fn inject_dial_upgrade_error(&mut self, info: Self::OutboundOpenInfo, err: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>) {
|
||||
self.inner.as_mut().expect("Can't receive an outbound substream if disabled; QED")
|
||||
fn inject_dial_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::OutboundOpenInfo,
|
||||
err: ProtocolsHandlerUpgrErr<<Self::OutboundProtocol as OutboundUpgradeSend>::Error>,
|
||||
) {
|
||||
self.inner
|
||||
.as_mut()
|
||||
.expect("Can't receive an outbound substream if disabled; QED")
|
||||
.inject_dial_upgrade_error(info, err)
|
||||
}
|
||||
|
||||
fn inject_listen_upgrade_error(&mut self, info: Self::InboundOpenInfo, err: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>) {
|
||||
fn inject_listen_upgrade_error(
|
||||
&mut self,
|
||||
info: Self::InboundOpenInfo,
|
||||
err: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>,
|
||||
) {
|
||||
let (inner, info) = match (self.inner.as_mut(), info) {
|
||||
(Some(inner), Either::Left(info)) => (inner, info),
|
||||
// Ignore listen upgrade errors in disabled state.
|
||||
@ -313,24 +359,26 @@ where
|
||||
"Unexpected `Either::Left` inbound info through \
|
||||
`inject_listen_upgrade_error` in disabled state.",
|
||||
),
|
||||
|
||||
};
|
||||
|
||||
let err = match err {
|
||||
ProtocolsHandlerUpgrErr::Timeout => ProtocolsHandlerUpgrErr::Timeout,
|
||||
ProtocolsHandlerUpgrErr::Timer => ProtocolsHandlerUpgrErr::Timer,
|
||||
ProtocolsHandlerUpgrErr::Upgrade(err) =>
|
||||
ProtocolsHandlerUpgrErr::Upgrade(err) => {
|
||||
ProtocolsHandlerUpgrErr::Upgrade(err.map_err(|err| match err {
|
||||
EitherError::A(e) => e,
|
||||
EitherError::B(v) => void::unreachable(v)
|
||||
EitherError::B(v) => void::unreachable(v),
|
||||
}))
|
||||
}
|
||||
};
|
||||
|
||||
inner.inject_listen_upgrade_error(info, err)
|
||||
}
|
||||
|
||||
fn connection_keep_alive(&self) -> KeepAlive {
|
||||
self.inner.as_ref().map(|h| h.connection_keep_alive())
|
||||
self.inner
|
||||
.as_ref()
|
||||
.map(|h| h.connection_keep_alive())
|
||||
.unwrap_or(KeepAlive::No)
|
||||
}
|
||||
|
||||
@ -338,7 +386,12 @@ where
|
||||
&mut self,
|
||||
cx: &mut Context<'_>,
|
||||
) -> Poll<
|
||||
ProtocolsHandlerEvent<Self::OutboundProtocol, Self::OutboundOpenInfo, Self::OutEvent, Self::Error>
|
||||
ProtocolsHandlerEvent<
|
||||
Self::OutboundProtocol,
|
||||
Self::OutboundOpenInfo,
|
||||
Self::OutEvent,
|
||||
Self::Error,
|
||||
>,
|
||||
> {
|
||||
if let Some(inner) = self.inner.as_mut() {
|
||||
inner.poll(cx)
|
||||
@ -369,9 +422,7 @@ mod tests {
|
||||
/// [`ToggleProtoHandler`] should ignore the error in both of these cases.
|
||||
#[test]
|
||||
fn ignore_listen_upgrade_error_when_disabled() {
|
||||
let mut handler = ToggleProtoHandler::<DummyProtocolsHandler> {
|
||||
inner: None,
|
||||
};
|
||||
let mut handler = ToggleProtoHandler::<DummyProtocolsHandler> { inner: None };
|
||||
|
||||
handler.inject_listen_upgrade_error(Either::Right(()), ProtocolsHandlerUpgrErr::Timeout);
|
||||
}
|
||||
|
Reference in New Issue
Block a user