From ccad93edb3f2b5dcc5966a5e01cb37f8f6f8be94 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Tue, 23 May 2017 20:32:17 +0930 Subject: [PATCH] gossipd: add fail_peer. We use this if it reconnects via another fd. Signed-off-by: Rusty Russell --- lightningd/gossip/gossip.c | 27 +++++++++++++++++++++++++++ lightningd/gossip/gossip_wire.csv | 9 +++++++-- lightningd/gossip_control.c | 2 ++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/lightningd/gossip/gossip.c b/lightningd/gossip/gossip.c index c0c7fd378..5156866a2 100644 --- a/lightningd/gossip/gossip.c +++ b/lightningd/gossip/gossip.c @@ -429,6 +429,30 @@ static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon, return daemon_conn_read_next(conn, &daemon->master); } +static struct io_plan *fail_peer(struct io_conn *conn, struct daemon *daemon, + const u8 *msg) +{ + u64 unique_id; + struct peer *peer; + + if (!fromwire_gossipctl_fail_peer(msg, NULL, &unique_id)) + status_failed(WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST, + "%s", tal_hex(trc, msg)); + + /* This may not find the peer, if we fail beforehand. */ + peer = find_peer(daemon, unique_id); + if (!peer) + status_trace("Unknown fail_peer %"PRIu64, unique_id); + else { + assert(peer->local); + status_trace("fail_peer %"PRIu64, unique_id); + /* This owns the peer, so we can free it */ + io_close(peer->conn); + } + + return daemon_conn_read_next(conn, &daemon->master); +} + static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon, u8 *msg) { @@ -616,6 +640,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master return new_peer(conn, daemon, master->msg_in); case WIRE_GOSSIPCTL_RELEASE_PEER: return release_peer(conn, daemon, master->msg_in); + case WIRE_GOSSIPCTL_FAIL_PEER: + return fail_peer(conn, daemon, master->msg_in); case WIRE_GOSSIP_GETNODES_REQUEST: return getnodes(conn, daemon); @@ -644,6 +670,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master case WIRE_GOSSIPSTATUS_INIT_FAILED: case WIRE_GOSSIPSTATUS_BAD_NEW_PEER_REQUEST: case WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST: + case WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST: case WIRE_GOSSIPSTATUS_BAD_REQUEST: case WIRE_GOSSIPSTATUS_FDPASS_FAILED: case WIRE_GOSSIPSTATUS_PEER_BAD_MSG: diff --git a/lightningd/gossip/gossip_wire.csv b/lightningd/gossip/gossip_wire.csv index db487a70c..60f6cbd0a 100644 --- a/lightningd/gossip/gossip_wire.csv +++ b/lightningd/gossip/gossip_wire.csv @@ -2,8 +2,9 @@ gossipstatus_init_failed,0x8000 gossipstatus_bad_new_peer_request,0x8001 gossipstatus_bad_release_request,0x8002 -gossipstatus_bad_request,0x8003 -gossipstatus_fdpass_failed,0x8004 +gossipstatus_bad_fail_request,0x8003 +gossipstatus_bad_request,0x8004 +gossipstatus_fdpass_failed,0x8005 # Peers can give a bad message, we close their fd, but no harm done. gossipstatus_peer_bad_msg,1000 @@ -100,3 +101,7 @@ gossip_resolve_channel_reply,0,keys,num_keys*struct pubkey gossip_forwarded_msg,10 gossip_forwarded_msg,0,msglen,2 gossip_forwarded_msg,2,msg,msglen + +# If peer is still connected, fail it (master does this for reconnect) +gossipctl_fail_peer,11 +gossipctl_fail_peer,0,unique_id,8 diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index 6041cdccd..864cf0140 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -106,10 +106,12 @@ static int gossip_msg(struct subd *gossip, const u8 *msg, const int *fds) case WIRE_GOSSIPSTATUS_BAD_REQUEST: case WIRE_GOSSIPSTATUS_FDPASS_FAILED: case WIRE_GOSSIPSTATUS_BAD_RELEASE_REQUEST: + case WIRE_GOSSIPSTATUS_BAD_FAIL_REQUEST: /* These are messages we send, not them. */ case WIRE_GOSSIPCTL_INIT: case WIRE_GOSSIPCTL_NEW_PEER: case WIRE_GOSSIPCTL_RELEASE_PEER: + case WIRE_GOSSIPCTL_FAIL_PEER: case WIRE_GOSSIP_GETNODES_REQUEST: case WIRE_GOSSIP_GETROUTE_REQUEST: case WIRE_GOSSIP_GETCHANNELS_REQUEST: