Skip to content

Commit c0bcb4b

Browse files
authored
Merge pull request #78 from TheBlueMatt/2018-07-43-rebased
Add DisconnectPeer event
2 parents fa9715d + 20fa9d3 commit c0bcb4b

File tree

12 files changed

+384
-46
lines changed

12 files changed

+384
-46
lines changed

fuzz/Cargo.toml

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,3 +114,7 @@ path = "fuzz_targets/msg_targets/msg_update_fail_htlc_target.rs"
114114
[[bin]]
115115
name = "msg_channel_reestablish_target"
116116
path = "fuzz_targets/msg_targets/msg_channel_reestablish_target.rs"
117+
118+
[[bin]]
119+
name = "msg_error_message_target"
120+
path = "fuzz_targets/msg_targets/msg_error_message_target.rs"

fuzz/fuzz_targets/channel_target.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,7 @@ pub fn do_test(data: &[u8]) {
118118
msgs::DecodeError::UnknownRealmByte => return,
119119
msgs::DecodeError::BadPublicKey => return,
120120
msgs::DecodeError::BadSignature => return,
121+
msgs::DecodeError::BadText => return,
121122
msgs::DecodeError::ExtraAddressesPerType => return,
122123
msgs::DecodeError::WrongLength => panic!("We picked the length..."),
123124
}
@@ -138,6 +139,7 @@ pub fn do_test(data: &[u8]) {
138139
msgs::DecodeError::UnknownRealmByte => return,
139140
msgs::DecodeError::BadPublicKey => return,
140141
msgs::DecodeError::BadSignature => return,
142+
msgs::DecodeError::BadText => return,
141143
msgs::DecodeError::ExtraAddressesPerType => return,
142144
msgs::DecodeError::WrongLength => panic!("We picked the length..."),
143145
}

fuzz/fuzz_targets/full_stack_target.rs

Lines changed: 35 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,9 @@ use lightning::util::reset_rng_state;
2525
use secp256k1::key::{PublicKey,SecretKey};
2626
use secp256k1::Secp256k1;
2727

28+
use std::cell::RefCell;
2829
use std::collections::HashMap;
30+
use std::hash::Hash;
2931
use std::sync::Arc;
3032
use std::sync::atomic::{AtomicUsize,Ordering};
3133

@@ -104,15 +106,31 @@ impl BroadcasterInterface for TestBroadcaster {
104106
fn broadcast_transaction(&self, _tx: &Transaction) {}
105107
}
106108

107-
#[derive(Clone, PartialEq, Eq, Hash)]
108-
struct Peer {
109+
#[derive(Clone)]
110+
struct Peer<'a> {
109111
id: u8,
112+
peers_connected: &'a RefCell<[bool; 256]>,
110113
}
111-
impl SocketDescriptor for Peer {
114+
impl<'a> SocketDescriptor for Peer<'a> {
112115
fn send_data(&mut self, data: &Vec<u8>, write_offset: usize, _resume_read: bool) -> usize {
113116
assert!(write_offset < data.len());
114117
data.len() - write_offset
115118
}
119+
fn disconnect_socket(&mut self) {
120+
assert!(self.peers_connected.borrow()[self.id as usize]);
121+
self.peers_connected.borrow_mut()[self.id as usize] = false;
122+
}
123+
}
124+
impl<'a> PartialEq for Peer<'a> {
125+
fn eq(&self, other: &Self) -> bool {
126+
self.id == other.id
127+
}
128+
}
129+
impl<'a> Eq for Peer<'a> {}
130+
impl<'a> Hash for Peer<'a> {
131+
fn hash<H : std::hash::Hasher>(&self, h: &mut H) {
132+
self.id.hash(h)
133+
}
116134
}
117135

118136
#[inline]
@@ -158,12 +176,12 @@ pub fn do_test(data: &[u8]) {
158176
let channelmanager = ChannelManager::new(our_network_key, slice_to_be32(get_slice!(4)), get_slice!(1)[0] != 0, Network::Bitcoin, fee_est.clone(), monitor.clone(), watch.clone(), broadcast.clone()).unwrap();
159177
let router = Arc::new(Router::new(PublicKey::from_secret_key(&secp_ctx, &our_network_key).unwrap()));
160178

179+
let peers = RefCell::new([false; 256]);
161180
let handler = PeerManager::new(MessageHandler {
162181
chan_handler: channelmanager.clone(),
163182
route_handler: router.clone(),
164183
}, our_network_key);
165184

166-
let mut peers = [false; 256];
167185
let mut should_forward = false;
168186
let mut payments_received = Vec::new();
169187
let mut payments_sent = 0;
@@ -176,39 +194,39 @@ pub fn do_test(data: &[u8]) {
176194
0 => {
177195
let mut new_id = 0;
178196
for i in 1..256 {
179-
if !peers[i-1] {
197+
if !peers.borrow()[i-1] {
180198
new_id = i;
181199
break;
182200
}
183201
}
184202
if new_id == 0 { return; }
185-
peers[new_id - 1] = true;
186-
handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8}).unwrap();
203+
peers.borrow_mut()[new_id - 1] = true;
204+
handler.new_outbound_connection(get_pubkey!(), Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
187205
},
188206
1 => {
189207
let mut new_id = 0;
190208
for i in 1..256 {
191-
if !peers[i-1] {
209+
if !peers.borrow()[i-1] {
192210
new_id = i;
193211
break;
194212
}
195213
}
196214
if new_id == 0 { return; }
197-
peers[new_id - 1] = true;
198-
handler.new_inbound_connection(Peer{id: (new_id - 1) as u8}).unwrap();
215+
peers.borrow_mut()[new_id - 1] = true;
216+
handler.new_inbound_connection(Peer{id: (new_id - 1) as u8, peers_connected: &peers}).unwrap();
199217
},
200218
2 => {
201219
let peer_id = get_slice!(1)[0];
202-
if !peers[peer_id as usize] { return; }
203-
peers[peer_id as usize] = false;
204-
handler.disconnect_event(&Peer{id: peer_id});
220+
if !peers.borrow()[peer_id as usize] { return; }
221+
peers.borrow_mut()[peer_id as usize] = false;
222+
handler.disconnect_event(&Peer{id: peer_id, peers_connected: &peers});
205223
},
206224
3 => {
207225
let peer_id = get_slice!(1)[0];
208-
if !peers[peer_id as usize] { return; }
209-
match handler.read_event(&mut Peer{id: peer_id}, get_slice!(get_slice!(1)[0]).to_vec()) {
226+
if !peers.borrow()[peer_id as usize] { return; }
227+
match handler.read_event(&mut Peer{id: peer_id, peers_connected: &peers}, get_slice!(get_slice!(1)[0]).to_vec()) {
210228
Ok(res) => assert!(!res),
211-
Err(_) => { peers[peer_id as usize] = false; }
229+
Err(_) => { peers.borrow_mut()[peer_id as usize] = false; }
212230
}
213231
},
214232
4 => {
@@ -231,7 +249,7 @@ pub fn do_test(data: &[u8]) {
231249
},
232250
5 => {
233251
let peer_id = get_slice!(1)[0];
234-
if !peers[peer_id as usize] { return; }
252+
if !peers.borrow()[peer_id as usize] { return; }
235253
let their_key = get_pubkey!();
236254
let chan_value = slice_to_be24(get_slice!(3)) as u64;
237255
if channelmanager.create_channel(their_key, chan_value, 0).is_err() { return; }

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; do
1+
for target in CommitmentSigned FundingCreated FundingLocked FundingSigned OpenChannel RevokeAndACK Shutdown UpdateAddHTLC UpdateFailHTLC UpdateFailMalformedHTLC UpdateFee UpdateFulfillHTLC AcceptChannel ClosingSigned ChannelReestablish ErrorMessage; 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
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
// This file is auto-generated by gen_target.sh based on msg_target_template.txt
2+
// To modify it, modify msg_target_template.txt and run gen_target.sh instead.
3+
4+
extern crate lightning;
5+
6+
use lightning::ln::msgs;
7+
use lightning::util::reset_rng_state;
8+
9+
use lightning::ln::msgs::{MsgEncodable, MsgDecodable};
10+
11+
mod utils;
12+
13+
#[inline]
14+
pub fn do_test(data: &[u8]) {
15+
reset_rng_state();
16+
test_msg!(msgs::ErrorMessage, data);
17+
}
18+
19+
#[cfg(feature = "afl")]
20+
extern crate afl;
21+
#[cfg(feature = "afl")]
22+
fn main() {
23+
afl::read_stdio_bytes(|data| {
24+
do_test(&data);
25+
});
26+
}
27+
28+
#[cfg(feature = "honggfuzz")]
29+
#[macro_use] extern crate honggfuzz;
30+
#[cfg(feature = "honggfuzz")]
31+
fn main() {
32+
loop {
33+
fuzz!(|data| {
34+
do_test(data);
35+
});
36+
}
37+
}
38+
39+
#[cfg(test)]
40+
mod tests {
41+
use utils::extend_vec_from_hex;
42+
#[test]
43+
fn duplicate_crash() {
44+
let mut a = Vec::new();
45+
extend_vec_from_hex("00", &mut a);
46+
super::do_test(&a);
47+
}
48+
}

src/ln/channel.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -328,7 +328,7 @@ macro_rules! secp_call {
328328
match $res {
329329
Ok(key) => key,
330330
//TODO: make the error a parameter
331-
Err(_) => return Err(HandleError{err: $err, action: Some(msgs::ErrorAction::DisconnectPeer{})})
331+
Err(_) => return Err(HandleError{err: $err, action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })})
332332
}
333333
};
334334
}
@@ -433,10 +433,10 @@ impl Channel {
433433

434434
fn check_remote_fee(fee_estimator: &FeeEstimator, feerate_per_kw: u32) -> Result<(), HandleError> {
435435
if (feerate_per_kw as u64) < fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::Background) * 250 {
436-
return Err(HandleError{err: "Peer's feerate much too low", action: Some(msgs::ErrorAction::DisconnectPeer{})});
436+
return Err(HandleError{err: "Peer's feerate much too low", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
437437
}
438438
if (feerate_per_kw as u64) > fee_estimator.get_est_sat_per_vbyte(ConfirmationTarget::HighPriority) * 375 { // 375 = 250 * 1.5x
439-
return Err(HandleError{err: "Peer's feerate much too high", action: Some(msgs::ErrorAction::DisconnectPeer{})});
439+
return Err(HandleError{err: "Peer's feerate much too high", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
440440
}
441441
Ok(())
442442
}
@@ -448,29 +448,29 @@ impl Channel {
448448
pub fn new_from_req(fee_estimator: &FeeEstimator, chan_keys: ChannelKeys, their_node_id: PublicKey, msg: &msgs::OpenChannel, user_id: u64, announce_publicly: bool) -> Result<Channel, HandleError> {
449449
// Check sanity of message fields:
450450
if msg.funding_satoshis >= MAX_FUNDING_SATOSHIS {
451-
return Err(HandleError{err: "funding value > 2^24", action: Some(msgs::ErrorAction::DisconnectPeer{})});
451+
return Err(HandleError{err: "funding value > 2^24", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
452452
}
453453
if msg.channel_reserve_satoshis > msg.funding_satoshis {
454-
return Err(HandleError{err: "Bogus channel_reserve_satoshis", action: Some(msgs::ErrorAction::DisconnectPeer{})});
454+
return Err(HandleError{err: "Bogus channel_reserve_satoshis", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
455455
}
456456
if msg.push_msat > (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
457-
return Err(HandleError{err: "push_msat more than highest possible value", action: Some(msgs::ErrorAction::DisconnectPeer{})});
457+
return Err(HandleError{err: "push_msat more than highest possible value", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
458458
}
459459
if msg.dust_limit_satoshis > msg.funding_satoshis {
460-
return Err(HandleError{err: "Peer never wants payout outputs?", action: Some(msgs::ErrorAction::DisconnectPeer{})});
460+
return Err(HandleError{err: "Peer never wants payout outputs?", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
461461
}
462462
if msg.htlc_minimum_msat >= (msg.funding_satoshis - msg.channel_reserve_satoshis) * 1000 {
463-
return Err(HandleError{err: "Minimum htlc value is full channel value", action: Some(msgs::ErrorAction::DisconnectPeer{})});
463+
return Err(HandleError{err: "Minimum htlc value is full channel value", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
464464
}
465465
Channel::check_remote_fee(fee_estimator, msg.feerate_per_kw)?;
466466
if msg.to_self_delay > MAX_LOCAL_BREAKDOWN_TIMEOUT {
467-
return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", action: Some(msgs::ErrorAction::DisconnectPeer{})});
467+
return Err(HandleError{err: "They wanted our payments to be delayed by a needlessly long period", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
468468
}
469469
if msg.max_accepted_htlcs < 1 {
470-
return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", action: Some(msgs::ErrorAction::DisconnectPeer{})});
470+
return Err(HandleError{err: "0 max_accpted_htlcs makes for a useless channel", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
471471
}
472472
if (msg.channel_flags & 254) != 0 {
473-
return Err(HandleError{err: "unknown channel_flags", action: Some(msgs::ErrorAction::DisconnectPeer{})});
473+
return Err(HandleError{err: "unknown channel_flags", action: Some(msgs::ErrorAction::DisconnectPeer{ msg: None })});
474474
}
475475

476476
// Convert things into internal flags and prep our state:

src/ln/channelmanager.rs

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -705,6 +705,16 @@ impl ChannelManager {
705705
/// Call this upon creation of a funding transaction for the given channel.
706706
/// Panics if a funding transaction has already been provided for this channel.
707707
pub fn funding_transaction_generated(&self, temporary_channel_id: &[u8; 32], funding_txo: OutPoint) {
708+
709+
macro_rules! add_pending_event {
710+
($event: expr) => {
711+
{
712+
let mut pending_events = self.pending_events.lock().unwrap();
713+
pending_events.push($event);
714+
}
715+
}
716+
}
717+
708718
let (chan, msg, chan_monitor) = {
709719
let mut channel_state = self.channel_state.lock().unwrap();
710720
match channel_state.by_id.remove(temporary_channel_id) {
@@ -713,10 +723,15 @@ impl ChannelManager {
713723
Ok(funding_msg) => {
714724
(chan, funding_msg.0, funding_msg.1)
715725
},
716-
Err(_e) => {
717-
//TODO: Push e to pendingevents
726+
Err(e) => {
727+
mem::drop(channel_state);
728+
add_pending_event!(events::Event::DisconnectPeer {
729+
node_id: chan.get_their_node_id(),
730+
msg: if let Some(msgs::ErrorAction::DisconnectPeer { msg } ) = e.action { msg } else { None },
731+
});
732+
718733
return;
719-
}
734+
},
720735
}
721736
},
722737
None => return
@@ -725,13 +740,10 @@ impl ChannelManager {
725740
if let Err(_e) = self.monitor.add_update_monitor(chan_monitor.get_funding_txo().unwrap(), chan_monitor) {
726741
unimplemented!(); // maybe remove from claimable_htlcs?
727742
}
728-
{
729-
let mut pending_events = self.pending_events.lock().unwrap();
730-
pending_events.push(events::Event::SendFundingCreated {
731-
node_id: chan.get_their_node_id(),
732-
msg: msg,
733-
});
734-
}
743+
add_pending_event!(events::Event::SendFundingCreated {
744+
node_id: chan.get_their_node_id(),
745+
msg: msg,
746+
});
735747

736748
let mut channel_state = self.channel_state.lock().unwrap();
737749
channel_state.by_id.insert(chan.channel_id(), chan);

src/ln/msgs.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ pub enum DecodeError {
3131
BadPublicKey,
3232
/// Failed to decode a signature (ie it's invalid)
3333
BadSignature,
34+
/// Value expected to be text wasn't decodable as text
35+
BadText,
3436
/// Buffer not of right length (either too short or too long)
3537
WrongLength,
3638
/// node_announcement included more than one address of a given type!
@@ -138,6 +140,11 @@ pub struct Init {
138140
pub local_features: LocalFeatures,
139141
}
140142

143+
pub struct ErrorMessage {
144+
pub channel_id: [u8; 32],
145+
pub data: String,
146+
}
147+
141148
pub struct Ping {
142149
pub ponglen: u16,
143150
pub byteslen: u16,
@@ -372,9 +379,15 @@ pub enum ErrorAction {
372379
msg: UpdateFailHTLC
373380
},
374381
/// The peer took some action which made us think they were useless. Disconnect them.
375-
DisconnectPeer,
382+
DisconnectPeer {
383+
msg: Option<ErrorMessage>
384+
},
376385
/// The peer did something harmless that we weren't able to process, just log and ignore
377386
IgnoreError,
387+
/// The peer did something incorrect. Tell them.
388+
SendErrorMessage {
389+
msg: ErrorMessage
390+
},
378391
}
379392

380393
pub struct HandleError { //TODO: rename me
@@ -486,6 +499,7 @@ impl Error for DecodeError {
486499
DecodeError::UnknownRealmByte => "Unknown realm byte in Onion packet",
487500
DecodeError::BadPublicKey => "Invalid public key in packet",
488501
DecodeError::BadSignature => "Invalid signature in packet",
502+
DecodeError::BadText => "Invalid text in packet",
489503
DecodeError::WrongLength => "Data was wrong length for packet",
490504
DecodeError::ExtraAddressesPerType => "More than one address of a single type",
491505
}
@@ -1600,6 +1614,37 @@ impl MsgEncodable for OnionErrorPacket {
16001614
}
16011615
}
16021616

1617+
impl MsgEncodable for ErrorMessage {
1618+
fn encode(&self) -> Vec<u8> {
1619+
let mut res = Vec::with_capacity(34 + self.data.len());
1620+
res.extend_from_slice(&self.channel_id);
1621+
res.extend_from_slice(&byte_utils::be16_to_array(self.data.len() as u16));
1622+
res.extend_from_slice(&self.data.as_bytes());
1623+
res
1624+
}
1625+
}
1626+
impl MsgDecodable for ErrorMessage {
1627+
fn decode(v: &[u8]) -> Result<Self,DecodeError> {
1628+
if v.len() < 34 {
1629+
return Err(DecodeError::WrongLength);
1630+
}
1631+
let len = byte_utils::slice_to_be16(&v[32..34]);
1632+
if v.len() < 34 + len as usize {
1633+
return Err(DecodeError::WrongLength);
1634+
}
1635+
let data = match String::from_utf8(v[34..34 + len as usize].to_vec()) {
1636+
Ok(s) => s,
1637+
Err(_) => return Err(DecodeError::BadText),
1638+
};
1639+
let mut channel_id = [0; 32];
1640+
channel_id[..].copy_from_slice(&v[0..32]);
1641+
Ok(Self {
1642+
channel_id,
1643+
data,
1644+
})
1645+
}
1646+
}
1647+
16031648
#[cfg(test)]
16041649
mod tests {
16051650
use bitcoin::util::misc::hex_bytes;

0 commit comments

Comments
 (0)