Browse Source

gossipd: reorder functions into related groups (MOVEONLY)

It's MOVEONLY but for the removal of the '#ifndef TESTING' which was
needed for old test code.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
trytravis
Rusty Russell 6 years ago
parent
commit
1bd76861fd
  1. 572
      gossipd/gossipd.c

572
gossipd/gossipd.c

@ -169,6 +169,39 @@ static struct peer *find_peer(struct daemon *daemon, const struct pubkey *id)
return NULL;
}
static void queue_peer_msg(struct peer *peer, const u8 *msg TAKES)
{
const u8 *send = towire_gossip_send_gossip(NULL, msg);
if (taken(msg))
tal_free(msg);
daemon_conn_send(peer->dc, take(send));
}
static void wake_gossip_out(struct peer *peer)
{
/* If we were waiting, we're not any more */
peer->gossip_timer = tal_free(peer->gossip_timer);
/* Notify the daemon_conn-write loop */
daemon_conn_wake(peer->dc);
}
static void peer_error(struct peer *peer, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
status_trace("peer %s: %s",
type_to_string(tmpctx, struct pubkey, &peer->id),
tal_vfmt(tmpctx, fmt, ap));
va_end(ap);
/* Send error: we'll close after writing this. */
va_start(ap, fmt);
queue_peer_msg(peer, take(towire_errorfmtv(peer, NULL, fmt, ap)));
va_end(ap);
}
static u8 *encode_short_channel_ids_start(const tal_t *ctx)
{
u8 *encoded = tal_arr(ctx, u8, 0);
@ -231,39 +264,6 @@ check_length:
return tal_count(*encoded) <= max_bytes;
}
static void queue_peer_msg(struct peer *peer, const u8 *msg TAKES)
{
const u8 *send = towire_gossip_send_gossip(NULL, msg);
if (taken(msg))
tal_free(msg);
daemon_conn_send(peer->dc, take(send));
}
static void wake_gossip_out(struct peer *peer)
{
/* If we were waiting, we're not any more */
peer->gossip_timer = tal_free(peer->gossip_timer);
/* Notify the daemon_conn-write loop */
daemon_conn_wake(peer->dc);
}
static void peer_error(struct peer *peer, const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
status_trace("peer %s: %s",
type_to_string(tmpctx, struct pubkey, &peer->id),
tal_vfmt(tmpctx, fmt, ap));
va_end(ap);
/* Send error: we'll close after writing this. */
va_start(ap, fmt);
queue_peer_msg(peer, take(towire_errorfmtv(peer, NULL, fmt, ap)));
va_end(ap);
}
static void setup_gossip_range(struct peer *peer)
{
u8 *msg;
@ -278,8 +278,6 @@ static void setup_gossip_range(struct peer *peer)
queue_peer_msg(peer, take(msg));
}
static bool dump_gossip(struct peer *peer);
/* 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
@ -642,61 +640,6 @@ static void handle_query_channel_range(struct peer *peer, const u8 *msg)
queue_channel_ranges(peer, first_blocknum, number_of_blocks);
}
static void handle_ping(struct peer *peer, const u8 *ping)
{
u8 *pong;
if (!check_ping_make_pong(NULL, ping, &pong)) {
peer_error(peer, "Bad ping");
return;
}
if (pong)
queue_peer_msg(peer, take(pong));
}
static void handle_pong(struct peer *peer, const u8 *pong)
{
const char *err = got_pong(pong, &peer->num_pings_outstanding);
if (err) {
peer_error(peer, "%s", err);
return;
}
daemon_conn_send(peer->daemon->master,
take(towire_gossip_ping_reply(NULL, &peer->id, true,
tal_count(pong))));
}
static void handle_reply_short_channel_ids_end(struct peer *peer, const u8 *msg)
{
struct bitcoin_blkid chain;
u8 complete;
if (!fromwire_reply_short_channel_ids_end(msg, &chain, &complete)) {
peer_error(peer, "Bad reply_short_channel_ids_end %s",
tal_hex(tmpctx, msg));
return;
}
if (!bitcoin_blkid_eq(&peer->daemon->rstate->chain_hash, &chain)) {
peer_error(peer, "reply_short_channel_ids_end for bad chain: %s",
tal_hex(tmpctx, msg));
return;
}
if (peer->num_scid_queries_outstanding == 0) {
peer_error(peer, "unexpected reply_short_channel_ids_end: %s",
tal_hex(tmpctx, msg));
return;
}
peer->num_scid_queries_outstanding--;
msg = towire_gossip_scids_reply(msg, true, complete);
daemon_conn_send(peer->daemon->master, take(msg));
}
static void handle_reply_channel_range(struct peer *peer, const u8 *msg)
{
struct bitcoin_blkid chain;
@ -788,6 +731,61 @@ static void handle_reply_channel_range(struct peer *peer, const u8 *msg)
peer->query_channel_blocks = tal_free(peer->query_channel_blocks);
}
static void handle_ping(struct peer *peer, const u8 *ping)
{
u8 *pong;
if (!check_ping_make_pong(NULL, ping, &pong)) {
peer_error(peer, "Bad ping");
return;
}
if (pong)
queue_peer_msg(peer, take(pong));
}
static void handle_pong(struct peer *peer, const u8 *pong)
{
const char *err = got_pong(pong, &peer->num_pings_outstanding);
if (err) {
peer_error(peer, "%s", err);
return;
}
daemon_conn_send(peer->daemon->master,
take(towire_gossip_ping_reply(NULL, &peer->id, true,
tal_count(pong))));
}
static void handle_reply_short_channel_ids_end(struct peer *peer, const u8 *msg)
{
struct bitcoin_blkid chain;
u8 complete;
if (!fromwire_reply_short_channel_ids_end(msg, &chain, &complete)) {
peer_error(peer, "Bad reply_short_channel_ids_end %s",
tal_hex(tmpctx, msg));
return;
}
if (!bitcoin_blkid_eq(&peer->daemon->rstate->chain_hash, &chain)) {
peer_error(peer, "reply_short_channel_ids_end for bad chain: %s",
tal_hex(tmpctx, msg));
return;
}
if (peer->num_scid_queries_outstanding == 0) {
peer_error(peer, "unexpected reply_short_channel_ids_end: %s",
tal_hex(tmpctx, msg));
return;
}
peer->num_scid_queries_outstanding--;
msg = towire_gossip_scids_reply(msg, true, complete);
daemon_conn_send(peer->daemon->master, take(msg));
}
/* Arbitrary ordering function of pubkeys.
*
* Note that we could use memcmp() here: even if they had somehow different
@ -940,6 +938,19 @@ static bool maybe_queue_gossip(struct peer *peer)
return false;
}
/**
* dump_gossip - catch the peer up with the latest gossip.
*/
static bool dump_gossip(struct peer *peer)
{
/* Do we have scid query replies to send? */
if (create_next_scid_reply(peer))
return true;
/* Otherwise queue any gossip we want to send */
return maybe_queue_gossip(peer);
}
static void update_local_channel(struct daemon *daemon,
const struct chan *chan,
int direction,
@ -1319,46 +1330,198 @@ done:
return daemon_conn_read_next(conn, daemon->connectd);
}
/**
* dump_gossip - catch the peer up with the latest gossip.
*/
static bool dump_gossip(struct peer *peer)
static struct io_plan *connectd_get_address(struct io_conn *conn,
struct daemon *daemon,
const u8 *msg)
{
/* Do we have scid query replies to send? */
if (create_next_scid_reply(peer))
return true;
struct pubkey id;
struct node *node;
const struct wireaddr *addrs;
/* Otherwise queue any gossip we want to send */
return maybe_queue_gossip(peer);
if (!fromwire_gossip_get_addrs(msg, &id)) {
status_broken("Bad gossip_get_addrs msg from connectd: %s",
tal_hex(tmpctx, msg));
return io_close(conn);
}
node = get_node(daemon->rstate, &id);
if (node)
addrs = node->addresses;
else
addrs = NULL;
daemon_conn_send(daemon->connectd,
take(towire_gossip_get_addrs_reply(NULL, addrs)));
return daemon_conn_read_next(conn, daemon->connectd);
}
static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
static struct io_plan *connectd_req(struct io_conn *conn,
const u8 *msg,
struct daemon *daemon)
{
struct pubkey source, destination;
u64 msatoshi;
u32 final_cltv;
u16 riskfactor;
u8 *out;
struct route_hop *hops;
double fuzz;
struct siphash_seed seed;
enum connect_gossip_wire_type t = fromwire_peektype(msg);
if (!fromwire_gossip_getroute_request(msg,
&source, &destination,
&msatoshi, &riskfactor,
&final_cltv, &fuzz, &seed))
master_badmsg(WIRE_GOSSIP_GETROUTE_REQUEST, msg);
switch (t) {
case WIRE_GOSSIP_NEW_PEER:
return connectd_new_peer(conn, daemon, msg);
status_trace("Trying to find a route from %s to %s for %"PRIu64" msatoshi",
pubkey_to_hexstr(tmpctx, &source),
pubkey_to_hexstr(tmpctx, &destination), msatoshi);
case WIRE_GOSSIP_GET_ADDRS:
return connectd_get_address(conn, daemon, msg);
hops = get_route(tmpctx, daemon->rstate, &source, &destination,
msatoshi, riskfactor, final_cltv,
fuzz, &seed);
/* We send these, don't receive them. */
case WIRE_GOSSIP_NEW_PEER_REPLY:
case WIRE_GOSSIP_GET_ADDRS_REPLY:
break;
}
out = towire_gossip_getroute_reply(msg, hops);
status_broken("Bad msg from connectd: %s",
tal_hex(tmpctx, msg));
return io_close(conn);
}
static void gossip_send_keepalive_update(struct daemon *daemon,
const struct chan *chan,
const struct half_chan *hc)
{
status_trace("Sending keepalive channel_update for %s",
type_to_string(tmpctx, struct short_channel_id,
&chan->scid));
/* As a side-effect, this will create an update which matches the
* local_disabled state */
update_local_channel(daemon, chan,
hc->channel_flags & ROUTING_FLAGS_DIRECTION,
chan->local_disabled,
hc->delay,
hc->htlc_minimum_msat,
hc->base_fee,
hc->proportional_fee,
hc->htlc_maximum_msat,
__func__);
}
static void gossip_refresh_network(struct daemon *daemon)
{
u64 now = time_now().ts.tv_sec;
/* Anything below this highwater mark could be pruned if not refreshed */
s64 highwater = now - daemon->rstate->prune_timeout / 2;
struct node *n;
/* Schedule next run now */
new_reltimer(&daemon->timers, daemon,
time_from_sec(daemon->rstate->prune_timeout/4),
gossip_refresh_network, daemon);
/* Find myself in the network */
n = get_node(daemon->rstate, &daemon->id);
if (n) {
/* Iterate through all outgoing connection and check whether
* it's time to re-announce */
for (size_t i = 0; i < tal_count(n->chans); i++) {
struct half_chan *hc = half_chan_from(n, n->chans[i]);
if (!is_halfchan_defined(hc)) {
/* Connection is not announced yet, so don't even
* try to re-announce it */
continue;
}
if (hc->last_timestamp > highwater) {
/* No need to send a keepalive update message */
continue;
}
if (!is_halfchan_enabled(hc)) {
/* Only send keepalives for active connections */
continue;
}
gossip_send_keepalive_update(daemon, n->chans[i], hc);
}
}
route_prune(daemon->rstate);
}
static void gossip_disable_local_channels(struct daemon *daemon)
{
struct node *local_node = get_node(daemon->rstate, &daemon->id);
/* We don't have a local_node, so we don't have any channels yet
* either */
if (!local_node)
return;
for (size_t i = 0; i < tal_count(local_node->chans); i++)
local_node->chans[i]->local_disabled = true;
}
/* Parse an incoming gossip init message and assign config variables
* to the daemon.
*/
static struct io_plan *gossip_init(struct io_conn *conn,
struct daemon *daemon,
const u8 *msg)
{
struct bitcoin_blkid chain_hash;
u32 update_channel_interval;
if (!fromwire_gossipctl_init(
daemon, msg, &daemon->broadcast_interval_msec, &chain_hash,
&daemon->id, &daemon->globalfeatures,
daemon->rgb,
daemon->alias, &update_channel_interval,
&daemon->announcable)) {
master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
}
/* Prune time is twice update time */
daemon->rstate = new_routing_state(daemon, &chain_hash, &daemon->id,
update_channel_interval * 2);
/* Load stored gossip messages */
gossip_store_load(daemon->rstate, daemon->rstate->store);
/* Now disable all local channels, they can't be connected yet. */
gossip_disable_local_channels(daemon);
/* If that announced channels, we can announce ourselves (options
* or addresses might have changed!) */
maybe_send_own_node_announce(daemon);
new_reltimer(&daemon->timers, daemon,
time_from_sec(daemon->rstate->prune_timeout/4),
gossip_refresh_network, daemon);
return daemon_conn_read_next(conn, daemon->master);
}
static struct io_plan *getroute_req(struct io_conn *conn, struct daemon *daemon,
const u8 *msg)
{
struct pubkey source, destination;
u64 msatoshi;
u32 final_cltv;
u16 riskfactor;
u8 *out;
struct route_hop *hops;
double fuzz;
struct siphash_seed seed;
if (!fromwire_gossip_getroute_request(msg,
&source, &destination,
&msatoshi, &riskfactor,
&final_cltv, &fuzz, &seed))
master_badmsg(WIRE_GOSSIP_GETROUTE_REQUEST, msg);
status_trace("Trying to find a route from %s to %s for %"PRIu64" msatoshi",
pubkey_to_hexstr(tmpctx, &source),
pubkey_to_hexstr(tmpctx, &destination), msatoshi);
hops = get_route(tmpctx, daemon->rstate, &source, &destination,
msatoshi, riskfactor, final_cltv,
fuzz, &seed);
out = towire_gossip_getroute_reply(msg, hops);
daemon_conn_send(daemon->master, out);
return daemon_conn_read_next(conn, daemon->master);
}
@ -1741,122 +1904,6 @@ static struct io_plan *dev_gossip_suppress(struct io_conn *conn,
}
#endif /* DEVELOPER */
static void gossip_send_keepalive_update(struct daemon *daemon,
const struct chan *chan,
const struct half_chan *hc)
{
status_trace("Sending keepalive channel_update for %s",
type_to_string(tmpctx, struct short_channel_id,
&chan->scid));
/* As a side-effect, this will create an update which matches the
* local_disabled state */
update_local_channel(daemon, chan,
hc->channel_flags & ROUTING_FLAGS_DIRECTION,
chan->local_disabled,
hc->delay,
hc->htlc_minimum_msat,
hc->base_fee,
hc->proportional_fee,
hc->htlc_maximum_msat,
__func__);
}
static void gossip_refresh_network(struct daemon *daemon)
{
u64 now = time_now().ts.tv_sec;
/* Anything below this highwater mark could be pruned if not refreshed */
s64 highwater = now - daemon->rstate->prune_timeout / 2;
struct node *n;
/* Schedule next run now */
new_reltimer(&daemon->timers, daemon,
time_from_sec(daemon->rstate->prune_timeout/4),
gossip_refresh_network, daemon);
/* Find myself in the network */
n = get_node(daemon->rstate, &daemon->id);
if (n) {
/* Iterate through all outgoing connection and check whether
* it's time to re-announce */
for (size_t i = 0; i < tal_count(n->chans); i++) {
struct half_chan *hc = half_chan_from(n, n->chans[i]);
if (!is_halfchan_defined(hc)) {
/* Connection is not announced yet, so don't even
* try to re-announce it */
continue;
}
if (hc->last_timestamp > highwater) {
/* No need to send a keepalive update message */
continue;
}
if (!is_halfchan_enabled(hc)) {
/* Only send keepalives for active connections */
continue;
}
gossip_send_keepalive_update(daemon, n->chans[i], hc);
}
}
route_prune(daemon->rstate);
}
static void gossip_disable_local_channels(struct daemon *daemon)
{
struct node *local_node = get_node(daemon->rstate, &daemon->id);
/* We don't have a local_node, so we don't have any channels yet
* either */
if (!local_node)
return;
for (size_t i = 0; i < tal_count(local_node->chans); i++)
local_node->chans[i]->local_disabled = true;
}
/* Parse an incoming gossip init message and assign config variables
* to the daemon.
*/
static struct io_plan *gossip_init(struct io_conn *conn,
struct daemon *daemon,
const u8 *msg)
{
struct bitcoin_blkid chain_hash;
u32 update_channel_interval;
if (!fromwire_gossipctl_init(
daemon, msg, &daemon->broadcast_interval_msec, &chain_hash,
&daemon->id, &daemon->globalfeatures,
daemon->rgb,
daemon->alias, &update_channel_interval,
&daemon->announcable)) {
master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
}
/* Prune time is twice update time */
daemon->rstate = new_routing_state(daemon, &chain_hash, &daemon->id,
update_channel_interval * 2);
/* Load stored gossip messages */
gossip_store_load(daemon->rstate, daemon->rstate->store);
/* Now disable all local channels, they can't be connected yet. */
gossip_disable_local_channels(daemon);
/* If that announced channels, we can announce ourselves (options
* or addresses might have changed!) */
maybe_send_own_node_announce(daemon);
new_reltimer(&daemon->timers, daemon,
time_from_sec(daemon->rstate->prune_timeout/4),
gossip_refresh_network, daemon);
return daemon_conn_read_next(conn, daemon->master);
}
static struct io_plan *get_channel_peer(struct io_conn *conn,
struct daemon *daemon, const u8 *msg)
{
@ -2082,56 +2129,6 @@ static struct io_plan *recv_req(struct io_conn *conn,
t, tal_hex(tmpctx, msg));
}
static struct io_plan *connectd_get_address(struct io_conn *conn,
struct daemon *daemon,
const u8 *msg)
{
struct pubkey id;
struct node *node;
const struct wireaddr *addrs;
if (!fromwire_gossip_get_addrs(msg, &id)) {
status_broken("Bad gossip_get_addrs msg from connectd: %s",
tal_hex(tmpctx, msg));
return io_close(conn);
}
node = get_node(daemon->rstate, &id);
if (node)
addrs = node->addresses;
else
addrs = NULL;
daemon_conn_send(daemon->connectd,
take(towire_gossip_get_addrs_reply(NULL, addrs)));
return daemon_conn_read_next(conn, daemon->connectd);
}
static struct io_plan *connectd_req(struct io_conn *conn,
const u8 *msg,
struct daemon *daemon)
{
enum connect_gossip_wire_type t = fromwire_peektype(msg);
switch (t) {
case WIRE_GOSSIP_NEW_PEER:
return connectd_new_peer(conn, daemon, msg);
case WIRE_GOSSIP_GET_ADDRS:
return connectd_get_address(conn, daemon, msg);
/* We send these, don't receive them. */
case WIRE_GOSSIP_NEW_PEER_REPLY:
case WIRE_GOSSIP_GET_ADDRS_REPLY:
break;
}
status_broken("Bad msg from connectd: %s",
tal_hex(tmpctx, msg));
return io_close(conn);
}
#ifndef TESTING
static void master_gone(struct daemon_conn *master UNUSED)
{
/* Can't tell master, it's gone. */
@ -2172,4 +2169,3 @@ int main(int argc, char *argv[])
daemon_shutdown();
return 0;
}
#endif

Loading…
Cancel
Save