mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 13:25:43 +01:00
json-rpc: Add sendcustommsg command
This command injects a custom message into the encrypted transport stream to the peer, allowing users to build custom protocols on top of c-lightning without requiring any changes to c-lightning itself.
This commit is contained in:
parent
f08447d624
commit
3ad8438d91
@ -54,6 +54,7 @@
|
||||
#include <lightningd/plugin_hook.h>
|
||||
#include <unistd.h>
|
||||
#include <wally_bip32.h>
|
||||
#include <wire/gen_common_wire.h>
|
||||
#include <wire/gen_onion_wire.h>
|
||||
#include <wire/wire_sync.h>
|
||||
|
||||
@ -2373,5 +2374,71 @@ void peer_dev_memleak(struct command *cmd)
|
||||
{
|
||||
peer_memleak_req_next(cmd, NULL);
|
||||
}
|
||||
|
||||
static struct command_result *json_sendcustommsg(struct command *cmd,
|
||||
const char *buffer,
|
||||
const jsmntok_t *obj UNNEEDED,
|
||||
const jsmntok_t *params)
|
||||
{
|
||||
struct json_stream *response;
|
||||
struct node_id *dest;
|
||||
struct peer *peer;
|
||||
struct subd *owner;
|
||||
u8 *msg;
|
||||
|
||||
if (!param(cmd, buffer, params,
|
||||
p_req("node_id", param_node_id, &dest),
|
||||
p_req("msg", param_bin_from_hex, &msg),
|
||||
NULL))
|
||||
return command_param_failed();
|
||||
|
||||
peer = peer_by_id(cmd->ld, dest);
|
||||
if (!peer) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||
"No such peer: %s",
|
||||
type_to_string(cmd, struct node_id, dest));
|
||||
}
|
||||
|
||||
owner = peer_get_owning_subd(peer);
|
||||
if (owner == NULL) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||
"Peer is not connected: %s",
|
||||
type_to_string(cmd, struct node_id, dest));
|
||||
}
|
||||
|
||||
/* Only a couple of subdaemons have the ability to send custom
|
||||
* messages. We whitelist those, and error if the current owner is not
|
||||
* in the whitelist. The reason is that some subdaemons do not handle
|
||||
* spontaneous messages from the master well (I'm looking at you
|
||||
* `closingd`...). */
|
||||
if (!streq(owner->name, "channeld") &&
|
||||
!streq(owner->name, "openingd")) {
|
||||
return command_fail(cmd, JSONRPC2_INVALID_REQUEST,
|
||||
"Peer is currently owned by %s which does "
|
||||
"not support injecting custom messages.",
|
||||
owner->name);
|
||||
}
|
||||
|
||||
subd_send_msg(owner, take(towire_custommsg_out(cmd, msg)));
|
||||
|
||||
response = json_stream_success(cmd);
|
||||
json_add_string(response, "status",
|
||||
tal_fmt(cmd,
|
||||
"Message sent to subdaemon %s for delivery",
|
||||
owner->name));
|
||||
|
||||
return command_success(cmd, response);
|
||||
}
|
||||
|
||||
static const struct json_command sendcustommsg_command = {
|
||||
"dev-sendcustommsg",
|
||||
"utility",
|
||||
json_sendcustommsg,
|
||||
"Send a custom message to the peer with the given {node_id}",
|
||||
.verbose = "dev-sendcustommsg node_id hexcustommsg",
|
||||
};
|
||||
|
||||
AUTODATA(json_command, &sendcustommsg_command);
|
||||
|
||||
#endif /* DEVELOPER */
|
||||
|
||||
|
@ -330,6 +330,11 @@ struct command_result *param_array(struct command *cmd UNNEEDED, const char *nam
|
||||
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
const jsmntok_t **arr UNNEEDED)
|
||||
{ fprintf(stderr, "param_array called!\n"); abort(); }
|
||||
/* Generated stub for param_bin_from_hex */
|
||||
struct command_result *param_bin_from_hex(struct command *cmd UNNEEDED, const char *name UNNEEDED,
|
||||
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
u8 **bin UNNEEDED)
|
||||
{ fprintf(stderr, "param_bin_from_hex called!\n"); abort(); }
|
||||
/* Generated stub for param_bitcoin_address */
|
||||
struct command_result *param_bitcoin_address(struct command *cmd UNNEEDED,
|
||||
const char *name UNNEEDED,
|
||||
@ -407,6 +412,9 @@ struct command_result *param_u64(struct command *cmd UNNEEDED, const char *name
|
||||
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
uint64_t **num UNNEEDED)
|
||||
{ fprintf(stderr, "param_u64 called!\n"); abort(); }
|
||||
/* Generated stub for peer_get_owning_subd */
|
||||
struct subd *peer_get_owning_subd(struct peer *peer UNNEEDED)
|
||||
{ fprintf(stderr, "peer_get_owning_subd called!\n"); abort(); }
|
||||
/* Generated stub for peer_memleak_done */
|
||||
void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDED)
|
||||
{ fprintf(stderr, "peer_memleak_done called!\n"); abort(); }
|
||||
|
@ -420,6 +420,11 @@ void outpointfilter_remove(struct outpointfilter *of UNNEEDED,
|
||||
bool param(struct command *cmd UNNEEDED, const char *buffer UNNEEDED,
|
||||
const jsmntok_t params[] UNNEEDED, ...)
|
||||
{ fprintf(stderr, "param called!\n"); abort(); }
|
||||
/* Generated stub for param_bin_from_hex */
|
||||
struct command_result *param_bin_from_hex(struct command *cmd UNNEEDED, const char *name UNNEEDED,
|
||||
const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
|
||||
u8 **bin UNNEEDED)
|
||||
{ fprintf(stderr, "param_bin_from_hex called!\n"); abort(); }
|
||||
/* Generated stub for param_bitcoin_address */
|
||||
struct command_result *param_bitcoin_address(struct command *cmd UNNEEDED,
|
||||
const char *name UNNEEDED,
|
||||
@ -491,6 +496,9 @@ void payment_store(struct lightningd *ld UNNEEDED, struct wallet_payment *paymen
|
||||
void payment_succeeded(struct lightningd *ld UNNEEDED, struct htlc_out *hout UNNEEDED,
|
||||
const struct preimage *rval UNNEEDED)
|
||||
{ fprintf(stderr, "payment_succeeded called!\n"); abort(); }
|
||||
/* Generated stub for peer_get_owning_subd */
|
||||
struct subd *peer_get_owning_subd(struct peer *peer UNNEEDED)
|
||||
{ fprintf(stderr, "peer_get_owning_subd called!\n"); abort(); }
|
||||
/* Generated stub for peer_memleak_done */
|
||||
void peer_memleak_done(struct command *cmd UNNEEDED, struct subd *leaker UNNEEDED)
|
||||
{ fprintf(stderr, "peer_memleak_done called!\n"); abort(); }
|
||||
@ -590,6 +598,9 @@ u8 *towire_connectctl_connect_to_peer(const tal_t *ctx UNNEEDED, const struct no
|
||||
/* Generated stub for towire_connectctl_peer_disconnected */
|
||||
u8 *towire_connectctl_peer_disconnected(const tal_t *ctx UNNEEDED, const struct node_id *id UNNEEDED)
|
||||
{ fprintf(stderr, "towire_connectctl_peer_disconnected called!\n"); abort(); }
|
||||
/* Generated stub for towire_custommsg_out */
|
||||
u8 *towire_custommsg_out(const tal_t *ctx UNNEEDED, const u8 *msg UNNEEDED)
|
||||
{ fprintf(stderr, "towire_custommsg_out called!\n"); abort(); }
|
||||
/* Generated stub for towire_errorfmt */
|
||||
u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
|
||||
const struct channel_id *channel UNNEEDED,
|
||||
|
Loading…
Reference in New Issue
Block a user