From 529fb48281e041a22a7e4b955e6fb1aa407d6a28 Mon Sep 17 00:00:00 2001 From: Alex 'AdUser' Z Date: Fri, 22 Jan 2021 12:48:33 +1000 Subject: [PATCH] * replace ready() with state() in modules api --- src/backend.c | 19 +++++++++++++++++-- src/backend.h | 5 +++-- src/backends/backend.c | 6 ++++++ src/backends/backend.h | 6 +++--- src/backends/exec.c | 13 +++---------- src/backends/ipset.c | 16 ++++------------ src/backends/redis.c | 23 ++++++++--------------- src/filter.c | 19 +++++++++++++++++-- src/filter.h | 5 +++-- src/filters/filter.c | 5 +++++ src/filters/filter.h | 6 +++--- src/filters/pcre.c | 11 +++-------- src/filters/preg.c | 11 +++-------- src/source.c | 20 +++++++++++++++++--- src/source.h | 10 ++++++---- src/sources/files.c | 19 ++++++++----------- src/sources/portknock.c | 13 ++++--------- src/sources/redis.c | 20 ++++++-------------- src/sources/source.c | 7 +++++++ src/sources/source.h | 6 +++--- t/t_filters.c | 9 +++++---- t/t_ipaddr.c | 1 - 22 files changed, 134 insertions(+), 116 deletions(-) diff --git a/src/backend.c b/src/backend.c index c86d10f..13d4190 100644 --- a/src/backend.c +++ b/src/backend.c @@ -48,7 +48,7 @@ f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config) { goto cleanup; if ((*(void **) (&backend->config) = dlsym(backend->h, "config")) == NULL) goto cleanup; - if ((*(void **) (&backend->ready) = dlsym(backend->h, "ready")) == NULL) + if ((*(void **) (&backend->state) = dlsym(backend->h, "state")) == NULL) goto cleanup; if ((*(void **) (&backend->logcb) = dlsym(backend->h, "logcb")) == NULL) goto cleanup; @@ -72,6 +72,11 @@ f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config) { goto cleanup; } + if ((backend->state(backend->cfg) & MOD_TYPE_BACKEND) == 0) { + f2b_log_msg(log_error, "loaded module is not backend type"); + goto cleanup; + } + backend->logcb(backend->cfg, f2b_log_mod_cb); /* try init */ @@ -84,7 +89,17 @@ f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config) { config->name, param->name, param->value); } - if (backend->ready(backend->cfg)) + if ((backend->flags = backend->state(backend->cfg)) < 0) { + f2b_log_msg(log_error, "can't get module state"); + goto cleanup; + } + + if (backend->flags & MOD_WRONG_API) { + f2b_log_msg(log_error, "module reports wrong api version"); + goto cleanup; + } + + if (backend->flags & MOD_IS_READY) return true; /* still not ready */ diff --git a/src/backend.h b/src/backend.h index 36a609a..4bb9cf1 100644 --- a/src/backend.h +++ b/src/backend.h @@ -16,13 +16,14 @@ typedef struct f2b_backend_t { void *h; /**< dlopen handler */ void *cfg; /**< opaque pointer of module config */ + int flags; /**< module flags (update with state() call) */ /* handlers */ /** dlsym pointer to handler of @a create command */ void *(*create) (const char *id); /** dlsym pointer to handler of @a config command */ bool (*config) (void *cfg, const char *key, const char *value); - /** dlsym pointer to handler of @a ready command */ - bool (*ready) (void *cfg); + /** dlsym pointer to handler of @a state command */ + int (*state) (void *cfg); /** dlsym pointer to handler of @a error command */ void (*logcb) (void *cfg, void (*cb)(log_msgtype_t lvl, const char *msg)); /** dlsym pointer to handler of @a start command */ diff --git a/src/backends/backend.c b/src/backends/backend.c index f5aeb54..e107de8 100644 --- a/src/backends/backend.c +++ b/src/backends/backend.c @@ -84,3 +84,9 @@ logcb(cfg_t *cfg, void (*cb)(enum loglevel lvl, const char *msg)) { cfg->logcb = cb; } + +int +state(cfg_t *cfg) { + assert(cfg != NULL); + return cfg->flags; +} diff --git a/src/backends/backend.h b/src/backends/backend.h index 219a58c..7526427 100644 --- a/src/backends/backend.h +++ b/src/backends/backend.h @@ -29,9 +29,9 @@ * f2b <<= backend [label="logcb(level, char *msg)"]; * f2b << backend [label="false"]; * |||; - * f2b => backend [label="ready(cfg)"]; - * f2b << backend [label="true"]; - * --- [label="backend is ready for start()"]; + * f2b => backend [label="state(cfg)"]; + * f2b << backend [label="int"]; + * --- [label="check for MOD_IS_READY flag"]; * f2b => backend [label="start()"]; * f2b << backend [label="true"]; * --- [label="backend is ready to use"]; diff --git a/src/backends/exec.c b/src/backends/exec.c index 5cbace5..4f5d66a 100644 --- a/src/backends/exec.c +++ b/src/backends/exec.c @@ -32,6 +32,7 @@ struct _config { char name[ID_MAX + 1]; void (*logcb)(enum loglevel lvl, const char *msg); time_t timeout; + int flags; bool shared; cmd_t *start; cmd_t *stop; @@ -166,6 +167,8 @@ create(const char *id) { strlcpy(cfg->name, id, sizeof(cfg->name)); cfg->logcb = &logcb_stub; + cfg->flags |= MOD_IS_READY; + cfg->flags |= MOD_TYPE_BACKEND; return cfg; } @@ -205,16 +208,6 @@ config(cfg_t *cfg, const char *key, const char *value) { return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - - if (cfg->ban && cfg->unban) - return true; - - return false; -} - bool start(cfg_t *cfg) { assert(cfg != NULL); diff --git a/src/backends/ipset.c b/src/backends/ipset.c index 63f2f3b..85b8b48 100644 --- a/src/backends/ipset.c +++ b/src/backends/ipset.c @@ -24,8 +24,9 @@ struct _config { char name[ID_MAX + 1]; void (*logcb)(enum loglevel lvl, const char *msg); - bool shared; struct ipset_session *sess; + int flags; + bool shared; }; #include "backend.c" @@ -78,8 +79,9 @@ create(const char *id) { if ((cfg = calloc(1, sizeof(cfg_t))) == NULL) return NULL; strlcpy(cfg->name, id, sizeof(cfg->name)); - cfg->logcb = &logcb_stub; + cfg->flags |= MOD_IS_READY; + cfg->flags |= MOD_TYPE_BACKEND; return cfg; } @@ -96,16 +98,6 @@ config(cfg_t *cfg, const char *key, const char *value) { return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - - if (cfg->name[0]) - return true; - - return false; -} - bool start(cfg_t *cfg) { assert(cfg != NULL); diff --git a/src/backends/redis.c b/src/backends/redis.c index c03d7d0..e26c89c 100644 --- a/src/backends/redis.c +++ b/src/backends/redis.c @@ -23,18 +23,19 @@ #define MODNAME "redis" struct _config { - char name[ID_MAX + 1]; - char hash[ID_MAX * 2]; void (*logcb)(enum loglevel lvl, const char *msg); - bool shared; + redisContext *conn; time_t timeout; + int flags; + uint16_t port; uint8_t ping_num; /*< current number of ping() call */ uint8_t ping_max; /*< max ping() calls before actually pinginig redis server */ uint8_t database; + bool shared; char password[32]; char host[32]; - uint16_t port; - redisContext *conn; + char name[ID_MAX + 1]; + char hash[ID_MAX * 2]; }; #include "backend.c" @@ -113,6 +114,7 @@ create(const char *id) { strlcat(cfg->hash, id, sizeof(cfg->hash)); cfg->logcb = &logcb_stub; + cfg->flags |= MOD_TYPE_BACKEND; return cfg; } @@ -132,6 +134,7 @@ config(cfg_t *cfg, const char *key, const char *value) { } if (strcmp(key, "host") == 0) { strlcpy(cfg->host, value, sizeof(cfg->host)); + cfg->flags |= MOD_IS_READY; return true; } if (strcmp(key, "port") == 0) { @@ -154,16 +157,6 @@ config(cfg_t *cfg, const char *key, const char *value) { return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - - if (cfg->host) - return true; - - return false; -} - bool start(cfg_t *cfg) { assert(cfg != NULL); diff --git a/src/filter.c b/src/filter.c index 8d2306c..b4b9c3d 100644 --- a/src/filter.c +++ b/src/filter.c @@ -112,7 +112,7 @@ f2b_filter_init(f2b_filter_t *filter, f2b_config_section_t *config) { goto cleanup; if ((*(void **) (&filter->logcb) = dlsym(filter->h, "logcb")) == NULL) goto cleanup; - if ((*(void **) (&filter->ready) = dlsym(filter->h, "ready")) == NULL) + if ((*(void **) (&filter->state) = dlsym(filter->h, "state")) == NULL) goto cleanup; if ((*(void **) (&filter->flush) = dlsym(filter->h, "flush")) == NULL) goto cleanup; @@ -128,6 +128,11 @@ f2b_filter_init(f2b_filter_t *filter, f2b_config_section_t *config) { goto cleanup; } + if ((filter->state(filter->cfg) & MOD_TYPE_FILTER) == 0) { + f2b_log_msg(log_error, "loaded module is not filter type"); + goto cleanup; + } + filter->logcb(filter->cfg, f2b_log_mod_cb); /* try init */ @@ -143,7 +148,17 @@ f2b_filter_init(f2b_filter_t *filter, f2b_config_section_t *config) { if (!f2b_filter_load_file(filter, filter->init)) goto cleanup; - if (filter->ready(filter->cfg)) + if ((filter->flags = filter->state(filter->cfg)) < 0) { + f2b_log_msg(log_error, "can't get module state"); + goto cleanup; + } + + if (filter->flags & MOD_WRONG_API) { + f2b_log_msg(log_error, "module reports wrong api version"); + goto cleanup; + } + + if (filter->flags & MOD_IS_READY) return true; /* still not ready */ diff --git a/src/filter.h b/src/filter.h index 9f5e616..3506477 100644 --- a/src/filter.h +++ b/src/filter.h @@ -16,6 +16,7 @@ typedef struct f2b_filter_t { void *h; /**< dlopen handler */ void *cfg; /**< opaque pointer of module config */ + int flags; /**< module flags (update with state() call) */ /* handlers */ /** dlsym pointer to handler of @a create command */ void *(*create) (const char *id); @@ -25,8 +26,8 @@ typedef struct f2b_filter_t { bool (*append) (void *cfg, const char *pattern); /** dlsym pointer to handler of @a logcb command */ void (*logcb) (void *cfg, void (*cb)(log_msgtype_t lvl, const char *msg)); - /** dlsym pointer to handler of @a ready command */ - bool (*ready) (void *cfg); + /** dlsym pointer to handler of @a state command */ + int (*state) (void *cfg); /** dlsym pointer to handler of @a flush command */ bool (*flush) (void *cfg); /** dlsym pointer to handler of @a stats command */ diff --git a/src/filters/filter.c b/src/filters/filter.c index 2f491cd..3f1aa2f 100644 --- a/src/filters/filter.c +++ b/src/filters/filter.c @@ -55,3 +55,8 @@ stats(cfg_t *cfg, char *buf, size_t bufsize) { return true; } +int +state(cfg_t *cfg) { + assert(cfg != NULL); + return cfg->flags; +} diff --git a/src/filters/filter.h b/src/filters/filter.h index 873fdf6..a3d93f5 100644 --- a/src/filters/filter.h +++ b/src/filters/filter.h @@ -43,9 +43,9 @@ * f2b <<= filter [label="logcb(level, char *msg)"]; * f2b << filter [label="false"]; * ||| [label="more calls of append()"]; - * f2b => filter [label="ready(cfg)"]; - * f2b << filter [label="true"]; - * --- [label="filter is ready to use"]; + * f2b => filter [label="state(cfg)"]; + * f2b << filter [label="int"]; + * --- [label="check for MOD_IS_READY flag"]; * f2b => filter [label="match(cfg, line, buf, sizeof(buf))"]; * f2b << filter [label="false"]; * ... [label="no match"]; diff --git a/src/filters/pcre.c b/src/filters/pcre.c index be0d603..61ec0f0 100644 --- a/src/filters/pcre.c +++ b/src/filters/pcre.c @@ -21,6 +21,7 @@ struct _regexp { struct _config { char id[ID_MAX]; void (*logcb)(enum loglevel lvl, const char *msg); + int flags; bool icase; bool study; bool usejit; @@ -38,6 +39,7 @@ create(const char *id) { strlcpy(cfg->id, id, sizeof(cfg->id)); cfg->logcb = &logcb_stub; + cfg->flags |= MOD_TYPE_FILTER; return cfg; } @@ -123,17 +125,10 @@ append(cfg_t *cfg, const char *pattern) { regex->next = cfg->regexps; cfg->regexps = regex; strlcpy(regex->pattern, pattern, sizeof(regex->pattern)); + cfg->flags |= MOD_IS_READY; return true; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - if (cfg->regexps) - return true; - return false; -} - bool match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) { enum { OVECSIZE = 30 }; diff --git a/src/filters/preg.c b/src/filters/preg.c index 81bb3c1..adcb93c 100644 --- a/src/filters/preg.c +++ b/src/filters/preg.c @@ -22,6 +22,7 @@ struct _regexp { struct _config { char id[ID_MAX]; + int flags; bool icase; void (*logcb)(enum loglevel lvl, const char *msg); rx_t *regexps; @@ -38,6 +39,7 @@ create(const char *id) { strlcpy(cfg->id, id, sizeof(cfg->id)); cfg->logcb = &logcb_stub; + cfg->flags |= MOD_TYPE_FILTER; return cfg; } @@ -88,6 +90,7 @@ append(cfg_t *cfg, const char *pattern) { regex->next = cfg->regexps; cfg->regexps = regex; strlcpy(regex->pattern, pattern, sizeof(regex->pattern)); + cfg->flags |= MOD_IS_READY; return true; } else { char buf[256] = ""; @@ -99,14 +102,6 @@ append(cfg_t *cfg, const char *pattern) { return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - if (cfg->regexps) - return true; - return false; -} - bool match(cfg_t *cfg, const char *line, char *buf, size_t buf_size) { size_t match_len = 0; diff --git a/src/source.c b/src/source.c index ea52284..e0402da 100644 --- a/src/source.c +++ b/src/source.c @@ -48,7 +48,7 @@ f2b_source_init(f2b_source_t *source, f2b_config_section_t *config) { goto cleanup; if ((*(void **) (&source->config) = dlsym(source->h, "config")) == NULL) goto cleanup; - if ((*(void **) (&source->ready) = dlsym(source->h, "ready")) == NULL) + if ((*(void **) (&source->state) = dlsym(source->h, "state")) == NULL) goto cleanup; if ((*(void **) (&source->logcb) = dlsym(source->h, "logcb")) == NULL) goto cleanup; @@ -68,6 +68,11 @@ f2b_source_init(f2b_source_t *source, f2b_config_section_t *config) { goto cleanup; } + if ((source->state(source->cfg) & MOD_TYPE_SOURCE) == 0) { + f2b_log_msg(log_error, "loaded module is not source type"); + goto cleanup; + } + source->logcb(source->cfg, f2b_log_mod_cb); /* try init */ @@ -80,7 +85,17 @@ f2b_source_init(f2b_source_t *source, f2b_config_section_t *config) { config->name, param->name, param->value); } - if (source->ready(source->cfg)) + if ((source->flags = source->state(source->cfg)) < 0) { + f2b_log_msg(log_error, "can't get module state"); + goto cleanup; + } + + if (source->flags & MOD_WRONG_API) { + f2b_log_msg(log_error, "module reports wrong api version"); + goto cleanup; + } + + if (source->flags & MOD_IS_READY) return true; /* still not ready */ @@ -122,7 +137,6 @@ f2b_source_ ## CMD(f2b_source_t *source) { \ SOURCE_CMD_ARG0(start, bool) SOURCE_CMD_ARG0(stop, bool) -SOURCE_CMD_ARG0(ready, bool) void f2b_source_cmd_stats(char *buf, size_t bufsize, f2b_source_t *source) { diff --git a/src/source.h b/src/source.h index fd53d62..a084dfa 100644 --- a/src/source.h +++ b/src/source.h @@ -14,17 +14,16 @@ /** source module definition */ typedef struct f2b_source_t { - char name[CONFIG_KEY_MAX]; /**< source name from config (eg [source:$NAME] section) */ - char init[CONFIG_VAL_MAX]; /**< source init string (eg `source = NAME:$INIT_STRING` line from jail section) */ void *h; /**< dlopen handler */ void *cfg; /**< opaque pointer of module config */ + int flags; /**< module flags (update with state() call) */ /* handlers */ /** dlsym pointer to handler of @a create command */ void *(*create) (const char *init); /** dlsym pointer to handler of @a config command */ bool (*config) (void *cfg, const char *key, const char *value); - /** dlsym pointer to handler of @a ready command */ - bool (*ready) (void *cfg); + /** dlsym pointer to handler of @a state command */ + int (*state) (void *cfg); /** dlsym pointer to handler of @a logcb command */ void (*logcb) (void *cfg, void (*cb)(log_msgtype_t l, const char *msg)); /** dlsym pointer to handler of @a start command */ @@ -37,6 +36,9 @@ typedef struct f2b_source_t { bool (*stop) (void *cfg); /** dlsym pointer to handler of @a destroy command */ void (*destroy) (void *cfg); + /* config variables */ + char name[CONFIG_KEY_MAX]; /**< source name from config (eg [source:$NAME] section) */ + char init[CONFIG_VAL_MAX]; /**< source init string (eg `source = NAME:$INIT_STRING` line from jail section) */ } f2b_source_t; /** diff --git a/src/sources/files.c b/src/sources/files.c index 3e0b3ad..882f324 100644 --- a/src/sources/files.c +++ b/src/sources/files.c @@ -23,10 +23,11 @@ typedef struct f2b_file_t { } f2b_file_t; struct _config { - char path[256]; void (*logcb)(enum loglevel lvl, const char *msg); f2b_file_t *files; f2b_file_t *current; + int flags; + char path[256]; }; #include "source.c" @@ -122,11 +123,15 @@ file_getline(f2b_file_t *file, char *buf, size_t bufsize) { cfg_t * create(const char *init) { cfg_t *cfg = NULL; - assert(init != NULL); if ((cfg = calloc(1, sizeof(cfg_t))) == NULL) return NULL; - strlcpy(cfg->path, init, sizeof(cfg->path)); cfg->logcb = &logcb_stub; + cfg->flags |= MOD_TYPE_SOURCE; + cfg->flags |= MOD_NEED_FILTER; + if (init != NULL && strlen(init) > 0) { + strlcpy(cfg->path, init, sizeof(cfg->path)); + cfg->flags |= MOD_IS_READY; + } return cfg; } @@ -144,14 +149,6 @@ config(cfg_t *cfg, const char *key, const char *value) { return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - if (cfg->path[0] == '\0') - return false; - return true; -} - bool start(cfg_t *cfg) { f2b_file_t *file = NULL; diff --git a/src/sources/portknock.c b/src/sources/portknock.c index ec39445..adcf778 100644 --- a/src/sources/portknock.c +++ b/src/sources/portknock.c @@ -25,10 +25,11 @@ typedef struct f2b_port_t { } f2b_port_t; struct _config { - char name[32]; void (*logcb)(enum loglevel lvl, const char *msg); f2b_port_t *ports; f2b_port_t *current; + int flags; + char name[32]; }; #include "source.c" @@ -76,6 +77,7 @@ create(const char *init) { return NULL; strlcpy(cfg->name, init, sizeof(cfg->name)); cfg->logcb = &logcb_stub; + cfg->flags |= MOD_TYPE_SOURCE; return cfg; } @@ -98,20 +100,13 @@ config(cfg_t *cfg, const char *key, const char *value) { } port->next = cfg->ports; cfg->ports = port; + cfg->flags |= MOD_IS_READY; return true; } return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - if (cfg->ports) - return true; - return false; -} - bool start(cfg_t *cfg) { struct addrinfo hints; diff --git a/src/sources/redis.c b/src/sources/redis.c index 5ed8cbc..f1608b4 100644 --- a/src/sources/redis.c +++ b/src/sources/redis.c @@ -24,6 +24,7 @@ struct _config { char host[32]; uint16_t port; uint32_t received; + int flags; redisContext *conn; }; @@ -107,16 +108,17 @@ cfg_t * create(const char *init) { cfg_t *cfg = NULL; - assert(init != NULL); - if ((cfg = calloc(1, sizeof(cfg_t))) == NULL) return NULL; - strlcpy(cfg->name, init, sizeof(cfg->name)); strlcpy(cfg->hash, "f2b-banned-", sizeof(cfg->hash)); strlcat(cfg->hash, init, sizeof(cfg->hash)); cfg->logcb = &logcb_stub; - + cfg->flags |= MOD_TYPE_SOURCE; + if (init && strlen(init) > 0) { + strlcpy(cfg->name, init, sizeof(cfg->name)); + cfg->flags |= MOD_IS_READY; + } return cfg; } @@ -150,16 +152,6 @@ config(cfg_t *cfg, const char *key, const char *value) { return false; } -bool -ready(cfg_t *cfg) { - assert(cfg != NULL); - - if (cfg->host) - return true; - - return true; -} - bool start(cfg_t *cfg) { assert(cfg != NULL); diff --git a/src/sources/source.c b/src/sources/source.c index dfe260f..cf74b21 100644 --- a/src/sources/source.c +++ b/src/sources/source.c @@ -36,3 +36,10 @@ logcb(cfg_t *cfg, void (*cb)(enum loglevel lvl, const char *msg)) { cfg->logcb = cb; } + +int +state(cfg_t *cfg) { + assert(cfg != NULL); + + return cfg->flags; +} diff --git a/src/sources/source.h b/src/sources/source.h index d41bba3..fccc70d 100644 --- a/src/sources/source.h +++ b/src/sources/source.h @@ -37,9 +37,9 @@ * f2b <<= source [label="logcb(level, char *msg)"]; * f2b << source [label="false"]; * |||; - * f2b => source [label="ready(cfg)"]; - * f2b << source [label="true"]; - * --- [label="source is ready for start()"]; + * f2b => source [label="state(cfg)"]; + * f2b << source [label="int"]; + * --- [label="check for MOD_IS_READY flag"]; * f2b => source [label="start()"]; * f2b << source [label="true"]; * --- [label="source is ready to use"]; diff --git a/t/t_filters.c b/t/t_filters.c index 777be01..d9df4db 100644 --- a/t/t_filters.c +++ b/t/t_filters.c @@ -8,6 +8,7 @@ int main() { cfg_t *filter = NULL; char matchbuf[IPADDR_MAX] = ""; bool result = false; + int flags; UNUSED(result); @@ -23,8 +24,8 @@ int main() { result = config(filter, "icase", "no"); assert(result == true); - result = ready(filter); - assert(result == false); + flags = state(filter); + assert((flags & MOD_IS_READY) == 0); result = append(filter, "host without marker"); assert(result == false); @@ -32,8 +33,8 @@ int main() { result = append(filter, "host with marker "); assert(result == true); - result = ready(filter); - assert(result == true); + flags = state(filter); + assert(flags & MOD_IS_READY); result = match(filter, "host", matchbuf, sizeof(matchbuf)); assert(result == false); diff --git a/t/t_ipaddr.c b/t/t_ipaddr.c index f17a2a3..e3367d3 100644 --- a/t/t_ipaddr.c +++ b/t/t_ipaddr.c @@ -24,7 +24,6 @@ int main() { assert(addr->type == AF_INET); assert(addr->next == NULL); assert(strncmp(addr->text, "127.0.0.1", sizeof(addr->text)) == 0); - assert(addr->matches.list != NULL); assert(addr->matches.count == 0); list = f2b_addrlist_append(list, addr);