Browse Source

status: split off error messages into a new 'peer_status' type.

Several daemons (onchaind, hsm) want to use the status messages, but
don't communicate with peers.  The coming changes made them drag in
more code they didn't need, so instead we have a different
non-overlapping type.

We combine the status_received_errmsg and status_sent_errmsg
into a single status_peer_error, with the presence or not of the
'error_for_them' field indicating direction. 

We also rename status_fatal_connection_lost() to
peer_failed_connection_lost() to fit in.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
f76ff90485
  1. 1
      channeld/Makefile
  2. 11
      channeld/channel.c
  3. 1
      closingd/Makefile
  4. 12
      closingd/closing.c
  5. 10
      common/Makefile
  6. 24
      common/peer_failed.c
  7. 10
      common/peer_failed.h
  8. 11
      common/peer_status_wire.csv
  9. 39
      common/read_peer_msg.c
  10. 35
      common/read_peer_msg.h
  11. 43
      common/status.c
  12. 15
      common/status.h
  13. 12
      common/status_wire.csv
  14. 1
      lightningd/Makefile
  15. 59
      lightningd/subd.c
  16. 1
      openingd/Makefile
  17. 16
      openingd/opening.c

1
channeld/Makefile

@ -42,6 +42,7 @@ CHANNELD_COMMON_OBJS := \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/dev_disconnect.o \ common/dev_disconnect.o \
common/gen_status_wire.o \ common/gen_status_wire.o \
common/gen_peer_status_wire.o \
common/htlc_state.o \ common/htlc_state.o \
common/htlc_tx.o \ common/htlc_tx.o \
common/htlc_wire.o \ common/htlc_wire.o \

11
channeld/channel.c

@ -185,7 +185,7 @@ static void do_peer_write(struct peer *peer)
r = write(PEER_FD, peer->peer_outmsg + peer->peer_outoff, r = write(PEER_FD, peer->peer_outmsg + peer->peer_outoff,
len - peer->peer_outoff); len - peer->peer_outoff);
if (r < 0) if (r < 0)
status_fatal_connection_lost(); peer_failed_connection_lost();
peer->peer_outoff += r; peer->peer_outoff += r;
if (peer->peer_outoff == len) if (peer->peer_outoff == len)
@ -1640,7 +1640,7 @@ static void peer_conn_broken(struct peer *peer)
wire_sync_write(GOSSIP_FD, take(cupdate)); wire_sync_write(GOSSIP_FD, take(cupdate));
} }
status_fatal_connection_lost(); peer_failed_connection_lost();
} }
static void resend_revoke(struct peer *peer) static void resend_revoke(struct peer *peer)
@ -1738,7 +1738,7 @@ static void resend_commitment(struct peer *peer, const struct changed_htlc *last
} }
/* Our local wrapper around read_peer_msg */ /* Our local wrapper around read_peer_msg */
static void channeld_io_error(const char *what_i_was_doing, struct peer *peer) static void channeld_io_error(struct peer *peer)
{ {
peer_conn_broken(peer); peer_conn_broken(peer);
} }
@ -1754,7 +1754,8 @@ static bool channeld_send_reply(struct crypto_state *cs,
static u8 *channeld_read_peer_msg(struct peer *peer) static u8 *channeld_read_peer_msg(struct peer *peer)
{ {
return read_peer_msg(peer, &peer->cs, &peer->channel_id, return read_peer_msg(peer, &peer->cs, peer->gossip_index,
&peer->channel_id,
channeld_send_reply, channeld_send_reply,
channeld_io_error, channeld_io_error,
status_fail_errpkt, status_fail_errpkt,
@ -1788,7 +1789,7 @@ static void peer_reconnect(struct peer *peer)
peer->next_index[LOCAL], peer->next_index[LOCAL],
peer->revocations_received); peer->revocations_received);
if (!sync_crypto_write(&peer->cs, PEER_FD, take(msg))) if (!sync_crypto_write(&peer->cs, PEER_FD, take(msg)))
status_fatal_connection_lost(); peer_failed_connection_lost();
/* Read until they say something interesting */ /* Read until they say something interesting */
while ((msg = channeld_read_peer_msg(peer)) == NULL); while ((msg = channeld_read_peer_msg(peer)) == NULL);

1
closingd/Makefile

@ -49,6 +49,7 @@ CLOSINGD_COMMON_OBJS := \
common/daemon_conn.o \ common/daemon_conn.o \
common/dev_disconnect.o \ common/dev_disconnect.o \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/gen_peer_status_wire.o \
common/gen_status_wire.o \ common/gen_status_wire.o \
common/htlc_wire.o \ common/htlc_wire.o \
common/memleak.o \ common/memleak.o \

12
closingd/closing.c

@ -79,11 +79,12 @@ static struct bitcoin_tx *close_tx(const tal_t *ctx,
/* Handle random messages we might get, returning the first non-handled one. */ /* Handle random messages we might get, returning the first non-handled one. */
static u8 *closing_read_peer_msg(const tal_t *ctx, static u8 *closing_read_peer_msg(const tal_t *ctx,
struct crypto_state *cs, struct crypto_state *cs,
u64 gossip_index,
const struct channel_id *channel) const struct channel_id *channel)
{ {
u8 *msg; u8 *msg;
while ((msg = read_peer_msg(ctx, cs, channel, while ((msg = read_peer_msg(ctx, cs, gossip_index, channel,
sync_crypto_write_arg, sync_crypto_write_arg,
status_fail_io, status_fail_io,
status_fail_errpkt, status_fail_errpkt,
@ -118,11 +119,10 @@ static void do_reconnect(struct crypto_state *cs,
next_index[LOCAL], next_index[LOCAL],
revocations_received); revocations_received);
if (!sync_crypto_write(cs, PEER_FD, take(msg))) if (!sync_crypto_write(cs, PEER_FD, take(msg)))
status_fatal_connection_lost(); peer_failed_connection_lost();
;
/* Wait for them to say something interesting */ /* Wait for them to say something interesting */
msg = closing_read_peer_msg(tmpctx, cs, channel_id); msg = closing_read_peer_msg(tmpctx, cs, gossip_index, channel_id);
if (!fromwire_channel_reestablish(msg, NULL, &their_channel_id, if (!fromwire_channel_reestablish(msg, NULL, &their_channel_id,
&next_local_commitment_number, &next_local_commitment_number,
@ -202,7 +202,7 @@ static void send_offer(struct crypto_state *cs,
msg = towire_closing_signed(tmpctx, channel_id, fee_to_offer, &our_sig); msg = towire_closing_signed(tmpctx, channel_id, fee_to_offer, &our_sig);
if (!sync_crypto_write(cs, PEER_FD, take(msg))) if (!sync_crypto_write(cs, PEER_FD, take(msg)))
status_fatal_connection_lost(); peer_failed_connection_lost();
tal_free(tmpctx); tal_free(tmpctx);
} }
@ -248,7 +248,7 @@ static uint64_t receive_offer(struct crypto_state *cs,
/* Wait for them to say something interesting */ /* Wait for them to say something interesting */
do { do {
msg = closing_read_peer_msg(tmpctx, cs, channel_id); msg = closing_read_peer_msg(tmpctx, cs, gossip_index, channel_id);
/* BOLT #2: /* BOLT #2:
* *

10
common/Makefile

@ -43,10 +43,10 @@ COMMON_SRC_NOGEN := \
common/wire_error.c \ common/wire_error.c \
common/withdraw_tx.c common/withdraw_tx.c
COMMON_SRC_GEN := common/gen_status_wire.c COMMON_SRC_GEN := common/gen_status_wire.c common/gen_peer_status_wire.c
COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) common/overflows.h common/htlc.h common/status_levels.h COMMON_HEADERS_NOGEN := $(COMMON_SRC_NOGEN:.c=.h) common/overflows.h common/htlc.h common/status_levels.h
COMMON_HEADERS_GEN := common/gen_htlc_state_names.h common/gen_status_wire.h COMMON_HEADERS_GEN := common/gen_htlc_state_names.h common/gen_status_wire.h common/gen_peer_status_wire.h
COMMON_HEADERS := $(COMMON_HEADERS_GEN) $(COMMON_HEADERS_NOGEN) COMMON_HEADERS := $(COMMON_HEADERS_GEN) $(COMMON_HEADERS_NOGEN)
COMMON_SRC := $(COMMON_SRC_NOGEN) $(COMMON_SRC_GEN) COMMON_SRC := $(COMMON_SRC_NOGEN) $(COMMON_SRC_GEN)
@ -68,6 +68,12 @@ common/gen_status_wire.h: $(WIRE_GEN) common/status_wire.csv
common/gen_status_wire.c: $(WIRE_GEN) common/status_wire.csv common/gen_status_wire.c: $(WIRE_GEN) common/status_wire.csv
$(WIRE_GEN) ${@:.c=.h} status < common/status_wire.csv > $@ $(WIRE_GEN) ${@:.c=.h} status < common/status_wire.csv > $@
common/gen_peer_status_wire.h: $(WIRE_GEN) common/peer_status_wire.csv
$(WIRE_GEN) --header $@ peer_status < common/peer_status_wire.csv > $@
common/gen_peer_status_wire.c: $(WIRE_GEN) common/peer_status_wire.csv
$(WIRE_GEN) ${@:.c=.h} peer_status < common/peer_status_wire.csv > $@
check-makefile: check-common-makefile check-makefile: check-common-makefile
check-common-makefile: check-common-makefile:

24
common/peer_failed.c

@ -1,12 +1,13 @@
#include <ccan/io/io.h> #include <ccan/io/io.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/crypto_sync.h> #include <common/crypto_sync.h>
#include <common/gen_peer_status_wire.h>
#include <common/gen_status_wire.h>
#include <common/peer_failed.h> #include <common/peer_failed.h>
#include <common/status.h> #include <common/status.h>
#include <common/wire_error.h> #include <common/wire_error.h>
#include <stdarg.h> #include <stdarg.h>
#include <unistd.h> #include <unistd.h>
#include <wire/gen_peer_wire.h>
/* We only support one channel per peer anyway */ /* We only support one channel per peer anyway */
void peer_failed_(int peer_fd, int gossip_fd, void peer_failed_(int peer_fd, int gossip_fd,
@ -29,5 +30,24 @@ void peer_failed_(int peer_fd, int gossip_fd,
io_fd_block(peer_fd, false); io_fd_block(peer_fd, false);
sync_crypto_write(cs, peer_fd, msg); sync_crypto_write(cs, peer_fd, msg);
status_fatal_sent_errmsg(take(msg), desc, channel_id); msg = towire_status_peer_error(NULL, channel_id,
desc, cs, gossip_index, msg);
tal_free(desc);
status_send_fatal(take(msg));
}
/* We're failing because peer sent us an error message */
void peer_failed_received_errmsg(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id)
{
u8 *msg = towire_status_peer_error(NULL, channel_id,
desc, cs, gossip_index, NULL);
status_send_fatal(take(msg));
}
void peer_failed_connection_lost(void)
{
status_send_fatal(take(towire_status_peer_connection_lost(NULL)));
} }

10
common/peer_failed.h

@ -22,4 +22,14 @@ void peer_failed_(int peer_fd, int gossip_fd,
const struct channel_id *channel_id, const struct channel_id *channel_id,
const char *fmt, ...) const char *fmt, ...)
PRINTF_FMT(6,7) NORETURN; PRINTF_FMT(6,7) NORETURN;
/* We're failing because peer sent us an error message */
void peer_failed_received_errmsg(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id) NORETURN;
/* I/O error */
void peer_failed_connection_lost(void) NORETURN;
#endif /* LIGHTNING_COMMON_PEER_FAILED_H */ #endif /* LIGHTNING_COMMON_PEER_FAILED_H */

11
common/peer_status_wire.csv

@ -0,0 +1,11 @@
#include <common/crypto_state.h>
# An error occurred: if error_for_them, that to go to them.
status_peer_error,0xFFF4
# This is implied if error_for_them, but master tries not to parse packets.
status_peer_error,,channel,struct channel_id
status_peer_error,,desc,wirestring
status_peer_error,,crypto_state,struct crypto_state
status_peer_error,,gossip_index,u64
status_peer_error,,len,u16
status_peer_error,,error_for_them,len*u8
Can't render this file because it has a wrong number of fields in line 3.

39
common/read_peer_msg.c

@ -1,5 +1,6 @@
#include <ccan/structeq/structeq.h> #include <ccan/structeq/structeq.h>
#include <common/crypto_sync.h> #include <common/crypto_sync.h>
#include <common/peer_failed.h>
#include <common/ping.h> #include <common/ping.h>
#include <common/read_peer_msg.h> #include <common/read_peer_msg.h>
#include <common/status.h> #include <common/status.h>
@ -16,7 +17,7 @@ static void handle_ping(const u8 *msg,
const struct channel_id *channel, const struct channel_id *channel,
bool (*send_reply)(struct crypto_state *, int, bool (*send_reply)(struct crypto_state *, int,
const u8 *, void *), const u8 *, void *),
void (*io_error)(const char *, void *), void (*io_error)(void *),
void *arg) void *arg)
{ {
u8 *pong; u8 *pong;
@ -26,7 +27,7 @@ static void handle_ping(const u8 *msg,
take(towire_errorfmt(msg, channel, take(towire_errorfmt(msg, channel,
"Bad ping %s", "Bad ping %s",
tal_hex(msg, msg))), arg); tal_hex(msg, msg))), arg);
io_error("Bad ping received", arg); io_error(arg);
} }
status_debug("Got ping, sending %s", pong ? status_debug("Got ping, sending %s", pong ?
@ -34,17 +35,20 @@ static void handle_ping(const u8 *msg,
: "nothing"); : "nothing");
if (pong && !send_reply(cs, peer_fd, pong, arg)) if (pong && !send_reply(cs, peer_fd, pong, arg))
io_error("Failed writing pong", arg); io_error(arg);
} }
u8 *read_peer_msg_(const tal_t *ctx, u8 *read_peer_msg_(const tal_t *ctx,
int peer_fd, int gossip_fd, int peer_fd, int gossip_fd,
struct crypto_state *cs, struct crypto_state *cs, u64 gossip_index,
const struct channel_id *channel, const struct channel_id *channel,
bool (*send_reply)(struct crypto_state *cs, int fd, bool (*send_reply)(struct crypto_state *cs, int fd,
const u8 *TAKES, void *arg), const u8 *TAKES, void *arg),
void (*io_error)(const char *what_i_was_doing, void *arg), void (*io_error)(void *arg),
void (*err_pkt)(const char *desc, const struct channel_id *, void (*err_pkt)(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id,
void *arg), void *arg),
void *arg) void *arg)
{ {
@ -53,7 +57,7 @@ u8 *read_peer_msg_(const tal_t *ctx,
msg = sync_crypto_read(ctx, cs, peer_fd); msg = sync_crypto_read(ctx, cs, peer_fd);
if (!msg) if (!msg)
io_error("reading from peer", arg); io_error(arg);
if (is_gossip_msg(msg)) { if (is_gossip_msg(msg)) {
/* Forward to gossip daemon */ /* Forward to gossip daemon */
@ -86,7 +90,8 @@ u8 *read_peer_msg_(const tal_t *ctx,
* - MUST ignore the message. * - MUST ignore the message.
*/ */
if (structeq(&chanid, channel) || channel_id_is_all(&chanid)) if (structeq(&chanid, channel) || channel_id_is_all(&chanid))
err_pkt(err, &chanid, arg); err_pkt(peer_fd, gossip_fd, cs, gossip_index,
err, &chanid, arg);
return tal_free(msg); return tal_free(msg);
} }
@ -102,7 +107,7 @@ u8 *read_peer_msg_(const tal_t *ctx,
"Multiple channels" "Multiple channels"
" unsupported")), " unsupported")),
arg)) arg))
io_error("Sending error for other channel ", arg); io_error(arg);
return tal_free(msg); return tal_free(msg);
} }
@ -116,15 +121,19 @@ bool sync_crypto_write_arg(struct crypto_state *cs, int fd, const u8 *msg,
return sync_crypto_write(cs, fd, msg); return sync_crypto_write(cs, fd, msg);
} }
/* Helper: calls status_fatal_connection_lost. */ /* Helper: calls peer_failed_connection_lost. */
void status_fail_io(const char *what_i_was_doing, void *unused) void status_fail_io(void *unused)
{ {
status_fatal_connection_lost(); peer_failed_connection_lost();
} }
/* Helper: calls status_fatal_received_errmsg() */ /* Helper: calls peer_failed_received_errmsg() */
void status_fail_errpkt(const char *desc, const struct channel_id *c, void status_fail_errpkt(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id,
void *unused) void *unused)
{ {
status_fatal_received_errmsg(desc, c); peer_failed_received_errmsg(peer_fd, gossip_fd,
cs, gossip_index, desc, channel_id);
} }

35
common/read_peer_msg.h

@ -12,6 +12,7 @@ struct channel_id;
* read_peer_msg - read & decode in a peer message, handling common ones. * read_peer_msg - read & decode in a peer message, handling common ones.
* @ctx: context to allocate return packet from. * @ctx: context to allocate return packet from.
* @cs: the cryptostate (updated) * @cs: the cryptostate (updated)
* @gossip_index: the gossip_index
* @chanid: the channel id (for identifying errors) * @chanid: the channel id (for identifying errors)
* @send_reply: the way to send a reply packet (eg. sync_crypto_write_arg) * @send_reply: the way to send a reply packet (eg. sync_crypto_write_arg)
* @io_error: what to do if there's an IO error (eg. status_fail_io) * @io_error: what to do if there's an IO error (eg. status_fail_io)
@ -22,15 +23,18 @@ struct channel_id;
* This returns NULL if it handled the message, so it's normally called in * This returns NULL if it handled the message, so it's normally called in
* a loop. * a loop.
*/ */
#define read_peer_msg(ctx, cs, chanid, send_reply, io_error, err_pkt, arg) \ #define read_peer_msg(ctx, cs, gossip_index, chanid, send_reply, \
read_peer_msg_((ctx), PEER_FD, GOSSIP_FD, (cs), (chanid), \ io_error, err_pkt, arg) \
read_peer_msg_((ctx), PEER_FD, GOSSIP_FD, (cs), (gossip_index), \
(chanid), \
typesafe_cb_preargs(bool, void *, (send_reply), (arg), \ typesafe_cb_preargs(bool, void *, (send_reply), (arg), \
struct crypto_state *, int, \ struct crypto_state *, int, \
const u8 *), \ const u8 *), \
typesafe_cb_preargs(void, void *, (io_error), (arg), \ typesafe_cb(void, void *, (io_error), (arg)), \
const char *), \
typesafe_cb_preargs(void, void *, (err_pkt), (arg), \ typesafe_cb_preargs(void, void *, (err_pkt), (arg), \
const char *, \ int, int, \
struct crypto_state *, \
u64, const char *, \
const struct channel_id *), \ const struct channel_id *), \
arg) arg)
@ -38,22 +42,27 @@ struct channel_id;
bool sync_crypto_write_arg(struct crypto_state *cs, int fd, const u8 *TAKES, bool sync_crypto_write_arg(struct crypto_state *cs, int fd, const u8 *TAKES,
void *unused); void *unused);
/* Helper: calls status_fatal_connection_lost. */ /* Helper: calls peer_failed_connection_lost. */
/* FIXME: Remove what_i_was_doing arg */ void status_fail_io(void *unused);
void status_fail_io(const char *what_i_was_doing, void *unused);
/* Helper: calls status_fatal_received_errmsg() */ /* Helper: calls peer_failed_received_errmsg() */
void status_fail_errpkt(const char *desc, const struct channel_id *c, void status_fail_errpkt(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id,
void *unused); void *unused);
u8 *read_peer_msg_(const tal_t *ctx, u8 *read_peer_msg_(const tal_t *ctx,
int peer_fd, int gossip_fd, int peer_fd, int gossip_fd,
struct crypto_state *cs, struct crypto_state *cs, u64 gossip_index,
const struct channel_id *channel, const struct channel_id *channel,
bool (*send_reply)(struct crypto_state *cs, int fd, bool (*send_reply)(struct crypto_state *cs, int fd,
const u8 *TAKES, void *arg), const u8 *TAKES, void *arg),
void (*io_error)(const char *what_i_was_doing, void *arg), void (*io_error)(void *arg),
void (*err_pkt)(const char *desc, const struct channel_id *, void (*err_pkt)(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id,
void *arg), void *arg),
void *arg); void *arg);

43
common/status.c

@ -122,19 +122,26 @@ static NORETURN void flush_and_exit(int reason)
exit(0x80 | (reason & 0xFF)); exit(0x80 | (reason & 0xFF));
} }
void status_send_fatal(const u8 *msg TAKES)
{
int reason = fromwire_peektype(msg);
breakpoint();
status_send(msg);
flush_and_exit(reason);
}
/* FIXME: rename to status_fatal, s/fail/fatal/ in status_failreason enums */ /* FIXME: rename to status_fatal, s/fail/fatal/ in status_failreason enums */
void status_failed(enum status_failreason reason, const char *fmt, ...) void status_failed(enum status_failreason reason, const char *fmt, ...)
{ {
va_list ap; va_list ap;
char *str; char *str;
breakpoint();
va_start(ap, fmt); va_start(ap, fmt);
str = tal_vfmt(NULL, fmt, ap); str = tal_vfmt(NULL, fmt, ap);
status_send(take(towire_status_fail(NULL, reason, str)));
va_end(ap); va_end(ap);
flush_and_exit(reason); status_send_fatal(take(towire_status_fail(NULL, reason, str)));
} }
void master_badmsg(u32 type_expected, const u8 *msg) void master_badmsg(u32 type_expected, const u8 *msg)
@ -147,33 +154,3 @@ void master_badmsg(u32 type_expected, const u8 *msg)
"Error parsing %u: %s", "Error parsing %u: %s",
type_expected, tal_hex(trc, msg)); type_expected, tal_hex(trc, msg));
} }
void status_fatal_connection_lost(void)
{
status_send(take(towire_status_peer_connection_lost(NULL)));
flush_and_exit(WIRE_STATUS_PEER_CONNECTION_LOST);
}
/* Got an error for one or all channels */
void status_fatal_received_errmsg(const char *desc, const struct channel_id *c)
{
static const struct channel_id all_channels;
if (!c)
c = &all_channels;
status_send(take(towire_status_received_errmsg(NULL, c, desc)));
flush_and_exit(WIRE_STATUS_RECEIVED_ERRMSG);
}
/* Sent an error for one or all channels */
void status_fatal_sent_errmsg(const u8 *errmsg,
const char *desc, const struct channel_id *c)
{
static const struct channel_id all_channels;
if (!c)
c = &all_channels;
status_send(take(towire_status_sent_errmsg(NULL, c, desc, errmsg)));
flush_and_exit(WIRE_STATUS_SENT_ERRMSG);
}

15
common/status.h

@ -3,7 +3,7 @@
#include "config.h" #include "config.h"
#include <ccan/compiler/compiler.h> #include <ccan/compiler/compiler.h>
#include <ccan/short_types/short_types.h> #include <ccan/short_types/short_types.h>
#include <common/htlc.h> /* For enum side */ #include <ccan/take/take.h>
#include <common/status_levels.h> #include <common/status_levels.h>
#include <stdarg.h> #include <stdarg.h>
#include <stdbool.h> #include <stdbool.h>
@ -51,16 +51,5 @@ void status_failed(enum status_failreason code,
* msg NULL == read failure. */ * msg NULL == read failure. */
void master_badmsg(u32 type_expected, const u8 *msg) NORETURN; void master_badmsg(u32 type_expected, const u8 *msg) NORETURN;
/* I/O error */ void status_send_fatal(const u8 *msg TAKES) NORETURN;
void status_fatal_connection_lost(void) NORETURN;
/* Got an error for one or all channels (if c == NULL) */
void status_fatal_received_errmsg(const char *desc,
const struct channel_id *c) NORETURN;
/* Sent an error for one or all channels (if c == NULL) */
void status_fatal_sent_errmsg(const u8 *errmsg,
const char *desc,
const struct channel_id *c) NORETURN;
#endif /* LIGHTNING_COMMON_STATUS_H */ #endif /* LIGHTNING_COMMON_STATUS_H */

12
common/status_wire.csv

@ -15,16 +15,4 @@ status_fail,,desc,wirestring
status_peer_connection_lost,0xFFF3 status_peer_connection_lost,0xFFF3
# They sent us this error.
status_received_errmsg,0xFFF4
status_received_errmsg,,channel,struct channel_id
status_received_errmsg,,desc,wirestring
# We sent them this error.
status_sent_errmsg,0xFFF5
status_sent_errmsg,,channel,struct channel_id
status_sent_errmsg,,desc,wirestring
status_sent_errmsg,,len,u16
status_sent_errmsg,,errmsg,len*u8
# Note: 0xFFFF is reserved for MSG_PASS_FD! # Note: 0xFFFF is reserved for MSG_PASS_FD!

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

1
lightningd/Makefile

@ -23,6 +23,7 @@ LIGHTNINGD_COMMON_OBJS := \
common/derive_basepoints.o \ common/derive_basepoints.o \
common/features.o \ common/features.o \
common/funding_tx.o \ common/funding_tx.o \
common/gen_peer_status_wire.o \
common/gen_status_wire.o \ common/gen_status_wire.o \
common/hash_u5.o \ common/hash_u5.o \
common/htlc_state.o \ common/htlc_state.o \

59
lightningd/subd.c

@ -7,6 +7,8 @@
#include <ccan/take/take.h> #include <ccan/take/take.h>
#include <ccan/tal/path/path.h> #include <ccan/tal/path/path.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <common/crypto_state.h>
#include <common/gen_peer_status_wire.h>
#include <common/gen_status_wire.h> #include <common/gen_status_wire.h>
#include <errno.h> #include <errno.h>
#include <fcntl.h> #include <fcntl.h>
@ -386,42 +388,26 @@ static bool log_status_fail(struct subd *sd, const u8 *msg)
return true; return true;
} }
static bool handle_received_errmsg(struct subd *sd, const u8 *msg) static bool handle_peer_error(struct subd *sd, const u8 *msg)
{ {
void *channel = sd->channel; void *channel = sd->channel;
struct channel_id channel_id; struct channel_id channel_id;
char *desc; char *desc;
struct crypto_state cs;
u64 gossip_index;
u8 *err_for_them;
if (!fromwire_status_received_errmsg(msg, msg, NULL, if (!fromwire_status_peer_error(msg, msg, NULL,
&channel_id, &desc)) &channel_id, &desc,
&cs, &gossip_index, &err_for_them))
return false; return false;
/* FIXME: if not all channels failed, hand back to gossipd! */ /* FIXME: hand back to gossipd! */
/* Don't free sd; we're may be about to free channel. */ /* Don't free sd; we're may be about to free channel. */
sd->channel = NULL; sd->channel = NULL;
if (sd->errcb) sd->errcb(channel, err_for_them ? LOCAL : REMOTE,
sd->errcb(channel, REMOTE, &channel_id, desc, NULL); &channel_id, desc, err_for_them);
return true;
}
static bool handle_sent_errmsg(struct subd *sd, const u8 *msg)
{
void *channel = sd->channel;
struct channel_id channel_id;
char *desc;
u8 *errmsg;
if (!fromwire_status_sent_errmsg(msg, msg, NULL,
&channel_id, &desc, &errmsg))
return false;
/* FIXME: if not all channels failed, hand back to gossipd! */
/* Don't free sd; we're may be about to free channel. */
sd->channel = NULL;
if (sd->errcb)
sd->errcb(channel, LOCAL, &channel_id, desc, errmsg);
return true; return true;
} }
@ -472,18 +458,15 @@ static struct io_plan *sd_msg_read(struct io_conn *conn, struct subd *sd)
goto malformed; goto malformed;
log_info(sd->log, "Peer connection lost"); log_info(sd->log, "Peer connection lost");
goto close; goto close;
case WIRE_STATUS_RECEIVED_ERRMSG: }
if (!sd->channel)
goto malformed; if (sd->channel) {
if (!handle_received_errmsg(sd, sd->msg_in)) switch ((enum peer_status)type) {
goto malformed; case WIRE_STATUS_PEER_ERROR:
goto close; if (!handle_peer_error(sd, sd->msg_in))
case WIRE_STATUS_SENT_ERRMSG: goto malformed;
if (!sd->channel) goto close;
goto malformed; }
if (!handle_sent_errmsg(sd, sd->msg_in))
goto malformed;
goto close;
} }
log_debug(sd->log, "UPDATE %s", sd->msgname(type)); log_debug(sd->log, "UPDATE %s", sd->msgname(type));

1
openingd/Makefile

@ -45,6 +45,7 @@ OPENINGD_COMMON_OBJS := \
common/dev_disconnect.o \ common/dev_disconnect.o \
common/funding_tx.o \ common/funding_tx.o \
common/gen_status_wire.o \ common/gen_status_wire.o \
common/gen_peer_status_wire.o \
common/htlc_wire.o \ common/htlc_wire.o \
common/initial_channel.o \ common/initial_channel.o \
common/initial_commit_tx.o \ common/initial_commit_tx.o \

16
openingd/opening.c

@ -206,14 +206,17 @@ static void temporary_channel_id(struct channel_id *channel_id)
} }
/* This handles the case where there's an error only for this channel */ /* This handles the case where there's an error only for this channel */
static void opening_errpkt(const char *desc, static void opening_errpkt(int peer_fd, int gossip_fd,
struct crypto_state *cs, u64 gossip_index,
const char *desc,
const struct channel_id *channel_id, const struct channel_id *channel_id,
struct state *state) struct state *state)
{ {
/* FIXME: Remove negotiation_failed */ /* FIXME: Remove negotiation_failed */
if (structeq(channel_id, &state->channel_id)) if (structeq(channel_id, &state->channel_id))
negotiation_failed(state, false, "Error packet: %s", desc); negotiation_failed(state, false, "Error packet: %s", desc);
status_fatal_received_errmsg(desc, channel_id); peer_failed_received_errmsg(peer_fd, gossip_fd,
cs, gossip_index, desc, channel_id);
} }
/* Handle random messages we might get, returning the first non-handled one. */ /* Handle random messages we might get, returning the first non-handled one. */
@ -221,7 +224,8 @@ static u8 *opening_read_peer_msg(struct state *state)
{ {
u8 *msg; u8 *msg;
while ((msg = read_peer_msg(state, &state->cs, &state->channel_id, while ((msg = read_peer_msg(state, &state->cs, state->gossip_index,
&state->channel_id,
sync_crypto_write_arg, sync_crypto_write_arg,
status_fail_io, status_fail_io,
opening_errpkt, opening_errpkt,
@ -288,7 +292,7 @@ static u8 *funder_channel(struct state *state,
&state->next_per_commit[LOCAL], &state->next_per_commit[LOCAL],
channel_flags); channel_flags);
if (!sync_crypto_write(&state->cs, PEER_FD, msg)) if (!sync_crypto_write(&state->cs, PEER_FD, msg))
status_fatal_connection_lost(); peer_failed_connection_lost();
state->remoteconf = tal(state, struct channel_config); state->remoteconf = tal(state, struct channel_config);
@ -405,7 +409,7 @@ static u8 *funder_channel(struct state *state,
state->funding_txout, state->funding_txout,
&sig); &sig);
if (!sync_crypto_write(&state->cs, PEER_FD, msg)) if (!sync_crypto_write(&state->cs, PEER_FD, msg))
status_fatal_connection_lost(); peer_failed_connection_lost();
/* BOLT #2: /* BOLT #2:
* *
@ -599,7 +603,7 @@ static u8 *fundee_channel(struct state *state,
&state->next_per_commit[LOCAL]); &state->next_per_commit[LOCAL]);
if (!sync_crypto_write(&state->cs, PEER_FD, take(msg))) if (!sync_crypto_write(&state->cs, PEER_FD, take(msg)))
status_fatal_connection_lost(); peer_failed_connection_lost();
msg = opening_read_peer_msg(state); msg = opening_read_peer_msg(state);

Loading…
Cancel
Save