From a1460b0a2861d5bb34ba25d409b234468f269e4e Mon Sep 17 00:00:00 2001 From: tv Date: Sat, 24 Oct 2026 03:19:28 +0200 Subject: use nonce in handshake To prevent stale hello replies to cause joins and thus stale sessions, each run gets a random ID, which used as nonce in the handshake. --- src/swarm/peer.rs | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) (limited to 'src/swarm/peer.rs') diff --git a/src/swarm/peer.rs b/src/swarm/peer.rs index c8c86ac..13a980c 100644 --- a/src/swarm/peer.rs +++ b/src/swarm/peer.rs @@ -271,6 +271,7 @@ async fn transmit_hello(state: &AppState, peer: &str) -> Result<()> { epoch: state.local_epoch(), auth, ready: state.is_ready().await, + run_id: state.run_id, }), ) .await; @@ -298,7 +299,8 @@ async fn ensure_handshake(state: &AppState, peer: &str) { } } -async fn send_hello_reply(state: &AppState, peer: &str) -> Result<()> { +/// Answers a HELLO that carried `run_id`. +async fn send_hello_reply(state: &AppState, peer: &str, run_id: transport::RunId) -> Result<()> { let swarm_id = state .swarm_id() .await @@ -335,6 +337,7 @@ async fn send_hello_reply(state: &AppState, peer: &str) -> Result<()> { epoch: state.local_epoch(), auth, ready, + run_id, }; debug!(to = %peer, ready, "Sending HELLO_REPLY"); @@ -661,6 +664,15 @@ pub(crate) async fn handle_message( return Ok(()); } + // A reply to a HELLO from an earlier run of ours (late, or queued in Mycelium while + // we were down) says nothing about now; the peer answers our current HELLO. + if let transport::ParsedMessage::HelloReply(reply) = &message { + if reply.run_id != state.run_id { + debug!(peer = %peer, "Ignoring a HELLO_REPLY to a HELLO from an earlier run"); + return Ok(()); + } + } + if !admit(state, &peer, &message).await { return Ok(()); } @@ -700,7 +712,7 @@ pub(crate) async fn handle_message( } establish_peer(state, &peer, swarm_id, true, hello.ready).await?; - if let Err(error) = send_hello_reply(state, &peer).await { + if let Err(error) = send_hello_reply(state, &peer, hello.run_id).await { // The peer retries its HELLO. warn!(peer = %peer, error = %format!("{error:#}"), "HELLO_REPLY failed"); } -- cgit v1.3.1