Browse Source

wireaddr: tell caller that we failed due to wanting DNS lookup, don't try.

This is useful for the next patch, where we want to hand the unresolved
name through to the proxy.

This also addresses @Saibato's worry that we still called getaddrinfo()
(with the AI_NUMERICHOST option) even if we didn't want a lookup.

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
parent
commit
a1dc4eef56
  1. 27
      common/wireaddr.c
  2. 9
      common/wireaddr.h
  3. 10
      gossipd/gossip.c
  4. 8
      lightningd/options.c

27
common/wireaddr.c

@ -270,7 +270,8 @@ static bool separate_address_and_port(const tal_t *ctx, const char *arg,
} }
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname, bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
const u16 port, bool dns_ok, const char **err_msg) const u16 port, bool *no_dns,
const char **err_msg)
{ {
struct sockaddr_in6 *sa6; struct sockaddr_in6 *sa6;
struct sockaddr_in *sa4; struct sockaddr_in *sa4;
@ -279,6 +280,9 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
int gai_err; int gai_err;
bool res = false; bool res = false;
if (no_dns)
*no_dns = false;
/* Don't do lookup on onion addresses. */ /* Don't do lookup on onion addresses. */
if (strends(hostname, ".onion")) { if (strends(hostname, ".onion")) {
u8 *dec = b32_decode(tmpctx, hostname, u8 *dec = b32_decode(tmpctx, hostname,
@ -299,13 +303,19 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
return true; return true;
} }
/* Tell them we wanted DNS and fail. */
if (no_dns) {
if (err_msg)
*err_msg = "Needed DNS, but lookups suppressed";
*no_dns = true;
return false;
}
memset(&hints, 0, sizeof(hints)); memset(&hints, 0, sizeof(hints));
hints.ai_family = AF_UNSPEC; hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM; hints.ai_socktype = SOCK_STREAM;
hints.ai_protocol = 0; hints.ai_protocol = 0;
hints.ai_flags = AI_ADDRCONFIG; hints.ai_flags = AI_ADDRCONFIG;
if (!dns_ok)
hints.ai_flags = AI_NUMERICHOST;
gai_err = getaddrinfo(hostname, tal_fmt(tmpctx, "%d", port), gai_err = getaddrinfo(hostname, tal_fmt(tmpctx, "%d", port),
&hints, &addrinfo); &hints, &addrinfo);
if (gai_err != 0) { if (gai_err != 0) {
@ -330,7 +340,7 @@ bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
} }
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport, bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 defport,
bool dns_ok, const char **err_msg) bool *no_dns, const char **err_msg)
{ {
struct in6_addr v6; struct in6_addr v6;
struct in_addr v4; struct in_addr v4;
@ -363,7 +373,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, dns_ok, err_msg); res = wireaddr_from_hostname(addr, ip, port, no_dns, err_msg);
finish: finish:
if (!res && err_msg && !*err_msg) if (!res && err_msg && !*err_msg)
@ -377,6 +387,7 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
{ {
u16 wildport; u16 wildport;
char *ip; char *ip;
bool needed_dns;
/* Addresses starting with '/' are local socket paths */ /* Addresses starting with '/' are local socket paths */
if (arg[0] == '/') { if (arg[0] == '/') {
@ -408,12 +419,14 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
if (strstarts(arg, "autotor:")) { if (strstarts(arg, "autotor:")) {
addr->itype = ADDR_INTERNAL_AUTOTOR; addr->itype = ADDR_INTERNAL_AUTOTOR;
return parse_wireaddr(arg + strlen("autotor:"), return parse_wireaddr(arg + strlen("autotor:"),
&addr->u.torservice, 9051, dns_ok, &addr->u.torservice, 9051,
dns_ok ? NULL : &needed_dns,
err_msg); err_msg);
} }
addr->itype = ADDR_INTERNAL_WIREADDR; addr->itype = ADDR_INTERNAL_WIREADDR;
return parse_wireaddr(arg, &addr->u.wireaddr, port, dns_ok, err_msg); return parse_wireaddr(arg, &addr->u.wireaddr, port,
dns_ok ? NULL : &needed_dns, err_msg);
} }
void wireaddr_from_sockname(struct wireaddr_internal *addr, void wireaddr_from_sockname(struct wireaddr_internal *addr,

9
common/wireaddr.h

@ -75,14 +75,19 @@ enum addr_listen_announce fromwire_addr_listen_announce(const u8 **cursor,
size_t *max); size_t *max);
void towire_addr_listen_announce(u8 **pptr, enum addr_listen_announce ala); void towire_addr_listen_announce(u8 **pptr, enum addr_listen_announce ala);
/* If no_dns is non-NULL, we will set it to true and return false if
* we wanted to do a DNS lookup. */
bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port, bool parse_wireaddr(const char *arg, struct wireaddr *addr, u16 port,
bool dns_ok, const char **err_msg); bool *no_dns, const char **err_msg);
char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a); char *fmt_wireaddr(const tal_t *ctx, const struct wireaddr *a);
char *fmt_wireaddr_without_port(const tal_t *ctx, const struct wireaddr *a); 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
* we wanted to do a DNS lookup. */
bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname, bool wireaddr_from_hostname(struct wireaddr *addr, const char *hostname,
const u16 port, bool dns_ok, const char **err_msg); const u16 port, bool *no_dns,
const char **err_msg);
void wireaddr_from_ipv4(struct wireaddr *addr, void wireaddr_from_ipv4(struct wireaddr *addr,
const struct in_addr *ip4, const struct in_addr *ip4,

10
gossipd/gossip.c

@ -1932,8 +1932,7 @@ static struct io_plan *conn_proxy_init(struct io_conn *conn,
} }
static struct addrhint * static struct addrhint *
seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port, seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port)
bool dns_ok)
{ {
struct addrhint *a; struct addrhint *a;
char bech32[100], *addr; char bech32[100], *addr;
@ -1949,7 +1948,7 @@ seed_resolve_addr(const tal_t *ctx, const struct pubkey *id, const u16 port,
a = tal(ctx, struct addrhint); a = tal(ctx, struct addrhint);
a->addr.itype = ADDR_INTERNAL_WIREADDR; a->addr.itype = ADDR_INTERNAL_WIREADDR;
if (!wireaddr_from_hostname(&a->addr.u.wireaddr, addr, port, dns_ok, if (!wireaddr_from_hostname(&a->addr.u.wireaddr, addr, port, NULL,
NULL)) { NULL)) {
status_trace("Could not resolve %s", addr); status_trace("Could not resolve %s", addr);
return tal_free(a); return tal_free(a);
@ -2036,9 +2035,8 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
daemon->rstate, daemon->rstate,
id); id);
if (!a) if (!a && !daemon->use_proxy_always)
a = seed_resolve_addr(tmpctx, id, 9735, a = seed_resolve_addr(tmpctx, id, 9735);
!daemon->use_proxy_always);
if (!a) { if (!a) {
status_debug("No address known for %s, giving up", status_debug("No address known for %s, giving up",

8
lightningd/options.c

@ -299,15 +299,17 @@ static char *opt_set_offline(struct lightningd *ld)
static char *opt_add_proxy_addr(const char *arg, struct lightningd *ld) static char *opt_add_proxy_addr(const char *arg, struct lightningd *ld)
{ {
bool needed_dns;
tal_free(ld->proxyaddr); tal_free(ld->proxyaddr);
/* We use a tal_arr here, so we can marshal it to gossipd */ /* We use a tal_arr here, so we can marshal it to gossipd */
ld->proxyaddr = tal_arr(ld, struct wireaddr, 1); ld->proxyaddr = tal_arr(ld, struct wireaddr, 1);
if (!parse_wireaddr(arg, ld->proxyaddr, 9050, !ld->use_proxy_always, if (!parse_wireaddr(arg, ld->proxyaddr, 9050,
ld->use_proxy_always ? &needed_dns : NULL,
NULL)) { NULL)) {
return tal_fmt(NULL, "Unable to parse Tor proxy address '%s'", return tal_fmt(NULL, "Unable to parse Tor proxy address '%s' %s",
arg); arg, needed_dns ? " (needed dns)" : "");
} }
return NULL; return NULL;
} }

Loading…
Cancel
Save