summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--conf/conf.h2
-rw-r--r--nest/cli.h14
-rw-r--r--sysdep/unix/config.Y3
-rw-r--r--sysdep/unix/io.c2
-rw-r--r--sysdep/unix/main.c67
-rw-r--r--sysdep/unix/unix.h2
6 files changed, 70 insertions, 20 deletions
diff --git a/conf/conf.h b/conf/conf.h
index c0a897fc..dd296652 100644
--- a/conf/conf.h
+++ b/conf/conf.h
@@ -14,6 +14,7 @@
#include "lib/hash.h"
#include "lib/resource.h"
#include "lib/timer.h"
+#include "lib/tlists.h"
/* Configuration structure */
struct config {
@@ -25,6 +26,7 @@ struct config {
list logfiles; /* Configured log files (sysdep) */
list tests; /* Configured unit tests (f_bt_test_suite) */
list symbols; /* Configured symbols in config order */
+ TLIST_STRUCT_DEF(cli_config, struct cli_config) cli; /* Configured CLI sockets */
int mrtdump_file; /* Configured MRTDump file (sysdep, fd in unix) */
const char *syslog_name; /* Name used for syslog (NULL -> no syslog) */
diff --git a/nest/cli.h b/nest/cli.h
index 3596e37c..a9848a89 100644
--- a/nest/cli.h
+++ b/nest/cli.h
@@ -11,6 +11,8 @@
#include "lib/resource.h"
#include "lib/event.h"
+#include "lib/tlists.h"
+#include "conf/conf.h"
#define CLI_RX_BUF_SIZE 4096
#define CLI_TX_BUF_SIZE 4096
@@ -47,6 +49,18 @@ typedef struct cli {
uint async_msg_size; /* Total size of async messages queued in tx_buf */
} cli;
+struct cli_config {
+#define TLIST_PREFIX cli_config
+#define TLIST_TYPE struct cli_config
+#define TLIST_ITEM n
+#define TLIST_DEFINED_BEFORE
+#define TLIST_WANT_ADD_TAIL
+ TLIST_DEFAULT_NODE;
+ const char *name;
+ uint uid, gid, mode;
+};
+#include "lib/tlists.h"
+
extern pool *cli_pool;
extern struct cli *this_cli; /* Used during parsing */
diff --git a/sysdep/unix/config.Y b/sysdep/unix/config.Y
index 8de79600..24d1ae5d 100644
--- a/sysdep/unix/config.Y
+++ b/sysdep/unix/config.Y
@@ -17,7 +17,7 @@ static struct log_config *this_log;
CF_DECLS
-CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT)
+CF_KEYWORDS(LOG, SYSLOG, NAME, STDERR, UDP, PORT, CLI)
CF_KEYWORDS(ALL, DEBUG, TRACE, INFO, REMOTE, WARNING, ERROR, AUTH, FATAL, BUG)
CF_KEYWORDS(DEBUG, LATENCY, LIMIT, WATCHDOG, WARNING, TIMEOUT, THREADS)
@@ -123,7 +123,6 @@ mrtdump_base:
}
;
-
conf: debug_unix ;
debug_unix:
diff --git a/sysdep/unix/io.c b/sysdep/unix/io.c
index da2c5492..5a0dde8e 100644
--- a/sysdep/unix/io.c
+++ b/sysdep/unix/io.c
@@ -1531,7 +1531,7 @@ err:
}
int
-sk_open_unix(sock *s, char *name)
+sk_open_unix(sock *s, const char *name)
{
struct sockaddr_un sa;
int fd;
diff --git a/sysdep/unix/main.c b/sysdep/unix/main.c
index 0d7788bb..c712aee4 100644
--- a/sysdep/unix/main.c
+++ b/sysdep/unix/main.c
@@ -395,9 +395,12 @@ cmd_reconfig_status(void)
* Command-Line Interface
*/
-static sock *cli_sk;
static char *path_control_socket = PATH_CONTROL_SOCKET;
-
+static struct cli_config *main_control_socket_config = NULL;
+static struct cli_listener {
+ sock *s;
+ struct cli_config *config;
+} *main_control_socket = NULL;
static void
cli_write(cli *c)
@@ -519,33 +522,65 @@ cli_connect(sock *s, uint size UNUSED)
return 1;
}
-static void
-cli_init_unix(uid_t use_uid, gid_t use_gid)
+static struct cli_listener *
+cli_listener(struct cli_config *cf)
{
- sock *s;
-
- cli_init();
- s = cli_sk = sk_new(cli_pool);
+ struct cli_listener *l = mb_allocz(cli_pool, sizeof *l);
+ l->config = cf;
+ sock *s = l->s = sk_new(cli_pool);
s->type = SK_UNIX_PASSIVE;
s->rx_hook = cli_connect;
s->err_hook = cli_connect_err;
+ s->data = cf;
s->rbsize = 1024;
s->fast_rx = 1;
/* Return value intentionally ignored */
- unlink(path_control_socket);
+ unlink(cf->name);
+
+ if (sk_open_unix(s, cf->name) < 0)
+ {
+ log(L_ERR "Cannot create control socket %s: %m", cf->name);
+ return NULL;
+ }
+
+ if (cf->uid || cf->gid)
+ if (chown(cf->name, cf->uid, cf->gid) < 0)
+ {
+ log(L_ERR "Cannot chown control socket %s: %m", cf->name);
+ return NULL;
+ }
- if (sk_open_unix(s, path_control_socket) < 0)
- die("Cannot create control socket %s: %m", path_control_socket);
+ if (chmod(cf->name, cf->mode) < 0)
+ {
+ log(L_ERR "Cannot chmod control socket %s: %m", cf->name);
+ return NULL;
+ }
- if (use_uid || use_gid)
- if (chown(path_control_socket, use_uid, use_gid) < 0)
- die("chown: %m");
+ return l;
+}
- if (chmod(path_control_socket, 0660) < 0)
- die("chmod: %m");
+static void
+cli_init_unix(uid_t use_uid, gid_t use_gid)
+{
+ ASSERT_DIE(main_control_socket_config == NULL);
+
+ main_control_socket_config = mb_alloc(&root_pool, sizeof *main_control_socket_config);
+ *main_control_socket_config = (struct cli_config) {
+ .name = path_control_socket,
+ .uid = use_uid,
+ .gid = use_gid,
+ .mode = 0660,
+ };
+
+ ASSERT_DIE(main_control_socket == NULL);
+ cli_init();
+ main_control_socket = cli_listener(main_control_socket_config);
+ if (!main_control_socket)
+ die("Won't run without control socket");
}
+
/*
* PID file
*/
diff --git a/sysdep/unix/unix.h b/sysdep/unix/unix.h
index c1d966f9..7c15e30d 100644
--- a/sysdep/unix/unix.h
+++ b/sysdep/unix/unix.h
@@ -107,7 +107,7 @@ extern volatile sig_atomic_t async_shutdown_flag;
void io_init(void);
void io_loop(void);
void io_log_dump(void);
-int sk_open_unix(struct birdsock *s, char *name);
+int sk_open_unix(struct birdsock *s, const char *name);
struct rfile *rf_open(struct pool *, const char *name, const char *mode);
struct rfile *rf_fdopen(pool *p, int fd, const char *mode);
void *rf_file(struct rfile *f);