lightningd: close channel ourselves, if we receive an error.

Previously, we would forward the message to a subd, but now we have
the case where the subd is gone, but we're still connected.  If the
peer anything but a reestablish in that state, we drop the connection.

Instead, an error should always make us fail the channel.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2023-10-22 14:37:32 +10:30
parent 6a67615274
commit cf2ebed567
5 changed files with 26 additions and 10 deletions

View file

@ -86,6 +86,8 @@ msgdata,connectd_peer_spoke,id,node_id,
msgdata,connectd_peer_spoke,counter,u64, msgdata,connectd_peer_spoke,counter,u64,
msgdata,connectd_peer_spoke,msgtype,u16, msgdata,connectd_peer_spoke,msgtype,u16,
msgdata,connectd_peer_spoke,channel_id,channel_id, msgdata,connectd_peer_spoke,channel_id,channel_id,
# If msgtype == WIRE_ERROR, this is the string.
msgdata,connectd_peer_spoke,error,?wirestring,
# master -> connectd: peer no longer wanted, you can disconnect. # master -> connectd: peer no longer wanted, you can disconnect.
msgtype,connectd_discard_peer,2015 msgtype,connectd_discard_peer,2015

1 #include <bitcoin/block.h>
86 msgdata,connectd_peer_final_msg,counter,u64, msgtype,connectd_peer_final_msg,2003
87 msgdata,connectd_peer_final_msg,len,u16, msgdata,connectd_peer_final_msg,id,node_id,
88 msgdata,connectd_peer_final_msg,msg,u8,len msgdata,connectd_peer_final_msg,counter,u64,
89 msgdata,connectd_peer_final_msg,len,u16,
90 msgdata,connectd_peer_final_msg,msg,u8,len
91 # master -> connectd: do you have a memleak?
92 msgtype,connectd_dev_memleak,2033
93 msgtype,connectd_dev_memleak_reply,2133

View file

@ -1120,7 +1120,8 @@ static struct io_plan *read_body_from_peer_done(struct io_conn *peer_conn,
take(towire_connectd_peer_spoke(NULL, &peer->id, take(towire_connectd_peer_spoke(NULL, &peer->id,
peer->counter, peer->counter,
t, t,
&channel_id))); &channel_id,
is_peer_error(tmpctx, decrypted))));
} }
/* Even if we just created it, call this to catch open_channel2 */ /* Even if we just created it, call this to catch open_channel2 */

View file

@ -1578,8 +1578,9 @@ void peer_spoke(struct lightningd *ld, const u8 *msg)
bool dual_fund; bool dual_fund;
u8 *error; u8 *error;
int fds[2]; int fds[2];
char *errmsg;
if (!fromwire_connectd_peer_spoke(msg, &id, &connectd_counter, &msgtype, &channel_id)) if (!fromwire_connectd_peer_spoke(msg, msg, &id, &connectd_counter, &msgtype, &channel_id, &errmsg))
fatal("Connectd gave bad CONNECTD_PEER_SPOKE message %s", fatal("Connectd gave bad CONNECTD_PEER_SPOKE message %s",
tal_hex(msg, msg)); tal_hex(msg, msg));
@ -1596,13 +1597,25 @@ void peer_spoke(struct lightningd *ld, const u8 *msg)
goto send_error; goto send_error;
} }
/* If channel is active, we raced, so ignore this:
* subd will get it soon. */
if (channel_state_wants_peercomms(channel->state)) { if (channel_state_wants_peercomms(channel->state)) {
log_debug(channel->log, /* If they send an error, handle it immediately. */
"channel already active"); if (errmsg) {
if (!channel->owner && channel_fail_permanent(channel, REASON_REMOTE,
channel->state == DUALOPEND_AWAITING_LOCKIN) { "They sent %s", errmsg);
return;
}
/* If channel is active there are two possibilities:
* 1. We have started subd, but channeld hasn't processed
* the connectd_peer_connect_subd message yet.
* 2. subd exited */
if (channel->owner) {
/* We raced... */
return;
}
log_debug(channel->log, "channel already active");
if (channel->state == DUALOPEND_AWAITING_LOCKIN) {
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) { if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0) {
log_broken(ld->log, log_broken(ld->log,
"Failed to create socketpair: %s", "Failed to create socketpair: %s",

View file

@ -277,7 +277,7 @@ bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p U
bool fromwire_connectd_peer_disconnect_done(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED) bool fromwire_connectd_peer_disconnect_done(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_disconnect_done called!\n"); abort(); } { fprintf(stderr, "fromwire_connectd_peer_disconnect_done called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_spoke */ /* Generated stub for fromwire_connectd_peer_spoke */
bool fromwire_connectd_peer_spoke(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED) bool fromwire_connectd_peer_spoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED, wirestring **error UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_spoke called!\n"); abort(); } { fprintf(stderr, "fromwire_connectd_peer_spoke called!\n"); abort(); }
/* Generated stub for fromwire_dualopend_dev_memleak_reply */ /* Generated stub for fromwire_dualopend_dev_memleak_reply */
bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED) bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)

View file

@ -192,7 +192,7 @@ bool fromwire_connectd_peer_connected(const tal_t *ctx UNNEEDED, const void *p U
bool fromwire_connectd_peer_disconnect_done(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED) bool fromwire_connectd_peer_disconnect_done(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_disconnect_done called!\n"); abort(); } { fprintf(stderr, "fromwire_connectd_peer_disconnect_done called!\n"); abort(); }
/* Generated stub for fromwire_connectd_peer_spoke */ /* Generated stub for fromwire_connectd_peer_spoke */
bool fromwire_connectd_peer_spoke(const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED) bool fromwire_connectd_peer_spoke(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct node_id *id UNNEEDED, u64 *counter UNNEEDED, u16 *msgtype UNNEEDED, struct channel_id *channel_id UNNEEDED, wirestring **error UNNEEDED)
{ fprintf(stderr, "fromwire_connectd_peer_spoke called!\n"); abort(); } { fprintf(stderr, "fromwire_connectd_peer_spoke called!\n"); abort(); }
/* Generated stub for fromwire_dualopend_dev_memleak_reply */ /* Generated stub for fromwire_dualopend_dev_memleak_reply */
bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED) bool fromwire_dualopend_dev_memleak_reply(const void *p UNNEEDED, bool *leak UNNEEDED)