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,,len,u16
|
||||||
|
|
||||||
gossip_ping_reply,3108
|
gossip_ping_reply,3108
|
||||||
|
gossip_ping_reply,,id,struct pubkey
|
||||||
# False if id in gossip_ping was unknown.
|
# False if id in gossip_ping was unknown.
|
||||||
gossip_ping_reply,,sent,bool
|
gossip_ping_reply,,sent,bool
|
||||||
# 0 == no pong expected
|
# 0 == no pong expected
|
||||||
|
|||||||
|
@@ -648,7 +648,7 @@ static void handle_pong(struct peer *peer, const u8 *pong)
|
|||||||
}
|
}
|
||||||
|
|
||||||
daemon_conn_send(&peer->daemon->master,
|
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))));
|
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);
|
peer = find_peer(daemon, &id);
|
||||||
if (!peer) {
|
if (!peer) {
|
||||||
daemon_conn_send(&daemon->master,
|
daemon_conn_send(&daemon->master,
|
||||||
take(towire_gossip_ping_reply(NULL, false, 0)));
|
take(towire_gossip_ping_reply(NULL, &id,
|
||||||
|
false, 0)));
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1581,7 +1582,8 @@ static struct io_plan *ping_req(struct io_conn *conn, struct daemon *daemon,
|
|||||||
*/
|
*/
|
||||||
if (num_pong_bytes >= 65532)
|
if (num_pong_bytes >= 65532)
|
||||||
daemon_conn_send(&daemon->master,
|
daemon_conn_send(&daemon->master,
|
||||||
take(towire_gossip_ping_reply(NULL, true, 0)));
|
take(towire_gossip_ping_reply(NULL, &id,
|
||||||
|
true, 0)));
|
||||||
else
|
else
|
||||||
peer->num_pings_outstanding++;
|
peer->num_pings_outstanding++;
|
||||||
|
|
||||||
|
|||||||
@@ -75,12 +75,12 @@ LIGHTNINGD_SRC := \
|
|||||||
lightningd/payalgo.c \
|
lightningd/payalgo.c \
|
||||||
lightningd/peer_control.c \
|
lightningd/peer_control.c \
|
||||||
lightningd/peer_htlcs.c \
|
lightningd/peer_htlcs.c \
|
||||||
|
lightningd/ping.c \
|
||||||
lightningd/subd.c \
|
lightningd/subd.c \
|
||||||
lightningd/watch.c
|
lightningd/watch.c
|
||||||
|
|
||||||
# Source files without corresponding headers
|
# Source files without corresponding headers
|
||||||
LIGHTNINGD_SRC_NOHDR := \
|
LIGHTNINGD_SRC_NOHDR := \
|
||||||
lightningd/ping.c \
|
|
||||||
lightningd/memdump.c
|
lightningd/memdump.c
|
||||||
|
|
||||||
LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o)
|
LIGHTNINGD_OBJS := $(LIGHTNINGD_SRC:.c=.o) $(LIGHTNINGD_SRC_NOHDR:.c=.o)
|
||||||
|
|||||||
@@ -27,6 +27,7 @@
|
|||||||
#include <lightningd/jsonrpc_errors.h>
|
#include <lightningd/jsonrpc_errors.h>
|
||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/param.h>
|
#include <lightningd/param.h>
|
||||||
|
#include <lightningd/ping.h>
|
||||||
#include <sodium/randombytes.h>
|
#include <sodium/randombytes.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <wire/gen_peer_wire.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_GETNODES_REPLY:
|
||||||
case WIRE_GOSSIP_GETROUTE_REPLY:
|
case WIRE_GOSSIP_GETROUTE_REPLY:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||||
case WIRE_GOSSIP_PING_REPLY:
|
|
||||||
case WIRE_GOSSIP_SCIDS_REPLY:
|
case WIRE_GOSSIP_SCIDS_REPLY:
|
||||||
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY:
|
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY:
|
||||||
case WIRE_GOSSIP_RESOLVE_CHANNEL_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:
|
case WIRE_GOSSIP_LOCAL_CHANNEL_CLOSE:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case WIRE_GOSSIP_PING_REPLY:
|
||||||
|
ping_reply(gossip, msg);
|
||||||
|
break;
|
||||||
|
|
||||||
case WIRE_GOSSIP_GET_TXOUT:
|
case WIRE_GOSSIP_GET_TXOUT:
|
||||||
get_txout(gossip, msg);
|
get_txout(gossip, msg);
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -176,6 +176,7 @@ static struct lightningd *new_lightningd(const tal_t *ctx)
|
|||||||
list_head_init(&ld->waitsendpay_commands);
|
list_head_init(&ld->waitsendpay_commands);
|
||||||
list_head_init(&ld->sendpay_commands);
|
list_head_init(&ld->sendpay_commands);
|
||||||
list_head_init(&ld->close_commands);
|
list_head_init(&ld->close_commands);
|
||||||
|
list_head_init(&ld->ping_commands);
|
||||||
|
|
||||||
/*~ Tal also explicitly supports arrays: it stores the number of
|
/*~ Tal also explicitly supports arrays: it stores the number of
|
||||||
* elements, which can be accessed with tal_count() (or tal_bytelen()
|
* elements, which can be accessed with tal_count() (or tal_bytelen()
|
||||||
|
|||||||
@@ -162,6 +162,8 @@ struct lightningd {
|
|||||||
struct list_head sendpay_commands;
|
struct list_head sendpay_commands;
|
||||||
/* Outstanding close commands. */
|
/* Outstanding close commands. */
|
||||||
struct list_head close_commands;
|
struct list_head close_commands;
|
||||||
|
/* Outstanding ping commands. */
|
||||||
|
struct list_head ping_commands;
|
||||||
|
|
||||||
/* Maintained by invoices.c */
|
/* Maintained by invoices.c */
|
||||||
struct invoices *invoices;
|
struct invoices *invoices;
|
||||||
|
|||||||
@@ -10,28 +10,71 @@
|
|||||||
#include <lightningd/log.h>
|
#include <lightningd/log.h>
|
||||||
#include <lightningd/param.h>
|
#include <lightningd/param.h>
|
||||||
#include <lightningd/peer_control.h>
|
#include <lightningd/peer_control.h>
|
||||||
|
#include <lightningd/ping.h>
|
||||||
#include <lightningd/subd.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 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;
|
u16 totlen;
|
||||||
bool ok, sent = true;
|
bool ok, sent = true;
|
||||||
|
struct pubkey id;
|
||||||
|
struct ping_command *pc;
|
||||||
|
|
||||||
log_debug(subd->ld->log, "Got ping reply!");
|
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)
|
if (!ok)
|
||||||
command_fail(cmd, LIGHTNINGD, "Bad reply message");
|
command_fail(pc->cmd, LIGHTNINGD, "Bad reply message");
|
||||||
else if (!sent)
|
else if (!sent)
|
||||||
command_fail(cmd, LIGHTNINGD, "Unknown peer");
|
command_fail(pc->cmd, LIGHTNINGD, "Unknown peer");
|
||||||
else {
|
else {
|
||||||
struct json_result *response = new_json_result(cmd);
|
struct json_result *response = new_json_result(pc->cmd);
|
||||||
|
|
||||||
json_object_start(response, NULL);
|
json_object_start(response, NULL);
|
||||||
json_add_num(response, "totlen", totlen);
|
json_add_num(response, "totlen", totlen);
|
||||||
json_object_end(response);
|
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;
|
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. */
|
/* gossipd handles all pinging, even if it's in another daemon. */
|
||||||
msg = towire_gossip_ping(NULL, id, *pongbytes, *len);
|
msg = towire_gossip_ping(NULL, id, *pongbytes, *len);
|
||||||
subd_req(cmd->ld->gossip, cmd->ld->gossip,
|
subd_send_msg(cmd->ld->gossip, take(msg));
|
||||||
take(msg), -1, 0, ping_reply, cmd);
|
|
||||||
command_still_pending(cmd);
|
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