]> git.bitcoin.ninja Git - rust-lightning/commitdiff
Parse and handle `DNSResolverMessage`s in `OnionMessenger`
authorMatt Corallo <git@bluematt.me>
Sat, 13 Jul 2024 17:08:27 +0000 (17:08 +0000)
committerMatt Corallo <git@bluematt.me>
Mon, 30 Sep 2024 16:19:33 +0000 (16:19 +0000)
This adds the requisite message parsing and handling code for the
new DNSSEC messages to `OnionMessenger`.

fuzz/src/onion_message.rs
lightning-background-processor/src/lib.rs
lightning/src/ln/functional_test_utils.rs
lightning/src/ln/offers_tests.rs
lightning/src/ln/peer_handler.rs
lightning/src/onion_message/functional_tests.rs
lightning/src/onion_message/messenger.rs
lightning/src/onion_message/packet.rs

index 5cd45238df2e841fb2e0c299de8cdae81df4da37..cf87467a5ea2de17af14763676af39c1dce190f1 100644 (file)
@@ -11,6 +11,7 @@ use lightning::blinded_path::message::{
 use lightning::blinded_path::EmptyNodeIdLookUp;
 use lightning::ln::features::InitFeatures;
 use lightning::ln::msgs::{self, DecodeError, OnionMessageHandler};
+use lightning::ln::peer_handler::IgnoringMessageHandler;
 use lightning::ln::script::ShutdownScript;
 use lightning::offers::invoice::UnsignedBolt12Invoice;
 use lightning::offers::invoice_request::UnsignedInvoiceRequest;
@@ -56,6 +57,7 @@ pub fn do_test<L: Logger>(data: &[u8], logger: &L) {
                        &message_router,
                        &offers_msg_handler,
                        &async_payments_msg_handler,
+                       IgnoringMessageHandler {}, // TODO: Move to ChannelManager once it supports DNSSEC.
                        &custom_msg_handler,
                );
 
index fdeb46229a3d2bdc2cedf74ecabc097485daf286..318dfcbbd7e9395a3f01e617b57be389ef072804 100644 (file)
@@ -657,7 +657,7 @@ use futures_util::{dummy_waker, OptionalSelector, Selector, SelectorOutput};
 /// # type NetworkGraph = lightning::routing::gossip::NetworkGraph<Arc<Logger>>;
 /// # type P2PGossipSync<UL> = lightning::routing::gossip::P2PGossipSync<Arc<NetworkGraph>, Arc<UL>, Arc<Logger>>;
 /// # type ChannelManager<B, F, FE> = lightning::ln::channelmanager::SimpleArcChannelManager<ChainMonitor<B, F, FE>, B, FE, Logger>;
-/// # type OnionMessenger<B, F, FE> = lightning::onion_message::messenger::OnionMessenger<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<Logger>, Arc<ChannelManager<B, F, FE>>, Arc<lightning::onion_message::messenger::DefaultMessageRouter<Arc<NetworkGraph>, Arc<Logger>, Arc<lightning::sign::KeysManager>>>, Arc<ChannelManager<B, F, FE>>, lightning::ln::peer_handler::IgnoringMessageHandler, lightning::ln::peer_handler::IgnoringMessageHandler>;
+/// # type OnionMessenger<B, F, FE> = lightning::onion_message::messenger::OnionMessenger<Arc<lightning::sign::KeysManager>, Arc<lightning::sign::KeysManager>, Arc<Logger>, Arc<ChannelManager<B, F, FE>>, Arc<lightning::onion_message::messenger::DefaultMessageRouter<Arc<NetworkGraph>, Arc<Logger>, Arc<lightning::sign::KeysManager>>>, Arc<ChannelManager<B, F, FE>>, lightning::ln::peer_handler::IgnoringMessageHandler, lightning::ln::peer_handler::IgnoringMessageHandler, lightning::ln::peer_handler::IgnoringMessageHandler>;
 /// # type Scorer = RwLock<lightning::routing::scoring::ProbabilisticScorer<Arc<NetworkGraph>, Arc<Logger>>>;
 /// # type PeerManager<B, F, FE, UL> = lightning::ln::peer_handler::SimpleArcPeerManager<SocketDescriptor, ChainMonitor<B, F, FE>, B, FE, Arc<UL>, Logger>;
 /// #
@@ -1202,6 +1202,7 @@ mod tests {
                IgnoringMessageHandler,
                Arc<ChannelManager>,
                IgnoringMessageHandler,
+               IgnoringMessageHandler,
        >;
 
        struct Node {
@@ -1604,6 +1605,7 @@ mod tests {
                                IgnoringMessageHandler {},
                                manager.clone(),
                                IgnoringMessageHandler {},
+                               IgnoringMessageHandler {},
                        ));
                        let wallet = Arc::new(TestWallet {});
                        let sweeper = Arc::new(OutputSweeper::new(
index afab38c7bc2a7e519f1da04c15d0b1d54b3aeb42..7776966b2853d454ef3ef524167f41a951110c61 100644 (file)
@@ -415,6 +415,7 @@ type TestOnionMessenger<'chan_man, 'node_cfg, 'chan_mon_cfg> = OnionMessenger<
        &'node_cfg test_utils::TestMessageRouter<'chan_mon_cfg>,
        &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
        &'chan_man TestChannelManager<'node_cfg, 'chan_mon_cfg>,
+       IgnoringMessageHandler, // TODO: Swap for ChannelManager (when built with the "dnssec" feature)
        IgnoringMessageHandler,
 >;
 
@@ -3283,6 +3284,7 @@ pub fn create_network<'a, 'b: 'a, 'c: 'b>(node_count: usize, cfgs: &'b Vec<NodeC
                let onion_messenger = OnionMessenger::new(
                        dedicated_entropy, cfgs[i].keys_manager, cfgs[i].logger, &chan_mgrs[i],
                        &cfgs[i].message_router, &chan_mgrs[i], &chan_mgrs[i], IgnoringMessageHandler {},
+                       IgnoringMessageHandler {},
                );
                let gossip_sync = P2PGossipSync::new(cfgs[i].network_graph.as_ref(), None, cfgs[i].logger);
                let wallet_source = Arc::new(test_utils::TestWalletSource::new(SecretKey::from_slice(&[i as u8 + 1; 32]).unwrap()));
index 9ea8856f82a4785a1e7eeee3f8c1cd4587dcb1ce..55251d38a8463ce09f32611934b42d25d39487f7 100644 (file)
@@ -212,9 +212,7 @@ fn extract_invoice_request<'a, 'b, 'c>(
                                OffersMessage::StaticInvoice(invoice) => panic!("Unexpected static invoice: {:?}", invoice),
                                OffersMessage::InvoiceError(error) => panic!("Unexpected invoice_error: {:?}", error),
                        },
-                       #[cfg(async_payments)]
-                       ParsedOnionMessageContents::AsyncPayments(message) => panic!("Unexpected async payments message: {:?}", message),
-                       ParsedOnionMessageContents::Custom(message) => panic!("Unexpected custom message: {:?}", message),
+                       _ => panic!("Unexpected message {:?}", message),
                },
                Ok(PeeledOnion::Forward(_, _)) => panic!("Unexpected onion message forward"),
                Err(e) => panic!("Failed to process onion message {:?}", e),
@@ -231,9 +229,7 @@ fn extract_invoice<'a, 'b, 'c>(node: &Node<'a, 'b, 'c>, message: &OnionMessage)
                                OffersMessage::StaticInvoice(invoice) => panic!("Unexpected static invoice: {:?}", invoice),
                                OffersMessage::InvoiceError(error) => panic!("Unexpected invoice_error: {:?}", error),
                        },
-                       #[cfg(async_payments)]
-                       ParsedOnionMessageContents::AsyncPayments(message) => panic!("Unexpected async payments message: {:?}", message),
-                       ParsedOnionMessageContents::Custom(message) => panic!("Unexpected custom message: {:?}", message),
+                       _ => panic!("Unexpected message {:?}", message),
                },
                Ok(PeeledOnion::Forward(_, _)) => panic!("Unexpected onion message forward"),
                Err(e) => panic!("Failed to process onion message {:?}", e),
@@ -252,9 +248,7 @@ fn extract_invoice_error<'a, 'b, 'c>(
                                OffersMessage::StaticInvoice(invoice) => panic!("Unexpected invoice: {:?}", invoice),
                                OffersMessage::InvoiceError(error) => error,
                        },
-                       #[cfg(async_payments)]
-                       ParsedOnionMessageContents::AsyncPayments(message) => panic!("Unexpected async payments message: {:?}", message),
-                       ParsedOnionMessageContents::Custom(message) => panic!("Unexpected custom message: {:?}", message),
+                       _ => panic!("Unexpected message: {:?}", message),
                },
                Ok(PeeledOnion::Forward(_, _)) => panic!("Unexpected onion message forward"),
                Err(e) => panic!("Failed to process onion message {:?}", e),
index cb61b4dee9eb702c4cd23a8f91704d65084fa38a..34b3f1ba9bd19570ec4f59409e6e12473b4fa9c4 100644 (file)
@@ -18,7 +18,7 @@
 use bitcoin::constants::ChainHash;
 use bitcoin::secp256k1::{self, Secp256k1, SecretKey, PublicKey};
 
-use crate::blinded_path::message::{AsyncPaymentsContext, OffersContext};
+use crate::blinded_path::message::{AsyncPaymentsContext, DNSResolverContext, OffersContext};
 use crate::sign::{NodeSigner, Recipient};
 use crate::events::{MessageSendEvent, MessageSendEventsProvider};
 use crate::ln::types::ChannelId;
@@ -30,6 +30,7 @@ use crate::ln::peer_channel_encryptor::{PeerChannelEncryptor, NextNoiseStep, Mes
 use crate::ln::wire;
 use crate::ln::wire::{Encode, Type};
 use crate::onion_message::async_payments::{AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc};
+use crate::onion_message::dns_resolution::{DNSResolverMessageHandler, DNSResolverMessage, DNSSECProof, DNSSECQuery};
 use crate::onion_message::messenger::{CustomOnionMessageHandler, Responder, ResponseInstruction, MessageSendInstructions};
 use crate::onion_message::offers::{OffersMessage, OffersMessageHandler};
 use crate::onion_message::packet::OnionMessageContents;
@@ -154,6 +155,14 @@ impl AsyncPaymentsMessageHandler for IgnoringMessageHandler {
        }
        fn release_held_htlc(&self, _message: ReleaseHeldHtlc, _context: AsyncPaymentsContext) {}
 }
+impl DNSResolverMessageHandler for IgnoringMessageHandler {
+       fn handle_dnssec_query(
+               &self, _message: DNSSECQuery, _responder: Option<Responder>,
+       ) -> Option<(DNSResolverMessage, ResponseInstruction)> {
+               None
+       }
+       fn handle_dnssec_proof(&self, _message: DNSSECProof, _context: DNSResolverContext) {}
+}
 impl CustomOnionMessageHandler for IgnoringMessageHandler {
        type CustomMessage = Infallible;
        fn handle_custom_message(&self, _message: Infallible, _context: Option<Vec<u8>>, _responder: Option<Responder>) -> Option<(Infallible, ResponseInstruction)> {
index ef733b0893c803cbb9c75ea06895fff0b6619eff..ac79c88fb00a10dc3c7b4ed6e746e4c837556643 100644 (file)
@@ -10,7 +10,7 @@
 //! Onion message testing and test utilities live here.
 
 use crate::blinded_path::EmptyNodeIdLookUp;
-use crate::blinded_path::message::{AsyncPaymentsContext, BlindedMessagePath, MessageForwardNode, MessageContext, OffersContext};
+use crate::blinded_path::message::{AsyncPaymentsContext, BlindedMessagePath, DNSResolverContext, MessageForwardNode, MessageContext, OffersContext};
 use crate::events::{Event, EventsProvider};
 use crate::ln::features::{ChannelFeatures, InitFeatures};
 use crate::ln::msgs::{self, DecodeError, OnionMessageHandler};
@@ -20,6 +20,7 @@ use crate::sign::{NodeSigner, Recipient};
 use crate::util::ser::{FixedLengthReader, LengthReadable, Writeable, Writer};
 use crate::util::test_utils;
 use super::async_payments::{AsyncPaymentsMessageHandler, HeldHtlcAvailable, ReleaseHeldHtlc};
+use super::dns_resolution::{DNSResolverMessageHandler, DNSResolverMessage, DNSSECProof, DNSSECQuery};
 use super::messenger::{CustomOnionMessageHandler, DefaultMessageRouter, Destination, OnionMessagePath, OnionMessenger, Responder, ResponseInstruction, MessageSendInstructions, SendError, SendSuccess};
 use super::offers::{OffersMessage, OffersMessageHandler};
 use super::packet::{OnionMessageContents, Packet};
@@ -52,6 +53,7 @@ struct MessengerNode {
                >>,
                Arc<TestOffersMessageHandler>,
                Arc<TestAsyncPaymentsMessageHandler>,
+               Arc<TestDNSResolverMessageHandler>,
                Arc<TestCustomMessageHandler>
        >,
        custom_message_handler: Arc<TestCustomMessageHandler>,
@@ -90,6 +92,17 @@ impl AsyncPaymentsMessageHandler for TestAsyncPaymentsMessageHandler {
        fn release_held_htlc(&self, _message: ReleaseHeldHtlc, _context: AsyncPaymentsContext) {}
 }
 
+struct TestDNSResolverMessageHandler {}
+
+impl DNSResolverMessageHandler for TestDNSResolverMessageHandler {
+       fn handle_dnssec_query(
+               &self, _message: DNSSECQuery, _responder: Option<Responder>,
+       ) -> Option<(DNSResolverMessage, ResponseInstruction)> {
+               None
+       }
+       fn handle_dnssec_proof(&self, _message: DNSSECProof, _context: DNSResolverContext) {}
+}
+
 #[derive(Clone, Debug, PartialEq)]
 enum TestCustomMessage {
        Ping,
@@ -264,18 +277,21 @@ fn create_nodes_using_cfgs(cfgs: Vec<MessengerCfg>) -> Vec<MessengerNode> {
                );
                let offers_message_handler = Arc::new(TestOffersMessageHandler {});
                let async_payments_message_handler = Arc::new(TestAsyncPaymentsMessageHandler {});
+               let dns_resolver_message_handler = Arc::new(TestDNSResolverMessageHandler {});
                let custom_message_handler = Arc::new(TestCustomMessageHandler::new());
                let messenger = if cfg.intercept_offline_peer_oms {
                        OnionMessenger::new_with_offline_peer_interception(
                                entropy_source.clone(), node_signer.clone(), logger.clone(),
                                node_id_lookup, message_router, offers_message_handler,
-                               async_payments_message_handler, custom_message_handler.clone()
+                               async_payments_message_handler, dns_resolver_message_handler,
+                               custom_message_handler.clone(),
                        )
                } else {
                        OnionMessenger::new(
                                entropy_source.clone(), node_signer.clone(), logger.clone(),
                                node_id_lookup, message_router, offers_message_handler,
-                               async_payments_message_handler, custom_message_handler.clone()
+                               async_payments_message_handler, dns_resolver_message_handler,
+                               custom_message_handler.clone(),
                        )
                };
                nodes.push(MessengerNode {
index 4b7ba02e4ddcd96e7116cde6b1eceba0738abcc3..c531846912f4f293ae444ded2b528653650103be 100644 (file)
@@ -27,6 +27,7 @@ use crate::routing::gossip::{NetworkGraph, NodeId, ReadOnlyNetworkGraph};
 use super::async_payments::AsyncPaymentsMessageHandler;
 #[cfg(async_payments)]
 use super::async_payments::AsyncPaymentsMessage;
+use super::dns_resolution::{DNSResolverMessageHandler, DNSResolverMessage};
 use super::packet::OnionMessageContents;
 use super::packet::ParsedOnionMessageContents;
 use super::offers::OffersMessageHandler;
@@ -86,16 +87,20 @@ pub trait AOnionMessenger {
        type AsyncPaymentsMessageHandler: AsyncPaymentsMessageHandler + ?Sized;
        /// A type that may be dereferenced to [`Self::AsyncPaymentsMessageHandler`]
        type APH: Deref<Target = Self::AsyncPaymentsMessageHandler>;
+       /// A type implementing [`DNSResolverMessageHandler`]
+       type DNSResolverMessageHandler: DNSResolverMessageHandler + ?Sized;
+       /// A type that may be dereferenced to [`Self::DNSResolverMessageHandler`]
+       type DRH: Deref<Target = Self::DNSResolverMessageHandler>;
        /// A type implementing [`CustomOnionMessageHandler`]
        type CustomOnionMessageHandler: CustomOnionMessageHandler + ?Sized;
        /// A type that may be dereferenced to [`Self::CustomOnionMessageHandler`]
        type CMH: Deref<Target = Self::CustomOnionMessageHandler>;
        /// Returns a reference to the actual [`OnionMessenger`] object.
-       fn get_om(&self) -> &OnionMessenger<Self::ES, Self::NS, Self::L, Self::NL, Self::MR, Self::OMH, Self::APH, Self::CMH>;
+       fn get_om(&self) -> &OnionMessenger<Self::ES, Self::NS, Self::L, Self::NL, Self::MR, Self::OMH, Self::APH, Self::DRH, Self::CMH>;
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref> AOnionMessenger
-for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, DRH: Deref, CMH: Deref> AOnionMessenger
+for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, DRH, CMH> where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
        L::Target: Logger,
@@ -103,6 +108,7 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
        MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        APH:: Target: AsyncPaymentsMessageHandler,
+       DRH::Target: DNSResolverMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
        type EntropySource = ES::Target;
@@ -119,9 +125,11 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
        type OMH = OMH;
        type AsyncPaymentsMessageHandler = APH::Target;
        type APH = APH;
+       type DNSResolverMessageHandler = DRH::Target;
+       type DRH = DRH;
        type CustomOnionMessageHandler = CMH::Target;
        type CMH = CMH;
-       fn get_om(&self) -> &OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> { self }
+       fn get_om(&self) -> &OnionMessenger<ES, NS, L, NL, MR, OMH, APH, DRH, CMH> { self }
 }
 
 /// A sender, receiver and forwarder of [`OnionMessage`]s.
@@ -194,11 +202,13 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
 /// # let custom_message_handler = IgnoringMessageHandler {};
 /// # let offers_message_handler = IgnoringMessageHandler {};
 /// # let async_payments_message_handler = IgnoringMessageHandler {};
+/// # let dns_resolution_message_handler = IgnoringMessageHandler {};
 /// // Create the onion messenger. This must use the same `keys_manager` as is passed to your
 /// // ChannelManager.
 /// let onion_messenger = OnionMessenger::new(
 ///     &keys_manager, &keys_manager, logger, &node_id_lookup, message_router,
-///     &offers_message_handler, &async_payments_message_handler, &custom_message_handler
+///     &offers_message_handler, &async_payments_message_handler, &dns_resolution_message_handler,
+///     &custom_message_handler,
 /// );
 
 /// # #[derive(Debug)]
@@ -241,7 +251,7 @@ for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH> where
 /// [`InvoiceRequest`]: crate::offers::invoice_request::InvoiceRequest
 /// [`Bolt12Invoice`]: crate::offers::invoice::Bolt12Invoice
 pub struct OnionMessenger<
-       ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref
+       ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, DRH: Deref, CMH: Deref
 > where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -250,6 +260,7 @@ pub struct OnionMessenger<
        MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        APH::Target: AsyncPaymentsMessageHandler,
+       DRH::Target: DNSResolverMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
        entropy_source: ES,
@@ -262,6 +273,7 @@ pub struct OnionMessenger<
        offers_handler: OMH,
        #[allow(unused)]
        async_payments_handler: APH,
+       dns_resolver_handler: DRH,
        custom_handler: CMH,
        intercept_messages_for_offline_peers: bool,
        pending_intercepted_msgs_events: Mutex<Vec<Event>>,
@@ -986,6 +998,9 @@ where
                                (ParsedOnionMessageContents::Custom(_), Some(MessageContext::Custom(_))) => {
                                        Ok(PeeledOnion::Receive(message, context, reply_path))
                                }
+                               (ParsedOnionMessageContents::DNSResolver(_), Some(MessageContext::DNSResolver(_))) => {
+                                       Ok(PeeledOnion::Receive(message, context, reply_path))
+                               }
                                _ => {
                                        log_trace!(logger, "Received message was sent on a blinded path with the wrong context.");
                                        Err(())
@@ -1071,8 +1086,8 @@ macro_rules! drop_handled_events_and_abort { ($self: expr, $res_iter: expr, $eve
        }
 }}
 
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref>
-OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, DRH: Deref, CMH: Deref>
+OnionMessenger<ES, NS, L, NL, MR, OMH, APH, DRH, CMH>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -1081,17 +1096,18 @@ where
        MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        APH::Target: AsyncPaymentsMessageHandler,
+       DRH::Target: DNSResolverMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
        /// Constructs a new `OnionMessenger` to send, forward, and delegate received onion messages to
        /// their respective handlers.
        pub fn new(
                entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL, message_router: MR,
-               offers_handler: OMH, async_payments_handler: APH, custom_handler: CMH
+               offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH, custom_handler: CMH,
        ) -> Self {
                Self::new_inner(
                        entropy_source, node_signer, logger, node_id_lookup, message_router,
-                       offers_handler, async_payments_handler, custom_handler, false
+                       offers_handler, async_payments_handler, dns_resolver, custom_handler, false,
                )
        }
 
@@ -1118,18 +1134,19 @@ where
        /// peers.
        pub fn new_with_offline_peer_interception(
                entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL,
-               message_router: MR, offers_handler: OMH, async_payments_handler: APH, custom_handler: CMH
+               message_router: MR, offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH,
+               custom_handler: CMH,
        ) -> Self {
                Self::new_inner(
                        entropy_source, node_signer, logger, node_id_lookup, message_router,
-                       offers_handler, async_payments_handler, custom_handler, true
+                       offers_handler, async_payments_handler, dns_resolver, custom_handler, true,
                )
        }
 
        fn new_inner(
                entropy_source: ES, node_signer: NS, logger: L, node_id_lookup: NL,
-               message_router: MR, offers_handler: OMH, async_payments_handler: APH, custom_handler: CMH,
-               intercept_messages_for_offline_peers: bool
+               message_router: MR, offers_handler: OMH, async_payments_handler: APH, dns_resolver: DRH,
+               custom_handler: CMH, intercept_messages_for_offline_peers: bool,
        ) -> Self {
                let mut secp_ctx = Secp256k1::new();
                secp_ctx.seeded_randomize(&entropy_source.get_secure_random_bytes());
@@ -1143,6 +1160,7 @@ where
                        message_router,
                        offers_handler,
                        async_payments_handler,
+                       dns_resolver_handler: dns_resolver,
                        custom_handler,
                        intercept_messages_for_offline_peers,
                        pending_intercepted_msgs_events: Mutex::new(Vec::new()),
@@ -1479,8 +1497,8 @@ fn outbound_buffer_full(peer_node_id: &PublicKey, buffer: &HashMap<PublicKey, On
        false
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref> EventsProvider
-for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, DRH: Deref, CMH: Deref> EventsProvider
+for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, DRH, CMH>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -1489,6 +1507,7 @@ where
        MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        APH::Target: AsyncPaymentsMessageHandler,
+       DRH::Target: DNSResolverMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
        fn process_pending_events<H: Deref>(&self, handler: H) where H::Target: EventHandler {
@@ -1564,8 +1583,8 @@ where
        }
 }
 
-impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, CMH: Deref> OnionMessageHandler
-for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, CMH>
+impl<ES: Deref, NS: Deref, L: Deref, NL: Deref, MR: Deref, OMH: Deref, APH: Deref, DRH: Deref, CMH: Deref> OnionMessageHandler
+for OnionMessenger<ES, NS, L, NL, MR, OMH, APH, DRH, CMH>
 where
        ES::Target: EntropySource,
        NS::Target: NodeSigner,
@@ -1574,6 +1593,7 @@ where
        MR::Target: MessageRouter,
        OMH::Target: OffersMessageHandler,
        APH::Target: AsyncPaymentsMessageHandler,
+       DRH::Target: DNSResolverMessageHandler,
        CMH::Target: CustomOnionMessageHandler,
 {
        fn handle_onion_message(&self, peer_node_id: PublicKey, msg: &OnionMessage) {
@@ -1622,6 +1642,19 @@ where
                                                };
                                                self.async_payments_handler.release_held_htlc(msg, context);
                                        },
+                                       ParsedOnionMessageContents::DNSResolver(DNSResolverMessage::DNSSECQuery(msg)) => {
+                                               let response_instructions = self.dns_resolver_handler.handle_dnssec_query(msg, responder);
+                                               if let Some((msg, instructions)) = response_instructions {
+                                                       let _ = self.handle_onion_message_response(msg, instructions);
+                                               }
+                                       },
+                                       ParsedOnionMessageContents::DNSResolver(DNSResolverMessage::DNSSECProof(msg)) => {
+                                               let context = match context {
+                                                       Some(MessageContext::DNSResolver(context)) => context,
+                                                       _ => return,
+                                               };
+                                               self.dns_resolver_handler.handle_dnssec_proof(msg, context);
+                                       },
                                        ParsedOnionMessageContents::Custom(msg) => {
                                                let context = match context {
                                                        None => None,
@@ -1773,6 +1806,13 @@ where
                        }
                }
 
+               // Enqueue any initiating `DNSResolverMessage`s to send.
+               for (message, instructions) in self.dns_resolver_handler.release_pending_messages() {
+                       let _ = self.send_onion_message_internal(
+                               message, instructions, format_args!("when sending DNSResolverMessage")
+                       );
+               }
+
                // Enqueue any initiating `CustomMessage`s to send.
                for (message, instructions) in self.custom_handler.release_pending_custom_messages() {
                        let _ = self.send_onion_message_internal(
@@ -1804,6 +1844,7 @@ pub type SimpleArcOnionMessenger<M, T, F, L> = OnionMessenger<
        Arc<DefaultMessageRouter<Arc<NetworkGraph<Arc<L>>>, Arc<L>, Arc<KeysManager>>>,
        Arc<SimpleArcChannelManager<M, T, F, L>>,
        Arc<SimpleArcChannelManager<M, T, F, L>>,
+       IgnoringMessageHandler, // TODO: Swap for ChannelManager (when built with the "dnssec" feature)
        IgnoringMessageHandler
 >;
 
@@ -1825,6 +1866,7 @@ pub type SimpleRefOnionMessenger<
        &'i DefaultMessageRouter<&'g NetworkGraph<&'b L>, &'b L, &'a KeysManager>,
        &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>,
        &'j SimpleRefChannelManager<'a, 'b, 'c, 'd, 'e, 'f, 'g, 'h, 'i, M, T, F, L>,
+       IgnoringMessageHandler, // TODO: Swap for ChannelManager (when built with the "dnssec" feature)
        IgnoringMessageHandler
 >;
 
index f65ed0d53ed39078929ac11fe0a07696ca7c828e..8ec85a6bed7aba02d373f74d74306adafc1973d3 100644 (file)
@@ -18,6 +18,7 @@ use crate::ln::msgs::DecodeError;
 use crate::ln::onion_utils;
 #[cfg(async_payments)]
 use super::async_payments::AsyncPaymentsMessage;
+use super::dns_resolution::DNSResolverMessage;
 use super::messenger::CustomOnionMessageHandler;
 use super::offers::OffersMessage;
 use crate::crypto::streams::{ChaChaPolyReadAdapter, ChaChaPolyWriteAdapter};
@@ -132,6 +133,8 @@ pub enum ParsedOnionMessageContents<T: OnionMessageContents> {
        /// A message related to async payments.
        #[cfg(async_payments)]
        AsyncPayments(AsyncPaymentsMessage),
+       /// A message requesting or providing a DNSSEC proof
+       DNSResolver(DNSResolverMessage),
        /// A custom onion message specified by the user.
        Custom(T),
 }
@@ -145,6 +148,7 @@ impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContent
                        &ParsedOnionMessageContents::Offers(ref msg) => msg.tlv_type(),
                        #[cfg(async_payments)]
                        &ParsedOnionMessageContents::AsyncPayments(ref msg) => msg.tlv_type(),
+                       &ParsedOnionMessageContents::DNSResolver(ref msg) => msg.tlv_type(),
                        &ParsedOnionMessageContents::Custom(ref msg) => msg.tlv_type(),
                }
        }
@@ -154,6 +158,7 @@ impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContent
                        ParsedOnionMessageContents::Offers(ref msg) => msg.msg_type(),
                        #[cfg(async_payments)]
                        ParsedOnionMessageContents::AsyncPayments(ref msg) => msg.msg_type(),
+                       ParsedOnionMessageContents::DNSResolver(ref msg) => msg.msg_type(),
                        ParsedOnionMessageContents::Custom(ref msg) => msg.msg_type(),
                }
        }
@@ -163,6 +168,7 @@ impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContent
                        ParsedOnionMessageContents::Offers(ref msg) => msg.msg_type(),
                        #[cfg(async_payments)]
                        ParsedOnionMessageContents::AsyncPayments(ref msg) => msg.msg_type(),
+                       ParsedOnionMessageContents::DNSResolver(ref msg) => msg.msg_type(),
                        ParsedOnionMessageContents::Custom(ref msg) => msg.msg_type(),
                }
        }
@@ -171,10 +177,11 @@ impl<T: OnionMessageContents> OnionMessageContents for ParsedOnionMessageContent
 impl<T: OnionMessageContents> Writeable for ParsedOnionMessageContents<T> {
        fn write<W: Writer>(&self, w: &mut W) -> Result<(), io::Error> {
                match self {
-                       ParsedOnionMessageContents::Offers(msg) => Ok(msg.write(w)?),
+                       ParsedOnionMessageContents::Offers(msg) => msg.write(w),
                        #[cfg(async_payments)]
-                       ParsedOnionMessageContents::AsyncPayments(msg) => Ok(msg.write(w)?),
-                       ParsedOnionMessageContents::Custom(msg) => Ok(msg.write(w)?),
+                       ParsedOnionMessageContents::AsyncPayments(msg) => msg.write(w),
+                       ParsedOnionMessageContents::DNSResolver(msg) => msg.write(w),
+                       ParsedOnionMessageContents::Custom(msg) => msg.write(w),
                }
        }
 }
@@ -286,6 +293,11 @@ for Payload<ParsedOnionMessageContents<<H as CustomOnionMessageHandler>::CustomM
                                        message = Some(ParsedOnionMessageContents::AsyncPayments(msg));
                                        Ok(true)
                                },
+                               tlv_type if DNSResolverMessage::is_known_type(tlv_type) => {
+                                       let msg = DNSResolverMessage::read(msg_reader, tlv_type)?;
+                                       message = Some(ParsedOnionMessageContents::DNSResolver(msg));
+                                       Ok(true)
+                               },
                                _ => match handler.read_custom_message(msg_type, msg_reader)? {
                                        Some(msg) => {
                                                message = Some(ParsedOnionMessageContents::Custom(msg));