Browse Source

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>
ppa-0.6.1
Rusty Russell 8 years ago
parent
commit
f504f0be47
  1. 24
      lightningd/gossip/gossip.c
  2. 12
      lightningd/peer_control.c

24
lightningd/gossip/gossip.c

@ -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);
}

12
lightningd/peer_control.c

@ -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…
Cancel
Save