|
|
@ -15,6 +15,12 @@ |
|
|
|
#include <sys/socket.h> |
|
|
|
#include <sys/types.h> |
|
|
|
|
|
|
|
struct json_connecting { |
|
|
|
/* This owns us, so we're freed after command_fail or command_success */ |
|
|
|
struct command *cmd; |
|
|
|
const char *name, *port; |
|
|
|
}; |
|
|
|
|
|
|
|
/* Send and receive (encrypted) hello message. */ |
|
|
|
static struct io_plan *peer_test_check(struct io_conn *conn, struct peer *peer) |
|
|
|
{ |
|
|
@ -82,15 +88,24 @@ static struct peer *new_peer(struct lightningd_state *state, |
|
|
|
|
|
|
|
static struct io_plan *peer_connected_out(struct io_conn *conn, |
|
|
|
struct lightningd_state *state, |
|
|
|
char *dest) |
|
|
|
struct json_connecting *connect) |
|
|
|
{ |
|
|
|
struct json_result *response; |
|
|
|
struct peer *peer = new_peer(state, conn, SOCK_STREAM, IPPROTO_TCP, |
|
|
|
"out"); |
|
|
|
if (!peer) { |
|
|
|
log_unusual(peer->log, "Failed to make peer for %s", dest); |
|
|
|
command_fail(connect->cmd, "Failed to make peer for %s:%s", |
|
|
|
connect->name, connect->port); |
|
|
|
return io_close(conn); |
|
|
|
} |
|
|
|
log_info(peer->log, "Connected out to %s", dest); |
|
|
|
log_info(peer->log, "Connected out to %s:%s", |
|
|
|
connect->name, connect->port); |
|
|
|
|
|
|
|
response = new_json_result(connect); |
|
|
|
json_object_start(response, NULL); |
|
|
|
json_object_end(response); |
|
|
|
command_success(connect->cmd, response); |
|
|
|
|
|
|
|
return peer_crypto_setup(conn, peer, peer_test); |
|
|
|
} |
|
|
|
|
|
|
@ -190,19 +205,19 @@ void setup_listeners(struct lightningd_state *state, unsigned int portnum) |
|
|
|
fatal("Could not bind to a network address"); |
|
|
|
} |
|
|
|
|
|
|
|
static void peer_failed(struct lightningd_state *state, char *dest) |
|
|
|
static void peer_failed(struct lightningd_state *state, |
|
|
|
struct json_connecting *connect) |
|
|
|
{ |
|
|
|
/* FIXME: Better diagnostics! */ |
|
|
|
log_unusual(state->base_log, "Connect to %s failed", dest); |
|
|
|
command_fail(connect->cmd, "Failed to connect to peer %s:%s", |
|
|
|
connect->name, connect->port); |
|
|
|
} |
|
|
|
|
|
|
|
static void json_connect(struct command *cmd, |
|
|
|
const char *buffer, const jsmntok_t *params) |
|
|
|
{ |
|
|
|
struct json_result *response; |
|
|
|
struct json_connecting *connect; |
|
|
|
jsmntok_t *host, *port; |
|
|
|
const char *hoststr, *portstr; |
|
|
|
char *dest; |
|
|
|
|
|
|
|
json_get_params(buffer, params, "host", &host, "port", &port, NULL); |
|
|
|
|
|
|
@ -211,26 +226,22 @@ static void json_connect(struct command *cmd, |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
hoststr = tal_strndup(cmd->state, buffer + host->start, |
|
|
|
host->end - host->start); |
|
|
|
portstr = tal_strndup(cmd->state, buffer + port->start, |
|
|
|
port->end - port->start); |
|
|
|
dest = tal_fmt(cmd->state, "%s:%s", hoststr, portstr); |
|
|
|
if (!dns_resolve_and_connect(cmd->state, hoststr, portstr, |
|
|
|
peer_connected_out, peer_failed, dest)) { |
|
|
|
connect = tal(cmd, struct json_connecting); |
|
|
|
connect->cmd = cmd; |
|
|
|
connect->name = tal_strndup(connect, buffer + host->start, |
|
|
|
host->end - host->start); |
|
|
|
connect->port = tal_strndup(connect, buffer + port->start, |
|
|
|
port->end - port->start); |
|
|
|
if (!dns_resolve_and_connect(cmd->state, connect->name, connect->port, |
|
|
|
peer_connected_out, peer_failed, connect)) { |
|
|
|
command_fail(cmd, "DNS failed"); |
|
|
|
return; |
|
|
|
} |
|
|
|
|
|
|
|
response = new_json_result(cmd); |
|
|
|
json_object_start(response, NULL); |
|
|
|
json_object_end(response); |
|
|
|
command_success(cmd, response); |
|
|
|
} |
|
|
|
|
|
|
|
const struct json_command connect_command = { |
|
|
|
"connect", |
|
|
|
json_connect, |
|
|
|
"Connect to a {host} at {port}", |
|
|
|
"Returns an empty result (meaning connection in progress)" |
|
|
|
"Returns an empty result on success" |
|
|
|
}; |
|
|
|