From a62f5e5d827a577a94d842912ed5eb71979ee1cd Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 3 Mar 2022 20:56:11 +1030 Subject: [PATCH] connectd: hoist find_local_address so we can give more graceful Tor erros. Signed-off-by: Rusty Russell --- connectd/connectd.c | 39 ++++++++++++++++++++++++++++++++++++-- connectd/tor_autoservice.c | 20 +------------------ connectd/tor_autoservice.h | 6 +----- 3 files changed, 39 insertions(+), 26 deletions(-) diff --git a/connectd/connectd.c b/connectd/connectd.c index 751a8cdac..bd4c7a0ee 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -1227,6 +1227,31 @@ static int wireaddr_cmp_type(const struct wireaddr *a, return cmp; } +/* We need to have a bound address we can tell Tor to connect to */ +static const struct wireaddr * +find_local_address(const struct wireaddr_internal *bindings) +{ + for (size_t i = 0; i < tal_count(bindings); i++) { + if (bindings[i].itype != ADDR_INTERNAL_WIREADDR) + continue; + if (bindings[i].u.wireaddr.type != ADDR_TYPE_IPV4 + && bindings[i].u.wireaddr.type != ADDR_TYPE_IPV6) + continue; + return &bindings[i].u.wireaddr; + } + return NULL; +} + +static bool want_tor(const struct wireaddr_internal *proposed_wireaddr) +{ + for (size_t i = 0; i < tal_count(proposed_wireaddr); i++) { + if (proposed_wireaddr[i].itype == ADDR_INTERNAL_STATICTOR + || proposed_wireaddr[i].itype == ADDR_INTERNAL_AUTOTOR) + return true; + } + return false; +} + /*~ The user can specify three kinds of addresses: ones we bind to but don't * announce, ones we announce but don't bind to, and ones we bind to and * announce if they seem to be public addresses. @@ -1249,6 +1274,7 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, struct sockaddr_un addrun; int fd; struct wireaddr_internal *binding; + const struct wireaddr *localaddr; const char *blob = NULL; struct secret random; struct pubkey pb; @@ -1367,6 +1393,15 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, proposed_wireaddr[i].itype); } + /* Make sure we have at least one non-websocket address to send to, + * for Tor */ + localaddr = find_local_address(binding); + if (want_tor(proposed_wireaddr) && !localaddr) { + *errstr = "Need to bind at least one local address," + " to send Tor connections to"; + return NULL; + } + /* If we want websockets to match IPv4/v6, set it up now. */ if (daemon->websocket_port) { bool announced_some = false; @@ -1417,7 +1452,7 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, toraddr = tor_autoservice(tmpctx, &proposed_wireaddr[i], tor_password, - binding, + localaddr, daemon->use_v3_autotor); if (!(proposed_listen_announce[i] & ADDR_ANNOUNCE)) { @@ -1462,7 +1497,7 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, &proposed_wireaddr[i], tor_password, blob, - find_local_address(binding), + localaddr, 0); /* get rid of blob data on our side of tor and add jitter */ randombytes_buf((void * const)proposed_wireaddr[i].u.torservice.blob, TOR_V3_BLOBLEN); diff --git a/connectd/tor_autoservice.c b/connectd/tor_autoservice.c index e471231f5..a790c8615 100644 --- a/connectd/tor_autoservice.c +++ b/connectd/tor_autoservice.c @@ -265,36 +265,18 @@ static void negotiate_auth(struct rbuf *rbuf, const char *tor_password) "Tor protocolinfo did not give auth"); } -/* We need to have a bound address we can tell Tor to connect to */ -const struct wireaddr * -find_local_address(const struct wireaddr_internal *bindings) -{ - for (size_t i = 0; i < tal_count(bindings); i++) { - if (bindings[i].itype != ADDR_INTERNAL_WIREADDR) - continue; - if (bindings[i].u.wireaddr.type != ADDR_TYPE_IPV4 - && bindings[i].u.wireaddr.type != ADDR_TYPE_IPV6) - continue; - return &bindings[i].u.wireaddr; - } - status_failed(STATUS_FAIL_INTERNAL_ERROR, - "No local address found to tell Tor to connect to"); -} - struct wireaddr *tor_autoservice(const tal_t *ctx, const struct wireaddr_internal *tor_serviceaddr, const char *tor_password, - const struct wireaddr_internal *bindings, + const struct wireaddr *laddr, const bool use_v3_autotor) { int fd; - const struct wireaddr *laddr; struct wireaddr *onion; struct addrinfo *ai_tor; struct rbuf rbuf; char *buffer; - laddr = find_local_address(bindings); ai_tor = wireaddr_to_addrinfo(tmpctx, &tor_serviceaddr->u.torservice.address); fd = socket(ai_tor->ai_family, SOCK_STREAM, 0); diff --git a/connectd/tor_autoservice.h b/connectd/tor_autoservice.h index e88731ac9..8bdb8bb9d 100644 --- a/connectd/tor_autoservice.h +++ b/connectd/tor_autoservice.h @@ -9,7 +9,7 @@ struct wireaddr *tor_autoservice(const tal_t *ctx, const struct wireaddr_internal *tor_serviceaddr, const char *tor_password, - const struct wireaddr_internal *bindings, + const struct wireaddr *localaddr, const bool use_v3_autotor); struct wireaddr *tor_fixed_service(const tal_t *ctx, @@ -19,8 +19,4 @@ struct wireaddr *tor_fixed_service(const tal_t *ctx, const struct wireaddr *bind, const u8 index); -const struct wireaddr * -find_local_address(const struct wireaddr_internal *bindings); - - #endif /* LIGHTNING_CONNECTD_TOR_AUTOSERVICE_H */