From c64ce4bbf31752120c9c7013e5d53d10c6d3758d Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Sat, 16 Jul 2022 14:19:29 +0930 Subject: [PATCH] lightningd: clean up channels when connectd says peer is gone. This is redundant now, since connectd only sends us this once we tell it it's OK, but that's changing, so clean up now. This means that connectd will be able to make *unsolicited* closes, if it needs to. We share logic with peer_please_disconnect. Signed-off-by: Rusty Russell --- lightningd/connect_control.c | 21 +-------------------- lightningd/peer_control.c | 34 ++++++++++++++++++++++++++++++---- lightningd/peer_control.h | 2 ++ 3 files changed, 33 insertions(+), 24 deletions(-) diff --git a/lightningd/connect_control.c b/lightningd/connect_control.c index 7f0965afb..842fe8a28 100644 --- a/lightningd/connect_control.c +++ b/lightningd/connect_control.c @@ -390,7 +390,6 @@ static void peer_please_disconnect(struct lightningd *ld, const u8 *msg) { struct node_id id; struct peer *peer; - struct channel *c, **channels; if (!fromwire_connectd_reconnected(msg, &id)) fatal("Bad msg %s from connectd", tal_hex(tmpctx, msg)); @@ -399,25 +398,7 @@ static void peer_please_disconnect(struct lightningd *ld, const u8 *msg) if (!peer) return; - /* Freeing channels can free peer, so gather first. */ - channels = tal_arr(tmpctx, struct channel *, 0); - list_for_each(&peer->channels, c, list) - tal_arr_expand(&channels, c); - - if (peer->uncommitted_channel) - kill_uncommitted_channel(peer->uncommitted_channel, - "Reconnected"); - - for (size_t i = 0; i < tal_count(channels); i++) { - c = channels[i]; - if (channel_active(c)) { - channel_cleanup_commands(c, "Reconnected"); - channel_fail_reconnect(c, "Reconnected"); - } else if (channel_unsaved(c)) { - log_info(c->log, "Killing opening daemon: Reconnected"); - channel_unsaved_close_conn(c, "Reconnected"); - } - } + peer_channels_cleanup_on_disconnect(peer); } struct custommsg_payload { diff --git a/lightningd/peer_control.c b/lightningd/peer_control.c index 4dfaaaeea..0ceb9f4bd 100644 --- a/lightningd/peer_control.c +++ b/lightningd/peer_control.c @@ -136,6 +136,34 @@ void maybe_delete_peer(struct peer *peer) delete_peer(peer); } +void peer_channels_cleanup_on_disconnect(struct peer *peer) +{ + struct channel *c, **channels; + + /* Freeing channels can free peer, so gather first. */ + channels = tal_arr(tmpctx, struct channel *, 0); + list_for_each(&peer->channels, c, list) + tal_arr_expand(&channels, c); + + if (peer->uncommitted_channel) { + /* Frees peer if no channels */ + kill_uncommitted_channel(peer->uncommitted_channel, + "Disconnected"); + } else if (tal_count(channels) == 0) + /* Was completely idle. */ + tal_free(peer); + + for (size_t i = 0; i < tal_count(channels); i++) { + c = channels[i]; + if (channel_active(c)) { + channel_cleanup_commands(c, "Disconnected"); + channel_fail_reconnect(c, "Disconnected"); + } else if (channel_unsaved(c)) { + channel_unsaved_close_conn(c, "Disconnected"); + } + } +} + struct peer *find_peer_by_dbid(struct lightningd *ld, u64 dbid) { struct peer *p; @@ -1427,10 +1455,8 @@ void peer_disconnect_done(struct lightningd *ld, const u8 *msg) if (p) { log_peer_debug(ld->log, &id, "peer_disconnect_done"); p->is_connected = false; - /* If we only cared about peer because of connectd, free it. */ - if (list_empty(&p->channels) && !p->uncommitted_channel) { - tal_free(p); - } + + peer_channels_cleanup_on_disconnect(p); } /* Fire off plugin notifications */ diff --git a/lightningd/peer_control.h b/lightningd/peer_control.h index ae4dd2ecd..c76d34d0a 100644 --- a/lightningd/peer_control.h +++ b/lightningd/peer_control.h @@ -73,6 +73,8 @@ struct peer *peer_from_json(struct lightningd *ld, void peer_connected(struct lightningd *ld, const u8 *msg); void peer_disconnect_done(struct lightningd *ld, const u8 *msg); void peer_active(struct lightningd *ld, const u8 *msg, int peer_fd); +/* May delete peer! */ +void peer_channels_cleanup_on_disconnect(struct peer *peer); /* Could be configurable. */ #define OUR_CHANNEL_FLAGS CHANNEL_FLAGS_ANNOUNCE_CHANNEL