Browse Source

lightningd/connect_control: routines to control connecting (move from peer_control.c)

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
ppa-0.6.1
Rusty Russell 7 years ago
committed by Christian Decker
parent
commit
a83ff83328
  1. 1
      lightningd/Makefile
  2. 194
      lightningd/connect_control.c
  3. 15
      lightningd/connect_control.h
  4. 1
      lightningd/gossip_control.c
  5. 192
      lightningd/peer_control.c
  6. 3
      lightningd/peer_control.h
  7. 14
      wallet/test/run-wallet.c

1
lightningd/Makefile

@ -51,6 +51,7 @@ LIGHTNINGD_SRC := \
lightningd/build_utxos.c \
lightningd/chaintopology.c \
lightningd/channel.c \
lightningd/connect_control.c \
lightningd/gossip_control.c \
lightningd/gossip_msg.c \
lightningd/hsm_control.c \

194
lightningd/connect_control.c

@ -0,0 +1,194 @@
#include <bitcoin/pubkey.h>
#include <ccan/list/list.h>
#include <ccan/tal/str/str.h>
#include <common/wireaddr.h>
#include <gossipd/gen_gossip_wire.h>
#include <lightningd/connect_control.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/lightningd.h>
#include <lightningd/log.h>
#include <lightningd/subd.h>
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;
list_add(&ld->connects, &c->list);
tal_add_destructor(c, destroy_connect);
return c;
}
void connect_succeeded(struct lightningd *ld, const struct pubkey *id)
{
struct connect *i, *next;
/* Careful! Completing command frees connect. */
list_for_each_safe(&ld->connects, i, next, list) {
struct json_result *response;
if (!pubkey_eq(&i->id, id))
continue;
response = new_json_result(i->cmd);
json_object_start(response, NULL);
json_add_pubkey(response, "id", id);
json_object_end(response);
command_success(i->cmd, response);
}
}
void connect_failed(struct lightningd *ld, const struct pubkey *id,
const char *error)
{
struct connect *i, *next;
/* Careful! Completing command frees connect. */
list_for_each_safe(&ld->connects, i, next, list) {
if (pubkey_eq(&i->id, id))
command_fail(i->cmd, "%s", error);
}
}
void peer_connection_failed(struct lightningd *ld, const u8 *msg)
{
struct pubkey id;
u32 attempts, timediff;
bool addr_unknown;
char *error;
if (!fromwire_gossip_peer_connection_failed(msg, NULL, &id, &timediff,
&attempts, &addr_unknown))
fatal(
"Gossip gave bad GOSSIP_PEER_CONNECTION_FAILED message %s",
tal_hex(msg, msg));
if (addr_unknown) {
error = tal_fmt(
msg, "No address known for node %s, please provide one",
type_to_string(msg, struct pubkey, &id));
} else {
error = tal_fmt(msg, "Could not connect to %s after %d seconds and %d attempts",
type_to_string(msg, struct pubkey, &id), timediff,
attempts);
}
connect_failed(ld, &id, error);
}
static void json_connect(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *hosttok, *porttok, *idtok;
struct pubkey id;
char *id_str;
char *atptr;
char *ataddr = NULL;
int atidx;
const char *name;
struct wireaddr addr;
u8 *msg;
if (!json_get_params(cmd, buffer, params,
"id", &idtok,
"?host", &hosttok,
"?port", &porttok,
NULL)) {
return;
}
/* Check for id@addrport form */
id_str = tal_strndup(cmd, buffer + idtok->start,
idtok->end - idtok->start);
atptr = strchr(id_str, '@');
if (atptr) {
atidx = atptr - id_str;
ataddr = tal_strdup(cmd, atptr + 1);
/* Cut id. */
idtok->end = idtok->start + atidx;
}
if (!json_tok_pubkey(buffer, idtok, &id)) {
command_fail(cmd, "id %.*s not valid",
idtok->end - idtok->start,
buffer + idtok->start);
return;
}
if (hosttok && ataddr) {
command_fail(cmd,
"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) {
command_fail(cmd, "Can't specify port without host");
return;
}
/* Was there parseable host name? */
if (name) {
/* Is there a port? */
if (porttok) {
u32 port;
if (!json_tok_number(buffer, porttok, &port)) {
command_fail(cmd, "Port %.*s not valid",
porttok->end - porttok->start,
buffer + porttok->start);
return;
}
addr.port = port;
} else {
addr.port = DEFAULT_PORT;
}
if (!parse_wireaddr(name, &addr, addr.port) || !addr.port) {
command_fail(cmd, "Host %s:%u not valid",
name, addr.port);
return;
}
/* Tell it about the address. */
msg = towire_gossipctl_peer_addrhint(cmd, &id, &addr);
subd_send_msg(cmd->ld->gossip, take(msg));
}
/* Now tell it to try reaching it. */
msg = towire_gossipctl_reach_peer(cmd, &id);
subd_send_msg(cmd->ld->gossip, take(msg));
/* Leave this here for gossip_peer_connected */
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);

15
lightningd/connect_control.h

@ -0,0 +1,15 @@
#ifndef LIGHTNING_LIGHTNINGD_CONNECT_CONTROL_H
#define LIGHTNING_LIGHTNINGD_CONNECT_CONTROL_H
#include "config.h"
struct lightningd;
struct pubkey;
void connect_succeeded(struct lightningd *ld, const struct pubkey *id);
void connect_failed(struct lightningd *ld, const struct pubkey *id,
const char *error);
/* Gossipd was unable to connect to the peer */
void peer_connection_failed(struct lightningd *ld, const u8 *msg);
#endif /* LIGHTNING_LIGHTNINGD_CONNECT_CONTROL_H */

1
lightningd/gossip_control.c

@ -17,6 +17,7 @@
#include <hsmd/capabilities.h>
#include <hsmd/gen_hsm_client_wire.h>
#include <inttypes.h>
#include <lightningd/connect_control.h>
#include <lightningd/gossip_msg.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>

192
lightningd/peer_control.c

@ -30,6 +30,7 @@
#include <lightningd/bitcoind.h>
#include <lightningd/build_utxos.h>
#include <lightningd/chaintopology.h>
#include <lightningd/connect_control.h>
#include <lightningd/hsm_control.h>
#include <lightningd/jsonrpc.h>
#include <lightningd/log.h>
@ -45,12 +46,6 @@
#include <wire/peer_wire.h>
#include <wire/wire_sync.h>
struct connect {
struct list_node list;
struct pubkey id;
struct command *cmd;
};
/* FIXME: Reorder */
static void copy_to_parent_log(const char *prefix,
enum log_level level,
@ -167,54 +162,6 @@ void drop_to_chain(struct lightningd *ld, struct channel *channel)
remove_sig(channel->last_tx);
}
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;
list_add(&ld->connects, &c->list);
tal_add_destructor(c, destroy_connect);
return c;
}
static void connect_succeeded(struct lightningd *ld, const struct pubkey *id)
{
struct connect *i, *next;
/* Careful! Completing command frees connect. */
list_for_each_safe(&ld->connects, i, next, list) {
struct json_result *response;
if (!pubkey_eq(&i->id, id))
continue;
response = new_json_result(i->cmd);
json_object_start(response, NULL);
json_add_pubkey(response, "id", id);
json_object_end(response);
command_success(i->cmd, response);
}
}
static void connect_failed(struct lightningd *ld, const struct pubkey *id,
const char *error)
{
struct connect *i, *next;
/* Careful! Completing command frees connect. */
list_for_each_safe(&ld->connects, i, next, list) {
if (pubkey_eq(&i->id, id))
command_fail(i->cmd, "%s", error);
}
}
static void channel_errmsg(struct channel *channel,
int peer_fd, int gossip_fd,
const struct crypto_state *cs,
@ -413,39 +360,6 @@ void peer_already_connected(struct lightningd *ld, const u8 *msg)
connect_succeeded(ld, &id);
}
void peer_connection_failed(struct lightningd *ld, const u8 *msg)
{
struct pubkey id;
u32 attempts, timediff;
struct connect *i, *next;
bool addr_unknown;
char *error;
if (!fromwire_gossip_peer_connection_failed(msg, NULL, &id, &timediff,
&attempts, &addr_unknown))
fatal(
"Gossip gave bad GOSSIP_PEER_CONNECTION_FAILED message %s",
tal_hex(msg, msg));
if (addr_unknown) {
error = tal_fmt(
msg, "No address known for node %s, please provide one",
type_to_string(msg, struct pubkey, &id));
} else {
error = tal_fmt(msg, "Could not connect to %s after %d seconds and %d attempts",
type_to_string(msg, struct pubkey, &id), timediff,
attempts);
}
/* Careful! Completing command frees connect. */
list_for_each_safe(&ld->connects, i, next, list) {
if (!pubkey_eq(&i->id, &id))
continue;
command_fail(i->cmd, "%s", error);
}
}
static struct channel *channel_by_channel_id(struct peer *peer,
const struct channel_id *channel_id)
{
@ -549,110 +463,6 @@ struct peer *peer_by_id(struct lightningd *ld, const struct pubkey *id)
return NULL;
}
static void json_connect(struct command *cmd,
const char *buffer, const jsmntok_t *params)
{
jsmntok_t *hosttok, *porttok, *idtok;
struct pubkey id;
char *id_str;
char *atptr;
char *ataddr = NULL;
int atidx;
const char *name;
struct wireaddr addr;
u8 *msg;
if (!json_get_params(cmd, buffer, params,
"id", &idtok,
"?host", &hosttok,
"?port", &porttok,
NULL)) {
return;
}
/* Check for id@addrport form */
id_str = tal_strndup(cmd, buffer + idtok->start,
idtok->end - idtok->start);
atptr = strchr(id_str, '@');
if (atptr) {
atidx = atptr - id_str;
ataddr = tal_strdup(cmd, atptr + 1);
/* Cut id. */
idtok->end = idtok->start + atidx;
}
if (!json_tok_pubkey(buffer, idtok, &id)) {
command_fail(cmd, "id %.*s not valid",
idtok->end - idtok->start,
buffer + idtok->start);
return;
}
if (hosttok && ataddr) {
command_fail(cmd,
"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) {
command_fail(cmd, "Can't specify port without host");
return;
}
/* Was there parseable host name? */
if (name) {
/* Is there a port? */
if (porttok) {
u32 port;
if (!json_tok_number(buffer, porttok, &port)) {
command_fail(cmd, "Port %.*s not valid",
porttok->end - porttok->start,
buffer + porttok->start);
return;
}
addr.port = port;
} else {
addr.port = DEFAULT_PORT;
}
if (!parse_wireaddr(name, &addr, addr.port) || !addr.port) {
command_fail(cmd, "Host %s:%u not valid",
name, addr.port);
return;
}
/* Tell it about the address. */
msg = towire_gossipctl_peer_addrhint(cmd, &id, &addr);
subd_send_msg(cmd->ld->gossip, take(msg));
}
/* Now tell it to try reaching it. */
msg = towire_gossipctl_reach_peer(cmd, &id);
subd_send_msg(cmd->ld->gossip, take(msg));
/* Leave this here for gossip_peer_connected */
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);
struct getpeers_args {
struct command *cmd;
/* If non-NULL, they want logs too */

3
lightningd/peer_control.h

@ -74,9 +74,6 @@ void peer_connected(struct lightningd *ld, const u8 *msg,
/* This simply means we asked to reach a peer, but we already have it */
void peer_already_connected(struct lightningd *ld, const u8 *msg);
/* We were unable to connect to the peer */
void peer_connection_failed(struct lightningd *ld, const u8 *msg);
void peer_sent_nongossip(struct lightningd *ld,
const struct pubkey *id,
const struct wireaddr *addr,

14
wallet/test/run-wallet.c

@ -62,6 +62,13 @@ void command_still_pending(struct command *cmd UNNEEDED)
/* Generated stub for command_success */
void command_success(struct command *cmd UNNEEDED, struct json_result *response UNNEEDED)
{ fprintf(stderr, "command_success called!\n"); abort(); }
/* Generated stub for connect_failed */
void connect_failed(struct lightningd *ld UNNEEDED, const struct pubkey *id UNNEEDED,
const char *error UNNEEDED)
{ fprintf(stderr, "connect_failed called!\n"); abort(); }
/* Generated stub for connect_succeeded */
void connect_succeeded(struct lightningd *ld UNNEEDED, const struct pubkey *id UNNEEDED)
{ fprintf(stderr, "connect_succeeded called!\n"); abort(); }
/* Generated stub for derive_basepoints */
bool derive_basepoints(const struct privkey *seed UNNEEDED,
struct pubkey *funding_pubkey UNNEEDED,
@ -105,9 +112,6 @@ bool fromwire_gossip_peer_already_connected(const void *p UNNEEDED, size_t *plen
/* Generated stub for fromwire_gossip_peer_connected */
bool fromwire_gossip_peer_connected(const tal_t *ctx UNNEEDED, const void *p UNNEEDED, size_t *plen UNNEEDED, struct pubkey *id UNNEEDED, struct wireaddr *addr UNNEEDED, struct crypto_state *crypto_state UNNEEDED, u64 *gossip_index UNNEEDED, u8 **gfeatures UNNEEDED, u8 **lfeatures UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_peer_connected called!\n"); abort(); }
/* Generated stub for fromwire_gossip_peer_connection_failed */
bool fromwire_gossip_peer_connection_failed(const void *p UNNEEDED, size_t *plen UNNEEDED, struct pubkey *id UNNEEDED, u32 *timeout UNNEEDED, u32 *attempts UNNEEDED, bool *addr_unknown UNNEEDED)
{ fprintf(stderr, "fromwire_gossip_peer_connection_failed called!\n"); abort(); }
/* Generated stub for fromwire_hsm_client_hsmfd_reply */
bool fromwire_hsm_client_hsmfd_reply(const void *p UNNEEDED, size_t *plen UNNEEDED)
{ fprintf(stderr, "fromwire_hsm_client_hsmfd_reply called!\n"); abort(); }
@ -261,10 +265,6 @@ bool json_tok_bool(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED, b
bool json_tok_loglevel(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
enum log_level *level UNNEEDED)
{ fprintf(stderr, "json_tok_loglevel called!\n"); abort(); }
/* Generated stub for json_tok_number */
bool json_tok_number(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
unsigned int *num UNNEEDED)
{ fprintf(stderr, "json_tok_number called!\n"); abort(); }
/* Generated stub for json_tok_pubkey */
bool json_tok_pubkey(const char *buffer UNNEEDED, const jsmntok_t *tok UNNEEDED,
struct pubkey *pubkey UNNEEDED)

Loading…
Cancel
Save