Skip to content

Commit 8aaeba4

Browse files
authored
protocol: Ensure transport manager knows about closed connections (#515)
This PR improves the connection management robustness by ensuring that the closed connections are reported. If a registered protocol could not receive the `InnerTransportEvent::ConnectionClosed` the function would fail to inform the transport manager. This would cause litep2p to think that the connection is still active, while the async task of the raw socket would exit immediately after the function call. The PR makes sure are not returning on the first encountered error and switch to a best-effort approach. --------- Signed-off-by: Alexandru Vasile <[email protected]>
1 parent 4ce2fbe commit 8aaeba4

File tree

1 file changed

+28
-6
lines changed

1 file changed

+28
-6
lines changed

src/protocol/protocol_set.rs

Lines changed: 28 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -396,31 +396,53 @@ impl ProtocolSet {
396396
) -> crate::Result<()> {
397397
let mut futures = self
398398
.protocols
399-
.values()
400-
.map(|sender| async move {
399+
.iter()
400+
.map(|(protocol, sender)| async move {
401401
sender
402402
.tx
403403
.send(InnerTransportEvent::ConnectionClosed {
404404
peer,
405405
connection: connection_id,
406406
})
407407
.await
408+
.inspect_err(|err| {
409+
tracing::debug!(
410+
target: LOG_TARGET,
411+
%protocol,
412+
?peer,
413+
?connection_id,
414+
?err,
415+
"failed to report connection closed to protocol",
416+
);
417+
})
408418
})
409419
.collect::<FuturesUnordered<_>>();
410420

421+
// Capture the first error that occurs while reporting to protocols.
422+
let mut protocol_error = None;
411423
while !futures.is_empty() {
412-
if let Some(Err(error)) = futures.next().await {
413-
return Err(error.into());
424+
if let Some(Err(err)) = futures.next().await {
425+
if protocol_error.is_none() {
426+
protocol_error = Some(err.into());
427+
}
414428
}
415429
}
416430

431+
// Ensure the manager receives the connection closed event. Otherwise, the
432+
// manager will think the connection is still open, while the underlying
433+
// protocols and raw connection are closed.
417434
self.mgr_tx
418435
.send(TransportManagerEvent::ConnectionClosed {
419436
peer,
420437
connection: connection_id,
421438
})
422-
.await
423-
.map_err(From::from)
439+
.await?;
440+
441+
// If any protocol report failed, return that error now
442+
match protocol_error {
443+
Some(e) => Err(e),
444+
None => Ok(()),
445+
}
424446
}
425447
}
426448

0 commit comments

Comments
 (0)