From 1106c40217b46a59db345822503649e239a22467 Mon Sep 17 00:00:00 2001 From: Rusty Russell Date: Thu, 10 May 2018 08:48:24 +0930 Subject: [PATCH] tor: add new 'autotor:' address option. This takes the Tor service address in the same option, rather than using a separate one. Gossipd now digests this like any other type. Signed-off-by: Rusty Russell --- common/wireaddr.c | 18 ++++++++++++++++ common/wireaddr.h | 3 +++ gossipd/gossip.c | 43 ++++++++++++++++++++++++------------- gossipd/gossip_wire.csv | 4 ---- lightningd/gossip_control.c | 7 ++---- lightningd/json.c | 6 ++++++ lightningd/lightningd.c | 1 - lightningd/lightningd.h | 4 ---- lightningd/options.c | 29 ------------------------- 9 files changed, 57 insertions(+), 58 deletions(-) diff --git a/common/wireaddr.c b/common/wireaddr.c index 481fbd576..92b8d618f 100644 --- a/common/wireaddr.c +++ b/common/wireaddr.c @@ -74,6 +74,9 @@ void towire_wireaddr_internal(u8 **pptr, const struct wireaddr_internal *addr) towire_u8_array(pptr, (const u8 *)addr->u.sockname, sizeof(addr->u.sockname)); return; + case ADDR_INTERNAL_AUTOTOR: + towire_wireaddr(pptr, &addr->u.torservice); + return; case ADDR_INTERNAL_ALLPROTO: towire_u16(pptr, addr->u.port); return; @@ -99,6 +102,8 @@ bool fromwire_wireaddr_internal(const u8 **cursor, size_t *max, case ADDR_INTERNAL_ALLPROTO: addr->u.port = fromwire_u16(cursor, max); return *cursor != NULL; + case ADDR_INTERNAL_AUTOTOR: + return fromwire_wireaddr(cursor, max, &addr->u.torservice); case ADDR_INTERNAL_WIREADDR: return fromwire_wireaddr(cursor, max, &addr->u.wireaddr); } @@ -174,6 +179,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_AUTOTOR: + return tal_fmt(ctx, "autotor:%s", + fmt_wireaddr(tmpctx, &a->u.torservice)); } abort(); } @@ -394,6 +402,15 @@ bool parse_wireaddr_internal(const char *arg, struct wireaddr_internal *addr, return true; } + /* 'autotor:' is a special prefix meaning talk to Tor to create + * an onion address. */ + if (strstarts(arg, "autotor:")) { + addr->itype = ADDR_INTERNAL_AUTOTOR; + return parse_wireaddr(arg + strlen("autotor:"), + &addr->u.torservice, 9051, dns_ok, + err_msg); + } + addr->itype = ADDR_INTERNAL_WIREADDR; return parse_wireaddr(arg, &addr->u.wireaddr, port, dns_ok, err_msg); } @@ -434,6 +451,7 @@ struct addrinfo *wireaddr_internal_to_addrinfo(const tal_t *ctx, ai->ai_addr = (struct sockaddr *)sun; return ai; case ADDR_INTERNAL_ALLPROTO: + case ADDR_INTERNAL_AUTOTOR: break; case ADDR_INTERNAL_WIREADDR: return wireaddr_to_addrinfo(ctx, &wireaddr->u.wireaddr); diff --git a/common/wireaddr.h b/common/wireaddr.h index 7e07e9eef..3c4c64ea5 100644 --- a/common/wireaddr.h +++ b/common/wireaddr.h @@ -98,6 +98,7 @@ bool wireaddr_is_wildcard(const struct wireaddr *addr); enum wireaddr_internal_type { ADDR_INTERNAL_SOCKNAME, ADDR_INTERNAL_ALLPROTO, + ADDR_INTERNAL_AUTOTOR, ADDR_INTERNAL_WIREADDR, }; @@ -109,6 +110,8 @@ struct wireaddr_internal { struct wireaddr wireaddr; /* ADDR_INTERNAL_ALLPROTO */ u16 port; + /* ADDR_INTERNAL_AUTOTOR */ + struct wireaddr torservice; /* ADDR_INTERNAL_SOCKNAME */ char sockname[sizeof(((struct sockaddr_un *)0)->sun_path)]; } u; diff --git a/gossipd/gossip.c b/gossipd/gossip.c index 23e5975b5..4fa5eb7db 100644 --- a/gossipd/gossip.c +++ b/gossipd/gossip.c @@ -150,9 +150,6 @@ struct daemon { struct addrinfo *proxyaddr; bool use_proxy_always; - - bool tor_autoservice; - struct wireaddr *tor_serviceaddr; char *tor_password; }; @@ -1689,6 +1686,9 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, /* We don't announce socket names */ add_binding(&binding, &wa); continue; + case ADDR_INTERNAL_AUTOTOR: + /* We handle these after we have all bindings. */ + continue; case ADDR_INTERNAL_ALLPROTO: { bool ipv6_ok; @@ -1732,6 +1732,20 @@ static struct wireaddr_internal *setup_listeners(const tal_t *ctx, daemon->proposed_wireaddr[i].itype); } + /* Now we have bindings, set up any Tor auto addresses */ + for (size_t i = 0; i < tal_count(daemon->proposed_wireaddr); i++) { + if (!(daemon->proposed_listen_announce[i] & ADDR_LISTEN)) + continue; + + if (daemon->proposed_wireaddr[i].itype != ADDR_INTERNAL_AUTOTOR) + continue; + + add_announcable(daemon, + tor_autoservice(tmpctx, + &daemon->proposed_wireaddr[i].u.torservice, + daemon->tor_password, + binding)); + } return binding; } @@ -1754,8 +1768,8 @@ static struct io_plan *gossip_init(struct daemon_conn *master, &daemon->proposed_listen_announce, daemon->rgb, daemon->alias, &update_channel_interval, &daemon->reconnect, &proxyaddr, &daemon->use_proxy_always, - &dev_allow_localhost, &daemon->tor_autoservice, - &daemon->tor_serviceaddr, &daemon->tor_password)) { + &dev_allow_localhost, + &daemon->tor_password)) { master_badmsg(WIRE_GOSSIPCTL_INIT, msg); } /* Prune time is twice update time */ @@ -1791,17 +1805,9 @@ static struct io_plan *gossip_activate(struct daemon_conn *master, if (!fromwire_gossipctl_activate(msg, &listen)) master_badmsg(WIRE_GOSSIPCTL_ACTIVATE, msg); - if (listen) { + if (listen) binding = setup_listeners(tmpctx, daemon); - if (daemon->tor_autoservice) { - struct wireaddr *tor; - tor = tor_autoservice(tmpctx, - daemon->tor_serviceaddr, - daemon->tor_password, - binding); - add_announcable(daemon, tor); - } - } else + else binding = NULL; /* If we only advertize Tor addresses, force everything through proxy @@ -1924,6 +1930,10 @@ static struct io_plan *conn_init(struct io_conn *conn, struct reaching *reach) status_failed(STATUS_FAIL_INTERNAL_ERROR, "Can't reach to all protocols"); break; + case ADDR_INTERNAL_AUTOTOR: + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Can't reach to autotor 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); @@ -2078,6 +2088,9 @@ static void try_reach_peer(struct daemon *daemon, const struct pubkey *id, case ADDR_INTERNAL_ALLPROTO: status_failed(STATUS_FAIL_INTERNAL_ERROR, "Can't reach ALLPROTO"); + case ADDR_INTERNAL_AUTOTOR: + status_failed(STATUS_FAIL_INTERNAL_ERROR, + "Can't reach AUTOTOR"); case ADDR_INTERNAL_WIREADDR: switch (a->addr.u.wireaddr.type) { case ADDR_TYPE_TOR_V2: diff --git a/gossipd/gossip_wire.csv b/gossipd/gossip_wire.csv index 7dc3c762b..9b4efb0c6 100644 --- a/gossipd/gossip_wire.csv +++ b/gossipd/gossip_wire.csv @@ -23,10 +23,6 @@ gossipctl_init,,num_tor_proxyaddrs,u16 gossipctl_init,,tor_proxyaddr,num_tor_proxyaddrs*struct wireaddr gossipctl_init,,use_tor_proxy_always,bool gossipctl_init,,dev_allow_localhost,bool -gossipctl_init,,tor_autoservice,bool -# This is 0 or 1. -gossipctl_init,,num_tor_serviceaddrs,u16 -gossipctl_init,,tor_serviceaddr,num_tor_serviceaddrs*struct wireaddr gossipctl_init,,tor_password,wirestring # Activate the gossip daemon, so others can connect. diff --git a/lightningd/gossip_control.c b/lightningd/gossip_control.c index b623b919e..ffd030669 100644 --- a/lightningd/gossip_control.c +++ b/lightningd/gossip_control.c @@ -209,9 +209,8 @@ void gossip_init(struct lightningd *ld) if (!ld->gossip) err(1, "Could not subdaemon gossip"); - /* If no addr (not even Tor auto) specified, hand wildcard to gossipd */ - if (tal_count(wireaddrs) == 0 && ld->autolisten - && !ld->config.tor_enable_auto_hidden_service) { + /* If no addr specified, hand wildcard to gossipd */ + if (tal_count(wireaddrs) == 0 && ld->autolisten) { wireaddrs = tal_arrz(tmpctx, struct wireaddr_internal, 1); listen_announce = tal_arr(tmpctx, enum addr_listen_announce, 1); wireaddrs->itype = ADDR_INTERNAL_ALLPROTO; @@ -228,8 +227,6 @@ void gossip_init(struct lightningd *ld) ld->alias, ld->config.channel_update_interval, ld->reconnect, ld->proxyaddr, ld->use_proxy_always, allow_localhost, - ld->config.tor_enable_auto_hidden_service, - ld->tor_serviceaddr, ld->tor_service_password ? ld->tor_service_password : ""); subd_send_msg(ld->gossip, msg); } diff --git a/lightningd/json.c b/lightningd/json.c index 88cadf2e9..6dde05f4b 100644 --- a/lightningd/json.c +++ b/lightningd/json.c @@ -168,6 +168,12 @@ void json_add_address_internal(struct json_result *response, json_add_num(response, "port", addr->u.port); json_object_end(response); return; + 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_object_end(response); + return; case ADDR_INTERNAL_WIREADDR: json_add_address(response, fieldname, &addr->u.wireaddr); return; diff --git a/lightningd/lightningd.c b/lightningd/lightningd.c index f30b4314b..642b20c3a 100644 --- a/lightningd/lightningd.c +++ b/lightningd/lightningd.c @@ -86,7 +86,6 @@ static struct lightningd *new_lightningd(const tal_t *ctx) ld->proxyaddr = NULL; ld->use_proxy_always = false; ld->tor_service_password = NULL; - ld->tor_serviceaddr = NULL; return ld; } diff --git a/lightningd/lightningd.h b/lightningd/lightningd.h index 856fd0a04..755f7a4db 100644 --- a/lightningd/lightningd.h +++ b/lightningd/lightningd.h @@ -70,9 +70,6 @@ struct config { * blockheight if rescan >= 500'000 */ s32 rescan; - /* tor support */ - bool tor_enable_auto_hidden_service; - /* ipv6 bind disable */ bool no_ipv6_bind; }; @@ -198,7 +195,6 @@ struct lightningd { /* tor support */ struct wireaddr *proxyaddr; bool use_proxy_always; - struct wireaddr *tor_serviceaddr; char *tor_service_password; }; diff --git a/lightningd/options.c b/lightningd/options.c index 8f202acd5..c8a3361d2 100644 --- a/lightningd/options.c +++ b/lightningd/options.c @@ -310,18 +310,6 @@ static char *opt_add_proxy_addr(const char *arg, struct lightningd *ld) return NULL; } -static char *opt_add_tor_service_addr(const char *arg, struct lightningd *ld) -{ - tal_free(ld->tor_serviceaddr); - ld->tor_serviceaddr = tal(ld, struct wireaddr); - if (!parse_wireaddr(arg, ld->tor_serviceaddr, 9051, - !ld->use_proxy_always, NULL)) { - return tal_fmt(NULL, "Unable to parse Tor service address '%s'", - arg); - } - return NULL; -} - static void config_register_opts(struct lightningd *ld) { opt_register_noarg("--daemon", opt_set_bool, &ld->daemon, @@ -427,13 +415,9 @@ static void config_register_opts(struct lightningd *ld) "If expired invoice autoclean enabled, invoices that have expired for at least this given seconds are cleaned"); opt_register_arg("--proxy", opt_add_proxy_addr, NULL, ld,"Set a socks v5 proxy IP address and port"); - opt_register_arg("--tor-service",opt_add_tor_service_addr, NULL, - ld,"Set a tor service api IP address and port"); opt_register_arg("--tor-service-password", opt_set_talstr, NULL, &ld->tor_service_password, "Set a Tor hidden service password"); - opt_register_arg("--tor-auto-listen", opt_set_bool_arg, opt_show_bool, - &ld->config.tor_enable_auto_hidden_service , "Generate and use a temp auto hidden-service and show the onion address"); /* Early, as it suppresses DNS lookups from cmdline too. */ opt_register_early_arg("--always-use-proxy", @@ -515,9 +499,6 @@ static const struct config testnet_config = { /* Rescan 5 hours of blocks on testnet, it's reorg happy */ .rescan = 30, - - /* tor support */ - .tor_enable_auto_hidden_service = false }; /* aka. "Dude, where's my coins?" */ @@ -582,9 +563,6 @@ static const struct config mainnet_config = { /* Rescan 2.5 hours of blocks on startup, it's not so reorg happy */ .rescan = 15, - - - .tor_enable_auto_hidden_service = false }; static void check_config(struct lightningd *ld) @@ -600,9 +578,6 @@ static void check_config(struct lightningd *ld) if (ld->config.anchor_confirms == 0) fatal("anchor-confirms must be greater than zero"); - if (ld->config.tor_enable_auto_hidden_service && !ld->tor_serviceaddr) - fatal("--tor-auto-listen needs --tor-service"); - if (ld->use_proxy_always && !ld->proxyaddr) fatal("--always-use-proxy needs --proxy"); } @@ -993,10 +968,6 @@ static void add_config(struct lightningd *ld, } else if (opt->cb_arg == (void *)opt_add_proxy_addr) { if (ld->proxyaddr) answer = fmt_wireaddr(name0, ld->proxyaddr); - } else if (opt->cb_arg == (void *)opt_add_tor_service_addr) { - if (ld->tor_serviceaddr) - answer = fmt_wireaddr(name0, - ld->tor_serviceaddr); #if DEVELOPER } else if (strstarts(name, "dev-")) { /* Ignore dev settings */