Browse Source

channeld: handle wrapping error messages messages.

Currently lightningd does this, but channeld is perfectly capable of doing it.
channeld is also in a far better position to add channel_updates to it.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
ee8274b7a1
  1. 22
      channeld/channel.c
  2. 6
      channeld/channel_wire.csv
  3. 13
      lightningd/peer_htlcs.c

22
channeld/channel.c

@ -1990,35 +1990,37 @@ static void handle_fail(struct peer *peer, const u8 *inmsg)
u8 *msg; u8 *msg;
u64 id; u64 id;
u8 *errpkt; u8 *errpkt;
u16 malformed; u16 failcode;
enum channel_remove_err e; enum channel_remove_err e;
struct htlc *h; struct htlc *h;
if (!fromwire_channel_fail_htlc(inmsg, inmsg, NULL, &id, &malformed, if (!fromwire_channel_fail_htlc(inmsg, inmsg, NULL, &id, &errpkt,
&errpkt)) &failcode))
master_badmsg(WIRE_CHANNEL_FAIL_HTLC, inmsg); master_badmsg(WIRE_CHANNEL_FAIL_HTLC, inmsg);
if (malformed && !(malformed & BADONION)) if ((failcode & BADONION) && tal_len(errpkt))
status_failed(STATUS_FAIL_MASTER_IO, status_failed(STATUS_FAIL_MASTER_IO,
"Invalid channel_fail_htlc: bad malformed 0x%x", "Invalid channel_fail_htlc: %s with errpkt?",
malformed); onion_type_name(failcode));
e = channel_fail_htlc(peer->channel, REMOTE, id, &h); e = channel_fail_htlc(peer->channel, REMOTE, id, &h);
switch (e) { switch (e) {
case CHANNEL_ERR_REMOVE_OK: case CHANNEL_ERR_REMOVE_OK:
if (malformed) { if (failcode & BADONION) {
struct sha256 sha256_of_onion; struct sha256 sha256_of_onion;
status_trace("Failing %"PRIu64" with code %u", status_trace("Failing %"PRIu64" with code %u",
id, malformed); id, failcode);
sha256(&sha256_of_onion, h->routing, sha256(&sha256_of_onion, h->routing,
tal_len(h->routing)); tal_len(h->routing));
msg = towire_update_fail_malformed_htlc(peer, msg = towire_update_fail_malformed_htlc(peer,
&peer->channel_id, &peer->channel_id,
id, &sha256_of_onion, id, &sha256_of_onion,
malformed); failcode);
} else { } else {
u8 *reply = wrap_onionreply(inmsg, h->shared_secret,
errpkt);
msg = towire_update_fail_htlc(peer, &peer->channel_id, msg = towire_update_fail_htlc(peer, &peer->channel_id,
id, errpkt); id, reply);
} }
msg_enqueue(&peer->peer_out, take(msg)); msg_enqueue(&peer->peer_out, take(msg));
start_commit_timer(peer); start_commit_timer(peer);

6
channeld/channel_wire.csv

@ -92,11 +92,11 @@ channel_fulfill_htlc,,payment_preimage,struct preimage
# Main daemon says HTLC failed # Main daemon says HTLC failed
channel_fail_htlc,1006 channel_fail_htlc,1006
channel_fail_htlc,,id,u64 channel_fail_htlc,,id,u64
# If malformed is non-zero, it's a BADONION code # If this is non-zero length, you need to wrap this and pass it on.
channel_fail_htlc,,malformed,u16
# Otherwise, error_pkt contains failreason.
channel_fail_htlc,,len,u16 channel_fail_htlc,,len,u16
channel_fail_htlc,,error_pkt,len*u8 channel_fail_htlc,,error_pkt,len*u8
# If it errcode is != 0, it's a local error, otherwise we're passing thru.
channel_fail_htlc,,errcode,u16
# Ping/pong test. # Ping/pong test.
channel_ping,1011 channel_ping,1011

Can't render this file because it has a wrong number of fields in line 2.

13
lightningd/peer_htlcs.c

@ -99,18 +99,13 @@ static void fail_in_htlc(struct htlc_in *hin,
subd_send_msg(hin->key.peer->owner, subd_send_msg(hin->key.peer->owner,
take(towire_channel_fail_htlc(hin, take(towire_channel_fail_htlc(hin,
hin->key.id, hin->key.id,
hin->failcode, NULL,
NULL))); hin->failcode)));
} else { } else {
u8 *reply;
/* This obfuscates the message, whether local or forwarded. */
reply = wrap_onionreply(hin, &hin->shared_secret,
hin->failuremsg);
subd_send_msg(hin->key.peer->owner, subd_send_msg(hin->key.peer->owner,
take(towire_channel_fail_htlc(hin, hin->key.id, take(towire_channel_fail_htlc(hin, hin->key.id,
0, reply))); hin->failuremsg,
tal_free(reply); 0)));
} }
} }

Loading…
Cancel
Save