mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-02-22 22:45:27 +01:00
commando: always use proper responses for commands.
All `struct command` should be terminated properly. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
7ce30e2873
commit
b1e2be3c89
1 changed files with 54 additions and 55 deletions
|
@ -32,6 +32,7 @@ enum commando_msgtype {
|
|||
};
|
||||
|
||||
struct commando {
|
||||
/* Only non-NULL for outgoing cmds */
|
||||
struct command *cmd;
|
||||
struct node_id peer;
|
||||
u64 id;
|
||||
|
@ -116,7 +117,7 @@ struct reply {
|
|||
};
|
||||
|
||||
/* Calls itself repeatedly: first time, result is NULL */
|
||||
static struct command_result *send_response(struct command *command UNUSED,
|
||||
static struct command_result *send_response(struct command *cmd,
|
||||
const char *buf UNUSED,
|
||||
const jsmntok_t *result,
|
||||
struct reply *reply)
|
||||
|
@ -133,7 +134,7 @@ static struct command_result *send_response(struct command *command UNUSED,
|
|||
} else {
|
||||
if (msglen == 0) {
|
||||
tal_free(reply);
|
||||
return command_done();
|
||||
return command_hook_success(cmd);
|
||||
}
|
||||
msgtype = COMMANDO_MSG_REPLY_TERM;
|
||||
}
|
||||
|
@ -144,7 +145,7 @@ static struct command_result *send_response(struct command *command UNUSED,
|
|||
towire(&cmd_msg, reply->buf + reply->off, msglen);
|
||||
reply->off += msglen;
|
||||
|
||||
req = jsonrpc_request_start(plugin, NULL, "sendcustommsg",
|
||||
req = jsonrpc_request_start(plugin, cmd, "sendcustommsg",
|
||||
send_response, send_response,
|
||||
reply);
|
||||
json_add_node_id(req->js, "node_id", &reply->incoming->peer);
|
||||
|
@ -152,7 +153,7 @@ static struct command_result *send_response(struct command *command UNUSED,
|
|||
tal_free(cmd_msg);
|
||||
send_outreq(plugin, req);
|
||||
|
||||
return command_done();
|
||||
return command_still_pending(cmd);
|
||||
}
|
||||
|
||||
static struct command_result *cmd_done(struct command *command,
|
||||
|
@ -192,12 +193,14 @@ static struct command_result *cmd_done(struct command *command,
|
|||
return send_response(command, NULL, NULL, reply);
|
||||
}
|
||||
|
||||
static void commando_error(struct commando *incoming,
|
||||
static struct command_result *commando_error(struct command *cmd,
|
||||
struct commando *incoming,
|
||||
int ecode,
|
||||
const char *fmt, ...)
|
||||
PRINTF_FMT(3,4);
|
||||
PRINTF_FMT(4, 5);
|
||||
|
||||
static void commando_error(struct commando *incoming,
|
||||
static struct command_result *commando_error(struct command *cmd,
|
||||
struct commando *incoming,
|
||||
int ecode,
|
||||
const char *fmt, ...)
|
||||
{
|
||||
|
@ -213,7 +216,7 @@ static void commando_error(struct commando *incoming,
|
|||
reply->off = 0;
|
||||
reply->len = tal_bytelen(reply->buf) - 1;
|
||||
|
||||
send_response(NULL, NULL, NULL, reply);
|
||||
return send_response(cmd, NULL, NULL, reply);
|
||||
}
|
||||
|
||||
struct cond_info {
|
||||
|
@ -270,12 +273,13 @@ static struct cond_info *new_cond_info(const tal_t *ctx,
|
|||
return cinfo;
|
||||
}
|
||||
|
||||
static struct command_result *execute_command(struct cond_info *cinfo)
|
||||
static struct command_result *execute_command(struct command *cmd,
|
||||
struct cond_info *cinfo)
|
||||
{
|
||||
struct out_req *req;
|
||||
|
||||
/* We handle success and failure the same */
|
||||
req = jsonrpc_request_whole_object_start(plugin, NULL,
|
||||
req = jsonrpc_request_whole_object_start(plugin, cmd,
|
||||
json_strdup(tmpctx, cinfo->buf, cinfo->method),
|
||||
cinfo->cmdid_prefix,
|
||||
cmd_done, cinfo->incoming);
|
||||
|
@ -336,12 +340,12 @@ static struct command_result *checkrune_done(struct command *cmd,
|
|||
|
||||
/* Shouldn't happen! */
|
||||
if (!valid) {
|
||||
commando_error(cinfo->incoming, COMMANDO_ERROR_REMOTE,
|
||||
return commando_error(cmd, cinfo->incoming,
|
||||
COMMANDO_ERROR_REMOTE,
|
||||
"Invalid rune");
|
||||
return command_done();
|
||||
}
|
||||
|
||||
return execute_command(cinfo);
|
||||
return execute_command(cmd, cinfo);
|
||||
}
|
||||
|
||||
static struct command_result *checkrune_failed(struct command *cmd,
|
||||
|
@ -357,13 +361,14 @@ static struct command_result *checkrune_failed(struct command *cmd,
|
|||
json_tok_full(buf, result));
|
||||
}
|
||||
|
||||
commando_error(cinfo->incoming, COMMANDO_ERROR_REMOTE_AUTH,
|
||||
return commando_error(cmd, cinfo->incoming,
|
||||
COMMANDO_ERROR_REMOTE_AUTH,
|
||||
"Invalid rune: %.*s",
|
||||
msg->end - msg->start, buf + msg->start);
|
||||
return command_done();
|
||||
}
|
||||
|
||||
static void try_command(struct commando *incoming STEALS)
|
||||
static struct command_result *try_command(struct command *cmd,
|
||||
struct commando *incoming STEALS)
|
||||
{
|
||||
const jsmntok_t *toks, *method, *params, *runetok, *id, *filter;
|
||||
const char *buf = (const char *)incoming->contents;
|
||||
|
@ -373,45 +378,40 @@ static void try_command(struct commando *incoming STEALS)
|
|||
|
||||
toks = json_parse_simple(incoming, buf, tal_bytelen(buf));
|
||||
if (!toks) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE,
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"Invalid JSON");
|
||||
return;
|
||||
}
|
||||
|
||||
if (toks[0].type != JSMN_OBJECT) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE,
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"Not a JSON object");
|
||||
return;
|
||||
}
|
||||
method = json_get_member(buf, toks, "method");
|
||||
if (!method) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE,
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"No method");
|
||||
return;
|
||||
}
|
||||
params = json_get_member(buf, toks, "params");
|
||||
if (params && (params->type != JSMN_OBJECT && params->type != JSMN_ARRAY)) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE,
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"Params must be object or array");
|
||||
return;
|
||||
}
|
||||
filter = json_get_member(buf, toks, "filter");
|
||||
id = json_get_member(buf, toks, "id");
|
||||
if (!id) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE,
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"missing id field");
|
||||
return;
|
||||
}
|
||||
runetok = json_get_member(buf, toks, "rune");
|
||||
if (!runetok) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE, "Missing rune");
|
||||
return;
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"Missing rune");
|
||||
}
|
||||
rune = rune_from_base64n(tmpctx, buf + runetok->start,
|
||||
runetok->end - runetok->start);
|
||||
if (!rune) {
|
||||
commando_error(incoming, COMMANDO_ERROR_REMOTE, "Invalid rune");
|
||||
return;
|
||||
return commando_error(cmd, incoming, COMMANDO_ERROR_REMOTE,
|
||||
"Invalid rune");
|
||||
}
|
||||
/* Gather all the info we need to execute this command (steals toks). */
|
||||
cinfo = new_cond_info(incoming, incoming, toks, method, params, id, filter);
|
||||
|
@ -420,7 +420,7 @@ static void try_command(struct commando *incoming STEALS)
|
|||
destroy_commando(incoming, &incoming_commands);
|
||||
tal_del_destructor2(incoming, destroy_commando, &incoming_commands);
|
||||
|
||||
req = jsonrpc_request_start(plugin, NULL, "checkrune",
|
||||
req = jsonrpc_request_start(plugin, cmd, "checkrune",
|
||||
checkrune_done, checkrune_failed,
|
||||
cinfo);
|
||||
json_add_node_id(req->js, "nodeid", &incoming->peer);
|
||||
|
@ -428,10 +428,10 @@ static void try_command(struct commando *incoming STEALS)
|
|||
json_add_tok(req->js, "method", method, cinfo->buf);
|
||||
if (params)
|
||||
json_add_tok(req->js, "params", params, cinfo->buf);
|
||||
send_outreq(plugin, req);
|
||||
return send_outreq(plugin, req);
|
||||
}
|
||||
|
||||
static void handle_incmd(struct command *cmd,
|
||||
static struct command_result *handle_incmd(struct command *cmd,
|
||||
struct node_id *peer,
|
||||
u64 idnum,
|
||||
const u8 *msg, size_t msglen,
|
||||
|
@ -462,15 +462,15 @@ static void handle_incmd(struct command *cmd,
|
|||
append_contents(incmd, msg, msglen, 1024*1024);
|
||||
|
||||
if (!terminal)
|
||||
return;
|
||||
return command_hook_success(cmd);
|
||||
|
||||
if (!incmd->contents) {
|
||||
plugin_log(plugin, LOG_UNUSUAL, "%s: ignoring oversize request",
|
||||
fmt_node_id(tmpctx, peer));
|
||||
return;
|
||||
return command_hook_success(cmd);
|
||||
}
|
||||
|
||||
try_command(incmd);
|
||||
return try_command(cmd, incmd);
|
||||
}
|
||||
|
||||
static struct command_result *handle_reply(struct node_id *peer,
|
||||
|
@ -592,9 +592,8 @@ static struct command_result *handle_custommsg(struct command *cmd,
|
|||
switch (mtype) {
|
||||
case COMMANDO_MSG_CMD_CONTINUES:
|
||||
case COMMANDO_MSG_CMD_TERM:
|
||||
handle_incmd(cmd, &peer, idnum, msg, len,
|
||||
return handle_incmd(cmd, &peer, idnum, msg, len,
|
||||
mtype == COMMANDO_MSG_CMD_TERM);
|
||||
break;
|
||||
case COMMANDO_MSG_REPLY_CONTINUES:
|
||||
case COMMANDO_MSG_REPLY_TERM:
|
||||
handle_reply(&peer, idnum, msg, len,
|
||||
|
|
Loading…
Add table
Reference in a new issue