Files
lightning/common/peer_failed.c
Rusty Russell f4ee41a989 common: remove peer_failed in favor of peer_failed_warn/peer_failed_err
And make all the callers choose which one.  In general, I prefer warn,
which lets them reconnect and try again, however some places are either
stated that they must be errors in the spec itself, or in openingd
where we abandon the channel when we close the connection anyway.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Changed: Protocol: we now send warning messages and close the connection, except on unrecoverable errors.
2021-02-04 12:02:52 +10:30

99 lines
2.3 KiB
C

#include <assert.h>
#include <ccan/breakpoint/breakpoint.h>
#include <ccan/tal/str/str.h>
#include <common/crypto_sync.h>
#include <common/peer_billboard.h>
#include <common/peer_failed.h>
#include <common/peer_status_wiregen.h>
#include <common/status.h>
#include <common/status_wiregen.h>
#include <common/wire_error.h>
#include <stdarg.h>
/* Fatal error here, return peer control to lightningd */
static void NORETURN
peer_fatal_continue(const u8 *msg TAKES, const struct per_peer_state *pps)
{
int reason = fromwire_peektype(msg);
breakpoint();
status_send(msg);
status_send_fd(pps->peer_fd);
status_send_fd(pps->gossip_fd);
status_send_fd(pps->gossip_store_fd);
exit(0x80 | (reason & 0xFF));
}
/* We only support one channel per peer anyway */
static void NORETURN
peer_failed(struct per_peer_state *pps,
bool warn,
const struct channel_id *channel_id,
const char *desc)
{
u8 *msg;
if (warn) {
msg = towire_warningfmt(desc, channel_id, "%s", desc);
} else {
msg = towire_errorfmt(desc, channel_id, "%s", desc);
}
sync_crypto_write(pps, msg);
/* Tell master the error so it can re-xmit. */
msg = towire_status_peer_error(NULL, channel_id,
desc,
warn,
pps,
msg);
peer_billboard(true, desc);
peer_fatal_continue(take(msg), pps);
}
void peer_failed_warn(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
{
va_list ap;
const char *desc;
va_start(ap, fmt);
desc = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);
peer_failed(pps, true, channel_id, desc);
}
void peer_failed_err(struct per_peer_state *pps,
const struct channel_id *channel_id,
const char *fmt, ...)
{
va_list ap;
const char *desc;
va_start(ap, fmt);
desc = tal_vfmt(tmpctx, fmt, ap);
va_end(ap);
peer_failed(pps, false, channel_id, desc);
}
/* We're failing because peer sent us an error/warning message */
void peer_failed_received_errmsg(struct per_peer_state *pps,
const char *desc,
const struct channel_id *channel_id,
bool warning)
{
u8 *msg;
msg = towire_status_peer_error(NULL, channel_id, desc, warning, pps,
NULL);
peer_billboard(true, "Received %s", desc);
peer_fatal_continue(take(msg), pps);
}
void peer_failed_connection_lost(void)
{
status_send_fatal(take(towire_status_peer_connection_lost(NULL)));
}