node: unregister old decrypt-worker entry on cross-connection-won promotion

The cross-connection-won path in handle_msg1 removes the old peer and frees
its allocated index, but does not unregister the old (transport_id, our_index)
cache_key from the decrypt worker pool. The orphan entry sits in the
per-shard HashMap until the index allocator recycles old_idx to a different
peer and that peer's register_decrypt_worker_session call overwrites it.
In the interim, any decrypt job that lands at the recycled cache_key
resolves to the wrong session and AEAD silently fails — observed as
multi-hop routing failure in 5-node static-mesh on next-branch where
bidirectional auto_connect drives cross-connections at every peer pair
on startup.
This commit is contained in:
Johnathan Corgan
2026-05-25 16:48:27 +00:00
parent 18297283ad
commit 00bd849ee1
+11
View File
@@ -1009,6 +1009,17 @@ impl Node {
(old_peer.transport_id(), old_peer.our_index())
{
self.peers_by_index.remove(&(old_tid, old_idx.as_u32()));
// Unregister the OLD cache_key from the decrypt
// worker pool BEFORE freeing the index for reuse.
// Otherwise the worker's per-shard HashMap retains a
// stale entry pointing at the removed peer's session;
// if the index allocator later recycles old_idx to a
// different peer, the new register call overwrites
// the stale entry — but until that point, decrypt
// jobs that land at the recycled cache_key resolve
// to the wrong session and AEAD silently fails.
#[cfg(unix)]
self.unregister_decrypt_worker_session((old_tid, old_idx.as_u32()));
let _ = self.index_allocator.free(old_idx);
}