|
4 | 4 | #include <lightningd/lightningd.h> |
5 | 5 | #include <lightningd/onion_message.h> |
6 | 6 | #include <lightningd/peer_control.h> |
| 7 | +#include <lightningd/plugin_hook.h> |
7 | 8 | #include <lightningd/subd.h> |
8 | 9 |
|
9 | 10 | #if EXPERIMENTAL_FEATURES |
| 11 | +struct onion_message_hook_payload { |
| 12 | + /* Optional */ |
| 13 | + struct pubkey *reply_blinding; |
| 14 | + struct onionmsg_path **reply_path; |
| 15 | + |
| 16 | + /* FIXME: Include other TLV fields here! */ |
| 17 | +}; |
| 18 | + |
| 19 | +static void |
| 20 | +onion_message_serialize(struct onion_message_hook_payload *payload, |
| 21 | + struct json_stream *stream) |
| 22 | +{ |
| 23 | + json_object_start(stream, "onion_message"); |
| 24 | + if (payload->reply_path) { |
| 25 | + json_array_start(stream, "reply_path"); |
| 26 | + for (size_t i = 0; i < tal_count(payload->reply_path); i++) { |
| 27 | + json_object_start(stream, NULL); |
| 28 | + json_add_pubkey(stream, "id", |
| 29 | + &payload->reply_path[i]->node_id); |
| 30 | + if (payload->reply_path[i]->enctlv) |
| 31 | + json_add_hex_talarr(stream, "enctlv", |
| 32 | + payload->reply_path[i]->enctlv); |
| 33 | + if (i == 0) |
| 34 | + json_add_pubkey(stream, "blinding", |
| 35 | + payload->reply_blinding); |
| 36 | + json_object_end(stream); |
| 37 | + } |
| 38 | + json_array_end(stream); |
| 39 | + } |
| 40 | + json_object_end(stream); |
| 41 | +} |
| 42 | + |
| 43 | +static void |
| 44 | +onion_message_hook_cb(struct onion_message_hook_payload *payload, |
| 45 | + const char *buffer, |
| 46 | + const jsmntok_t *toks) |
| 47 | +{ |
| 48 | + /* The core infra checks the "result"; anything other than continue |
| 49 | + * just stops. */ |
| 50 | + tal_free(payload); |
| 51 | +} |
| 52 | + |
| 53 | +REGISTER_PLUGIN_HOOK(onion_message, |
| 54 | + PLUGIN_HOOK_CHAIN, |
| 55 | + onion_message_hook_cb, |
| 56 | + struct onion_message_hook_payload *, |
| 57 | + onion_message_serialize, |
| 58 | + struct onion_message_hook_payload *); |
| 59 | + |
10 | 60 | /* Returns false if we can't tell it */ |
11 | 61 | static bool make_peer_send(struct lightningd *ld, |
12 | 62 | struct channel *dst, const u8 *msg TAKES) |
@@ -40,19 +90,29 @@ static bool make_peer_send(struct lightningd *ld, |
40 | 90 |
|
41 | 91 | void handle_onionmsg_to_us(struct channel *channel, const u8 *msg) |
42 | 92 | { |
43 | | - struct pubkey *reply_blinding; |
44 | | - struct onionmsg_path **reply_path; |
| 93 | + struct lightningd *ld = channel->peer->ld; |
| 94 | + struct onion_message_hook_payload *payload; |
| 95 | + |
| 96 | + payload = tal(ld, struct onion_message_hook_payload); |
45 | 97 |
|
46 | | - if (!fromwire_got_onionmsg_to_us(msg, msg, |
47 | | - &reply_blinding, &reply_path)) { |
| 98 | + if (!fromwire_got_onionmsg_to_us(payload, msg, |
| 99 | + &payload->reply_blinding, |
| 100 | + &payload->reply_path)) { |
48 | 101 | channel_internal_error(channel, "bad got_onionmsg_tous: %s", |
49 | 102 | tal_hex(tmpctx, msg)); |
50 | 103 | return; |
51 | 104 | } |
52 | 105 |
|
| 106 | + if (payload->reply_path && !payload->reply_blinding) { |
| 107 | + log_broken(channel->log, |
| 108 | + "No reply blinding, ignoring reply path"); |
| 109 | + payload->reply_path = tal_free(payload->reply_path); |
| 110 | + } |
| 111 | + |
53 | 112 | log_info(channel->log, "Got onionmsg%s%s", |
54 | | - reply_blinding ? " reply_blinding": "", |
55 | | - reply_path ? " reply_path": ""); |
| 113 | + payload->reply_blinding ? " reply_blinding": "", |
| 114 | + payload->reply_path ? " reply_path": ""); |
| 115 | + plugin_hook_call_onion_message(ld, payload, payload); |
56 | 116 | } |
57 | 117 |
|
58 | 118 | void handle_onionmsg_forward(struct channel *channel, const u8 *msg) |
|
0 commit comments