diff --git a/channeld/channeld.c b/channeld/channeld.c index c0a2d4685..01736f526 100644 --- a/channeld/channeld.c +++ b/channeld/channeld.c @@ -29,7 +29,6 @@ #include #include #include -#include #include #include #include @@ -50,15 +49,6 @@ #define MASTER_FD STDIN_FILENO #define HSM_FD 5 -enum pong_expect_type { - /* We weren't expecting a ping reply */ - PONG_UNEXPECTED = 0, - /* We were expecting a ping reply due to ping command */ - PONG_EXPECTED_COMMAND = 1, - /* We were expecting a ping reply due to ping timer */ - PONG_EXPECTED_PROBING = 2, -}; - struct peer { struct per_peer_state *pps; bool funding_locked[NUM_SIDES]; @@ -110,12 +100,6 @@ struct peer { u64 commit_timer_attempts; u32 commit_msec; - /* Random ping timer, to detect dead connections. */ - struct oneshot *ping_timer; - - /* Are we expecting a pong? */ - enum pong_expect_type expecting_pong; - /* The feerate we want. */ u32 desired_feerate; @@ -1095,29 +1079,6 @@ static struct bitcoin_signature *calc_commitsigs(const tal_t *ctx, return htlc_sigs; } -/* Mutual recursion */ -static void send_ping(struct peer *peer); - -static void set_ping_timer(struct peer *peer) -{ - peer->ping_timer = new_reltimer(&peer->timers, peer, - time_from_sec(15 + pseudorand(30)), - send_ping, peer); -} - -static void send_ping(struct peer *peer) -{ - /* Already have a ping in flight? */ - if (peer->expecting_pong != PONG_UNEXPECTED) { - status_debug("Last ping unreturned: hanging up"); - exit(0); - } - - peer_write(peer->pps, take(make_ping(NULL, 1, 0))); - peer->expecting_pong = PONG_EXPECTED_PROBING; - set_ping_timer(peer); -} - /* Peer protocol doesn't want sighash flags. */ static secp256k1_ecdsa_signature *raw_sigs(const tal_t *ctx, const struct bitcoin_signature *sigs) @@ -2190,29 +2151,6 @@ static void handle_unexpected_reestablish(struct peer *peer, const u8 *msg) &channel_id)); } -static void handle_ping_reply(struct peer *peer, const u8 *msg) -{ - u8 *ignored; - size_t i; - - /* We print this out because we asked for pong, so can't spam us... */ - if (!fromwire_pong(msg, msg, &ignored)) - status_unusual("Got malformed ping reply %s", - tal_hex(tmpctx, msg)); - - /* We print this because dev versions of c-lightning embed - * version here: see check_ping_make_pong! */ - for (i = 0; i < tal_count(ignored); i++) { - if (ignored[i] < ' ' || ignored[i] == 127) - break; - } - status_debug("Got pong %zu bytes (%.*s...)", - tal_count(ignored), (int)i, (char *)ignored); - wire_sync_write(MASTER_FD, - take(towire_channeld_ping_reply(NULL, true, - tal_bytelen(msg)))); -} - static void peer_in(struct peer *peer, const u8 *msg) { enum peer_wire type = fromwire_peektype(msg); @@ -2298,19 +2236,6 @@ static void peer_in(struct peer *peer, const u8 *msg) case WIRE_INIT_RBF: case WIRE_ACK_RBF: break; - case WIRE_PONG: - switch (peer->expecting_pong) { - case PONG_EXPECTED_COMMAND: - handle_ping_reply(peer, msg); - /* fall thru */ - case PONG_EXPECTED_PROBING: - peer->expecting_pong = PONG_UNEXPECTED; - return; - case PONG_UNEXPECTED: - status_debug("Unexpected pong?"); - return; - } - abort(); case WIRE_CHANNEL_REESTABLISH: handle_unexpected_reestablish(peer, msg); @@ -2326,6 +2251,7 @@ static void peer_in(struct peer *peer, const u8 *msg) case WIRE_GOSSIP_TIMESTAMP_FILTER: case WIRE_REPLY_SHORT_CHANNEL_IDS_END: case WIRE_PING: + case WIRE_PONG: case WIRE_WARNING: case WIRE_ERROR: case WIRE_OBS2_ONION_MESSAGE: @@ -3608,57 +3534,6 @@ static void handle_send_error(struct peer *peer, const u8 *msg) take(towire_channeld_send_error_reply(NULL))); } -static void handle_send_ping(struct peer *peer, const u8 *msg) -{ - u8 *ping; - u16 len, num_pong_bytes; - - if (!fromwire_channeld_ping(msg, &num_pong_bytes, &len)) - master_badmsg(WIRE_CHANNELD_PING, msg); - - /* We're not supposed to send another ping until previous replied */ - if (peer->expecting_pong != PONG_UNEXPECTED) { - wire_sync_write(MASTER_FD, - take(towire_channeld_ping_reply(NULL, false, 0))); - return; - } - - /* It should never ask for an oversize ping. */ - ping = make_ping(NULL, num_pong_bytes, len); - if (tal_count(ping) > 65535) - status_failed(STATUS_FAIL_MASTER_IO, "Oversize ping"); - - peer_write(peer->pps, take(ping)); - - /* Since we're doing this manually, kill and restart timer. */ - status_debug("sending ping expecting %sresponse", - num_pong_bytes >= 65532 ? "no " : ""); - - /* BOLT #1: - * - * A node receiving a `ping` message: - *... - * - if `num_pong_bytes` is less than 65532: - * - MUST respond by sending a `pong` message, with `byteslen` equal - * to `num_pong_bytes`. - * - otherwise (`num_pong_bytes` is **not** less than 65532): - * - MUST ignore the `ping`. - */ - if (num_pong_bytes >= 65532) { - wire_sync_write(MASTER_FD, - take(towire_channeld_ping_reply(NULL, - true, 0))); - return; - } - - /* We'll respond to lightningd once the pong comes in */ - peer->expecting_pong = PONG_EXPECTED_COMMAND; - - /* Restart our timed pings now. */ - tal_free(peer->ping_timer); - set_ping_timer(peer); -} - #if DEVELOPER static void handle_dev_reenable_commit(struct peer *peer) { @@ -3757,9 +3632,6 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_SEND_ERROR: handle_send_error(peer, msg); return; - case WIRE_CHANNELD_PING: - handle_send_ping(peer, msg); - return; case WIRE_CHANNELD_CHANNEL_UPDATE: handle_channel_update(peer, msg); return; @@ -3798,7 +3670,6 @@ static void req_in(struct peer *peer, const u8 *msg) case WIRE_CHANNELD_SEND_ERROR_REPLY: case WIRE_CHANNELD_DEV_QUIESCE_REPLY: case WIRE_CHANNELD_UPGRADED: - case WIRE_CHANNELD_PING_REPLY: case WIRE_CHANNELD_USED_CHANNEL_UPDATE: case WIRE_CHANNELD_LOCAL_CHANNEL_UPDATE: case WIRE_CHANNELD_LOCAL_CHANNEL_ANNOUNCEMENT: @@ -4039,10 +3910,8 @@ int main(int argc, char *argv[]) status_setup_sync(MASTER_FD); peer = tal(NULL, struct peer); - peer->expecting_pong = PONG_UNEXPECTED; timers_init(&peer->timers, time_mono()); peer->commit_timer = NULL; - set_ping_timer(peer); peer->have_sigs[LOCAL] = peer->have_sigs[REMOTE] = false; peer->announce_depth_reached = false; peer->channel_local_active = false; diff --git a/channeld/channeld_wire.csv b/channeld/channeld_wire.csv index 4770aea3d..a444125ce 100644 --- a/channeld/channeld_wire.csv +++ b/channeld/channeld_wire.csv @@ -266,14 +266,3 @@ msgdata,channeld_upgraded,new_type,channel_type, # Tell peer about our latest and greatest blockheight. msgtype,channeld_blockheight,1012 msgdata,channeld_blockheight,blockheight,u32, - -# Ping/pong test. Waits for a reply if it expects one. -msgtype,channeld_ping,1030 -msgdata,channeld_ping,num_pong_bytes,u16, -msgdata,channeld_ping,len,u16, - -msgtype,channeld_ping_reply,1130 -# False if we there was already a ping in progress. -msgdata,channeld_ping_reply,sent,bool, -# 0 == no pong expected, otherwise length of pong. -msgdata,channeld_ping_reply,totlen,u16, diff --git a/connectd/Makefile b/connectd/Makefile index fdf21e23e..779a354a8 100644 --- a/connectd/Makefile +++ b/connectd/Makefile @@ -57,6 +57,7 @@ CONNECTD_COMMON_OBJS := \ common/msg_queue.o \ common/node_id.o \ common/onionreply.o \ + common/ping.o \ common/per_peer_state.o \ common/psbt_open.o \ common/pseudorand.o \ diff --git a/connectd/connectd.c b/connectd/connectd.c index babdd5c00..1d9bdfe29 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -1966,6 +1966,10 @@ static struct io_plan *recv_req(struct io_conn *conn, peer_final_msg(conn, daemon, msg); goto out; + case WIRE_CONNECTD_PING: + send_manual_ping(daemon, msg); + goto out; + case WIRE_CONNECTD_DEV_MEMLEAK: #if DEVELOPER dev_connect_memleak(daemon, msg); @@ -1978,6 +1982,7 @@ static struct io_plan *recv_req(struct io_conn *conn, case WIRE_CONNECTD_RECONNECTED: case WIRE_CONNECTD_CONNECT_FAILED: case WIRE_CONNECTD_DEV_MEMLEAK_REPLY: + case WIRE_CONNECTD_PING_REPLY: break; } diff --git a/connectd/connectd.h b/connectd/connectd.h index 86800f1e9..7b2eaa98d 100644 --- a/connectd/connectd.h +++ b/connectd/connectd.h @@ -27,6 +27,16 @@ struct gossip_state { size_t off; }; +/*~ We need to know if we were expecting a pong, and why */ +enum pong_expect_type { + /* We weren't expecting a ping reply */ + PONG_UNEXPECTED = 0, + /* We were expecting a ping reply due to ping command */ + PONG_EXPECTED_COMMAND = 1, + /* We were expecting a ping reply due to ping timer */ + PONG_EXPECTED_PROBING = 2, +}; + /*~ We keep a hash table (ccan/htable) of peers, which tells us what peers are * already connected (by peer->id). */ struct peer { @@ -65,6 +75,12 @@ struct peer { /* We stream from the gossip_store for them, when idle */ struct gossip_state gs; + /* Are we expecting a pong? */ + enum pong_expect_type expecting_pong; + + /* Random ping timer, to detect dead connections. */ + struct oneshot *ping_timer; + #if DEVELOPER bool dev_read_enabled; /* If non-NULL, this counts down; 0 means disable */ diff --git a/connectd/connectd_wire.csv b/connectd/connectd_wire.csv index deee01f4f..b3f8f5b17 100644 --- a/connectd/connectd_wire.csv +++ b/connectd/connectd_wire.csv @@ -82,3 +82,15 @@ msgtype,connectd_dev_memleak,2033 msgtype,connectd_dev_memleak_reply,2133 msgdata,connectd_dev_memleak_reply,leak,bool, + +# Ping/pong test. Waits for a reply if it expects one. +msgtype,connectd_ping,2030 +msgdata,connectd_ping,id,node_id, +msgdata,connectd_ping,num_pong_bytes,u16, +msgdata,connectd_ping,len,u16, + +msgtype,connectd_ping_reply,2130 +# False if we there was already a ping in progress. +msgdata,connectd_ping_reply,sent,bool, +# 0 == no pong expected, otherwise length of pong. +msgdata,connectd_ping_reply,totlen,u16, diff --git a/connectd/multiplex.c b/connectd/multiplex.c index 2d0ee88b2..18010471a 100644 --- a/connectd/multiplex.c +++ b/connectd/multiplex.c @@ -14,12 +14,14 @@ #include #include #include +#include #include #include #include #include #include #include +#include #include #include #include @@ -337,32 +339,110 @@ again: return NULL; } -/* We handle gossip_timestamp_filter, and divert other gossip msgs to gossipd */ -static bool handle_message_locally(struct peer *peer, const u8 *msg) +/* Mutual recursion */ +static void send_ping(struct peer *peer); + +static void set_ping_timer(struct peer *peer) +{ + peer->ping_timer = new_reltimer(&peer->daemon->timers, peer, + time_from_sec(15 + pseudorand(30)), + send_ping, peer); +} + +static void send_ping(struct peer *peer) +{ + /* Already have a ping in flight? */ + if (peer->expecting_pong != PONG_UNEXPECTED) { + status_peer_debug(&peer->id, "Last ping unreturned: hanging up"); + if (peer->to_peer) + io_close(peer->to_peer); + return; + } + + queue_peer_msg(peer, take(make_ping(NULL, 1, 0))); + peer->expecting_pong = PONG_EXPECTED_PROBING; + set_ping_timer(peer); +} + +static void handle_ping_in(struct peer *peer, const u8 *msg) +{ + u8 *pong; + + /* gossipd doesn't log IO, so we log it here. */ + status_peer_io(LOG_IO_IN, &peer->id, msg); + + if (!check_ping_make_pong(NULL, msg, &pong)) { + send_warning(peer, "Invalid ping %s", tal_hex(msg, msg)); + return; + } + + if (pong) + queue_peer_msg(peer, take(pong)); +} + +static void handle_ping_reply(struct peer *peer, const u8 *msg) +{ + u8 *ignored; + size_t i; + + /* We print this out because we asked for pong, so can't spam us... */ + if (!fromwire_pong(msg, msg, &ignored)) + status_peer_unusual(&peer->id, "Got malformed ping reply %s", + tal_hex(tmpctx, msg)); + + /* We print this because dev versions of c-lightning embed + * version here: see check_ping_make_pong! */ + for (i = 0; i < tal_count(ignored); i++) { + if (ignored[i] < ' ' || ignored[i] == 127) + break; + } + status_debug("Got pong %zu bytes (%.*s...)", + tal_count(ignored), (int)i, (char *)ignored); + daemon_conn_send(peer->daemon->master, + take(towire_connectd_ping_reply(NULL, true, + tal_bytelen(msg)))); +} + +static void handle_pong_in(struct peer *peer, const u8 *msg) +{ + /* gossipd doesn't log IO, so we log it here. */ + status_peer_io(LOG_IO_IN, &peer->id, msg); + + switch (peer->expecting_pong) { + case PONG_EXPECTED_COMMAND: + handle_ping_reply(peer, msg); + /* fall thru */ + case PONG_EXPECTED_PROBING: + peer->expecting_pong = PONG_UNEXPECTED; + return; + case PONG_UNEXPECTED: + status_debug("Unexpected pong?"); + return; + } + abort(); +} + +/* Forward to gossipd */ +static void handle_gossip_in(struct peer *peer, const u8 *msg) +{ + u8 *gmsg = towire_gossipd_recv_gossip(NULL, &peer->id, msg); + + /* gossipd doesn't log IO, so we log it here. */ + status_peer_io(LOG_IO_IN, &peer->id, msg); + daemon_conn_send(peer->daemon->gossipd, take(gmsg)); +} + +static void handle_gossip_timetamp_filter_in(struct peer *peer, const u8 *msg) { struct bitcoin_blkid chain_hash; u32 first_timestamp, timestamp_range; - /* We remember these so we don't rexmit them */ - if (is_msg_gossip_broadcast(msg)) - gossip_rcvd_filter_add(peer->gs.grf, msg); - if (!fromwire_gossip_timestamp_filter(msg, &chain_hash, &first_timestamp, ×tamp_range)) { - /* Do we want to divert to gossipd? */ - if (is_msg_for_gossipd(msg)) { - u8 *gmsg = towire_gossipd_recv_gossip(NULL, - &peer->id, msg); - - /* gossipd doesn't log IO, so we log it here. */ - status_peer_io(LOG_IO_IN, &peer->id, msg); - - daemon_conn_send(peer->daemon->gossipd, take(gmsg)); - return true; - } - - return false; + send_warning(peer, "gossip_timestamp_filter invalid: %s", + tal_hex(tmpctx, msg)); + return; } /* gossipd doesn't log IO, so we log it here. */ @@ -371,7 +451,7 @@ static bool handle_message_locally(struct peer *peer, const u8 *msg) if (!bitcoin_blkid_eq(&chainparams->genesis_blockhash, &chain_hash)) { send_warning(peer, "gossip_timestamp_filter for bad chain: %s", tal_hex(tmpctx, msg)); - return true; + return; } peer->gs.timestamp_min = first_timestamp; @@ -388,8 +468,35 @@ static bool handle_message_locally(struct peer *peer, const u8 *msg) /* We send immediately the first time, after that we wait. */ if (!peer->gs.gossip_timer) wake_gossip(peer); +} - return true; +/* We handle pings and gossip messages. */ +static bool handle_message_locally(struct peer *peer, const u8 *msg) +{ + enum peer_wire type = fromwire_peektype(msg); + + /* We remember these so we don't rexmit them */ + if (is_msg_gossip_broadcast(msg)) + gossip_rcvd_filter_add(peer->gs.grf, msg); + + if (type == WIRE_GOSSIP_TIMESTAMP_FILTER) { + handle_gossip_timetamp_filter_in(peer, msg); + return true; + } else if (type == WIRE_PING) { + handle_ping_in(peer, msg); + return true; + } else if (type == WIRE_PONG) { + handle_pong_in(peer, msg); + return true; + } + + /* Do we want to divert to gossipd? */ + if (is_msg_for_gossipd(msg)) { + handle_gossip_in(peer, msg); + return true; + } + + return false; } static void close_timeout(struct peer *peer) @@ -665,6 +772,10 @@ struct io_plan *multiplex_peer_setup(struct io_conn *peer_conn, * lightningd to tell us to close with the peer */ tal_add_destructor2(peer_conn, destroy_peer_conn, peer); + /* Start keepalives */ + peer->expecting_pong = PONG_UNEXPECTED; + set_ping_timer(peer); + return io_duplex(peer_conn, read_hdr_from_peer(peer_conn, peer), write_to_peer(peer_conn, peer)); @@ -677,3 +788,65 @@ void multiplex_final_msg(struct peer *peer, const u8 *final_msg TAKES) if (!peer->to_subd) io_wake(peer->peer_outq); } + +/* Lightningd says to send a ping */ +void send_manual_ping(struct daemon *daemon, const u8 *msg) +{ + u8 *ping; + struct node_id id; + u16 len, num_pong_bytes; + struct peer *peer; + + if (!fromwire_connectd_ping(msg, &id, &num_pong_bytes, &len)) + master_badmsg(WIRE_CONNECTD_PING, msg); + + peer = peer_htable_get(&daemon->peers, &id); + if (!peer) { + daemon_conn_send(daemon->master, + take(towire_connectd_ping_reply(NULL, + false, 0))); + return; + } + + /* We're not supposed to send another ping until previous replied */ + if (peer->expecting_pong != PONG_UNEXPECTED) { + daemon_conn_send(daemon->master, + take(towire_connectd_ping_reply(NULL, + false, 0))); + return; + } + + /* It should never ask for an oversize ping. */ + ping = make_ping(NULL, num_pong_bytes, len); + if (tal_count(ping) > 65535) + status_failed(STATUS_FAIL_MASTER_IO, "Oversize ping"); + + queue_peer_msg(peer, take(ping)); + + status_debug("sending ping expecting %sresponse", + num_pong_bytes >= 65532 ? "no " : ""); + + /* BOLT #1: + * + * A node receiving a `ping` message: + *... + * - if `num_pong_bytes` is less than 65532: + * - MUST respond by sending a `pong` message, with `byteslen` equal + * to `num_pong_bytes`. + * - otherwise (`num_pong_bytes` is **not** less than 65532): + * - MUST ignore the `ping`. + */ + if (num_pong_bytes >= 65532) { + daemon_conn_send(daemon->master, + take(towire_connectd_ping_reply(NULL, + true, 0))); + return; + } + + /* We'll respond to lightningd once the pong comes in */ + peer->expecting_pong = PONG_EXPECTED_COMMAND; + + /* Since we're doing this manually, kill and restart timer. */ + tal_free(peer->ping_timer); + set_ping_timer(peer); +} diff --git a/connectd/multiplex.h b/connectd/multiplex.h index 0b3ba146a..bbb67e755 100644 --- a/connectd/multiplex.h +++ b/connectd/multiplex.h @@ -30,4 +30,7 @@ void setup_peer_gossip_store(struct peer *peer, /* Start the process of flushing and closing the peer_conn */ void close_peer_conn(struct peer *peer); + +/* When lightningd says to send a ping */ +void send_manual_ping(struct daemon *daemon, const u8 *msg); #endif /* LIGHTNING_CONNECTD_MULTIPLEX_H */ diff --git a/lightningd/Makefile b/lightningd/Makefile index 557bfb9c2..c6827849e 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -31,7 +31,6 @@ LIGHTNINGD_SRC := \ lightningd/peer_control.c \ lightningd/peer_fd.c \ lightningd/peer_htlcs.c \ - lightningd/ping.c \ lightningd/plugin.c \ lightningd/plugin_control.c \ lightningd/plugin_hook.c \ @@ -42,6 +41,7 @@ LIGHTNINGD_SRC := \ LIGHTNINGD_SRC_NOHDR := \ lightningd/datastore.c \ + lightningd/ping.c \ lightningd/offer.c \ lightningd/signmessage.c diff --git a/lightningd/channel_control.c b/lightningd/channel_control.c index 030b15b5e..2e7792dc8 100644 --- a/lightningd/channel_control.c +++ b/lightningd/channel_control.c @@ -22,7 +22,6 @@ #include #include #include -#include #include static void update_feerates(struct lightningd *ld, struct channel *channel) @@ -519,9 +518,6 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_SEND_ERROR_REPLY: handle_error_channel(sd->channel, msg); break; - case WIRE_CHANNELD_PING_REPLY: - ping_reply(sd, msg); - break; case WIRE_CHANNELD_USED_CHANNEL_UPDATE: /* This tells gossipd we used it. */ get_channel_update(sd->channel); @@ -565,7 +561,6 @@ static unsigned channel_msg(struct subd *sd, const u8 *msg, const int *fds) case WIRE_CHANNELD_DEV_MEMLEAK_REPLY: case WIRE_CHANNELD_SEND_ERROR: case WIRE_CHANNELD_DEV_QUIESCE_REPLY: - case WIRE_CHANNELD_PING: break; } diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index e46305595..ed037461a 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -363,10 +363,12 @@ static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fd case WIRE_CONNECTD_PEER_DISCONNECTED: case WIRE_CONNECTD_DEV_MEMLEAK: case WIRE_CONNECTD_PEER_FINAL_MSG: + case WIRE_CONNECTD_PING: /* This is a reply, so never gets through to here. */ case WIRE_CONNECTD_INIT_REPLY: case WIRE_CONNECTD_ACTIVATE_REPLY: case WIRE_CONNECTD_DEV_MEMLEAK_REPLY: + case WIRE_CONNECTD_PING_REPLY: break; case WIRE_CONNECTD_RECONNECTED: diff --git a/lightningd/ping.c b/lightningd/ping.c index e97351595..144dbe8fa 100644 --- a/lightningd/ping.c +++ b/lightningd/ping.c @@ -1,83 +1,39 @@ #include "config.h" -#include #include #include #include +#include #include #include #include #include -#include #include -struct ping_command { - struct list_node list; - struct node_id id; - struct command *cmd; -}; - -static struct ping_command *find_ping_cmd(struct lightningd *ld, - const struct node_id *id) -{ - struct ping_command *i; - - list_for_each(&ld->ping_commands, i, list) { - if (node_id_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 node_id *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 *channeld, const u8 *msg) +static void ping_reply(struct subd *connectd, + const u8 *msg, const int *fds, + struct command *cmd) { u16 totlen; bool sent; - struct ping_command *pc; - struct channel *c = channeld->channel; - log_debug(channeld->log, "Got ping reply!"); - pc = find_ping_cmd(channeld->ld, &c->peer->id); - if (!pc) { - log_broken(channeld->log, "Unexpected ping reply?"); - return; - } + log_debug(connectd->log, "Got ping reply!"); - if (!fromwire_channeld_ping_reply(msg, &sent, &totlen)) { - log_broken(channeld->log, "Malformed ping reply %s", + if (!fromwire_connectd_ping_reply(msg, &sent, &totlen)) { + log_broken(connectd->log, "Malformed ping reply %s", tal_hex(tmpctx, msg)); - was_pending(command_fail(pc->cmd, LIGHTNINGD, + was_pending(command_fail(cmd, LIGHTNINGD, "Bad reply message")); return; } if (!sent) - was_pending(command_fail(pc->cmd, LIGHTNINGD, + was_pending(command_fail(cmd, LIGHTNINGD, "Ping already pending")); else { - struct json_stream *response = json_stream_success(pc->cmd); + struct json_stream *response = json_stream_success(cmd); json_add_num(response, "totlen", totlen); - was_pending(command_success(pc->cmd, response)); + was_pending(command_success(cmd, response)); } } @@ -88,8 +44,6 @@ static struct command_result *json_ping(struct command *cmd, { unsigned int *len, *pongbytes; struct node_id *id; - struct peer *peer; - struct channel *channel; u8 *msg; if (!param(cmd, buffer, params, @@ -124,19 +78,11 @@ static struct command_result *json_ping(struct command *cmd, "pongbytes %u > 65535", *pongbytes); } - peer = peer_by_id(cmd->ld, id); - if (!peer) + if (!peer_by_id(cmd->ld, id)) return command_fail(cmd, LIGHTNINGD, "Peer not connected"); - channel = peer_active_channel(peer); - if (!channel || !channel->owner || channel->state != CHANNELD_NORMAL) - return command_fail(cmd, LIGHTNINGD, "Peer bad state"); - - /* parent is cmd, so when we complete cmd, we free this. */ - new_ping_command(cmd, cmd->ld, id, cmd); - - msg = towire_channeld_ping(NULL, *pongbytes, *len); - subd_send_msg(channel->owner, take(msg)); + msg = towire_connectd_ping(NULL, id, *pongbytes, *len); + subd_req(cmd, cmd->ld->connectd, take(msg), -1, 0, ping_reply, cmd); return command_still_pending(cmd); } diff --git a/lightningd/ping.h b/lightningd/ping.h deleted file mode 100644 index fec5c90ee..000000000 --- a/lightningd/ping.h +++ /dev/null @@ -1,9 +0,0 @@ -#ifndef LIGHTNING_LIGHTNINGD_PING_H -#define LIGHTNING_LIGHTNINGD_PING_H -#include "config.h" -#include - -struct subd; -void ping_reply(struct subd *subd, const u8 *msg); - -#endif /* LIGHTNING_LIGHTNINGD_PING_H */