mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-24 01:24:26 +01:00
lightningd: handle modern onion termination.
This adds a new hook: onion_message_ourpath for when we know a message came in via a blinded path we created. The onion_message_blinded hook is now called for all other messages, since all messages are now blinded. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
committed by
Christian Decker
parent
89d143bc63
commit
f9a21d9fc9
@@ -1508,28 +1508,34 @@ type prefix, since c-lightning does not know how to parse the message.
|
||||
Because this is a chained hook, the daemon expects the result to be
|
||||
`{'result': 'continue'}`. It will fail if something else is returned.
|
||||
|
||||
### `onion_message` and `onion_message_blinded`
|
||||
### `onion_message`, `onion_message_blinded` and `onion_message_ourpath`
|
||||
|
||||
**(WARNING: experimental-offers only)**
|
||||
|
||||
These two hooks are almost identical, in that they are called when an
|
||||
onion message is received. The former is only used for unblinded
|
||||
messages (where the source knows that it is sending to this node), and
|
||||
the latter for blinded messages (where the source doesn't know that
|
||||
this node is the destination). The latter hook will have a
|
||||
"blinding_in" field, the former never will.
|
||||
These three hooks are almost identical, in that they are called when
|
||||
an onion message is received. The `onion_message` hook is only used
|
||||
for obsolete unblinded messages, and can be ignored for modern usage.
|
||||
|
||||
These hooks are separate, because blinded messages must ensure the
|
||||
sender used the correct "blinding_in", otherwise it should ignore the
|
||||
message: this avoids the source trying to probe for responses without
|
||||
using the designated delivery path.
|
||||
`onion_message_blinded` is used for unsolicited messages (where the
|
||||
source knows that it is sending to this node), and
|
||||
`onion_message_ourpath` is used for messages which use a blinded path
|
||||
we supplied (where the source doesn't know that this node is the
|
||||
destination). The latter hook will have a `our_alias` field, the
|
||||
former never will.
|
||||
|
||||
These hooks are separate, because replies MUST be ignored unless they
|
||||
use the correct path (i.e. `onion_message_ourpath`, with the expected
|
||||
`our_alias`). This avoids the source trying to probe for responses
|
||||
without using the designated delivery path.
|
||||
|
||||
The payload for a call follows this format:
|
||||
|
||||
```json
|
||||
{
|
||||
"onion_message": {
|
||||
"blinding_in": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||
"our_alias": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||
"reply_first_node": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||
"reply_blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||
"reply_path": [ {"id": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f",
|
||||
"enctlv": "0a020d0d",
|
||||
"blinding": "02df5ffe895c778e10f7742a6c5b8a0cefbe9465df58b92fadeb883752c8107c8f"} ],
|
||||
|
||||
@@ -104,7 +104,8 @@ msgdata,gossipd_got_obs_onionmsg_forward,next_onion_len,u16,
|
||||
msgdata,gossipd_got_obs_onionmsg_forward,next_onion,u8,next_onion_len
|
||||
|
||||
msgtype,gossipd_got_onionmsg_to_us,3145
|
||||
msgdata,gossipd_got_onionmsg_to_us,blinding_in,pubkey,
|
||||
msgdata,gossipd_got_onionmsg_to_us,node_alias,pubkey,
|
||||
msgdata,gossipd_got_onionmsg_to_us,self_id,?secret,
|
||||
msgdata,gossipd_got_onionmsg_to_us,reply_blinding,?pubkey,
|
||||
msgdata,gossipd_got_onionmsg_to_us,reply_first_node,?pubkey,
|
||||
msgdata,gossipd_got_onionmsg_to_us,reply_path_len,u16,
|
||||
|
||||
|
@@ -1,3 +1,4 @@
|
||||
#include <ccan/mem/mem.h>
|
||||
#include <common/blindedpath.h>
|
||||
#include <common/json_command.h>
|
||||
#include <common/json_helpers.h>
|
||||
@@ -14,10 +15,15 @@
|
||||
#include <sodium/randombytes.h>
|
||||
|
||||
struct onion_message_hook_payload {
|
||||
/* Pre-spec or modern? */
|
||||
bool obsolete;
|
||||
|
||||
/* Optional */
|
||||
struct pubkey *blinding_in;
|
||||
struct pubkey *blinding_in; /* obsolete only */
|
||||
struct pubkey *reply_blinding;
|
||||
struct onionmsg_path **reply_path;
|
||||
struct pubkey *reply_first_node; /* non-obsolete only */
|
||||
struct pubkey *our_alias; /* non-obsolete only */
|
||||
|
||||
struct tlv_onionmsg_payload *om;
|
||||
};
|
||||
@@ -47,9 +53,19 @@ static void onion_message_serialize(struct onion_message_hook_payload *payload,
|
||||
struct plugin *plugin)
|
||||
{
|
||||
json_object_start(stream, "onion_message");
|
||||
json_add_bool(stream, "obsolete", payload->obsolete);
|
||||
if (payload->blinding_in)
|
||||
json_add_pubkey(stream, "blinding_in", payload->blinding_in);
|
||||
if (payload->reply_path) {
|
||||
if (payload->our_alias)
|
||||
json_add_pubkey(stream, "our_alias", payload->our_alias);
|
||||
|
||||
/* Modern style. */
|
||||
if (payload->reply_first_node) {
|
||||
json_add_blindedpath(stream, "reply_blindedpath",
|
||||
payload->reply_blinding,
|
||||
payload->reply_first_node,
|
||||
payload->reply_path);
|
||||
} else if (payload->reply_path) {
|
||||
json_array_start(stream, "reply_path");
|
||||
for (size_t i = 0; i < tal_count(payload->reply_path); i++) {
|
||||
json_object_start(stream, NULL);
|
||||
@@ -113,6 +129,12 @@ REGISTER_PLUGIN_HOOK(onion_message_blinded,
|
||||
onion_message_serialize,
|
||||
struct onion_message_hook_payload *);
|
||||
|
||||
REGISTER_PLUGIN_HOOK(onion_message_ourpath,
|
||||
plugin_hook_continue,
|
||||
onion_message_hook_cb,
|
||||
onion_message_serialize,
|
||||
struct onion_message_hook_payload *);
|
||||
|
||||
void handle_obs_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
||||
{
|
||||
struct onion_message_hook_payload *payload;
|
||||
@@ -121,7 +143,10 @@ void handle_obs_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
||||
const u8 *subptr;
|
||||
|
||||
payload = tal(ld, struct onion_message_hook_payload);
|
||||
payload->obsolete = true;
|
||||
payload->reply_first_node = NULL;
|
||||
payload->om = tlv_onionmsg_payload_new(payload);
|
||||
payload->our_alias = NULL;
|
||||
|
||||
if (!fromwire_gossipd_got_obs_onionmsg_to_us(payload, msg,
|
||||
&payload->blinding_in,
|
||||
@@ -197,8 +222,62 @@ void handle_obs_onionmsg_forward(struct lightningd *ld, const u8 *msg)
|
||||
|
||||
void handle_onionmsg_to_us(struct lightningd *ld, const u8 *msg)
|
||||
{
|
||||
/* FIXME! */
|
||||
return;
|
||||
struct onion_message_hook_payload *payload;
|
||||
u8 *submsg;
|
||||
struct secret *self_id;
|
||||
size_t submsglen;
|
||||
const u8 *subptr;
|
||||
|
||||
payload = tal(ld, struct onion_message_hook_payload);
|
||||
payload->obsolete = false;
|
||||
payload->om = tlv_onionmsg_payload_new(payload);
|
||||
payload->blinding_in = NULL;
|
||||
payload->our_alias = tal(payload, struct pubkey);
|
||||
|
||||
if (!fromwire_gossipd_got_onionmsg_to_us(payload, msg,
|
||||
payload->our_alias,
|
||||
&self_id,
|
||||
&payload->reply_blinding,
|
||||
&payload->reply_first_node,
|
||||
&payload->reply_path,
|
||||
&submsg)) {
|
||||
log_broken(ld->log, "bad got_onionmsg_tous: %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
return;
|
||||
}
|
||||
|
||||
/* If there's no self_id, or it's not correct, ignore alias: alias
|
||||
* means we created the path it's using. */
|
||||
if (!self_id || !secret_eq_consttime(self_id, &ld->onion_reply_secret))
|
||||
payload->our_alias = tal_free(payload->our_alias);
|
||||
|
||||
submsglen = tal_bytelen(submsg);
|
||||
subptr = submsg;
|
||||
if (!fromwire_onionmsg_payload(&subptr,
|
||||
&submsglen, payload->om)) {
|
||||
tal_free(payload);
|
||||
log_broken(ld->log, "bad got_onionmsg_tous om: %s",
|
||||
tal_hex(tmpctx, msg));
|
||||
return;
|
||||
}
|
||||
tal_free(submsg);
|
||||
|
||||
/* Make sure gossipd gets this right. */
|
||||
if (payload->reply_path
|
||||
&& (!payload->reply_blinding || !payload->reply_first_node)) {
|
||||
log_broken(ld->log,
|
||||
"No reply blinding/first_node, ignoring reply path");
|
||||
payload->reply_path = tal_free(payload->reply_path);
|
||||
}
|
||||
|
||||
log_debug(ld->log, "Got onionmsg%s%s",
|
||||
payload->our_alias ? " via-ourpath": "",
|
||||
payload->reply_path ? " reply_path": "");
|
||||
|
||||
if (payload->our_alias)
|
||||
plugin_hook_call_onion_message_ourpath(ld, payload);
|
||||
else
|
||||
plugin_hook_call_onion_message_blinded(ld, payload);
|
||||
}
|
||||
|
||||
struct hop {
|
||||
|
||||
Reference in New Issue
Block a user