mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
connectd: get multiple addresses from hostname
This commit is contained in:
@@ -289,17 +289,18 @@ static bool separate_address_and_port(const tal_t *ctx, const char *arg,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
bool wireaddr_from_hostname(struct wireaddr **addrs, const char *hostname,
|
||||||
const u16 port, bool *no_dns,
|
const u16 port, bool *no_dns,
|
||||||
struct sockaddr *broken_reply,
|
struct sockaddr *broken_reply,
|
||||||
const char **err_msg)
|
const char **err_msg)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 *sa6;
|
struct sockaddr_in6 *sa6;
|
||||||
struct sockaddr_in *sa4;
|
struct sockaddr_in *sa4;
|
||||||
struct addrinfo *addrinfo;
|
struct addrinfo *addrinfo, *addrinfos;
|
||||||
struct addrinfo hints;
|
struct addrinfo hints;
|
||||||
int gai_err;
|
int gai_err;
|
||||||
bool res = false;
|
bool res = false;
|
||||||
|
struct wireaddr *addr;
|
||||||
|
|
||||||
if (no_dns)
|
if (no_dns)
|
||||||
*no_dns = false;
|
*no_dns = false;
|
||||||
@@ -309,18 +310,18 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
|||||||
u8 *dec = b32_decode(tmpctx, hostname,
|
u8 *dec = b32_decode(tmpctx, hostname,
|
||||||
strlen(hostname) - strlen(".onion"));
|
strlen(hostname) - strlen(".onion"));
|
||||||
if (tal_count(dec) == TOR_V2_ADDRLEN)
|
if (tal_count(dec) == TOR_V2_ADDRLEN)
|
||||||
addr->type = ADDR_TYPE_TOR_V2;
|
addrs[0]->type = ADDR_TYPE_TOR_V2;
|
||||||
else if (tal_count(dec) == TOR_V3_ADDRLEN)
|
else if (tal_count(dec) == TOR_V3_ADDRLEN)
|
||||||
addr->type = ADDR_TYPE_TOR_V3;
|
addrs[0]->type = ADDR_TYPE_TOR_V3;
|
||||||
else {
|
else {
|
||||||
if (err_msg)
|
if (err_msg)
|
||||||
*err_msg = "Invalid Tor address";
|
*err_msg = "Invalid Tor address";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
addr->addrlen = tal_count(dec);
|
addrs[0]->addrlen = tal_count(dec);
|
||||||
addr->port = port;
|
addrs[0]->port = port;
|
||||||
memcpy(&addr->addr, dec, tal_count(dec));
|
memcpy(&addrs[0]->addr, dec, tal_count(dec));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -338,19 +339,20 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
|||||||
hints.ai_protocol = 0;
|
hints.ai_protocol = 0;
|
||||||
hints.ai_flags = AI_ADDRCONFIG;
|
hints.ai_flags = AI_ADDRCONFIG;
|
||||||
gai_err = getaddrinfo(hostname, tal_fmt(tmpctx, "%d", port),
|
gai_err = getaddrinfo(hostname, tal_fmt(tmpctx, "%d", port),
|
||||||
&hints, &addrinfo);
|
&hints, &addrinfos);
|
||||||
if (gai_err != 0) {
|
if (gai_err != 0) {
|
||||||
if (err_msg)
|
if (err_msg)
|
||||||
*err_msg = gai_strerror(gai_err);
|
*err_msg = gai_strerror(gai_err);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (broken_reply != NULL && memeq(addrinfo->ai_addr, addrinfo->ai_addrlen, broken_reply, tal_count(broken_reply))) {
|
if (broken_reply != NULL && memeq(addrinfos->ai_addr, addrinfos->ai_addrlen, broken_reply, tal_count(broken_reply))) {
|
||||||
res = false;
|
res = false;
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Use only the first found address */
|
for (addrinfo = addrinfos; addrinfo; addrinfo = addrinfo->ai_next) {
|
||||||
|
addr = tal(addrs, struct wireaddr);
|
||||||
if (addrinfo->ai_family == AF_INET) {
|
if (addrinfo->ai_family == AF_INET) {
|
||||||
sa4 = (struct sockaddr_in *) addrinfo->ai_addr;
|
sa4 = (struct sockaddr_in *) addrinfo->ai_addr;
|
||||||
wireaddr_from_ipv4(addr, &sa4->sin_addr, port);
|
wireaddr_from_ipv4(addr, &sa4->sin_addr, port);
|
||||||
@@ -360,10 +362,12 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
|||||||
wireaddr_from_ipv6(addr, &sa6->sin6_addr, port);
|
wireaddr_from_ipv6(addr, &sa6->sin6_addr, port);
|
||||||
res = true;
|
res = true;
|
||||||
}
|
}
|
||||||
|
tal_arr_expand(&addrs, addr);
|
||||||
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
/* Clean up */
|
/* Clean up */
|
||||||
freeaddrinfo(addrinfo);
|
freeaddrinfo(addrinfos);
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -401,7 +405,7 @@ bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
|
|||||||
|
|
||||||
/* Resolve with getaddrinfo */
|
/* Resolve with getaddrinfo */
|
||||||
if (!res)
|
if (!res)
|
||||||
res = wireaddr_from_hostname(addr, ip, port, no_dns, NULL, err_msg);
|
res = wireaddr_from_hostname(&addr, ip, port, no_dns, NULL, err_msg);
|
||||||
|
|
||||||
finish:
|
finish:
|
||||||
if (!res && err_msg && !*err_msg)
|
if (!res && err_msg && !*err_msg)
|
||||||
|
|||||||
@@ -86,7 +86,7 @@ char *fmt_wireaddr_without_port(const tal_t *ctx, const struct wireaddr *a);
|
|||||||
|
|
||||||
/* If no_dns is non-NULL, we will set it to true and return false if
|
/* If no_dns is non-NULL, we will set it to true and return false if
|
||||||
* we wanted to do a DNS lookup. */
|
* we wanted to do a DNS lookup. */
|
||||||
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
|
bool wireaddr_from_hostname(struct wireaddr **addrs, const char *hostname,
|
||||||
const u16 port, bool *no_dns,
|
const u16 port, bool *no_dns,
|
||||||
struct sockaddr *broken_reply,
|
struct sockaddr *broken_reply,
|
||||||
const char **err_msg);
|
const char **err_msg);
|
||||||
|
|||||||
@@ -1264,24 +1264,28 @@ static void add_seed_addrs(struct wireaddr_internal **addrs,
|
|||||||
const struct node_id *id,
|
const struct node_id *id,
|
||||||
struct sockaddr *broken_reply)
|
struct sockaddr *broken_reply)
|
||||||
{
|
{
|
||||||
struct wireaddr_internal a;
|
struct wireaddr **new_addrs;
|
||||||
const char *addr;
|
const char *hostname;
|
||||||
|
|
||||||
addr = seedname(tmpctx, id);
|
new_addrs = tal_arr(tmpctx, struct wireaddr *, 0);
|
||||||
status_trace("Resolving %s", addr);
|
hostname = seedname(tmpctx, id);
|
||||||
|
status_trace("Resolving %s", hostname);
|
||||||
|
|
||||||
a.itype = ADDR_INTERNAL_WIREADDR;
|
if (!wireaddr_from_hostname(new_addrs, hostname, DEFAULT_PORT, NULL,
|
||||||
/* FIXME: wireaddr_from_hostname should return multiple addresses. */
|
|
||||||
if (!wireaddr_from_hostname(&a.u.wireaddr, addr, DEFAULT_PORT, NULL,
|
|
||||||
broken_reply, NULL)) {
|
broken_reply, NULL)) {
|
||||||
status_trace("Could not resolve %s", addr);
|
status_trace("Could not resolve %s", hostname);
|
||||||
} else {
|
} else {
|
||||||
status_trace("Resolved %s to %s", addr,
|
for (size_t i = 0; i < tal_count(new_addrs); i++) {
|
||||||
|
struct wireaddr_internal a;
|
||||||
|
a.itype = ADDR_INTERNAL_WIREADDR;
|
||||||
|
a.u.wireaddr = *new_addrs[i];
|
||||||
|
status_trace("Resolved %s to %s", hostname,
|
||||||
type_to_string(tmpctx, struct wireaddr,
|
type_to_string(tmpctx, struct wireaddr,
|
||||||
&a.u.wireaddr));
|
&a.u.wireaddr));
|
||||||
tal_arr_expand(addrs, a);
|
tal_arr_expand(addrs, a);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/*~ This asks gossipd for any addresses advertized by the node. */
|
/*~ This asks gossipd for any addresses advertized by the node. */
|
||||||
static void add_gossip_addrs(struct wireaddr_internal **addrs,
|
static void add_gossip_addrs(struct wireaddr_internal **addrs,
|
||||||
|
|||||||
Reference in New Issue
Block a user