From cc417a7bef3df20a3d3fce78138d05ffeff7ff9c Mon Sep 17 00:00:00 2001 From: Johnathan Corgan Date: Thu, 28 May 2026 21:13:26 +0000 Subject: [PATCH] node: free the connection index when XX msg3 processing fails The msg3-processing-failure cleanup read our_index from the connection after removing it from the connections map, so the lookup always returned None and the allocated index was never released, slowly leaking index slots across failed XX handshakes. Capture the index before the remove, matching the idiom used in the other cleanup paths in this file. --- src/node/handlers/handshake.rs | 39 ++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/node/handlers/handshake.rs b/src/node/handlers/handshake.rs index 75e5cbf..d195873 100644 --- a/src/node/handlers/handshake.rs +++ b/src/node/handlers/handshake.rs @@ -810,25 +810,28 @@ impl Node { // Process msg3 — learns initiator's identity and epoch let noise_msg3 = &packet.data[header.noise_msg3_offset..]; - let received_negotiation = match conn - .complete_handshake_msg3(noise_msg3, packet.timestamp_ms) - { - Ok(neg) => neg, - Err(e) => { - warn!( - link_id = %link_id, - error = %e, - "Msg3 processing failed" - ); - // Clean up - self.connections.remove(&link_id); - self.remove_link(&link_id); - if let Some(idx) = self.connections.get(&link_id).and_then(|c| c.our_index()) { - let _ = self.index_allocator.free(idx); + let received_negotiation = + match conn.complete_handshake_msg3(noise_msg3, packet.timestamp_ms) { + Ok(neg) => neg, + Err(e) => { + warn!( + link_id = %link_id, + error = %e, + "Msg3 processing failed" + ); + // Clean up. Capture the index before removing the + // connection; reading it after the remove would always + // return None and leak the allocated index. + let our_idx_to_free = + self.connections.get(&link_id).and_then(|c| c.our_index()); + self.connections.remove(&link_id); + self.remove_link(&link_id); + if let Some(idx) = our_idx_to_free { + let _ = self.index_allocator.free(idx); + } + return; } - return; - } - }; + }; // Process peer's FMP negotiation payload from msg3 if let Some(neg_bytes) = &received_negotiation {