mirror of
https://github.com/aljazceru/lightning.git
synced 2026-01-10 01:24:30 +01:00
lightningd/lightningd: maintain "condition" for each peer.
This lets us return better messages to the connect json command on failure. Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
@@ -15,6 +15,7 @@ LIGHTNINGD_OLD_SRC := \
|
||||
daemon/json.c \
|
||||
daemon/jsonrpc.c \
|
||||
daemon/log.c \
|
||||
daemon/netaddr.c \
|
||||
daemon/options.c \
|
||||
daemon/opt_time.c \
|
||||
daemon/pseudorand.c \
|
||||
|
||||
@@ -32,9 +32,11 @@ static void peer_bad_message(struct subdaemon *gossip, const u8 *msg)
|
||||
if (!peer)
|
||||
fatal("Gossip gave bad peerid %"PRIu64, unique_id);
|
||||
|
||||
log_info(gossip->log, "Peer %s gave bad msg %s",
|
||||
type_to_string(msg, struct pubkey, peer->id),
|
||||
tal_hex(msg, msg));
|
||||
log_debug(gossip->log, "Peer %s gave bad msg %s",
|
||||
type_to_string(msg, struct pubkey, peer->id),
|
||||
tal_hex(msg, msg));
|
||||
peer_set_condition(peer, "Bad message %s during gossip phase",
|
||||
gossip_status_wire_type_name(fromwire_peektype(msg)));
|
||||
tal_free(peer);
|
||||
}
|
||||
|
||||
@@ -54,9 +56,11 @@ static void peer_nongossip(struct subdaemon *gossip, const u8 *msg, int fd)
|
||||
if (!peer)
|
||||
fatal("Gossip gave bad peerid %"PRIu64, unique_id);
|
||||
|
||||
log_info(gossip->log, "Peer %s said %s",
|
||||
type_to_string(msg, struct pubkey, peer->id),
|
||||
gossip_status_wire_type_name(fromwire_peektype(inner)));
|
||||
log_debug(gossip->log, "Peer %s said %s",
|
||||
type_to_string(msg, struct pubkey, peer->id),
|
||||
gossip_status_wire_type_name(fromwire_peektype(inner)));
|
||||
peer_set_condition(peer, "Gossip ended up receipt of %s",
|
||||
gossip_status_wire_type_name(fromwire_peektype(inner)));
|
||||
|
||||
/* FIXME: create new daemon to handle peer. */
|
||||
}
|
||||
@@ -74,8 +78,8 @@ static void peer_ready(struct subdaemon *gossip, const u8 *msg)
|
||||
if (!peer)
|
||||
fatal("Gossip gave bad peerid %"PRIu64, unique_id);
|
||||
|
||||
log_info_struct(gossip->log, "Peer %s ready for channel open",
|
||||
struct pubkey, peer->id);
|
||||
log_debug_struct(gossip->log, "Peer %s ready for channel open",
|
||||
struct pubkey, peer->id);
|
||||
|
||||
if (peer->connect_cmd) {
|
||||
struct json_result *response;
|
||||
@@ -87,6 +91,8 @@ static void peer_ready(struct subdaemon *gossip, const u8 *msg)
|
||||
command_success(peer->connect_cmd, response);
|
||||
peer->connect_cmd = NULL;
|
||||
}
|
||||
|
||||
peer_set_condition(peer, "Exchanging gossip");
|
||||
}
|
||||
|
||||
static enum subdaemon_status gossip_status(struct subdaemon *gossip,
|
||||
|
||||
@@ -24,21 +24,46 @@ static void destroy_peer(struct peer *peer)
|
||||
if (peer->fd >= 0)
|
||||
close(peer->fd);
|
||||
if (peer->connect_cmd)
|
||||
/* FIXME: Better diagnostics */
|
||||
command_fail(peer->connect_cmd, "Connect failed");
|
||||
command_fail(peer->connect_cmd, "Failed after %s",
|
||||
peer->condition);
|
||||
}
|
||||
|
||||
static struct peer *new_peer(const tal_t *ctx, struct lightningd *ld, int fd,
|
||||
void peer_set_condition(struct peer *peer, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
tal_free(peer->condition);
|
||||
peer->condition = tal_vfmt(peer, fmt, ap);
|
||||
va_end(ap);
|
||||
}
|
||||
|
||||
static struct peer *new_peer(struct lightningd *ld,
|
||||
struct io_conn *conn,
|
||||
const char *in_or_out,
|
||||
struct command *cmd)
|
||||
{
|
||||
static u64 id_counter;
|
||||
struct peer *peer = tal(ctx, struct peer);
|
||||
struct peer *peer = tal(ld, struct peer);
|
||||
const char *netname;
|
||||
|
||||
peer->ld = ld;
|
||||
peer->unique_id = id_counter++;
|
||||
peer->owner = NULL;
|
||||
peer->id = NULL;
|
||||
peer->fd = fd;
|
||||
peer->fd = io_conn_fd(conn);
|
||||
peer->connect_cmd = cmd;
|
||||
|
||||
/* FIXME: Don't assume protocol here! */
|
||||
if (!netaddr_from_fd(peer->fd, SOCK_STREAM, IPPROTO_TCP,
|
||||
&peer->netaddr)) {
|
||||
log_unusual(ld->log, "Failed to get netaddr for outgoing: %s",
|
||||
strerror(errno));
|
||||
return tal_free(peer);
|
||||
}
|
||||
netname = netaddr_name(peer, &peer->netaddr);
|
||||
peer->condition = tal_fmt(peer, "%s %s", in_or_out, netname);
|
||||
tal_free(netname);
|
||||
list_add_tail(&ld->peers, &peer->list);
|
||||
tal_add_destructor(peer, destroy_peer);
|
||||
return peer;
|
||||
@@ -82,6 +107,7 @@ static void handshake_succeeded(struct subdaemon *hs, const u8 *msg,
|
||||
|
||||
peer->owner = peer->ld->gossip;
|
||||
tal_steal(peer->owner, peer);
|
||||
peer_set_condition(peer, "Beginning gossip");
|
||||
|
||||
/* Tell gossip to handle it now. */
|
||||
msg = towire_gossipctl_new_peer(msg, peer->unique_id, cs);
|
||||
@@ -119,6 +145,7 @@ static void peer_got_hsmfd(struct subdaemon *hsm, const u8 *msg,
|
||||
if (!peer->owner) {
|
||||
log_unusual(peer->ld->log, "Could not subdaemon handshake: %s",
|
||||
strerror(errno));
|
||||
peer_set_condition(peer, "Failed to subdaemon handshake");
|
||||
goto error;
|
||||
}
|
||||
|
||||
@@ -126,11 +153,14 @@ static void peer_got_hsmfd(struct subdaemon *hsm, const u8 *msg,
|
||||
* when it does. */
|
||||
tal_steal(peer->owner, peer);
|
||||
|
||||
if (peer->id)
|
||||
if (peer->id) {
|
||||
req = towire_handshake_initiator_req(peer, &peer->ld->dstate.id,
|
||||
peer->id);
|
||||
else
|
||||
peer_set_condition(peer, "Starting handshake as initiator");
|
||||
} else {
|
||||
req = towire_handshake_responder_req(peer, &peer->ld->dstate.id);
|
||||
peer_set_condition(peer, "Starting handshake as responder");
|
||||
}
|
||||
|
||||
/* Now hand peer fd to the handshake daemon, it hand back on success */
|
||||
subdaemon_req(peer->owner, take(req),
|
||||
@@ -148,7 +178,10 @@ error:
|
||||
/* FIXME: timeout handshake if taking too long? */
|
||||
static struct io_plan *peer_in(struct io_conn *conn, struct lightningd *ld)
|
||||
{
|
||||
struct peer *peer = new_peer(ld, ld, io_conn_fd(conn), NULL);
|
||||
struct peer *peer = new_peer(ld, conn, "Incoming from", NULL);
|
||||
|
||||
if (!peer)
|
||||
return io_close(conn);
|
||||
|
||||
/* Get HSM fd for this peer. */
|
||||
subdaemon_req(ld->hsm,
|
||||
@@ -273,7 +306,10 @@ static struct io_plan *peer_out(struct io_conn *conn,
|
||||
struct json_connecting *jc)
|
||||
{
|
||||
struct lightningd *ld = ld_from_dstate(jc->cmd->dstate);
|
||||
struct peer *peer = new_peer(ld, ld, io_conn_fd(conn), jc->cmd);
|
||||
struct peer *peer = new_peer(ld, conn, "Outgoing to", jc->cmd);
|
||||
|
||||
if (!peer)
|
||||
return io_close(conn);
|
||||
|
||||
/* We already know ID we're trying to reach. */
|
||||
peer->id = tal_dup(peer, struct pubkey, &jc->id);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef LIGHTNING_LIGHTNINGD_PEER_CONTROL_H
|
||||
#define LIGHTNING_LIGHTNINGD_PEER_CONTROL_H
|
||||
#include "config.h"
|
||||
#include <ccan/compiler/compiler.h>
|
||||
#include <daemon/netaddr.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
struct peer {
|
||||
@@ -12,15 +14,21 @@ struct peer {
|
||||
/* Inside ld->peers. */
|
||||
struct list_node list;
|
||||
|
||||
/* What stage is this in? */
|
||||
/* What stage is this in? NULL during first creation. */
|
||||
struct subdaemon *owner;
|
||||
|
||||
/* What's happening (doubles as error return for connect_cmd) */
|
||||
const char *condition;
|
||||
|
||||
/* ID of peer (NULL before initial handshake). */
|
||||
struct pubkey *id;
|
||||
|
||||
/* Our fd to the peer. */
|
||||
/* Our fd to the peer (-1 when we don't have it). */
|
||||
int fd;
|
||||
|
||||
/* Where we connected to, or it connected from. */
|
||||
struct netaddr netaddr;
|
||||
|
||||
/* HSM connection for this peer. */
|
||||
int hsmfd;
|
||||
|
||||
@@ -30,5 +38,6 @@ struct peer {
|
||||
|
||||
struct peer *peer_by_unique_id(struct lightningd *ld, u64 unique_id);
|
||||
|
||||
PRINTF_FMT(2,3) void peer_set_condition(struct peer *peer, const char *fmt, ...);
|
||||
void setup_listeners(struct lightningd *ld);
|
||||
#endif /* LIGHTNING_LIGHTNINGD_PEER_CONTROL_H */
|
||||
|
||||
Reference in New Issue
Block a user