Fix #114: Prevent zombie quic connections

Signed-off-by: Lee Smet <lee.smet@hotmail.com>
This commit is contained in:
Lee Smet
2024-01-23 15:32:54 +01:00
parent 09cff9ff35
commit 4ade07f9a7
4 changed files with 43 additions and 2 deletions
+5
View File
@@ -11,6 +11,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- If the router notices a Peer is dead, the connection is now forcibly terminated.
### Fixed
- Inbound peers now replace existing peers in the peer manager. This should fix
an issue where Quic could leave zombie connections.
## [0.3.1] - 2024-01-23
### Added
+5
View File
@@ -286,6 +286,11 @@ impl PeerRef {
false
}
}
/// Attempts to convert this `PeerRef` into a full [`Peer`].
pub fn upgrade(&self) -> Option<Peer> {
self.inner.upgrade().map(|inner| Peer { inner })
}
}
impl Default for PeerRef {
+32 -1
View File
@@ -393,7 +393,7 @@ impl Inner {
Endpoint::new(Protocol::Quic, con.remote_address()),
PeerType::Inbound,
Some(new_peer),
);
)
}
}
@@ -416,6 +416,37 @@ impl Inner {
self.router.lock().unwrap().add_peer_interface(p);
}
info!("Added new peer {endpoint}");
} else if discovery_type == PeerType::Inbound {
// We got an inbound peer with a duplicate entry. This is possible if the sending port
// is the same as the previous one, which generally happens with our Quic setup. In
// this case, the old connection needs to be replaced.
let old_peer_info = peers.insert(
endpoint,
PeerInfo {
pt: discovery_type,
connecting: false,
pr: if let Some(p) = &peer {
p.refer()
} else {
PeerRef::new()
},
connection_attempts: 0,
},
);
// If we have a new peer notify insert the new one in the router, then notify it that
// the old one is dead.
if let Some(p) = peer {
let router = self.router.lock().unwrap();
router.add_peer_interface(p);
if let Some(old_peer) = old_peer_info
.expect("We already checked the entry was occupied so this is always Some; qed")
.pr
.upgrade()
{
router.handle_dead_peer(old_peer);
}
}
info!("Replaced existing inbound peer {endpoint}");
} else {
debug!("Ignoring request to add {endpoint} as it already exists");
}
+1 -1
View File
@@ -353,7 +353,7 @@ impl Router {
}
/// Remove a dead peer from the router.
fn handle_dead_peer(&self, dead_peer: Peer) {
pub fn handle_dead_peer(&self, dead_peer: Peer) {
debug!(
"Cleaning up peer {} which is reportedly dead",
dead_peer.connection_identifier()