Browse Source

* update f2b_jail_t struct

master
Alex 'AdUser' Z 3 years ago
parent
commit
ce7defbb13
  1. 9
      src/backend-test.c
  2. 27
      src/backend.c
  3. 21
      src/backend.h
  4. 11
      src/filter-test.c
  5. 33
      src/filter.c
  6. 20
      src/filter.h
  7. 113
      src/jail.c
  8. 31
      src/jail.h
  9. 9
      src/source-test.c
  10. 27
      src/source.c
  11. 17
      src/source.h

9
src/backend-test.c

@ -84,8 +84,13 @@ int main(int argc, char *argv[]) {
section = config.backends;
}
if ((backend = f2b_backend_create(section, argv[2])) == NULL) {
f2b_log_msg(log_fatal, "can't create backend '%s' with id '%s'", section->name, argv[2]);
if ((backend = f2b_backend_create(section->name, argv[2])) == NULL) {
f2b_log_msg(log_fatal, "can't create backend '%s'", section->name);
return EXIT_FAILURE;
}
if (!f2b_backend_init(backend, section)) {
f2b_log_msg(log_fatal, "can't init backend '%s'", backend->name);
return EXIT_FAILURE;
}

27
src/backend.c

@ -10,9 +10,21 @@
#define BACKEND_LIBRARY_PARAM "load"
f2b_backend_t *
f2b_backend_create(f2b_config_section_t *config, const char *id) {
f2b_config_param_t *param = NULL;
f2b_backend_create(const char *name, const char *init) {
f2b_backend_t *backend = NULL;
if ((backend = calloc(1, sizeof(f2b_backend_t))) == NULL)
return NULL;
strlcpy(backend->name, name, sizeof(backend->name));
strlcpy(backend->init, init, sizeof(backend->init));
return backend;
}
bool
f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config) {
f2b_config_param_t *param = NULL;
int flags = RTLD_NOW | RTLD_LOCAL;
const char *dlerr = NULL;
@ -22,12 +34,9 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) {
param = f2b_config_param_find(config->param, BACKEND_LIBRARY_PARAM);
if (!param) {
f2b_log_msg(log_error, "can't find '%s' param in backend config", BACKEND_LIBRARY_PARAM);
return NULL;
return false;
}
if ((backend = calloc(1, sizeof(f2b_backend_t))) == NULL)
return NULL;
if ((backend->h = dlopen(param->value, flags)) == NULL)
goto cleanup;
if ((*(void **) (&backend->create) = dlsym(backend->h, "create")) == NULL)
@ -53,7 +62,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) {
if ((*(void **) (&backend->destroy) = dlsym(backend->h, "destroy")) == NULL)
goto cleanup;
if ((backend->cfg = backend->create(id)) == NULL) {
if ((backend->cfg = backend->create(backend->init)) == NULL) {
f2b_log_msg(log_error, "backend create config failed");
goto cleanup;
}
@ -71,7 +80,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) {
}
if (backend->ready(backend->cfg))
return backend;
return true;
/* still not ready */
f2b_log_msg(log_error, "backend '%s' not fully configured", config->name);
@ -86,7 +95,7 @@ f2b_backend_create(f2b_config_section_t *config, const char *id) {
dlclose(backend->h);
}
free(backend);
return NULL;
return false;
}
void

21
src/backend.h

@ -42,15 +42,26 @@ typedef struct f2b_backend_t {
bool (*unban) (void *cfg, const char *ip);
/** dlsym pointer to handler of @a destroy command */
void (*destroy) (void *cfg);
/* config variables */
char name[CONFIG_KEY_MAX]; /**< backend name from config (eg [backend:$NAME] section) */
char init[CONFIG_VAL_MAX]; /**< backend init string (eg `backend = NAME:$INIT_STRING` line from jail section) */
} f2b_backend_t;
/**
* @brief Create module from config
* @param config Pointer to section of config
* @param id Backend id
* @returns Pointer to module metadata of NULL on error
* @brief Allocate new backend struct and fill name/init fields
* @param name Module name
* @param init Module init string
* @returns Pointer to allocated module struct or NULL on error
*/
f2b_backend_t * f2b_backend_create (f2b_config_section_t *config, const char *id);
f2b_backend_t * f2b_backend_create (const char *name, const char *init);
/**
* @brief Initialize and configure backend
* @param config Pointer to config section with module description
* @return true on success, false on error
*/
bool f2b_backend_init(f2b_backend_t *backend, f2b_config_section_t *config);
/**
* @brief Free module metadata
* @param b Pointer to module struct

11
src/filter-test.c

@ -41,14 +41,19 @@ int main(int argc, char *argv[]) {
section = config.filters;
}
if ((filter = f2b_filter_create(section, argv[2])) == false) {
f2b_log_msg(log_fatal, "can't create filter '%s' with file '%s'", section->name, argv[2]);
if ((filter = f2b_filter_create(section->name, argv[2])) == false) {
f2b_log_msg(log_fatal, "can't create filter '%s'", section->name);
return EXIT_FAILURE;
}
if (!f2b_filter_init(filter, section)) {
f2b_log_msg(log_fatal, "can't configure filter '%s' with file '%s'", filter->name, argv[2]);
return EXIT_FAILURE;
}
if (argc > 3) {
if ((file = fopen(argv[3], "r")) == NULL) {
f2b_log_msg(log_fatal, "can't open regexp file '%s': %s", argv[2], strerror(errno));
f2b_log_msg(log_fatal, "can't open log file '%s': %s", argv[3], strerror(errno));
return EXIT_FAILURE;
}
} else {

33
src/filter.c

@ -70,25 +70,33 @@ f2b_filter_load_file(f2b_filter_t *filter, const char *path) {
}
f2b_filter_t *
f2b_filter_create(f2b_config_section_t *config, const char *file) {
f2b_config_param_t *param = NULL;
f2b_filter_create(const char *name, const char *init) {
f2b_filter_t *filter = NULL;
if ((filter = calloc(1, sizeof(f2b_filter_t))) == NULL)
return NULL;
strlcpy(filter->name, name, sizeof(filter->name));
strlcpy(filter->init, init, sizeof(filter->init));
return filter;
}
bool
f2b_filter_init(f2b_filter_t *filter, f2b_config_section_t *config) {
f2b_config_param_t *param = NULL;
int flags = RTLD_NOW | RTLD_LOCAL;
const char *dlerr = NULL;
assert(file != NULL);
assert(config != NULL);
assert(config->type == t_filter);
param = f2b_config_param_find(config->param, FILTER_LIBRARY_PARAM);
if (!param) {
f2b_log_msg(log_error, "can't find '%s' param in filter config", FILTER_LIBRARY_PARAM);
return NULL;
return false;
}
if ((filter = calloc(1, sizeof(f2b_filter_t))) == NULL)
return NULL;
if ((filter->h = dlopen(param->value, flags)) == NULL)
goto cleanup;
if ((*(void **) (&filter->create) = dlsym(filter->h, "create")) == NULL)
@ -110,7 +118,6 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) {
if ((*(void **) (&filter->destroy) = dlsym(filter->h, "destroy")) == NULL)
goto cleanup;
/* TODO: do we need id? */
if ((filter->cfg = filter->create("")) == NULL) {
f2b_log_msg(log_error, "filter create config failed");
goto cleanup;
@ -128,13 +135,11 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) {
config->name, param->name, param->value);
}
strlcpy(filter->file, file, sizeof(filter->file));
if (!f2b_filter_load_file(filter, file))
if (!f2b_filter_load_file(filter, filter->init))
goto cleanup;
if (filter->ready(filter->cfg))
return filter;
return true;
/* still not ready */
f2b_log_msg(log_error, "filter '%s' not fully configured", config->name);
@ -149,7 +154,7 @@ f2b_filter_create(f2b_config_section_t *config, const char *file) {
dlclose(filter->h);
}
free(filter);
return NULL;
return false;
}
void
@ -191,7 +196,7 @@ f2b_filter_cmd_reload(char *buf, size_t bufsize, f2b_filter_t *filter) {
assert(filter != NULL);
filter->flush(filter->cfg);
if (f2b_filter_load_file(filter, filter->file)) {
if (f2b_filter_load_file(filter, filter->init)) {
snprintf(buf, bufsize, "can't reload filter");
}
}

20
src/filter.h

@ -19,7 +19,6 @@
typedef struct f2b_filter_t {
void *h; /**< dlopen handler */
void *cfg; /**< opaque pointer of module config */
char file[PATH_MAX]; /**< path to file with patterns */
/* handlers */
/** dlsym pointer to handler of @a create command */
void *(*create) (const char *id);
@ -39,15 +38,26 @@ typedef struct f2b_filter_t {
bool (*match) (void *cfg, const char *line, char *buf, size_t buf_size);
/** dlsym pointer to handler of @a destroy command */
void (*destroy) (void *cfg);
/* config variables */
char name[CONFIG_KEY_MAX]; /**< filter name from config (eg [filter:$NAME] section) */
char init[CONFIG_VAL_MAX]; /**< filter init string (eg `filter = NAME:$INIT_STRING` line from jail section) */
} f2b_filter_t;
/**
* @brief Create module from config
* @param config Pointer to config section with module description
* @param id Filter id
* @brief Allocate new filter struct and fill name/init fields
* @param name Module name
* @param init Module init string
* @returns Pointer to allocated module struct or NULL on error
*/
f2b_filter_t * f2b_filter_create (f2b_config_section_t *config, const char *id);
f2b_filter_t * f2b_filter_create (const char *name, const char *init);
/**
* @brief Initialize and configure filter
* @param config Pointer to config section with module description
* @return true on success, false on error
*/
bool f2b_filter_init (f2b_filter_t *filter, f2b_config_section_t *config);
/**
* @brief Free module metadata
* @param f Pointer to module struct

113
src/jail.c

@ -89,12 +89,12 @@ f2b_jail_set_param(f2b_jail_t *jail, const char *param, const char *value) {
jail->maxretry = DEFAULT_MAXRETRY;
return true;
}
if (strcmp(param, "incr_bantime") == 0) {
jail->incr_bantime = atof(value);
if (strcmp(param, "bantime_extend") == 0) {
jail->bantime_extend = atof(value);
return true;
}
if (strcmp(param, "incr_findtime") == 0) {
jail->incr_findtime = atof(value);
if (strcmp(param, "findtime_extend") == 0) {
jail->findtime_extend = atof(value);
return true;
}
return false;
@ -102,6 +102,8 @@ f2b_jail_set_param(f2b_jail_t *jail, const char *param, const char *value) {
void
f2b_jail_apply_config(f2b_jail_t *jail, f2b_config_section_t *section) {
char name[CONFIG_KEY_MAX];
char init[CONFIG_KEY_MAX];
f2b_config_param_t *param = NULL;
assert(jail != NULL);
@ -110,15 +112,18 @@ f2b_jail_apply_config(f2b_jail_t *jail, f2b_config_section_t *section) {
for (param = section->param; param != NULL; param = param->next) {
if (strcmp(param->name, "source") == 0) {
f2b_jail_parse_compound_value(param->value, jail->source_name, jail->source_init);
f2b_jail_parse_compound_value(param->value, name, init);
jail->source = f2b_source_create(name, init);
continue;
}
if (strcmp(param->name, "filter") == 0) {
f2b_jail_parse_compound_value(param->value, jail->filter_name, jail->filter_init);
f2b_jail_parse_compound_value(param->value, name, init);
jail->filter = f2b_filter_create(name, init);
continue;
}
if (strcmp(param->name, "backend") == 0) {
f2b_jail_parse_compound_value(param->value, jail->backend_name, jail->backend_init);
f2b_jail_parse_compound_value(param->value, name, init);
jail->backend = f2b_backend_create(name, init);
continue;
}
if (f2b_jail_set_param(jail, param->name, param->value))
@ -149,14 +154,14 @@ f2b_jail_ban(f2b_jail_t *jail, f2b_ipaddr_t *addr) {
addr->banned = true;
addr->banned_at = addr->lastseen;
if (jail->incr_bantime > 0) {
bantime = jail->bantime + (int) (addr->bancount * (jail->bantime * jail->incr_bantime));
if (jail->bantime_extend > 0) {
bantime = jail->bantime + (int) (addr->bancount * (jail->bantime * jail->bantime_extend));
} else {
bantime = jail->bantime;
}
addr->bancount++;
addr->release_at = addr->banned_at + bantime;
jail->bancount++;
jail->stats.bans++;
if (f2b_backend_check(jail->backend, addr->text)) {
f2b_log_msg(log_warn, "jail '%s': ip %s was already banned", jail->name, addr->text);
@ -246,7 +251,7 @@ f2b_jail_process(f2b_jail_t *jail) {
if (!f2b_filter_match(jail->filter, line, matchbuf, sizeof(matchbuf)))
continue;
/* some regex matches the line */
jail->matchcount++;
jail->stats.matches++;
addr = f2b_addrlist_lookup(jail->ipaddrs, matchbuf);
if (!addr) {
addr = f2b_ipaddr_create(matchbuf);
@ -260,10 +265,10 @@ f2b_jail_process(f2b_jail_t *jail) {
continue;
}
match = f2b_match_create(now);
if (jail->incr_findtime > 0 && addr->matches.count > jail->maxretry) {
if (jail->findtime_extend > 0 && addr->matches.count > jail->maxretry) {
findtime = now - jail->findtime;
findtime -= (int) ((addr->matches.count - jail->maxretry) *
(jail->findtime * jail->incr_findtime));
(jail->findtime * jail->findtime_extend));
} else {
findtime = now - jail->findtime;
}
@ -324,61 +329,55 @@ f2b_jail_process(f2b_jail_t *jail) {
bool
f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) {
f2b_config_section_t * s_section = NULL;
f2b_config_section_t * b_section = NULL;
f2b_config_section_t * f_section = NULL;
f2b_config_section_t *section = NULL;
assert(jail != NULL);
assert(config != NULL);
/* source */
if (jail->source_name[0] == '\0') {
f2b_log_msg(log_error, "jail '%s': missing 'source' parameter", jail->name);
return false;
}
if ((s_section = f2b_config_section_find(config->sources, jail->source_name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no source with name '%s'", jail->name, jail->source_name);
return false;
if (!jail->source) {
f2b_log_msg(log_error, "jail '%s': missing 'source' option", jail->name);
goto cleanup;
}
/* filter */
if (jail->filter_name[0] == '\0') {
f2b_log_msg(log_error, "jail '%s': missing 'filter' parameter", jail->name);
return false;
if (!jail->filter) {
f2b_log_msg(log_error, "jail '%s': missing 'filter' option", jail->name);
goto cleanup;
}
if ((f_section = f2b_config_section_find(config->filters, jail->filter_name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no filter with name '%s'", jail->name, jail->filter_name);
return false;
if (!jail->backend) {
f2b_log_msg(log_error, "jail '%s': missing 'backend' option", jail->name);
goto cleanup;
}
/* backend */
if (jail->backend_name[0] == '\0') {
f2b_log_msg(log_error, "jail '%s': missing 'backend' parameter", jail->name);
return false;
if ((section = f2b_config_section_find(config->sources, jail->source->name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no source with name '%s'", jail->name, jail->source->name);
goto cleanup;
}
if ((b_section = f2b_config_section_find(config->backends, jail->backend_name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no backend with name '%s'", jail->name, jail->backend_name);
return false;
if (!f2b_source_init(jail->source, section)) {
f2b_log_msg(log_error, "jail '%s': can't init source '%s' with %s", jail->name, jail->source->name, jail->source->init);
goto cleanup;
}
/* init all */
if ((jail->source = f2b_source_create(s_section, jail->source_init)) == NULL) {
f2b_log_msg(log_error, "jail '%s': can't init source '%s' with %s", jail->name, jail->source_name, jail->source_init);
if ((section = f2b_config_section_find(config->filters, jail->filter->name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no filter with name '%s'", jail->name, jail->filter->name);
goto cleanup;
}
if (!f2b_source_start(jail->source)) {
f2b_log_msg(log_warn, "jail '%s': source action 'start' failed", jail->name);
if (!f2b_filter_init(jail->filter, section)) {
f2b_log_msg(log_error, "jail '%s': no regexps loaded from '%s'", jail->name, jail->filter->init);
goto cleanup;
}
if ((jail->filter = f2b_filter_create(f_section, jail->filter_init)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no regexps loaded from '%s'", jail->name, jail->filter_init);
if ((section = f2b_config_section_find(config->backends, jail->backend->name)) == NULL) {
f2b_log_msg(log_error, "jail '%s': no backend with name '%s'", jail->name, jail->backend->name);
goto cleanup;
}
if ((jail->backend = f2b_backend_create(b_section, jail->backend_init)) == NULL) {
if (!f2b_backend_init(jail->backend, section)) {
f2b_log_msg(log_error, "jail '%s': can't init backend '%s' with %s",
jail->name, jail->backend_name, jail->backend_init);
jail->name, jail->backend->name, jail->backend->init);
goto cleanup;
}
/* start all */
if (!f2b_source_start(jail->source)) {
f2b_log_msg(log_warn, "jail '%s': source action 'start' failed", jail->name);
goto cleanup;
}
if (!f2b_backend_start(jail->backend)) {
@ -391,12 +390,18 @@ f2b_jail_init(f2b_jail_t *jail, f2b_config_t *config) {
return true;
cleanup:
if (jail->source)
if (jail->source) {
f2b_source_destroy(jail->source);
if (jail->filter)
jail->source = NULL;
}
if (jail->filter) {
f2b_filter_destroy(jail->filter);
if (jail->backend)
jail->filter = NULL;
}
if (jail->backend) {
f2b_backend_destroy(jail->backend);
jail->backend = NULL;
}
return false;
}
@ -500,8 +505,8 @@ f2b_jail_cmd_status(char *res, size_t ressize, f2b_jail_t *jail) {
jail->flags & JAIL_HAS_STATE ? "yes" : "no",
jail->maxretry,
jail->bantime, jail->findtime, jail->expiretime,
jail->incr_bantime, jail->incr_findtime,
jail->bancount, jail->matchcount);
jail->bantime_extend, jail->findtime_extend,
jail->stats.bans, jail->stats.matches);
}
void

31
src/jail.h

@ -28,26 +28,27 @@
/** jail metadata struct */
typedef struct f2b_jail_t {
struct f2b_jail_t *next; /**< pointer to next jail */
char name[CONFIG_KEY_MAX]; /**< name of the jail */
int flags; /**< jail flags, see above */
time_t bantime; /**< option: ban host for this time if maxretry exceeded */
time_t findtime; /**< option: time period for counting matches */
time_t expiretime; /**< option: forget about host after this time with on activity (not including bantime) */
size_t maxretry; /**< option: maximum count of matches before ban */
size_t bancount; /**< stats: total number of bans for this jail */
size_t matchcount; /**< stats: total number of matches for this jail */
float incr_bantime; /**< option: multiplier for bantime */
float incr_findtime; /**< option: multiplier for finetime */
char name[CONFIG_KEY_MAX]; /**< name of the jail */
char backend_name[CONFIG_KEY_MAX]; /**< backend name from config (eg [backend:$NAME] section) */
char backend_init[CONFIG_VAL_MAX]; /**< backend init string (eg `backend = NAME:$INIT_STRING` line from jail section) */
char filter_name[CONFIG_KEY_MAX]; /**< filter name from config (eg [filter:$NAME] section) */
char filter_init[CONFIG_VAL_MAX]; /**< filter init string (eg `filter = NAME:$INIT_STRING` line from jail section) */
char source_name[CONFIG_KEY_MAX]; /**< source name from config (eg [source:$NAME] section) */
char source_init[CONFIG_VAL_MAX]; /**< source init string (eg `source = NAME:$INIT_STRING` line from jail section) */
f2b_statefile_t *sfile; /**< pointer to state file description */
/* duration of misc time periods */
time_t findtime; /**< option: length of time period for estimating recent host activity (in seconds) */
time_t bantime; /**< option: host ban time on excess activity (seconds) */
time_t expiretime; /**< option: forget about host after this time with no activity (seconds, for banned hosts - after it's release, for not banned - after latest match) */
/** time period length modifiers for already banned hosts */
float findtime_extend; /**< findtime modifier for already banned hosts in past (float) */
float bantime_extend; /**< bantime modifier for already banned hosts in past (float) */
float expiretime_extend; /**< expiretime modifier for already banned hosts in past (float) */
/* jail stats */
struct {
unsigned int hosts; /**< number of tracked hosts */
unsigned int bans; /**< number of ban events */
unsigned int matches; /**< number of match events */
} stats;
f2b_source_t *source; /**< pointer to source */
f2b_filter_t *filter; /**< pointer to filter */
f2b_backend_t *backend; /**< pointer to backend */
f2b_statefile_t *sfile; /**< pointer to state file description */
f2b_ipaddr_t *ipaddrs; /**< list of known ip addresses */
} f2b_jail_t;

9
src/source-test.c

@ -37,8 +37,13 @@ int main(int argc, char *argv[]) {
section = config.sources;
}
if ((source = f2b_source_create(section, argv[2])) == NULL) {
f2b_log_msg(log_fatal, "can't create source '%s' with init '%s'", section->name, argv[2]);
if ((source = f2b_source_create(section->name, argv[2])) == NULL) {
f2b_log_msg(log_fatal, "can't create source '%s'", section->name);
return EXIT_FAILURE;
}
if (!f2b_source_init(source, section)) {
f2b_log_msg(log_fatal, "can't init source '%s'", source->name);
return EXIT_FAILURE;
}

27
src/source.c

@ -10,9 +10,21 @@
#define SOURCE_LIBRARY_PARAM "load"
f2b_source_t *
f2b_source_create(f2b_config_section_t *config, const char *init) {
f2b_config_param_t *param = NULL;
f2b_source_create(const char *name, const char *init) {
f2b_source_t *source = NULL;
if ((source = calloc(1, sizeof(f2b_source_t))) == NULL)
return NULL;
strlcpy(source->name, name, sizeof(source->name));
strlcpy(source->init, init, sizeof(source->init));
return source;
}
bool
f2b_source_init(f2b_source_t *source, f2b_config_section_t *config) {
f2b_config_param_t *param = NULL;
int flags = RTLD_NOW | RTLD_LOCAL;
const char *dlerr = NULL;
@ -22,12 +34,9 @@ f2b_source_create(f2b_config_section_t *config, const char *init) {
param = f2b_config_param_find(config->param, SOURCE_LIBRARY_PARAM);
if (!param) {
f2b_log_msg(log_error, "can't find '%s' param in source config", SOURCE_LIBRARY_PARAM);
return NULL;
return false;
}
if ((source = calloc(1, sizeof(f2b_source_t))) == NULL)
return NULL;
if ((source->h = dlopen(param->value, flags)) == NULL)
goto cleanup;
if ((*(void **) (&source->create) = dlsym(source->h, "create")) == NULL)
@ -49,7 +58,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) {
if ((*(void **) (&source->destroy) = dlsym(source->h, "destroy")) == NULL)
goto cleanup;
if ((source->cfg = source->create(init)) == NULL) {
if ((source->cfg = source->create(source->init)) == NULL) {
f2b_log_msg(log_error, "source create config failed");
goto cleanup;
}
@ -67,7 +76,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) {
}
if (source->ready(source->cfg))
return source;
return true;
/* still not ready */
f2b_log_msg(log_error, "source '%s' not fully configured", config->name);
@ -82,7 +91,7 @@ f2b_source_create(f2b_config_section_t *config, const char *init) {
dlclose(source->h);
}
free(source);
return NULL;
return false;
}
void

17
src/source.h

@ -17,6 +17,8 @@
/** 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 */
/* handlers */
@ -41,13 +43,20 @@ typedef struct f2b_source_t {
} f2b_source_t;
/**
* @brief Create module from config
* @param config Pointer to config section with module description
* @brief Allocate new source struct and fill name/init fields
* @param name Module name
* @param init Module init string
* @param logcb Logging callback
* @returns Pointer to allocated module struct or NULL on error
*/
f2b_source_t * f2b_source_create (f2b_config_section_t *config, const char *init);
f2b_source_t * f2b_source_create(const char *name, const char *init);
/**
* @brief Initialize and configure source
* @param config Pointer to config section with module description
* @return true on success, false on error
*/
bool f2b_source_init(f2b_source_t *source, f2b_config_section_t *config);
/**
* @brief Free module metadata
* @param s Pointer to module struct

Loading…
Cancel
Save