mirror of
https://github.com/aljazceru/lightning.git
synced 2025-12-19 15:14:23 +01:00
gossipd: take over negotiation of autogenerated Tor addresses.
For the moment, this is a straight handing of current parameters through from master to the gossip daemon. Next we'll change that. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -15,6 +15,14 @@ struct sockaddr_in6;
|
||||
struct sockaddr_in;
|
||||
struct sockaddr_un;
|
||||
|
||||
/* BOLT #1:
|
||||
*
|
||||
* The default TCP port is 9735. This corresponds to hexadecimal
|
||||
* `0x2607`, the Unicode code point for LIGHTNING.
|
||||
*/
|
||||
#define DEFAULT_PORT 9735
|
||||
|
||||
|
||||
/* BOLT #7:
|
||||
*
|
||||
* The following `address descriptor` types are defined:
|
||||
|
||||
@@ -19,6 +19,7 @@ LIGHTNINGD_GOSSIP_HEADERS := gossipd/gen_gossip_wire.h \
|
||||
gossipd/handshake.h \
|
||||
gossipd/netaddress.h \
|
||||
gossipd/routing.h \
|
||||
gossipd/tor_autoservice.h \
|
||||
gossipd/tor.h \
|
||||
gossipd/broadcast.h
|
||||
LIGHTNINGD_GOSSIP_SRC := $(LIGHTNINGD_GOSSIP_HEADERS:.h=.c)
|
||||
|
||||
@@ -38,6 +38,7 @@
|
||||
#include <gossipd/netaddress.h>
|
||||
#include <gossipd/routing.h>
|
||||
#include <gossipd/tor.h>
|
||||
#include <gossipd/tor_autoservice.h>
|
||||
#include <hsmd/client.h>
|
||||
#include <hsmd/gen_hsm_client_wire.h>
|
||||
#include <inttypes.h>
|
||||
@@ -149,6 +150,11 @@ struct daemon {
|
||||
|
||||
struct addrinfo *proxyaddr;
|
||||
bool use_proxy_always;
|
||||
|
||||
bool tor_autoservice;
|
||||
struct wireaddr *tor_serviceaddr;
|
||||
char *tor_password;
|
||||
|
||||
};
|
||||
|
||||
/* Peers we're trying to reach. */
|
||||
@@ -1748,7 +1754,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)) {
|
||||
&dev_allow_localhost, &daemon->tor_autoservice,
|
||||
&daemon->tor_serviceaddr, &daemon->tor_password)) {
|
||||
master_badmsg(WIRE_GOSSIPCTL_INIT, msg);
|
||||
}
|
||||
/* Prune time is twice update time */
|
||||
@@ -1784,9 +1791,17 @@ 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);
|
||||
else
|
||||
if (daemon->tor_autoservice) {
|
||||
struct wireaddr *tor;
|
||||
tor = tor_autoservice(tmpctx,
|
||||
daemon->tor_serviceaddr,
|
||||
daemon->tor_password,
|
||||
binding);
|
||||
add_announcable(daemon, tor);
|
||||
}
|
||||
} else
|
||||
binding = NULL;
|
||||
|
||||
/* If we only advertize Tor addresses, force everything through proxy
|
||||
|
||||
@@ -23,6 +23,11 @@ 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.
|
||||
gossipctl_activate,3025
|
||||
|
||||
|
@@ -12,8 +12,8 @@
|
||||
#include <common/wireaddr.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <gossipd/tor_autoservice.h>
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/tor.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/socket.h>
|
||||
@@ -32,28 +32,30 @@ static void *buf_resize(void *buf, size_t len)
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void tor_send_cmd(struct lightningd *ld,
|
||||
struct rbuf *rbuf, const char *cmd)
|
||||
static void tor_send_cmd(struct rbuf *rbuf, const char *cmd)
|
||||
{
|
||||
log_io(ld->log, LOG_IO_OUT, "torcontrol", cmd, strlen(cmd));
|
||||
status_io(LOG_IO_OUT, "torcontrol", cmd, strlen(cmd));
|
||||
if (!write_all(rbuf->fd, cmd, strlen(cmd)))
|
||||
err(1, "Writing '%s' to Tor socket", cmd);
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Writing '%s' to Tor socket", cmd);
|
||||
|
||||
log_io(ld->log, LOG_IO_OUT, "torcontrol", "\r\n", 2);
|
||||
status_io(LOG_IO_OUT, "torcontrol", "\r\n", 2);
|
||||
if (!write_all(rbuf->fd, "\r\n", 2))
|
||||
err(1, "Writing CRLF to Tor socket");
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Writing CRLF to Tor socket");
|
||||
}
|
||||
|
||||
static char *tor_response_line(struct lightningd *ld, struct rbuf *rbuf)
|
||||
static char *tor_response_line(struct rbuf *rbuf)
|
||||
{
|
||||
char *line;
|
||||
|
||||
while ((line = rbuf_read_str(rbuf, '\n', buf_resize)) != NULL) {
|
||||
log_io(ld->log, LOG_IO_IN, "torcontrol", line, strlen(line));
|
||||
status_io(LOG_IO_IN, "torcontrol", line, strlen(line));
|
||||
|
||||
/* Weird response */
|
||||
if (!strstarts(line, "250"))
|
||||
errx(1, "Tor returned '%s'", line);
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Tor returned '%s'", line);
|
||||
|
||||
/* Last line */
|
||||
if (strstarts(line, "250 "))
|
||||
@@ -64,23 +66,27 @@ static char *tor_response_line(struct lightningd *ld, struct rbuf *rbuf)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void discard_remaining_response(struct lightningd *ld, struct rbuf *rbuf)
|
||||
static void discard_remaining_response(struct rbuf *rbuf)
|
||||
{
|
||||
while (tor_response_line(ld, rbuf));
|
||||
while (tor_response_line(rbuf));
|
||||
}
|
||||
|
||||
static void make_onion(struct lightningd *ld, struct rbuf *rbuf)
|
||||
static struct wireaddr *make_onion(const tal_t *ctx,
|
||||
struct rbuf *rbuf,
|
||||
const struct wireaddr *local)
|
||||
{
|
||||
char *line;
|
||||
struct wireaddr *onion;
|
||||
|
||||
//V3 tor after 3.3.3.aplha FIXME: TODO SAIBATO
|
||||
//sprintf((char *)reach->buffer,"ADD_ONION NEW:ED25519-V3 Port=9735,127.0.0.1:9735\r\n");
|
||||
tor_send_cmd(ld, rbuf,
|
||||
tal_fmt(tmpctx, "ADD_ONION NEW:RSA1024 Port=%d,127.0.0.1:%d Flags=DiscardPK,Detach",
|
||||
ld->portnum, ld->portnum));
|
||||
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)));
|
||||
|
||||
while ((line = tor_response_line(ld, rbuf)) != NULL) {
|
||||
size_t n;
|
||||
while ((line = tor_response_line(rbuf)) != NULL) {
|
||||
const char *name;
|
||||
|
||||
if (!strstarts(line, "ServiceID="))
|
||||
continue;
|
||||
@@ -89,17 +95,16 @@ static void make_onion(struct lightningd *ld, struct rbuf *rbuf)
|
||||
if (strchr(line, '\r'))
|
||||
*strchr(line, '\r') = '\0';
|
||||
|
||||
n = tal_count(ld->proposed_wireaddr);
|
||||
tal_resize(&ld->proposed_wireaddr, n + 1);
|
||||
tal_resize(&ld->proposed_listen_announce, n + 1);
|
||||
parse_wireaddr_internal(tal_fmt(tmpctx, "%s.onion", line),
|
||||
&ld->proposed_wireaddr[n],
|
||||
ld->portnum, false, false, NULL);
|
||||
ld->proposed_listen_announce[n] = ADDR_ANNOUNCE;
|
||||
discard_remaining_response(ld, rbuf);
|
||||
return;
|
||||
name = tal_fmt(tmpctx, "%s.onion", line);
|
||||
onion = tal(ctx, struct wireaddr);
|
||||
if (!parse_wireaddr(name, onion, 0, false, NULL))
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Tor gave bad onion name '%s'", name);
|
||||
discard_remaining_response(rbuf);
|
||||
return onion;
|
||||
}
|
||||
errx(1, "Tor didn't give us a ServiceID");
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Tor didn't give us a ServiceID");
|
||||
}
|
||||
|
||||
/* https://gitweb.torproject.org/torspec.git/tree/control-spec.txt:
|
||||
@@ -111,32 +116,32 @@ static void make_onion(struct lightningd *ld, struct rbuf *rbuf)
|
||||
* ReplyText = XXXX
|
||||
* StatusCode = 3DIGIT
|
||||
*/
|
||||
static void negotiate_auth(struct lightningd *ld, struct rbuf *rbuf)
|
||||
static void negotiate_auth(struct rbuf *rbuf, const char *tor_password)
|
||||
{
|
||||
char *line;
|
||||
char *cookiefile = NULL;
|
||||
int cookiefileerrno;
|
||||
|
||||
tor_send_cmd(ld, rbuf, "PROTOCOLINFO 1");
|
||||
tor_send_cmd(rbuf, "PROTOCOLINFO 1");
|
||||
|
||||
while ((line = tor_response_line(ld, rbuf)) != NULL) {
|
||||
while ((line = tor_response_line(rbuf)) != NULL) {
|
||||
const char *p;
|
||||
|
||||
if (!strstarts(line, "AUTH METHODS="))
|
||||
continue;
|
||||
|
||||
if (strstr(line, "NULL")) {
|
||||
discard_remaining_response(ld, rbuf);
|
||||
tor_send_cmd(ld, rbuf, "AUTHENTICATE");
|
||||
discard_remaining_response(ld, rbuf);
|
||||
discard_remaining_response(rbuf);
|
||||
tor_send_cmd(rbuf, "AUTHENTICATE");
|
||||
discard_remaining_response(rbuf);
|
||||
return;
|
||||
} else if (strstr(line, "HASHEDPASSWORD")
|
||||
&& strlen(ld->tor_service_password)) {
|
||||
discard_remaining_response(ld, rbuf);
|
||||
tor_send_cmd(ld, rbuf,
|
||||
&& strlen(tor_password)) {
|
||||
discard_remaining_response(rbuf);
|
||||
tor_send_cmd(rbuf,
|
||||
tal_fmt(tmpctx, "AUTHENTICATE \"%s\"",
|
||||
ld->tor_service_password));
|
||||
discard_remaining_response(ld, rbuf);
|
||||
tor_password));
|
||||
discard_remaining_response(rbuf);
|
||||
return;
|
||||
} else if ((p = strstr(line, "COOKIEFILE=\"")) != NULL) {
|
||||
char *contents, *end;
|
||||
@@ -144,7 +149,9 @@ static void negotiate_auth(struct lightningd *ld, struct rbuf *rbuf)
|
||||
p += strlen("COOKIEFILE=\"");
|
||||
end = strstr(p, "\"");
|
||||
if (!end)
|
||||
errx(1, "Tor protocolinfo bad line '%s'", line);
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Tor protocolinfo bad line '%s'",
|
||||
line);
|
||||
*end = '\0';
|
||||
|
||||
/* If we can't access this, try other methods */
|
||||
@@ -152,44 +159,59 @@ static void negotiate_auth(struct lightningd *ld, struct rbuf *rbuf)
|
||||
contents = grab_file(tmpctx, p);
|
||||
if (!contents) {
|
||||
cookiefileerrno = errno;
|
||||
fprintf(stderr, "No cookies for me!\n");
|
||||
continue;
|
||||
}
|
||||
discard_remaining_response(ld, rbuf);
|
||||
tor_send_cmd(ld, rbuf,
|
||||
discard_remaining_response(rbuf);
|
||||
tor_send_cmd(rbuf,
|
||||
tal_fmt(tmpctx, "AUTHENTICATE %s",
|
||||
tal_hexstr(tmpctx,
|
||||
contents,
|
||||
tal_len(contents)-1)));
|
||||
discard_remaining_response(ld, rbuf);
|
||||
discard_remaining_response(rbuf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* Now report if we tried cookie file and it failed */
|
||||
if (cookiefile) {
|
||||
errno = cookiefileerrno;
|
||||
err(1, "Could not open Tor cookie file '%s'", cookiefile);
|
||||
}
|
||||
if (cookiefile)
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Could not open Tor cookie file '%s': %s",
|
||||
cookiefile, strerror(cookiefileerrno));
|
||||
|
||||
errx(1, "Tor protocolinfo did not give auth");
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"Tor protocolinfo did not give auth");
|
||||
}
|
||||
|
||||
void tor_init(struct lightningd *ld)
|
||||
/* We need to have a bound address we can tell Tor to connect to */
|
||||
static const struct wireaddr *
|
||||
find_local_address(const struct wireaddr_internal *bindings)
|
||||
{
|
||||
for (size_t i = 0; i < tal_count(bindings); i++) {
|
||||
if (bindings[i].itype != ADDR_INTERNAL_WIREADDR)
|
||||
continue;
|
||||
if (bindings[i].u.wireaddr.type != ADDR_TYPE_IPV4
|
||||
&& bindings[i].u.wireaddr.type != ADDR_TYPE_IPV6)
|
||||
continue;
|
||||
return &bindings[i].u.wireaddr;
|
||||
}
|
||||
status_failed(STATUS_FAIL_INTERNAL_ERROR,
|
||||
"No local address found to tell Tor to connect to");
|
||||
}
|
||||
|
||||
struct wireaddr *tor_autoservice(const tal_t *ctx,
|
||||
const struct wireaddr *tor_serviceaddr,
|
||||
const char *tor_password,
|
||||
const struct wireaddr_internal *bindings)
|
||||
{
|
||||
int fd;
|
||||
const struct wireaddr *laddr;
|
||||
struct wireaddr *onion;
|
||||
struct addrinfo *ai_tor;
|
||||
struct rbuf rbuf;
|
||||
char *buffer;
|
||||
|
||||
if (!ld->config.tor_enable_auto_hidden_service)
|
||||
return;
|
||||
|
||||
/* FIXME: Need better way to convert wireaddr to addrinfo... */
|
||||
if (getaddrinfo(fmt_wireaddr_without_port(ld, ld->tor_serviceaddr),
|
||||
tal_fmt(tmpctx, "%d", ld->tor_serviceaddr->port), NULL,
|
||||
&ai_tor) != 0)
|
||||
errx(1, "getaddrinfo failed for Tor service");
|
||||
laddr = find_local_address(bindings);
|
||||
ai_tor = wireaddr_to_addrinfo(tmpctx, tor_serviceaddr);
|
||||
|
||||
fd = socket(ai_tor->ai_family, SOCK_STREAM, 0);
|
||||
if (fd < 0)
|
||||
@@ -201,8 +223,8 @@ void tor_init(struct lightningd *ld)
|
||||
buffer = tal_arr(tmpctx, char, rbuf_good_size(fd));
|
||||
rbuf_init(&rbuf, fd, buffer, tal_len(buffer));
|
||||
|
||||
negotiate_auth(ld, &rbuf);
|
||||
make_onion(ld, &rbuf);
|
||||
negotiate_auth(&rbuf, tor_password);
|
||||
onion = make_onion(ctx, &rbuf, laddr);
|
||||
|
||||
/*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
|
||||
@@ -210,4 +232,6 @@ void tor_init(struct lightningd *ld)
|
||||
//read_partial to keep it open until LN drops
|
||||
//FIXME: SAIBATO we might not want to close this conn
|
||||
close(fd);
|
||||
|
||||
return onion;
|
||||
}
|
||||
14
gossipd/tor_autoservice.h
Normal file
14
gossipd/tor_autoservice.h
Normal file
@@ -0,0 +1,14 @@
|
||||
#ifndef LIGHTNING_GOSSIPD_TOR_AUTOSERVICE_H
|
||||
#define LIGHTNING_GOSSIPD_TOR_AUTOSERVICE_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
struct wireaddr *tor_autoservice(const tal_t *ctx,
|
||||
const struct wireaddr *tor_serviceaddr,
|
||||
const char *tor_password,
|
||||
const struct wireaddr_internal *bindings);
|
||||
|
||||
#endif /* LIGHTNING_GOSSIPD_TOR_AUTOSERVICE_H */
|
||||
@@ -76,7 +76,6 @@ LIGHTNINGD_SRC := \
|
||||
lightningd/peer_control.c \
|
||||
lightningd/peer_htlcs.c \
|
||||
lightningd/subd.c \
|
||||
lightningd/tor.c \
|
||||
lightningd/watch.c
|
||||
|
||||
# Source files without corresponding headers
|
||||
|
||||
@@ -227,7 +227,10 @@ void gossip_init(struct lightningd *ld)
|
||||
listen_announce, ld->rgb,
|
||||
ld->alias, ld->config.channel_update_interval, ld->reconnect,
|
||||
ld->proxyaddr, ld->use_proxy_always,
|
||||
allow_localhost);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -32,7 +32,6 @@
|
||||
#include <lightningd/log.h>
|
||||
#include <lightningd/onchain_control.h>
|
||||
#include <lightningd/options.h>
|
||||
#include <lightningd/tor.h>
|
||||
#include <onchaind/onchain_wire.h>
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
@@ -316,9 +315,6 @@ int main(int argc, char *argv[])
|
||||
/* Ignore SIGPIPE: we look at our write return values*/
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
|
||||
/* tor support */
|
||||
tor_init(ld);
|
||||
|
||||
/* Make sure we can reach other daemons, and versions match. */
|
||||
test_daemons(ld);
|
||||
|
||||
|
||||
@@ -12,13 +12,6 @@
|
||||
#include <wallet/txfilter.h>
|
||||
#include <wallet/wallet.h>
|
||||
|
||||
/* BOLT #1:
|
||||
*
|
||||
* The default TCP port is 9735. This corresponds to hexadecimal
|
||||
* `0x2607`, the Unicode code point for LIGHTNING.
|
||||
*/
|
||||
#define DEFAULT_PORT 9735
|
||||
|
||||
/* Various adjustable things. */
|
||||
struct config {
|
||||
/* How long do we want them to lock up their funds? (blocks) */
|
||||
|
||||
@@ -104,9 +104,6 @@ void subd_shutdown(struct subd *subd UNNEEDED, unsigned int seconds UNNEEDED)
|
||||
/* Generated stub for timer_expired */
|
||||
void timer_expired(tal_t *ctx UNNEEDED, struct timer *timer UNNEEDED)
|
||||
{ fprintf(stderr, "timer_expired called!\n"); abort(); }
|
||||
/* Generated stub for tor_init */
|
||||
void tor_init(struct lightningd *ld UNNEEDED)
|
||||
{ fprintf(stderr, "tor_init called!\n"); abort(); }
|
||||
/* Generated stub for txfilter_add_derkey */
|
||||
void txfilter_add_derkey(struct txfilter *filter UNNEEDED,
|
||||
const u8 derkey[PUBKEY_DER_LEN])
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
#ifndef LIGHTNING_LIGHTNINGD_TOR_H
|
||||
#define LIGHTNING_LIGHTNINGD_TOR_H
|
||||
#include "config.h"
|
||||
#include <ccan/short_types/short_types.h>
|
||||
#include <ccan/tal/tal.h>
|
||||
#include <lightningd/lightningd.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
void tor_init(struct lightningd *ld);
|
||||
#endif /* LIGHTNING_LIGHTNINGD_TOR_H */
|
||||
Reference in New Issue
Block a user