mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-20 07:34:24 +01:00
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:
@@ -117,6 +117,28 @@ static struct peer *setup_new_peer(struct daemon *daemon, const u8 *msg)
|
|||||||
return peer;
|
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,
|
static struct io_plan *owner_msg_in(struct io_conn *conn,
|
||||||
struct daemon_conn *dc);
|
struct daemon_conn *dc);
|
||||||
static struct io_plan *nonlocal_dump_gossip(struct io_conn *conn,
|
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);
|
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,
|
static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
|
||||||
u8 *msg)
|
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);
|
return release_peer(conn, daemon, master->msg_in);
|
||||||
case WIRE_GOSSIPCTL_FAIL_PEER:
|
case WIRE_GOSSIPCTL_FAIL_PEER:
|
||||||
return fail_peer(conn, daemon, master->msg_in);
|
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:
|
case WIRE_GOSSIP_GETNODES_REQUEST:
|
||||||
return getnodes(conn, daemon);
|
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);
|
return daemon_conn_read_next(conn, &daemon->master);
|
||||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
|
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
|
||||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
|
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_GETNODES_REPLY:
|
||||||
case WIRE_GOSSIP_GETROUTE_REPLY:
|
case WIRE_GOSSIP_GETROUTE_REPLY:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||||
|
|||||||
@@ -107,3 +107,15 @@ gossip_forwarded_msg,,msg,msglen
|
|||||||
# If peer is still connected, fail it (master does this for reconnect)
|
# If peer is still connected, fail it (master does this for reconnect)
|
||||||
gossipctl_fail_peer,11
|
gossipctl_fail_peer,11
|
||||||
gossipctl_fail_peer,,unique_id,8
|
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
|
||||||
|
|||||||
|
@@ -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_NEW_PEER:
|
||||||
case WIRE_GOSSIPCTL_RELEASE_PEER:
|
case WIRE_GOSSIPCTL_RELEASE_PEER:
|
||||||
case WIRE_GOSSIPCTL_FAIL_PEER:
|
case WIRE_GOSSIPCTL_FAIL_PEER:
|
||||||
|
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD:
|
||||||
case WIRE_GOSSIP_GETNODES_REQUEST:
|
case WIRE_GOSSIP_GETNODES_REQUEST:
|
||||||
case WIRE_GOSSIP_GETROUTE_REQUEST:
|
case WIRE_GOSSIP_GETROUTE_REQUEST:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_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. */
|
/* This is a reply, so never gets through to here. */
|
||||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
|
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
|
||||||
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
|
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_GETNODES_REPLY:
|
||||||
case WIRE_GOSSIP_GETROUTE_REPLY:
|
case WIRE_GOSSIP_GETROUTE_REPLY:
|
||||||
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
case WIRE_GOSSIP_GETCHANNELS_REPLY:
|
||||||
|
|||||||
Reference in New Issue
Block a user