mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 14:42:40 +01:00
channeld: implement malformed HTLC message.
I implemented this because a bug causes us to consider the HTLC malformed, so I can trivially test it for now. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
39115717f6
commit
09e489030c
2 changed files with 96 additions and 7 deletions
|
@ -830,6 +830,47 @@ static void handle_peer_fail_htlc(struct peer *peer, const u8 *msg)
|
||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void handle_peer_fail_malformed_htlc(struct peer *peer, const u8 *msg)
|
||||||
|
{
|
||||||
|
struct channel_id channel_id;
|
||||||
|
u64 id;
|
||||||
|
enum channel_remove_err e;
|
||||||
|
struct sha256 sha256_of_onion;
|
||||||
|
u16 failcode;
|
||||||
|
|
||||||
|
if (!fromwire_update_fail_malformed_htlc(msg, NULL, &channel_id, &id,
|
||||||
|
&sha256_of_onion, &failcode)) {
|
||||||
|
peer_failed(io_conn_fd(peer->peer_conn),
|
||||||
|
&peer->pcs.cs,
|
||||||
|
&peer->channel_id,
|
||||||
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||||
|
"Bad update_fail_malformed_htlc %s",
|
||||||
|
tal_hex(msg, msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
e = channel_fail_htlc(peer->channel, LOCAL, id);
|
||||||
|
switch (e) {
|
||||||
|
case CHANNEL_ERR_REMOVE_OK:
|
||||||
|
msg = towire_channel_malformed_htlc(msg, id, &sha256_of_onion,
|
||||||
|
failcode);
|
||||||
|
daemon_conn_send(&peer->master, take(msg));
|
||||||
|
start_commit_timer(peer);
|
||||||
|
return;
|
||||||
|
case CHANNEL_ERR_NO_SUCH_ID:
|
||||||
|
case CHANNEL_ERR_ALREADY_FULFILLED:
|
||||||
|
case CHANNEL_ERR_HTLC_UNCOMMITTED:
|
||||||
|
case CHANNEL_ERR_HTLC_NOT_IRREVOCABLE:
|
||||||
|
case CHANNEL_ERR_BAD_PREIMAGE:
|
||||||
|
peer_failed(io_conn_fd(peer->peer_conn),
|
||||||
|
&peer->pcs.cs,
|
||||||
|
&peer->channel_id,
|
||||||
|
WIRE_CHANNEL_PEER_BAD_MESSAGE,
|
||||||
|
"Bad update_fail_malformed_htlc: failed to remove %"
|
||||||
|
PRIu64 " error %u", id, e);
|
||||||
|
}
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
|
||||||
static void handle_ping(struct peer *peer, const u8 *msg)
|
static void handle_ping(struct peer *peer, const u8 *msg)
|
||||||
{
|
{
|
||||||
u8 *pong;
|
u8 *pong;
|
||||||
|
@ -914,6 +955,9 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
|
||||||
case WIRE_UPDATE_FAIL_HTLC:
|
case WIRE_UPDATE_FAIL_HTLC:
|
||||||
handle_peer_fail_htlc(peer, msg);
|
handle_peer_fail_htlc(peer, msg);
|
||||||
goto done;
|
goto done;
|
||||||
|
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
|
||||||
|
handle_peer_fail_malformed_htlc(peer, msg);
|
||||||
|
goto done;
|
||||||
case WIRE_PING:
|
case WIRE_PING:
|
||||||
handle_ping(peer, msg);
|
handle_ping(peer, msg);
|
||||||
goto done;
|
goto done;
|
||||||
|
@ -931,7 +975,6 @@ static struct io_plan *peer_in(struct io_conn *conn, struct peer *peer, u8 *msg)
|
||||||
|
|
||||||
case WIRE_SHUTDOWN:
|
case WIRE_SHUTDOWN:
|
||||||
case WIRE_CLOSING_SIGNED:
|
case WIRE_CLOSING_SIGNED:
|
||||||
case WIRE_UPDATE_FAIL_MALFORMED_HTLC:
|
|
||||||
case WIRE_UPDATE_FEE:
|
case WIRE_UPDATE_FEE:
|
||||||
peer_failed(io_conn_fd(peer->peer_conn),
|
peer_failed(io_conn_fd(peer->peer_conn),
|
||||||
&peer->pcs.cs,
|
&peer->pcs.cs,
|
||||||
|
|
|
@ -645,9 +645,6 @@ static void fail_htlc(struct peer *peer, u64 htlc_id, const u8 *msg)
|
||||||
log_broken(peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)",
|
log_broken(peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)",
|
||||||
htlc_id, failcode, onion_type_name(failcode));
|
htlc_id, failcode, onion_type_name(failcode));
|
||||||
|
|
||||||
/* We don't do BADONION here */
|
|
||||||
assert(!(failcode & BADONION));
|
|
||||||
|
|
||||||
/* FIXME: encrypt msg! */
|
/* FIXME: encrypt msg! */
|
||||||
subd_send_msg(peer->owner,
|
subd_send_msg(peer->owner,
|
||||||
take(towire_channel_fail_htlc(peer, htlc_id, msg)));
|
take(towire_channel_fail_htlc(peer, htlc_id, msg)));
|
||||||
|
@ -1163,6 +1160,57 @@ static int peer_failed_htlc(struct peer *peer, const u8 *msg)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME: Encrypt! */
|
||||||
|
static u8 *malformed_msg(const tal_t *ctx, enum onion_type type,
|
||||||
|
const struct sha256 *sha256_of_onion)
|
||||||
|
{
|
||||||
|
/* FIXME: check the reported SHA matches what we sent! */
|
||||||
|
switch (type) {
|
||||||
|
case WIRE_INVALID_ONION_VERSION:
|
||||||
|
return towire_invalid_onion_version(ctx, sha256_of_onion);
|
||||||
|
case WIRE_INVALID_ONION_HMAC:
|
||||||
|
return towire_invalid_onion_hmac(ctx, sha256_of_onion);
|
||||||
|
case WIRE_INVALID_ONION_KEY:
|
||||||
|
return towire_invalid_onion_key(ctx, sha256_of_onion);
|
||||||
|
default:
|
||||||
|
/* FIXME */
|
||||||
|
return towire_temporary_channel_failure(ctx);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static int peer_failed_malformed_htlc(struct peer *peer, const u8 *msg)
|
||||||
|
{
|
||||||
|
u64 id;
|
||||||
|
struct htlc_end *hend;
|
||||||
|
struct sha256 sha256_of_onion;
|
||||||
|
u16 failcode;
|
||||||
|
|
||||||
|
if (!fromwire_channel_malformed_htlc(msg, NULL, &id,
|
||||||
|
&sha256_of_onion, &failcode)) {
|
||||||
|
log_broken(peer->log, "bad fromwire_channel_malformed_htlc %s",
|
||||||
|
tal_hex(peer, msg));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
hend = find_htlc_end(&peer->ld->htlc_ends, peer, id, HTLC_DST);
|
||||||
|
if (!hend) {
|
||||||
|
log_broken(peer->log,
|
||||||
|
"channel_malformed_htlc unknown htlc %"PRIu64,
|
||||||
|
id);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hend->other_end) {
|
||||||
|
fail_htlc(hend->other_end->peer, hend->other_end->htlc_id,
|
||||||
|
malformed_msg(msg, failcode, &sha256_of_onion));
|
||||||
|
} else {
|
||||||
|
payment_failed(peer->ld, hend, NULL, failcode);
|
||||||
|
}
|
||||||
|
tal_free(hend);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int channel_msg(struct subd *sd, const u8 *msg, const int *unused)
|
static int channel_msg(struct subd *sd, const u8 *msg, const int *unused)
|
||||||
{
|
{
|
||||||
enum channel_wire_type t = fromwire_peektype(msg);
|
enum channel_wire_type t = fromwire_peektype(msg);
|
||||||
|
@ -1181,9 +1229,7 @@ static int channel_msg(struct subd *sd, const u8 *msg, const int *unused)
|
||||||
case WIRE_CHANNEL_FAILED_HTLC:
|
case WIRE_CHANNEL_FAILED_HTLC:
|
||||||
return peer_failed_htlc(sd->peer, msg);
|
return peer_failed_htlc(sd->peer, msg);
|
||||||
case WIRE_CHANNEL_MALFORMED_HTLC:
|
case WIRE_CHANNEL_MALFORMED_HTLC:
|
||||||
/* FIXME: Forward. */
|
return peer_failed_malformed_htlc(sd->peer, msg);
|
||||||
abort();
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* We never see fatal ones. */
|
/* We never see fatal ones. */
|
||||||
case WIRE_CHANNEL_BAD_COMMAND:
|
case WIRE_CHANNEL_BAD_COMMAND:
|
||||||
|
|
Loading…
Add table
Reference in a new issue