diff --git a/openingd/opening.c b/openingd/opening.c index aee1581f4..9cf087c48 100644 --- a/openingd/opening.c +++ b/openingd/opening.c @@ -66,7 +66,8 @@ struct state { }; /* For negotiation failures: we can still gossip with client. */ -static void negotiation_failed(struct state *state, const char *fmt, ...) +static void negotiation_failed(struct state *state, bool send_error, + const char *fmt, ...) { va_list ap; const char *errmsg; @@ -79,9 +80,12 @@ static void negotiation_failed(struct state *state, const char *fmt, ...) /* Make sure it's correct length for towire_. */ tal_resize(&errmsg, strlen(errmsg)+1); - /* Tell peer we're bailing on this channel. */ - msg = towire_errorfmt(errmsg, &state->channel_id, "%s", errmsg); - sync_crypto_write(&state->cs, PEER_FD, take(msg)); + /* We don't send error in response to their error packet. */ + if (send_error) { + /* Tell peer we're bailing on this channel. */ + msg = towire_errorfmt(errmsg, &state->channel_id, "%s", errmsg); + sync_crypto_write(&state->cs, PEER_FD, take(msg)); + } /* Tell master we should return to gossiping. */ msg = towire_opening_negotiation_failed(state, &state->cs, @@ -105,7 +109,7 @@ static void check_config_bounds(struct state *state, * unreasonably large. */ if (remoteconf->to_self_delay > state->max_to_self_delay) - negotiation_failed(state, + negotiation_failed(state, true, "to_self_delay %u larger than %u", remoteconf->to_self_delay, state->max_to_self_delay); @@ -123,7 +127,7 @@ static void check_config_bounds(struct state *state, /* Overflow check before capacity calc. */ if (remoteconf->channel_reserve_satoshis > state->funding_satoshis) - negotiation_failed(state, + negotiation_failed(state, true, "Invalid channel_reserve_satoshis %"PRIu64 " for funding_satoshis %"PRIu64, remoteconf->channel_reserve_satoshis, @@ -140,7 +144,7 @@ static void check_config_bounds(struct state *state, capacity_msat = remoteconf->max_htlc_value_in_flight_msat; if (remoteconf->htlc_minimum_msat * (u64)1000 > capacity_msat) - negotiation_failed(state, + negotiation_failed(state, true, "Invalid htlc_minimum_msat %"PRIu64 " for funding_satoshis %"PRIu64 " capacity_msat %"PRIu64, @@ -149,7 +153,7 @@ static void check_config_bounds(struct state *state, capacity_msat); if (capacity_msat < state->min_effective_htlc_capacity_msat) - negotiation_failed(state, + negotiation_failed(state, true, "Channel capacity with funding %"PRIu64" msat," " reserves %"PRIu64"/%"PRIu64" msat," " max_htlc_value_in_flight_msat %"PRIu64 @@ -163,7 +167,7 @@ static void check_config_bounds(struct state *state, /* We don't worry about how many HTLCs they accept, as long as > 0! */ if (remoteconf->max_accepted_htlcs == 0) - negotiation_failed(state, + negotiation_failed(state, true, "max_accepted_htlcs %u invalid", remoteconf->max_accepted_htlcs); @@ -220,6 +224,33 @@ static u8 *read_next_peer_msg(struct state *state, const tal_t *ctx) if (!wire_sync_write(GOSSIP_FD, take(msg))) status_failed(STATUS_FAIL_PEER_IO, "Relaying gossip message"); + } else if (fromwire_peektype(msg) == WIRE_ERROR) { + struct channel_id chanid; + char *err = sanitize_error(msg, msg, &chanid); + + /* BOLT #1: + * + * The channel is referred to by `channel_id`, unless + * `channel_id` is 0 (i.e. all bytes are 0), in which + * case it refers to all channels. + * ... + + * The receiving node: + * - upon receiving `error`: + * - MUST fail the channel referred to by the error + * message. + * - if no existing channel is referred to by the + * message: + * - MUST ignore the message. + */ + if (channel_id_is_all(&chanid)) + peer_failed(PEER_FD, &state->cs, + &state->channel_id, + "Error packet: %s", err); + + if (structeq(&chanid, &state->channel_id)) + negotiation_failed(state, false, + "Error packet: %s", err); } else { return msg; } @@ -344,7 +375,7 @@ static u8 *funder_channel(struct state *state, * `open_channel`. */ if (minimum_depth > max_minimum_depth) - negotiation_failed(state, + negotiation_failed(state, true, "minimum_depth %u larger than %u", minimum_depth, max_minimum_depth); check_config_bounds(state, state->remoteconf); @@ -537,7 +568,7 @@ static u8 *fundee_channel(struct state *state, * unknown to the receiver. */ if (!structeq(&chain_hash, &state->chainparams->genesis_blockhash)) { - negotiation_failed(state, + negotiation_failed(state, true, "Unknown chain-hash %s", type_to_string(peer_msg, struct sha256_double, @@ -570,12 +601,12 @@ static u8 *fundee_channel(struct state *state, * too small for timely processing, or unreasonably large. */ if (state->feerate_per_kw < min_feerate) - negotiation_failed(state, + negotiation_failed(state, true, "feerate_per_kw %u below minimum %u", state->feerate_per_kw, min_feerate); if (state->feerate_per_kw > max_feerate) - negotiation_failed(state, + negotiation_failed(state, true, "feerate_per_kw %u above maximum %u", state->feerate_per_kw, max_feerate);