diff --git a/closingd/Makefile b/closingd/Makefile index 4b7f1e982..54bd5e066 100644 --- a/closingd/Makefile +++ b/closingd/Makefile @@ -55,6 +55,7 @@ CLOSINGD_COMMON_OBJS := \ common/peer_failed.o \ common/permute_tx.o \ common/ping.o \ + common/read_peer_msg.o \ common/status.o \ common/subdaemon.o \ common/type_to_string.o \ diff --git a/closingd/closing.c b/closingd/closing.c index f370aca62..94f5561cc 100644 --- a/closingd/closing.c +++ b/closingd/closing.c @@ -6,7 +6,7 @@ #include #include #include -#include +#include #include #include #include @@ -83,88 +83,18 @@ static u64 one_towards(u64 target, u64 value) return value; } -static void handle_ping(const u8 *msg, - struct crypto_state *cs, - const struct channel_id *our_channel_id) -{ - u8 *pong; - - if (!check_ping_make_pong(msg, msg, &pong)) - peer_failed(PEER_FD, cs, our_channel_id, "Bad ping"); - - status_trace("Got ping, sending %s", pong ? - wire_type_name(fromwire_peektype(pong)) - : "nothing"); - - if (pong && !sync_crypto_write(cs, PEER_FD, take(pong))) - status_failed(STATUS_FAIL_PEER_IO, - "Failed writing pong: %s", strerror(errno)); -} - -/* Handle random messages we might get, returning NULL if we handled it. */ -static u8 *read_peer_msg(const tal_t *ctx, - struct crypto_state *cs, - const struct channel_id *our_channel_id) +/* Handle random messages we might get, returning the first non-handled one. */ +static u8 *closing_read_peer_msg(const tal_t *ctx, + struct crypto_state *cs, + const struct channel_id *channel) { u8 *msg; - struct channel_id channel_id; - msg = sync_crypto_read(ctx, cs, PEER_FD); - if (!msg) - status_failed(STATUS_FAIL_PEER_IO, - "Failed reading from peer: %s", strerror(errno)); - - if (is_gossip_msg(msg)) { - /* Forward to gossip daemon */ - wire_sync_write(GOSSIP_FD, take(msg)); - return NULL; - } - - if (fromwire_peektype(msg) == WIRE_PING) { - handle_ping(msg, cs, our_channel_id); - return tal_free(msg); - } - - if (fromwire_peektype(msg) == WIRE_ERROR) { - struct channel_id chanid; - char *err = sanitize_error(msg, msg, &chanid); - - /* BOLT #1: - * - * The channel is referred to by `channel_id`, unless - * `channel_id` is 0 (i.e. all bytes are 0), in which - * case it refers to all channels. - * ... - - * The receiving node: - * - upon receiving `error`: - * - MUST fail the channel referred to by the error - * message. - * - if no existing channel is referred to by the - * message: - * - MUST ignore the message. - */ - if (channel_id_is_all(&chanid) - || structeq(&chanid, our_channel_id)) { - status_failed(STATUS_FAIL_PEER_BAD, - "Received ERROR %s", err); - } - return tal_free(msg); - } - - /* They're talking about a different channel? */ - if (extract_channel_id(msg, &channel_id) - && !structeq(&channel_id, our_channel_id)) { - status_trace("Rejecting %s for unknown channel_id %s", - wire_type_name(fromwire_peektype(msg)), - type_to_string(msg, struct channel_id, - &channel_id)); - sync_crypto_write(cs, PEER_FD, - take(towire_errorfmt(msg, &channel_id, - "Multiple channels" - " unsupported"))); - return tal_free(msg); - } + while ((msg = read_peer_msg(ctx, cs, channel, + sync_crypto_write_arg, + status_fail_io, + status_fail_errpkt, + NULL)) == NULL); return msg; } @@ -198,7 +128,7 @@ static void do_reconnect(struct crypto_state *cs, "Failed writing reestablish: %s", strerror(errno)); /* Wait for them to say something interesting */ - while ((msg = read_peer_msg(tmpctx, cs, channel_id)) == NULL); + msg = closing_read_peer_msg(tmpctx, cs, channel_id); if (!fromwire_channel_reestablish(msg, NULL, &their_channel_id, &next_local_commitment_number, @@ -344,7 +274,7 @@ int main(int argc, char *argv[]) again: /* Wait for them to say something interesting */ - while ((msg = read_peer_msg(tmpctx, &cs, &channel_id)) == NULL); + msg = closing_read_peer_msg(tmpctx, &cs, &channel_id); /* BOLT #2: *