Browse Source

connectd: get multiple addresses from hostname

travis-debug
darosior 5 years ago
committed by Rusty Russell
parent
commit
b2bb97adde
  1. 44
      common/wireaddr.c
  2. 2
      common/wireaddr.h
  3. 28
      connectd/connectd.c

44
common/wireaddr.c

@ -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,32 +339,35 @@ 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) {
if (addrinfo->ai_family == AF_INET) { addr = tal(addrs, struct wireaddr);
sa4 = (struct sockaddr_in *) addrinfo->ai_addr; if (addrinfo->ai_family == AF_INET) {
wireaddr_from_ipv4(addr, &sa4->sin_addr, port); sa4 = (struct sockaddr_in *) addrinfo->ai_addr;
res = true; wireaddr_from_ipv4(addr, &sa4->sin_addr, port);
} else if (addrinfo->ai_family == AF_INET6) { res = true;
sa6 = (struct sockaddr_in6 *) addrinfo->ai_addr; } else if (addrinfo->ai_family == AF_INET6) {
wireaddr_from_ipv6(addr, &sa6->sin6_addr, port); sa6 = (struct sockaddr_in6 *) addrinfo->ai_addr;
res = true; wireaddr_from_ipv6(addr, &sa6->sin6_addr, port);
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)

2
common/wireaddr.h

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

28
connectd/connectd.c

@ -1264,22 +1264,26 @@ 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++) {
type_to_string(tmpctx, struct wireaddr, struct wireaddr_internal a;
&a.u.wireaddr)); a.itype = ADDR_INTERNAL_WIREADDR;
tal_arr_expand(addrs, a); a.u.wireaddr = *new_addrs[i];
status_trace("Resolved %s to %s", hostname,
type_to_string(tmpctx, struct wireaddr,
&a.u.wireaddr));
tal_arr_expand(addrs, a);
}
} }
} }

Loading…
Cancel
Save