Skip to content

Commit

Permalink
channeld/channeld.c: Log and ignore repeated WIRE_CHANNEL_REESTABLISH.
Browse files Browse the repository at this point in the history
Fixes: #3608

Changelog-Changed: protocol: Ignore (and log as "unusual") repeated `WIRE_CHANNEL_REESTABLISH` messages, to be compatible with buggy peer software that sometimes does this.
  • Loading branch information
ZmnSCPxj authored and rustyrussell committed Aug 28, 2020
1 parent 26f1160 commit a1ba214
Showing 1 changed file with 58 additions and 1 deletion.
59 changes: 58 additions & 1 deletion channeld/channeld.c
Original file line number Diff line number Diff line change
Expand Up @@ -1975,6 +1975,60 @@ static void send_onionmsg(struct peer *peer, const u8 *msg)
}
#endif /* EXPERIMENTAL_FEATURES */

static void handle_unexpected_reestablish(struct peer *peer, const u8 *msg)
{
struct channel_id channel_id;
u64 next_commitment_number;
u64 next_revocation_number;
struct secret your_last_per_commitment_secret;
struct pubkey my_current_per_commitment_point;

if (!fromwire_channel_reestablish(msg, &channel_id,
&next_commitment_number,
&next_revocation_number,
&your_last_per_commitment_secret,
&my_current_per_commitment_point))
peer_failed(peer->pps,
&peer->channel_id,
"Bad channel_reestablish %s", tal_hex(peer, msg));

/* Is it the same as the peer channel ID? */
if (channel_id_eq(&channel_id, &peer->channel_id)) {
/* Log this event as unusual. */
status_unusual("Got repeated WIRE_CHANNEL_REESTABLISH "
"for channel %s, ignoring: %s",
type_to_string(tmpctx, struct channel_id,
&peer->channel_id),
tal_hex(tmpctx, msg));
/* This is a mitigation for a known bug in some peer software
* that sometimes double-sends a reestablish message.
*
* Ideally we would send some kind of `error` message to the
* peer here, but if we sent an `error` message with the
* same channel ID it would cause the peer to drop the
* channel unilaterally.
* We also cannot use 0x00...00 because that means "all
* channels", so a proper peer (like C-lightning) will
* unilaterally close all channels we have with it, if we
* sent the 0x00...00 channel ID.
*
* So just do not send an error.
*/
return;
}

/* We only support one channel here, so the unexpected channel is the
* peer getting its wires crossed somewhere.
* Fail the channel they sent, not the channel we are actively
* handling. */
peer_failed(peer->pps, &channel_id,
"Peer sent unexpected message %u, (%s) "
"for nonexistent channel %s",
WIRE_CHANNEL_REESTABLISH, "WIRE_CHANNEL_REESTABLISH",
type_to_string(tmpctx, struct channel_id,
&channel_id));
}

static void peer_in(struct peer *peer, const u8 *msg)
{
enum wire_type type = fromwire_peektype(msg);
Expand Down Expand Up @@ -2057,10 +2111,13 @@ static void peer_in(struct peer *peer, const u8 *msg)
case WIRE_ACCEPT_CHANNEL:
case WIRE_FUNDING_CREATED:
case WIRE_FUNDING_SIGNED:
case WIRE_CHANNEL_REESTABLISH:
case WIRE_CLOSING_SIGNED:
break;

case WIRE_CHANNEL_REESTABLISH:
handle_unexpected_reestablish(peer, msg);
return;

/* These are all swallowed by handle_peer_gossip_or_error */
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
Expand Down

0 comments on commit a1ba214

Please sign in to comment.