From c8594fd4438bfb202bfef5a635a3def78d3ffbb4 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Mon, 18 Sep 2023 16:41:27 +0930 Subject: [PATCH] lightningd: tell connectd about the custom messages. We re-send whenever a plugin which allows them starts/finishes. Signed-off-by: Rusty Russell --- connectd/connectd.c | 5 ++++ connectd/connectd.h | 3 +++ connectd/connectd_wire.csv | 5 ++++ connectd/multiplex.c | 49 ++++++++++++++++++++++++++++-------- connectd/multiplex.h | 3 +++ lightningd/connect_control.c | 1 + lightningd/plugin.c | 29 +++++++++++++++++++++ 7 files changed, 84 insertions(+), 11 deletions(-) diff --git a/connectd/connectd.c b/connectd/connectd.c index 6d78a26aca81..6ae26affb5d9 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -2081,6 +2081,10 @@ static struct io_plan *recv_req(struct io_conn *conn, start_shutdown(daemon, msg); goto out; + case WIRE_CONNECTD_SET_CUSTOMMSGS: + set_custommsgs(daemon, msg); + goto out; + case WIRE_CONNECTD_DEV_MEMLEAK: #if DEVELOPER dev_connect_memleak(daemon, msg); @@ -2186,6 +2190,7 @@ int main(int argc, char *argv[]) timers_init(&daemon->timers, time_mono()); daemon->gossip_store_fd = -1; daemon->shutting_down = false; + daemon->custom_msgs = NULL; /* stdin == control */ daemon->master = daemon_conn_new(daemon, STDIN_FILENO, recv_req, NULL, diff --git a/connectd/connectd.h b/connectd/connectd.h index 8605155fc72b..f311ec0cc087 100644 --- a/connectd/connectd.h +++ b/connectd/connectd.h @@ -194,6 +194,9 @@ struct daemon { /* Shutting down, don't send new stuff */ bool shutting_down; + /* What (even) custom messages we accept */ + u16 *custom_msgs; + #if DEVELOPER /* Hack to speed up gossip timer */ bool dev_fast_gossip; diff --git a/connectd/connectd_wire.csv b/connectd/connectd_wire.csv index d42d5f506a6d..6ec84bd13416 100644 --- a/connectd/connectd_wire.csv +++ b/connectd/connectd_wire.csv @@ -40,6 +40,11 @@ msgtype,connectd_activate,2025 # Do we listen? msgdata,connectd_activate,listen,bool, +# Set the allowed (i.e. don't hang up on!) unknown messages. +msgtype,connectd_set_custommsgs,2007 +msgdata,connectd_set_custommsgs,len,u32, +msgdata,connectd_set_custommsgs,msgnums,u16,len + # Connectd->master, I am ready. msgtype,connectd_activate_reply,2125 msgdata,connectd_activate_reply,failmsg,?wirestring, diff --git a/connectd/multiplex.c b/connectd/multiplex.c index ce69b1dcc997..1c61cb02fde3 100644 --- a/connectd/multiplex.c +++ b/connectd/multiplex.c @@ -570,6 +570,13 @@ static void send_ping(struct peer *peer) set_ping_timer(peer); } +void set_custommsgs(struct daemon *daemon, const u8 *msg) +{ + tal_free(daemon->custom_msgs); + if (!fromwire_connectd_set_custommsgs(daemon, msg, &daemon->custom_msgs)) + master_badmsg(WIRE_CONNECTD_SET_CUSTOMMSGS, msg); +} + void send_custommsg(struct daemon *daemon, const u8 *msg) { struct node_id id; @@ -712,24 +719,44 @@ static void handle_gossip_timestamp_filter_in(struct peer *peer, const u8 *msg) wake_gossip(peer); } +static bool find_custom_msg(const u16 *custom_msgs, u16 type) +{ + for (size_t i = 0; i < tal_count(custom_msgs); i++) { + if (custom_msgs[i] == type) + return true; + } + return false; +} + static bool handle_custommsg(struct daemon *daemon, struct peer *peer, const u8 *msg) { enum peer_wire type = fromwire_peektype(msg); - if (type % 2 == 1 && !peer_wire_is_internal(type)) { - /* The message is not part of the messages we know how to - * handle. Assuming this is a custommsg, we just forward it to the - * master. */ - status_peer_io(LOG_IO_IN, &peer->id, msg); - daemon_conn_send(daemon->master, - take(towire_connectd_custommsg_in(NULL, - &peer->id, - msg))); - return true; - } else { + + /* Messages we expect to handle ourselves. */ + if (peer_wire_is_internal(type)) return false; + + /* We log it, since it's not going to a subdaemon */ + status_peer_io(LOG_IO_IN, &peer->id, msg); + + /* Even unknown messages must be explicitly allowed */ + if (type % 2 == 0 && !find_custom_msg(daemon->custom_msgs, type)) { + send_warning(peer, "Invalid unknown even msg %s", + tal_hex(msg, msg)); + /* We "handled" it... */ + return true; } + + /* The message is not part of the messages we know how to + * handle. Assuming this is a custommsg, we just forward it to the + * master. */ + daemon_conn_send(daemon->master, + take(towire_connectd_custommsg_in(NULL, + &peer->id, + msg))); + return true; } /* We handle pings and gossip messages. */ diff --git a/connectd/multiplex.h b/connectd/multiplex.h index 77a41fa2aae4..ff8e3c2864fa 100644 --- a/connectd/multiplex.h +++ b/connectd/multiplex.h @@ -32,6 +32,9 @@ void send_manual_ping(struct daemon *daemon, const u8 *msg); /* When lightningd says to send a custom message (from a plugin) */ void send_custommsg(struct daemon *daemon, const u8 *msg); +/* When lightningd says what custom messages we can recv */ +void set_custommsgs(struct daemon *daemon, const u8 *msg); + /* Lightningd wants to talk to you. */ void peer_connect_subd(struct daemon *daemon, const u8 *msg, int fd); #endif /* LIGHTNING_CONNECTD_MULTIPLEX_H */ diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index ae253c5a4939..2577343a2be4 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -580,6 +580,7 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd case WIRE_CONNECTD_SEND_ONIONMSG: case WIRE_CONNECTD_CUSTOMMSG_OUT: case WIRE_CONNECTD_START_SHUTDOWN: + case WIRE_CONNECTD_SET_CUSTOMMSGS: /* This is a reply, so never gets through to here. */ case WIRE_CONNECTD_INIT_REPLY: case WIRE_CONNECTD_ACTIVATE_REPLY: diff --git a/lightningd/plugin.c b/lightningd/plugin.c index d18da9f696a2..16d11e682d02 100644 --- a/lightningd/plugin.c +++ b/lightningd/plugin.c @@ -16,6 +16,7 @@ #include #include #include +#include #include #include #include @@ -23,6 +24,7 @@ #include #include #include +#include #include /* Only this file can include this generated header! */ @@ -196,6 +198,28 @@ struct command_result *plugin_register_all_complete(struct lightningd *ld, return NULL; } +static void tell_connectd_custommsgs(struct plugins *plugins) +{ + struct plugin *p; + size_t n = 0; + u16 *all_msgs = tal_arr(tmpctx, u16, n); + + /* Not when shutting down */ + if (!plugins->ld->connectd) + return; + + /* Gather from all plugins. */ + list_for_each(&plugins->plugins, p, list) { + tal_resize(&all_msgs, n + tal_count(p->custom_msgs)); + memcpy(all_msgs + n, p->custom_msgs, tal_bytelen(p->custom_msgs)); + n += tal_count(p->custom_msgs); + } + + /* Don't bother sorting or uniquifying. If plugins are dumb, they deserve it. */ + subd_send_msg(plugins->ld->connectd, + take(towire_connectd_set_custommsgs(NULL, all_msgs))); +} + static void destroy_plugin(struct plugin *p) { struct plugin_rpccall *call; @@ -236,6 +260,9 @@ static void destroy_plugin(struct plugin *p) "shutting down lightningd!"); lightningd_exit(p->plugins->ld, 1); } + + if (tal_count(p->custom_msgs)) + tell_connectd_custommsgs(p->plugins); } static u32 file_checksum(struct lightningd *ld, const char *path) @@ -1958,6 +1985,8 @@ static void plugin_config_cb(const char *buffer, plugin_cmd_succeeded(plugin->start_cmd, plugin); plugin->start_cmd = NULL; } + if (tal_count(plugin->custom_msgs)) + tell_connectd_custommsgs(plugin->plugins); check_plugins_initted(plugin->plugins); }