2017-03-10 11:48:43 +01:00
|
|
|
#ifndef LIGHTNING_LIGHTNINGD_SUBD_H
|
|
|
|
#define LIGHTNING_LIGHTNINGD_SUBD_H
|
|
|
|
#include "config.h"
|
|
|
|
#include <ccan/endian/endian.h>
|
|
|
|
#include <ccan/list/list.h>
|
|
|
|
#include <ccan/short_types/short_types.h>
|
|
|
|
#include <ccan/tal/tal.h>
|
2018-02-18 13:59:46 +01:00
|
|
|
#include <ccan/typesafe_cb/typesafe_cb.h>
|
2017-08-28 18:05:01 +02:00
|
|
|
#include <common/msg_queue.h>
|
2018-03-25 12:21:57 +02:00
|
|
|
#include <wire/wire.h>
|
2017-03-10 11:48:43 +01:00
|
|
|
|
2018-02-19 02:06:15 +01:00
|
|
|
struct crypto_state;
|
2017-03-10 11:48:43 +01:00
|
|
|
struct io_conn;
|
2022-01-11 02:13:59 +01:00
|
|
|
struct peer_fd;
|
2017-03-10 11:48:43 +01:00
|
|
|
|
|
|
|
/* By convention, replies are requests + 100 */
|
|
|
|
#define SUBD_REPLY_OFFSET 100
|
2017-06-24 08:25:53 +02:00
|
|
|
/* And reply failures are requests + 200 */
|
|
|
|
#define SUBD_REPLYFAIL_OFFSET 200
|
2017-03-10 11:48:43 +01:00
|
|
|
|
|
|
|
/* One of our subds. */
|
|
|
|
struct subd {
|
2022-01-22 05:49:22 +01:00
|
|
|
/* Inside ld->subds */
|
|
|
|
struct list_node list;
|
|
|
|
|
2017-08-29 06:12:04 +02:00
|
|
|
/* Name, like John, or "lightning_hsmd" */
|
2017-03-10 11:48:43 +01:00
|
|
|
const char *name;
|
|
|
|
/* The Big Cheese. */
|
|
|
|
struct lightningd *ld;
|
|
|
|
/* pid, for waiting for status when it dies. */
|
|
|
|
int pid;
|
|
|
|
/* Connection. */
|
|
|
|
struct io_conn *conn;
|
|
|
|
|
2018-02-12 11:13:04 +01:00
|
|
|
/* If we are associated with a single channel, this points to it. */
|
2018-02-18 13:59:46 +01:00
|
|
|
void *channel;
|
2017-03-10 11:48:43 +01:00
|
|
|
|
2021-04-16 06:31:26 +02:00
|
|
|
/* Have we received the version msg yet? Don't send until we do. */
|
|
|
|
bool rcvd_version;
|
|
|
|
|
2017-03-10 11:48:43 +01:00
|
|
|
/* For logging */
|
|
|
|
struct log *log;
|
2019-11-17 12:40:33 +01:00
|
|
|
const struct node_id *node_id;
|
2017-03-10 11:48:43 +01:00
|
|
|
|
2017-11-01 02:10:48 +01:00
|
|
|
/* Callback when non-reply message comes in (inside db transaction) */
|
2017-10-12 08:35:04 +02:00
|
|
|
unsigned (*msgcb)(struct subd *, const u8 *, const int *);
|
2017-03-10 11:48:43 +01:00
|
|
|
const char *(*msgname)(int msgtype);
|
2017-09-12 06:55:52 +02:00
|
|
|
|
2022-01-11 02:13:59 +01:00
|
|
|
/* If peer_fd == NULL, it was a disconnect/crash. Otherwise,
|
2018-02-19 02:06:15 +01:00
|
|
|
* sufficient information to hand back to gossipd, including the
|
|
|
|
* error message we sent them if any. */
|
2018-02-18 13:59:46 +01:00
|
|
|
void (*errcb)(void *channel,
|
2022-01-11 02:13:59 +01:00
|
|
|
struct peer_fd *peer_fd,
|
2018-02-18 13:59:46 +01:00
|
|
|
const struct channel_id *channel_id,
|
|
|
|
const char *desc,
|
2021-02-02 13:47:01 +01:00
|
|
|
bool warning,
|
2018-02-19 02:06:15 +01:00
|
|
|
const u8 *err_for_them);
|
2018-02-18 13:59:46 +01:00
|
|
|
|
2018-02-23 06:53:47 +01:00
|
|
|
/* Callback to display information for listpeers RPC */
|
|
|
|
void (*billboardcb)(void *channel, bool perm, const char *happenings);
|
|
|
|
|
2017-03-10 11:48:43 +01:00
|
|
|
/* Buffer for input. */
|
|
|
|
u8 *msg_in;
|
2017-03-19 21:31:35 +01:00
|
|
|
|
|
|
|
/* While we're reading fds in. */
|
|
|
|
size_t num_fds_in_read;
|
|
|
|
int *fds_in;
|
2017-03-10 11:48:43 +01:00
|
|
|
|
2017-10-12 08:35:03 +02:00
|
|
|
/* For global daemons: we fail if they fail. */
|
|
|
|
bool must_not_exit;
|
|
|
|
|
2018-04-26 06:51:01 +02:00
|
|
|
/* Do we talk to a peer? ie. not onchaind */
|
|
|
|
bool talks_to_peer;
|
|
|
|
|
2017-03-10 11:48:43 +01:00
|
|
|
/* Messages queue up here. */
|
2018-10-25 01:46:08 +02:00
|
|
|
struct msg_queue *outq;
|
2017-03-10 11:48:43 +01:00
|
|
|
|
|
|
|
/* Callbacks for replies. */
|
|
|
|
struct list_head reqs;
|
2022-01-22 05:49:22 +01:00
|
|
|
|
|
|
|
/* Did lightningd already wait for this pid? */
|
|
|
|
int *wstatus;
|
2017-03-10 11:48:43 +01:00
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
2017-10-12 08:35:03 +02:00
|
|
|
* new_global_subd - create a new global subdaemon.
|
2017-03-10 11:48:43 +01:00
|
|
|
* @ld: global state
|
|
|
|
* @name: basename of daemon
|
|
|
|
* @msgname: function to get name from messages
|
2018-09-20 05:06:42 +02:00
|
|
|
* @msgcb: function to call (inside db transaction) when non-fatal message received
|
2017-05-25 04:16:03 +02:00
|
|
|
* @...: NULL-terminated list of pointers to fds to hand as fd 3, 4...
|
|
|
|
* (can be take, if so, set to -1)
|
2017-03-10 11:48:43 +01:00
|
|
|
*
|
2017-03-19 21:31:35 +01:00
|
|
|
* @msgcb gets called with @fds set to NULL: if it returns a positive number,
|
2017-10-12 08:35:04 +02:00
|
|
|
* that many @fds are received before calling again. @msgcb can free subd
|
|
|
|
* to shut it down.
|
2017-03-10 11:48:43 +01:00
|
|
|
*/
|
2017-10-12 08:35:03 +02:00
|
|
|
struct subd *new_global_subd(struct lightningd *ld,
|
|
|
|
const char *name,
|
|
|
|
const char *(*msgname)(int msgtype),
|
2017-10-12 08:35:04 +02:00
|
|
|
unsigned int (*msgcb)(struct subd *, const u8 *,
|
|
|
|
const int *fds),
|
2017-10-12 08:35:03 +02:00
|
|
|
...);
|
|
|
|
|
|
|
|
/**
|
2018-02-12 11:13:04 +01:00
|
|
|
* new_channel_subd - create a new subdaemon for a specific channel.
|
2022-03-29 01:49:23 +02:00
|
|
|
* @ctx: context to allocate from (usually peer or channel)
|
2017-10-12 08:35:03 +02:00
|
|
|
* @ld: global state
|
|
|
|
* @name: basename of daemon
|
2018-02-12 11:13:04 +01:00
|
|
|
* @channel: channel to associate.
|
2019-11-17 12:40:33 +01:00
|
|
|
* @node_id: node_id of peer, for logging.
|
2018-02-18 13:59:46 +01:00
|
|
|
* @base_log: log to use (actually makes a copy so it has name in prefix)
|
2017-10-12 08:35:03 +02:00
|
|
|
* @msgname: function to get name from messages
|
2017-11-01 02:10:48 +01:00
|
|
|
* @msgcb: function to call (inside db transaction) when non-fatal message received (or NULL)
|
2018-02-23 06:53:47 +01:00
|
|
|
* @errcb: function to call on errors.
|
|
|
|
* @billboardcb: function to call for billboard updates.
|
2017-10-12 08:35:03 +02:00
|
|
|
* @...: NULL-terminated list of pointers to fds to hand as fd 3, 4...
|
|
|
|
* (can be take, if so, set to -1)
|
|
|
|
*
|
|
|
|
* @msgcb gets called with @fds set to NULL: if it returns a positive number,
|
|
|
|
* that many @fds are received before calling again. If it returns -1, the
|
|
|
|
* subdaemon is shutdown.
|
|
|
|
*/
|
2022-03-29 01:49:23 +02:00
|
|
|
struct subd *new_channel_subd_(const tal_t *ctx,
|
|
|
|
struct lightningd *ld,
|
2018-02-18 13:59:46 +01:00
|
|
|
const char *name,
|
|
|
|
void *channel,
|
2019-11-17 12:40:33 +01:00
|
|
|
const struct node_id *node_id,
|
2018-02-18 13:59:46 +01:00
|
|
|
struct log *base_log,
|
2018-04-26 06:51:01 +02:00
|
|
|
bool talks_to_peer,
|
2018-02-18 13:59:46 +01:00
|
|
|
const char *(*msgname)(int msgtype),
|
|
|
|
unsigned int (*msgcb)(struct subd *, const u8 *,
|
|
|
|
const int *fds),
|
|
|
|
void (*errcb)(void *channel,
|
2022-01-11 02:13:59 +01:00
|
|
|
struct peer_fd *peer_fd,
|
2018-02-18 13:59:46 +01:00
|
|
|
const struct channel_id *channel_id,
|
|
|
|
const char *desc,
|
2021-02-02 13:47:01 +01:00
|
|
|
bool warning,
|
2018-02-19 02:06:15 +01:00
|
|
|
const u8 *err_for_them),
|
2018-02-23 06:53:47 +01:00
|
|
|
void (*billboardcb)(void *channel, bool perm,
|
|
|
|
const char *happenings),
|
2018-02-18 13:59:46 +01:00
|
|
|
...);
|
|
|
|
|
2022-03-29 01:49:23 +02:00
|
|
|
#define new_channel_subd(ctx, ld, name, channel, node_id, log, \
|
2020-12-01 21:49:35 +01:00
|
|
|
talks_to_peer, msgname, msgcb, errcb, \
|
|
|
|
billboardcb, ...) \
|
2022-03-29 01:49:23 +02:00
|
|
|
new_channel_subd_((ctx), (ld), (name), (channel), (node_id), \
|
2020-12-01 21:49:35 +01:00
|
|
|
(log), (talks_to_peer), \
|
2018-04-26 06:51:01 +02:00
|
|
|
(msgname), (msgcb), \
|
2018-02-18 13:59:46 +01:00
|
|
|
typesafe_cb_postargs(void, void *, (errcb), \
|
2019-05-04 07:53:12 +02:00
|
|
|
(channel), \
|
2022-01-11 02:13:59 +01:00
|
|
|
struct peer_fd *, \
|
2018-02-18 13:59:46 +01:00
|
|
|
const struct channel_id *, \
|
2019-07-26 04:11:19 +02:00
|
|
|
const char *, bool, const u8 *), \
|
2018-02-23 06:53:47 +01:00
|
|
|
typesafe_cb_postargs(void, void *, (billboardcb), \
|
|
|
|
(channel), bool, \
|
|
|
|
const char *), \
|
2018-02-18 13:59:46 +01:00
|
|
|
__VA_ARGS__)
|
2017-06-24 08:50:23 +02:00
|
|
|
|
2017-03-10 11:48:43 +01:00
|
|
|
/**
|
|
|
|
* subd_send_msg - queue a message to the subdaemon.
|
|
|
|
* @sd: subdaemon to request
|
|
|
|
* @msg_out: message (can be take)
|
|
|
|
*/
|
|
|
|
void subd_send_msg(struct subd *sd, const u8 *msg_out);
|
|
|
|
|
|
|
|
/**
|
2017-06-24 08:50:23 +02:00
|
|
|
* subd_send_fd - queue a file descriptor to pass to the subdaemon.
|
2017-03-10 11:48:43 +01:00
|
|
|
* @sd: subdaemon to request
|
|
|
|
* @fd: the file descriptor (closed after passing).
|
|
|
|
*/
|
|
|
|
void subd_send_fd(struct subd *sd, int fd);
|
|
|
|
|
|
|
|
/**
|
|
|
|
* subd_req - queue a request to the subdaemon.
|
2017-04-01 12:58:30 +02:00
|
|
|
* @ctx: lifetime for the callback: if this is freed, don't call replycb.
|
2017-03-10 11:48:43 +01:00
|
|
|
* @sd: subdaemon to request
|
|
|
|
* @msg_out: request message (can be take)
|
|
|
|
* @fd_out: if >=0 fd to pass at the end of the message (closed after)
|
2017-06-24 08:25:53 +02:00
|
|
|
* @num_fds_in: how many fds to read in to hand to @replycb if it's a reply.
|
2017-11-01 02:10:48 +01:00
|
|
|
* @replycb: callback (inside db transaction) when reply comes in (can free subd)
|
2017-03-10 11:48:43 +01:00
|
|
|
* @replycb_data: final arg to hand to @replycb
|
|
|
|
*
|
|
|
|
* @replycb cannot free @sd, so it returns false to remove it.
|
2017-06-24 08:25:53 +02:00
|
|
|
* Note that @replycb is called for replies of type @msg_out + SUBD_REPLY_OFFSET
|
|
|
|
* with @num_fds_in fds, or type @msg_out + SUBD_REPLYFAIL_OFFSET with no fds.
|
2017-03-10 11:48:43 +01:00
|
|
|
*/
|
2017-04-01 12:58:30 +02:00
|
|
|
#define subd_req(ctx, sd, msg_out, fd_out, num_fds_in, replycb, replycb_data) \
|
|
|
|
subd_req_((ctx), (sd), (msg_out), (fd_out), (num_fds_in), \
|
2017-10-12 08:35:04 +02:00
|
|
|
typesafe_cb_preargs(void, void *, \
|
2017-03-19 21:31:30 +01:00
|
|
|
(replycb), (replycb_data), \
|
|
|
|
struct subd *, \
|
|
|
|
const u8 *, const int *), \
|
2017-03-10 11:48:43 +01:00
|
|
|
(replycb_data))
|
2022-03-08 01:14:41 +01:00
|
|
|
struct subd_req *subd_req_(const tal_t *ctx,
|
2017-04-01 12:58:30 +02:00
|
|
|
struct subd *sd,
|
2017-03-19 21:31:30 +01:00
|
|
|
const u8 *msg_out,
|
|
|
|
int fd_out, size_t num_fds_in,
|
2017-10-12 08:35:04 +02:00
|
|
|
void (*replycb)(struct subd *, const u8 *, const int *, void *),
|
2017-03-19 21:31:30 +01:00
|
|
|
void *replycb_data);
|
2017-03-10 11:48:43 +01:00
|
|
|
|
2017-10-12 08:35:03 +02:00
|
|
|
/**
|
2018-02-20 10:44:21 +01:00
|
|
|
* subd_release_channel - shut down a subdaemon which no longer owns the channel.
|
2018-02-12 11:13:04 +01:00
|
|
|
* @owner: subd which owned channel.
|
|
|
|
* @channel: channel to release.
|
2017-10-12 08:35:03 +02:00
|
|
|
*
|
2018-02-12 11:13:04 +01:00
|
|
|
* If the subdaemon is not already shutting down, and it is a per-channel
|
2021-12-28 00:21:09 +01:00
|
|
|
* subdaemon, this shuts it down. Don't call this directly, use
|
|
|
|
* channel_set_owner() or uncommitted_channel_release_subd().
|
2017-10-12 08:35:03 +02:00
|
|
|
*/
|
2021-12-28 00:21:09 +01:00
|
|
|
void subd_release_channel(struct subd *owner, const void *channel);
|
2017-10-12 08:35:03 +02:00
|
|
|
|
2017-04-12 08:52:32 +02:00
|
|
|
/**
|
|
|
|
* subd_shutdown - try to politely shut down a subdaemon.
|
|
|
|
* @subd: subd to shutdown.
|
|
|
|
* @seconds: maximum seconds to wait for it to exit.
|
|
|
|
*
|
|
|
|
* This closes the fd to the subdaemon, and gives it a little while to exit.
|
|
|
|
* The @finished callback will never be called.
|
2019-05-30 16:54:06 +02:00
|
|
|
*
|
|
|
|
* Return value is null, so pattern should be:
|
|
|
|
*
|
|
|
|
* sd = subd_shutdown(sd, 10);
|
2017-04-12 08:52:32 +02:00
|
|
|
*/
|
2019-05-30 16:54:06 +02:00
|
|
|
struct subd *subd_shutdown(struct subd *subd, unsigned int seconds);
|
2017-04-12 08:52:32 +02:00
|
|
|
|
2022-01-30 04:37:30 +01:00
|
|
|
/**
|
|
|
|
* subd_shutdown_remaining - kill all remaining (per-peer) subds
|
|
|
|
* @ld: lightningd
|
|
|
|
*
|
|
|
|
* They should already be exiting (since we shutdown hsmd), but
|
|
|
|
* make sure they have.
|
|
|
|
*/
|
|
|
|
void subd_shutdown_remaining(struct lightningd *ld);
|
|
|
|
|
2018-09-03 05:40:00 +02:00
|
|
|
/* Ugly helper to get full pathname of the current binary. */
|
|
|
|
const char *find_my_abspath(const tal_t *ctx, const char *argv0);
|
|
|
|
|
2022-01-22 05:49:22 +01:00
|
|
|
/* lightningd captures SIGCHLD and waits, but so does subd. */
|
|
|
|
void maybe_subd_child(struct lightningd *ld, int childpid, int wstatus);
|
|
|
|
|
2017-10-24 04:06:14 +02:00
|
|
|
#if DEVELOPER
|
2017-05-24 12:10:16 +02:00
|
|
|
char *opt_subd_dev_disconnect(const char *optarg, struct lightningd *ld);
|
2017-08-18 06:43:52 +02:00
|
|
|
|
|
|
|
bool dev_disconnect_permanent(struct lightningd *ld);
|
2017-10-24 04:06:14 +02:00
|
|
|
#endif /* DEVELOPER */
|
2017-03-10 11:48:43 +01:00
|
|
|
#endif /* LIGHTNING_LIGHTNINGD_SUBD_H */
|