plugin: Dispatch incoming RPC calls to appropriate plugin

Signed-off-by: Christian Decker <@cdecker>
This commit is contained in:
Christian Decker 2018-11-23 00:38:51 +01:00 committed by Rusty Russell
parent a0f6a82a0b
commit 7c93cf00bb

View file

@ -9,6 +9,7 @@
#include <common/memleak.h>
#include <errno.h>
#include <lightningd/json.h>
#include <lightningd/lightningd.h>
#include <signal.h>
#include <unistd.h>
@ -72,6 +73,20 @@ struct json_output {
const char *json;
};
/* Represents a pending JSON-RPC request that was forwarded to a
* plugin and is currently waiting for it to return the result. */
struct plugin_rpc_request {
/* The json-serialized ID as it was passed to us by the
* client, will be used to return the result */
const char *id;
const char *method;
const char *params;
struct plugin *plugin;
struct command *cmd;
};
/* Simple storage for plugin options inbetween registering them on the
* command line and passing them off to the plugin */
struct plugin_opt {
@ -399,12 +414,68 @@ static void plugin_rpcmethod_destroy(struct json_command *cmd,
jsonrpc_command_remove(rpc, cmd->name);
}
static void plugin_rpcmethod_cb(const struct plugin_request *req,
struct plugin_rpc_request *rpc_req)
{
// Parse
// Extract results or error
// Construct reply
// Return result with appropriate return code.
}
static void plugin_rpcmethod_dispatch(struct command *cmd, const char *buffer,
const jsmntok_t *params)
{
// FIXME: We could avoid parsing the buffer again if we were
// to also pass in the method name.
cmd->usage = "[params]";
const jsmntok_t *toks = params, *methtok, *idtok;
struct plugin_rpc_request *request;
struct plugins *plugins = cmd->ld->plugins;
struct plugin *plugin;
if (cmd->mode == CMD_USAGE) {
cmd->usage = "[params]";
return;
}
/* We're given the params, but we need to walk back to the
* root object, so just walk backwards until the current
* element has no parents, that's going to be the root
* element. */
while (toks->parent != -1)
toks--;
methtok = json_get_member(buffer, toks, "method");
idtok = json_get_member(buffer, toks, "id");
/* We've parsed them before, these should not fail! */
assert(idtok != NULL && methtok != NULL);
request = tal(NULL, struct plugin_rpc_request);
request->method = tal_strndup(request, buffer + methtok->start,
methtok->end - methtok->start);
request->id = tal_strndup(request, buffer + idtok->start,
idtok->end - idtok->start);
request->params = tal_strndup(request, buffer + params->start,
params->end - params->start);
request->plugin = NULL;
request->cmd = cmd;
/* Find the plugin that registered this RPC call */
list_for_each(&plugins->plugins, plugin, list) {
for (size_t i=0; i<tal_count(plugin->methods); i++) {
if (streq(request->method, plugin->methods[i])) {
request->plugin = plugin;
goto found;
}
}
}
found:
/* This should never happen, it'd mean that a plugin didn't
* cleanup after dying */
assert(request->plugin);
tal_steal(request->plugin, request);
plugin_request_send(request->plugin, request->method, request->params, plugin_rpcmethod_cb, request);
command_still_pending(cmd);
}