Browse Source

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>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
e6c678e5df
  1. 1
      gossipd/Makefile
  2. 16
      gossipd/gossip.c
  3. 8
      gossipd/gossip_wire.csv
  4. 70
      gossipd/netaddress.c
  5. 10
      gossipd/netaddress.h
  6. 1
      lightningd/Makefile
  7. 16
      lightningd/gossip_control.c
  8. 11
      lightningd/netaddress.h
  9. 7
      lightningd/options.c
  10. 1
      lightningd/peer_control.c

1
gossipd/Makefile

@ -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 \

16
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);
}

8
gossipd/gossip_wire.csv

@ -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

Can't render this file because it has a wrong number of fields in line 6.

70
lightningd/netaddress.c → gossipd/netaddress.c

@ -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,27 +202,26 @@ 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",
af, strerror(errno));
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",
af, strerror(errno));
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",
af, strerror(errno));
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,8 +279,8 @@ 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",
type_to_string(tmpctx, struct wireaddr, addr));
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",
type_to_string(tmpctx, struct wireaddr, addr));
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

@ -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 */

1
lightningd/Makefile

@ -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 \

16
lightningd/gossip_control.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);

11
lightningd/netaddress.h

@ -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 */

7
lightningd/options.c

@ -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.*/

1
lightningd/peer_control.c

@ -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…
Cancel
Save