mirror of
https://github.com/ElementsProject/lightning.git
synced 2025-01-17 19:03:42 +01:00
wireaddr: new type, ADDR_INTERNAL_FORPROXY, use it if we can't/wont resolve.
Tor wasn't actually working for me to connect to anything, but it worked for 'ssh -D' testing. Note that the resulting 'netaddr' is a bit weird, but I guess it's honest. $ ./cli/lightning-cli connect 021f2cbffc4045ca2d70678ecf8ed75e488290874c9da38074f6d378248337062b { "id": "021f2cbffc4045ca2d70678ecf8ed75e488290874c9da38074f6d378248337062b" } $ ./cli/lightning-cli listpeers { "peers": [ { "state": "GOSSIPING", "id": "021f2cbffc4045ca2d70678ecf8ed75e488290874c9da38074f6d378248337062b", "netaddr": [ "ln1qg0je0lugpzu5ttsv78vlrkhteyg9yy8fjw68qr57mfhsfyrxurzkq522ah.lseed.bitcoinstats.com:9735" ], "connected": true, "owner": "lightning_gossipd" } ] } Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
parent
2a0acd3492
commit
1125682ceb
@ -83,6 +83,11 @@ void towire_wireaddr_internal(u8 **pptr, const struct wireaddr_internal *addr)
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
towire_wireaddr(pptr, &addr->u.wireaddr);
|
||||
return;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
towire_u8_array(pptr, (const u8 *)addr->u.unresolved.name,
|
||||
sizeof(addr->u.unresolved.name));
|
||||
towire_u16(pptr, addr->u.unresolved.port);
|
||||
return;
|
||||
}
|
||||
abort();
|
||||
}
|
||||
@ -106,6 +111,15 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max,
|
||||
return fromwire_wireaddr(cursor, max, &addr->u.torservice);
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return fromwire_wireaddr(cursor, max, &addr->u.wireaddr);
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
fromwire_u8_array(cursor, max, (u8 *)addr->u.unresolved.name,
|
||||
sizeof(addr->u.unresolved.name));
|
||||
/* Must be NUL terminated */
|
||||
if (!memchr(addr->u.unresolved.name, 0,
|
||||
sizeof(addr->u.unresolved.name)))
|
||||
fromwire_fail(cursor, max);
|
||||
addr->u.unresolved.port = fromwire_u16(cursor, max);
|
||||
return *cursor != NULL;
|
||||
}
|
||||
fromwire_fail(cursor, max);
|
||||
return false;
|
||||
@ -179,6 +193,9 @@ char *fmt_wireaddr_internal(const tal_t *ctx,
|
||||
return tal_fmt(ctx, ":%u", a->u.port);
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return fmt_wireaddr(ctx, &a->u.wireaddr);
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
return tal_fmt(ctx, "%s:%u",
|
||||
a->u.unresolved.name, a->u.unresolved.port);
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
return tal_fmt(ctx, "autotor:%s",
|
||||
fmt_wireaddr(tmpctx, &a->u.torservice));
|
||||
@ -383,11 +400,12 @@ finish:
|
||||
|
||||
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
u16 port, bool wildcard_ok, bool dns_ok,
|
||||
bool unresolved_ok,
|
||||
const char **err_msg)
|
||||
{
|
||||
u16 wildport;
|
||||
u16 splitport;
|
||||
char *ip;
|
||||
bool needed_dns;
|
||||
bool needed_dns = false;
|
||||
|
||||
/* Addresses starting with '/' are local socket paths */
|
||||
if (arg[0] == '/') {
|
||||
@ -405,12 +423,12 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
|
||||
/* An empty string means IPv4 and IPv6 (which under Linux by default
|
||||
* means just IPv6, and IPv4 gets autobound). */
|
||||
wildport = port;
|
||||
splitport = port;
|
||||
if (wildcard_ok
|
||||
&& separate_address_and_port(tmpctx, arg, &ip, &wildport)
|
||||
&& separate_address_and_port(tmpctx, arg, &ip, &splitport)
|
||||
&& streq(ip, "")) {
|
||||
addr->itype = ADDR_INTERNAL_ALLPROTO;
|
||||
addr->u.port = wildport;
|
||||
addr->u.port = splitport;
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -425,8 +443,33 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
}
|
||||
|
||||
addr->itype = ADDR_INTERNAL_WIREADDR;
|
||||
return parse_wireaddr(arg, &addr->u.wireaddr, port,
|
||||
dns_ok ? NULL : &needed_dns, err_msg);
|
||||
if (parse_wireaddr(arg, &addr->u.wireaddr, port,
|
||||
dns_ok ? NULL : &needed_dns, err_msg))
|
||||
return true;
|
||||
|
||||
if (!needed_dns || !unresolved_ok)
|
||||
return false;
|
||||
|
||||
/* We can't do DNS, so keep unresolved. */
|
||||
if (!wireaddr_from_unresolved(addr, ip, splitport)) {
|
||||
if (err_msg)
|
||||
*err_msg = "Name too long";
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
bool wireaddr_from_unresolved(struct wireaddr_internal *addr,
|
||||
const char *name, u16 port)
|
||||
{
|
||||
addr->itype = ADDR_INTERNAL_FORPROXY;
|
||||
if (strlen(name) >= sizeof(addr->u.unresolved.name))
|
||||
return false;
|
||||
|
||||
memset(addr->u.unresolved.name, 0, sizeof(addr->u.unresolved.name));
|
||||
strcpy(addr->u.unresolved.name, name);
|
||||
addr->u.unresolved.port = port;
|
||||
return true;
|
||||
}
|
||||
|
||||
void wireaddr_from_sockname(struct wireaddr_internal *addr,
|
||||
@ -466,6 +509,7 @@ struct addrinfo *wireaddr_internal_to_addrinfo(const tal_t *ctx,
|
||||
return ai;
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
return wireaddr_to_addrinfo(ctx, &wireaddr->u.wireaddr);
|
||||
@ -511,6 +555,8 @@ bool all_tor_addresses(const struct wireaddr_internal *wireaddr)
|
||||
switch (wireaddr[i].itype) {
|
||||
case ADDR_INTERNAL_SOCKNAME:
|
||||
return false;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
abort();
|
||||
case ADDR_INTERNAL_ALLPROTO:
|
||||
return false;
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
|
@ -104,6 +104,7 @@ enum wireaddr_internal_type {
|
||||
ADDR_INTERNAL_SOCKNAME,
|
||||
ADDR_INTERNAL_ALLPROTO,
|
||||
ADDR_INTERNAL_AUTOTOR,
|
||||
ADDR_INTERNAL_FORPROXY,
|
||||
ADDR_INTERNAL_WIREADDR,
|
||||
};
|
||||
|
||||
@ -117,13 +118,18 @@ struct wireaddr_internal {
|
||||
u16 port;
|
||||
/* ADDR_INTERNAL_AUTOTOR */
|
||||
struct wireaddr torservice;
|
||||
/* ADDR_INTERNAL_FORPROXY */
|
||||
struct unresolved {
|
||||
char name[256];
|
||||
u16 port;
|
||||
} unresolved;
|
||||
/* ADDR_INTERNAL_SOCKNAME */
|
||||
char sockname[sizeof(((struct sockaddr_un *)0)->sun_path)];
|
||||
} u;
|
||||
};
|
||||
bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr,
|
||||
u16 port, bool wildcard_ok, bool dns_ok,
|
||||
const char **err_msg);
|
||||
bool unresolved_ok, const char **err_msg);
|
||||
|
||||
void towire_wireaddr_internal(u8 **pptr,
|
||||
const struct wireaddr_internal *addr);
|
||||
@ -132,6 +138,9 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max,
|
||||
char *fmt_wireaddr_internal(const tal_t *ctx,
|
||||
const struct wireaddr_internal *a);
|
||||
|
||||
bool wireaddr_from_unresolved(struct wireaddr_internal *addr,
|
||||
const char *name, u16 port);
|
||||
|
||||
void wireaddr_from_sockname(struct wireaddr_internal *addr,
|
||||
const char *sockname);
|
||||
bool wireaddr_to_sockname(const struct wireaddr_internal *addr,
|
||||
|
@ -1711,6 +1711,8 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx,
|
||||
if (public_address(daemon, &wa.u.wireaddr))
|
||||
add_announcable(daemon, &wa.u.wireaddr);
|
||||
continue;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
break;
|
||||
}
|
||||
/* Shouldn't happen. */
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
@ -1911,6 +1913,10 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach)
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Can't reach to autotor address");
|
||||
break;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Can't reach to forproxy address");
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
/* If it was a Tor address, we wouldn't be here. */
|
||||
ai = wireaddr_to_addrinfo(tmpctx, &reach->addr.u.wireaddr);
|
||||
@ -1929,6 +1935,10 @@ static struct io_plan *conn_proxy_init(struct io_conn *conn,
|
||||
u16 port;
|
||||
|
||||
switch (reach->addr.itype) {
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
host = reach->addr.u.unresolved.name;
|
||||
port = reach->addr.u.unresolved.port;
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
host = fmt_wireaddr_without_port(tmpctx,
|
||||
&reach->addr.u.wireaddr);
|
||||
@ -2024,7 +2034,7 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
|
||||
int fd, af;
|
||||
struct reaching *reach;
|
||||
u8 *msg;
|
||||
bool use_proxy;
|
||||
bool use_proxy = daemon->use_proxy_always;
|
||||
struct peer *peer = find_peer(daemon, id);
|
||||
|
||||
if (peer) {
|
||||
@ -2063,8 +2073,16 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
|
||||
daemon->rstate,
|
||||
id);
|
||||
|
||||
if (!a && !daemon->use_proxy_always)
|
||||
if (!a) {
|
||||
/* Don't resolve via DNS seed if we're supposed to use proxy. */
|
||||
if (use_proxy) {
|
||||
a = tal(tmpctx, struct wireaddr_internal);
|
||||
wireaddr_from_unresolved(a, seedname(tmpctx, id),
|
||||
DEFAULT_PORT);
|
||||
} else {
|
||||
a = seed_resolve_addr(tmpctx, id);
|
||||
}
|
||||
}
|
||||
|
||||
if (!a) {
|
||||
status_debug("No address known for %s, giving up",
|
||||
@ -2080,7 +2098,6 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
|
||||
|
||||
/* Might not even be able to create eg. IPv6 sockets */
|
||||
af = -1;
|
||||
use_proxy = daemon->use_proxy_always;
|
||||
|
||||
switch (a->itype) {
|
||||
case ADDR_INTERNAL_SOCKNAME:
|
||||
@ -2094,6 +2111,9 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id,
|
||||
case ADDR_INTERNAL_AUTOTOR:
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Can't reach AUTOTOR");
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
use_proxy = true;
|
||||
break;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
switch (a->u.wireaddr.type) {
|
||||
case ADDR_TYPE_TOR_V2:
|
||||
|
@ -154,6 +154,7 @@ static void json_connect(struct command *cmd,
|
||||
if (!parse_wireaddr_internal(name, &addr, port, false,
|
||||
!cmd->ld->use_proxy_always
|
||||
&& !cmd->ld->pure_tor_setup,
|
||||
true,
|
||||
&err_msg)) {
|
||||
command_fail(cmd, "Host %s:%u not valid: %s",
|
||||
name, port, err_msg ? err_msg : "port is 0");
|
||||
|
@ -174,6 +174,13 @@ void json_add_address_internal(struct json_result *response,
|
||||
json_add_address(response, "service", &addr->u.torservice);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_FORPROXY:
|
||||
json_object_start(response, fieldname);
|
||||
json_add_string(response, "type", "unresolved");
|
||||
json_add_string(response, "name", addr->u.unresolved.name);
|
||||
json_add_num(response, "port", addr->u.unresolved.port);
|
||||
json_object_end(response);
|
||||
return;
|
||||
case ADDR_INTERNAL_WIREADDR:
|
||||
json_add_address(response, fieldname, &addr->u.wireaddr);
|
||||
return;
|
||||
|
@ -160,7 +160,7 @@ static char *opt_add_addr_withtype(const char *arg,
|
||||
ld->proposed_listen_announce[n] = ala;
|
||||
|
||||
if (!parse_wireaddr_internal(arg, &ld->proposed_wireaddr[n], ld->portnum,
|
||||
wildcard_ok, !ld->use_proxy_always,
|
||||
wildcard_ok, !ld->use_proxy_always, false,
|
||||
&err_msg)) {
|
||||
return tal_fmt(NULL, "Unable to parse address '%s': %s", arg, err_msg);
|
||||
}
|
||||
|
@ -510,7 +510,7 @@ static struct peer *wallet_peer_load(struct wallet *w, const u64 dbid)
|
||||
addrstr = sqlite3_column_text(stmt, 2);
|
||||
if (addrstr) {
|
||||
addrp = &addr;
|
||||
if (!parse_wireaddr_internal((const char*)addrstr, addrp, DEFAULT_PORT, false, false, NULL)) {
|
||||
if (!parse_wireaddr_internal((const char*)addrstr, addrp, DEFAULT_PORT, false, false, true, NULL)) {
|
||||
db_stmt_done(stmt);
|
||||
return NULL;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user