mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-18 21:35:11 +01:00
connectd: reorder functions again for better grouping (MOVEONLY)
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
4de2b362f5
commit
2bdedf5582
@ -315,54 +315,6 @@ struct io_plan *peer_connected(struct io_conn *conn,
|
|||||||
return io_close_taken_fd(conn);
|
return io_close_taken_fd(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct listen_fd {
|
|
||||||
int fd;
|
|
||||||
/* If we bind() IPv6 then IPv4 to same port, we *may* fail to listen()
|
|
||||||
* on the IPv4 socket: under Linux, by default, the IPv6 listen()
|
|
||||||
* covers IPv4 too. Normally we'd consider failing to listen on a
|
|
||||||
* port to be fatal, so we note this when setting up addresses. */
|
|
||||||
bool mayfail;
|
|
||||||
};
|
|
||||||
|
|
||||||
static int make_listen_fd(int domain, void *addr, socklen_t len, bool mayfail)
|
|
||||||
{
|
|
||||||
int fd = socket(domain, SOCK_STREAM, 0);
|
|
||||||
if (fd < 0) {
|
|
||||||
if (!mayfail)
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Failed to create %u socket: %s",
|
|
||||||
domain, strerror(errno));
|
|
||||||
status_trace("Failed to create %u socket: %s",
|
|
||||||
domain, strerror(errno));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (addr) {
|
|
||||||
int on = 1;
|
|
||||||
|
|
||||||
/* Re-use, please.. */
|
|
||||||
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
|
|
||||||
status_unusual("Failed setting socket reuse: %s",
|
|
||||||
strerror(errno));
|
|
||||||
|
|
||||||
if (bind(fd, addr, len) != 0) {
|
|
||||||
if (!mayfail)
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Failed to bind on %u socket: %s",
|
|
||||||
domain, strerror(errno));
|
|
||||||
status_trace("Failed to create %u socket: %s",
|
|
||||||
domain, strerror(errno));
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return fd;
|
|
||||||
|
|
||||||
fail:
|
|
||||||
close_noerr(fd);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct io_plan *handshake_in_success(struct io_conn *conn,
|
static struct io_plan *handshake_in_success(struct io_conn *conn,
|
||||||
const struct pubkey *id,
|
const struct pubkey *id,
|
||||||
const struct wireaddr_internal *addr,
|
const struct wireaddr_internal *addr,
|
||||||
@ -411,6 +363,228 @@ static struct io_plan *connection_in(struct io_conn *conn, struct daemon *daemon
|
|||||||
handshake_in_success, daemon);
|
handshake_in_success, daemon);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static struct io_plan *handshake_out_success(struct io_conn *conn,
|
||||||
|
const struct pubkey *id,
|
||||||
|
const struct wireaddr_internal *addr,
|
||||||
|
const struct crypto_state *cs,
|
||||||
|
struct connecting *connect)
|
||||||
|
{
|
||||||
|
connect->connstate = "Exchanging init messages";
|
||||||
|
status_trace("Connect OUT to %s",
|
||||||
|
type_to_string(tmpctx, struct pubkey, id));
|
||||||
|
return peer_exchange_initmsg(conn, connect->daemon, cs, id, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct io_plan *connection_out(struct io_conn *conn, struct connecting *connect)
|
||||||
|
{
|
||||||
|
/* FIXME: Timeout */
|
||||||
|
status_trace("Connected out for %s",
|
||||||
|
type_to_string(tmpctx, struct pubkey, &connect->id));
|
||||||
|
|
||||||
|
connect->connstate = "Cryptographic handshake";
|
||||||
|
return initiator_handshake(conn, &connect->daemon->id, &connect->id,
|
||||||
|
&connect->addrs[connect->addrnum],
|
||||||
|
handshake_out_success, connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void PRINTF_FMT(5,6)
|
||||||
|
connect_failed(struct daemon *daemon,
|
||||||
|
const struct pubkey *id,
|
||||||
|
u32 seconds_waited,
|
||||||
|
const struct wireaddr_internal *addrhint,
|
||||||
|
const char *errfmt, ...)
|
||||||
|
{
|
||||||
|
u8 *msg;
|
||||||
|
va_list ap;
|
||||||
|
char *err;
|
||||||
|
u32 wait_seconds;
|
||||||
|
|
||||||
|
va_start(ap, errfmt);
|
||||||
|
err = tal_vfmt(tmpctx, errfmt, ap);
|
||||||
|
va_end(ap);
|
||||||
|
|
||||||
|
/* Wait twice as long to reconnect, between min and max. */
|
||||||
|
wait_seconds = seconds_waited * 2;
|
||||||
|
if (wait_seconds > MAX_WAIT_SECONDS)
|
||||||
|
wait_seconds = MAX_WAIT_SECONDS;
|
||||||
|
if (wait_seconds < INITIAL_WAIT_SECONDS)
|
||||||
|
wait_seconds = INITIAL_WAIT_SECONDS;
|
||||||
|
|
||||||
|
/* Tell any connect command what happened. */
|
||||||
|
msg = towire_connectctl_connect_failed(NULL, id, err, wait_seconds,
|
||||||
|
addrhint);
|
||||||
|
daemon_conn_send(&daemon->master, take(msg));
|
||||||
|
|
||||||
|
status_trace("Failed connected out for %s: %s",
|
||||||
|
type_to_string(tmpctx, struct pubkey, id),
|
||||||
|
err);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void destroy_io_conn(struct io_conn *conn, struct connecting *connect)
|
||||||
|
{
|
||||||
|
tal_append_fmt(&connect->errors,
|
||||||
|
"%s: %s: %s. ",
|
||||||
|
type_to_string(tmpctx, struct wireaddr_internal,
|
||||||
|
&connect->addrs[connect->addrnum]),
|
||||||
|
connect->connstate, strerror(errno));
|
||||||
|
connect->addrnum++;
|
||||||
|
try_connect_one_addr(connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct io_plan *conn_init(struct io_conn *conn,
|
||||||
|
struct connecting *connect)
|
||||||
|
{
|
||||||
|
struct addrinfo *ai = NULL;
|
||||||
|
const struct wireaddr_internal *addr = &connect->addrs[connect->addrnum];
|
||||||
|
|
||||||
|
switch (addr->itype) {
|
||||||
|
case ADDR_INTERNAL_SOCKNAME:
|
||||||
|
ai = wireaddr_internal_to_addrinfo(tmpctx, addr);
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_ALLPROTO:
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Can't connect to all protocols");
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_AUTOTOR:
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Can't connect to autotor address");
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_FORPROXY:
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Can't connect to forproxy address");
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_WIREADDR:
|
||||||
|
/* If it was a Tor address, we wouldn't be here. */
|
||||||
|
ai = wireaddr_to_addrinfo(tmpctx, &addr->u.wireaddr);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
assert(ai);
|
||||||
|
|
||||||
|
io_set_finish(conn, destroy_io_conn, connect);
|
||||||
|
return io_connect(conn, ai, connection_out, connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct io_plan *conn_proxy_init(struct io_conn *conn,
|
||||||
|
struct connecting *connect)
|
||||||
|
{
|
||||||
|
const char *host = NULL;
|
||||||
|
u16 port;
|
||||||
|
const struct wireaddr_internal *addr = &connect->addrs[connect->addrnum];
|
||||||
|
|
||||||
|
switch (addr->itype) {
|
||||||
|
case ADDR_INTERNAL_FORPROXY:
|
||||||
|
host = addr->u.unresolved.name;
|
||||||
|
port = addr->u.unresolved.port;
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_WIREADDR:
|
||||||
|
host = fmt_wireaddr_without_port(tmpctx, &addr->u.wireaddr);
|
||||||
|
port = addr->u.wireaddr.port;
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_SOCKNAME:
|
||||||
|
case ADDR_INTERNAL_ALLPROTO:
|
||||||
|
case ADDR_INTERNAL_AUTOTOR:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!host)
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Can't connect to %u address", addr->itype);
|
||||||
|
|
||||||
|
io_set_finish(conn, destroy_io_conn, connect);
|
||||||
|
return io_tor_connect(conn, connect->daemon->proxyaddr, host, port,
|
||||||
|
connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void try_connect_one_addr(struct connecting *connect)
|
||||||
|
{
|
||||||
|
int fd, af;
|
||||||
|
bool use_proxy = connect->daemon->use_proxy_always;
|
||||||
|
const struct wireaddr_internal *addr = &connect->addrs[connect->addrnum];
|
||||||
|
|
||||||
|
if (connect->addrnum == tal_count(connect->addrs)) {
|
||||||
|
connect_failed(connect->daemon, &connect->id,
|
||||||
|
connect->seconds_waited,
|
||||||
|
connect->addrhint, "%s", connect->errors);
|
||||||
|
tal_free(connect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Might not even be able to create eg. IPv6 sockets */
|
||||||
|
af = -1;
|
||||||
|
|
||||||
|
switch (addr->itype) {
|
||||||
|
case ADDR_INTERNAL_SOCKNAME:
|
||||||
|
af = AF_LOCAL;
|
||||||
|
/* Local sockets don't use tor proxy */
|
||||||
|
use_proxy = false;
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_ALLPROTO:
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Can't connect ALLPROTO");
|
||||||
|
case ADDR_INTERNAL_AUTOTOR:
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Can't connect AUTOTOR");
|
||||||
|
case ADDR_INTERNAL_FORPROXY:
|
||||||
|
use_proxy = true;
|
||||||
|
break;
|
||||||
|
case ADDR_INTERNAL_WIREADDR:
|
||||||
|
switch (addr->u.wireaddr.type) {
|
||||||
|
case ADDR_TYPE_TOR_V2:
|
||||||
|
case ADDR_TYPE_TOR_V3:
|
||||||
|
use_proxy = true;
|
||||||
|
break;
|
||||||
|
case ADDR_TYPE_IPV4:
|
||||||
|
af = AF_INET;
|
||||||
|
break;
|
||||||
|
case ADDR_TYPE_IPV6:
|
||||||
|
af = AF_INET6;
|
||||||
|
break;
|
||||||
|
case ADDR_TYPE_PADDING:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If we have to use proxy but we don't have one, we fail. */
|
||||||
|
if (use_proxy) {
|
||||||
|
if (!connect->daemon->proxyaddr) {
|
||||||
|
status_debug("Need proxy");
|
||||||
|
af = -1;
|
||||||
|
} else
|
||||||
|
af = connect->daemon->proxyaddr->ai_family;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (af == -1) {
|
||||||
|
fd = -1;
|
||||||
|
errno = EPROTONOSUPPORT;
|
||||||
|
} else
|
||||||
|
fd = socket(af, SOCK_STREAM, 0);
|
||||||
|
|
||||||
|
if (fd < 0) {
|
||||||
|
tal_append_fmt(&connect->errors,
|
||||||
|
"%s: opening %i socket gave %s. ",
|
||||||
|
type_to_string(tmpctx, struct wireaddr_internal,
|
||||||
|
addr),
|
||||||
|
af, strerror(errno));
|
||||||
|
connect->addrnum++;
|
||||||
|
try_connect_one_addr(connect);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (use_proxy)
|
||||||
|
io_new_conn(connect, fd, conn_proxy_init, connect);
|
||||||
|
else
|
||||||
|
io_new_conn(connect, fd, conn_init, connect);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct listen_fd {
|
||||||
|
int fd;
|
||||||
|
/* If we bind() IPv6 then IPv4 to same port, we *may* fail to listen()
|
||||||
|
* on the IPv4 socket: under Linux, by default, the IPv6 listen()
|
||||||
|
* covers IPv4 too. Normally we'd consider failing to listen on a
|
||||||
|
* port to be fatal, so we note this when setting up addresses. */
|
||||||
|
bool mayfail;
|
||||||
|
};
|
||||||
|
|
||||||
static void add_listen_fd(struct daemon *daemon, int fd, bool mayfail)
|
static void add_listen_fd(struct daemon *daemon, int fd, bool mayfail)
|
||||||
{
|
{
|
||||||
struct listen_fd *l = tal_arr_expand(&daemon->listen_fds);
|
struct listen_fd *l = tal_arr_expand(&daemon->listen_fds);
|
||||||
@ -418,6 +592,45 @@ static void add_listen_fd(struct daemon *daemon, int fd, bool mayfail)
|
|||||||
l->mayfail = mayfail;
|
l->mayfail = mayfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int make_listen_fd(int domain, void *addr, socklen_t len, bool mayfail)
|
||||||
|
{
|
||||||
|
int fd = socket(domain, SOCK_STREAM, 0);
|
||||||
|
if (fd < 0) {
|
||||||
|
if (!mayfail)
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Failed to create %u socket: %s",
|
||||||
|
domain, strerror(errno));
|
||||||
|
status_trace("Failed to create %u socket: %s",
|
||||||
|
domain, strerror(errno));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addr) {
|
||||||
|
int on = 1;
|
||||||
|
|
||||||
|
/* Re-use, please.. */
|
||||||
|
if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)))
|
||||||
|
status_unusual("Failed setting socket reuse: %s",
|
||||||
|
strerror(errno));
|
||||||
|
|
||||||
|
if (bind(fd, addr, len) != 0) {
|
||||||
|
if (!mayfail)
|
||||||
|
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||||
|
"Failed to bind on %u socket: %s",
|
||||||
|
domain, strerror(errno));
|
||||||
|
status_trace("Failed to create %u socket: %s",
|
||||||
|
domain, strerror(errno));
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fd;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_noerr(fd);
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
/* 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,
|
||||||
@ -736,138 +949,6 @@ static struct io_plan *connect_activate(struct daemon_conn *master,
|
|||||||
return daemon_conn_read_next(master->conn, master);
|
return daemon_conn_read_next(master->conn, master);
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct io_plan *handshake_out_success(struct io_conn *conn,
|
|
||||||
const struct pubkey *id,
|
|
||||||
const struct wireaddr_internal *addr,
|
|
||||||
const struct crypto_state *cs,
|
|
||||||
struct connecting *connect)
|
|
||||||
{
|
|
||||||
connect->connstate = "Exchanging init messages";
|
|
||||||
status_trace("Connect OUT to %s",
|
|
||||||
type_to_string(tmpctx, struct pubkey, id));
|
|
||||||
return peer_exchange_initmsg(conn, connect->daemon, cs, id, addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct io_plan *connection_out(struct io_conn *conn, struct connecting *connect)
|
|
||||||
{
|
|
||||||
/* FIXME: Timeout */
|
|
||||||
status_trace("Connected out for %s",
|
|
||||||
type_to_string(tmpctx, struct pubkey, &connect->id));
|
|
||||||
|
|
||||||
connect->connstate = "Cryptographic handshake";
|
|
||||||
return initiator_handshake(conn, &connect->daemon->id, &connect->id,
|
|
||||||
&connect->addrs[connect->addrnum],
|
|
||||||
handshake_out_success, connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void PRINTF_FMT(5,6)
|
|
||||||
connect_failed(struct daemon *daemon,
|
|
||||||
const struct pubkey *id,
|
|
||||||
u32 seconds_waited,
|
|
||||||
const struct wireaddr_internal *addrhint,
|
|
||||||
const char *errfmt, ...)
|
|
||||||
{
|
|
||||||
u8 *msg;
|
|
||||||
va_list ap;
|
|
||||||
char *err;
|
|
||||||
u32 wait_seconds;
|
|
||||||
|
|
||||||
va_start(ap, errfmt);
|
|
||||||
err = tal_vfmt(tmpctx, errfmt, ap);
|
|
||||||
va_end(ap);
|
|
||||||
|
|
||||||
/* Wait twice as long to reconnect, between min and max. */
|
|
||||||
wait_seconds = seconds_waited * 2;
|
|
||||||
if (wait_seconds > MAX_WAIT_SECONDS)
|
|
||||||
wait_seconds = MAX_WAIT_SECONDS;
|
|
||||||
if (wait_seconds < INITIAL_WAIT_SECONDS)
|
|
||||||
wait_seconds = INITIAL_WAIT_SECONDS;
|
|
||||||
|
|
||||||
/* Tell any connect command what happened. */
|
|
||||||
msg = towire_connectctl_connect_failed(NULL, id, err, wait_seconds,
|
|
||||||
addrhint);
|
|
||||||
daemon_conn_send(&daemon->master, take(msg));
|
|
||||||
|
|
||||||
status_trace("Failed connected out for %s: %s",
|
|
||||||
type_to_string(tmpctx, struct pubkey, id),
|
|
||||||
err);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void destroy_io_conn(struct io_conn *conn, struct connecting *connect)
|
|
||||||
{
|
|
||||||
tal_append_fmt(&connect->errors,
|
|
||||||
"%s: %s: %s. ",
|
|
||||||
type_to_string(tmpctx, struct wireaddr_internal,
|
|
||||||
&connect->addrs[connect->addrnum]),
|
|
||||||
connect->connstate, strerror(errno));
|
|
||||||
connect->addrnum++;
|
|
||||||
try_connect_one_addr(connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct io_plan *conn_init(struct io_conn *conn,
|
|
||||||
struct connecting *connect)
|
|
||||||
{
|
|
||||||
struct addrinfo *ai = NULL;
|
|
||||||
const struct wireaddr_internal *addr = &connect->addrs[connect->addrnum];
|
|
||||||
|
|
||||||
switch (addr->itype) {
|
|
||||||
case ADDR_INTERNAL_SOCKNAME:
|
|
||||||
ai = wireaddr_internal_to_addrinfo(tmpctx, addr);
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_ALLPROTO:
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Can't connect to all protocols");
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_AUTOTOR:
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Can't connect to autotor address");
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_FORPROXY:
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Can't connect to forproxy address");
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_WIREADDR:
|
|
||||||
/* If it was a Tor address, we wouldn't be here. */
|
|
||||||
ai = wireaddr_to_addrinfo(tmpctx, &addr->u.wireaddr);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
assert(ai);
|
|
||||||
|
|
||||||
io_set_finish(conn, destroy_io_conn, connect);
|
|
||||||
return io_connect(conn, ai, connection_out, connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static struct io_plan *conn_proxy_init(struct io_conn *conn,
|
|
||||||
struct connecting *connect)
|
|
||||||
{
|
|
||||||
const char *host = NULL;
|
|
||||||
u16 port;
|
|
||||||
const struct wireaddr_internal *addr = &connect->addrs[connect->addrnum];
|
|
||||||
|
|
||||||
switch (addr->itype) {
|
|
||||||
case ADDR_INTERNAL_FORPROXY:
|
|
||||||
host = addr->u.unresolved.name;
|
|
||||||
port = addr->u.unresolved.port;
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_WIREADDR:
|
|
||||||
host = fmt_wireaddr_without_port(tmpctx, &addr->u.wireaddr);
|
|
||||||
port = addr->u.wireaddr.port;
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_SOCKNAME:
|
|
||||||
case ADDR_INTERNAL_ALLPROTO:
|
|
||||||
case ADDR_INTERNAL_AUTOTOR:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!host)
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Can't connect to %u address", addr->itype);
|
|
||||||
|
|
||||||
io_set_finish(conn, destroy_io_conn, connect);
|
|
||||||
return io_tor_connect(conn, connect->daemon->proxyaddr, host, port,
|
|
||||||
connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char *seedname(const tal_t *ctx, const struct pubkey *id)
|
static const char *seedname(const tal_t *ctx, const struct pubkey *id)
|
||||||
{
|
{
|
||||||
char bech32[100];
|
char bech32[100];
|
||||||
@ -930,87 +1011,6 @@ static void add_gossip_addrs(struct wireaddr_internal **addrs,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void try_connect_one_addr(struct connecting *connect)
|
|
||||||
{
|
|
||||||
int fd, af;
|
|
||||||
bool use_proxy = connect->daemon->use_proxy_always;
|
|
||||||
const struct wireaddr_internal *addr = &connect->addrs[connect->addrnum];
|
|
||||||
|
|
||||||
if (connect->addrnum == tal_count(connect->addrs)) {
|
|
||||||
connect_failed(connect->daemon, &connect->id,
|
|
||||||
connect->seconds_waited,
|
|
||||||
connect->addrhint, "%s", connect->errors);
|
|
||||||
tal_free(connect);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Might not even be able to create eg. IPv6 sockets */
|
|
||||||
af = -1;
|
|
||||||
|
|
||||||
switch (addr->itype) {
|
|
||||||
case ADDR_INTERNAL_SOCKNAME:
|
|
||||||
af = AF_LOCAL;
|
|
||||||
/* Local sockets don't use tor proxy */
|
|
||||||
use_proxy = false;
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_ALLPROTO:
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Can't connect ALLPROTO");
|
|
||||||
case ADDR_INTERNAL_AUTOTOR:
|
|
||||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
|
||||||
"Can't connect AUTOTOR");
|
|
||||||
case ADDR_INTERNAL_FORPROXY:
|
|
||||||
use_proxy = true;
|
|
||||||
break;
|
|
||||||
case ADDR_INTERNAL_WIREADDR:
|
|
||||||
switch (addr->u.wireaddr.type) {
|
|
||||||
case ADDR_TYPE_TOR_V2:
|
|
||||||
case ADDR_TYPE_TOR_V3:
|
|
||||||
use_proxy = true;
|
|
||||||
break;
|
|
||||||
case ADDR_TYPE_IPV4:
|
|
||||||
af = AF_INET;
|
|
||||||
break;
|
|
||||||
case ADDR_TYPE_IPV6:
|
|
||||||
af = AF_INET6;
|
|
||||||
break;
|
|
||||||
case ADDR_TYPE_PADDING:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we have to use proxy but we don't have one, we fail. */
|
|
||||||
if (use_proxy) {
|
|
||||||
if (!connect->daemon->proxyaddr) {
|
|
||||||
status_debug("Need proxy");
|
|
||||||
af = -1;
|
|
||||||
} else
|
|
||||||
af = connect->daemon->proxyaddr->ai_family;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (af == -1) {
|
|
||||||
fd = -1;
|
|
||||||
errno = EPROTONOSUPPORT;
|
|
||||||
} else
|
|
||||||
fd = socket(af, SOCK_STREAM, 0);
|
|
||||||
|
|
||||||
if (fd < 0) {
|
|
||||||
tal_append_fmt(&connect->errors,
|
|
||||||
"%s: opening %i socket gave %s. ",
|
|
||||||
type_to_string(tmpctx, struct wireaddr_internal,
|
|
||||||
addr),
|
|
||||||
af, strerror(errno));
|
|
||||||
connect->addrnum++;
|
|
||||||
try_connect_one_addr(connect);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (use_proxy)
|
|
||||||
io_new_conn(connect, fd, conn_proxy_init, connect);
|
|
||||||
else
|
|
||||||
io_new_conn(connect, fd, conn_init, connect);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Consumes addrhint if not NULL */
|
/* Consumes addrhint if not NULL */
|
||||||
static void try_connect_peer(struct daemon *daemon,
|
static void try_connect_peer(struct daemon *daemon,
|
||||||
const struct pubkey *id,
|
const struct pubkey *id,
|
||||||
|
Loading…
Reference in New Issue
Block a user