Skip to content

Commit 16d5a95

Browse files
committed
fix: crash on double peer_destroy (ASSERT paddr->connected == 1)
On Linux, peer_destroy was crashing with 'ASSERT(peer->paddr->connected == 1) not TRUE' when a peer's verack handler returned an error (e.g. peergroup_handle_handshake_ok returned nonzero), causing peer_receive_cb to goto exit -> peer_destroy. But the network layer may have already torn down the same peer (socket closed while the message handler was running), setting paddr->connected = 0 in a prior peer_destroy call -- making this a legitimate double-destroy race, not a programmer error. Replaced the ASSERT with a graceful early-return guard: if paddr->connected is already 0, the peer has already been cleaned up; log and return instead of crashing.
1 parent eb677e6 commit 16d5a95

1 file changed

Lines changed: 13 additions & 1 deletion

File tree

core/peer.c

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -484,10 +484,22 @@ peer_destroy(struct circlist_item *li,
484484

485485
ASSERT(peer);
486486

487+
/*
488+
* Guard against double-destroy: the network layer may have already torn
489+
* down this peer (e.g. socket closed while a message handler was running)
490+
* before the message-handling error path reaches peer_destroy via goto
491+
* exit. In that case paddr->connected is already 0 and the peer has
492+
* already been cleaned up -- just return.
493+
*/
494+
if (peer->paddr->connected == 0) {
495+
LOG(1, (LGPFX" %s: peer already disconnected; skipping destroy.\n",
496+
peer->name));
497+
return;
498+
}
499+
487500
LOG(1, (LGPFX" %s: destroying peer '%s' -- %s\n",
488501
peer->name, peer->hostname, peer->clientStr));
489502

490-
ASSERT(peer->paddr->connected == 1);
491503
peer->paddr->connected = 0;
492504
peer->connected = 0;
493505

0 commit comments

Comments
 (0)