libplugin: don't expose the rpc_conn struct

This commit is contained in:
darosior 2020-02-03 10:14:43 +01:00 committed by Rusty Russell
parent b31e3b1541
commit 02fe34ed95
3 changed files with 31 additions and 29 deletions

View file

@ -69,7 +69,7 @@ static struct command_result *json_autocleaninvoice(struct command *cmd,
static void init(struct plugin *p,
const char *buf UNUSED, const jsmntok_t *config UNUSED)
{
rpc = &p->rpc_conn;
rpc = p->rpc_conn;
if (cycle_seconds) {
plugin_log(p, LOG_INFORM, "autocleaning every %"PRIu64" seconds", cycle_seconds);

View file

@ -44,6 +44,11 @@ struct out_req {
void *arg;
};
struct rpc_conn {
int fd;
MEMBUF(char) mb;
};
/* command_result is mainly used as a compile-time check to encourage you
* to return as soon as you get one (and not risk use-after-free of command).
* Here we use two values: complete (cmd freed) and pending (still going) */
@ -134,24 +139,24 @@ static int read_json_from_rpc(struct plugin *p)
/* We rely on the double-\n marker which only terminates JSON top
* levels. Thanks lightningd! */
while ((end = memmem(membuf_elems(&p->rpc_conn.mb),
membuf_num_elems(&p->rpc_conn.mb), "\n\n", 2))
while ((end = memmem(membuf_elems(&p->rpc_conn->mb),
membuf_num_elems(&p->rpc_conn->mb), "\n\n", 2))
== NULL) {
ssize_t r;
/* Make sure we've room for at least READ_CHUNKSIZE. */
membuf_prepare_space(&p->rpc_conn.mb, READ_CHUNKSIZE);
r = read(p->rpc_conn.fd, membuf_space(&p->rpc_conn.mb),
membuf_num_space(&p->rpc_conn.mb));
membuf_prepare_space(&p->rpc_conn->mb, READ_CHUNKSIZE);
r = read(p->rpc_conn->fd, membuf_space(&p->rpc_conn->mb),
membuf_num_space(&p->rpc_conn->mb));
/* lightningd goes away, we go away. */
if (r == 0)
exit(0);
if (r < 0)
plugin_err(p, "Reading JSON input: %s", strerror(errno));
membuf_added(&p->rpc_conn.mb, r);
membuf_added(&p->rpc_conn->mb, r);
}
return end + 2 - membuf_elems(&p->rpc_conn.mb);
return end + 2 - membuf_elems(&p->rpc_conn->mb);
}
/* This starts a JSON RPC message with boilerplate */
@ -317,20 +322,20 @@ static const jsmntok_t *read_rpc_reply(const tal_t *ctx,
*reqlen = read_json_from_rpc(plugin);
toks = json_parse_input(ctx, membuf_elems(&plugin->rpc_conn.mb), *reqlen, &valid);
toks = json_parse_input(ctx, membuf_elems(&plugin->rpc_conn->mb), *reqlen, &valid);
if (!valid)
plugin_err(plugin, "Malformed JSON reply '%.*s'",
*reqlen, membuf_elems(&plugin->rpc_conn.mb));
*reqlen, membuf_elems(&plugin->rpc_conn->mb));
*contents = json_get_member(membuf_elems(&plugin->rpc_conn.mb), toks, "error");
*contents = json_get_member(membuf_elems(&plugin->rpc_conn->mb), toks, "error");
if (*contents)
*error = true;
else {
*contents = json_get_member(membuf_elems(&plugin->rpc_conn.mb), toks,
*contents = json_get_member(membuf_elems(&plugin->rpc_conn->mb), toks,
"result");
if (!*contents)
plugin_err(plugin, "JSON reply with no 'result' nor 'error'? '%.*s'",
*reqlen, membuf_elems(&plugin->rpc_conn.mb));
*reqlen, membuf_elems(&plugin->rpc_conn->mb));
*error = false;
}
return toks;
@ -366,20 +371,20 @@ const char *rpc_delve(const tal_t *ctx,
struct json_out *jout;
jout = start_json_request(tmpctx, 0, method, params);
finish_and_send_json(plugin->rpc_conn.fd, jout);
finish_and_send_json(plugin->rpc_conn->fd, jout);
read_rpc_reply(tmpctx, plugin, &contents, &error, &reqlen);
if (error)
plugin_err(plugin, "Got error reply to %s: '%.*s'",
method, reqlen, membuf_elems(&plugin->rpc_conn.mb));
method, reqlen, membuf_elems(&plugin->rpc_conn->mb));
t = json_delve(membuf_elems(&plugin->rpc_conn.mb), contents, guide);
t = json_delve(membuf_elems(&plugin->rpc_conn->mb), contents, guide);
if (!t)
plugin_err(plugin, "Could not find %s in reply to %s: '%.*s'",
guide, method, reqlen, membuf_elems(&plugin->rpc_conn.mb));
guide, method, reqlen, membuf_elems(&plugin->rpc_conn->mb));
ret = json_strdup(ctx, membuf_elems(&plugin->rpc_conn.mb), t);
membuf_consume(&plugin->rpc_conn.mb, reqlen);
ret = json_strdup(ctx, membuf_elems(&plugin->rpc_conn->mb), t);
membuf_consume(&plugin->rpc_conn->mb, reqlen);
return ret;
}
@ -646,7 +651,7 @@ static struct command_result *handle_init(struct command *cmd,
chainparams = chainparams_for_network(network);
rpctok = json_delve(buf, configtok, ".rpc-file");
p->rpc_conn.fd = socket(AF_UNIX, SOCK_STREAM, 0);
p->rpc_conn->fd = socket(AF_UNIX, SOCK_STREAM, 0);
if (rpctok->end - rpctok->start + 1 > sizeof(addr.sun_path))
plugin_err(p, "rpc filename '%.*s' too long",
rpctok->end - rpctok->start,
@ -655,7 +660,7 @@ static struct command_result *handle_init(struct command *cmd,
addr.sun_path[rpctok->end - rpctok->start] = '\0';
addr.sun_family = AF_UNIX;
if (connect(p->rpc_conn.fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
if (connect(p->rpc_conn->fd, (struct sockaddr *)&addr, sizeof(addr)) != 0)
plugin_err(p, "Connecting to '%.*s': %s",
rpctok->end - rpctok->start, buf + rpctok->start,
strerror(errno));
@ -685,7 +690,7 @@ static struct command_result *handle_init(struct command *cmd,
if (p->init)
p->init(p, buf, configtok);
io_new_conn(p, p->rpc_conn.fd, rpc_conn_init, p);
io_new_conn(p, p->rpc_conn->fd, rpc_conn_init, p);
return command_success_str(cmd, NULL);
}
@ -1028,7 +1033,8 @@ static struct plugin *new_plugin(const tal_t *ctx,
p->next_outreq_id = 0;
uintmap_init(&p->out_reqs);
/* Sync RPC FIXME: maybe go full async ? */
membuf_init(&p->rpc_conn.mb,
p->rpc_conn = tal(p, struct rpc_conn);
membuf_init(&p->rpc_conn->mb,
tal_arr(p, char, READ_CHUNKSIZE), READ_CHUNKSIZE,
membuf_tal_realloc);

View file

@ -17,17 +17,13 @@
#include <common/status_levels.h>
struct json_out;
struct rpc_conn;
enum plugin_restartability {
PLUGIN_STATIC,
PLUGIN_RESTARTABLE
};
struct rpc_conn {
int fd;
MEMBUF(char) mb;
};
struct plugin {
/* lightningd interaction */
struct io_conn *stdin_conn;
@ -50,7 +46,7 @@ struct plugin {
u64 next_outreq_id;
/* Synchronous RPC interaction */
struct rpc_conn rpc_conn;
struct rpc_conn *rpc_conn;
/* Plugin informations */
enum plugin_restartability restartability;