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, msg = handle_channel_update(daemon->rstate, update,
find_peer(daemon, find_peer(daemon,
&chan->nodes[!direction]->id), &chan->nodes[!direction]->id),
NULL); NULL, true);
if (msg) if (msg)
status_failed(STATUS_FAIL_INTERNAL_ERROR, status_failed(STATUS_FAIL_INTERNAL_ERROR,
"%s: rejected local channel update %s: %s", "%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: case WIRE_CHANNEL_UPDATE:
if (!routing_add_channel_update(rstate, if (!routing_add_channel_update(rstate,
take(msg), gs->len, take(msg), gs->len,
NULL)) { NULL, false)) {
bad = "Bad channel_update"; bad = "Bad channel_update";
goto badmsg; 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; unknown_scid.u64 = 0;
err = handle_channel_update(peer->daemon->rstate, msg, peer, err = handle_channel_update(peer->daemon->rstate, msg, peer,
&unknown_scid); &unknown_scid, false);
if (err) { if (err) {
if (unknown_scid.u64 != 0) if (unknown_scid.u64 != 0)
query_unknown_channel(peer->daemon, peer, &unknown_scid); 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, channel_update),
tal_hex(tmpctx, error)); tal_hex(tmpctx, error));
u8 *err = handle_channel_update(daemon->rstate, channel_update, u8 *err = handle_channel_update(daemon->rstate, channel_update,
NULL, NULL); NULL, NULL, true);
if (err) { if (err) {
status_info("extracted bad channel_update %s from onionreply %s", status_info("extracted bad channel_update %s from onionreply %s",
sanitize_error(err, err, NULL), 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 we had private updates, they'll immediately create the channel. */
if (private_updates[0]) if (private_updates[0])
routing_add_channel_update(rstate, take(private_updates[0]), 0, routing_add_channel_update(rstate, take(private_updates[0]), 0,
peer); peer, false);
if (private_updates[1]) if (private_updates[1])
routing_add_channel_update(rstate, take(private_updates[1]), 0, routing_add_channel_update(rstate, take(private_updates[1]), 0,
peer); peer, false);
return true; return true;
} }
@ -1872,7 +1872,7 @@ static void process_pending_channel_update(struct daemon *daemon,
if (!cupdate) if (!cupdate)
return; return;
err = handle_channel_update(rstate, cupdate, peer, NULL); err = handle_channel_update(rstate, cupdate, peer, NULL, false);
if (err) { if (err) {
/* FIXME: We could send this error back to peer if != NULL */ /* FIXME: We could send this error back to peer if != NULL */
status_peer_debug(peer ? &peer->id : 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, bool routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES, const u8 *update TAKES,
u32 index, u32 index,
struct peer *peer) struct peer *peer,
bool ignore_timestamp)
{ {
secp256k1_ecdsa_signature signature; secp256k1_ecdsa_signature signature;
struct short_channel_id short_channel_id; struct short_channel_id short_channel_id;
@ -2111,7 +2112,7 @@ bool routing_add_channel_update(struct routing_state *rstate,
/* Discard older updates */ /* Discard older updates */
hc = &chan->half[direction]; 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 we're loading from store, duplicate entries are a bug. */
if (index != 0) { if (index != 0) {
status_broken("gossip_store channel_update %u replaces %u!", 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, 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, type_to_string(tmpctx, struct short_channel_id,
&short_channel_id), &short_channel_id),
channel_flags & 0x01, 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, u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
struct peer *peer, struct peer *peer,
struct short_channel_id *unknown_scid) struct short_channel_id *unknown_scid,
bool force)
{ {
u8 *serialized; u8 *serialized;
const struct node_id *owner; const struct node_id *owner;
@ -2376,7 +2379,7 @@ u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
return err; return err;
} }
routing_add_channel_update(rstate, take(serialized), 0, peer); routing_add_channel_update(rstate, take(serialized), 0, peer, force);
return NULL; 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). */ * (if not NULL). */
u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES, u8 *handle_channel_update(struct routing_state *rstate, const u8 *update TAKES,
struct peer *peer, 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. /* 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 * 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, bool routing_add_channel_update(struct routing_state *rstate,
const u8 *update TAKES, const u8 *update TAKES,
u32 index, u32 index,
struct peer *peer); struct peer *peer,
bool ignore_timestamp);
/** /**
* Add a node_announcement to the network view without checking it * 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 */ /* Generated stub for handle_channel_update */
u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *update TAKES UNNEEDED, u8 *handle_channel_update(struct routing_state *rstate UNNEEDED, const u8 *update TAKES UNNEEDED,
struct peer *peer 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(); } { fprintf(stderr, "handle_channel_update called!\n"); abort(); }
/* Generated stub for handle_node_announcement */ /* Generated stub for handle_node_announcement */
u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED, u8 *handle_node_announcement(struct routing_state *rstate UNNEEDED, const u8 *node UNNEEDED,

Loading…
Cancel
Save