mirror of
https://github.com/jorisvink/kore
synced 2025-03-10 13:09:02 -04:00
Allow Kore to load multiple modules at once.
This commit is contained in:
parent
f2aa206f3b
commit
21b148e3a5
@ -171,6 +171,15 @@ struct kore_handler_params {
|
|||||||
#define HANDLER_TYPE_STATIC 1
|
#define HANDLER_TYPE_STATIC 1
|
||||||
#define HANDLER_TYPE_DYNAMIC 2
|
#define HANDLER_TYPE_DYNAMIC 2
|
||||||
|
|
||||||
|
struct kore_module {
|
||||||
|
void *handle;
|
||||||
|
char *path;
|
||||||
|
char *onload;
|
||||||
|
time_t mtime;
|
||||||
|
|
||||||
|
TAILQ_ENTRY(kore_module) list;
|
||||||
|
};
|
||||||
|
|
||||||
struct kore_module_handle {
|
struct kore_module_handle {
|
||||||
char *path;
|
char *path;
|
||||||
char *func;
|
char *func;
|
||||||
@ -263,7 +272,6 @@ extern int kore_debug;
|
|||||||
extern int skip_chroot;
|
extern int skip_chroot;
|
||||||
extern char *chroot_path;
|
extern char *chroot_path;
|
||||||
extern char *runas_user;
|
extern char *runas_user;
|
||||||
extern char *kore_module_onload;
|
|
||||||
extern char *kore_pidfile;
|
extern char *kore_pidfile;
|
||||||
extern char *config_file;
|
extern char *config_file;
|
||||||
extern char *kore_cb_name;
|
extern char *kore_cb_name;
|
||||||
@ -357,11 +365,12 @@ void *kore_mem_find(void *, size_t, void *, u_int32_t);
|
|||||||
|
|
||||||
void kore_domain_init(void);
|
void kore_domain_init(void);
|
||||||
int kore_domain_new(char *);
|
int kore_domain_new(char *);
|
||||||
void kore_module_load(char *);
|
void kore_module_init(void);
|
||||||
void kore_module_reload(void);
|
void kore_module_reload(void);
|
||||||
int kore_module_loaded(void);
|
int kore_module_loaded(void);
|
||||||
void kore_domain_closelogs(void);
|
void kore_domain_closelogs(void);
|
||||||
void *kore_module_getsym(char *);
|
void *kore_module_getsym(char *);
|
||||||
|
void kore_module_load(char *, char *);
|
||||||
void kore_domain_sslstart(struct kore_domain *);
|
void kore_domain_sslstart(struct kore_domain *);
|
||||||
int kore_module_handler_new(char *, char *, char *, int);
|
int kore_module_handler_new(char *, char *, char *, int);
|
||||||
struct kore_domain *kore_domain_lookup(const char *);
|
struct kore_domain *kore_domain_lookup(const char *);
|
||||||
|
22
src/config.c
22
src/config.c
@ -24,7 +24,6 @@
|
|||||||
|
|
||||||
static int configure_bind(char **);
|
static int configure_bind(char **);
|
||||||
static int configure_load(char **);
|
static int configure_load(char **);
|
||||||
static int configure_onload(char **);
|
|
||||||
static int configure_handler(char **);
|
static int configure_handler(char **);
|
||||||
static int configure_domain(char **);
|
static int configure_domain(char **);
|
||||||
static int configure_chroot(char **);
|
static int configure_chroot(char **);
|
||||||
@ -58,7 +57,6 @@ static struct {
|
|||||||
} config_names[] = {
|
} config_names[] = {
|
||||||
{ "bind", configure_bind },
|
{ "bind", configure_bind },
|
||||||
{ "load", configure_load },
|
{ "load", configure_load },
|
||||||
{ "onload", configure_onload },
|
|
||||||
{ "static", configure_handler },
|
{ "static", configure_handler },
|
||||||
{ "dynamic", configure_handler },
|
{ "dynamic", configure_handler },
|
||||||
{ "ssl_cipher", configure_ssl_cipher },
|
{ "ssl_cipher", configure_ssl_cipher },
|
||||||
@ -148,7 +146,8 @@ kore_parse_config(void)
|
|||||||
|
|
||||||
if (!kore_module_loaded())
|
if (!kore_module_loaded())
|
||||||
fatal("no site module was loaded");
|
fatal("no site module was loaded");
|
||||||
|
if (kore_cb_name != NULL && kore_cb == NULL)
|
||||||
|
fatal("no '%s' symbol found for kore_cb", kore_cb_name);
|
||||||
if (LIST_EMPTY(&listeners))
|
if (LIST_EMPTY(&listeners))
|
||||||
fatal("no listeners defined");
|
fatal("no listeners defined");
|
||||||
if (chroot_path == NULL)
|
if (chroot_path == NULL)
|
||||||
@ -177,22 +176,7 @@ configure_load(char **argv)
|
|||||||
if (argv[1] == NULL)
|
if (argv[1] == NULL)
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
|
|
||||||
kore_module_load(argv[1]);
|
kore_module_load(argv[1], argv[2]);
|
||||||
return (KORE_RESULT_OK);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int
|
|
||||||
configure_onload(char **argv)
|
|
||||||
{
|
|
||||||
if (argv[1] == NULL)
|
|
||||||
return (KORE_RESULT_ERROR);
|
|
||||||
|
|
||||||
if (kore_module_onload != NULL) {
|
|
||||||
kore_debug("duplicate onload directive found");
|
|
||||||
return (KORE_RESULT_ERROR);
|
|
||||||
}
|
|
||||||
|
|
||||||
kore_module_onload = kore_strdup(argv[1]);
|
|
||||||
return (KORE_RESULT_OK);
|
return (KORE_RESULT_OK);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,6 +88,7 @@ main(int argc, char *argv[])
|
|||||||
kore_log_init();
|
kore_log_init();
|
||||||
kore_mem_init();
|
kore_mem_init();
|
||||||
kore_domain_init();
|
kore_domain_init();
|
||||||
|
kore_module_init();
|
||||||
kore_validator_init();
|
kore_validator_init();
|
||||||
kore_server_sslstart();
|
kore_server_sslstart();
|
||||||
kore_parse_config();
|
kore_parse_config();
|
||||||
|
137
src/module.c
137
src/module.c
@ -20,94 +20,118 @@
|
|||||||
|
|
||||||
#include "kore.h"
|
#include "kore.h"
|
||||||
|
|
||||||
static void *mod_handle = NULL;
|
static TAILQ_HEAD(, kore_module) modules;
|
||||||
static char *mod_name = NULL;
|
|
||||||
static time_t mod_last_mtime = 0;
|
|
||||||
|
|
||||||
char *kore_cb_name = NULL;
|
char *kore_cb_name = NULL;
|
||||||
char *kore_module_onload = NULL;
|
|
||||||
|
|
||||||
void
|
void
|
||||||
kore_module_load(char *module_name)
|
kore_module_init(void)
|
||||||
|
{
|
||||||
|
TAILQ_INIT(&modules);
|
||||||
|
TAILQ_INIT(&domains);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
kore_module_load(char *path, char *onload)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
void (*onload)(void);
|
struct kore_module *module;
|
||||||
|
void (*cb)(void);
|
||||||
|
|
||||||
kore_debug("kore_module_load(%s)", module_name);
|
kore_debug("kore_module_load(%s, %s)", path, onload);
|
||||||
|
|
||||||
if (mod_handle != NULL)
|
if (stat(path, &st) == -1)
|
||||||
fatal("site module already loaded, skipping %s", module_name);
|
fatal("stat(%s): %s", path, errno_s);
|
||||||
|
|
||||||
if (stat(module_name, &st) == -1)
|
module = kore_malloc(sizeof(struct kore_module));
|
||||||
fatal("stat(%s): %s", module_name, errno_s);
|
module->path = kore_strdup(path);
|
||||||
|
module->mtime = st.st_mtime;
|
||||||
|
module->onload = NULL;
|
||||||
|
|
||||||
mod_last_mtime = st.st_mtime;
|
module->handle = dlopen(module->path, RTLD_NOW | RTLD_GLOBAL);
|
||||||
mod_handle = dlopen(module_name, RTLD_NOW);
|
if (module->handle == NULL)
|
||||||
if (mod_handle == NULL)
|
fatal("%s: %s", path, dlerror());
|
||||||
fatal("%s", dlerror());
|
|
||||||
|
|
||||||
TAILQ_INIT(&domains);
|
if (onload != NULL) {
|
||||||
mod_name = kore_strdup(module_name);
|
module->onload = kore_strdup(onload);
|
||||||
|
cb = dlsym(module->handle, onload);
|
||||||
if (kore_module_onload != NULL) {
|
if (cb == NULL)
|
||||||
onload = dlsym(mod_handle, kore_module_onload);
|
fatal("%s: onload '%s' not present", path, onload);
|
||||||
if (onload == NULL)
|
cb();
|
||||||
fatal("onload '%s' not present", kore_module_onload);
|
|
||||||
onload();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (kore_cb_name != NULL) {
|
if (kore_cb_name != NULL && kore_cb == NULL)
|
||||||
kore_cb = dlsym(mod_handle, kore_cb_name);
|
kore_cb = dlsym(module->handle, kore_cb_name);
|
||||||
if (kore_cb == NULL)
|
|
||||||
fatal("kore_cb '%s' not present", kore_cb_name);
|
TAILQ_INSERT_TAIL(&modules, module, list);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
kore_module_reload(void)
|
kore_module_reload(void)
|
||||||
{
|
{
|
||||||
|
struct stat st;
|
||||||
struct kore_domain *dom;
|
struct kore_domain *dom;
|
||||||
struct kore_module_handle *hdlr;
|
struct kore_module_handle *hdlr;
|
||||||
|
struct kore_module *module;
|
||||||
void (*onload)(void);
|
void (*onload)(void);
|
||||||
|
|
||||||
if (dlclose(mod_handle))
|
kore_cb = NULL;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(module, &modules, list) {
|
||||||
|
if (stat(module->path, &st) == -1) {
|
||||||
|
kore_log(LOG_NOTICE, "stat(%s): %s, skipping reload",
|
||||||
|
module->path, errno_s);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (module->mtime == st.st_mtime)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
module->mtime = st.st_mtime;
|
||||||
|
if (dlclose(module->handle))
|
||||||
fatal("cannot close existing module: %s", dlerror());
|
fatal("cannot close existing module: %s", dlerror());
|
||||||
|
|
||||||
mod_handle = dlopen(mod_name, RTLD_NOW);
|
module->handle = dlopen(module->path, RTLD_NOW | RTLD_GLOBAL);
|
||||||
if (mod_handle == NULL)
|
if (module->handle == NULL)
|
||||||
fatal("kore_module_reload(): %s", dlerror());
|
fatal("kore_module_reload(): %s", dlerror());
|
||||||
|
|
||||||
|
if (module->onload != NULL) {
|
||||||
|
onload = dlsym(module->handle, module->onload);
|
||||||
|
if (onload == NULL) {
|
||||||
|
fatal("%s: onload '%s' not present",
|
||||||
|
module->path, module->onload);
|
||||||
|
}
|
||||||
|
|
||||||
|
onload();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kore_cb_name != NULL && kore_cb == NULL)
|
||||||
|
kore_cb = dlsym(module->handle, kore_cb_name);
|
||||||
|
|
||||||
|
kore_log(LOG_NOTICE, "reloaded '%s' module", module->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (kore_cb_name != NULL && kore_cb == NULL)
|
||||||
|
fatal("no kore_cb %s found in loaded modules", kore_cb_name);
|
||||||
|
|
||||||
TAILQ_FOREACH(dom, &domains, list) {
|
TAILQ_FOREACH(dom, &domains, list) {
|
||||||
TAILQ_FOREACH(hdlr, &(dom->handlers), list) {
|
TAILQ_FOREACH(hdlr, &(dom->handlers), list) {
|
||||||
hdlr->errors = 0;
|
hdlr->addr = kore_module_getsym(hdlr->func);
|
||||||
hdlr->addr = dlsym(mod_handle, hdlr->func);
|
|
||||||
if (hdlr->func == NULL)
|
if (hdlr->func == NULL)
|
||||||
fatal("no function '%s' found", hdlr->func);
|
fatal("no function '%s' found", hdlr->func);
|
||||||
|
hdlr->errors = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kore_validator_reload();
|
kore_validator_reload();
|
||||||
|
|
||||||
if (kore_module_onload != NULL) {
|
|
||||||
onload = dlsym(mod_handle, kore_module_onload);
|
|
||||||
if (onload == NULL)
|
|
||||||
fatal("onload '%s' not present", kore_module_onload);
|
|
||||||
onload();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (kore_cb_name != NULL) {
|
|
||||||
kore_cb = dlsym(mod_handle, kore_cb_name);
|
|
||||||
if (kore_cb == NULL)
|
|
||||||
fatal("kore_cb '%s' not present", kore_cb_name);
|
|
||||||
}
|
|
||||||
|
|
||||||
kore_log(LOG_NOTICE, "reloaded '%s' module", mod_name);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
kore_module_loaded(void)
|
kore_module_loaded(void)
|
||||||
{
|
{
|
||||||
return (mod_handle != NULL ? KORE_RESULT_OK : KORE_RESULT_ERROR);
|
if (TAILQ_EMPTY(&modules))
|
||||||
|
return (0);
|
||||||
|
|
||||||
|
return (1);
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@ -120,7 +144,7 @@ kore_module_handler_new(char *path, char *domain, char *func, int type)
|
|||||||
kore_debug("kore_module_handler_new(%s, %s, %s, %d)", path,
|
kore_debug("kore_module_handler_new(%s, %s, %s, %d)", path,
|
||||||
domain, func, type);
|
domain, func, type);
|
||||||
|
|
||||||
addr = dlsym(mod_handle, func);
|
addr = kore_module_getsym(func);
|
||||||
if (addr == NULL) {
|
if (addr == NULL) {
|
||||||
kore_debug("function '%s' not found", func);
|
kore_debug("function '%s' not found", func);
|
||||||
return (KORE_RESULT_ERROR);
|
return (KORE_RESULT_ERROR);
|
||||||
@ -177,5 +201,14 @@ kore_module_handler_find(char *domain, char *path)
|
|||||||
void *
|
void *
|
||||||
kore_module_getsym(char *symbol)
|
kore_module_getsym(char *symbol)
|
||||||
{
|
{
|
||||||
return (dlsym(mod_handle, symbol));
|
void *ptr;
|
||||||
|
struct kore_module *module;
|
||||||
|
|
||||||
|
TAILQ_FOREACH(module, &modules, list) {
|
||||||
|
ptr = dlsym(module->handle, symbol);
|
||||||
|
if (ptr != NULL)
|
||||||
|
return (ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
return (NULL);
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user