Handle Error messages by closing channels as required by BOLT 1
authorMatt Corallo <git@bluematt.me>
Sat, 25 Aug 2018 18:48:18 +0000 (14:48 -0400)
committerMatt Corallo <git@bluematt.me>
Sat, 25 Aug 2018 21:20:58 +0000 (17:20 -0400)
src/ln/channelmanager.rs
src/ln/msgs.rs
src/ln/peer_handler.rs
src/util/test_utils.rs

index a360c376a16282f450c2b7b8dc62f10547e89f98..3a98cd5a17647fb5a4a036abf5814411018bed22 100644 (file)
@@ -2053,6 +2053,18 @@ impl ChannelMessageHandler for ChannelManager {
                        }
                }
        }
+
+       fn handle_error(&self, their_node_id: &PublicKey, msg: &msgs::ErrorMessage) {
+               if msg.channel_id == [0; 32] {
+                       for chan in self.list_channels() {
+                               if chan.remote_network_id == *their_node_id {
+                                       self.force_close_channel(&chan.channel_id);
+                               }
+                       }
+               } else {
+                       self.force_close_channel(&msg.channel_id);
+               }
+       }
 }
 
 #[cfg(test)]
index c3b997566c81ce1b165e166458f641712cd867bc..4500ee2f89f48bee0290257c3c49411169cc0c07 100644 (file)
@@ -439,12 +439,14 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync {
        // Channel-to-announce:
        fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>;
 
-       // Informational:
+       // Error conditions:
        /// Indicates a connection to the peer failed/an existing connection was lost. If no connection
        /// is believed to be possible in the future (eg they're sending us messages we don't
        /// understand or indicate they require unknown feature bits), no_connection_possible is set
        /// and any outstanding channels should be failed.
        fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
+
+       fn handle_error(&self, their_node_id: &PublicKey, msg: &ErrorMessage);
 }
 
 pub trait RoutingMessageHandler : Send + Sync {
index 53788b3f265bf53b3505c4b10adc8d372ba1bfc2..f941f47dc10e5c99f13460b5aa82b96fba3a13c4 100644 (file)
@@ -431,7 +431,24 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
                                                                                                }
                                                                                        },
                                                                                        17 => {
-                                                                                               // Error msg
+                                                                                               let msg = try_potential_decodeerror!(msgs::ErrorMessage::decode(&msg_data[2..]));
+                                                                                               let mut data_is_printable = true;
+                                                                                               for b in msg.data.bytes() {
+                                                                                                       if b < 32 || b > 126 {
+                                                                                                               data_is_printable = false;
+                                                                                                               break;
+                                                                                                       }
+                                                                                               }
+
+                                                                                               if data_is_printable {
+                                                                                                       log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data);
+                                                                                               } else {
+                                                                                                       log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap()));
+                                                                                               }
+                                                                                               self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg);
+                                                                                               if msg.channel_id == [0; 32] {
+                                                                                                       return Err(PeerHandleError{ no_connection_possible: true });
+                                                                                               }
                                                                                        },
 
                                                                                        18 => {
index aff84735ece7e6a15355a1ef7710b80b97d8de9c..dc158230fad812acb467fcc05f08487f34d2c936 100644 (file)
@@ -115,6 +115,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
                Err(HandleError { err: "", action: None })
        }
        fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
+       fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {}
 }
 
 impl events::EventsProvider for TestChannelMessageHandler {