mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-03-03 10:46:58 +01:00
connectd: do socket binding during initial setup.
gossipd does a two-step initialization: it only tries to create the listening sockets when it's activated. This means it doesn't know the addresses to announce until this point. Now connectd is doing this, this would mean we'd have to tell gossipd later ("oh, BTW here are your addresses") since we need to start gossipd before connectd activation. So make connectd do all the setup, but only actually listen on the fds once we activate it. We clone the gossip_init message into connect_wire.csv. The master daemon still waits for a reply from connectd for the activate message, since it wants to be listening before it prints "Server started". Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
5a8091c853
commit
b4ed954435
2 changed files with 81 additions and 24 deletions
|
@ -162,6 +162,9 @@ struct daemon {
|
||||||
/* The address that the broken response returns instead of
|
/* The address that the broken response returns instead of
|
||||||
* NXDOMAIN. NULL if we have not detected a broken resolver. */
|
* NXDOMAIN. NULL if we have not detected a broken resolver. */
|
||||||
struct sockaddr *broken_resolver_response;
|
struct sockaddr *broken_resolver_response;
|
||||||
|
|
||||||
|
/* File descriptors to listen on once we're activated. */
|
||||||
|
int *listen_fds;
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Peers we're trying to reach. */
|
/* Peers we're trying to reach. */
|
||||||
|
@ -989,11 +992,6 @@ static int make_listen_fd(int domain, void *addr, socklen_t len, bool mayfail)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (listen(fd, 5) != 0) {
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Failed to listen on %u socket: %s",
|
|
||||||
domain, strerror(errno));
|
|
||||||
}
|
|
||||||
return fd;
|
return fd;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
|
@ -1038,6 +1036,13 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon
|
||||||
init_new_peer, daemon);
|
init_new_peer, daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void add_listen_fd(struct daemon *daemon, int fd)
|
||||||
|
{
|
||||||
|
size_t n = tal_count(daemon->listen_fds);
|
||||||
|
tal_resize(&daemon->listen_fds, n+1);
|
||||||
|
daemon->listen_fds[n] = fd;
|
||||||
|
}
|
||||||
|
|
||||||
/* Return true if it created socket successfully. */
|
/* Return true if it created socket successfully. */
|
||||||
static bool handle_wireaddr_listen(struct daemon *daemon,
|
static bool handle_wireaddr_listen(struct daemon *daemon,
|
||||||
const struct wireaddr *wireaddr,
|
const struct wireaddr *wireaddr,
|
||||||
|
@ -1055,7 +1060,7 @@ static bool handle_wireaddr_listen(struct daemon *daemon,
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
status_trace("Created IPv4 listener on port %u",
|
status_trace("Created IPv4 listener on port %u",
|
||||||
wireaddr->port);
|
wireaddr->port);
|
||||||
io_new_listener(daemon, fd, connection_in, daemon);
|
add_listen_fd(daemon, fd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1065,7 +1070,7 @@ static bool handle_wireaddr_listen(struct daemon *daemon,
|
||||||
if (fd >= 0) {
|
if (fd >= 0) {
|
||||||
status_trace("Created IPv6 listener on port %u",
|
status_trace("Created IPv6 listener on port %u",
|
||||||
wireaddr->port);
|
wireaddr->port);
|
||||||
io_new_listener(daemon, fd, connection_in, daemon);
|
add_listen_fd(daemon, fd);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -1276,8 +1281,9 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
|
||||||
struct bitcoin_blkid chain_hash;
|
struct bitcoin_blkid chain_hash;
|
||||||
u32 update_channel_interval;
|
u32 update_channel_interval;
|
||||||
struct wireaddr *proxyaddr;
|
struct wireaddr *proxyaddr;
|
||||||
|
struct wireaddr_internal *binding;
|
||||||
|
|
||||||
if (!fromwire_gossipctl_init(
|
if (!fromwire_connectctl_init(
|
||||||
daemon, msg, &daemon->broadcast_interval, &chain_hash,
|
daemon, msg, &daemon->broadcast_interval, &chain_hash,
|
||||||
&daemon->id, &daemon->globalfeatures,
|
&daemon->id, &daemon->globalfeatures,
|
||||||
&daemon->localfeatures, &daemon->proposed_wireaddr,
|
&daemon->localfeatures, &daemon->proposed_wireaddr,
|
||||||
|
@ -1286,7 +1292,7 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
|
||||||
&proxyaddr, &daemon->use_proxy_always,
|
&proxyaddr, &daemon->use_proxy_always,
|
||||||
&daemon->dev_allow_localhost, &daemon->use_dns,
|
&daemon->dev_allow_localhost, &daemon->use_dns,
|
||||||
&daemon->tor_password)) {
|
&daemon->tor_password)) {
|
||||||
master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
|
master_badmsg(WIRE_CONNECTCTL_INIT, msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Resolve Tor proxy address if any */
|
/* Resolve Tor proxy address if any */
|
||||||
|
@ -1302,6 +1308,13 @@ static struct io_plan *gossip_init(struct daemon_conn *master,
|
||||||
"dummy replies");
|
"dummy replies");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
binding = setup_listeners(tmpctx, daemon);
|
||||||
|
|
||||||
|
daemon_conn_send(&daemon->master,
|
||||||
|
take(towire_connectctl_init_reply(NULL,
|
||||||
|
binding,
|
||||||
|
daemon->announcable)));
|
||||||
|
|
||||||
return daemon_conn_read_next(master->conn, master);
|
return daemon_conn_read_next(master->conn, master);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1309,23 +1322,26 @@ static struct io_plan *gossip_activate(struct daemon_conn *master,
|
||||||
struct daemon *daemon,
|
struct daemon *daemon,
|
||||||
const u8 *msg)
|
const u8 *msg)
|
||||||
{
|
{
|
||||||
bool listen;
|
bool do_listen;
|
||||||
struct wireaddr_internal *binding;
|
|
||||||
|
|
||||||
if (!fromwire_gossipctl_activate(msg, &listen))
|
if (!fromwire_connectctl_activate(msg, &do_listen))
|
||||||
master_badmsg(WIRE_GOSSIPCTL_ACTIVATE, msg);
|
master_badmsg(WIRE_CONNECTCTL_ACTIVATE, msg);
|
||||||
|
|
||||||
if (listen)
|
if (do_listen) {
|
||||||
binding = setup_listeners(tmpctx, daemon);
|
for (size_t i = 0; i < tal_count(daemon->listen_fds); i++) {
|
||||||
else
|
if (listen(daemon->listen_fds[i], 5) != 0)
|
||||||
binding = NULL;
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Failed to listen on socket: %s",
|
||||||
|
strerror(errno));
|
||||||
|
io_new_listener(daemon, daemon->listen_fds[i],
|
||||||
|
connection_in, daemon);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
daemon->listen_fds = tal_free(daemon->listen_fds);
|
||||||
|
|
||||||
/* OK, we're ready! */
|
/* OK, we're ready! */
|
||||||
daemon_conn_send(&daemon->master,
|
daemon_conn_send(&daemon->master,
|
||||||
take(towire_gossipctl_activate_reply(NULL,
|
take(towire_connectctl_activate_reply(NULL)));
|
||||||
binding,
|
|
||||||
daemon->announcable)));
|
|
||||||
|
|
||||||
return daemon_conn_read_next(master->conn, master);
|
return daemon_conn_read_next(master->conn, master);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1813,13 +1829,14 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
|
||||||
struct daemon *daemon = container_of(master, struct daemon, master);
|
struct daemon *daemon = container_of(master, struct daemon, master);
|
||||||
enum gossip_wire_type t= fromwire_peektype(master->msg_in);
|
enum gossip_wire_type t= fromwire_peektype(master->msg_in);
|
||||||
|
|
||||||
|
/* FIXME: Move away from gossip wiretypes */
|
||||||
|
if (fromwire_peektype(master->msg_in) == WIRE_CONNECTCTL_ACTIVATE)
|
||||||
|
return gossip_activate(master, daemon, master->msg_in);
|
||||||
|
|
||||||
switch (t) {
|
switch (t) {
|
||||||
case WIRE_GOSSIPCTL_INIT:
|
case WIRE_GOSSIPCTL_INIT:
|
||||||
return gossip_init(master, daemon, master->msg_in);
|
return gossip_init(master, daemon, master->msg_in);
|
||||||
|
|
||||||
case WIRE_GOSSIPCTL_ACTIVATE:
|
|
||||||
return gossip_activate(master, daemon, master->msg_in);
|
|
||||||
|
|
||||||
case WIRE_GOSSIPCTL_RELEASE_PEER:
|
case WIRE_GOSSIPCTL_RELEASE_PEER:
|
||||||
return release_peer(conn, daemon, master->msg_in);
|
return release_peer(conn, daemon, master->msg_in);
|
||||||
|
|
||||||
|
@ -1845,6 +1862,7 @@ static struct io_plan *recv_req(struct io_conn *conn, struct daemon_conn *master
|
||||||
return disconnect_peer(conn, daemon, master->msg_in);
|
return disconnect_peer(conn, daemon, master->msg_in);
|
||||||
|
|
||||||
/* FIXME: We don't really do these, gossipd does */
|
/* FIXME: We don't really do these, gossipd does */
|
||||||
|
case WIRE_GOSSIPCTL_ACTIVATE:
|
||||||
case WIRE_GOSSIP_GETNODES_REQUEST:
|
case WIRE_GOSSIP_GETNODES_REQUEST:
|
||||||
case WIRE_GOSSIP_PING:
|
case WIRE_GOSSIP_PING:
|
||||||
case WIRE_GOSSIP_QUERY_SCIDS:
|
case WIRE_GOSSIP_QUERY_SCIDS:
|
||||||
|
@ -1917,6 +1935,7 @@ int main(int argc, char *argv[])
|
||||||
timers_init(&daemon->timers, time_mono());
|
timers_init(&daemon->timers, time_mono());
|
||||||
daemon->broadcast_interval = 30000;
|
daemon->broadcast_interval = 30000;
|
||||||
daemon->broken_resolver_response = NULL;
|
daemon->broken_resolver_response = NULL;
|
||||||
|
daemon->listen_fds = tal_arr(daemon, int, 0);
|
||||||
/* stdin == control */
|
/* stdin == control */
|
||||||
daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req,
|
daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req,
|
||||||
master_gone);
|
master_gone);
|
||||||
|
|
|
@ -1,3 +1,41 @@
|
||||||
|
#include <common/wireaddr.h>
|
||||||
|
|
||||||
|
connectctl_init,2000
|
||||||
|
connectctl_init,,broadcast_interval,u32
|
||||||
|
connectctl_init,,chain_hash,struct bitcoin_blkid
|
||||||
|
connectctl_init,,id,struct pubkey
|
||||||
|
connectctl_init,,gflen,u16
|
||||||
|
connectctl_init,,gfeatures,gflen*u8
|
||||||
|
connectctl_init,,lflen,u16
|
||||||
|
connectctl_init,,lfeatures,lflen*u8
|
||||||
|
connectctl_init,,num_wireaddrs,u16
|
||||||
|
connectctl_init,,wireaddrs,num_wireaddrs*struct wireaddr_internal
|
||||||
|
connectctl_init,,listen_announce,num_wireaddrs*enum addr_listen_announce
|
||||||
|
connectctl_init,,rgb,3*u8
|
||||||
|
connectctl_init,,alias,32*u8
|
||||||
|
connectctl_init,,update_channel_interval,u32
|
||||||
|
connectctl_init,,reconnect,bool
|
||||||
|
connectctl_init,,tor_proxyaddr,?struct wireaddr
|
||||||
|
connectctl_init,,use_tor_proxy_always,bool
|
||||||
|
connectctl_init,,dev_allow_localhost,bool
|
||||||
|
connectctl_init,,use_dns,bool
|
||||||
|
connectctl_init,,tor_password,wirestring
|
||||||
|
|
||||||
|
# Connectd->master, here are the addresses I bound, can announce.
|
||||||
|
connectctl_init_reply,2100
|
||||||
|
connectctl_init_reply,,num_bindings,u16
|
||||||
|
connectctl_init_reply,,bindings,num_bindings*struct wireaddr_internal
|
||||||
|
connectctl_init_reply,,num_announcable,u16
|
||||||
|
connectctl_init_reply,,announcable,num_announcable*struct wireaddr
|
||||||
|
|
||||||
|
# Activate the connect daemon, so others can connect.
|
||||||
|
connectctl_activate,2025
|
||||||
|
# Do we listen?
|
||||||
|
connectctl_activate,,listen,bool
|
||||||
|
|
||||||
|
# Connectd->master, I am ready.
|
||||||
|
connectctl_activate_reply,2125
|
||||||
|
|
||||||
# connectd->master: disconnect this peer please (due to reconnect).
|
# connectd->master: disconnect this peer please (due to reconnect).
|
||||||
connect_reconnected,2112
|
connect_reconnected,2112
|
||||||
connect_reconnected,,id,struct pubkey
|
connect_reconnected,,id,struct pubkey
|
||||||
|
|
|
Loading…
Add table
Reference in a new issue