Browse Source

gossipd: add an internal flag to force a channel update

This overcomes the internal spam filter on updates, which can be useful
if we're actually trying to send through such a node.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
Changelog-Fixed: Protocol: always accept channel_updates from errors, even they'd otherwise be rejected as spam.
Fixes: #4300
master
Rusty Russell 4 years ago
committed by Christian Decker
parent
commit
f1c599516e
  1. 2
      gossipd/gossip_generation.c
  2. 2
      gossipd/gossip_store.c
  3. 4
      gossipd/gossipd.c
  4. 19
      gossipd/routing.c
  5. 6
      gossipd/routing.h
  6. 3
      gossipd/test/run-crc32_of_update.c

2
gossipd/gossip_generation.c

@ -392,7 +392,7 @@ static void update_local_channel(struct local_cupdate *lc /* frees! */)
msg = handle_channel_update(daemon->rstate, update,
find_peer(daemon,
&chan->nodes[!direction]->id),
NULL);
NULL, true);
if (msg)
status_failed(STATUS_FAIL_INTERNAL_ERROR,
"%s: rejected local channel update %s: %s",

2
gossipd/gossip_store.c

@ -829,7 +829,7 @@ u32 gossip_store_load(struct routing_state *rstate, struct gossip_store *gs)
case WIRE_CHANNEL_UPDATE:
if (!routing_add_channel_update(rstate,
take(msg), gs->len,
NULL)) {
NULL, false)) {
bad = "Bad channel_update";
goto badmsg;
}

4
gossipd/gossipd.c

@ -268,7 +268,7 @@ static u8 *handle_channel_update_msg(struct peer *peer, const u8 *msg)
unknown_scid.u64 = 0;
err = handle_channel_update(peer->daemon->rstate, msg, peer,
&unknown_scid);
&unknown_scid, false);
if (err) {
if (unknown_scid.u64 != 0)
query_unknown_channel(peer->daemon, peer, &unknown_scid);
@ -1797,7 +1797,7 @@ static struct io_plan *handle_payment_failure(struct io_conn *conn,
tal_hex(tmpctx, channel_update),
tal_hex(tmpctx, error));
u8 *err = handle_channel_update(daemon->rstate, channel_update,
NULL, NULL);
NULL, NULL, true);
if (err) {
status_info("extracted bad channel_update %s from onionreply %s",
sanitize_error(err, err, NULL),

19
gossipd/routing.c

@ -1674,10 +1674,10 @@ bool routing_add_channel_announcement(struct routing_state *rstate,
/* If we had private updates, they'll immediately create the channel. */
if (private_updates[0])
routing_add_channel_update(rstate, take(private_updates[0]), 0,
peer);
peer, false);
if (private_updates[1])
routing_add_channel_update(rstate, take(private_updates[1]), 0,
peer);
peer, false);
return true;
}
@ -1872,7 +1872,7 @@ static void process_pending_channel_update(struct daemon *daemon,
if (!cupdate)
return;
err = handle_channel_update(rstate, cupdate, peer, NULL);
err = handle_channel_update(rstate, cupdate, peer, NULL, false);
if (err) {
/* FIXME: We could send this error back to peer if != NULL */
status_peer_debug(peer ? &peer->id : NULL,
@ -2021,7 +2021,8 @@ static void set_connection_values(struct chan *chan,
bool routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES,
u32 index,
struct peer *peer)
struct peer *peer,
bool ignore_timestamp)
{
secp256k1_ecdsa_signature signature;
struct short_channel_id short_channel_id;
@ -2111,7 +2112,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
/* Discard older updates */
hc = &chan->half[direction];
if (is_halfchan_defined(hc)) {
if (is_halfchan_defined(hc) && !ignore_timestamp) {
/* If we're loading from store, duplicate entries are a bug. */
if (index != 0) {
status_broken("gossip_store channel_update %u replaces %u!",
@ -2222,7 +2223,8 @@ bool routing_add_channel_update(struct routing_state *rstate,
}
status_peer_debug(peer ? &peer->id : NULL,
"Received channel_update for channel %s/%d now %s",
"Received %schannel_update for channel %s/%d now %s",
ignore_timestamp ? "(forced) " : "",
type_to_string(tmpctx, struct short_channel_id,
&short_channel_id),
channel_flags & 0x01,
@ -2281,7 +2283,8 @@ void remove_channel_from_store(struct routing_state *rstate,
u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
struct peer *peer,
struct short_channel_id *unknown_scid)
struct short_channel_id *unknown_scid,
bool force)
{
u8 *serialized;
const struct node_id *owner;
@ -2376,7 +2379,7 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
return err;
}
routing_add_channel_update(rstate, take(serialized), 0, peer);
routing_add_channel_update(rstate, take(serialized), 0, peer, force);
return NULL;
}

6
gossipd/routing.h

@ -402,7 +402,8 @@ struct chan *next_chan(const struct node *node, struct chan_map_iter *i);
* (if not NULL). */
u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
struct peer *peer,
struct short_channel_id *unknown_scid);
struct short_channel_id *unknown_scid,
bool force);
/* Returns NULL if all OK, otherwise an error for the peer which sent.
* If was_unknown is not NULL, sets it to true if that was the reason for
@ -456,7 +457,8 @@ bool routing_add_channel_announcement(struct routing_state *rstate,
bool routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES,
u32 index,
struct peer *peer);
struct peer *peer,
bool ignore_timestamp);
/**
* Add a node_announcement to the network view without checking it
*

3
gossipd/test/run-crc32_of_update.c

@ -58,7 +58,8 @@ struct timeabs gossip_time_now(const struct routing_state *rstate UNNEEDED)
/* Generated stub for handle_channel_update */
u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *update TAKES UNNEEDED,
struct peer *peer UNNEEDED,
struct short_channel_id *unknown_scid UNNEEDED)
struct short_channel_id *unknown_scid UNNEEDED,
bool force UNNEEDED)
{ fprintf(stderr, "handle_channel_update called!\n"); abort(); }
/* Generated stub for handle_node_announcement */
u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,

Loading…
Cancel
Save