mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +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
@@ -52,6 +52,7 @@ gossip_ping,,num_pong_bytes,u16
|
||||
gossip_ping,,len,u16
|
||||
|
||||
gossip_ping_reply,3108
|
||||
gossip_ping_reply,,id,struct pubkey
|
||||
# False if id in gossip_ping was unknown.
|
||||
gossip_ping_reply,,sent,bool
|
||||
# 0 == no pong expected
|
||||
|
||||
|
@@ -648,7 +648,7 @@ static void handle_pong(struct peer *peer, const u8 *pong)
|
||||
}
|
||||
|
||||
daemon_conn_send(&peer->daemon->master,
|
||||
take(towire_gossip_ping_reply(NULL, true,
|
||||
take(towire_gossip_ping_reply(NULL, &peer->id, true,
|
||||
tal_count(pong))));
|
||||
}
|
||||
|
||||
@@ -1557,7 +1557,8 @@ static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
|
||||
peer = find_peer(daemon, &id);
|
||||
if (!peer) {
|
||||
daemon_conn_send(&daemon->master,
|
||||
take(towire_gossip_ping_reply(NULL, false, 0)));
|
||||
take(towire_gossip_ping_reply(NULL, &id,
|
||||
false, 0)));
|
||||
goto out;
|
||||
}
|
||||
|
||||
@@ -1581,7 +1582,8 @@ static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
|
||||
*/
|
||||
if (num_pong_bytes >= 65532)
|
||||
daemon_conn_send(&daemon->master,
|
||||
take(towire_gossip_ping_reply(NULL, true, 0)));
|
||||
take(towire_gossip_ping_reply(NULL, &id,
|
||||
true, 0)));
|
||||
else
|
||||
peer->num_pings_outstanding++;
|
||||
|
||||
|
||||
@@ -75,12 +75,12 @@ LIGHTNINGD_SRC := \
|
||||
lightningd/payalgo.c \
|
||||
lightningd/peer_control.c \
|
||||
lightningd/peer_htlcs.c \
|
||||
lightningd/ping.c \
|
||||
lightningd/subd.c \
|
||||
lightningd/watch.c
|
||||
|
||||
# Source files without corresponding headers
|
||||
LIGHTNINGD_SRC_NOHDR := \
|
||||
lightningd/ping.c \
|
||||
lightningd/memdump.c
|
||||
|
||||
LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o)
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
#include <lightningd/jsonrpc_errors.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/param.h>
|
||||
#include <lightningd/ping.h>
|
||||
#include <sodium/randombytes.h>
|
||||
#include <string.h>
|
||||
#include <wire/gen_peer_wire.h>
|
||||
@@ -121,7 +122,6 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
||||
case WIRE_GOSSIP_GETNODES_REPLY:
|
||||
case WIRE_GOSSIP_GETROUTE_REPLY:
|
||||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||
case WIRE_GOSSIP_PING_REPLY:
|
||||
case WIRE_GOSSIP_SCIDS_REPLY:
|
||||
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY:
|
||||
case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY:
|
||||
@@ -131,6 +131,10 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
|
||||
case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE:
|
||||
break;
|
||||
|
||||
case WIRE_GOSSIP_PING_REPLY:
|
||||
ping_reply(gossip, msg);
|
||||
break;
|
||||
|
||||
case WIRE_GOSSIP_GET_TXOUT:
|
||||
get_txout(gossip, msg);
|
||||
break;
|
||||
|
||||
@@ -176,6 +176,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
|
||||
list_head_init(&ld->waitsendpay_commands);
|
||||
list_head_init(&ld->sendpay_commands);
|
||||
list_head_init(&ld->close_commands);
|
||||
list_head_init(&ld->ping_commands);
|
||||
|
||||
/*~ Tal also explicitly supports arrays: it stores the number of
|
||||
* elements, which can be accessed with tal_count() (or tal_bytelen()
|
||||
|
||||
@@ -162,6 +162,8 @@ struct lightningd {
|
||||
struct list_head sendpay_commands;
|
||||
/* Outstanding close commands. */
|
||||
struct list_head close_commands;
|
||||
/* Outstanding ping commands. */
|
||||
struct list_head ping_commands;
|
||||
|
||||
/* Maintained by invoices.c */
|
||||
struct invoices *invoices;
|
||||
|
||||
@@ -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 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);
|
||||
}
|
||||
|
||||
|
||||
9
lightningd/ping.h
Normal file
9
lightningd/ping.h
Normal file
@@ -0,0 +1,9 @@
|
||||
#ifndef LIGHTNING_LIGHTNINGD_PING_H
|
||||
#define LIGHTNING_LIGHTNINGD_PING_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
|
||||
struct subd;
|
||||
void ping_reply(struct subd *subd, const u8 *msg);
|
||||
|
||||
#endif /* LIGHTNING_LIGHTNINGD_PING_H */
|
||||
Reference in New Issue
Block a user