gossipd: interface to get a client gossip_fd for a reconnect.

At the moment, master simply keeps the gossip fd open when peer
disconnects.  That's inefficient, and wrong anyway (it may want a
complete new sync, or may not, but we'll currently send all the
messages including stale ones).

This interface will be required for restart anyway.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-06-24 16:20:23 +09:30
parent ea52b0a8ff
commit 4185153d81
3 changed files with 82 additions and 0 deletions

View File

@ -117,6 +117,28 @@ static struct peer *setup_new_peer(struct daemon *daemon, const u8 *msg)
return peer;
}
static struct peer *setup_new_remote_peer(struct daemon *daemon,
u64 unique_id, bool sync)
{
struct peer *peer = tal(daemon, struct peer);
peer->daemon = daemon;
peer->error = NULL;
peer->local = false;
peer->num_pings_outstanding = 0;
peer->fd = -1;
peer->unique_id = unique_id;
if (sync)
peer->broadcast_index = 0;
else
peer->broadcast_index = daemon->rstate->broadcasts->next_index;
msg_queue_init(&peer->peer_out, peer);
list_add_tail(&daemon->peers, &peer->list);
tal_add_destructor(peer, destroy_peer);
return peer;
}
static struct io_plan *owner_msg_in(struct io_conn *conn,
struct daemon_conn *dc);
static struct io_plan *nonlocal_dump_gossip(struct io_conn *conn,
@ -457,6 +479,47 @@ static struct io_plan *fail_peer(struct io_conn *conn, struct daemon *daemon,
return daemon_conn_read_next(conn, &daemon->master);
}
static void forget_peer(struct io_conn *conn, struct daemon_conn *dc)
{
/* Free peer. */
tal_free(dc->ctx);
}
static struct io_plan *new_peer_fd(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
int fds[2];
u8 *out;
u64 unique_id;
bool sync;
struct peer *peer;
if (!fromwire_gossipctl_get_peer_gossipfd(msg, NULL,
&unique_id, &sync))
status_failed(WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST,
"%s", tal_hex(trc, msg));
peer = setup_new_remote_peer(daemon, unique_id, sync);
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
status_trace("Failed to create socketpair: %s",
strerror(errno));
out = towire_gossipctl_get_peer_gossipfd_replyfail(msg);
daemon_conn_send(&peer->daemon->master, take(out));
return daemon_conn_read_next(conn, &daemon->master);
}
daemon_conn_init(peer, &peer->owner_conn, fds[0], owner_msg_in,
forget_peer);
peer->owner_conn.msg_queue_cleared_cb = nonlocal_dump_gossip;
out = towire_gossipctl_get_peer_gossipfd_reply(msg);
daemon_conn_send(&peer->daemon->master, out);
daemon_conn_send_fd(&peer->daemon->master, fds[1]);
return daemon_conn_read_next(conn, &daemon->master);
}
static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
u8 *msg)
{
@ -649,6 +712,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
return release_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIPCTL_FAIL_PEER:
return fail_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD:
return new_peer_fd(conn, daemon, master->msg_in);
case WIRE_GOSSIP_GETNODES_REQUEST:
return getnodes(conn, daemon);
@ -670,6 +735,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
return daemon_conn_read_next(conn, &daemon->master);
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLY:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLYFAIL:
case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY:

View File

@ -107,3 +107,15 @@ gossip_forwarded_msg,,msg,msglen
# If peer is still connected, fail it (master does this for reconnect)
gossipctl_fail_peer,11
gossipctl_fail_peer,,unique_id,8
# Get a gossip fd for this peer (it has reconnected)
gossipctl_get_peer_gossipfd,12
gossipctl_get_peer_gossipfd,,unique_id,u64
# Does it want a full dump of gossip?
gossipctl_get_peer_gossipfd,,sync,bool
# + fd.
gossipctl_get_peer_gossipfd_reply,112
# Failure (can't make new socket)
gossipctl_get_peer_gossipfd_replyfail,212

1 # These are fatal.
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121

View File

@ -106,6 +106,7 @@ static int gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIPCTL_NEW_PEER:
case WIRE_GOSSIPCTL_RELEASE_PEER:
case WIRE_GOSSIPCTL_FAIL_PEER:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD:
case WIRE_GOSSIP_GETNODES_REQUEST:
case WIRE_GOSSIP_GETROUTE_REQUEST:
case WIRE_GOSSIP_GETCHANNELS_REQUEST:
@ -115,6 +116,8 @@ static int gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
/* This is a reply, so never gets through to here. */
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLY:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLYFAIL:
case WIRE_GOSSIP_GETNODES_REPLY:
case WIRE_GOSSIP_GETROUTE_REPLY:
case WIRE_GOSSIP_GETCHANNELS_REPLY: