Skip to content

Commit 5ba2f80

Browse files
committed
Add new DisconnectPeerWithWarning variant to ErrorAction
1 parent 6d4f105 commit 5ba2f80

File tree

2 files changed

+45
-14
lines changed

2 files changed

+45
-14
lines changed

lightning/src/ln/msgs.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1137,6 +1137,11 @@ pub enum ErrorAction {
11371137
/// An error message which we should make an effort to send before we disconnect.
11381138
msg: Option<ErrorMessage>
11391139
},
1140+
/// The peer did something incorrect. Tell them without closing any channels and disconnect them.
1141+
DisconnectPeerWithWarning {
1142+
/// A warning message which we should make an effort to send before we disconnect.
1143+
msg: WarningMessage,
1144+
},
11401145
/// The peer did something harmless that we weren't able to process, just log and ignore
11411146
// New code should *not* use this. New code must use IgnoreAndLog, below!
11421147
IgnoreError,

lightning/src/ln/peer_handler.rs

Lines changed: 40 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1230,8 +1230,21 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
12301230
Ok(x) => x,
12311231
Err(e) => {
12321232
match e.action {
1233-
msgs::ErrorAction::DisconnectPeer { msg: _ } => {
1234-
//TODO: Try to push msg
1233+
msgs::ErrorAction::DisconnectPeer { .. } => {
1234+
// We may have an `ErrorMessage` to send to the peer,
1235+
// but writing to the socket while reading can lead to
1236+
// re-entrant code and possibly unexpected behavior. The
1237+
// message send is optimistic anyway, and in this case
1238+
// we immediately disconnect the peer.
1239+
log_debug!(self.logger, "Error handling message{}; disconnecting peer with: {}", OptionalFromDebugger(&peer_node_id), e.err);
1240+
return Err(PeerHandleError { });
1241+
},
1242+
msgs::ErrorAction::DisconnectPeerWithWarning { .. } => {
1243+
// We have a `WarningMessage` to send to the peer, but
1244+
// writing to the socket while reading can lead to
1245+
// re-entrant code and possibly unexpected behavior. The
1246+
// message send is optimistic anyway, and in this case
1247+
// we immediately disconnect the peer.
12351248
log_debug!(self.logger, "Error handling message{}; disconnecting peer with: {}", OptionalFromDebugger(&peer_node_id), e.err);
12361249
return Err(PeerHandleError { });
12371250
},
@@ -1362,7 +1375,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
13621375
Ok(x) => x,
13631376
Err(e) => {
13641377
match e {
1365-
// Note that to avoid recursion we never call
1378+
// Note that to avoid re-entrancy we never call
13661379
// `do_attempt_write_data` from here, causing
13671380
// the messages enqueued here to not actually
13681381
// be sent before the peer is disconnected.
@@ -2064,32 +2077,48 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
20642077
log_pubkey!(node_id), msg.contents.short_channel_id);
20652078
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
20662079
},
2067-
MessageSendEvent::HandleError { ref node_id, ref action } => {
2068-
match *action {
2069-
msgs::ErrorAction::DisconnectPeer { ref msg } => {
2080+
MessageSendEvent::HandleError { node_id, action } => {
2081+
match action {
2082+
msgs::ErrorAction::DisconnectPeer { msg } => {
2083+
if let Some(msg) = msg.as_ref() {
2084+
log_trace!(self.logger, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}",
2085+
log_pubkey!(node_id), msg.data);
2086+
} else {
2087+
log_trace!(self.logger, "Handling DisconnectPeer HandleError event in peer_handler for node {}",
2088+
log_pubkey!(node_id));
2089+
}
2090+
// We do not have the peers write lock, so we just store that we're
2091+
// about to disconenct the peer and do it after we finish
2092+
// processing most messages.
2093+
let msg = msg.map(|msg| wire::Message::<<<CMH as core::ops::Deref>::Target as wire::CustomMessageReader>::CustomMessage>::Error(msg));
2094+
peers_to_disconnect.insert(node_id, msg);
2095+
},
2096+
msgs::ErrorAction::DisconnectPeerWithWarning { msg } => {
2097+
log_trace!(self.logger, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}",
2098+
log_pubkey!(node_id), msg.data);
20702099
// We do not have the peers write lock, so we just store that we're
20712100
// about to disconenct the peer and do it after we finish
20722101
// processing most messages.
2073-
peers_to_disconnect.insert(*node_id, msg.clone());
2102+
peers_to_disconnect.insert(node_id, Some(wire::Message::Warning(msg)));
20742103
},
20752104
msgs::ErrorAction::IgnoreAndLog(level) => {
20762105
log_given_level!(self.logger, level, "Received a HandleError event to be ignored for node {}", log_pubkey!(node_id));
20772106
},
20782107
msgs::ErrorAction::IgnoreDuplicateGossip => {},
20792108
msgs::ErrorAction::IgnoreError => {
2080-
log_debug!(self.logger, "Received a HandleError event to be ignored for node {}", log_pubkey!(node_id));
2081-
},
2109+
log_debug!(self.logger, "Received a HandleError event to be ignored for node {}", log_pubkey!(node_id));
2110+
},
20822111
msgs::ErrorAction::SendErrorMessage { ref msg } => {
20832112
log_trace!(self.logger, "Handling SendErrorMessage HandleError event in peer_handler for node {} with message {}",
20842113
log_pubkey!(node_id),
20852114
msg.data);
2086-
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
2115+
self.enqueue_message(&mut *get_peer_for_forwarding!(&node_id), msg);
20872116
},
20882117
msgs::ErrorAction::SendWarningMessage { ref msg, ref log_level } => {
20892118
log_given_level!(self.logger, *log_level, "Handling SendWarningMessage HandleError event in peer_handler for node {} with message {}",
20902119
log_pubkey!(node_id),
20912120
msg.data);
2092-
self.enqueue_message(&mut *get_peer_for_forwarding!(node_id), msg);
2121+
self.enqueue_message(&mut *get_peer_for_forwarding!(&node_id), msg);
20932122
},
20942123
}
20952124
},
@@ -2139,9 +2168,6 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
21392168
if let Some(peer_mutex) = peers.remove(&descriptor) {
21402169
let mut peer = peer_mutex.lock().unwrap();
21412170
if let Some(msg) = msg {
2142-
log_trace!(self.logger, "Handling DisconnectPeer HandleError event in peer_handler for node {} with message {}",
2143-
log_pubkey!(node_id),
2144-
msg.data);
21452171
self.enqueue_message(&mut *peer, &msg);
21462172
// This isn't guaranteed to work, but if there is enough free
21472173
// room in the send buffer, put the error message there...

0 commit comments

Comments
 (0)