diff --git a/common/wireaddr.c b/common/wireaddr.c index 492eed0bef98..8c80f51e36b9 100644 --- a/common/wireaddr.c +++ b/common/wireaddr.c @@ -80,7 +80,8 @@ void towire_wireaddr_internal(u8 **pptr, const struct wireaddr_internal *addr) sizeof(addr->u.sockname)); return; case ADDR_INTERNAL_AUTOTOR: - towire_wireaddr(pptr, &addr->u.torservice); + towire_wireaddr(pptr, &addr->u.torservice.torservice_address); + towire_u16(pptr, addr->u.torservice.port); return; case ADDR_INTERNAL_ALLPROTO: towire_u16(pptr, addr->u.port); @@ -113,7 +114,9 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max, addr->u.port = fromwire_u16(cursor, max); return *cursor != NULL; case ADDR_INTERNAL_AUTOTOR: - return fromwire_wireaddr(cursor, max, &addr->u.torservice); + fromwire_wireaddr(cursor, max, &addr->u.torservice.torservice_address); + addr->u.torservice.port = fromwire_u16(cursor, max); + return *cursor != NULL; case ADDR_INTERNAL_WIREADDR: return fromwire_wireaddr(cursor, max, &addr->u.wireaddr); case ADDR_INTERNAL_FORPROXY: @@ -204,7 +207,7 @@ char *fmt_wireaddr_internal(const tal_t *ctx, a->u.unresolved.name, a->u.unresolved.port); case ADDR_INTERNAL_AUTOTOR: return tal_fmt(ctx, "autotor:%s", - fmt_wireaddr(tmpctx, &a->u.torservice)); + fmt_wireaddr(tmpctx, &a->u.torservice.torservice_address)); } abort(); } @@ -448,12 +451,32 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, return true; } + /* 'statictor:' is a special prefix meaning talk to Tor to create + * an onion address from a blob. */ + if (strstarts(arg, "autotor:") && + (strstr(arg, ":torport:"))) { + addr->itype = ADDR_INTERNAL_AUTOTOR; + char *temp = tal_fmt(tmpctx , "%.6s", strstr(arg, ":torport:") + strlen(":torport:")); + addr->u.torservice.port = atoi(temp); + if (strlen(temp) == 0) { + if (err_msg) + *err_msg = "port string too short"; + return false; + } + temp = tal_fmt(tmpctx, "%s", arg + strlen("autotor:")); + *(strstr(temp, ":torport:")) = '\0'; + return parse_wireaddr(temp, + &addr->u.torservice.torservice_address, 9051, + dns_ok ? NULL : &needed_dns, + err_msg); + } /* 'autotor:' is a special prefix meaning talk to Tor to create * an onion address. */ if (strstarts(arg, "autotor:")) { addr->itype = ADDR_INTERNAL_AUTOTOR; + addr->u.torservice.port = DEFAULT_PORT; return parse_wireaddr(arg + strlen("autotor:"), - &addr->u.torservice, 9051, + &addr->u.torservice.torservice_address, 9051, dns_ok ? NULL : &needed_dns, err_msg); } diff --git a/common/wireaddr.h b/common/wireaddr.h index 45cda29028ae..d11e5487ecf7 100644 --- a/common/wireaddr.h +++ b/common/wireaddr.h @@ -121,7 +121,10 @@ struct wireaddr_internal { /* ADDR_INTERNAL_ALLPROTO */ u16 port; /* ADDR_INTERNAL_AUTOTOR */ - struct wireaddr torservice; + struct torservice { + struct wireaddr torservice_address; + u16 port; + } torservice; /* ADDR_INTERNAL_FORPROXY */ struct unresolved { char name[256]; diff --git a/connectd/connectd.c b/connectd/connectd.c index a54c16b0110b..179d1d1619b6 100644 --- a/connectd/connectd.c +++ b/connectd/connectd.c @@ -1102,7 +1102,7 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, continue; if (!(proposed_listen_announce[i] & ADDR_ANNOUNCE)) { tor_autoservice(tmpctx, - &proposed_wireaddr[i].u.torservice, + &proposed_wireaddr[i], tor_password, binding, daemon->use_v3_autotor); @@ -1110,7 +1110,7 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, }; add_announcable(announcable, tor_autoservice(tmpctx, - &proposed_wireaddr[i].u.torservice, + &proposed_wireaddr[i], tor_password, binding, daemon->use_v3_autotor)); diff --git a/connectd/tor_autoservice.c b/connectd/tor_autoservice.c index abc8cbdca555..db61c5932ffb 100644 --- a/connectd/tor_autoservice.c +++ b/connectd/tor_autoservice.c @@ -74,7 +74,8 @@ static void discard_remaining_response(struct rbuf *rbuf) static struct wireaddr *make_onion(const tal_t *ctx, struct rbuf *rbuf, const struct wireaddr *local, - bool use_v3_autotor) + bool use_v3_autotor, + u16 port) { char *line; struct wireaddr *onion; @@ -102,12 +103,12 @@ static struct wireaddr *make_onion(const tal_t *ctx, tor_send_cmd(rbuf, tal_fmt(tmpctx, "ADD_ONION NEW:RSA1024 Port=%d,%s Flags=DiscardPK,Detach", /* FIXME: We *could* allow user to set Tor port */ - DEFAULT_PORT, fmt_wireaddr(tmpctx, local))); + port, fmt_wireaddr(tmpctx, local))); } else { tor_send_cmd(rbuf, tal_fmt(tmpctx, "ADD_ONION NEW:ED25519-V3 Port=%d,%s Flags=DiscardPK,Detach", /* FIXME: We *could* allow user to set Tor port */ - DEFAULT_PORT, fmt_wireaddr(tmpctx, local))); + port, fmt_wireaddr(tmpctx, local))); } while ((line = tor_response_line(rbuf)) != NULL) { @@ -122,10 +123,10 @@ static struct wireaddr *make_onion(const tal_t *ctx, name = tal_fmt(tmpctx, "%s.onion", line); onion = tal(ctx, struct wireaddr); - if (!parse_wireaddr(name, onion, DEFAULT_PORT, false, NULL)) + if (!parse_wireaddr(name, onion, local->port, false, NULL)) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Tor gave bad onion name '%s'", name); - status_info("New autotor service onion address: \"%s:%d\"", name, DEFAULT_PORT); + status_info("New autotor service onion address: \"%s:%d\" bound to extern-port:%d", name, local->port, port); discard_remaining_response(rbuf); return onion; } @@ -226,7 +227,7 @@ find_local_address(const struct wireaddr_internal *bindings) } struct wireaddr *tor_autoservice(const tal_t *ctx, - const struct wireaddr *tor_serviceaddr, + const struct wireaddr_internal *tor_serviceaddr, const char *tor_password, const struct wireaddr_internal *bindings, const bool use_v3_autotor) @@ -239,7 +240,7 @@ struct wireaddr *tor_autoservice(const tal_t *ctx, char *buffer; laddr = find_local_address(bindings); - ai_tor = wireaddr_to_addrinfo(tmpctx, tor_serviceaddr); + ai_tor = wireaddr_to_addrinfo(tmpctx, &tor_serviceaddr->u.torservice.torservice_address); fd = socket(ai_tor->ai_family, SOCK_STREAM, 0); if (fd < 0) @@ -252,7 +253,7 @@ struct wireaddr *tor_autoservice(const tal_t *ctx, rbuf_init(&rbuf, fd, buffer, tal_count(buffer), buf_resize); negotiate_auth(&rbuf, tor_password); - onion = make_onion(ctx, &rbuf, laddr, use_v3_autotor); + onion = make_onion(ctx, &rbuf, laddr, use_v3_autotor, tor_serviceaddr->u.torservice.port); /*on the other hand we can stay connected until ln finish to keep onion alive and then vanish */ //because when we run with Detach flag as we now do every start of LN creates a new addr while the old diff --git a/connectd/tor_autoservice.h b/connectd/tor_autoservice.h index 13b153c75c9d..ccec58e3e77c 100644 --- a/connectd/tor_autoservice.h +++ b/connectd/tor_autoservice.h @@ -7,7 +7,7 @@ #include struct wireaddr *tor_autoservice(const tal_t *ctx, - const struct wireaddr *tor_serviceaddr, + const struct wireaddr_internal *tor_serviceaddr, const char *tor_password, const struct wireaddr_internal *bindings, const bool use_v3_autotor); diff --git a/lightningd/json.c b/lightningd/json.c index fde8bec7fa7e..5f95f7a423d6 100644 --- a/lightningd/json.c +++ b/lightningd/json.c @@ -277,7 +277,7 @@ void json_add_address_internal(struct json_stream *response, case ADDR_INTERNAL_AUTOTOR: json_object_start(response, fieldname); json_add_string(response, "type", "Tor generated address"); - json_add_address(response, "service", &addr->u.torservice); + json_add_address(response, "service", &addr->u.torservice.torservice_address); json_object_end(response); return; case ADDR_INTERNAL_FORPROXY: