Skip to content

Commit

Permalink
connectd: Track sodium_fd for Mac tests
Browse files Browse the repository at this point in the history
On Mac most tests report BROKEN because sodium creating an untracked fd pointing to /dev/random. dev_report_fd’s finds it at tear down and reports a BROKEN message.

Tracking the fd used by sodium allows us to squeltch this message and make tests more usable on Mac.

While we’re here we added the fd mode to the log to help with future rogue fd issues.

ChangeLog-None
  • Loading branch information
ddustin committed Sep 28, 2023
1 parent 57ead06 commit e805392
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 1 deletion.
42 changes: 41 additions & 1 deletion connectd/connectd.c
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@
#include <unistd.h>
#include <wire/wire_io.h>
#include <wire/wire_sync.h>
#include <sys/stat.h>

/*~ We are passed two file descriptors when exec'ed from `lightningd`: the
* first is a connection to `hsmd`, which we need for the cryptographic
Expand Down Expand Up @@ -1393,6 +1394,9 @@ setup_listeners(const tal_t *ctx,
}


static void dev_report_fds(struct daemon *daemon, const u8 *msg);


/*~ Parse the incoming connect init message from lightningd ("master") and
* assign config variables to the daemon; it should be the first message we
* get. */
Expand Down Expand Up @@ -1957,6 +1961,28 @@ static const char *try_tal_name(const tal_t *ctx, const void *p)
return tal_fmt(ctx, "%p", p);
}

static char *fd_mode_str(int fd)
{
struct stat finfo;
if (0 != fstat(fd, &finfo))
return "invalid fd";
if (S_ISBLK(finfo.st_mode))
return "block special";
if (S_ISCHR(finfo.st_mode))
return "char special";
if (S_ISDIR(finfo.st_mode))
return "directory";
if (S_ISFIFO(finfo.st_mode))
return "fifo or socket";
if (S_ISREG(finfo.st_mode))
return "regular file";
if (S_ISLNK(finfo.st_mode))
return "symbolic link";
if (S_ISSOCK(finfo.st_mode))
return "socket";
return "unknown";
}

static void dev_report_fds(struct daemon *daemon, const u8 *msg)
{
for (int fd = 3; fd < 4096; fd++) {
Expand All @@ -1981,9 +2007,14 @@ static void dev_report_fds(struct daemon *daemon, const u8 *msg)
status_info("dev_report_fds: %i -> gossip_store", fd);
continue;
}
if (fd == daemon->sodium_fd) {
status_info("dev_report_fds: %i -> sodium fd", fd);
continue;
}
c = io_have_fd(fd, &listener);
if (!c) {
status_broken("dev_report_fds: %i open but unowned?", fd);
status_broken("dev_report_fds: %i open but unowned? fd"
" mode: %s", fd, fd_mode_str(fd));
continue;
} else if (listener) {
l = (void *)c;
Expand Down Expand Up @@ -2154,12 +2185,20 @@ int main(int argc, char *argv[])
{
struct daemon *daemon;
bool developer;
struct stat finfo;
int sodium_fd;

setup_locale();

/* Common subdaemon setup code. */
developer = subdaemon_setup(argc, argv);

/* Check if lib-sodium is using fd 5 and it looks like /dev/random */
sodium_fd = -1;
if(!isatty(5) && errno == ENOTTY && 0 == fstat(5, &finfo))
if (S_ISCHR(finfo.st_mode) && !finfo.st_size)
sodium_fd = 5;

/* Allocate and set up our simple top-level structure. */
daemon = tal(NULL, struct daemon);
daemon->developer = developer;
Expand All @@ -2171,6 +2210,7 @@ int main(int argc, char *argv[])
list_head_init(&daemon->connecting);
timers_init(&daemon->timers, time_mono());
daemon->gossip_store_fd = -1;
daemon->sodium_fd = sodium_fd;
daemon->shutting_down = false;
daemon->dev_suppress_gossip = false;

Expand Down
3 changes: 3 additions & 0 deletions connectd/connectd.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,9 @@ struct daemon {
/* If non-zero, port to listen for websocket connections. */
u16 websocket_port;

/* If lib-sodium keeps a fd open to /dev/random, we track it here. */
int sodium_fd;

/* The gossip_store */
int gossip_store_fd;
size_t gossip_store_end;
Expand Down

0 comments on commit e805392

Please sign in to comment.