feat: don't report inbound stream upgrade errors to handler

When an inbound stream upgrade fails, there isn't a whole lot we can do about that in the handler. In fact, for several errors, we wouldn't even know which specific handler to target, for example, `NegotiationFailed`. Similiarly, in case of an IO error during the upgrade, we don't know which handler the stream was eventually meant to be for.

Pull-Request: #3605.
This commit is contained in:
Thomas Eizinger
2023-05-08 06:54:50 +02:00
committed by GitHub
parent 2130923aa5
commit 53e5370919
21 changed files with 90 additions and 553 deletions

View File

@ -25,10 +25,9 @@ use crate::handler::{
InboundUpgradeSend, KeepAlive, ListenUpgradeError, SubstreamProtocol,
};
use crate::upgrade::SendWrapper;
use crate::ConnectionHandlerUpgrErr;
use either::Either;
use futures::future;
use libp2p_core::{ConnectedPoint, UpgradeError};
use libp2p_core::ConnectedPoint;
use libp2p_identity::PeerId;
use std::task::{Context, Poll};
@ -125,61 +124,13 @@ where
fn transpose(self) -> Either<ListenUpgradeError<LIOI, LIP>, ListenUpgradeError<RIOI, RIP>> {
match self {
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(error))),
error: Either::Left(error),
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(error)),
info,
}),
} => Either::Left(ListenUpgradeError { error, info }),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(error))),
error: Either::Right(error),
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(error)),
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timer,
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info: Either::Left(info),
} => Either::Left(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info,
}),
ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info: Either::Right(info),
} => Either::Right(ListenUpgradeError {
error: ConnectionHandlerUpgrErr::Timeout,
info,
}),
} => Either::Right(ListenUpgradeError { error, info }),
_ => unreachable!(),
}
}

View File

@ -24,14 +24,13 @@
#[allow(deprecated)]
use crate::handler::IntoConnectionHandler;
use crate::handler::{
AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent,
ConnectionHandlerUpgrErr, DialUpgradeError, FullyNegotiatedInbound, FullyNegotiatedOutbound,
KeepAlive, ListenUpgradeError, SubstreamProtocol,
AddressChange, ConnectionEvent, ConnectionHandler, ConnectionHandlerEvent, DialUpgradeError,
FullyNegotiatedInbound, FullyNegotiatedOutbound, KeepAlive, ListenUpgradeError,
SubstreamProtocol,
};
use crate::upgrade::{InboundUpgradeSend, OutboundUpgradeSend, UpgradeInfoSend};
use crate::NegotiatedSubstream;
use futures::{future::BoxFuture, prelude::*};
use libp2p_core::upgrade::{NegotiationError, ProtocolError, UpgradeError};
use libp2p_core::ConnectedPoint;
use libp2p_identity::PeerId;
use rand::Rng;
@ -89,128 +88,20 @@ where
fn on_listen_upgrade_error(
&mut self,
ListenUpgradeError { error, mut info }: ListenUpgradeError<
ListenUpgradeError {
error: (key, error),
mut info,
}: ListenUpgradeError<
<Self as ConnectionHandler>::InboundOpenInfo,
<Self as ConnectionHandler>::InboundProtocol,
>,
) {
match error {
ConnectionHandlerUpgrErr::Timer => {
for (k, h) in &mut self.handlers {
if let Some(i) = info.take(k) {
h.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::Timer,
},
));
}
}
}
ConnectionHandlerUpgrErr::Timeout => {
for (k, h) in &mut self.handlers {
if let Some(i) = info.take(k) {
h.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::Timeout,
},
));
}
}
}
ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) => {
for (k, h) in &mut self.handlers {
if let Some(i) = info.take(k) {
h.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(
NegotiationError::Failed,
)),
},
));
}
}
}
ConnectionHandlerUpgrErr::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.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::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.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::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.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::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.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(
e,
)),
},
));
}
}
}
},
ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply((k, e))) => {
if let Some(h) = self.handlers.get_mut(&k) {
if let Some(i) = info.take(&k) {
h.on_connection_event(ConnectionEvent::ListenUpgradeError(
ListenUpgradeError {
info: i,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)),
},
));
}
}
if let Some(h) = self.handlers.get_mut(&key) {
if let Some(i) = info.take(&key) {
h.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i,
error,
}));
}
}
}

View File

@ -29,7 +29,7 @@ use crate::upgrade::SendWrapper;
use either::Either;
use futures::future;
use libp2p_core::{
upgrade::{NegotiationError, ProtocolError, SelectUpgrade, UpgradeError},
upgrade::{SelectUpgrade, UpgradeError},
ConnectedPoint,
};
use libp2p_identity::PeerId;
@ -161,13 +161,6 @@ where
self,
) -> Either<DialUpgradeError<S1OOI, S1OP>, DialUpgradeError<S2OOI, S2OP>> {
match self {
DialUpgradeError {
info: Either::Left(info),
error: ConnectionHandlerUpgrErr::Timer,
} => Either::Left(DialUpgradeError {
info,
error: ConnectionHandlerUpgrErr::Timer,
}),
DialUpgradeError {
info: Either::Left(info),
error: ConnectionHandlerUpgrErr::Timeout,
@ -189,13 +182,6 @@ where
info,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(err)),
}),
DialUpgradeError {
info: Either::Right(info),
error: ConnectionHandlerUpgrErr::Timer,
} => Either::Right(DialUpgradeError {
info,
error: ConnectionHandlerUpgrErr::Timer,
}),
DialUpgradeError {
info: Either::Right(info),
error: ConnectionHandlerUpgrErr::Timeout,
@ -238,96 +224,18 @@ where
>,
) {
match error {
ConnectionHandlerUpgrErr::Timer => {
Either::Left(error) => {
self.proto1
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i1,
error: ConnectionHandlerUpgrErr::Timer,
error,
}));
}
Either::Right(error) => {
self.proto2
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i2,
error: ConnectionHandlerUpgrErr::Timer,
}));
}
ConnectionHandlerUpgrErr::Timeout => {
self.proto1
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i1,
error: ConnectionHandlerUpgrErr::Timeout,
}));
self.proto2
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i2,
error: ConnectionHandlerUpgrErr::Timeout,
}));
}
ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(NegotiationError::Failed)) => {
self.proto1
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i1,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(
NegotiationError::Failed,
)),
}));
self.proto2
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i2,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(
NegotiationError::Failed,
)),
}));
}
ConnectionHandlerUpgrErr::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
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i1,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(e1)),
}));
self.proto2
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i2,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Select(e2)),
}));
}
ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Left(e))) => {
self.proto1
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i1,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)),
}));
}
ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(Either::Right(e))) => {
self.proto2
.on_connection_event(ConnectionEvent::ListenUpgradeError(ListenUpgradeError {
info: i2,
error: ConnectionHandlerUpgrErr::Upgrade(UpgradeError::Apply(e)),
error,
}));
}
}