Skip to content

Commit b83443f

Browse files
authored
Merge pull request #131 from TheBlueMatt/2018-08-bolt-1-compliance
update Error/Init handling to be BOLT 1 compliant
2 parents a33b3a2 + 755b76b commit b83443f

File tree

7 files changed

+54
-18
lines changed

7 files changed

+54
-18
lines changed

fuzz/Cargo.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,10 @@ path = "fuzz_targets/msg_ping_target.rs"
6060
name = "msg_pong_target"
6161
path = "fuzz_targets/msg_pong_target.rs"
6262

63+
[[bin]]
64+
name = "msg_error_message_target"
65+
path = "fuzz_targets/msg_error_message_target.rs"
66+
6367
[[bin]]
6468
name = "msg_accept_channel_target"
6569
path = "fuzz_targets/msg_targets/msg_accept_channel_target.rs"
@@ -119,7 +123,3 @@ path = "fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs"
119123
[[bin]]
120124
name = "msg_channel_reestablish_target"
121125
path = "fuzz_targets/msg_targets/msg_channel_reestablish_target.rs"
122-
123-
[[bin]]
124-
name = "msg_error_message_target"
125-
path = "fuzz_targets/msg_targets/msg_error_message_target.rs"

fuzz/fuzz_targets/msg_targets/msg_error_message_target.rs renamed to fuzz/fuzz_targets/msg_error_message_target.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ use lightning::util::reset_rng_state;
88

99
use lightning::ln::msgs::{MsgEncodable, MsgDecodable};
1010

11-
mod utils;
12-
1311
#[inline]
1412
pub fn do_test(data: &[u8]) {
1513
reset_rng_state();
16-
test_msg!(msgs::ErrorMessage, data);
14+
if let Ok(msg) = msgs::ErrorMessage::decode(data){
15+
let enc = msg.encode();
16+
assert_eq!(&data[0..32], &enc[0..32]);
17+
assert_eq!(&data[34..enc.len()], &enc[34..]);
18+
}
1719
}
1820

1921
#[cfg(feature = "afl")]

fuzz/fuzz_targets/msg_targets/gen_target.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned ChannelReestablish ErrorMessage; do
1+
for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned ChannelReestablish; do
22
tn=$(echo $target | sed 's/\([a-z0-9]\)\([A-Z]\)/\1_\2/g')
33
fn=msg_$(echo $tn | tr '[:upper:]' '[:lower:]')_target.rs
44
cat msg_target_template.txt | sed s/MSG_TARGET/$target/ > $fn

src/ln/channelmanager.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2053,6 +2053,18 @@ impl ChannelMessageHandler for ChannelManager {
20532053
}
20542054
}
20552055
}
2056+
2057+
fn handle_error(&self, their_node_id: &PublicKey, msg: &msgs::ErrorMessage) {
2058+
if msg.channel_id == [0; 32] {
2059+
for chan in self.list_channels() {
2060+
if chan.remote_network_id == *their_node_id {
2061+
self.force_close_channel(&chan.channel_id);
2062+
}
2063+
}
2064+
} else {
2065+
self.force_close_channel(&msg.channel_id);
2066+
}
2067+
}
20562068
}
20572069

20582070
#[cfg(test)]

src/ln/msgs.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use bitcoin::network::serialize::{deserialize,serialize};
55
use bitcoin::blockdata::script::Script;
66

77
use std::error::Error;
8-
use std::fmt;
8+
use std::{cmp, fmt};
99
use std::result::Result;
1010

1111
use util::{byte_utils, internal_traits, events};
@@ -439,12 +439,14 @@ pub trait ChannelMessageHandler : events::EventsProvider + Send + Sync {
439439
// Channel-to-announce:
440440
fn handle_announcement_signatures(&self, their_node_id: &PublicKey, msg: &AnnouncementSignatures) -> Result<(), HandleError>;
441441

442-
// Informational:
442+
// Error conditions:
443443
/// Indicates a connection to the peer failed/an existing connection was lost. If no connection
444444
/// is believed to be possible in the future (eg they're sending us messages we don't
445445
/// understand or indicate they require unknown feature bits), no_connection_possible is set
446446
/// and any outstanding channels should be failed.
447447
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
448+
449+
fn handle_error(&self, their_node_id: &PublicKey, msg: &ErrorMessage);
448450
}
449451

450452
pub trait RoutingMessageHandler : Send + Sync {
@@ -1624,11 +1626,9 @@ impl MsgDecodable for ErrorMessage {
16241626
if v.len() < 34 {
16251627
return Err(DecodeError::ShortRead);
16261628
}
1627-
let len = byte_utils::slice_to_be16(&v[32..34]);
1628-
if v.len() < 34 + len as usize {
1629-
return Err(DecodeError::ShortRead);
1630-
}
1631-
let data = match String::from_utf8(v[34..34 + len as usize].to_vec()) {
1629+
// Unlike most messages, BOLT 1 requires we truncate our read if the value is out of range
1630+
let len = cmp::min(byte_utils::slice_to_be16(&v[32..34]) as usize, v.len() - 34);
1631+
let data = match String::from_utf8(v[34..34 + len].to_vec()) {
16321632
Ok(s) => s,
16331633
Err(_) => return Err(DecodeError::BadText),
16341634
};

src/ln/peer_handler.rs

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -431,7 +431,24 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
431431
}
432432
},
433433
17 => {
434-
// Error msg
434+
let msg = try_potential_decodeerror!(msgs::ErrorMessage::decode(&msg_data[2..]));
435+
let mut data_is_printable = true;
436+
for b in msg.data.bytes() {
437+
if b < 32 || b > 126 {
438+
data_is_printable = false;
439+
break;
440+
}
441+
}
442+
443+
if data_is_printable {
444+
log_debug!(self, "Got Err message from {}: {}", log_pubkey!(peer.their_node_id.unwrap()), msg.data);
445+
} else {
446+
log_debug!(self, "Got Err message from {} with non-ASCII error message", log_pubkey!(peer.their_node_id.unwrap()));
447+
}
448+
self.message_handler.chan_handler.handle_error(&peer.their_node_id.unwrap(), &msg);
449+
if msg.channel_id == [0; 32] {
450+
return Err(PeerHandleError{ no_connection_possible: true });
451+
}
435452
},
436453

437454
18 => {
@@ -621,6 +638,10 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
621638
};
622639
match peers.peers.get_mut(&descriptor) {
623640
Some(peer) => {
641+
if peer.their_global_features.is_none() {
642+
$handle_no_such_peer;
643+
continue;
644+
}
624645
(descriptor, peer)
625646
},
626647
None => panic!("Inconsistent peers set state!"),
@@ -717,7 +738,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
717738
let encoded_update_msg = encode_msg!(update_msg, 258);
718739

719740
for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
720-
if !peer.channel_encryptor.is_ready_for_encryption() {
741+
if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() {
721742
continue
722743
}
723744
match peer.their_node_id {
@@ -741,7 +762,7 @@ impl<Descriptor: SocketDescriptor> PeerManager<Descriptor> {
741762
let encoded_msg = encode_msg!(msg, 258);
742763

743764
for (ref descriptor, ref mut peer) in peers.peers.iter_mut() {
744-
if !peer.channel_encryptor.is_ready_for_encryption() {
765+
if !peer.channel_encryptor.is_ready_for_encryption() || peer.their_global_features.is_none() {
745766
continue
746767
}
747768
peer.pending_outbound_buffer.push_back(peer.channel_encryptor.encrypt_message(&encoded_msg[..]));

src/util/test_utils.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ impl msgs::ChannelMessageHandler for TestChannelMessageHandler {
115115
Err(HandleError { err: "", action: None })
116116
}
117117
fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
118+
fn handle_error(&self, _their_node_id: &PublicKey, _msg: &msgs::ErrorMessage) {}
118119
}
119120

120121
impl events::EventsProvider for TestChannelMessageHandler {

0 commit comments

Comments
 (0)