Skip to content

Commit 818cf06

Browse files
rustyrussellendothermicdev
authored andcommitted
common: translate legacy onion payloads.
We do this by literally creating the modern-style TLV, and pretending we found it in the onion. This isolates us from messing with any callers, who don't even know. Co-programmed-with: Alex Myers <[email protected]> Signed-off-by: Rusty Russell <[email protected]> Fixes: #7347 Changelog-Fixed: Protocol: forward legacy non-TLV onions which we removed in 22.11 and spec itself in Feb 2022. Still sent by LND nodes who haven't seen our node_announcement.
1 parent a473217 commit 818cf06

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

common/sphinx.c

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -667,12 +667,55 @@ struct route_step *process_onionpacket(
667667

668668
/* Any of these could fail, falling thru with cursor == NULL */
669669
payload_size = fromwire_bigsize(&cursor, &max);
670-
/* FIXME: raw_payload *includes* the length, which is redundant and
671-
* means we can't just ust fromwire_tal_arrn. */
672-
fromwire_pad(&cursor, &max, payload_size);
673-
if (cursor != NULL)
674-
step->raw_payload = tal_dup_arr(step, u8, paddedheader,
675-
cursor - paddedheader, 0);
670+
671+
/* Legacy! 0 length payload means fixed 32 byte structure */
672+
if (payload_size == 0 && max >= 32) {
673+
struct tlv_payload *legacy = tlv_payload_new(tmpctx);
674+
const u8 *legacy_cursor = cursor;
675+
size_t legacy_max = 32;
676+
u8 *onwire_tlv;
677+
678+
legacy->amt_to_forward = tal(legacy, u64);
679+
legacy->outgoing_cltv_value = tal(legacy, u32);
680+
legacy->short_channel_id = tal(legacy, struct short_channel_id);
681+
682+
/* BOLT-obsolete #4:
683+
* ## Legacy `hop_data` payload format
684+
*
685+
* The `hop_data` format is identified by a single `0x00`-byte
686+
* length, for backward compatibility. Its payload is defined
687+
* as:
688+
*
689+
* 1. type: `hop_data` (for `realm` 0)
690+
* 2. data:
691+
* * [`short_channel_id`:`short_channel_id`]
692+
* * [`u64`:`amt_to_forward`]
693+
* * [`u32`:`outgoing_cltv_value`]
694+
* * [`12*byte`:`padding`]
695+
*/
696+
*legacy->short_channel_id = fromwire_short_channel_id(&legacy_cursor, &legacy_max);
697+
*legacy->amt_to_forward = fromwire_u64(&legacy_cursor, &legacy_max);
698+
*legacy->outgoing_cltv_value = fromwire_u32(&legacy_cursor, &legacy_max);
699+
700+
/* Re-linearize it as a modern TLV! */
701+
onwire_tlv = tal_arr(tmpctx, u8, 0);
702+
towire_tlv_payload(&onwire_tlv, legacy);
703+
704+
/* Length, then tlv */
705+
step->raw_payload = tal_arr(step, u8, 0);
706+
towire_bigsize(&step->raw_payload, tal_bytelen(onwire_tlv));
707+
towire_u8_array(&step->raw_payload, onwire_tlv, tal_bytelen(onwire_tlv));
708+
709+
payload_size = 32;
710+
fromwire_pad(&cursor, &max, payload_size);
711+
} else {
712+
/* FIXME: raw_payload *includes* the length, which is redundant and
713+
* means we can't just ust fromwire_tal_arrn. */
714+
fromwire_pad(&cursor, &max, payload_size);
715+
if (cursor != NULL)
716+
step->raw_payload = tal_dup_arr(step, u8, paddedheader,
717+
cursor - paddedheader, 0);
718+
}
676719
fromwire_hmac(&cursor, &max, &step->next->hmac);
677720

678721
/* BOLT #4:

common/test/run-sphinx-xor_cipher_stream.c

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ void subkey_from_hmac(const char *prefix UNNEEDED,
108108
const struct secret *base UNNEEDED,
109109
struct secret *key UNNEEDED)
110110
{ fprintf(stderr, "subkey_from_hmac called!\n"); abort(); }
111+
/* Generated stub for tlv_payload_new */
112+
struct tlv_payload *tlv_payload_new(const tal_t *ctx UNNEEDED)
113+
{ fprintf(stderr, "tlv_payload_new called!\n"); abort(); }
111114
/* Generated stub for towire */
112115
void towire(u8 **pptr UNNEEDED, const void *data UNNEEDED, size_t len UNNEEDED)
113116
{ fprintf(stderr, "towire called!\n"); abort(); }
@@ -133,6 +136,9 @@ void towire_secp256k1_ecdsa_signature(u8 **pptr UNNEEDED,
133136
/* Generated stub for towire_sha256 */
134137
void towire_sha256(u8 **pptr UNNEEDED, const struct sha256 *sha256 UNNEEDED)
135138
{ fprintf(stderr, "towire_sha256 called!\n"); abort(); }
139+
/* Generated stub for towire_tlv_payload */
140+
void towire_tlv_payload(u8 **pptr UNNEEDED, const struct tlv_payload *record UNNEEDED)
141+
{ fprintf(stderr, "towire_tlv_payload called!\n"); abort(); }
136142
/* Generated stub for towire_u16 */
137143
void towire_u16(u8 **pptr UNNEEDED, u16 v UNNEEDED)
138144
{ fprintf(stderr, "towire_u16 called!\n"); abort(); }

tests/test_pay.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5662,7 +5662,6 @@ def test_pay_while_opening_channel(node_factory, bitcoind, executor):
56625662
l1.rpc.pay(inv['bolt11'])
56635663

56645664

5665-
@pytest.mark.xfail(strict=True)
56665665
def test_pay_legacy_forward(node_factory, bitcoind, executor):
56675666
"""We removed legacy in 22.11, and LND will still send them for
56685667
route hints! See

0 commit comments

Comments
 (0)