lightningd/status: support daemon_conn for status_trace and status_failed.

We remove the unused status_send_fd, and rename status_send_sync (it
should only be used for that case now).

We add a status_setup_async(), and wire things internally to use that
if it's set up: status_setup() is renamed status_setup_sync().

Signed-off-by: Rusty Russell <rusty@rustcorp.com.au>
This commit is contained in:
Rusty Russell 2017-03-20 07:02:44 +10:30
parent 7442cf7c3e
commit 5637564cd4
10 changed files with 75 additions and 34 deletions

View File

@ -312,7 +312,7 @@ int main(int argc, char *argv[])
daemon_conn_init(peer, &peer->master, REQ_FD, req_in); daemon_conn_init(peer, &peer->master, REQ_FD, req_in);
peer->channel = NULL; peer->channel = NULL;
status_setup(REQ_FD); status_setup_async(&peer->master);
msg_queue_init(&peer->peer_out, peer); msg_queue_init(&peer->peer_out, peer);
daemon_conn_init(peer, &peer->gossip_client, GOSSIP_FD, daemon_conn_init(peer, &peer->gossip_client, GOSSIP_FD,

View File

@ -1,7 +1,9 @@
#include "connection.h" #include "connection.h"
#include <ccan/fdpass/fdpass.h>
#include <ccan/io/fdpass/fdpass.h> #include <ccan/io/fdpass/fdpass.h>
#include <ccan/take/take.h> #include <ccan/take/take.h>
#include <wire/wire_io.h> #include <wire/wire_io.h>
#include <wire/wire_sync.h>
struct io_plan *daemon_conn_read_next(struct io_conn *conn, struct io_plan *daemon_conn_read_next(struct io_conn *conn,
struct daemon_conn *dc) struct daemon_conn *dc)
@ -30,6 +32,26 @@ struct io_plan *daemon_conn_write_next(struct io_conn *conn,
} }
} }
bool daemon_conn_sync_flush(struct daemon_conn *dc)
{
const u8 *msg;
/* Flush any current packet. */
if (!io_flush_sync(dc->conn))
return false;
/* Flush existing messages. */
while ((msg = msg_dequeue(&dc->out)) != NULL) {
int fd = msg_is_fd(msg);
if (fd >= 0) {
if (!fdpass_send(io_conn_fd(dc->conn), fd))
return false;
} else if (!wire_sync_write(io_conn_fd(dc->conn), msg))
return false;
}
return true;
}
static struct io_plan *daemon_conn_start(struct io_conn *conn, static struct io_plan *daemon_conn_start(struct io_conn *conn,
struct daemon_conn *dc) struct daemon_conn *dc)
{ {

View File

@ -66,4 +66,8 @@ struct io_plan *daemon_conn_write_next(struct io_conn *conn,
struct io_plan *daemon_conn_read_next(struct io_conn *conn, struct io_plan *daemon_conn_read_next(struct io_conn *conn,
struct daemon_conn *dc); struct daemon_conn *dc);
/**
* daemon_conn_sync_flush - Flush connection by sending all messages now..
*/
bool daemon_conn_sync_flush(struct daemon_conn *dc);
#endif /* LIGHTNING_LIGHTNINGD_CONNECTION_H */ #endif /* LIGHTNING_LIGHTNINGD_CONNECTION_H */

View File

@ -537,8 +537,8 @@ int main(int argc, char *argv[])
timers_init(&daemon->timers, time_mono()); timers_init(&daemon->timers, time_mono());
/* stdin == control */ /* stdin == control */
status_setup(STDIN_FILENO);
daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req); daemon_conn_init(daemon, &daemon->master, STDIN_FILENO, recv_req);
status_setup_async(&daemon->master);
for (;;) { for (;;) {
struct timer *expired = NULL; struct timer *expired = NULL;
io_loop(&daemon->timers, &expired); io_loop(&daemon->timers, &expired);

View File

@ -308,7 +308,7 @@ static void act_one_initiator(struct handshake *h, int fd,
struct act_one act1; struct act_one act1;
size_t len; size_t len;
status_send(towire_initr_act_one(h)); status_send_sync(towire_initr_act_one(h));
/* BOLT #8: /* BOLT #8:
* *
@ -390,7 +390,7 @@ static void act_one_responder(struct handshake *h, int fd, struct pubkey *re)
{ {
struct act_one act1; struct act_one act1;
status_send(towire_respr_act_one(h)); status_send_sync(towire_respr_act_one(h));
/* BOLT #8: /* BOLT #8:
* *
@ -519,7 +519,7 @@ static void act_two_responder(struct handshake *h, int fd,
struct act_two act2; struct act_two act2;
size_t len; size_t len;
status_send(towire_respr_act_two(h)); status_send_sync(towire_respr_act_two(h));
/* BOLT #8: /* BOLT #8:
* *
@ -602,7 +602,7 @@ static void act_two_initiator(struct handshake *h, int fd, struct pubkey *re)
{ {
struct act_two act2; struct act_two act2;
status_send(towire_initr_act_two(h)); status_send_sync(towire_initr_act_two(h));
/* BOLT #8: /* BOLT #8:
* *
@ -731,7 +731,7 @@ static void act_three_initiator(struct handshake *h, int fd,
u8 spub[PUBKEY_DER_LEN]; u8 spub[PUBKEY_DER_LEN];
size_t len = sizeof(spub); size_t len = sizeof(spub);
status_send(towire_initr_act_three(h)); status_send_sync(towire_initr_act_three(h));
/* BOLT #8: /* BOLT #8:
* * `c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())` * * `c = encryptWithAD(temp_k2, 1, h, s.pub.serializeCompressed())`
@ -803,7 +803,7 @@ static void act_three_responder(struct handshake *h, int fd,
struct act_three act3; struct act_three act3;
u8 der[PUBKEY_DER_LEN]; u8 der[PUBKEY_DER_LEN];
status_send(towire_respr_act_three(h)); status_send_sync(towire_respr_act_three(h));
/* BOLT #8: /* BOLT #8:
* *
@ -979,7 +979,7 @@ int main(int argc, char *argv[])
subdaemon_debug(argc, argv); subdaemon_debug(argc, argv);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN); | SECP256K1_CONTEXT_SIGN);
status_setup(REQ_FD); status_setup_sync(REQ_FD);
hsm_setup(hsmfd); hsm_setup(hsmfd);

View File

@ -25,7 +25,7 @@ static ssize_t fake_write_all(int fd, const void *buf, size_t count)
static const char *status_prefix; static const char *status_prefix;
/* Simply print out status updates. */ /* Simply print out status updates. */
#define status_send(msg) \ #define status_send_sync(msg) \
printf("%s:# Act %s\n", status_prefix, \ printf("%s:# Act %s\n", status_prefix, \
fromwire_peektype(msg) == WIRE_INITR_ACT_ONE ? "One" \ fromwire_peektype(msg) == WIRE_INITR_ACT_ONE ? "One" \
: fromwire_peektype(msg) == WIRE_INITR_ACT_TWO ? "Two" \ : fromwire_peektype(msg) == WIRE_INITR_ACT_TWO ? "Two" \

View File

@ -426,7 +426,7 @@ int main(int argc, char *argv[])
master = tal(NULL, struct daemon_conn); master = tal(NULL, struct daemon_conn);
daemon_conn_init(master, master, STDIN_FILENO, control_received_req); daemon_conn_init(master, master, STDIN_FILENO, control_received_req);
status_setup(STDIN_FILENO); status_setup_async(master);
/* When conn closes, everything is freed. */ /* When conn closes, everything is freed. */
tal_steal(master->conn, master); tal_steal(master->conn, master);

View File

@ -676,7 +676,7 @@ int main(int argc, char *argv[])
signal(SIGCHLD, SIG_IGN); signal(SIGCHLD, SIG_IGN);
secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY secp256k1_ctx = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY
| SECP256K1_CONTEXT_SIGN); | SECP256K1_CONTEXT_SIGN);
status_setup(REQ_FD); status_setup_sync(REQ_FD);
msg = wire_sync_read(state, REQ_FD); msg = wire_sync_read(state, REQ_FD);
if (!msg) if (!msg)

View File

@ -1,4 +1,3 @@
#include "status.h"
#include "utils.h" #include "utils.h"
#include "wire/wire.h" #include "wire/wire.h"
#include "wire/wire_sync.h" #include "wire/wire_sync.h"
@ -8,18 +7,32 @@
#include <ccan/err/err.h> #include <ccan/err/err.h>
#include <ccan/fdpass/fdpass.h> #include <ccan/fdpass/fdpass.h>
#include <ccan/read_write_all/read_write_all.h> #include <ccan/read_write_all/read_write_all.h>
#include <ccan/take/take.h>
#include <ccan/tal/str/str.h> #include <ccan/tal/str/str.h>
#include <lightningd/connection.h>
#include <lightningd/status.h>
#include <stdarg.h> #include <stdarg.h>
static int status_fd = -1; static int status_fd = -1;
static struct daemon_conn *status_conn;
const void *trc; const void *trc;
void status_setup(int fd) void status_setup_sync(int fd)
{ {
assert(status_fd == -1);
assert(!status_conn);
status_fd = fd; status_fd = fd;
trc = tal_tmpctx(NULL); trc = tal_tmpctx(NULL);
} }
void status_setup_async(struct daemon_conn *master)
{
assert(status_fd == -1);
assert(!status_conn);
status_conn = master;
trc = tal_tmpctx(NULL);
}
static bool too_large(size_t len, int type) static bool too_large(size_t len, int type)
{ {
if (len > 65535) { if (len > 65535) {
@ -30,7 +43,7 @@ static bool too_large(size_t len, int type)
return false; return false;
} }
void status_send(const u8 *p) void status_send_sync(const u8 *p)
{ {
const u8 *msg = p; const u8 *msg = p;
assert(status_fd >= 0); assert(status_fd >= 0);
@ -43,16 +56,6 @@ void status_send(const u8 *p)
tal_free(p); tal_free(p);
} }
void status_send_fd(int fd)
{
assert(status_fd >= 0);
assert(fd >= 0);
if (!fdpass_send(status_fd, fd))
err(1, "Writing out status fd %i", fd);
close(fd);
}
static void status_send_with_hdr(u16 type, const void *p, size_t len) static void status_send_with_hdr(u16 type, const void *p, size_t len)
{ {
be16 be_type, be_len; be16 be_type, be_len;
@ -62,13 +65,19 @@ static void status_send_with_hdr(u16 type, const void *p, size_t len)
be_type = cpu_to_be16(type); be_type = cpu_to_be16(type);
be_len = cpu_to_be16(len + sizeof(be_type)); be_len = cpu_to_be16(len + sizeof(be_type));
assert(status_fd >= 0);
assert(be16_to_cpu(be_len) == len + sizeof(be_type)); assert(be16_to_cpu(be_len) == len + sizeof(be_type));
if (!write_all(status_fd, &be_len, sizeof(be_len)) if (status_fd >= 0) {
|| !write_all(status_fd, &be_type, sizeof(be_type)) if (!write_all(status_fd, &be_len, sizeof(be_len))
|| !write_all(status_fd, p, len)) || !write_all(status_fd, &be_type, sizeof(be_type))
err(1, "Writing out status %u len %zu", type, len); || !write_all(status_fd, p, len))
err(1, "Writing out status %u len %zu", type, len);
} else {
u8 *msg = tal_arr(NULL, u8, sizeof(be_type) + len);
memcpy(msg, &be_type, sizeof(be_type));
memcpy(msg + sizeof(be_type), p, len);
daemon_conn_send(status_conn, take(msg));
}
} }
void status_trace(const char *fmt, ...) void status_trace(const char *fmt, ...)
@ -99,5 +108,10 @@ void status_failed(u16 code, const char *fmt, ...)
status_send_with_hdr(code, str, strlen(str)); status_send_with_hdr(code, str, strlen(str));
va_end(ap); va_end(ap);
/* Don't let it take forever. */
alarm(10);
if (status_conn)
daemon_conn_sync_flush(status_conn);
exit(0x80 | (code & 0xFF)); exit(0x80 | (code & 0xFF));
} }

View File

@ -5,8 +5,11 @@
#include <ccan/short_types/short_types.h> #include <ccan/short_types/short_types.h>
#include <stdlib.h> #include <stdlib.h>
struct daemon_conn;
/* Simple status reporting API. */ /* Simple status reporting API. */
void status_setup(int fd); void status_setup_sync(int fd);
void status_setup_async(struct daemon_conn *master);
/* Convenient context, frees up after every status_update/failed */ /* Convenient context, frees up after every status_update/failed */
extern const void *trc; extern const void *trc;
@ -18,9 +21,7 @@ extern const void *trc;
#define STATUS_FAIL 0x8000 #define STATUS_FAIL 0x8000
/* Send a message (frees the message). */ /* Send a message (frees the message). */
void status_send(const u8 *msg); void status_send_sync(const u8 *msg);
/* Send a file descriptor (closes fd). */
void status_send_fd(int fd);
/* Send a printf-style debugging trace. */ /* Send a printf-style debugging trace. */
void status_trace(const char *fmt, ...) PRINTF_FMT(1,2); void status_trace(const char *fmt, ...) PRINTF_FMT(1,2);
/* Send a failure status code with printf-style msg, and exit. */ /* Send a failure status code with printf-style msg, and exit. */