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