@@ -1462,9 +1462,10 @@ impl HTLCFailReason {
14621462 pub ( super ) fn get_encrypted_failure_packet (
14631463 & self , incoming_packet_shared_secret : & [ u8 ; 32 ] , phantom_shared_secret : & Option < [ u8 ; 32 ] > ,
14641464 ) -> msgs:: OnionErrorPacket {
1465+ let payload: [ u8 ; 4 ] = [ 1 ; 4 ] ;
1466+
14651467 match self . 0 {
14661468 HTLCFailReasonRepr :: Reason { ref failure_code, ref data } => {
1467- let payload = [ 1 ; 4 ] ;
14681469 if let Some ( phantom_ss) = phantom_shared_secret {
14691470 let mut phantom_packet =
14701471 build_failure_packet ( phantom_ss, * failure_code, & data[ ..] , & payload) ;
@@ -1489,6 +1490,8 @@ impl HTLCFailReason {
14891490 } ,
14901491 HTLCFailReasonRepr :: LightningError { ref err } => {
14911492 let mut err = err. clone ( ) ;
1493+
1494+ process_failure_packet ( & mut err, incoming_packet_shared_secret, & payload) ;
14921495 encrypt_failure_packet ( incoming_packet_shared_secret, & mut err) ;
14931496
14941497 err
@@ -1954,39 +1957,44 @@ fn process_failure_packet(onion_error: &mut OnionErrorPacket, shared_secret: &[u
19541957 // Create new packet.
19551958 let mut processed_packet = [ 0 ; ATTRIBUTION_DATA_LEN ] ;
19561959
1957- // Shift payloads right.
1958- {
1959- let payloads = & onion_error. attribution_data . as_ref ( ) . unwrap ( ) [ ..MAX_HOPS * PAYLOAD_LEN ] ; // XXX: This will break if we get an err from an unupgraded node
1960- processed_packet[ PAYLOAD_LEN ..MAX_HOPS * PAYLOAD_LEN ] . copy_from_slice ( & payloads[ ..payloads. len ( ) -PAYLOAD_LEN ] ) ;
1960+ // Process received attribution data. If there's none, we'll still add our payload and hmacs to potentially give the
1961+ // sender attribution data for the partial path. In order for this to work, all upstream nodes need to support
1962+ // attributable failures.
1963+ if let Some ( ref attribution_data) = onion_error. attribution_data {
1964+ // Shift payloads right.
1965+ {
1966+ let payloads = & attribution_data[ ..MAX_HOPS * PAYLOAD_LEN ] ;
1967+ processed_packet[ PAYLOAD_LEN ..MAX_HOPS * PAYLOAD_LEN ] . copy_from_slice ( & payloads[ ..payloads. len ( ) -PAYLOAD_LEN ] ) ;
1968+ }
19611969
1962- // Add this node's payload.
1963- processed_packet[ 0 ..PAYLOAD_LEN ] . copy_from_slice ( payload) ;
1964- }
1970+ // Shift hmacs right.
1971+ {
1972+ let hmacs = & attribution_data[ MAX_HOPS * PAYLOAD_LEN ..] ;
1973+ let processed_hmacs = & mut processed_packet[ MAX_HOPS * PAYLOAD_LEN ..] ;
19651974
1966- // Shift hmacs right.
1967- {
1968- let hmacs = & onion_error. attribution_data . as_ref ( ) . unwrap ( ) [ MAX_HOPS * PAYLOAD_LEN ..] ; // XXX: This will break if we get an err from an unupgraded node
1969- let processed_hmacs = & mut processed_packet[ MAX_HOPS * PAYLOAD_LEN ..] ;
1975+ let mut src_idx = HMAC_COUNT - 2 ;
1976+ let mut dest_idx = HMAC_COUNT - 1 ;
1977+ let mut copy_len = 1 ;
19701978
1971- let mut src_idx = HMAC_COUNT - 2 ;
1972- let mut dest_idx = HMAC_COUNT - 1 ;
1973- let mut copy_len = 1 ;
1979+ for i in 0 .. MAX_HOPS - 1 {
1980+ processed_hmacs [ dest_idx * HMAC_LEN .. ( dest_idx + copy_len ) * HMAC_LEN ] .
1981+ copy_from_slice ( & hmacs [ src_idx * HMAC_LEN .. ( src_idx + copy_len) * HMAC_LEN ] ) ;
19741982
1975- for i in 0 ..MAX_HOPS - 1 {
1976- processed_hmacs[ dest_idx * HMAC_LEN ..( dest_idx + copy_len) * HMAC_LEN ] .
1977- copy_from_slice ( & hmacs[ src_idx * HMAC_LEN ..( src_idx + copy_len) * HMAC_LEN ] ) ;
1983+ // Break at last iteration to prevent underflow when updating indices.
1984+ if i == MAX_HOPS - 2 {
1985+ break ;
1986+ }
19781987
1979- // Break at last iteration to prevent underflow when updating indices.
1980- if i == MAX_HOPS - 2 {
1981- break ;
1988+ copy_len += 1 ;
1989+ src_idx -= copy_len + 1 ;
1990+ dest_idx -= copy_len ;
19821991 }
1983-
1984- copy_len += 1 ;
1985- src_idx -= copy_len + 1 ;
1986- dest_idx -= copy_len;
19871992 }
19881993 }
19891994
1995+ // Add this node's payload.
1996+ processed_packet[ 0 ..PAYLOAD_LEN ] . copy_from_slice ( payload) ;
1997+
19901998 // Add this node's hmacs.
19911999 add_hmacs ( & shared_secret, & onion_error. data , & mut processed_packet) ;
19922000
0 commit comments