Skip to content

Commit 7402cab

Browse files
fix(network): reject duplicate HELLO instead of panicking
A peer that completed HELLO and sent a second one re-entered `update_ingress_node_id` with its own token already in `node_id_index`, hitting a `panic!` — a remotely-triggerable node panic from the simultaneous-dial tie-break. Reject a second HELLO on an already-ready session with `BadProtocol` (disconnecting it like any protocol violation), and downgrade the now-unreachable index branch to a soft error. Surfaced via #3510. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent b3a6035 commit 7402cab

2 files changed

Lines changed: 14 additions & 1 deletion

File tree

crates/network/src/session.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,13 @@ impl Session {
309309
match packet.id {
310310
PACKET_HELLO => {
311311
debug!("Read HELLO in session {:?}", self);
312+
// A second HELLO would re-enter the ingress tie-break with this
313+
// token already indexed (a remotely-triggerable panic). Reject
314+
// it as a protocol violation.
315+
if self.is_ready() {
316+
debug!("Duplicate HELLO on ready session {:?}", self);
317+
return Err(Error::BadProtocol);
318+
}
312319
self.metadata.peer_header_version = packet.header_version;
313320

314321
// Validate before the tie-break touches the index, so a failed

crates/network/src/session_manager.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -383,7 +383,13 @@ impl SessionManager {
383383

384384
if let Some(existing) = node_id_index.get(node_id).cloned() {
385385
if existing.token == idx {
386-
panic!("The same token already exists for the same node!!!");
386+
// Should be unreachable: the duplicate-HELLO guard in
387+
// `Session::read_packet` rejects a second HELLO before this.
388+
// Return a soft error instead of panicking the node.
389+
return Err(format!(
390+
"node id index already maps node {:?} to this session's own token {}",
391+
node_id, idx
392+
));
387393
}
388394
let outcome = simultaneous_dial_outcome(
389395
&self.own_node_id,

0 commit comments

Comments
 (0)