commit 2f5d274059dcb6a55b4c5b7014b7064ffe31f716
parent d21c0aab5fcf1ae6db061cda8d02ba114986f694
Author: Joris Vink <joris@coders.se>
Date: Mon, 16 Jan 2023 21:00:01 +0100
Rework runtime init a little bit.
It was hardcoded that if KORE_USE_PYTHON was defined we would
look at the passed argument on the command-line as the python
script or module to be run.
This won't work when adding more runtimes.
So instead call a kore_runtime_resolve() function that in
turn calls each available runtime its resolve function.
That resolve function will check if its a script / module
that it can load, and if so will load it.
This way we can remove all those KORE_USE_PYTHON blocks in the
Kore startup path and we pave the way for lua.
Diffstat:
7 files changed, 136 insertions(+), 53 deletions(-)
diff --git a/include/kore/kore.h b/include/kore/kore.h
@@ -25,6 +25,7 @@
#include <sys/types.h>
#include <sys/time.h>
#include <sys/queue.h>
+#include <sys/stat.h>
#include <sys/un.h>
#include <netinet/in.h>
@@ -276,6 +277,7 @@ extern struct connection_list disconnected;
struct kore_runtime {
int type;
+ int (*resolve)(const char *, const struct stat *);
#if !defined(KORE_NO_HTTP)
int (*http_request)(void *, struct http_request *);
void (*http_request_free)(void *, struct http_request *);
@@ -749,6 +751,7 @@ void kore_server_closeall(void);
void kore_server_cleanup(void);
void kore_server_free(struct kore_server *);
void kore_server_finalize(struct kore_server *);
+void kore_hooks_set(const char *, const char *, const char *);
struct kore_server *kore_server_create(const char *);
struct kore_server *kore_server_lookup(const char *);
@@ -819,6 +822,7 @@ void kore_tls_dh_check(void);
int kore_tls_supported(void);
void kore_tls_version_set(int);
void kore_tls_keymgr_init(void);
+void kore_tls_log_version(void);
int kore_tls_dh_load(const char *);
void kore_tls_seed(const void *, size_t);
int kore_tls_ciphersuite_set(const char *);
@@ -1024,6 +1028,7 @@ int kore_route_lookup(struct http_request *,
#endif
/* runtime.c */
+const size_t kore_runtime_count(void);
struct kore_runtime_call *kore_runtime_getcall(const char *);
struct kore_module *kore_module_load(const char *,
const char *, int);
@@ -1031,6 +1036,7 @@ struct kore_module *kore_module_load(const char *,
void kore_runtime_execute(struct kore_runtime_call *);
int kore_runtime_onload(struct kore_runtime_call *, int);
void kore_runtime_signal(struct kore_runtime_call *, int);
+void kore_runtime_resolve(const char *, const struct stat *);
void kore_runtime_configure(struct kore_runtime_call *, int, char **);
void kore_runtime_connect(struct kore_runtime_call *, struct connection *);
#if !defined(KORE_NO_HTTP)
diff --git a/include/kore/python_api.h b/include/kore/python_api.h
@@ -44,10 +44,6 @@ void kore_python_seccomp_cleanup(void);
void kore_python_seccomp_hook(const char *);
#endif
-#if !defined(KORE_SINGLE_BINARY)
-extern const char *kore_pymodule;
-#endif
-
extern struct kore_module_functions kore_python_module;
extern struct kore_runtime kore_python_runtime;
diff --git a/src/kore.c b/src/kore.c
@@ -62,7 +62,7 @@ int skip_chroot = 0;
u_int8_t worker_count = 0;
char **kore_argv = NULL;
int kore_mem_guard = 0;
-int kore_foreground = 0;
+int kore_foreground = 1;
char *kore_progname = NULL;
u_int32_t kore_socket_backlog = 5000;
int kore_quit = KORE_QUIT_NONE;
@@ -83,16 +83,16 @@ static void kore_server_shutdown(void);
static void kore_server_start(int, char *[]);
static void kore_call_parent_configure(int, char **);
-#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON)
-static const char *parent_config_hook = KORE_PYTHON_CONFIG_HOOK;
-static const char *parent_teardown_hook = KORE_PYTHON_TEARDOWN_HOOK;
-#else
+#if !defined(KORE_SINGLE_BINARY)
+static const char *rarg0 = NULL;
+#endif
+
static const char *parent_config_hook = KORE_CONFIG_HOOK;
static const char *parent_teardown_hook = KORE_TEARDOWN_HOOK;
+
#if defined(KORE_SINGLE_BINARY)
static const char *parent_daemonized_hook = KORE_DAEMONIZED_HOOK;
#endif
-#endif
static void
usage(void)
@@ -167,10 +167,10 @@ version(void)
int
main(int argc, char *argv[])
{
- struct kore_runtime_call *rcall;
-#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON)
+#if !defined(KORE_SINGLE_BINARY)
struct stat st;
#endif
+ struct kore_runtime_call *rcall;
kore_argc = argc;
kore_argv = argv;
@@ -192,23 +192,22 @@ main(int argc, char *argv[])
argv += optind;
#endif
-#if !defined(KORE_SINGLE_BINARY) && defined(KORE_USE_PYTHON)
- if (argc > 0) {
- kore_pymodule = argv[0];
- argc--;
- argv++;
- } else {
- kore_pymodule = NULL;
- }
-
- if (kore_pymodule) {
- if (lstat(kore_pymodule, &st) == -1) {
- fatal("failed to stat '%s': %s",
- kore_pymodule, errno_s);
+#if !defined(KORE_SINGLE_BINARY)
+ if (kore_runtime_count() > 0) {
+ if (argc > 0) {
+ rarg0 = argv[0];
+ argc--;
+ argv++;
}
- if (!S_ISDIR(st.st_mode) && !S_ISREG(st.st_mode))
- fatal("%s: not a directory or file", kore_pymodule);
+ if (rarg0) {
+ if (lstat(rarg0, &st) == -1) {
+ if (errno == ENOENT)
+ rarg0 = NULL;
+ else
+ fatal("stat(%s): %s", rarg0, errno_s);
+ }
+ }
}
#endif
@@ -243,25 +242,17 @@ main(int argc, char *argv[])
#if defined(KORE_USE_PYTHON)
kore_python_init();
-#if !defined(KORE_SINGLE_BINARY)
- if (kore_pymodule) {
- kore_module_load(kore_pymodule, NULL, KORE_MODULE_PYTHON);
- if (S_ISDIR(st.st_mode) && chdir(kore_pymodule) == -1)
- fatal("chdir(%s): %s", kore_pymodule, errno_s);
- } else {
- /* swap back to non-python hooks. */
- parent_config_hook = KORE_CONFIG_HOOK;
- parent_teardown_hook = KORE_TEARDOWN_HOOK;
- }
#endif
+
+#if !defined(KORE_SINGLE_BINARY)
+ if (kore_runtime_count() > 0 && rarg0 != NULL)
+ kore_runtime_resolve(rarg0, &st);
#endif
#if defined(KORE_SINGLE_BINARY)
kore_call_parent_configure(argc, argv);
-#endif
-
-#if defined(KORE_USE_PYTHON) && !defined(KORE_SINGLE_BINARY)
- if (kore_pymodule)
+#else
+ if (kore_runtime_count() > 0 && rarg0 != NULL)
kore_call_parent_configure(argc, argv);
#endif
@@ -314,9 +305,9 @@ kore_default_getopt(int argc, char **argv)
int ch;
#if !defined(KORE_SINGLE_BINARY)
- while ((ch = getopt(argc, argv, "c:fhnqrv")) != -1) {
+ while ((ch = getopt(argc, argv, "c:dfhnqrv")) != -1) {
#else
- while ((ch = getopt(argc, argv, "fhnqrv")) != -1) {
+ while ((ch = getopt(argc, argv, "dfhnqrv")) != -1) {
#endif
switch (ch) {
#if !defined(KORE_SINGLE_BINARY)
@@ -326,8 +317,12 @@ kore_default_getopt(int argc, char **argv)
fatal("strdup");
break;
#endif
+ case 'd':
+ kore_foreground = 0;
+ break;
case 'f':
- kore_foreground = 1;
+ printf("note: -f is the default now, "
+ "use -d to daemonize\n");
break;
case 'h':
usage();
@@ -763,6 +758,17 @@ kore_proctitle(const char *title)
memset(kore_argv[0] + len, 0, proctitle_maxlen - len);
}
+void
+kore_hooks_set(const char *config, const char *teardown, const char *daemonized)
+{
+ parent_config_hook = config;
+ parent_teardown_hook = teardown;
+
+#if defined(KORE_SINGLE_BINARY)
+ parent_daemonized_hook = daemonized;
+#endif
+}
+
static void
kore_proctitle_setup(void)
{
@@ -827,6 +833,8 @@ kore_server_start(int argc, char *argv[])
);
}
+ kore_tls_log_version();
+
if (kore_foreground == 0) {
if (daemon(1, 0) == -1)
fatal("cannot daemon(): %s", errno_s);
@@ -842,12 +850,8 @@ kore_server_start(int argc, char *argv[])
kore_pid = getpid();
kore_write_kore_pid();
-#if !defined(KORE_SINGLE_BINARY) && !defined(KORE_USE_PYTHON)
- kore_call_parent_configure(argc, argv);
-#endif
-
-#if defined(KORE_USE_PYTHON) && !defined(KORE_SINGLE_BINARY)
- if (kore_pymodule == NULL)
+#if !defined(KORE_SINGLE_BINARY)
+ if (kore_runtime_count() == 0 || rarg0 == NULL)
kore_call_parent_configure(argc, argv);
#endif
diff --git a/src/python.c b/src/python.c
@@ -167,6 +167,7 @@ static void python_push_integer(PyObject *, const char *, long);
static void python_push_type(const char *, PyObject *, PyTypeObject *);
static int python_validator_check(PyObject *);
+static int python_runtime_resolve(const char *, const struct stat *);
static int python_runtime_http_request(void *, struct http_request *);
static void python_runtime_http_request_free(void *, struct http_request *);
static void python_runtime_http_body_chunk(void *, struct http_request *,
@@ -200,6 +201,7 @@ struct kore_module_functions kore_python_module = {
struct kore_runtime kore_python_runtime = {
KORE_RUNTIME_PYTHON,
+ .resolve = python_runtime_resolve,
.http_request = python_runtime_http_request,
.http_body_chunk = python_runtime_http_body_chunk,
.http_request_free = python_runtime_http_request_free,
@@ -330,7 +332,7 @@ static PyObject *python_tracer = NULL;
static struct python_coro *coro_running = NULL;
#if !defined(KORE_SINGLE_BINARY)
-const char *kore_pymodule = NULL;
+static const char *kore_pymodule = NULL;
#endif
void
@@ -1279,6 +1281,36 @@ pyhttp_file_dealloc(struct pyhttp_file *pyfile)
}
static int
+python_runtime_resolve(const char *module, const struct stat *st)
+{
+ const char *ext;
+
+ if (!S_ISDIR(st->st_mode) && !S_ISREG(st->st_mode))
+ return (KORE_RESULT_ERROR);
+
+ if (S_ISDIR(st->st_mode)) {
+ kore_module_load(module, NULL, KORE_MODULE_PYTHON);
+ if (chdir(module) == -1)
+ fatal("chdir(%s): %s", module, errno_s);
+ } else {
+ if ((ext = strrchr(module, '.')) == NULL)
+ return (KORE_RESULT_ERROR);
+
+ if (strcasecmp(ext, ".py"))
+ return (KORE_RESULT_ERROR);
+
+ kore_module_load(module, NULL, KORE_MODULE_PYTHON);
+ }
+
+ kore_pymodule = module;
+
+ kore_hooks_set(KORE_PYTHON_CONFIG_HOOK,
+ KORE_PYTHON_TEARDOWN_HOOK, KORE_PYTHON_DAEMONIZED_HOOK);
+
+ return (KORE_RESULT_OK);
+}
+
+static int
python_runtime_http_request(void *addr, struct http_request *req)
{
int ret, idx, cnt;
diff --git a/src/runtime.c b/src/runtime.c
@@ -62,6 +62,38 @@ struct kore_runtime kore_native_runtime = {
.configure = native_runtime_configure
};
+static struct kore_runtime *runtimes[] = {
+#if defined(KORE_USE_PYTHON)
+ &kore_python_runtime,
+#endif
+ NULL
+};
+
+const size_t
+kore_runtime_count(void)
+{
+ return ((sizeof(runtimes) / sizeof(runtimes[0])) - 1);
+}
+
+void
+kore_runtime_resolve(const char *module, const struct stat *st)
+{
+ int i;
+
+ if (runtimes[0] == NULL)
+ return;
+
+ for (i = 0; runtimes[i] != NULL; i++) {
+ if (runtimes[i]->resolve == NULL)
+ continue;
+ if (runtimes[i]->resolve(module, st))
+ break;
+ }
+
+ if (runtimes[i] == NULL)
+ fatal("No runtime available to run '%s'", module);
+}
+
struct kore_runtime_call *
kore_runtime_getcall(const char *symbol)
{
diff --git a/src/tls_none.c b/src/tls_none.c
@@ -41,6 +41,11 @@ kore_keymgr_cleanup(int final)
void
kore_tls_init(void)
{
+}
+
+void
+kore_tls_log_version(void)
+{
kore_log(LOG_NOTICE, "No compiled in TLS backend");
}
diff --git a/src/tls_openssl.c b/src/tls_openssl.c
@@ -111,15 +111,23 @@ kore_tls_init(void)
#if !defined(LIBRESSL_VERSION_NUMBER)
if (!CRYPTO_set_mem_functions(tls_malloc, tls_realloc, tls_free))
fatalx("CRYPTO_set_mem_functions failed");
-#else
- kore_log(LOG_NOTICE, "libressl does not support malloc-wrappers");
#endif
SSL_library_init();
SSL_load_error_strings();
ERR_load_crypto_strings();
+}
+
+void
+kore_tls_log_version(void)
+{
kore_log(LOG_NOTICE, "TLS backend %s", OPENSSL_VERSION_TEXT);
+
+#if defined(LIBRESSL_VERSION_NUMBER)
+ kore_log(LOG_NOTICE, "libressl does not support malloc-wrappers");
+#endif
+
#if !defined(TLS1_3_VERSION)
if (!kore_quiet) {
kore_log(LOG_NOTICE,