Skip to content

Commit 55d622b

Browse files
committed
lightningd: fix race with mutual connect.
65dccea "pytest: fix flake in test_reconnect_signed" accidentally introduced a bug, where the connect command may not return. If we call "connect" while a connection is still being processed through the peer_connected hooks, we would call peer_channels_cleanup(), which (if the peer has no channels) would free the peer. Then when the peer_connected hook returned, it would lookup the peer, see it was gone, and silently return. The connect_succeeded() function was never called, and the connect command never woken. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au> Changelog-None: bug introduced this release.
1 parent 79e6094 commit 55d622b

File tree

1 file changed

+19
-12
lines changed

1 file changed

+19
-12
lines changed

lightningd/connect_control.c

Lines changed: 19 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -219,21 +219,28 @@ static struct command_result *json_connect(struct command *cmd,
219219

220220
/* If we know about peer, see if it's already connected. */
221221
peer = peer_by_id(cmd->ld, &id_addr.id);
222-
if (peer && peer->connected == PEER_CONNECTED) {
223-
log_debug(cmd->ld->log, "Already connected via %s",
224-
fmt_wireaddr_internal(tmpctx,
222+
if (peer) {
223+
switch (peer->connected) {
224+
case PEER_CONNECTED:
225+
log_debug(cmd->ld->log, "Already connected via %s",
226+
fmt_wireaddr_internal(tmpctx,
225227
&peer->addr));
226-
return connect_cmd_succeed(cmd, peer,
227-
peer->connected_incoming,
228-
&peer->addr);
228+
return connect_cmd_succeed(cmd, peer,
229+
peer->connected_incoming,
230+
&peer->addr);
231+
case PEER_DISCONNECTED:
232+
/* When a peer disconnects, we give subds time to clean themselves up
233+
* (this lets connectd ensure they've seen the final messages). But
234+
* now it's going to try to reconnect, we've gotta force them out. */
235+
peer_channels_cleanup(peer);
236+
break;
237+
case PEER_CONNECTING:
238+
/* Just wait until connection finished. Though we still ask connectd to connect,
239+
* it's going to ignore it. */
240+
break;
241+
}
229242
}
230243

231-
/* When a peer disconnects, we give subds time to clean themselves up
232-
* (this lets connectd ensure they've seen the final messages). But
233-
* now it's going to try to reconnect, we've gotta force them out. */
234-
if (peer)
235-
peer_channels_cleanup(peer);
236-
237244
subd_send_msg(cmd->ld->connectd,
238245
take(towire_connectd_connect_to_peer(NULL, &id_addr.id,
239246
addr, true,

0 commit comments

Comments
 (0)