Browse Source

* replace ready() with state() in modules api

master
Alex 'AdUser' Z 3 years ago
parent
commit
529fb48281
  1. 19
      src/backend.c
  2. 5
      src/backend.h
  3. 6
      src/backends/backend.c
  4. 6
      src/backends/backend.h
  5. 13
      src/backends/exec.c
  6. 16
      src/backends/ipset.c
  7. 23
      src/backends/redis.c
  8. 19
      src/filter.c
  9. 5
      src/filter.h
  10. 5
      src/filters/filter.c
  11. 6
      src/filters/filter.h
  12. 11
      src/filters/pcre.c
  13. 11
      src/filters/preg.c
  14. 20
      src/source.c
  15. 10
      src/source.h
  16. 19
      src/sources/files.c
  17. 13
      src/sources/portknock.c
  18. 20
      src/sources/redis.c
  19. 7
      src/sources/source.c
  20. 6
      src/sources/source.h
  21. 9
      t/t_filters.c
  22. 1
      t/t_ipaddr.c

19
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 */

5
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 */

6
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;
}

6
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"];

13
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);

16
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);

23
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);

19
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 */

5
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 */

5
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;
}

6
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"];

11
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 };

11
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;

20
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) {

10
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;
/**

19
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;

13
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;

20
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);

7
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;
}

6
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"];

9
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 <HOST>");
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);

1
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);

Loading…
Cancel
Save