Fix panic when peer is mid-handshake

Peer::their_node_id is set to Some during the handshake process.
However, df3ab2ee27 accesses the field
unconditionally, causing a panic. This may be triggered if a gossip
message is received mid-handshake from another peer or if the user calls
broadcast_node_announcement during this time. The latter tends to be
executed on a timer.

Ensure that Peer::their_node_id is only accessed once the handshake is
complete.
This commit is contained in:
Jeffrey Czyz 2024-01-18 15:34:19 -06:00
parent 5592378de2
commit c7465bdb3e
No known key found for this signature in database
GPG key ID: 3A4E08275D5E96D2

View file

@ -1835,13 +1835,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
for (_, peer_mutex) in peers.iter() { for (_, peer_mutex) in peers.iter() {
let mut peer = peer_mutex.lock().unwrap(); let mut peer = peer_mutex.lock().unwrap();
let logger = WithContext::from(&self.logger, Some(peer.their_node_id.unwrap().0), None);
if !peer.handshake_complete() || if !peer.handshake_complete() ||
!peer.should_forward_channel_announcement(msg.contents.short_channel_id) { !peer.should_forward_channel_announcement(msg.contents.short_channel_id) {
continue continue
} }
debug_assert!(peer.their_node_id.is_some()); debug_assert!(peer.their_node_id.is_some());
debug_assert!(peer.channel_encryptor.is_ready_for_encryption()); debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
let logger = WithContext::from(&self.logger, Some(peer.their_node_id.unwrap().0), None);
if peer.buffer_full_drop_gossip_broadcast() { if peer.buffer_full_drop_gossip_broadcast() {
log_gossip!(logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id); log_gossip!(logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id);
continue; continue;
@ -1863,13 +1863,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
for (_, peer_mutex) in peers.iter() { for (_, peer_mutex) in peers.iter() {
let mut peer = peer_mutex.lock().unwrap(); let mut peer = peer_mutex.lock().unwrap();
let logger = WithContext::from(&self.logger, Some(peer.their_node_id.unwrap().0), None);
if !peer.handshake_complete() || if !peer.handshake_complete() ||
!peer.should_forward_node_announcement(msg.contents.node_id) { !peer.should_forward_node_announcement(msg.contents.node_id) {
continue continue
} }
debug_assert!(peer.their_node_id.is_some()); debug_assert!(peer.their_node_id.is_some());
debug_assert!(peer.channel_encryptor.is_ready_for_encryption()); debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
let logger = WithContext::from(&self.logger, Some(peer.their_node_id.unwrap().0), None);
if peer.buffer_full_drop_gossip_broadcast() { if peer.buffer_full_drop_gossip_broadcast() {
log_gossip!(logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id); log_gossip!(logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id);
continue; continue;
@ -1891,13 +1891,13 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
for (_, peer_mutex) in peers.iter() { for (_, peer_mutex) in peers.iter() {
let mut peer = peer_mutex.lock().unwrap(); let mut peer = peer_mutex.lock().unwrap();
let logger = WithContext::from(&self.logger, Some(peer.their_node_id.unwrap().0), None);
if !peer.handshake_complete() || if !peer.handshake_complete() ||
!peer.should_forward_channel_announcement(msg.contents.short_channel_id) { !peer.should_forward_channel_announcement(msg.contents.short_channel_id) {
continue continue
} }
debug_assert!(peer.their_node_id.is_some()); debug_assert!(peer.their_node_id.is_some());
debug_assert!(peer.channel_encryptor.is_ready_for_encryption()); debug_assert!(peer.channel_encryptor.is_ready_for_encryption());
let logger = WithContext::from(&self.logger, Some(peer.their_node_id.unwrap().0), None);
if peer.buffer_full_drop_gossip_broadcast() { if peer.buffer_full_drop_gossip_broadcast() {
log_gossip!(logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id); log_gossip!(logger, "Skipping broadcast message to {:?} as its outbound buffer is full", peer.their_node_id);
continue; continue;