Implement ProtocolsHandler methods in wrappers. (#1710)

* Implement ProtocolsHandler methods in wrappers.

This PR forwards calls to some ProtocolsHandler methods that were
previously not implemented in wrappers such as `MapInEvent`.

It is unclear though how this can be implemented in some handlers
such as `MultiHandler` as the information at hand does not enable
it to decide which handler to forward the call to.

* Add `MultiHandler::inject_listen_ugrade_error`.
This commit is contained in:
Toralf Wittner
2020-08-18 16:27:02 +02:00
committed by GitHub
parent cbdbf656c0
commit 21f9447796
7 changed files with 169 additions and 40 deletions

View File

@ -26,7 +26,7 @@ use crate::protocols_handler::{
ProtocolsHandlerEvent,
ProtocolsHandlerUpgrErr
};
use libp2p_core::upgrade::{InboundUpgrade, OutboundUpgrade, DeniedUpgrade};
use libp2p_core::{Multiaddr, upgrade::{InboundUpgrade, OutboundUpgrade, DeniedUpgrade}};
use std::task::{Context, Poll};
use void::Void;
@ -71,8 +71,12 @@ impl ProtocolsHandler for DummyProtocolsHandler {
fn inject_event(&mut self, _: Self::InEvent) {}
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_listen_upgrade_error(&mut self, _: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgrade<NegotiatedSubstream>>::Error>) {}
fn connection_keep_alive(&self) -> KeepAlive {
self.keep_alive
}

View File

@ -26,7 +26,7 @@ use crate::protocols_handler::{
ProtocolsHandlerEvent,
ProtocolsHandlerUpgrErr
};
use libp2p_core::Multiaddr;
use std::{marker::PhantomData, task::Context, task::Poll};
/// Wrapper around a protocol handler that turns the input event into something else.
@ -38,7 +38,6 @@ pub struct MapInEvent<TProtoHandler, TNewIn, TMap> {
impl<TProtoHandler, TMap, TNewIn> MapInEvent<TProtoHandler, TNewIn, TMap> {
/// Creates a `MapInEvent`.
#[inline]
pub(crate) fn new(inner: TProtoHandler, map: TMap) -> Self {
MapInEvent {
inner,
@ -62,12 +61,10 @@ where
type OutboundProtocol = TProtoHandler::OutboundProtocol;
type OutboundOpenInfo = TProtoHandler::OutboundOpenInfo;
#[inline]
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
self.inner.listen_protocol()
}
#[inline]
fn inject_fully_negotiated_inbound(
&mut self,
protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output
@ -75,7 +72,6 @@ where
self.inner.inject_fully_negotiated_inbound(protocol)
}
#[inline]
fn inject_fully_negotiated_outbound(
&mut self,
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
@ -84,24 +80,31 @@ where
self.inner.inject_fully_negotiated_outbound(protocol, info)
}
#[inline]
fn inject_event(&mut self, event: TNewIn) {
if let Some(event) = (self.map)(event) {
self.inner.inject_event(event);
}
}
#[inline]
fn inject_address_change(&mut self, addr: &Multiaddr) {
self.inner.inject_address_change(addr)
}
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)
}
#[inline]
fn inject_listen_upgrade_error(
&mut self,
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>
) {
self.inner.inject_listen_upgrade_error(error)
}
fn connection_keep_alive(&self) -> KeepAlive {
self.inner.connection_keep_alive()
}
#[inline]
fn poll(
&mut self,
cx: &mut Context<'_>,

View File

@ -26,7 +26,7 @@ use crate::protocols_handler::{
ProtocolsHandlerEvent,
ProtocolsHandlerUpgrErr
};
use libp2p_core::Multiaddr;
use std::task::{Context, Poll};
/// Wrapper around a protocol handler that turns the output event into something else.
@ -37,7 +37,6 @@ pub struct MapOutEvent<TProtoHandler, TMap> {
impl<TProtoHandler, TMap> MapOutEvent<TProtoHandler, TMap> {
/// Creates a `MapOutEvent`.
#[inline]
pub(crate) fn new(inner: TProtoHandler, map: TMap) -> Self {
MapOutEvent {
inner,
@ -60,12 +59,10 @@ where
type OutboundProtocol = TProtoHandler::OutboundProtocol;
type OutboundOpenInfo = TProtoHandler::OutboundOpenInfo;
#[inline]
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
self.inner.listen_protocol()
}
#[inline]
fn inject_fully_negotiated_inbound(
&mut self,
protocol: <Self::InboundProtocol as InboundUpgradeSend>::Output
@ -73,7 +70,6 @@ where
self.inner.inject_fully_negotiated_inbound(protocol)
}
#[inline]
fn inject_fully_negotiated_outbound(
&mut self,
protocol: <Self::OutboundProtocol as OutboundUpgradeSend>::Output,
@ -82,22 +78,29 @@ where
self.inner.inject_fully_negotiated_outbound(protocol, info)
}
#[inline]
fn inject_event(&mut self, event: Self::InEvent) {
self.inner.inject_event(event)
}
#[inline]
fn inject_address_change(&mut self, addr: &Multiaddr) {
self.inner.inject_address_change(addr)
}
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)
}
#[inline]
fn inject_listen_upgrade_error(
&mut self,
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>
) {
self.inner.inject_listen_upgrade_error(error)
}
fn connection_keep_alive(&self) -> KeepAlive {
self.inner.connection_keep_alive()
}
#[inline]
fn poll(
&mut self,
cx: &mut Context<'_>,

View File

@ -36,7 +36,8 @@ use crate::upgrade::{
UpgradeInfoSend
};
use futures::{future::BoxFuture, prelude::*};
use libp2p_core::{ConnectedPoint, PeerId, upgrade::ProtocolName};
use libp2p_core::{ConnectedPoint, Multiaddr, PeerId};
use libp2p_core::upgrade::{ProtocolName, UpgradeError, NegotiationError, ProtocolError};
use rand::Rng;
use std::{
collections::{HashMap, HashSet},
@ -135,6 +136,12 @@ where
}
}
fn inject_address_change(&mut self, addr: &Multiaddr) {
for h in self.handlers.values_mut() {
h.inject_address_change(addr)
}
}
fn inject_dial_upgrade_error (
&mut self,
(key, arg): Self::OutboundOpenInfo,
@ -147,6 +154,53 @@ where
}
}
fn inject_listen_upgrade_error(
&mut self,
error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>
) {
match error {
ProtocolsHandlerUpgrErr::Timer =>
for h in self.handlers.values_mut() {
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Timer)
}
ProtocolsHandlerUpgrErr::Timeout =>
for h in self.handlers.values_mut() {
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Timeout)
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) =>
for h in self.handlers.values_mut() {
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)))
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::ProtocolError(e))) =>
match e {
ProtocolError::IoError(e) =>
for h in self.handlers.values_mut() {
let e = NegotiationError::ProtocolError(ProtocolError::IoError(e.kind().into()));
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
}
ProtocolError::InvalidMessage =>
for h in self.handlers.values_mut() {
let e = NegotiationError::ProtocolError(ProtocolError::InvalidMessage);
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
}
ProtocolError::InvalidProtocol =>
for h in self.handlers.values_mut() {
let e = NegotiationError::ProtocolError(ProtocolError::InvalidProtocol);
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
}
ProtocolError::TooManyProtocols =>
for h in self.handlers.values_mut() {
let e = NegotiationError::ProtocolError(ProtocolError::TooManyProtocols);
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e)))
}
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply((k, e))) =>
if let Some(h) = self.handlers.get_mut(&k) {
h.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)))
}
}
}
fn connection_keep_alive(&self) -> KeepAlive {
self.handlers.values()
.map(|h| h.connection_keep_alive())

View File

@ -30,9 +30,10 @@ use crate::protocols_handler::{
use libp2p_core::{
ConnectedPoint,
Multiaddr,
PeerId,
either::{EitherError, EitherOutput},
upgrade::{EitherUpgrade, SelectUpgrade, UpgradeError}
upgrade::{EitherUpgrade, SelectUpgrade, UpgradeError, NegotiationError, ProtocolError}
};
use std::{cmp, task::Context, task::Poll};
@ -47,7 +48,6 @@ pub struct IntoProtocolsHandlerSelect<TProto1, TProto2> {
impl<TProto1, TProto2> IntoProtocolsHandlerSelect<TProto1, TProto2> {
/// Builds a `IntoProtocolsHandlerSelect`.
#[inline]
pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self {
IntoProtocolsHandlerSelect {
proto1,
@ -86,7 +86,6 @@ pub struct ProtocolsHandlerSelect<TProto1, TProto2> {
impl<TProto1, TProto2> ProtocolsHandlerSelect<TProto1, TProto2> {
/// Builds a `ProtocolsHandlerSelect`.
#[inline]
pub(crate) fn new(proto1: TProto1, proto2: TProto2) -> Self {
ProtocolsHandlerSelect {
proto1,
@ -107,7 +106,6 @@ where
type OutboundProtocol = EitherUpgrade<SendWrapper<TProto1::OutboundProtocol>, SendWrapper<TProto2::OutboundProtocol>>;
type OutboundOpenInfo = EitherOutput<TProto1::OutboundOpenInfo, TProto2::OutboundOpenInfo>;
#[inline]
fn listen_protocol(&self) -> SubstreamProtocol<Self::InboundProtocol> {
let proto1 = self.proto1.listen_protocol();
let proto2 = self.proto2.listen_protocol();
@ -138,7 +136,6 @@ where
}
}
#[inline]
fn inject_event(&mut self, event: Self::InEvent) {
match event {
EitherOutput::First(event) => self.proto1.inject_event(event),
@ -146,7 +143,11 @@ where
}
}
#[inline]
fn inject_address_change(&mut self, addr: &Multiaddr) {
self.proto1.inject_address_change(addr);
self.proto2.inject_address_change(addr)
}
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) => {
@ -182,7 +183,52 @@ where
}
}
#[inline]
fn inject_listen_upgrade_error(&mut self, error: ProtocolsHandlerUpgrErr<<Self::InboundProtocol as InboundUpgradeSend>::Error>) {
match error {
ProtocolsHandlerUpgrErr::Timer => {
self.proto1.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Timer);
self.proto2.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Timer);
}
ProtocolsHandlerUpgrErr::Timeout => {
self.proto1.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Timeout);
self.proto2.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Timeout);
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) => {
self.proto1.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)));
self.proto2.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)));
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::ProtocolError(e))) => {
let (e1, e2);
match e {
ProtocolError::IoError(e) => {
e1 = NegotiationError::ProtocolError(ProtocolError::IoError(e.kind().into()));
e2 = NegotiationError::ProtocolError(ProtocolError::IoError(e))
}
ProtocolError::InvalidMessage => {
e1 = NegotiationError::ProtocolError(ProtocolError::InvalidMessage);
e2 = NegotiationError::ProtocolError(ProtocolError::InvalidMessage)
}
ProtocolError::InvalidProtocol => {
e1 = NegotiationError::ProtocolError(ProtocolError::InvalidProtocol);
e2 = NegotiationError::ProtocolError(ProtocolError::InvalidProtocol)
}
ProtocolError::TooManyProtocols => {
e1 = NegotiationError::ProtocolError(ProtocolError::TooManyProtocols);
e2 = NegotiationError::ProtocolError(ProtocolError::TooManyProtocols)
}
}
self.proto1.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e1)));
self.proto2.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Select(e2)))
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::A(e))) => {
self.proto1.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)))
}
ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(EitherError::B(e))) => {
self.proto2.inject_listen_upgrade_error(ProtocolsHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)))
}
}
}
fn connection_keep_alive(&self) -> KeepAlive {
cmp::max(self.proto1.connection_keep_alive(), self.proto2.connection_keep_alive())
}