mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 07:04:22 +01:00
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:
committed by
Christian Decker
parent
4a1bc0f90c
commit
704d30edce
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user