@@ -181,17 +181,34 @@ pub enum SendError {
181181///
182182/// [`IgnoringMessageHandler`]: crate::ln::peer_handler::IgnoringMessageHandler
183183/// [`CustomMessage`]: Self::CustomMessage
184- pub trait CustomOnionMessageHandler {
184+ pub trait CustomOnionMessageHandler : ResponseErrorHandler {
185185 /// The message known to the handler. To support multiple message types, you may want to make this
186186 /// an enum with a variant for each supported message.
187187 type CustomMessage : CustomOnionMessageContents ;
188- /// Called with the custom message that was received.
189- fn handle_custom_message ( & self , msg : Self :: CustomMessage ) ;
188+
189+ /// Called with the custom message that was received, returning a response to send, if any.
190+ fn handle_custom_message ( & self , msg : Self :: CustomMessage ) -> Option < Self :: CustomMessage > ;
191+
190192 /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
191193 /// message type is unknown.
192194 fn read_custom_message < R : io:: Read > ( & self , message_type : u64 , buffer : & mut R ) -> Result < Option < Self :: CustomMessage > , msgs:: DecodeError > ;
193195}
194196
197+ ///
198+ pub trait ResponseErrorHandler {
199+ /// Called if an error occurred when sending a response to the handled message.
200+ fn handle_response_error ( & self , error : ResponseError ) ;
201+ }
202+
203+ ///
204+ #[ derive( Debug , PartialEq , Eq ) ]
205+ pub enum ResponseError {
206+ ///
207+ NoReplyPath ,
208+ ///
209+ Sending ( SendError ) ,
210+ }
211+
195212impl < ES : Deref , NS : Deref , L : Deref , OMH : Deref , CMH : Deref > OnionMessenger < ES , NS , L , OMH , CMH >
196213where
197214 ES :: Target : EntropySource ,
@@ -272,6 +289,38 @@ where
272289 }
273290 }
274291
292+ fn respond_with_onion_message < T : CustomOnionMessageContents , EH : ResponseErrorHandler > (
293+ & self , response : OnionMessageContents < T > , path_id : Option < [ u8 ; 32 ] > ,
294+ reply_path : Option < BlindedPath > , error_handler : & EH
295+ ) {
296+ match reply_path {
297+ Some ( reply_path) => {
298+ let intermediate_nodes = vec ! [ ] ; // TODO: replace with Router trait
299+ let destination = Destination :: BlindedPath ( reply_path) ;
300+
301+ log_info ! ( self . logger, "Responding to onion message with path_id {:02x?}" , path_id) ;
302+ let send_result = self . send_onion_message (
303+ & intermediate_nodes, destination, response, None
304+ ) ;
305+
306+ if let Err ( e) = send_result {
307+ log_info ! (
308+ self . logger,
309+ "Failed responding to onion message with path_id {:02x?}: {:?}" , path_id, e
310+ ) ;
311+ error_handler. handle_response_error ( ResponseError :: Sending ( e) ) ;
312+ }
313+ } ,
314+ None => {
315+ log_info ! (
316+ self . logger, "No reply path to respond to onion message with path_id {:02x?}" ,
317+ path_id
318+ ) ;
319+ error_handler. handle_response_error ( ResponseError :: NoReplyPath ) ;
320+ } ,
321+ }
322+ }
323+
275324 #[ cfg( test) ]
276325 pub ( super ) fn release_pending_msgs ( & self ) -> HashMap < PublicKey , VecDeque < msgs:: OnionMessage > > {
277326 let mut pending_msgs = self . pending_messages . lock ( ) . unwrap ( ) ;
@@ -314,7 +363,7 @@ where
314363 ES :: Target : EntropySource ,
315364 NS :: Target : NodeSigner ,
316365 L :: Target : Logger ,
317- OMH :: Target : OffersMessageHandler ,
366+ OMH :: Target : OffersMessageHandler + Sized ,
318367 CMH :: Target : CustomOnionMessageHandler + Sized ,
319368{
320369 /// Handle an incoming onion message. Currently, if a message was destined for us we will log, but
@@ -353,9 +402,27 @@ where
353402 log_info!( self . logger,
354403 "Received an onion message with path_id {:02x?} and {} reply_path" ,
355404 path_id, if reply_path. is_some ( ) { "a" } else { "no" } ) ;
356- match message {
357- OnionMessageContents :: Offers ( msg) => self . offers_handler . handle_message ( msg) ,
358- OnionMessageContents :: Custom ( msg) => self . custom_handler . handle_custom_message ( msg) ,
405+
406+ let response = match message {
407+ OnionMessageContents :: Offers ( msg) => {
408+ self . offers_handler . handle_message ( msg)
409+ . map ( |msg| OnionMessageContents :: Offers ( msg) )
410+ } ,
411+ OnionMessageContents :: Custom ( msg) => {
412+ self . custom_handler . handle_custom_message ( msg)
413+ . map ( |msg| OnionMessageContents :: Custom ( msg) )
414+ } ,
415+ } ;
416+
417+ if let Some ( response) = response {
418+ match response {
419+ OnionMessageContents : : Offers ( _) => self . respond_with_onion_message (
420+ response, path_id, reply_path, & * self . offers_handler
421+ ) ,
422+ OnionMessageContents : : Custom ( _) => self . respond_with_onion_message (
423+ response, path_id, reply_path, & * self . custom_handler
424+ ) ,
425+ }
359426 }
360427 } ,
361428 Ok ( ( Payload :: Forward ( ForwardControlTlvs :: Unblinded ( ForwardTlvs {
0 commit comments