Skip to content

Commit 007cce0

Browse files
committed
Give peers one timer tick to finish handshake before disconnecting
This ensures we don't let a hung connection stick around forever if the peer never completes the initial handshake. This also resolves a race where, on receiving a second connection from a peer, we may reset their_node_id to None to prevent sending messages even though the `channel_encryptor` `is_ready_for_encryption()`. Sending pings only checks the `channel_encryptor` status, not `their_node_id` resulting in an `unwrap` on `None` in `enqueue_message`.
1 parent 9a2e727 commit 007cce0

File tree

1 file changed

+15
-9
lines changed

1 file changed

+15
-9
lines changed

lightning/src/ln/peer_handler.rs

+15-9
Original file line numberDiff line numberDiff line change
@@ -849,6 +849,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
849849
let features = InitFeatures::known();
850850
let resp = msgs::Init { features };
851851
self.enqueue_message(peer, &resp);
852+
peer.awaiting_pong_tick_intervals = 0;
852853
},
853854
NextNoiseStep::ActThree => {
854855
let their_node_id = try_potential_handleerror!(peer.channel_encryptor.process_act_three(&peer.pending_read_buffer[..]));
@@ -859,6 +860,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
859860
let features = InitFeatures::known();
860861
let resp = msgs::Init { features };
861862
self.enqueue_message(peer, &resp);
863+
peer.awaiting_pong_tick_intervals = 0;
862864
},
863865
NextNoiseStep::NoiseComplete => {
864866
if peer.pending_read_is_header {
@@ -1498,12 +1500,20 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
14981500
let mut descriptors_needing_disconnect = Vec::new();
14991501

15001502
peers.retain(|descriptor, peer| {
1501-
if !peer.channel_encryptor.is_ready_for_encryption() {
1502-
// The peer needs to complete its handshake before we can exchange messages
1503-
return true;
1503+
let mut do_disconnect_peer = false;
1504+
if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_node_id.is_none() {
1505+
// The peer needs to complete its handshake before we can exchange messages. We
1506+
// give peers one timer tick to complet handshake.
1507+
if peer.awaiting_pong_tick_intervals != 0 {
1508+
do_disconnect_peer = true;
1509+
} else {
1510+
peer.awaiting_pong_tick_intervals = 1;
1511+
return true;
1512+
}
15041513
}
15051514

1506-
if (peer.awaiting_pong_tick_intervals > 0 && !peer.received_message_since_timer_tick)
1515+
if do_disconnect_peer
1516+
|| (peer.awaiting_pong_tick_intervals > 0 && !peer.received_message_since_timer_tick)
15071517
|| peer.awaiting_pong_tick_intervals > MAX_BUFFER_DRAIN_TICK_INTERVALS
15081518
{
15091519
descriptors_needing_disconnect.push(descriptor.clone());
@@ -1513,11 +1523,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, L: Deref, CMH: Deref> P
15131523
node_id_to_descriptor.remove(&node_id);
15141524
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
15151525
}
1516-
None => {
1517-
// This can't actually happen as we should have hit
1518-
// is_ready_for_encryption() previously on this same peer.
1519-
unreachable!();
1520-
},
1526+
None => {},
15211527
}
15221528
return false;
15231529
}

0 commit comments

Comments
 (0)