summaryrefslogtreecommitdiffstats
path: root/src/swarm/peer.rs
diff options
context:
space:
mode:
authortv <tv@krebsco.de>2026-10-24 03:19:28 +0200
committertv <tv@krebsco.de>2026-10-24 03:19:28 +0200
commita1460b0a2861d5bb34ba25d409b234468f269e4e (patch)
treefb447e712aa587b4136c12f4b918cd9c6cf160f0 /src/swarm/peer.rs
parent84a307a09eb3ba95920b028a49d0ec57bf316cdc (diff)
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.
Diffstat (limited to 'src/swarm/peer.rs')
-rw-r--r--src/swarm/peer.rs16
1 files changed, 14 insertions, 2 deletions
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");
}