routing: Return boolean from handle_channel_announcement

This will later be used to determine whether or not we should announce
ourselves as a node.

Signed-off-by: Christian Decker <decker.christian@gmail.com>
This commit is contained in:
Christian Decker 2017-11-24 15:47:14 +01:00 committed by Rusty Russell
parent b5f737e563
commit ba45ccffd8
3 changed files with 94 additions and 16 deletions

View File

@ -31,6 +31,7 @@
#include <gossipd/handshake.h>
#include <gossipd/routing.h>
#include <hsmd/client.h>
#include <hsmd/gen_hsm_client_wire.h>
#include <inttypes.h>
#include <lightningd/gossip_msg.h>
#include <netdb.h>
@ -43,6 +44,7 @@
#include <unistd.h>
#include <wire/gen_peer_wire.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>
#define HSM_FD 3
@ -371,12 +373,69 @@ static struct io_plan *owner_msg_in(struct io_conn *conn,
static struct io_plan *nonlocal_dump_gossip(struct io_conn *conn,
struct daemon_conn *dc);
static void handle_gossip_msg(struct routing_state *rstate, u8 *msg)
/* Create a node_announcement with the given signature. It may be NULL
* in the case we need to create a provisional announcement for the
* HSM to sign. This is typically called twice: once with the dummy
* signature to get it signed and a second time to build the full
* packet with the signature. The timestamp is handed in since that is
* the only thing that may change between the dummy creation and the
* call with a signature.*/
static u8 *create_node_announcement(const tal_t *ctx, struct daemon *daemon,
secp256k1_ecdsa_signature *sig,
u32 timestamp)
{
u8 *features = NULL;
u8 *addresses = tal_arr(ctx, u8, 0);
u8 *announcement;
size_t i;
if (!sig) {
sig = tal(ctx, secp256k1_ecdsa_signature);
memset(sig, 0, sizeof(*sig));
}
for (i = 0; i < tal_count(daemon->wireaddrs); i++)
towire_wireaddr(&addresses, daemon->wireaddrs+i);
announcement =
towire_node_announcement(ctx, sig, features, timestamp,
&daemon->id, daemon->rgb, daemon->alias,
addresses);
return announcement;
}
static void send_node_announcement(struct daemon *daemon)
{
tal_t *tmpctx = tal_tmpctx(daemon);
u32 timestamp = time_now().ts.tv_sec;
secp256k1_ecdsa_signature sig;
u8 *msg, *nannounce = create_node_announcement(tmpctx, daemon, NULL, timestamp);
if (!wire_sync_write(HSM_FD, take(towire_hsm_node_announcement_sig_req(tmpctx, nannounce))))
status_failed(STATUS_FAIL_MASTER_IO, "Could not write to HSM: %s", strerror(errno));
msg = wire_sync_read(tmpctx, HSM_FD);
if (!fromwire_hsm_node_announcement_sig_reply(msg, NULL, &sig))
status_failed(STATUS_FAIL_MASTER_IO, "HSM returned an invalid node_announcement sig");
/* We got the signature for out provisional node_announcement back
* from the HSM, create the real announcement and forward it to
* gossipd so it can take care of forwarding it. */
nannounce = create_node_announcement(tmpctx, daemon, &sig, timestamp);
handle_node_announcement(daemon->rstate, take(nannounce), tal_len(nannounce));
tal_free(tmpctx);
}
static void handle_gossip_msg(struct daemon *daemon, u8 *msg)
{
struct routing_state *rstate = daemon->rstate;
int t = fromwire_peektype(msg);
switch(t) {
case WIRE_CHANNEL_ANNOUNCEMENT:
handle_channel_announcement(rstate, msg, tal_count(msg));
/* Add the channel_announcement to the routing state,
* it'll tell us whether this is local and signed, so
* we can hand in a node_announcement as well. */
if(handle_channel_announcement(rstate, msg, tal_count(msg))) {
send_node_announcement(daemon);
}
break;
case WIRE_NODE_ANNOUNCEMENT:
@ -489,7 +548,7 @@ static struct io_plan *peer_msgin(struct io_conn *conn,
case WIRE_CHANNEL_ANNOUNCEMENT:
case WIRE_NODE_ANNOUNCEMENT:
case WIRE_CHANNEL_UPDATE:
handle_gossip_msg(peer->daemon->rstate, msg);
handle_gossip_msg(peer->daemon, msg);
return peer_next_in(conn, peer);
case WIRE_PING:
@ -661,7 +720,7 @@ static struct io_plan *owner_msg_in(struct io_conn *conn,
int type = fromwire_peektype(msg);
if (type == WIRE_CHANNEL_ANNOUNCEMENT || type == WIRE_CHANNEL_UPDATE ||
type == WIRE_NODE_ANNOUNCEMENT) {
handle_gossip_msg(peer->daemon->rstate, dc->msg_in);
handle_gossip_msg(peer->daemon, dc->msg_in);
} else if (type == WIRE_GOSSIP_GET_UPDATE) {
handle_get_update(peer, dc->msg_in);
}
@ -1161,7 +1220,7 @@ static void handle_forwarded_msg(struct io_conn *conn, struct daemon *daemon, co
if (!fromwire_gossip_forwarded_msg(msg, msg, NULL, &payload))
master_badmsg(WIRE_GOSSIP_FORWARDED_MSG, msg);
handle_gossip_msg(daemon->rstate, payload);
handle_gossip_msg(daemon, payload);
}
static struct io_plan *handshake_out_success(struct io_conn *conn,

View File

@ -463,12 +463,12 @@ static bool check_channel_announcement(
check_signed_hash(&hash, bitcoin2_sig, bitcoin2_key);
}
void handle_channel_announcement(
bool handle_channel_announcement(
struct routing_state *rstate,
const u8 *announce, size_t len)
{
u8 *serialized;
bool forward = false;
bool forward = false, local, sigfail;
secp256k1_ecdsa_signature node_signature_1;
secp256k1_ecdsa_signature node_signature_2;
struct short_channel_id short_channel_id;
@ -493,7 +493,7 @@ void handle_channel_announcement(
&node_id_1, &node_id_2,
&bitcoin_key_1, &bitcoin_key_2)) {
tal_free(tmpctx);
return;
return false;
}
/* BOLT #7:
@ -507,7 +507,7 @@ void handle_channel_announcement(
type_to_string(tmpctx, struct sha256_double,
&chain_hash));
tal_free(tmpctx);
return;
return false;
}
// FIXME: Check features!
@ -517,24 +517,31 @@ void handle_channel_announcement(
type_to_string(trc, struct short_channel_id,
&short_channel_id));
if (!check_channel_announcement(&node_id_1, &node_id_2, &bitcoin_key_1,
&bitcoin_key_2, &node_signature_1,
&node_signature_2, &bitcoin_signature_1,
&bitcoin_signature_2, serialized)) {
local = pubkey_eq(&node_id_1, &rstate->local_id) ||
pubkey_eq(&node_id_2, &rstate->local_id);
sigfail = !check_channel_announcement(
&node_id_1, &node_id_2, &bitcoin_key_1, &bitcoin_key_2,
&node_signature_1, &node_signature_2, &bitcoin_signature_1,
&bitcoin_signature_2, serialized);
if (sigfail && !local) {
status_trace(
"Signature verification of channel announcement failed");
tal_free(tmpctx);
return;
return false;
}
forward |= add_channel_direction(rstate, &node_id_1, &node_id_2,
&short_channel_id, serialized);
forward |= add_channel_direction(rstate, &node_id_2, &node_id_1,
&short_channel_id, serialized);
if (!forward) {
status_trace("Not forwarding channel_announcement");
tal_free(tmpctx);
return;
/* This will not be forwarded so we do not want to
* announce the node either, others might drop it. */
return false;
}
u8 *tag = tal_arr(tmpctx, u8, 0);
@ -543,6 +550,7 @@ void handle_channel_announcement(
tag, serialized);
tal_free(tmpctx);
return local;
}
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len)

View File

@ -83,6 +83,9 @@ struct routing_state {
struct broadcast_state *broadcasts;
struct sha256_double chain_hash;
/* Our own ID so we can identify local channels */
struct pubkey local_id;
};
struct route_hop {
@ -117,7 +120,15 @@ struct node_connection *get_connection_by_scid(const struct routing_state *rstat
const u8 direction);
/* Handlers for incoming messages */
void handle_channel_announcement(struct routing_state *rstate, const u8 *announce, size_t len);
/**
* handle_channel_announcement -- Add channel announcement to state
*
* Returns true if the channel was fully signed and is local. This
* means that if we haven't sent a node_announcement just yet, now
* would be a good time.
*/
bool handle_channel_announcement(struct routing_state *rstate, const u8 *announce, size_t len);
void handle_channel_update(struct routing_state *rstate, const u8 *update, size_t len);
void handle_node_announcement(struct routing_state *rstate, const u8 *node, size_t len);