mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-21 16:14:23 +01:00
sphinx: Incrementally wrap replies in new onion layers
This commit is contained in:
committed by
Rusty Russell
parent
9820abda7c
commit
870b83f67f
@@ -644,20 +644,26 @@ struct decoding_htlc {
|
|||||||
u8 shared_secret[32];
|
u8 shared_secret[32];
|
||||||
};
|
};
|
||||||
|
|
||||||
static void fail_htlc(struct peer *peer, u64 htlc_id, const u8 *msg)
|
static void fail_htlc(struct peer *peer, struct htlc_end *hend, const u8 *msg)
|
||||||
{
|
{
|
||||||
enum onion_type failcode = fromwire_peektype(msg);
|
u8 *reply = wrap_onionreply(hend, hend->shared_secret.u.u8, msg);
|
||||||
|
|
||||||
log_broken(peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)",
|
|
||||||
htlc_id, failcode, onion_type_name(failcode));
|
|
||||||
|
|
||||||
/* 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, hend->htlc_id, reply)));
|
||||||
if (taken(msg))
|
if (taken(msg))
|
||||||
tal_free(msg);
|
tal_free(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void fail_local_htlc(struct peer *peer, struct htlc_end *hend, const u8 *msg)
|
||||||
|
{
|
||||||
|
u8 *reply;
|
||||||
|
enum onion_type failcode = fromwire_peektype(msg);
|
||||||
|
log_broken(peer->log, "failed htlc %"PRIu64" code 0x%04x (%s)",
|
||||||
|
hend->htlc_id, failcode, onion_type_name(failcode));
|
||||||
|
|
||||||
|
reply = create_onionreply(hend, hend->shared_secret.u.u8, msg);
|
||||||
|
fail_htlc(peer, hend, reply);
|
||||||
|
}
|
||||||
|
|
||||||
static u8 *make_failmsg(const tal_t *ctx, const struct htlc_end *hend,
|
static u8 *make_failmsg(const tal_t *ctx, const struct htlc_end *hend,
|
||||||
enum onion_type failcode)
|
enum onion_type failcode)
|
||||||
{
|
{
|
||||||
@@ -874,7 +880,7 @@ static void handle_localpay(struct htlc_end *hend,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
fail_htlc(hend->peer, hend->htlc_id, take(err));
|
fail_local_htlc(hend->peer, hend, take(err));
|
||||||
tal_free(hend);
|
tal_free(hend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1031,7 +1037,7 @@ static void forward_htlc(struct htlc_end *hend,
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
fail_htlc(hend->peer, hend->htlc_id, take(err));
|
fail_local_htlc(hend->peer, hend, take(err));
|
||||||
tal_free(hend);
|
tal_free(hend);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,7 +1056,7 @@ static bool channel_resolve_reply(struct subd *gossip, const u8 *msg,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (tal_count(nodes) == 0) {
|
if (tal_count(nodes) == 0) {
|
||||||
fail_htlc(hend->peer, hend->htlc_id,
|
fail_htlc(hend->peer, hend,
|
||||||
take(towire_unknown_next_peer(hend)));
|
take(towire_unknown_next_peer(hend)));
|
||||||
tal_free(hend);
|
tal_free(hend);
|
||||||
return true;
|
return true;
|
||||||
@@ -1151,6 +1157,7 @@ static int peer_failed_htlc(struct peer *peer, const u8 *msg)
|
|||||||
u8 *reason;
|
u8 *reason;
|
||||||
struct htlc_end *hend;
|
struct htlc_end *hend;
|
||||||
enum onion_type failcode;
|
enum onion_type failcode;
|
||||||
|
struct onionreply *reply;
|
||||||
|
|
||||||
if (!fromwire_channel_failed_htlc(msg, msg, NULL, &id, &reason)) {
|
if (!fromwire_channel_failed_htlc(msg, msg, NULL, &id, &reason)) {
|
||||||
log_broken(peer->log, "bad fromwire_channel_failed_htlc %s",
|
log_broken(peer->log, "bad fromwire_channel_failed_htlc %s",
|
||||||
@@ -1166,16 +1173,21 @@ static int peer_failed_htlc(struct peer *peer, const u8 *msg)
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
failcode = fromwire_peektype(reason);
|
|
||||||
|
|
||||||
log_info(peer->log, "htlc %"PRIu64" failed with code 0x%04x (%s)",
|
|
||||||
id, failcode, onion_type_name(failcode));
|
|
||||||
|
|
||||||
if (hend->other_end) {
|
if (hend->other_end) {
|
||||||
fail_htlc(hend->other_end->peer, hend->other_end->htlc_id,
|
fail_htlc(hend->other_end->peer, hend->other_end,
|
||||||
reason);
|
reason);
|
||||||
} else {
|
} else {
|
||||||
/* FIXME: Decrypt reason, determine sender! */
|
size_t numhops = tal_count(hend->path_secrets);
|
||||||
|
u8 **shared_secrets = tal_arr(hend, u8*, numhops);
|
||||||
|
for (size_t i=0; i<numhops; i++) {
|
||||||
|
shared_secrets[i] = tal_arr(hend, u8, 32);
|
||||||
|
memcpy(shared_secrets[i], hend->path_secrets[i].u.u8, 32);
|
||||||
|
}
|
||||||
|
reply = unwrap_onionreply(msg, shared_secrets, numhops, reason);
|
||||||
|
failcode = fromwire_peektype(reply->msg);
|
||||||
|
log_info(peer->log, "htlc %"PRIu64" failed with code 0x%04x (%s)",
|
||||||
|
id, failcode, onion_type_name(failcode));
|
||||||
|
|
||||||
payment_failed(peer->ld, hend, NULL, failcode);
|
payment_failed(peer->ld, hend, NULL, failcode);
|
||||||
}
|
}
|
||||||
tal_free(hend);
|
tal_free(hend);
|
||||||
@@ -1224,7 +1236,10 @@ static int peer_failed_malformed_htlc(struct peer *peer, const u8 *msg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (hend->other_end) {
|
if (hend->other_end) {
|
||||||
fail_htlc(hend->other_end->peer, hend->other_end->htlc_id,
|
/* Not really a local failure, but since the failing
|
||||||
|
* peer could not derive its shared secret it cannot
|
||||||
|
* create a valid HMAC, so we do it on his behalf */
|
||||||
|
fail_local_htlc(hend->other_end->peer, hend->other_end,
|
||||||
malformed_msg(msg, failcode, &sha256_of_onion));
|
malformed_msg(msg, failcode, &sha256_of_onion));
|
||||||
} else {
|
} else {
|
||||||
payment_failed(peer->ld, hend, NULL, failcode);
|
payment_failed(peer->ld, hend, NULL, failcode);
|
||||||
|
|||||||
@@ -373,6 +373,7 @@ struct onionpacket *create_onionpacket(
|
|||||||
u8 nexthmac[SECURITY_PARAMETER];
|
u8 nexthmac[SECURITY_PARAMETER];
|
||||||
u8 stream[ROUTING_INFO_SIZE];
|
u8 stream[ROUTING_INFO_SIZE];
|
||||||
struct hop_params *params = generate_hop_params(ctx, sessionkey, path);
|
struct hop_params *params = generate_hop_params(ctx, sessionkey, path);
|
||||||
|
struct sha256 *secrets = tal_arr(ctx, struct sha256, num_hops);
|
||||||
|
|
||||||
if (!params)
|
if (!params)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -405,10 +406,11 @@ struct onionpacket *create_onionpacket(
|
|||||||
memcpy(packet->mac, nexthmac, sizeof(nexthmac));
|
memcpy(packet->mac, nexthmac, sizeof(nexthmac));
|
||||||
memcpy(&packet->ephemeralkey, ¶ms[0].ephemeralkey, sizeof(secp256k1_pubkey));
|
memcpy(&packet->ephemeralkey, ¶ms[0].ephemeralkey, sizeof(secp256k1_pubkey));
|
||||||
|
|
||||||
*path_secrets = tal_arr(ctx, struct sha256, num_hops);
|
|
||||||
for (i=0; i<num_hops; i++) {
|
for (i=0; i<num_hops; i++) {
|
||||||
create_shared_secret((*path_secrets)[i].u.u8, &path[i].pubkey, sessionkey);
|
memcpy(&secrets[i], params[i].secret, SHARED_SECRET_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*path_secrets = secrets;
|
||||||
return packet;
|
return packet;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -516,6 +518,10 @@ struct onionreply *unwrap_onionreply(const tal_t *ctx, u8 **shared_secrets,
|
|||||||
size_t max;
|
size_t max;
|
||||||
u16 msglen;
|
u16 msglen;
|
||||||
|
|
||||||
|
if (tal_len(reply) != ONION_REPLY_SIZE + sizeof(hmac) + 4) {
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
memcpy(msg, reply, tal_len(reply));
|
memcpy(msg, reply, tal_len(reply));
|
||||||
oreply->origin_index = -1;
|
oreply->origin_index = -1;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user