@@ -224,8 +224,10 @@ pub trait CustomOnionMessageHandler {
224224 /// The message known to the handler. To support multiple message types, you may want to make this
225225 /// an enum with a variant for each supported message.
226226 type CustomMessage : CustomOnionMessageContents ;
227- /// Called with the custom message that was received.
228- fn handle_custom_message ( & self , msg : Self :: CustomMessage ) ;
227+
228+ /// Called with the custom message that was received, returning a response to send, if any.
229+ fn handle_custom_message ( & self , msg : Self :: CustomMessage ) -> Option < Self :: CustomMessage > ;
230+
229231 /// Read a custom message of type `message_type` from `buffer`, returning `Ok(None)` if the
230232 /// message type is unknown.
231233 fn read_custom_message < R : io:: Read > ( & self , message_type : u64 , buffer : & mut R ) -> Result < Option < Self :: CustomMessage > , msgs:: DecodeError > ;
@@ -320,6 +322,56 @@ where
320322 }
321323 }
322324
325+ fn respond_with_onion_message < T : CustomOnionMessageContents > (
326+ & self , response : OnionMessageContents < T > , path_id : Option < [ u8 ; 32 ] > ,
327+ reply_path : Option < BlindedPath >
328+ ) {
329+ let sender = match self . node_signer . get_node_id ( Recipient :: Node ) {
330+ Ok ( node_id) => node_id,
331+ Err ( _) => {
332+ log_warn ! (
333+ self . logger, "Unable to retrieve node id when responding to onion message with \
334+ path_id {:02x?}", path_id
335+ ) ;
336+ return ;
337+ }
338+ } ;
339+
340+ let peers = self . pending_messages . lock ( ) . unwrap ( ) . keys ( ) . copied ( ) . collect ( ) ;
341+
342+ let destination = match reply_path {
343+ Some ( reply_path) => Destination :: BlindedPath ( reply_path) ,
344+ None => {
345+ log_trace ! (
346+ self . logger, "Missing reply path when responding to onion message with path_id \
347+ {:02x?}", path_id
348+ ) ;
349+ return ;
350+ } ,
351+ } ;
352+
353+ let path = match self . message_router . find_path ( sender, peers, destination) {
354+ Ok ( path) => path,
355+ Err ( ( ) ) => {
356+ log_trace ! (
357+ self . logger, "Failed to find path when responding to onion message with \
358+ path_id {:02x?}", path_id
359+ ) ;
360+ return ;
361+ } ,
362+ } ;
363+
364+ log_trace ! ( self . logger, "Responding to onion message with path_id {:02x?}" , path_id) ;
365+
366+ if let Err ( e) = self . send_onion_message ( path, response, None ) {
367+ log_trace ! (
368+ self . logger, "Failed responding to onion message with path_id {:02x?}: {:?}" ,
369+ path_id, e
370+ ) ;
371+ return ;
372+ }
373+ }
374+
323375 #[ cfg( test) ]
324376 pub ( super ) fn release_pending_msgs ( & self ) -> HashMap < PublicKey , VecDeque < msgs:: OnionMessage > > {
325377 let mut pending_msgs = self . pending_messages . lock ( ) . unwrap ( ) ;
@@ -403,9 +455,20 @@ where
403455 log_info!( self . logger,
404456 "Received an onion message with path_id {:02x?} and {} reply_path" ,
405457 path_id, if reply_path. is_some ( ) { "a" } else { "no" } ) ;
406- match message {
407- OnionMessageContents :: Offers ( msg) => self . offers_handler . handle_message ( msg) ,
408- OnionMessageContents :: Custom ( msg) => self . custom_handler . handle_custom_message ( msg) ,
458+
459+ let response = match message {
460+ OnionMessageContents :: Offers ( msg) => {
461+ self . offers_handler . handle_message ( msg)
462+ . map ( |msg| OnionMessageContents :: Offers ( msg) )
463+ } ,
464+ OnionMessageContents :: Custom ( msg) => {
465+ self . custom_handler . handle_custom_message ( msg)
466+ . map ( |msg| OnionMessageContents :: Custom ( msg) )
467+ } ,
468+ } ;
469+
470+ if let Some ( response) = response {
471+ self. respond_with_onion_message ( response, path_id, reply_path) ;
409472 }
410473 } ,
411474 Ok ( ( Payload :: Forward ( ForwardControlTlvs :: Unblinded ( ForwardTlvs {
0 commit comments