diff --git a/common/peer_failed.c b/common/peer_failed.c index 13a97887d..f21754e3a 100644 --- a/common/peer_failed.c +++ b/common/peer_failed.c @@ -25,6 +25,7 @@ peer_fatal_continue(const u8 *msg TAKES, const struct per_peer_state *pps) /* We only support one channel per peer anyway */ static void NORETURN peer_failed(struct per_peer_state *pps, + bool disconnect, bool warn, const struct channel_id *channel_id, const char *desc) @@ -40,9 +41,9 @@ peer_failed(struct per_peer_state *pps, /* Tell master the error so it can re-xmit. */ msg = towire_status_peer_error(NULL, + disconnect, desc, warn, - false, msg); peer_billboard(true, desc); peer_fatal_continue(take(msg), pps); @@ -59,7 +60,21 @@ void peer_failed_warn(struct per_peer_state *pps, desc = tal_vfmt(tmpctx, fmt, ap); va_end(ap); - peer_failed(pps, true, channel_id, desc); + peer_failed(pps, true, true, channel_id, desc); +} + +void peer_failed_warn_nodisconnect(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, true, channel_id, desc); } void peer_failed_err(struct per_peer_state *pps, @@ -74,17 +89,17 @@ void peer_failed_err(struct per_peer_state *pps, desc = tal_vfmt(tmpctx, fmt, ap); va_end(ap); - peer_failed(pps, false, channel_id, desc); + peer_failed(pps, true, 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, - bool abort_restart) + bool disconnect, + const char *desc) { u8 *msg; - msg = towire_status_peer_error(NULL, desc, false, abort_restart, NULL); + msg = towire_status_peer_error(NULL, disconnect, desc, false, NULL); peer_billboard(true, "Received %s", desc); peer_fatal_continue(take(msg), pps); } diff --git a/common/peer_failed.h b/common/peer_failed.h index c33c68d2d..b782e525b 100644 --- a/common/peer_failed.h +++ b/common/peer_failed.h @@ -21,6 +21,17 @@ void peer_failed_warn(struct per_peer_state *pps, const char *fmt, ...) PRINTF_FMT(3,4) NORETURN; +/** + * peer_failed_warn_nodisconnect - Send a warning msg, don't close. + * @pps: the per-peer state. + * @channel_id: channel with error, or NULL for no particular channel. + * @fmt...: format as per status_failed(STATUS_FAIL_PEER_BAD) + */ +void peer_failed_warn_nodisconnect(struct per_peer_state *pps, + const struct channel_id *channel_id, + const char *fmt, ...) + PRINTF_FMT(3,4) NORETURN; + /** * peer_failed_err - Send a warning msg and close the channel. * @pps: the per-peer state. @@ -35,8 +46,8 @@ void peer_failed_err(struct per_peer_state *pps, /* We're failing because peer sent us an error message: NULL * channel_id means all channels. */ void peer_failed_received_errmsg(struct per_peer_state *pps, - const char *desc, - bool abort_restart) + bool disconnect, + const char *desc) NORETURN; /* I/O error */ diff --git a/common/peer_status_wire.csv b/common/peer_status_wire.csv index cc3ffdf0e..66cb54a4e 100644 --- a/common/peer_status_wire.csv +++ b/common/peer_status_wire.csv @@ -3,11 +3,13 @@ # An error occurred: if error_for_them, that to go to them. msgtype,status_peer_error,0xFFF4 +# Do we force a disconnect from the peer? +msgdata,status_peer_error,disconnect,bool, +# The error string msgdata,status_peer_error,desc,wirestring, -# Take a deep breath, then try reconnecting to the precious little snowflake. -# (Means we sent it, since we don't hang up if they send one) +# Actually a warning, not a (fatal!) error. msgdata,status_peer_error,warning,bool, -# From an abort, no reconnect but restart daemon -msgdata,status_peer_error,abort_do_restart,bool, +# The error to send to them in future if they try to talk to us about +# this channel. msgdata,status_peer_error,len,u16, msgdata,status_peer_error,error_for_them,u8,len diff --git a/common/read_peer_msg.c b/common/read_peer_msg.c index c9a8837d2..d5b2a14d1 100644 --- a/common/read_peer_msg.c +++ b/common/read_peer_msg.c @@ -35,7 +35,7 @@ bool handle_peer_error_or_warning(struct per_peer_state *pps, err = is_peer_error(tmpctx, msg); if (err) - peer_failed_received_errmsg(pps, err, false); + peer_failed_received_errmsg(pps, true, err); /* Simply log incoming warnings */ err = is_peer_warning(tmpctx, msg); diff --git a/lightningd/subd.c b/lightningd/subd.c index f19b0ee80..e48f6cd7f 100644 --- a/lightningd/subd.c +++ b/lightningd/subd.c @@ -422,18 +422,18 @@ static bool handle_peer_error(struct subd *sd, const u8 *msg, int fds[1]) struct peer_fd *peer_fd; u8 *err_for_them; bool warning; - bool aborted; + bool disconnect; if (!fromwire_status_peer_error(msg, msg, - &desc, &warning, - &aborted, &err_for_them)) + &disconnect, &desc, &warning, + &err_for_them)) return false; peer_fd = new_peer_fd_arr(msg, fds); /* Don't free sd; we may be about to free channel. */ sd->channel = NULL; - sd->errcb(channel, peer_fd, desc, warning, aborted, err_for_them); + sd->errcb(channel, peer_fd, desc, warning, !disconnect, err_for_them); return true; } diff --git a/lightningd/test/run-find_my_abspath.c b/lightningd/test/run-find_my_abspath.c index bd350e252..09ece1c79 100644 --- a/lightningd/test/run-find_my_abspath.c +++ b/lightningd/test/run-find_my_abspath.c @@ -84,7 +84,7 @@ bool fromwire_status_fail(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, enu bool fromwire_status_peer_billboard(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *perm UNNEEDED, wirestring **happenings UNNEEDED) { fprintf(stderr, "fromwire_status_peer_billboard called!\n"); abort(); } /* Generated stub for fromwire_status_peer_error */ -bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **desc UNNEEDED, bool *warning UNNEEDED, bool *abort_do_restart UNNEEDED, u8 **error_for_them UNNEEDED) +bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *disconnect UNNEEDED, wirestring **desc UNNEEDED, bool *warning UNNEEDED, u8 **error_for_them UNNEEDED) { fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); } /* Generated stub for fromwire_status_version */ bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED) diff --git a/lightningd/test/run-shuffle_fds.c b/lightningd/test/run-shuffle_fds.c index de06f7a70..eb4e54c6f 100644 --- a/lightningd/test/run-shuffle_fds.c +++ b/lightningd/test/run-shuffle_fds.c @@ -70,7 +70,7 @@ bool fromwire_status_fail(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, enu bool fromwire_status_peer_billboard(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *perm UNNEEDED, wirestring **happenings UNNEEDED) { fprintf(stderr, "fromwire_status_peer_billboard called!\n"); abort(); } /* Generated stub for fromwire_status_peer_error */ -bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **desc UNNEEDED, bool *warning UNNEEDED, bool *abort_do_restart UNNEEDED, u8 **error_for_them UNNEEDED) +bool fromwire_status_peer_error(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, bool *disconnect UNNEEDED, wirestring **desc UNNEEDED, bool *warning UNNEEDED, u8 **error_for_them UNNEEDED) { fprintf(stderr, "fromwire_status_peer_error called!\n"); abort(); } /* Generated stub for fromwire_status_version */ bool fromwire_status_version(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, wirestring **version UNNEEDED) diff --git a/openingd/dualopend.c b/openingd/dualopend.c index 5a999c45e..6248ce0da 100644 --- a/openingd/dualopend.c +++ b/openingd/dualopend.c @@ -333,8 +333,8 @@ static void negotiation_aborted(struct state *state, const char *why, bool abort { status_debug("aborted opening negotiation: %s", why); - /* Tell master that funding failed. */ - peer_failed_received_errmsg(state->pps, why, aborted); + /* Tell master that funding failed (don't disconnect if we aborted) */ + peer_failed_received_errmsg(state->pps, !aborted, why); } /* Softer version of 'warning' (we don't disconnect)