lightningd: allow filtering on custommsg hook too.
What changed, and why it matters
This commit adds a new plugin feature: the ability for plugin authors to register a 'custommsg' hook with a filter list, so the hook is only invoked for specific custom message types. It is a feature enhancement, not a security fix. There is no indication in the commit or supplied references that this resolves a known vulnerability.
No security action required. Treat as a normal feature commit. Plugin developers may review the new filtering capability for potential logic errors in their own hook filters.
Security signals we found
No security-relevant keywords in commit title or message
No CVE, advisory, or security-fix language present
Change is a feature addition (filtering for plugin hooks)
No bounds, validation, or memory-safety fixes visible in diff
Evidence from the diff
The change replaces REGISTER_PLUGIN_HOOK with REGISTER_PLUGIN_HOOK_INTFILTER for the ‘custommsg’ hook in lightningd/connect_control.c, and passes the message type (fromwire_peektype) when calling the hook. Documentation and tests are updated to show that plugins can specify a JSON array of message numbers to limit hook invocations. No security bug is patched; the change is additive.
Changed components
lightningd/connect_control.cdoc/developers-guide/plugin-development/hooks.mdtests/plugins/custommsg_b.pytests/test_misc.pyInspect captured patch +14 / −8
diff --git a/doc/developers-guide/plugin-development/hooks.md b/doc/developers-guide/plugin-development/hooks.md
index 96f1ff1a..9c229953 100644
--- a/doc/developers-guide/plugin-development/hooks.md
+++ b/doc/developers-guide/plugin-development/hooks.md
@@ -585,7 +585,7 @@ Note: The `rpc_command` hook is chainable. If two or more plugins try to replace
### `custommsg`
-The `custommsg` plugin hook is the receiving counterpart to the [`sendcustommsg`](ref:sendcustommsg) RPC method and allows plugins to handle messages that are not handled internally. The goal of these two components is to allow the implementation of custom protocols or prototypes on top of a Core Lightning node, without having to change the node's implementation itself.
+The `custommsg` plugin hook is the receiving counterpart to the [`sendcustommsg`](ref:sendcustommsg) RPC method and allows plugins to handle messages that are not handled internally. The goal of these two components is to allow the implementation of custom protocols or prototypes on top of a Core Lightning node, without having to change the node's implementation itself. Note that if the hook registration specifies "filters" then that should be a JSON array of message numbers, and the hook will only be called for those. Otherwise, the hook is called for all messages not handled internally.
The payload for a call follows this format:
diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c
index e57bc975..e374ae96 100644
--- a/lightningd/connect_control.c
+++ b/lightningd/connect_control.c
@@ -375,11 +375,11 @@ static void custommsg_payload_serialize(struct custommsg_payload *payload,
json_add_node_id(stream, "peer_id", &payload->peer_id);
}
-REGISTER_PLUGIN_HOOK(custommsg,
- custommsg_cb,
- custommsg_final,
- custommsg_payload_serialize,
- struct custommsg_payload *);
+REGISTER_PLUGIN_HOOK_INTFILTER(custommsg,
+ custommsg_cb,
+ custommsg_final,
+ custommsg_payload_serialize,
+ struct custommsg_payload *);
static void handle_custommsg_in(struct lightningd *ld, const u8 *msg)
{
@@ -393,7 +393,7 @@ static void handle_custommsg_in(struct lightningd *ld, const u8 *msg)
}
notify_custommsg(ld, &p->peer_id, p->msg);
- plugin_hook_call_custommsg(ld, NULL, p);
+ plugin_hook_call_custommsg(ld, fromwire_peektype(p->msg), NULL, p);
}
static void handle_onionmsg_forward_fail(struct lightningd *ld, const u8 *msg)
diff --git a/tests/plugins/custommsg_b.py b/tests/plugins/custommsg_b.py
index 6282701f..63ddcaf8 100755
--- a/tests/plugins/custommsg_b.py
+++ b/tests/plugins/custommsg_b.py
@@ -4,7 +4,7 @@ from pyln.client import Plugin
plugin = Plugin()
-@plugin.hook('custommsg')
+@plugin.hook('custommsg', filters=[0xaaff])
def on_custommsg(peer_id, payload, plugin, message=None, **kwargs):
plugin.log("Got custommessage_b {msg} from peer {peer_id}".format(
msg=payload,
diff --git a/tests/test_misc.py b/tests/test_misc.py
index 6adcfad8..31a9c3c9 100644
--- a/tests/test_misc.py
+++ b/tests/test_misc.py
@@ -2903,6 +2903,12 @@ def test_sendcustommsg(node_factory):
msg=msg, peer_id=l2.info['id']),
])
+ # custommessage_b plugin only registers for 0xaaff msgs, so it won't see this one:
+ msg2 = 'aa' + ('fd' * 30) + 'bb'
+ l2.rpc.sendcustommsg(l4.info['id'], msg2)
+ l4.daemon.wait_for_log(f'Got custommessage_a {msg2} from peer')
+ assert not l4.daemon.is_in_log(f'Got custommessage_b {msg2} from peer')
+
def test_custommsg_triggers_notification(node_factory):
"""Check that a notification is triggered when a node receives
Why this scored 19/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.