Skip to content

Commit 1742bff

Browse files
feat(request-response): don't close connection on stream errors
Related: #3591. Pull-Request: #3913.
1 parent 8c00dc9 commit 1742bff

File tree

6 files changed

+23
-20
lines changed

6 files changed

+23
-20
lines changed

Cargo.lock

Lines changed: 3 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

examples/file-sharing/Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ either = "1.8"
1313
env_logger = "0.10"
1414
futures = "0.3.28"
1515
libp2p = { path = "../../libp2p", features = ["async-std", "dns", "kad", "noise", "macros", "request-response", "tcp", "websocket", "yamux"] }
16-
multiaddr = { version = "0.17.1" }
16+
multiaddr = { version = "0.17.1" }
17+
void = "1.0.2"

examples/file-sharing/src/network.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use libp2p::{
1616
multiaddr::Protocol,
1717
noise,
1818
request_response::{self, ProtocolSupport, RequestId, ResponseChannel},
19-
swarm::{NetworkBehaviour, StreamUpgradeError, Swarm, SwarmBuilder, SwarmEvent},
19+
swarm::{NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent},
2020
tcp, yamux, PeerId, Transport,
2121
};
2222

@@ -216,7 +216,7 @@ impl EventLoop {
216216

217217
async fn handle_event(
218218
&mut self,
219-
event: SwarmEvent<ComposedEvent, Either<StreamUpgradeError<io::Error>, io::Error>>,
219+
event: SwarmEvent<ComposedEvent, Either<void::Void, io::Error>>,
220220
) {
221221
match event {
222222
SwarmEvent::Behaviour(ComposedEvent::Kademlia(

protocols/request-response/CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,14 @@
88
These variants are no longer constructed.
99
See [PR 3605].
1010

11+
- Don't close connections if individual streams fail.
12+
Log the error instead.
13+
See [PR 3913].
14+
1115
[PR 3605]: https://github.com/libp2p/rust-libp2p/pull/3605
1216
[PR 3715]: https://github.com/libp2p/rust-libp2p/pull/3715
1317
[PR 3702]: https://github.com/libp2p/rust-libp2p/pull/3702
18+
[PR 3913]: https://github.com/libp2p/rust-libp2p/pull/3913
1419

1520
## 0.24.1
1621

protocols/request-response/Cargo.toml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ libp2p-swarm = { workspace = true }
1919
libp2p-identity = { workspace = true }
2020
rand = "0.8"
2121
smallvec = "1.6.1"
22+
void = "1.0.2"
23+
log = "0.4.17"
2224

2325
[dev-dependencies]
2426
async-std = { version = "1.6.2", features = ["attributes"] }

protocols/request-response/src/handler.rs

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ use libp2p_swarm::{
3939
use smallvec::SmallVec;
4040
use std::{
4141
collections::VecDeque,
42-
fmt, io,
42+
fmt,
4343
sync::{
4444
atomic::{AtomicU64, Ordering},
4545
Arc,
@@ -65,8 +65,6 @@ where
6565
substream_timeout: Duration,
6666
/// The current connection keep-alive.
6767
keep_alive: KeepAlive,
68-
/// A pending fatal error that results in the connection being closed.
69-
pending_error: Option<StreamUpgradeError<io::Error>>,
7068
/// Queue of events to emit in `poll()`.
7169
pending_events: VecDeque<Event<TCodec>>,
7270
/// Outbound upgrades waiting to be emitted as an `OutboundSubstreamRequest`.
@@ -107,7 +105,6 @@ where
107105
outbound: VecDeque::new(),
108106
inbound: FuturesUnordered::new(),
109107
pending_events: VecDeque::new(),
110-
pending_error: None,
111108
inbound_request_id,
112109
}
113110
}
@@ -151,21 +148,22 @@ where
151148
self.pending_events
152149
.push_back(Event::OutboundUnsupportedProtocols(info));
153150
}
154-
_ => {
155-
// Anything else is considered a fatal error or misbehaviour of
156-
// the remote peer and results in closing the connection.
157-
self.pending_error = Some(error);
151+
StreamUpgradeError::Apply(e) => {
152+
log::debug!("outbound stream {info} failed: {e}");
153+
}
154+
StreamUpgradeError::Io(e) => {
155+
log::debug!("outbound stream {info} failed: {e}");
158156
}
159157
}
160158
}
161159
fn on_listen_upgrade_error(
162160
&mut self,
163-
ListenUpgradeError { error, .. }: ListenUpgradeError<
161+
ListenUpgradeError { error, info }: ListenUpgradeError<
164162
<Self as ConnectionHandler>::InboundOpenInfo,
165163
<Self as ConnectionHandler>::InboundProtocol,
166164
>,
167165
) {
168-
self.pending_error = Some(StreamUpgradeError::Apply(error));
166+
log::debug!("inbound stream {info} failed: {error}");
169167
}
170168
}
171169

@@ -241,7 +239,7 @@ where
241239
{
242240
type FromBehaviour = RequestProtocol<TCodec>;
243241
type ToBehaviour = Event<TCodec>;
244-
type Error = StreamUpgradeError<io::Error>;
242+
type Error = void::Void;
245243
type InboundProtocol = ResponseProtocol<TCodec>;
246244
type OutboundProtocol = RequestProtocol<TCodec>;
247245
type OutboundOpenInfo = RequestId;
@@ -296,12 +294,6 @@ where
296294
) -> Poll<
297295
ConnectionHandlerEvent<RequestProtocol<TCodec>, RequestId, Self::ToBehaviour, Self::Error>,
298296
> {
299-
// Check for a pending (fatal) error.
300-
if let Some(err) = self.pending_error.take() {
301-
// The handler will not be polled again by the `Swarm`.
302-
return Poll::Ready(ConnectionHandlerEvent::Close(err));
303-
}
304-
305297
// Drain pending events.
306298
if let Some(event) = self.pending_events.pop_front() {
307299
return Poll::Ready(ConnectionHandlerEvent::Custom(event));

0 commit comments

Comments
 (0)