2018-02-20 21:59:09 +01:00
|
|
|
#include <bitcoin/pubkey.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <ccan/err/err.h>
|
|
|
|
#include <ccan/fdpass/fdpass.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <ccan/list/list.h>
|
|
|
|
#include <ccan/tal/str/str.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <common/features.h>
|
2018-08-09 02:25:29 +02:00
|
|
|
#include <common/memleak.h>
|
|
|
|
#include <common/timeout.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <common/wireaddr.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <connectd/gen_connect_wire.h>
|
|
|
|
#include <errno.h>
|
|
|
|
#include <hsmd/capabilities.h>
|
|
|
|
#include <hsmd/gen_hsm_client_wire.h>
|
|
|
|
#include <lightningd/channel.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <lightningd/connect_control.h>
|
2018-03-16 04:45:08 +01:00
|
|
|
#include <lightningd/json.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <lightningd/jsonrpc.h>
|
2018-05-24 23:40:18 +02:00
|
|
|
#include <lightningd/jsonrpc_errors.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <lightningd/lightningd.h>
|
|
|
|
#include <lightningd/log.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <lightningd/opening_control.h>
|
2018-07-16 22:48:38 +02:00
|
|
|
#include <lightningd/param.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <lightningd/peer_control.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
#include <lightningd/subd.h>
|
2018-07-24 08:18:58 +02:00
|
|
|
#include <wire/gen_peer_wire.h>
|
|
|
|
#include <wire/wire_sync.h>
|
2018-02-20 21:59:09 +01:00
|
|
|
|
|
|
|
struct connect {
|
|
|
|
struct list_node list;
|
|
|
|
struct pubkey id;
|
|
|
|
struct command *cmd;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void destroy_connect(struct connect *c)
|
|
|
|
{
|
|
|
|
list_del(&c->list);
|
|
|
|
}
|
|
|
|
|
|
|
|
static struct connect *new_connect(struct lightningd *ld,
|
|
|
|
const struct pubkey *id,
|
|
|
|
struct command *cmd)
|
|
|
|
{
|
|
|
|
struct connect *c = tal(cmd, struct connect);
|
|
|
|
c->id = *id;
|
|
|
|
c->cmd = cmd;
|
2018-04-26 06:50:58 +02:00
|
|
|
list_add_tail(&ld->connects, &c->list);
|
2018-02-20 21:59:09 +01:00
|
|
|
tal_add_destructor(c, destroy_connect);
|
|
|
|
return c;
|
|
|
|
}
|
|
|
|
|
2018-04-26 06:50:58 +02:00
|
|
|
/* Finds first command which matches. */
|
|
|
|
static struct connect *find_connect(struct lightningd *ld,
|
|
|
|
const struct pubkey *id)
|
2018-02-20 21:59:09 +01:00
|
|
|
{
|
2018-04-26 06:50:58 +02:00
|
|
|
struct connect *i;
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2018-04-26 06:50:58 +02:00
|
|
|
list_for_each(&ld->connects, i, list) {
|
2018-02-20 21:59:09 +01:00
|
|
|
if (pubkey_eq(&i->id, id))
|
2018-04-26 06:50:58 +02:00
|
|
|
return i;
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
2018-04-26 06:50:58 +02:00
|
|
|
return NULL;
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
static void connect_cmd_succeed(struct command *cmd, const struct pubkey *id)
|
|
|
|
{
|
|
|
|
struct json_result *response = new_json_result(cmd);
|
|
|
|
json_object_start(response, NULL);
|
|
|
|
json_add_pubkey(response, "id", id);
|
|
|
|
json_object_end(response);
|
|
|
|
command_success(cmd, response);
|
|
|
|
}
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
static void json_connect(struct command *cmd,
|
|
|
|
const char *buffer, const jsmntok_t *params)
|
|
|
|
{
|
2018-07-16 22:48:38 +02:00
|
|
|
const jsmntok_t *hosttok, *porttok;
|
|
|
|
jsmntok_t *idtok;
|
2018-02-20 21:59:09 +01:00
|
|
|
struct pubkey id;
|
|
|
|
char *id_str;
|
|
|
|
char *atptr;
|
|
|
|
char *ataddr = NULL;
|
|
|
|
const char *name;
|
2018-05-07 06:29:21 +02:00
|
|
|
struct wireaddr_internal addr;
|
2018-02-20 21:59:09 +01:00
|
|
|
u8 *msg;
|
2018-02-25 03:30:33 +01:00
|
|
|
const char *err_msg;
|
2018-08-09 02:25:29 +02:00
|
|
|
struct peer *peer;
|
2018-02-20 21:59:09 +01:00
|
|
|
|
2018-07-16 22:48:38 +02:00
|
|
|
if (!param(cmd, buffer, params,
|
|
|
|
p_req("id", json_tok_tok, (const jsmntok_t **) &idtok),
|
|
|
|
p_opt_tok("host", &hosttok),
|
|
|
|
p_opt_tok("port", &porttok),
|
|
|
|
NULL))
|
2018-02-20 21:59:09 +01:00
|
|
|
return;
|
|
|
|
|
|
|
|
/* Check for id@addrport form */
|
|
|
|
id_str = tal_strndup(cmd, buffer + idtok->start,
|
|
|
|
idtok->end - idtok->start);
|
|
|
|
atptr = strchr(id_str, '@');
|
|
|
|
if (atptr) {
|
2018-03-25 21:51:11 +02:00
|
|
|
int atidx = atptr - id_str;
|
2018-02-20 21:59:09 +01:00
|
|
|
ataddr = tal_strdup(cmd, atptr + 1);
|
|
|
|
/* Cut id. */
|
|
|
|
idtok->end = idtok->start + atidx;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!json_tok_pubkey(buffer, idtok, &id)) {
|
2018-05-24 23:40:18 +02:00
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"id %.*s not valid",
|
2018-02-20 21:59:09 +01:00
|
|
|
idtok->end - idtok->start,
|
|
|
|
buffer + idtok->start);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (hosttok && ataddr) {
|
2018-05-24 23:40:18 +02:00
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
2018-02-20 21:59:09 +01:00
|
|
|
"Can't specify host as both xxx@yyy "
|
|
|
|
"and separate argument");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get parseable host if provided somehow */
|
|
|
|
if (hosttok)
|
|
|
|
name = tal_strndup(cmd, buffer + hosttok->start,
|
|
|
|
hosttok->end - hosttok->start);
|
|
|
|
else if (ataddr)
|
|
|
|
name = ataddr;
|
|
|
|
else
|
|
|
|
name = NULL;
|
|
|
|
|
|
|
|
/* Port without host name? */
|
|
|
|
if (porttok && !name) {
|
2018-05-24 23:40:18 +02:00
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"Can't specify port without host");
|
2018-02-20 21:59:09 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
/* If we know about peer, see if it's already connected. */
|
|
|
|
peer = peer_by_id(cmd->ld, &id);
|
|
|
|
if (peer) {
|
|
|
|
struct channel *channel = peer_active_channel(peer);
|
|
|
|
|
|
|
|
if (peer->uncommitted_channel
|
|
|
|
|| (channel && channel->connected)) {
|
|
|
|
connect_cmd_succeed(cmd, &id);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-02-20 21:59:09 +01:00
|
|
|
/* Was there parseable host name? */
|
|
|
|
if (name) {
|
2018-05-07 06:29:21 +02:00
|
|
|
u32 port;
|
2018-02-20 21:59:09 +01:00
|
|
|
/* Is there a port? */
|
|
|
|
if (porttok) {
|
2018-05-07 06:29:21 +02:00
|
|
|
if (!json_tok_number(buffer, porttok, &port) || !port) {
|
2018-05-24 23:40:18 +02:00
|
|
|
command_fail(cmd, JSONRPC2_INVALID_PARAMS,
|
|
|
|
"Port %.*s not valid",
|
2018-02-20 21:59:09 +01:00
|
|
|
porttok->end - porttok->start,
|
|
|
|
buffer + porttok->start);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
} else {
|
2018-05-07 06:29:21 +02:00
|
|
|
port = DEFAULT_PORT;
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
2018-05-07 06:29:22 +02:00
|
|
|
if (!parse_wireaddr_internal(name, &addr, port, false,
|
2018-05-10 01:18:24 +02:00
|
|
|
!cmd->ld->use_proxy_always
|
|
|
|
&& !cmd->ld->pure_tor_setup,
|
2018-05-10 05:44:23 +02:00
|
|
|
true,
|
2018-05-07 06:29:22 +02:00
|
|
|
&err_msg)) {
|
2018-05-24 23:40:18 +02:00
|
|
|
command_fail(cmd, LIGHTNINGD, "Host %s:%u not valid: %s",
|
2018-05-07 06:29:21 +02:00
|
|
|
name, port, err_msg ? err_msg : "port is 0");
|
2018-02-20 21:59:09 +01:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Tell it about the address. */
|
2018-07-24 08:18:58 +02:00
|
|
|
msg = towire_connectctl_peer_addrhint(cmd, &id, &addr);
|
2018-07-24 08:18:58 +02:00
|
|
|
subd_send_msg(cmd->ld->connectd, take(msg));
|
2018-02-20 21:59:09 +01:00
|
|
|
}
|
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
msg = towire_connectctl_connect_to_peer(NULL, &id, 0);
|
2018-08-09 02:25:29 +02:00
|
|
|
subd_send_msg(cmd->ld->connectd, take(msg));
|
|
|
|
|
|
|
|
/* Leave this here for peer_connected or connect_failed. */
|
2018-02-20 21:59:09 +01:00
|
|
|
new_connect(cmd->ld, &id, cmd);
|
|
|
|
command_still_pending(cmd);
|
|
|
|
}
|
|
|
|
|
|
|
|
static const struct json_command connect_command = {
|
|
|
|
"connect",
|
|
|
|
json_connect,
|
|
|
|
"Connect to {id} at {host} (which can end in ':port' if not default). "
|
|
|
|
"{id} can also be of the form id@host"
|
|
|
|
};
|
|
|
|
AUTODATA(json_command, &connect_command);
|
2018-07-24 08:18:58 +02:00
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
struct delayed_reconnect {
|
|
|
|
struct channel *channel;
|
|
|
|
u32 seconds_delayed;
|
|
|
|
};
|
|
|
|
|
|
|
|
static void maybe_reconnect(struct delayed_reconnect *d)
|
|
|
|
{
|
|
|
|
struct peer *peer = d->channel->peer;
|
|
|
|
|
|
|
|
/* Might have gone onchain since we started timer. */
|
|
|
|
if (channel_active(d->channel)) {
|
|
|
|
u8 *msg = towire_connectctl_connect_to_peer(NULL, &peer->id,
|
|
|
|
d->seconds_delayed);
|
|
|
|
subd_send_msg(peer->ld->connectd, take(msg));
|
|
|
|
}
|
|
|
|
tal_free(d);
|
|
|
|
}
|
|
|
|
|
|
|
|
void delay_then_reconnect(struct channel *channel, u32 seconds_delay)
|
|
|
|
{
|
|
|
|
struct delayed_reconnect *d;
|
|
|
|
struct lightningd *ld = channel->peer->ld;
|
|
|
|
|
|
|
|
if (!ld->reconnect)
|
|
|
|
return;
|
|
|
|
|
|
|
|
d = tal(channel, struct delayed_reconnect);
|
|
|
|
d->channel = channel;
|
|
|
|
d->seconds_delayed = seconds_delay;
|
|
|
|
|
|
|
|
log_debug(channel->log, "Will try reconnect in %u seconds",
|
|
|
|
seconds_delay);
|
|
|
|
notleak(new_reltimer(&ld->timers, d, time_from_sec(seconds_delay),
|
|
|
|
maybe_reconnect, d));
|
|
|
|
}
|
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
static void connect_failed(struct lightningd *ld, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct pubkey id;
|
|
|
|
char *err;
|
|
|
|
struct connect *c;
|
2018-08-09 02:25:29 +02:00
|
|
|
u32 seconds_to_delay;
|
|
|
|
struct channel *channel;
|
2018-08-09 02:25:29 +02:00
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
if (!fromwire_connectctl_connect_failed(tmpctx, msg, &id, &err,
|
|
|
|
&seconds_to_delay))
|
2018-08-09 02:25:29 +02:00
|
|
|
fatal("Connect gave bad CONNECTCTL_CONNECT_FAILED message %s",
|
|
|
|
tal_hex(msg, msg));
|
|
|
|
|
|
|
|
/* We can have multiple connect commands: fail them all */
|
|
|
|
while ((c = find_connect(ld, &id)) != NULL) {
|
|
|
|
/* They delete themselves from list */
|
|
|
|
command_fail(c->cmd, LIGHTNINGD, "%s", err);
|
|
|
|
}
|
2018-08-09 02:25:29 +02:00
|
|
|
|
|
|
|
/* If we have an active channel, then reconnect. */
|
|
|
|
channel = active_channel_by_id(ld, &id, NULL);
|
|
|
|
if (channel)
|
|
|
|
delay_then_reconnect(channel, seconds_to_delay);
|
2018-08-09 02:25:29 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
void connect_succeeded(struct lightningd *ld, const struct pubkey *id)
|
|
|
|
{
|
|
|
|
struct connect *c;
|
|
|
|
|
|
|
|
/* We can have multiple connect commands: fail them all */
|
|
|
|
while ((c = find_connect(ld, id)) != NULL) {
|
|
|
|
/* They delete themselves from list */
|
|
|
|
connect_cmd_succeed(c->cmd, id);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-07-24 08:18:58 +02:00
|
|
|
static void peer_please_disconnect(struct lightningd *ld, const u8 *msg)
|
|
|
|
{
|
|
|
|
struct pubkey id;
|
|
|
|
struct channel *c;
|
|
|
|
struct uncommitted_channel *uc;
|
|
|
|
|
|
|
|
if (!fromwire_connect_reconnected(msg, &id))
|
|
|
|
fatal("Bad msg %s from connectd", tal_hex(tmpctx, msg));
|
|
|
|
|
|
|
|
c = active_channel_by_id(ld, &id, &uc);
|
|
|
|
if (uc)
|
|
|
|
kill_uncommitted_channel(uc, "Reconnected");
|
|
|
|
else if (c)
|
|
|
|
channel_fail_transient(c, "Reconnected");
|
|
|
|
}
|
|
|
|
|
|
|
|
static unsigned connectd_msg(struct subd *connectd, const u8 *msg, const int *fds)
|
|
|
|
{
|
2018-07-24 08:18:58 +02:00
|
|
|
enum connect_wire_type t = fromwire_peektype(msg);
|
|
|
|
|
|
|
|
switch (t) {
|
|
|
|
/* These are messages we send, not them. */
|
|
|
|
case WIRE_CONNECTCTL_INIT:
|
|
|
|
case WIRE_CONNECTCTL_ACTIVATE:
|
|
|
|
case WIRE_CONNECTCTL_PEER_ADDRHINT:
|
|
|
|
case WIRE_CONNECTCTL_CONNECT_TO_PEER:
|
|
|
|
case WIRE_CONNECTCTL_PEER_DISCONNECTED:
|
|
|
|
/* This is a reply, so never gets through to here. */
|
|
|
|
case WIRE_CONNECTCTL_INIT_REPLY:
|
|
|
|
case WIRE_CONNECTCTL_ACTIVATE_REPLY:
|
|
|
|
break;
|
|
|
|
|
|
|
|
case WIRE_CONNECT_RECONNECTED:
|
2018-07-24 08:18:58 +02:00
|
|
|
peer_please_disconnect(connectd->ld, msg);
|
2018-07-24 08:18:58 +02:00
|
|
|
break;
|
|
|
|
|
|
|
|
case WIRE_CONNECT_PEER_CONNECTED:
|
|
|
|
if (tal_count(fds) != 2)
|
|
|
|
return 2;
|
|
|
|
peer_connected(connectd->ld, msg, fds[0], fds[1]);
|
|
|
|
break;
|
openingd: take peer before we're opening, wait for explicit funding msg.
Prior to this, lightningd would hand uninteresting peers back to connectd,
which would then return it to lightningd if it sent a non-gossip msg,
or if lightningd asked it to release the peer.
Now connectd hands the peer to lightningd once we've done the init
handshake, which hands it off to openingd.
This is a deep structural change, so we do the minimum here and cleanup
in the following patches.
Lightningd:
1. Remove peer_nongossip handling from connect_control and peer_control.
2. Remove list of outstanding fundchannel command; it was only needed to
find the race between us asking connectd to release the peer and it
reconnecting.
3. We can no longer tell if the remote end has started trying to fund a
channel (until it has succeeded): it's very transitory anyway so not
worth fixing.
4. We now always have a struct peer, and allocate an uncommitted_channel
for it, though it may never be used if neither end funds a channel.
5. We start funding on messages for openingd: we can get a funder_reply
or a fundee, or an error in response to our request to fund a channel.
so we handle all of them.
6. A new peer_start_openingd() is called after connectd hands us a peer.
7. json_fund_channel just looks through local peers; there are none
hidden in connectd any more.
8. We sometimes start a new openingd just to send an error message.
Openingd:
1. We always have information we need to accept them funding a channel (in
the init message).
2. We have to listen for three fds: peer, gossip and master, so we opencode
the poll.
3. We have an explicit message to start trying to fund a channel.
4. We can be told to send a message in our init message.
Testing:
1. We don't handle some things gracefully yet, so two tests are disabled.
2. 'hand_back_peer .*: now local again' from connectd is no longer a message,
openingd says 'Handed peer, entering loop' once its managing it.
3. peer['state'] used to be set to 'GOSSIPING' (otherwise this field doesn't
exist; 'state' is now per-channel. It doesn't exist at all now.
4. Some tests now need to turn on IO logging in openingd, not connectd.
5. There's a gap between connecting on one node and having connectd on
the peer hand over the connection to openingd. Our tests sometimes
checked getpeers() on the peer, and didn't see anything, so line_graph
needed updating.
Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
2018-08-08 16:10:58 +02:00
|
|
|
|
2018-08-09 02:25:29 +02:00
|
|
|
case WIRE_CONNECTCTL_CONNECT_FAILED:
|
|
|
|
connect_failed(connectd->ld, msg);
|
2018-07-24 08:18:58 +02:00
|
|
|
break;
|
2018-07-24 08:18:58 +02:00
|
|
|
}
|
2018-07-24 08:18:58 +02:00
|
|
|
return 0;
|
2018-07-24 08:18:58 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static void connect_init_done(struct subd *connectd,
|
|
|
|
const u8 *reply,
|
|
|
|
const int *fds UNUSED,
|
|
|
|
void *unused UNUSED)
|
|
|
|
{
|
|
|
|
struct lightningd *ld = connectd->ld;
|
|
|
|
|
|
|
|
if (!fromwire_connectctl_init_reply(ld, reply,
|
|
|
|
&ld->binding,
|
|
|
|
&ld->announcable))
|
|
|
|
fatal("Bad connectctl_activate_reply: %s",
|
|
|
|
tal_hex(reply, reply));
|
|
|
|
|
|
|
|
/* Break out of loop, so we can begin */
|
|
|
|
io_break(connectd);
|
|
|
|
}
|
|
|
|
|
2018-07-24 08:18:58 +02:00
|
|
|
int connectd_init(struct lightningd *ld)
|
|
|
|
{
|
|
|
|
int fds[2];
|
2018-07-24 08:18:58 +02:00
|
|
|
u8 *msg;
|
|
|
|
int hsmfd;
|
|
|
|
u64 capabilities = HSM_CAP_ECDH;
|
|
|
|
struct wireaddr_internal *wireaddrs = ld->proposed_wireaddr;
|
|
|
|
enum addr_listen_announce *listen_announce = ld->proposed_listen_announce;
|
|
|
|
bool allow_localhost = false;
|
|
|
|
#if DEVELOPER
|
|
|
|
if (ld->dev_allow_localhost)
|
|
|
|
allow_localhost = true;
|
|
|
|
#endif
|
2018-07-24 08:18:58 +02:00
|
|
|
|
|
|
|
if (socketpair(AF_LOCAL, SOCK_STREAM, 0, fds) != 0)
|
|
|
|
fatal("Could not socketpair for connectd<->gossipd");
|
|
|
|
|
2018-07-24 08:18:58 +02:00
|
|
|
msg = towire_hsm_client_hsmfd(tmpctx, &ld->id, 0, capabilities);
|
|
|
|
if (!wire_sync_write(ld->hsm_fd, msg))
|
|
|
|
fatal("Could not write to HSM: %s", strerror(errno));
|
|
|
|
|
|
|
|
msg = wire_sync_read(tmpctx, ld->hsm_fd);
|
|
|
|
if (!fromwire_hsm_client_hsmfd_reply(msg))
|
|
|
|
fatal("Malformed hsmfd response: %s", tal_hex(msg, msg));
|
|
|
|
|
|
|
|
hsmfd = fdpass_recv(ld->hsm_fd);
|
|
|
|
if (hsmfd < 0)
|
|
|
|
fatal("Could not read fd from HSM: %s", strerror(errno));
|
|
|
|
|
|
|
|
ld->connectd = new_global_subd(ld, "lightning_connectd",
|
2018-07-24 08:18:58 +02:00
|
|
|
connect_wire_type_name, connectd_msg,
|
2018-07-24 08:18:58 +02:00
|
|
|
take(&hsmfd), take(&fds[1]), NULL);
|
|
|
|
if (!ld->connectd)
|
|
|
|
err(1, "Could not subdaemon connectd");
|
|
|
|
|
|
|
|
/* If no addr specified, hand wildcard to connectd */
|
|
|
|
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;
|
|
|
|
wireaddrs->u.port = ld->portnum;
|
|
|
|
*listen_announce = ADDR_LISTEN_AND_ANNOUNCE;
|
|
|
|
}
|
|
|
|
|
|
|
|
msg = towire_connectctl_init(
|
2018-07-24 08:18:58 +02:00
|
|
|
tmpctx, &ld->id,
|
2018-07-24 08:18:58 +02:00
|
|
|
get_offered_global_features(tmpctx),
|
|
|
|
get_offered_local_features(tmpctx), wireaddrs,
|
2018-08-09 02:25:29 +02:00
|
|
|
listen_announce,
|
2018-07-24 08:18:58 +02:00
|
|
|
ld->proxyaddr, ld->use_proxy_always || ld->pure_tor_setup,
|
|
|
|
allow_localhost, ld->config.use_dns,
|
|
|
|
ld->tor_service_password ? ld->tor_service_password : "");
|
|
|
|
|
|
|
|
subd_req(ld->connectd, ld->connectd, take(msg), -1, 0,
|
|
|
|
connect_init_done, NULL);
|
|
|
|
|
|
|
|
/* Wait for init_reply */
|
|
|
|
io_loop(NULL, NULL);
|
|
|
|
|
2018-07-24 08:18:58 +02:00
|
|
|
return fds[0];
|
|
|
|
}
|
2018-07-24 08:18:58 +02:00
|
|
|
|
|
|
|
static void connect_activate_done(struct subd *connectd,
|
|
|
|
const u8 *reply UNUSED,
|
|
|
|
const int *fds UNUSED,
|
|
|
|
void *unused UNUSED)
|
|
|
|
{
|
|
|
|
/* Break out of loop, so we can begin */
|
|
|
|
io_break(connectd);
|
|
|
|
}
|
|
|
|
|
|
|
|
void connectd_activate(struct lightningd *ld)
|
|
|
|
{
|
|
|
|
const u8 *msg = towire_connectctl_activate(NULL, ld->listen);
|
|
|
|
|
|
|
|
subd_req(ld->connectd, ld->connectd, take(msg), -1, 0,
|
|
|
|
connect_activate_done, NULL);
|
|
|
|
|
|
|
|
/* Wait for activate_reply */
|
|
|
|
io_loop(NULL, NULL);
|
|
|
|
}
|
|
|
|
|