mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 05:12:45 +01:00
gossipd: take over address determination, from master.
It does all the other address handling, do this too. It also proves useful as we clean up wildcard address handling. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
356e5dcea8
commit
e6c678e5df
@ -16,6 +16,7 @@ LIGHTNINGD_GOSSIP_HEADERS := gossipd/gen_gossip_wire.h \
|
||||
gossipd/gen_gossip_store.h \
|
||||
gossipd/gossip_store.h \
|
||||
gossipd/handshake.h \
|
||||
gossipd/netaddress.h \
|
||||
gossipd/routing.h \
|
||||
gossipd/broadcast.h
|
||||
LIGHTNINGD_GOSSIP_SRC := gossipd/gossip.c \
|
||||
|
@ -34,6 +34,7 @@
|
||||
#include <gossipd/broadcast.h>
|
||||
#include <gossipd/gen_gossip_wire.h>
|
||||
#include <gossipd/handshake.h>
|
||||
#include <gossipd/netaddress.h>
|
||||
#include <gossipd/routing.h>
|
||||
#include <hsmd/client.h>
|
||||
#include <hsmd/gen_hsm_client_wire.h>
|
||||
@ -1631,16 +1632,25 @@ static struct io_plan *gossip_activate(struct daemon_conn *master,
|
||||
const u8 *msg)
|
||||
{
|
||||
bool listen;
|
||||
bool guess_addrs;
|
||||
u16 port;
|
||||
|
||||
if (!fromwire_gossipctl_activate(msg, &listen))
|
||||
if (!fromwire_gossipctl_activate(msg, &listen, &guess_addrs, &port))
|
||||
master_badmsg(WIRE_GOSSIPCTL_ACTIVATE, msg);
|
||||
|
||||
if (listen)
|
||||
if (listen) {
|
||||
if (guess_addrs)
|
||||
guess_addresses(&daemon->wireaddrs,
|
||||
&daemon->listen_announce,
|
||||
port);
|
||||
setup_listeners(daemon);
|
||||
}
|
||||
|
||||
/* OK, we're ready! */
|
||||
daemon_conn_send(&daemon->master,
|
||||
take(towire_gossipctl_activate_reply(NULL)));
|
||||
take(towire_gossipctl_activate_reply(NULL,
|
||||
daemon->wireaddrs,
|
||||
daemon->listen_announce)));
|
||||
|
||||
return daemon_conn_read_next(master->conn, master);
|
||||
}
|
||||
|
@ -23,9 +23,15 @@ gossipctl_init,,reconnect,bool
|
||||
gossipctl_activate,3025
|
||||
# Do we listen?
|
||||
gossipctl_activate,,listen,bool
|
||||
gossipctl_activate,,guess_addresses,bool
|
||||
# FIXME: Hack for deprecated --port option.
|
||||
gossipctl_activate,,port,u16
|
||||
|
||||
# Gossipd->master, I am ready.
|
||||
# Gossipd->master, I am ready, here are the final addresses.
|
||||
gossipctl_activate_reply,3125
|
||||
gossipctl_activate_reply,,num_wireaddrs,u16
|
||||
gossipctl_activate_reply,,wireaddrs,num_wireaddrs*struct wireaddr
|
||||
gossipctl_activate_reply,,listen_announce,num_wireaddrs*enum addr_listen_announce
|
||||
|
||||
# Master -> gossipd: Optional hint for where to find peer.
|
||||
gossipctl_peer_addrhint,3014
|
||||
|
|
@ -1,10 +1,10 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <assert.h>
|
||||
#include <common/status.h>
|
||||
#include <common/type_to_string.h>
|
||||
#include <common/wireaddr.h>
|
||||
#include <errno.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/netaddress.h>
|
||||
#include <gossipd/netaddress.h>
|
||||
#include <netinet/in.h>
|
||||
#include <stdbool.h>
|
||||
#include <sys/socket.h>
|
||||
@ -202,26 +202,25 @@ static bool IsRoutable(const struct wireaddr *addr)
|
||||
* then query address. */
|
||||
/* Returns 0 if protocol completely unsupported, ADDR_LISTEN if we
|
||||
* can't reach addr, ADDR_LISTEN_AND_ANNOUNCE if we can (and fill saddr). */
|
||||
static enum addr_listen_announce get_local_sockname(struct lightningd *ld,
|
||||
int af, void *saddr,
|
||||
static enum addr_listen_announce get_local_sockname(int af, void *saddr,
|
||||
socklen_t saddrlen)
|
||||
{
|
||||
int fd = socket(af, SOCK_DGRAM, 0);
|
||||
if (fd < 0) {
|
||||
log_debug(ld->log, "Failed to create %u socket: %s",
|
||||
status_trace("Failed to create %u socket: %s",
|
||||
af, strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (connect(fd, saddr, saddrlen) != 0) {
|
||||
log_debug(ld->log, "Failed to connect %u socket: %s",
|
||||
status_trace("Failed to connect %u socket: %s",
|
||||
af, strerror(errno));
|
||||
close(fd);
|
||||
return ADDR_LISTEN;
|
||||
}
|
||||
|
||||
if (getsockname(fd, saddr, &saddrlen) != 0) {
|
||||
log_debug(ld->log, "Failed to get %u socket name: %s",
|
||||
status_trace("Failed to get %u socket name: %s",
|
||||
af, strerror(errno));
|
||||
close(fd);
|
||||
return ADDR_LISTEN;
|
||||
@ -234,8 +233,7 @@ static enum addr_listen_announce get_local_sockname(struct lightningd *ld,
|
||||
/* Return 0 if not available, or whether it's listenable-only or announceable.
|
||||
* If it's listenable only, will set wireaddr to all-zero address for universal
|
||||
* binding. */
|
||||
static enum addr_listen_announce guess_one_address(struct lightningd *ld,
|
||||
struct wireaddr *addr,
|
||||
static enum addr_listen_announce guess_one_address(struct wireaddr *addr,
|
||||
u16 portnum,
|
||||
enum wire_addr_type type)
|
||||
{
|
||||
@ -252,7 +250,7 @@ static enum addr_listen_announce guess_one_address(struct lightningd *ld,
|
||||
/* 8.8.8.8 */
|
||||
sin.sin_addr.s_addr = 0x08080808;
|
||||
sin.sin_family = AF_INET;
|
||||
ret = get_local_sockname(ld, AF_INET, &sin, sizeof(sin));
|
||||
ret = get_local_sockname(AF_INET, &sin, sizeof(sin));
|
||||
addr->addrlen = sizeof(sin.sin_addr);
|
||||
memcpy(addr->addr, &sin.sin_addr, addr->addrlen);
|
||||
break;
|
||||
@ -266,13 +264,13 @@ static enum addr_listen_announce guess_one_address(struct lightningd *ld,
|
||||
sin6.sin6_port = htons(53);
|
||||
sin6.sin6_family = AF_INET6;
|
||||
memcpy(sin6.sin6_addr.s6_addr, pchGoogle, sizeof(pchGoogle));
|
||||
ret = get_local_sockname(ld, AF_INET6, &sin6, sizeof(sin6));
|
||||
ret = get_local_sockname(AF_INET6, &sin6, sizeof(sin6));
|
||||
addr->addrlen = sizeof(sin6.sin6_addr);
|
||||
memcpy(addr->addr, &sin6.sin6_addr, addr->addrlen);
|
||||
break;
|
||||
}
|
||||
case ADDR_TYPE_PADDING:
|
||||
log_debug(ld->log, "Padding address, ignoring");
|
||||
status_trace("Padding address, ignoring");
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -281,7 +279,7 @@ static enum addr_listen_announce guess_one_address(struct lightningd *ld,
|
||||
|
||||
/* If we can reach it, but resulting address is unroutable, listen only */
|
||||
if (ret == ADDR_LISTEN_AND_ANNOUNCE && !IsRoutable(addr)) {
|
||||
log_debug(ld->log, "Address %s is not routable",
|
||||
status_trace("Address %s is not routable",
|
||||
type_to_string(tmpctx, struct wireaddr, addr));
|
||||
ret = ADDR_LISTEN;
|
||||
}
|
||||
@ -290,33 +288,35 @@ static enum addr_listen_announce guess_one_address(struct lightningd *ld,
|
||||
/* This corresponds to INADDR_ANY or in6addr_any */
|
||||
memset(addr->addr, 0, addr->addrlen);
|
||||
} else {
|
||||
log_debug(ld->log, "Public address %s",
|
||||
status_trace("Public address %s",
|
||||
type_to_string(tmpctx, struct wireaddr, addr));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
void guess_addresses(struct lightningd *ld)
|
||||
void guess_addresses(struct wireaddr **wireaddrs,
|
||||
enum addr_listen_announce **listen_announce,
|
||||
u16 portnum)
|
||||
{
|
||||
size_t n = tal_count(ld->wireaddrs);
|
||||
size_t n = tal_count(*wireaddrs);
|
||||
|
||||
log_debug(ld->log, "Trying to guess public addresses...");
|
||||
status_trace("Trying to guess public addresses...");
|
||||
|
||||
/* We allocate an extra, then remove if it's not needed. */
|
||||
tal_resize(&ld->wireaddrs, n+1);
|
||||
tal_resize(&ld->listen_announce, n+1);
|
||||
tal_resize(wireaddrs, n+1);
|
||||
tal_resize(listen_announce, n+1);
|
||||
/* We do IPv6 first: on Linux, that binds to IPv4 too. */
|
||||
ld->listen_announce[n] = guess_one_address(ld, &ld->wireaddrs[n],
|
||||
ld->portnum, ADDR_TYPE_IPV6);
|
||||
if (ld->listen_announce[n] != 0) {
|
||||
(*listen_announce)[n] = guess_one_address(&(*wireaddrs)[n],
|
||||
portnum, ADDR_TYPE_IPV6);
|
||||
if ((*listen_announce)[n] != 0) {
|
||||
n++;
|
||||
tal_resize(&ld->wireaddrs, n+1);
|
||||
tal_resize(&ld->listen_announce, n+1);
|
||||
tal_resize(wireaddrs, n+1);
|
||||
tal_resize(listen_announce, n+1);
|
||||
}
|
||||
ld->listen_announce[n] = guess_one_address(ld, &ld->wireaddrs[n],
|
||||
ld->portnum, ADDR_TYPE_IPV4);
|
||||
if (ld->listen_announce[n] == 0) {
|
||||
tal_resize(&ld->wireaddrs, n);
|
||||
tal_resize(&ld->listen_announce, n);
|
||||
(*listen_announce)[n] = guess_one_address(&(*wireaddrs)[n],
|
||||
portnum, ADDR_TYPE_IPV4);
|
||||
if ((*listen_announce)[n] == 0) {
|
||||
tal_resize(wireaddrs, n);
|
||||
tal_resize(listen_announce, n);
|
||||
}
|
||||
}
|
10
gossipd/netaddress.h
Normal file
10
gossipd/netaddress.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef LIGHTNING_GOSSIPD_NETADDRESS_H
|
||||
#define LIGHTNING_GOSSIPD_NETADDRESS_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
|
||||
void guess_addresses(struct wireaddr **wireaddrs,
|
||||
enum addr_listen_announce **listen_announce,
|
||||
u16 portnum);
|
||||
|
||||
#endif /* LIGHTNING_GOSSIPD_NETADDRESS_H */
|
@ -66,7 +66,6 @@ LIGHTNINGD_SRC := \
|
||||
lightningd/lightningd.c \
|
||||
lightningd/log.c \
|
||||
lightningd/log_status.c \
|
||||
lightningd/netaddress.c \
|
||||
lightningd/onchain_control.c \
|
||||
lightningd/opening_control.c \
|
||||
lightningd/opt_time.c \
|
||||
|
@ -213,17 +213,29 @@ void gossip_init(struct lightningd *ld)
|
||||
}
|
||||
|
||||
static void gossip_activate_done(struct subd *gossip UNUSED,
|
||||
const u8 *reply UNUSED,
|
||||
const u8 *reply,
|
||||
const int *fds UNUSED,
|
||||
void *unused UNUSED)
|
||||
{
|
||||
struct lightningd *ld = gossip->ld;
|
||||
|
||||
/* Reply gives us the actual wireaddrs we're using */
|
||||
tal_free(ld->wireaddrs);
|
||||
tal_free(ld->listen_announce);
|
||||
if (!fromwire_gossipctl_activate_reply(gossip->ld, reply,
|
||||
&ld->wireaddrs,
|
||||
&ld->listen_announce))
|
||||
fatal("Bad gossipctl_activate_reply: %s",
|
||||
tal_hex(reply, reply));
|
||||
|
||||
/* Break out of loop, so we can begin */
|
||||
io_break(gossip);
|
||||
}
|
||||
|
||||
void gossip_activate(struct lightningd *ld)
|
||||
{
|
||||
const u8 *msg = towire_gossipctl_activate(NULL, ld->listen);
|
||||
const u8 *msg = towire_gossipctl_activate(NULL, ld->listen, ld->autolisten,
|
||||
ld->portnum);
|
||||
subd_req(ld->gossip, ld->gossip, take(msg), -1, 0,
|
||||
gossip_activate_done, NULL);
|
||||
|
||||
|
@ -1,11 +0,0 @@
|
||||
#ifndef LIGHTNING_LIGHTNINGD_NETADDRESS_H
|
||||
#define LIGHTNING_LIGHTNINGD_NETADDRESS_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
|
||||
struct lightningd;
|
||||
|
||||
void guess_addresses(struct lightningd *ld);
|
||||
|
||||
|
||||
#endif /* LIGHTNING_LIGHTNINGD_NETADDRESS_H */
|
@ -22,7 +22,6 @@
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/netaddress.h>
|
||||
#include <lightningd/opt_time.h>
|
||||
#include <lightningd/options.h>
|
||||
#include <lightningd/subd.h>
|
||||
@ -809,12 +808,6 @@ void handle_opts(struct lightningd *ld, int argc, char *argv[])
|
||||
errx(1, "no arguments accepted");
|
||||
|
||||
check_config(ld);
|
||||
|
||||
if (ld->listen && ld->autolisten)
|
||||
guess_addresses(ld);
|
||||
else
|
||||
log_debug(ld->log, "Not guessing addresses: %s",
|
||||
!ld->listen ? "--offline" : "--autolisten=0");
|
||||
}
|
||||
|
||||
/* FIXME: This is a hack! Expose somehow in ccan/opt.*/
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include <lightningd/json.h>
|
||||
#include <lightningd/jsonrpc.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/netaddress.h>
|
||||
#include <lightningd/onchain_control.h>
|
||||
#include <lightningd/opening_control.h>
|
||||
#include <lightningd/options.h>
|
||||
|
Loading…
Reference in New Issue
Block a user