diff --git a/CHANGELOG.md b/CHANGELOG.md index d569eb90e5c..9415d741e20 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -45,7 +45,7 @@ - Use `libp2p-swarm-derive`, the former `libp2p-core-derive`. -- Update `libp2p-gossipsub` and `libp2p-request-response`. +- Update `libp2p-gossipsub`, `libp2p-request-response` and `libp2p-swarm`. ## Version 0.34.0 [2021-01-12] diff --git a/Cargo.toml b/Cargo.toml index 5939dc79691..9b820a59110 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -72,7 +72,7 @@ libp2p-ping = { version = "0.27.0", path = "protocols/ping", optional = true } libp2p-plaintext = { version = "0.27.0", path = "transports/plaintext", optional = true } libp2p-pnet = { version = "0.20.0", path = "transports/pnet", optional = true } libp2p-request-response = { version = "0.9.1", path = "protocols/request-response", optional = true } -libp2p-swarm = { version = "0.27.1", path = "swarm" } +libp2p-swarm = { version = "0.27.2", path = "swarm" } libp2p-swarm-derive = { version = "0.22.0", path = "swarm-derive" } libp2p-uds = { version = "0.27.0", path = "transports/uds", optional = true } libp2p-wasm-ext = { version = "0.27.0", path = "transports/wasm-ext", optional = true } diff --git a/swarm/CHANGELOG.md b/swarm/CHANGELOG.md index a8e0399978c..169277984a0 100644 --- a/swarm/CHANGELOG.md +++ b/swarm/CHANGELOG.md @@ -1,3 +1,8 @@ +# 0.27.2 [2021-02-04] + +- Have `ToggleProtoHandler` ignore listen upgrade errors when disabled. + [PR 1945](https://github.com/libp2p/rust-libp2p/pull/1945/files). + # 0.27.1 [2021-01-27] - Make `OneShotHandler`s `max_dial_negotiate` limit configurable. diff --git a/swarm/Cargo.toml b/swarm/Cargo.toml index 60a2526fb15..33b410ceb58 100644 --- a/swarm/Cargo.toml +++ b/swarm/Cargo.toml @@ -2,7 +2,7 @@ name = "libp2p-swarm" edition = "2018" description = "The libp2p swarm" -version = "0.27.1" +version = "0.27.2" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/swarm/src/toggle.rs b/swarm/src/toggle.rs index bb9011261ad..cf58ad91e25 100644 --- a/swarm/src/toggle.rs +++ b/swarm/src/toggle.rs @@ -271,6 +271,21 @@ where } fn inject_listen_upgrade_error(&mut self, info: Self::InboundOpenInfo, err: ProtocolsHandlerUpgrErr<::Error>) { + let (inner, info) = match (self.inner.as_mut(), info) { + (Some(inner), Either::Left(info)) => (inner, info), + // Ignore listen upgrade errors in disabled state. + (None, Either::Right(())) => return, + (Some(_), Either::Right(())) => panic!( + "Unexpected `Either::Right` inbound info through \ + `inject_listen_upgrade_error` in enabled state.", + ), + (None, Either::Left(_)) => panic!( + "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, @@ -280,13 +295,8 @@ where EitherError::B(v) => void::unreachable(v) })) }; - if let Either::Left(info) = info { - self.inner.as_mut() - .expect("Can't receive an inbound substream if disabled; QED") - .inject_listen_upgrade_error(info, err) - } else { - panic!("Unexpected Either::Right on enabled `inject_listen_upgrade_error`.") - } + + inner.inject_listen_upgrade_error(info, err) } fn connection_keep_alive(&self) -> KeepAlive { @@ -307,3 +317,32 @@ where } } } + +#[cfg(test)] +mod tests { + use super::*; + use crate::protocols_handler::DummyProtocolsHandler; + + /// A disabled [`ToggleProtoHandler`] can receive listen upgrade errors in + /// the following two cases: + /// + /// 1. Protocol negotiation on an incoming stream failed with no protocol + /// being agreed on. + /// + /// 2. When combining [`ProtocolsHandler`] implementations a single + /// [`ProtocolsHandler`] might be notified of an inbound upgrade error + /// unrelated to its own upgrade logic. For example when nesting a + /// [`ToggleProtoHandler`] in a + /// [`ProtocolsHandlerSelect`](crate::protocols_handler::ProtocolsHandlerSelect) + /// the former might receive an inbound upgrade error even when disabled. + /// + /// [`ToggleProtoHandler`] should ignore the error in both of these cases. + #[test] + fn ignore_listen_upgrade_error_when_disabled() { + let mut handler = ToggleProtoHandler:: { + inner: None, + }; + + handler.inject_listen_upgrade_error(Either::Right(()), ProtocolsHandlerUpgrErr::Timeout); + } +}