From 7612ec9c0bce1fa1f9def17f221435ca07e4119d Mon Sep 17 00:00:00 2001
From: Alexandru Vasile <60601340+lexnv@users.noreply.github.com>
Date: Tue, 3 Dec 2024 15:16:21 +0200
Subject: [PATCH] req-resp: Fix memory leak of pending substreams (#297)
Similar to https://github.com/paritytech/litep2p/pull/296, there is a
possibility of leaking memory in the following edge-case:
- T0: Connection is established and outbound substream is initiated with
peer
- This maps the substream ID to the request bytes information
- T1: Connection is closed before the service has a chance to report
`TransportEvent::SubstreamOpened` or
`TransportEvent::SubstreamOpenFailure`
In this case, if we connect and immediately disconnect with a request in
flight, we are effectively leaking the request bytes.
Detected by:
- https://github.com/paritytech/litep2p/pull/294
### Dashboard
- We are leaking ~111 requests over 3 days timespan:
cc @paritytech/networking
Signed-off-by: Alexandru Vasile
---
src/protocol/request_response/mod.rs | 3 +++
1 file changed, 3 insertions(+)
diff --git a/src/protocol/request_response/mod.rs b/src/protocol/request_response/mod.rs
index 38e631a1..3a64a386 100644
--- a/src/protocol/request_response/mod.rs
+++ b/src/protocol/request_response/mod.rs
@@ -292,6 +292,9 @@ impl RequestResponseProtocol {
async fn on_connection_closed(&mut self, peer: PeerId) {
tracing::debug!(target: LOG_TARGET, ?peer, protocol = %self.protocol, "connection closed");
+ // Remove any pending outbound substreams for this peer.
+ self.pending_outbound.retain(|_, context| context.peer != peer);
+
let Some(context) = self.peers.remove(&peer) else {
tracing::error!(
target: LOG_TARGET,