X-Git-Url: http://git.bitcoin.ninja/index.cgi?a=blobdiff_plain;f=src%2Fln%2Fpeer_handler.rs;h=86e2553623d2405232c97c735f548e7fb84bb04b;hb=76d127f7e46319d23e3eb21955f8cce091ac27d3;hp=9df01489f214071d146f46cdb307180e1d01307e;hpb=3057df26566f9b111db0470563689f5633ebfaec;p=rust-lightning diff --git a/src/ln/peer_handler.rs b/src/ln/peer_handler.rs index 9df01489..86e25536 100644 --- a/src/ln/peer_handler.rs +++ b/src/ln/peer_handler.rs @@ -8,7 +8,8 @@ use util::events::{EventsProvider,Event}; use std::collections::{HashMap,LinkedList}; use std::sync::{Arc, Mutex}; -use std::{cmp,mem,hash,fmt}; +use std::sync::atomic::{AtomicUsize, Ordering}; +use std::{cmp,error,mem,hash,fmt}; pub struct MessageHandler { pub chan_handler: Arc, @@ -48,6 +49,16 @@ impl fmt::Debug for PeerHandleError { formatter.write_str("Peer Sent Invalid Data") } } +impl fmt::Display for PeerHandleError { + fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> { + formatter.write_str("Peer Sent Invalid Data") + } +} +impl error::Error for PeerHandleError { + fn description(&self) -> &str { + "Peer Sent Invalid Data" + } +} struct Peer { channel_encryptor: PeerChannelEncryptor, @@ -76,6 +87,7 @@ pub struct PeerManager { peers: Mutex>, pending_events: Mutex>, our_node_secret: SecretKey, + initial_syncs_sent: AtomicUsize, } @@ -91,6 +103,9 @@ macro_rules! encode_msg { } } +//TODO: Really should do something smarter for this +const INITIAL_SYNCS_TO_SEND: usize = 5; + /// Manages and reacts to connection events. You probably want to use file descriptors as PeerIds. /// PeerIds may repeat, but only after disconnect_event() has been called. impl PeerManager { @@ -100,6 +115,7 @@ impl PeerManager { peers: Mutex::new(PeerHolder { peers: HashMap::new(), node_id_to_descriptor: HashMap::new() }), pending_events: Mutex::new(Vec::new()), our_node_secret: our_node_secret, + initial_syncs_sent: AtomicUsize::new(0), } } @@ -262,16 +278,19 @@ impl PeerManager { match $thing { Ok(x) => x, Err(e) => { - // TODO: Log e.err + println!("Got error handling message: {}!", e.err); if let Some(action) = e.msg { match action { msgs::ErrorAction::UpdateFailHTLC { msg } => { encode_and_send_msg!(msg, 131); continue; }, - msgs::ErrorAction::DisconnectPeer {} => { + msgs::ErrorAction::DisconnectPeer => { return Err(PeerHandleError{ no_connection_possible: false }); }, + msgs::ErrorAction::IgnoreError => { + continue; + }, } } else { return Err(PeerHandleError{ no_connection_possible: false }); @@ -286,6 +305,7 @@ impl PeerManager { match $thing { Ok(x) => x, Err(_e) => { + println!("Error decoding message"); //TODO: Handle e? return Err(PeerHandleError{ no_connection_possible: false }); } @@ -293,6 +313,18 @@ impl PeerManager { } } + macro_rules! try_ignore_potential_decodeerror { + ($thing: expr) => { + match $thing { + Ok(x) => x, + Err(_e) => { + println!("Error decoding message, ignoring due to lnd spec incompatibility. See https://github.com/lightningnetwork/lnd/issues/1407"); + continue; + } + }; + } + } + let next_step = peer.channel_encryptor.get_noise_step(); match next_step { NextNoiseStep::ActOne => { @@ -307,9 +339,14 @@ impl PeerManager { peer.pending_read_is_header = true; insert_node_id = Some(peer.their_node_id.unwrap()); + let mut local_features = msgs::LocalFeatures::new(); + if self.initial_syncs_sent.load(Ordering::Acquire) < INITIAL_SYNCS_TO_SEND { + self.initial_syncs_sent.fetch_add(1, Ordering::AcqRel); + local_features.set_initial_routing_sync(); + } encode_and_send_msg!(msgs::Init { global_features: msgs::GlobalFeatures::new(), - local_features: msgs::LocalFeatures::new(), + local_features, }, 16); }, NextNoiseStep::ActThree => { @@ -355,17 +392,31 @@ impl PeerManager { peer.their_local_features = Some(msg.local_features); if !peer.outbound { + let mut local_features = msgs::LocalFeatures::new(); + if self.initial_syncs_sent.load(Ordering::Acquire) < INITIAL_SYNCS_TO_SEND { + self.initial_syncs_sent.fetch_add(1, Ordering::AcqRel); + local_features.set_initial_routing_sync(); + } encode_and_send_msg!(msgs::Init { global_features: msgs::GlobalFeatures::new(), - local_features: msgs::LocalFeatures::new(), + local_features, }, 16); } }, 17 => { // Error msg }, - 18 => { }, // ping - 19 => { }, // pong + + 18 => { + let msg = try_potential_decodeerror!(msgs::Ping::decode(&msg_data[2..])); + if msg.ponglen < 65532 { + let resp = msgs::Pong { byteslen: msg.ponglen }; + encode_and_send_msg!(resp, 19); + } + }, + 19 => { + try_potential_decodeerror!(msgs::Pong::decode(&msg_data[2..])); + }, // Channel control: 32 => { @@ -481,7 +532,7 @@ impl PeerManager { } }, 257 => { - let msg = try_potential_decodeerror!(msgs::NodeAnnouncement::decode(&msg_data[2..])); + let msg = try_ignore_potential_decodeerror!(msgs::NodeAnnouncement::decode(&msg_data[2..])); try_potential_handleerror!(self.message_handler.route_handler.handle_node_announcement(&msg)); }, 258 => {