Skip to content

Commit

Permalink
subdaemons: remove gossipd fd from per-peer daemons.
Browse files Browse the repository at this point in the history
Signed-off-by: Rusty Russell <[email protected]>
  • Loading branch information
rustyrussell committed Feb 8, 2022
1 parent 1abbc3d commit 3c5d27e
Show file tree
Hide file tree
Showing 27 changed files with 120 additions and 342 deletions.
25 changes: 8 additions & 17 deletions channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,9 @@
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>

/* stdin == requests, 3 == peer, 4 = gossip, 5 = HSM */
/* stdin == requests, 3 == peer, 4 = HSM */
#define MASTER_FD STDIN_FILENO
#define HSM_FD 5
#define HSM_FD 4

struct peer {
struct per_peer_state *pps;
Expand Down Expand Up @@ -2132,13 +2132,12 @@ static void peer_in(struct peer *peer, const u8 *msg)
{
enum peer_wire type = fromwire_peektype(msg);

if (handle_peer_gossip_or_error(peer->pps, &peer->channel_id, msg))
if (handle_peer_error(peer->pps, &peer->channel_id, msg))
return;

/* Must get funding_locked before almost anything. */
if (!peer->funding_locked[REMOTE]) {
if (type != WIRE_FUNDING_LOCKED
&& type != WIRE_PONG
&& type != WIRE_SHUTDOWN
/* We expect these for v2 !! */
&& type != WIRE_TX_SIGNATURES
Expand Down Expand Up @@ -2215,7 +2214,7 @@ static void peer_in(struct peer *peer, const u8 *msg)
handle_unexpected_reestablish(peer, msg);
return;

/* These are all swallowed by handle_peer_gossip_or_error */
/* These are all swallowed by connectd */
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
case WIRE_NODE_ANNOUNCEMENT:
Expand Down Expand Up @@ -2798,7 +2797,7 @@ static void peer_reconnect(struct peer *peer,
do {
clean_tmpctx();
msg = peer_read(tmpctx, peer->pps);
} while (handle_peer_gossip_or_error(peer->pps, &peer->channel_id, msg) ||
} while (handle_peer_error(peer->pps, &peer->channel_id, msg) ||
capture_premature_msg(&premature_msgs, msg));

got_reestablish:
Expand Down Expand Up @@ -3752,9 +3751,9 @@ static void init_channel(struct peer *peer)
tal_dup(peer, struct penalty_base, &pbases[i]));
tal_free(pbases);

/* stdin == requests, 3 == peer, 4 = gossip */
/* stdin == requests, 3 == peer */
peer->pps = new_per_peer_state(peer);
per_peer_state_set_fds(peer->pps, 3, 4);
per_peer_state_set_fd(peer->pps, 3);

status_debug("init %s: remote_per_commit = %s, old_remote_per_commit = %s"
" next_idx_local = %"PRIu64
Expand Down Expand Up @@ -3895,11 +3894,10 @@ int main(int argc, char *argv[])
FD_ZERO(&fds_in);
FD_SET(MASTER_FD, &fds_in);
FD_SET(peer->pps->peer_fd, &fds_in);
FD_SET(peer->pps->gossip_fd, &fds_in);

FD_ZERO(&fds_out);
FD_SET(peer->pps->peer_fd, &fds_out);
nfds = peer->pps->gossip_fd+1;
nfds = peer->pps->peer_fd+1;

while (!shutdown_complete(peer)) {
struct timemono first;
Expand Down Expand Up @@ -3958,13 +3956,6 @@ int main(int argc, char *argv[])
/* This could take forever, but who cares? */
msg = peer_read(tmpctx, peer->pps);
peer_in(peer, msg);
} else if (FD_ISSET(peer->pps->gossip_fd, &rfds)) {
msg = wire_sync_read(tmpctx, peer->pps->gossip_fd);
/* Gossipd hangs up on us to kill us when a new
* connection comes in. */
if (!msg)
peer_failed_connection_lost();
handle_gossip_msg(peer->pps, take(msg));
}
}

Expand Down
17 changes: 6 additions & 11 deletions closingd/closingd.c
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,9 @@
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>

/* stdin == requests, 3 == peer, 4 = gossip, 5 = hsmd */
/* stdin == requests, 3 == peer, 4 = hsmd */
#define REQ_FD STDIN_FILENO
#define HSM_FD 5
#define HSM_FD 4

static void notify(enum log_level level, const char *fmt, ...)
{
Expand Down Expand Up @@ -117,15 +117,10 @@ static u8 *closing_read_peer_msg(const tal_t *ctx,
{
for (;;) {
u8 *msg;
bool from_gossipd;

clean_tmpctx();
msg = peer_or_gossip_sync_read(ctx, pps, &from_gossipd);
if (from_gossipd) {
handle_gossip_msg(pps, take(msg));
continue;
}
if (!handle_peer_gossip_or_error(pps, channel_id, msg))
msg = peer_read(ctx, pps);
if (!handle_peer_error(pps, channel_id, msg))
return msg;
}
}
Expand Down Expand Up @@ -892,9 +887,9 @@ int main(int argc, char *argv[])
&wrong_funding))
master_badmsg(WIRE_CLOSINGD_INIT, msg);

/* stdin == requests, 3 == peer, 4 = gossip, 5 = hsmd */
/* stdin == requests, 3 == peer, 4 = hsmd */
pps = notleak(new_per_peer_state(ctx));
per_peer_state_set_fds(pps, 3, 4);
per_peer_state_set_fd(pps, 3);

funding_wscript = bitcoin_redeem_2of2(ctx,
&funding_pubkey[LOCAL],
Expand Down
1 change: 0 additions & 1 deletion common/peer_failed.c
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ peer_fatal_continue(const u8 *msg TAKES, const struct per_peer_state *pps)
status_send(msg);

status_send_fd(pps->peer_fd);
status_send_fd(pps->gossip_fd);
exit(0x80 | (reason & 0xFF));
}

Expand Down
18 changes: 2 additions & 16 deletions common/per_peer_state.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,25 @@ static void destroy_per_peer_state(struct per_peer_state *pps)
{
if (pps->peer_fd != -1)
close(pps->peer_fd);
if (pps->gossip_fd != -1)
close(pps->gossip_fd);
}

struct per_peer_state *new_per_peer_state(const tal_t *ctx)
{
struct per_peer_state *pps = tal(ctx, struct per_peer_state);

pps->peer_fd = pps->gossip_fd = -1;
pps->peer_fd = -1;
tal_add_destructor(pps, destroy_per_peer_state);
return pps;
}

void per_peer_state_set_fds(struct per_peer_state *pps,
int peer_fd, int gossip_fd)
void per_peer_state_set_fd(struct per_peer_state *pps, int peer_fd)
{
assert(pps->peer_fd == -1);
assert(pps->gossip_fd == -1);
pps->peer_fd = peer_fd;
pps->gossip_fd = gossip_fd;
}

void per_peer_state_set_fds_arr(struct per_peer_state *pps, const int *fds)
{
/* We expect 2 fds. */
assert(tal_count(fds) == 2);
per_peer_state_set_fds(pps, fds[0], fds[1]);
}

void per_peer_state_fdpass_send(int fd, const struct per_peer_state *pps)
{
assert(pps->peer_fd != -1);
assert(pps->gossip_fd != -1);
fdpass_send(fd, pps->peer_fd);
fdpass_send(fd, pps->gossip_fd);
}
10 changes: 3 additions & 7 deletions common/per_peer_state.h
Original file line number Diff line number Diff line change
Expand Up @@ -9,19 +9,15 @@
/* Things we hand between daemons to talk to peers. */
struct per_peer_state {
/* If not -1, closed on freeing */
int peer_fd, gossip_fd;
int peer_fd;
};

/* Allocate a new per-peer state and add destructor to close fds if set;
* sets fds to -1. */
* sets peer_fd to -1. */
struct per_peer_state *new_per_peer_state(const tal_t *ctx);

/* Initialize the fds (must be -1 previous) */
void per_peer_state_set_fds(struct per_peer_state *pps,
int peer_fd, int gossip_fd);

/* Array version of above: tal_count(fds) must be 2 */
void per_peer_state_set_fds_arr(struct per_peer_state *pps, const int *fds);
void per_peer_state_set_fd(struct per_peer_state *pps, int peer_fd);

void per_peer_state_fdpass_send(int fd, const struct per_peer_state *pps);

Expand Down
96 changes: 8 additions & 88 deletions common/read_peer_msg.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,39 +12,6 @@
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>

u8 *peer_or_gossip_sync_read(const tal_t *ctx,
struct per_peer_state *pps,
bool *from_gossipd)
{
fd_set readfds;
u8 *msg;

FD_ZERO(&readfds);
FD_SET(pps->peer_fd, &readfds);
FD_SET(pps->gossip_fd, &readfds);

if (select(pps->peer_fd > pps->gossip_fd
? pps->peer_fd + 1 : pps->gossip_fd + 1,
&readfds, NULL, NULL, NULL) <= 0) {
status_failed(STATUS_FAIL_GOSSIP_IO,
"select failed?: %s", strerror(errno));
}

if (FD_ISSET(pps->peer_fd, &readfds)) {
msg = peer_read(ctx, pps);
*from_gossipd = false;
return msg;
}

msg = wire_sync_read(ctx, pps->gossip_fd);
if (!msg)
status_failed(STATUS_FAIL_GOSSIP_IO,
"Error reading gossip msg: %s",
strerror(errno));
*from_gossipd = true;
return msg;
}

bool is_peer_error(const tal_t *ctx, const u8 *msg,
const struct channel_id *channel_id,
char **desc, bool *warning)
Expand Down Expand Up @@ -94,70 +61,23 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected,
return !channel_id_eq(expected, actual);
}

void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES)
{
u8 *gossip;

/* It's a raw gossip msg: this copies or takes() */
gossip = tal_dup_talarr(tmpctx, u8, msg);

/* Gossipd can send us gossip messages, OR warnings */
if (fromwire_peektype(gossip) == WIRE_WARNING) {
peer_write(pps, gossip);
peer_failed_connection_lost();
} else {
peer_write(pps, gossip);
}
}

bool handle_peer_gossip_or_error(struct per_peer_state *pps,
const struct channel_id *channel_id,
const u8 *msg TAKES)
bool handle_peer_error(struct per_peer_state *pps,
const struct channel_id *channel_id,
const u8 *msg TAKES)
{
char *err;
bool warning;
u8 *pong;

#if DEVELOPER
/* Any odd-typed unknown message is handled by the caller, so if we
* find one here it's an error. */
assert(!is_unknown_msg_discardable(msg));
#else
/* BOLT #1:
*
* A receiving node:
* - upon receiving a message of _odd_, unknown type:
* - MUST ignore the received message.
*/
if (is_unknown_msg_discardable(msg))
goto handled;
#endif

if (check_ping_make_pong(NULL, msg, &pong)) {
if (pong)
peer_write(pps, take(pong));
return true;
} else if (is_msg_for_gossipd(msg)) {
wire_sync_write(pps->gossip_fd, msg);
/* wire_sync_write takes, so don't take again. */
return true;
}

if (is_peer_error(tmpctx, msg, channel_id, &err, &warning)) {
/* Ignore unknown channel errors. */
if (!err)
goto handled;
if (!err) {
if (taken(msg))
tal_free(msg);
return true;
}

/* We hang up when a warning is received. */
peer_failed_received_errmsg(pps, err, channel_id, warning);

goto handled;
}

return false;

handled:
if (taken(msg))
tal_free(msg);
return true;
}
40 changes: 5 additions & 35 deletions common/read_peer_msg.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,25 +8,6 @@ struct crypto_state;
struct channel_id;
struct per_peer_state;

/**
* peer_or_gossip_sync_read - read a peer message, or maybe a gossip msg.
* @ctx: context to allocate return packet from.
* @pps: the per-peer peer state and fds
* @from_gossipd: true if the msg was from gossipd, otherwise false.
*
* Will call peer_failed_connection_lost() or
* status_failed(STATUS_FAIL_GOSSIP_IO) or return a message.
*
* Usually, you should call handle_gossip_msg if *@from_gossipd is
* true, otherwise if is_peer_error() handle the error, otherwise if
* is_msg_for_gossipd() then send to gossipd, otherwise if is
* is_wrong_channel() send that as a reply. Otherwise it should be
* a valid message.
*/
u8 *peer_or_gossip_sync_read(const tal_t *ctx,
struct per_peer_state *pps,
bool *from_gossipd);

/**
* is_peer_error - if it's an error, describe if it applies to this channel.
* @ctx: context to allocate return from.
Expand Down Expand Up @@ -55,26 +36,15 @@ bool is_wrong_channel(const u8 *msg, const struct channel_id *expected,


/**
* handle_peer_gossip_or_error - simple handler for all the above cases.
* handle_peer_error - simple handler for errors
* @pps: per-peer state.
* @channel_id: the channel id of the current channel.
* @msg: the peer message (only taken if returns true).
*
* This returns true if it handled the packet: a gossip packet (forwarded
* to gossipd), or an error packet (causes peer_failed_received_errmsg or
* ignored), or a ping (may reply with pong).
*/
bool handle_peer_gossip_or_error(struct per_peer_state *pps,
const struct channel_id *channel_id,
const u8 *msg TAKES);

/**
* handle_timestamp_filter - deal with timestamp filter requests.
* @pps: per-peer state.
* @msg: the peer message (only taken if returns true).
* This returns true if it handled the packet.
*/
bool handle_timestamp_filter(struct per_peer_state *pps, const u8 *msg TAKES);
bool handle_peer_error(struct per_peer_state *pps,
const struct channel_id *channel_id,
const u8 *msg TAKES);

/* We got this message from gossipd: forward/quit as it asks. */
void handle_gossip_msg(struct per_peer_state *pps, const u8 *msg TAKES);
#endif /* LIGHTNING_COMMON_READ_PEER_MSG_H */
Loading

0 comments on commit 3c5d27e

Please sign in to comment.