Skip to content

Commit 848a6d9

Browse files
Drop OMs from disconnected peers in OnionMessenger
And refuse to forward OMs to disconnected peers
1 parent 4894f4f commit 848a6d9

File tree

4 files changed

+62
-5
lines changed

4 files changed

+62
-5
lines changed

lightning/src/ln/msgs.rs

+5
Original file line numberDiff line numberDiff line change
@@ -949,6 +949,11 @@ pub trait RoutingMessageHandler : MessageSendEventsProvider {
949949
pub trait OnionMessageHandler : OnionMessageProvider {
950950
/// Handle an incoming onion_message message from the given peer.
951951
fn handle_onion_message(&self, peer_node_id: &PublicKey, msg: &OnionMessage);
952+
///
953+
fn peer_connected(&self, their_node_id: &PublicKey, init: &Init);
954+
/// Indicates a connection to the peer failed/an existing connection was lost. Allows handlers to
955+
/// drop and refuse to forward onion messages to this peer.
956+
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool);
952957
}
953958

954959
mod fuzzy_internal_msgs {

lightning/src/ln/peer_handler.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,8 @@ impl OnionMessageProvider for IgnoringMessageHandler {
8282
}
8383
impl OnionMessageHandler for IgnoringMessageHandler {
8484
fn handle_onion_message(&self, _their_node_id: &PublicKey, _msg: &msgs::OnionMessage) {}
85+
fn peer_connected(&self, _their_node_id: &PublicKey, _init: &msgs::Init) {}
86+
fn peer_disconnected(&self, _their_node_id: &PublicKey, _no_connection_possible: bool) {}
8587
}
8688
impl Deref for IgnoringMessageHandler {
8789
type Target = IgnoringMessageHandler;
@@ -1154,8 +1156,9 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
11541156
}
11551157

11561158
self.message_handler.route_handler.peer_connected(&their_node_id, &msg);
1157-
11581159
self.message_handler.chan_handler.peer_connected(&their_node_id, &msg);
1160+
self.message_handler.onion_message_handler.peer_connected(&their_node_id, &msg);
1161+
11591162
peer_lock.their_features = Some(msg.features);
11601163
return Ok(None);
11611164
} else if peer_lock.their_features.is_none() {
@@ -1734,6 +1737,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
17341737
}
17351738
descriptor.disconnect_socket();
17361739
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
1740+
self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
17371741
}
17381742
}
17391743
}
@@ -1761,6 +1765,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
17611765
log_pubkey!(node_id), if no_connection_possible { "no " } else { "" });
17621766
self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
17631767
self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
1768+
self.message_handler.onion_message_handler.peer_disconnected(&node_id, no_connection_possible);
17641769
}
17651770
}
17661771
};
@@ -1781,6 +1786,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
17811786
log_trace!(self.logger, "Disconnecting peer with id {} due to client request", node_id);
17821787
peers_lock.remove(&descriptor);
17831788
self.message_handler.chan_handler.peer_disconnected(&node_id, no_connection_possible);
1789+
self.message_handler.onion_message_handler.peer_disconnected(&node_id, no_connection_possible);
17841790
descriptor.disconnect_socket();
17851791
}
17861792
}
@@ -1796,6 +1802,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
17961802
if let Some(node_id) = peer.lock().unwrap().their_node_id {
17971803
log_trace!(self.logger, "Disconnecting peer with id {} due to client request to disconnect all peers", node_id);
17981804
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
1805+
self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
17991806
}
18001807
descriptor.disconnect_socket();
18011808
}
@@ -1886,6 +1893,7 @@ impl<Descriptor: SocketDescriptor, CM: Deref, RM: Deref, OM: Deref, L: Deref, CM
18861893
log_trace!(self.logger, "Disconnecting peer with id {} due to ping timeout", node_id);
18871894
self.node_id_to_descriptor.lock().unwrap().remove(&node_id);
18881895
self.message_handler.chan_handler.peer_disconnected(&node_id, false);
1896+
self.message_handler.onion_message_handler.peer_disconnected(&node_id, false);
18891897
}
18901898
}
18911899
}

lightning/src/onion_message/functional_tests.rs

+11-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@
1010
//! Onion message testing and test utilities live here.
1111
1212
use chain::keysinterface::{KeysInterface, Recipient};
13-
use ln::msgs::OnionMessageHandler;
13+
use ln::features::InitFeatures;
14+
use ln::msgs::{self, OnionMessageHandler};
1415
use super::{BlindedRoute, Destination, OnionMessenger, SendError};
1516
use util::enforcing_trait_impls::EnforcingSigner;
1617
use util::events::MessageSendEvent;
@@ -35,18 +36,24 @@ impl MessengerNode {
3536
}
3637

3738
fn create_nodes(num_messengers: u8) -> Vec<MessengerNode> {
38-
let mut res = Vec::new();
39+
let mut nodes = Vec::new();
3940
for i in 0..num_messengers {
4041
let logger = Arc::new(test_utils::TestLogger::with_id(format!("node {}", i)));
4142
let seed = [i as u8; 32];
4243
let keys_manager = Arc::new(test_utils::TestKeysInterface::new(&seed, Network::Testnet));
43-
res.push(MessengerNode {
44+
nodes.push(MessengerNode {
4445
keys_manager: keys_manager.clone(),
4546
messenger: OnionMessenger::new(keys_manager, logger.clone()),
4647
logger,
4748
});
4849
}
49-
res
50+
for idx in 0..num_messengers - 1 {
51+
let i = idx as usize;
52+
let init_msg = msgs::Init { features: InitFeatures::known(), remote_network_address: None };
53+
nodes[i].messenger.peer_connected(&nodes[i + 1].get_node_pk(), &init_msg.clone());
54+
nodes[i + 1].messenger.peer_connected(&nodes[i].get_node_pk(), &init_msg.clone());
55+
}
56+
nodes
5057
}
5158

5259
fn pass_along_path(mut path: Vec<MessengerNode>, expected_path_id: Option<[u8; 32]>) {

lightning/src/onion_message/messenger.rs

+37
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ pub struct OnionMessenger<Signer: Sign, K: Deref, L: Deref>
8585
keys_manager: K,
8686
logger: L,
8787
pending_messages: Mutex<HashMap<PublicKey, Vec<MessageSendEvent>>>,
88+
peer_set: Mutex<HashSet<PublicKey>>,
8889
secp_ctx: Secp256k1<secp256k1::All>,
8990
// Coming soon:
9091
// invoice_handler: InvoiceHandler,
@@ -121,6 +122,9 @@ pub enum SendError {
121122
/// The provided [`Destination`] was an invalid [`BlindedRoute`], due to having fewer than two
122123
/// blinded hops.
123124
TooFewBlindedHops,
125+
/// Our next-hop peer was offline or does not support onion message forwarding.
126+
// See TODO in `peer_connected`
127+
InvalidFirstHop,
124128
}
125129

126130
impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
@@ -134,6 +138,7 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
134138
secp_ctx.seeded_randomize(&keys_manager.get_secure_random_bytes());
135139
OnionMessenger {
136140
keys_manager,
141+
peer_set: Mutex::new(HashSet::new()),
137142
pending_messages: Mutex::new(HashMap::new()),
138143
secp_ctx,
139144
logger,
@@ -159,6 +164,9 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
159164
(introduction_node_id, blinding_point),
160165
}
161166
};
167+
if !self.peer_connected(&introduction_node_id) {
168+
return Err(SendError::InvalidFirstHop)
169+
}
162170
let (packet_payloads, packet_keys) = packet_payloads_and_keys(
163171
&self.secp_ctx, intermediate_nodes, destination, &blinding_secret)
164172
.map_err(|e| SendError::Secp256k1(e))?;
@@ -179,6 +187,11 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessenger<Signer, K, L>
179187
Ok(())
180188
}
181189

190+
fn peer_connected(&self, peer_node_id: &PublicKey) -> bool {
191+
let peers = self.peer_set.lock().unwrap();
192+
peers.contains(peer_node_id)
193+
}
194+
182195
#[cfg(test)]
183196
pub(super) fn release_pending_msgs(&self) -> HashMap<PublicKey, Vec<MessageSendEvent>> {
184197
let mut pending_msgs = self.pending_messages.lock().unwrap();
@@ -229,6 +242,10 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
229242
Ok((Payload::Forward(ForwardControlTlvs::Unblinded(ForwardTlvs {
230243
next_node_id, next_blinding_override
231244
})), Some((next_hop_hmac, new_packet_bytes)))) => {
245+
if !self.peer_connected(&next_node_id) {
246+
log_trace!(self.logger, "Dropping onion message to disconnected peer {:?}", next_node_id);
247+
return
248+
}
232249
// TODO: we need to check whether `next_node_id` is our node, in which case this is a dummy
233250
// blinded hop and this onion message is destined for us. In this situation, we should keep
234251
// unwrapping the onion layers to get to the final payload. Since we don't have the option
@@ -282,6 +299,26 @@ impl<Signer: Sign, K: Deref, L: Deref> OnionMessageHandler for OnionMessenger<Si
282299
},
283300
};
284301
}
302+
303+
fn peer_connected(&self, their_node_id: &PublicKey, _init: &msgs::Init) {
304+
// TODO: check feature bits to see if onion message forwarding is supported
305+
let mut peers = self.peer_set.lock().unwrap();
306+
peers.insert(their_node_id.clone());
307+
}
308+
309+
fn peer_disconnected(&self, their_node_id: &PublicKey, no_connection_possible: bool) {
310+
{
311+
let mut peers = self.peer_set.lock().unwrap();
312+
peers.remove(their_node_id);
313+
}
314+
315+
let mut pending_msgs = self.pending_messages.lock().unwrap();
316+
if no_connection_possible {
317+
pending_msgs.remove(their_node_id);
318+
} else if let Some(msgs) = pending_msgs.get_mut(their_node_id) {
319+
msgs.clear();
320+
}
321+
}
285322
}
286323

287324
impl<Signer: Sign, K: Deref, L: Deref> OnionMessageProvider for OnionMessenger<Signer, K, L>

0 commit comments

Comments
 (0)