ping: complete JSON RPC ping commands even if one ping gets no response.

We would never complete further ping commands if we had < responses
than pings.  Oops.

Fixes: #1928
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell
2018-09-12 05:27:11 +09:30
committed by Christian Decker
parent 4a1bc0f90c
commit 704d30edce
8 changed files with 78 additions and 14 deletions

View File

@@ -10,28 +10,71 @@
#include <lightningd/log.h>
#include <lightningd/param.h>
#include <lightningd/peer_control.h>
#include <lightningd/ping.h>
#include <lightningd/subd.h>
static void ping_reply(struct subd *subd, const u8 *msg, const int *fds UNUSED,
struct command *cmd)
struct ping_command {
struct list_node list;
struct pubkey id;
struct command *cmd;
};
static struct ping_command *find_ping_cmd(struct lightningd *ld,
const struct pubkey *id)
{
struct ping_command *i;
list_for_each(&ld->ping_commands, i, list) {
if (pubkey_eq(id, &i->id))
return i;
}
return NULL;
}
static void destroy_ping_command(struct ping_command *pc)
{
list_del(&pc->list);
}
static struct ping_command *new_ping_command(const tal_t *ctx,
struct lightningd *ld,
const struct pubkey *peer_id,
struct command *cmd)
{
struct ping_command *pc = tal(ctx, struct ping_command);
pc->id = *peer_id;
pc->cmd = cmd;
list_add_tail(&ld->ping_commands, &pc->list);
tal_add_destructor(pc, destroy_ping_command);
return pc;
}
void ping_reply(struct subd *subd, const u8 *msg)
{
u16 totlen;
bool ok, sent = true;
struct pubkey id;
struct ping_command *pc;
log_debug(subd->ld->log, "Got ping reply!");
ok = fromwire_gossip_ping_reply(msg, &sent, &totlen);
ok = fromwire_gossip_ping_reply(msg, &id, &sent, &totlen);
pc = find_ping_cmd(subd->ld, &id);
assert(pc);
if (!ok)
command_fail(cmd, LIGHTNINGD, "Bad reply message");
command_fail(pc->cmd, LIGHTNINGD, "Bad reply message");
else if (!sent)
command_fail(cmd, LIGHTNINGD, "Unknown peer");
command_fail(pc->cmd, LIGHTNINGD, "Unknown peer");
else {
struct json_result *response = new_json_result(cmd);
struct json_result *response = new_json_result(pc->cmd);
json_object_start(response, NULL);
json_add_num(response, "totlen", totlen);
json_object_end(response);
command_success(cmd, response);
command_success(pc->cmd, response);
}
}
@@ -76,10 +119,12 @@ static void json_ping(struct command *cmd,
return;
}
/* parent is cmd, so when we complete cmd, we free this. */
new_ping_command(cmd, cmd->ld, id, cmd);
/* gossipd handles all pinging, even if it's in another daemon. */
msg = towire_gossip_ping(NULL, id, *pongbytes, *len);
subd_req(cmd->ld->gossip, cmd->ld->gossip,
take(msg), -1, 0, ping_reply, cmd);
subd_send_msg(cmd->ld->gossip, take(msg));
command_still_pending(cmd);
}