Browse Source

gossipd: fail peer for the master daemon.

This fixes the only case where the master currently has to write directly
to the peer: re-sending an error.  We make gossipd do it, by adding
a new gossipctl_fail_peer message.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
f172be71dc
  1. 65
      gossipd/gossip.c
  2. 8
      gossipd/gossip_wire.csv
  3. 1
      lightningd/Makefile
  4. 1
      lightningd/gossip_control.c
  5. 40
      lightningd/peer_control.c

65
gossipd/gossip.c

@ -99,14 +99,15 @@ static void destroy_peer(struct peer *peer)
}
}
static struct peer *setup_new_peer(struct daemon *daemon, const u8 *msg)
static struct peer *setup_new_peer(struct daemon *daemon,
u64 unique_id,
const struct crypto_state *cs)
{
struct peer *peer = tal(daemon, struct peer);
init_peer_crypto_state(peer, &peer->pcs);
if (!fromwire_gossipctl_new_peer(msg, NULL, &peer->unique_id,
&peer->pcs.cs))
return tal_free(peer);
peer->pcs.cs = *cs;
peer->unique_id = unique_id;
peer->daemon = daemon;
peer->error = NULL;
peer->local = true;
@ -115,6 +116,7 @@ static struct peer *setup_new_peer(struct daemon *daemon, const u8 *msg)
msg_queue_init(&peer->peer_out, peer);
list_add_tail(&daemon->peers, &peer->list);
tal_add_destructor(peer, destroy_peer);
wake_pkt_out(peer);
return peer;
}
@ -416,10 +418,14 @@ static struct io_plan *new_peer_got_fd(struct io_conn *conn, struct peer *peer)
static struct io_plan *new_peer(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
struct peer *peer = setup_new_peer(daemon, msg);
if (!peer)
status_failed(STATUS_FAIL_MASTER_IO,
"bad gossipctl_new_peer: %s", tal_hex(trc, msg));
struct peer *peer;
struct crypto_state cs;
u64 unique_id;
if (!fromwire_gossipctl_new_peer(msg, NULL, &unique_id, &cs))
master_badmsg(WIRE_GOSSIPCTL_NEW_PEER, msg);
peer = setup_new_peer(daemon, unique_id, &cs);
return io_recv_fd(conn, &peer->fd, new_peer_got_fd, peer);
}
@ -433,6 +439,45 @@ static struct peer *find_peer(struct daemon *daemon, u64 unique_id)
return NULL;
}
/* We send error, then close. */
static struct io_plan *peer_send_error(struct io_conn *conn, struct peer *peer)
{
const u8 *out = msg_dequeue(&peer->peer_out);
return peer_write_message(conn, &peer->pcs, take(out),
(void *)io_close_cb);
}
static struct io_plan *fail_peer_got_fd(struct io_conn *conn, struct peer *peer)
{
peer->conn = io_new_conn(conn, peer->fd, peer_send_error, peer);
if (!peer->conn) {
peer->error = "Could not create connection";
tal_free(peer);
} else {
/* If conn dies, we forget peer. */
tal_steal(peer->conn, peer);
}
return daemon_conn_read_next(conn, &peer->daemon->master);
}
static struct io_plan *fail_peer(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
struct peer *peer;
struct crypto_state cs;
u64 unique_id;
u8 *failmsg;
if (!fromwire_gossipctl_fail_peer(msg, msg, NULL, &unique_id, &cs,
&failmsg))
master_badmsg(WIRE_GOSSIPCTL_FAIL_PEER, msg);
peer = setup_new_peer(daemon, unique_id, &cs);
msg_enqueue(&peer->peer_out, take(failmsg));
return io_recv_fd(conn, &peer->fd, fail_peer_got_fd, peer);
}
static struct io_plan *release_peer(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
@ -742,6 +787,10 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_FORWARDED_MSG:
handle_forwarded_msg(conn, daemon, daemon->master.msg_in);
return daemon_conn_read_next(conn, &daemon->master);
case WIRE_GOSSIPCTL_FAIL_PEER:
return fail_peer(conn, daemon, master->msg_in);
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLY:
case WIRE_GOSSIPCTL_RELEASE_PEER_REPLYFAIL:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD_REPLY:

8
gossipd/gossip_wire.csv

@ -18,7 +18,6 @@ gossipctl_init,,broadcast_interval,u32
gossipctl_init,,chain_hash,struct sha256_double
# These take an fd, but have no response
# (if it is to move onto a channel, we get a status msg).
gossipctl_new_peer,3001
gossipctl_new_peer,,unique_id,u64
gossipctl_new_peer,,crypto_state,struct crypto_state
@ -112,3 +111,10 @@ gossipctl_get_peer_gossipfd_reply,3112
# Failure (can't make new socket)
gossipctl_get_peer_gossipfd_replyfail,3212
# Send canned message to peer and fail it.
gossipctl_fail_peer,3013
gossipctl_fail_peer,,unique_id,u64
gossipctl_fail_peer,,crypto_state,struct crypto_state
gossipctl_fail_peer,,len,u16
gossipctl_fail_peer,,failmsg,len*u8

Can't render this file because it has a wrong number of fields in line 2.

1
lightningd/Makefile

@ -18,7 +18,6 @@ LIGHTNINGD_COMMON_OBJS := \
common/channel_config.o \
common/configdir.o \
common/crypto_state.o \
common/cryptomsg.o \
common/derive_basepoints.o \
common/funding_tx.o \
common/htlc_state.o \

1
lightningd/gossip_control.c

@ -95,6 +95,7 @@ static int gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
/* These are messages we send, not them. */
case WIRE_GOSSIPCTL_INIT:
case WIRE_GOSSIPCTL_NEW_PEER:
case WIRE_GOSSIPCTL_FAIL_PEER:
case WIRE_GOSSIPCTL_RELEASE_PEER:
case WIRE_GOSSIPCTL_DROP_PEER:
case WIRE_GOSSIPCTL_GET_PEER_GOSSIPFD:

40
lightningd/peer_control.c

@ -262,34 +262,6 @@ static void peer_start_closingd(struct peer *peer,
int peer_fd, int gossip_fd,
bool reconnected);
/* FIXME: Fake NOP dev_disconnect/dev_sabotage_fd for below. */
enum dev_disconnect dev_disconnect(int pkt_type)
{
return DEV_DISCONNECT_NORMAL;
}
void dev_sabotage_fd(int fd)
{
abort();
}
void dev_blackhole_fd(int fd)
{
abort();
}
/* Send (encrypted) error message, then close. */
static struct io_plan *send_error(struct io_conn *conn,
struct peer_crypto_state *pcs)
{
log_debug(pcs->peer->log, "Sending canned error");
/* FIXME: This is the only place where master talks directly to peer;
* and pulls in quite a lot of code to do so. If we got a subdaemon
* to do this work, we'd avoid pulling in cryptomsg.o and the fake
* dev_disconnect. */
return peer_write_message(conn, pcs, pcs->peer->error, (void *)io_close_cb);
}
/* FIXME:
*
* This is a lot of code duplication! We should turn gossipd into welcomed(?):
@ -483,10 +455,14 @@ static bool peer_reconnected(struct lightningd *ld,
* retransmit the error packet and ignore any other packets for that
* channel, and the following requirements do not apply. */
if (peer->error) {
struct peer_crypto_state *pcs = tal(peer, struct peer_crypto_state);
init_peer_crypto_state(peer, pcs);
pcs->cs = *cs;
tal_steal(io_new_conn(peer, fd, send_error, pcs), pcs);
/* FIXME: we should do this in response to reestablish, unless
* global error */
log_debug(peer->log, "Sending canned error");
subd_send_msg(peer->ld->gossip,
take(towire_gossipctl_fail_peer(peer,
peer->unique_id,
cs, peer->error)));
subd_send_fd(peer->ld->gossip, fd);
return true;
}

Loading…
Cancel
Save