mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
gossip: handle release race.
We can go to release a gossip peer, and it can fail at the same time. We work around the problem that the reply must be a gossipctl_release_peer_reply with two fds, but it's not pretty. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
b3a2a0623c
commit
f504f0be47
@ -418,15 +418,27 @@ static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon,
|
||||
"%s", tal_hex(trc, msg));
|
||||
|
||||
peer = find_peer(daemon, unique_id);
|
||||
if (!peer)
|
||||
status_failed(WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST,
|
||||
"Unknown peer %"PRIu64, unique_id);
|
||||
if (!peer) {
|
||||
/* This can happen with a reconnect vs connect race.
|
||||
* See gossip_peer_released in master daemon. */
|
||||
struct crypto_state dummy;
|
||||
|
||||
send_peer_with_fds(peer,
|
||||
take(towire_gossipctl_release_peer_reply(msg,
|
||||
status_trace("release_peer: Unknown peer %"PRIu64, unique_id);
|
||||
memset(&dummy, 0, sizeof(dummy));
|
||||
daemon_conn_send(&daemon->master,
|
||||
take(towire_gossipctl_release_peer_reply(msg,
|
||||
~unique_id,
|
||||
&dummy)));
|
||||
/* Needs two fds, send dummies. */
|
||||
daemon_conn_send_fd(&daemon->master, dup(STDOUT_FILENO));
|
||||
daemon_conn_send_fd(&daemon->master, dup(STDOUT_FILENO));
|
||||
} else {
|
||||
send_peer_with_fds(peer,
|
||||
take(towire_gossipctl_release_peer_reply(msg,
|
||||
unique_id,
|
||||
&peer->pcs.cs)));
|
||||
io_close_taken_fd(peer->conn);
|
||||
io_close_taken_fd(peer->conn);
|
||||
}
|
||||
return daemon_conn_read_next(conn, &daemon->master);
|
||||
}
|
||||
|
||||
|
@ -1846,9 +1846,15 @@ static bool gossip_peer_released(struct subd *gossip,
|
||||
fatal("Gossup daemon gave invalid reply %s",
|
||||
tal_hex(gossip, resp));
|
||||
|
||||
if (id != fc->peer->unique_id)
|
||||
fatal("Gossup daemon release gave %"PRIu64" not %"PRIu64,
|
||||
id, fc->peer->unique_id);
|
||||
/* This is how gossipd handles a reconnect (gossipctl_fail_peer) racing
|
||||
* with us trying to connect. */
|
||||
if (id != fc->peer->unique_id) {
|
||||
tal_del_destructor(fc, fail_fundchannel_command);
|
||||
command_fail(fc->cmd, "Peer reconnected, try again");
|
||||
close(fds[0]);
|
||||
close(fds[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
peer_set_condition(fc->peer, GOSSIPD, OPENINGD);
|
||||
opening = new_subd(fc->peer->ld, ld,
|
||||
|
Loading…
Reference in New Issue
Block a user