libplugin: don't call callbacks if cmd completed before response.

This can particularly happen with commando:

```
 commando: FATAL SIGNAL 11 (version 06b36d3)
0x55609e953d51 send_backtrace
	common/daemon.c:33
0x55609e953dfb crashdump
	common/daemon.c:46
0x7f665e3b908f ???
	/build/glibc-SzIz7B/glibc-2.31/signal/../sysdeps/unix/sysv/linux/x86_64/sigaction.c:0
0x55609e9387a3 send_more_cmd
	plugins/commando.c:632
0x55609e93b270 handle_rpc_reply
	plugins/libplugin.c:669
0x55609e93bd50 rpc_read_response_one
	plugins/libplugin.c:842
0x55609e93be86 rpc_conn_read_response
	plugins/libplugin.c:862
0x55609e9f4f68 next_plan
	ccan/ccan/io/io.c:59
0x55609e9f5b70 do_plan
	ccan/ccan/io/io.c:407
0x55609e9f5bb2 io_ready
	ccan/ccan/io/io.c:417
0x55609e9f7ea5 io_loop
	ccan/ccan/io/poll.c:453
0x55609e93eb20 plugin_main
	plugins/libplugin.c:1676
0x55609e9397ab main
	plugins/commando.c:922
0x7f665e39a082 __libc_start_main
	../csu/libc-start.c:308
0x55609e93677d ???
	???:0
0xffffffffffffffff ???
	???:0
```

Reported-by: @adi2011
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2022-07-21 11:19:30 +09:30 committed by neil saitug
parent b3fde87063
commit 43e5ef3cc4
1 changed files with 24 additions and 0 deletions

View File

@ -135,6 +135,22 @@ static void ld_rpc_send(struct plugin *plugin, struct json_stream *stream)
io_wake(plugin->io_rpc_conn);
}
/* When cmd for request is gone, we use this as noop callback */
static struct command_result *ignore_cb(struct command *command,
const char *buf,
const jsmntok_t *result,
void *arg)
{
return command_done();
}
static void disable_request_cb(struct command *cmd, struct out_req *out)
{
out->errcb = NULL;
out->cb = ignore_cb;
}
/* FIXME: Move lightningd/jsonrpc to common/ ? */
struct out_req *
@ -160,6 +176,10 @@ jsonrpc_request_start_(struct plugin *plugin, struct command *cmd,
out->arg = arg;
uintmap_add(&plugin->out_reqs, out->id, out);
/* If command goes away, don't call callbacks! */
if (out->cmd)
tal_add_destructor2(out->cmd, disable_request_cb, out);
out->js = new_json_stream(NULL, cmd, NULL);
json_object_start(out->js, NULL);
json_add_string(out->js, "jsonrpc", "2.0");
@ -646,6 +666,10 @@ static void handle_rpc_reply(struct plugin *plugin, const jsmntok_t *toks)
json_tok_full_len(toks),
json_tok_full(plugin->rpc_buffer, toks), id);
/* Remove destructor if one existed */
if (out->cmd)
tal_del_destructor2(out->cmd, disable_request_cb, out);
/* We want to free this if callback doesn't. */
tal_steal(tmpctx, out);
uintmap_del(&plugin->out_reqs, out->id);