gossipd: don't accept forwarding short_channel_ids we don't own.

Gossipd provided a generic "get endpoints of this scid" and we only
use it in one place: to look up htlc forwards.  But lightningd just
assumed that one would be us.

Instead, provide a simpler API which only returns the peer node
if any, and now we handle it much more gracefully.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2018-10-15 15:27:22 +10:30
parent 030fe1ce53
commit 3991425111
5 changed files with 35 additions and 49 deletions

View file

@ -93,13 +93,12 @@ gossip_query_channel_range_reply,,scids,num*struct short_channel_id
gossip_dev_set_max_scids_encode_size,3030 gossip_dev_set_max_scids_encode_size,3030
gossip_dev_set_max_scids_encode_size,,max,u32 gossip_dev_set_max_scids_encode_size,,max,u32
# Given a short_channel_id, return the endpoints # Given a short_channel_id, return the other endpoint (or none if DNE)
gossip_resolve_channel_request,3009 gossip_get_channel_peer,3009
gossip_resolve_channel_request,,channel_id,struct short_channel_id gossip_get_channel_peer,,channel_id,struct short_channel_id
gossip_resolve_channel_reply,3109 gossip_get_channel_peer_reply,3109
gossip_resolve_channel_reply,,num_keys,u16 gossip_get_channel_peer_reply,,peer_id,?struct pubkey
gossip_resolve_channel_reply,,keys,num_keys*struct pubkey
# Channel daemon can ask for updates for a specific channel, for sending # Channel daemon can ask for updates for a specific channel, for sending
# errors. Must be distinct from WIRE_CHANNEL_ANNOUNCEMENT etc. gossip msgs! # errors. Must be distinct from WIRE_CHANNEL_ANNOUNCEMENT etc. gossip msgs!

1 #include <common/cryptomsg.h>
93 gossip_get_update_reply,,update,len*u8 # Gossipd can tell channeld etc about gossip to fwd.
94 # Gossipd can tell channeld etc about gossip to fwd. gossip_send_gossip,3016
95 gossip_send_gossip,3016 gossip_send_gossip,,len,u16
96 gossip_send_gossip,,len,u16 gossip_send_gossip,,gossip,len*u8
97 gossip_send_gossip,,gossip,len*u8 # Both sides have seen the funding tx being locked, but we have not
98 # Both sides have seen the funding tx being locked, but we have not # yet reached the announcement depth. So we add the channel locally so
99 # yet reached the announcement depth. So we add the channel locally so # we (and peer) can update it already.
100 # we (and peer) can update it already. gossip_local_add_channel,3017
101 gossip_local_add_channel,3017 gossip_local_add_channel,,short_channel_id,struct short_channel_id
gossip_local_add_channel,,short_channel_id,struct short_channel_id
102 gossip_local_add_channel,,remote_node_id,struct pubkey
103 gossip_local_add_channel,,satoshis,u64
104 gossip_local_channel_update,3026

View file

@ -1846,32 +1846,32 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
return daemon_conn_read_next(master->conn, master); return daemon_conn_read_next(master->conn, master);
} }
static struct io_plan *resolve_channel_req(struct io_conn *conn, static struct io_plan *get_channel_peer(struct io_conn *conn,
struct daemon *daemon, const u8 *msg) struct daemon *daemon, const u8 *msg)
{ {
struct short_channel_id scid; struct short_channel_id scid;
struct chan *chan; struct chan *chan;
struct pubkey *keys; const struct pubkey *key;
int direction;
if (!fromwire_gossip_resolve_channel_request(msg, &scid)) if (!fromwire_gossip_get_channel_peer(msg, &scid))
master_badmsg(WIRE_GOSSIP_RESOLVE_CHANNEL_REQUEST, msg); master_badmsg(WIRE_GOSSIP_GET_CHANNEL_PEER, msg);
chan = get_channel(daemon->rstate, &scid); chan = get_channel(daemon->rstate, &scid);
if (!chan) { if (!chan) {
status_trace("Failed to resolve channel %s", status_trace("Failed to resolve channel %s",
type_to_string(tmpctx, struct short_channel_id, &scid)); type_to_string(tmpctx, struct short_channel_id, &scid));
keys = NULL; key = NULL;
} else if (local_direction(daemon, chan, &direction)) {
key = &chan->nodes[!direction]->id;
} else { } else {
keys = tal_arr(msg, struct pubkey, 2); status_trace("Resolved channel %s was not local",
keys[0] = chan->nodes[0]->id; type_to_string(tmpctx, struct short_channel_id,
keys[1] = chan->nodes[1]->id; &scid));
status_trace("Resolved channel %s %s<->%s", key = NULL;
type_to_string(tmpctx, struct short_channel_id, &scid),
type_to_string(tmpctx, struct pubkey, &keys[0]),
type_to_string(tmpctx, struct pubkey, &keys[1]));
} }
daemon_conn_send(&daemon->master, daemon_conn_send(&daemon->master,
take(towire_gossip_resolve_channel_reply(NULL, keys))); take(towire_gossip_get_channel_peer_reply(NULL, key)));
return daemon_conn_read_next(conn, &daemon->master); return daemon_conn_read_next(conn, &daemon->master);
} }
@ -2000,8 +2000,8 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_GETCHANNELS_REQUEST: case WIRE_GOSSIP_GETCHANNELS_REQUEST:
return getchannels_req(conn, daemon, daemon->master.msg_in); return getchannels_req(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_RESOLVE_CHANNEL_REQUEST: case WIRE_GOSSIP_GET_CHANNEL_PEER:
return resolve_channel_req(conn, daemon, daemon->master.msg_in); return get_channel_peer(conn, daemon, daemon->master.msg_in);
case WIRE_GOSSIP_GET_TXOUT_REPLY: case WIRE_GOSSIP_GET_TXOUT_REPLY:
return handle_txout_reply(conn, daemon, master->msg_in); return handle_txout_reply(conn, daemon, master->msg_in);
@ -2057,7 +2057,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
case WIRE_GOSSIP_PING_REPLY: case WIRE_GOSSIP_PING_REPLY:
case WIRE_GOSSIP_SCIDS_REPLY: case WIRE_GOSSIP_SCIDS_REPLY:
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY: case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY:
case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY: case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY:
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY: case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
case WIRE_GOSSIP_GET_UPDATE: case WIRE_GOSSIP_GET_UPDATE:
case WIRE_GOSSIP_GET_UPDATE_REPLY: case WIRE_GOSSIP_GET_UPDATE_REPLY:

View file

@ -106,7 +106,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIP_GETROUTE_REQUEST: case WIRE_GOSSIP_GETROUTE_REQUEST:
case WIRE_GOSSIP_GETCHANNELS_REQUEST: case WIRE_GOSSIP_GETCHANNELS_REQUEST:
case WIRE_GOSSIP_PING: case WIRE_GOSSIP_PING:
case WIRE_GOSSIP_RESOLVE_CHANNEL_REQUEST: case WIRE_GOSSIP_GET_CHANNEL_PEER:
case WIRE_GOSSIP_GET_UPDATE: case WIRE_GOSSIP_GET_UPDATE:
case WIRE_GOSSIP_SEND_GOSSIP: case WIRE_GOSSIP_SEND_GOSSIP:
case WIRE_GOSSIP_GET_TXOUT_REPLY: case WIRE_GOSSIP_GET_TXOUT_REPLY:
@ -126,7 +126,7 @@ static unsigned gossip_msg(struct subd *gossip, const u8 *msg, const int *fds)
case WIRE_GOSSIP_GETCHANNELS_REPLY: case WIRE_GOSSIP_GETCHANNELS_REPLY:
case WIRE_GOSSIP_SCIDS_REPLY: case WIRE_GOSSIP_SCIDS_REPLY:
case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY: case WIRE_GOSSIP_QUERY_CHANNEL_RANGE_REPLY:
case WIRE_GOSSIP_RESOLVE_CHANNEL_REPLY: case WIRE_GOSSIP_GET_CHANNEL_PEER_REPLY:
case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY: case WIRE_GOSSIP_GET_INCOMING_CHANNELS_REPLY:
/* These are inter-daemon messages, not received by us */ /* These are inter-daemon messages, not received by us */
case WIRE_GOSSIP_LOCAL_ADD_CHANNEL: case WIRE_GOSSIP_LOCAL_ADD_CHANNEL:

View file

@ -569,30 +569,18 @@ struct gossip_resolve {
static void channel_resolve_reply(struct subd *gossip, const u8 *msg, static void channel_resolve_reply(struct subd *gossip, const u8 *msg,
const int *fds UNUSED, struct gossip_resolve *gr) const int *fds UNUSED, struct gossip_resolve *gr)
{ {
struct pubkey *nodes, *peer_id; struct pubkey *peer_id;
if (!fromwire_gossip_resolve_channel_reply(msg, msg, &nodes)) { if (!fromwire_gossip_get_channel_peer_reply(msg, msg, &peer_id)) {
log_broken(gossip->log, log_broken(gossip->log,
"bad fromwire_gossip_resolve_channel_reply %s", "bad fromwire_gossip_get_channel_peer_reply %s",
tal_hex(msg, msg)); tal_hex(msg, msg));
return; return;
} }
if (tal_count(nodes) == 0) { if (!peer_id) {
local_fail_htlc(gr->hin, WIRE_UNKNOWN_NEXT_PEER, NULL); local_fail_htlc(gr->hin, WIRE_UNKNOWN_NEXT_PEER, NULL);
return; return;
} else if (tal_count(nodes) != 2) {
log_broken(gossip->log,
"fromwire_gossip_resolve_channel_reply has %zu nodes",
tal_count(nodes));
return;
}
/* Get the other peer matching the id that is not us */
if (pubkey_cmp(&nodes[0], &gossip->ld->id) == 0) {
peer_id = &nodes[1];
} else {
peer_id = &nodes[0];
} }
forward_htlc(gr->hin, gr->hin->cltv_expiry, forward_htlc(gr->hin, gr->hin->cltv_expiry,
@ -697,8 +685,7 @@ static bool peer_accepted_htlc(struct channel *channel,
gr->outgoing_cltv_value = rs->hop_data.outgoing_cltv; gr->outgoing_cltv_value = rs->hop_data.outgoing_cltv;
gr->hin = hin; gr->hin = hin;
req = towire_gossip_resolve_channel_request(tmpctx, req = towire_gossip_get_channel_peer(tmpctx, &gr->next_channel);
&gr->next_channel);
log_debug(channel->log, "Asking gossip to resolve channel %s", log_debug(channel->log, "Asking gossip to resolve channel %s",
type_to_string(tmpctx, struct short_channel_id, type_to_string(tmpctx, struct short_channel_id,
&gr->next_channel)); &gr->next_channel));

View file

@ -85,9 +85,9 @@ bool fromwire_channel_sending_commitsig(const tal_t *ctx UNNEEDED, const void *p
/* Generated stub for fromwire_connect_peer_connected */ /* Generated stub for fromwire_connect_peer_connected */
bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED) bool fromwire_connect_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr_internal *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u8 **globalfeatures UNNEEDED, u8 **localfeatures UNNEEDED)
{ fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); } { fprintf(stderr, "fromwire_connect_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_gossip_resolve_channel_reply */ /* Generated stub for fromwire_gossip_get_channel_peer_reply */
bool fromwire_gossip_resolve_channel_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **keys UNNEEDED) bool fromwire_gossip_get_channel_peer_reply(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, struct pubkey **peer_id UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_resolve_channel_reply called!\n"); abort(); } { fprintf(stderr, "fromwire_gossip_get_channel_peer_reply called!\n"); abort(); }
/* Generated stub for fromwire_hsm_sign_commitment_tx_reply */ /* Generated stub for fromwire_hsm_sign_commitment_tx_reply */
bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, secp256k1_ecdsa_signature *sig UNNEEDED) bool fromwire_hsm_sign_commitment_tx_reply(const void *p UNNEEDED, secp256k1_ecdsa_signature *sig UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_sign_commitment_tx_reply called!\n"); abort(); } { fprintf(stderr, "fromwire_hsm_sign_commitment_tx_reply called!\n"); abort(); }
@ -424,9 +424,9 @@ u8 *towire_errorfmt(const tal_t *ctx UNNEEDED,
const struct channel_id *channel UNNEEDED, const struct channel_id *channel UNNEEDED,
const char *fmt UNNEEDED, ...) const char *fmt UNNEEDED, ...)
{ fprintf(stderr, "towire_errorfmt called!\n"); abort(); } { fprintf(stderr, "towire_errorfmt called!\n"); abort(); }
/* Generated stub for towire_gossip_resolve_channel_request */ /* Generated stub for towire_gossip_get_channel_peer */
u8 *towire_gossip_resolve_channel_request(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED) u8 *towire_gossip_get_channel_peer(const tal_t *ctx UNNEEDED, const struct short_channel_id *channel_id UNNEEDED)
{ fprintf(stderr, "towire_gossip_resolve_channel_request called!\n"); abort(); } { fprintf(stderr, "towire_gossip_get_channel_peer called!\n"); abort(); }
/* Generated stub for towire_hsm_sign_commitment_tx */ /* Generated stub for towire_hsm_sign_commitment_tx */
u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 funding_amount UNNEEDED) u8 *towire_hsm_sign_commitment_tx(const tal_t *ctx UNNEEDED, const struct pubkey *peer_id UNNEEDED, u64 channel_dbid UNNEEDED, const struct bitcoin_tx *tx UNNEEDED, const struct pubkey *remote_funding_key UNNEEDED, u64 funding_amount UNNEEDED)
{ fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); } { fprintf(stderr, "towire_hsm_sign_commitment_tx called!\n"); abort(); }