diff --git a/lightningd/Makefile b/lightningd/Makefile index 57143ba17..1d1f37243 100644 --- a/lightningd/Makefile +++ b/lightningd/Makefile @@ -32,6 +32,7 @@ LIGHTNINGD_OLD_LIB_SRC := \ LIGHTNINGD_OLD_LIB_OBJS := $(LIGHTNINGD_OLD_LIB_SRC:.c=.o) LIGHTNINGD_OLD_LIB_HEADERS := $(LIGHTNINGD_OLD_LIB_SRC:.c=.h) +# FIXME: put in a library so we don't link all of them. LIGHTNINGD_LIB_SRC := \ lightningd/channel.c \ lightningd/channel_config.c \ @@ -41,6 +42,7 @@ LIGHTNINGD_LIB_SRC := \ lightningd/funding_tx.c \ lightningd/htlc_tx.c \ lightningd/key_derive.c \ + lightningd/peer_failed.c \ lightningd/utxo.c LIGHTNINGD_LIB_OBJS := $(LIGHTNINGD_LIB_SRC:.c=.o) diff --git a/lightningd/peer_failed.c b/lightningd/peer_failed.c new file mode 100644 index 000000000..6d622bae7 --- /dev/null +++ b/lightningd/peer_failed.c @@ -0,0 +1,41 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +/* We only support one channel per peer anyway */ +void peer_failed(int peer_fd, struct crypto_state *cs, + const struct channel_id *channel_id, + u16 error_code, const char *fmt, ...) +{ + va_list ap; + const char *errmsg; + struct channel_id all_channels; + u8 *msg; + + /* BOLT #1: + * + * A node sending `error` MUST fail the channel referred to by the + * `channel-id`, or if `channel-id` is `0xFFFFFFFFFFFFFFFF` it MUST + * fail all channels and MUST close the connection. + */ + if (!channel_id) { + memset(&all_channels, 0xFF, sizeof(all_channels)); + channel_id = &all_channels; + } + + va_start(ap, fmt); + errmsg = tal_vfmt(NULL, fmt, ap); + va_end(ap); + msg = towire_error(errmsg, channel_id, (const u8 *)errmsg); + + /* This is only best-effort; don't block. */ + fcntl(peer_fd, F_SETFL, fcntl(peer_fd, F_GETFL) | O_NONBLOCK); + sync_crypto_write(cs, peer_fd, msg); + + status_failed(error_code, "%s", errmsg); +} diff --git a/lightningd/peer_failed.h b/lightningd/peer_failed.h new file mode 100644 index 000000000..2449fd68d --- /dev/null +++ b/lightningd/peer_failed.h @@ -0,0 +1,21 @@ +#ifndef LIGHTNING_LIGHTNINGD_PEER_FAILED_H +#define LIGHTNING_LIGHTNINGD_PEER_FAILED_H +#include "config.h" +#include +#include + +struct channel_id; + +/** + * peer_failed - Try sending error to peer, but exit with status. + * @peer_fd: file descriptor for peer. + * @cs: the peer's current crypto state. + * @channel_id: channel with error, or NULL for all. + * @error_code: error code as per status_failed + * @fmt: format as per status_failed + */ +void peer_failed(int peer_fd, struct crypto_state *cs, + const struct channel_id *channel_id, + u16 error_code, const char *fmt, ...) + PRINTF_FMT(5,6) NORETURN; +#endif /* LIGHTNING_STATUS_H */