MT#62053 generalise config loading

Switch from specialised handling of config sections (used to load
signalling templates) to a more general approach using a callback
mechanism. This allows us to add more information to the config file
while keeping the details of the underlying GKeyFile hidden. Use a typed
hash table for type safety.

Change-Id: I71ddfda0202b47df363bcc5acf1725078774f8f1
pull/1910/head
Richard Fuchs 4 months ago
parent b61925d264
commit 052972082a

@ -4188,14 +4188,14 @@ void call_interfaces_free(void) {
t_hash_table_destroy(rtpe_signalling_templates);
}
static void parse_templates(GHashTable *templates) {
if (!templates)
static void parse_templates(charp_ht templates) {
if (!t_hash_table_is_set(templates))
return;
GHashTableIter iter;
g_hash_table_iter_init(&iter, templates);
void *keyp, *valuep;
while (g_hash_table_iter_next(&iter, &keyp, &valuep)) {
charp_ht_iter iter;
t_hash_table_iter_init(&iter, templates);
char *keyp, *valuep;
while (t_hash_table_iter_next(&iter, &keyp, &valuep)) {
char *key = keyp;
char *value = valuep;
t_hash_table_insert(rtpe_signalling_templates, str_dup(STR_PTR(key)), str_dup(STR_PTR(value)));
@ -4215,7 +4215,7 @@ static void parse_templates(GHashTable *templates) {
rtpe_default_signalling_templates[OP_OTHER] = *tmpl;
}
int call_interfaces_init(GHashTable *templates) {
int call_interfaces_init(charp_ht templates) {
int errcode;
PCRE2_SIZE erroff;

@ -492,7 +492,7 @@ static void release_listeners(GQueue *q) {
}
static void options(int *argc, char ***argv, GHashTable *templates) {
static void options(int *argc, char ***argv, charp_ht templates) {
g_autoptr(char_p) if_a = NULL;
g_autoptr(char_p) ks_a = NULL;
long int_keyspace_db;
@ -730,7 +730,17 @@ static void options(int *argc, char ***argv, GHashTable *templates) {
config_load_ext(argc, argv, e, " - next-generation media proxy",
"/etc/rtpengine/rtpengine.conf", "rtpengine", &rtpe_config.common,
&templates_section, templates);
(struct rtpenging_config_callback []) {
{
.type = RCC_SECTION_KEYS,
.arg.ht = templates,
.section_keys = {
.name = &templates_section,
.callback = add_c_str_to_ht,
},
},
{ 0 },
});
// default values, if not configured
if (rtpe_config.rec_method == NULL)
@ -1319,7 +1329,7 @@ fallback:
}
static void init_everything(GHashTable *templates) {
static void init_everything(charp_ht templates) {
bufferpool_init();
gettimeofday(&rtpe_now, NULL);
log_init(rtpe_common_config_ptr->log_name);
@ -1585,7 +1595,7 @@ static void uring_poller_loop(void *ptr) {
int main(int argc, char **argv) {
early_init();
{
g_autoptr(GHashTable) templates = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, g_free);
g_auto(charp_ht) templates = charp_ht_new();
options(&argc, &argv, templates);
init_everything(templates);
}

@ -323,7 +323,7 @@ void call_unlock_release(call_t *c);
G_DEFINE_AUTO_CLEANUP_CLEAR_FUNC(sdp_ng_flags, call_ng_free_flags)
G_DEFINE_AUTOPTR_CLEANUP_FUNC(call_t, call_unlock_release)
int call_interfaces_init(GHashTable *);
int call_interfaces_init(charp_ht);
void call_interfaces_free(void);
void call_interfaces_timer(void);

@ -155,20 +155,26 @@ void config_load_free(struct rtpengine_common_config *cconfig) {
g_free(cconfig->pidfile);
}
static void load_templates(GKeyFile *kf, const char *template_section, GHashTable *templates) {
size_t length;
static void section_keys_callback(GKeyFile *kf,
const char *section_name,
void (*callback)(const char *key, char *value, union rtpenging_config_callback_arg),
union rtpenging_config_callback_arg arg)
{
if (!section_name)
return;
g_autoptr(GError) err = NULL;
g_autoptr(char_p) keys = g_key_file_get_keys(kf, template_section, &length, &err);
g_autoptr(char_p) keys = g_key_file_get_keys(kf, section_name, NULL, &err);
if (err)
die("Failed to load templates from given config file section '%s': %s", template_section, err->message);
die("Failed to load keys from given config file section '%s': %s", section_name, err->message);
if (!keys)
return; // empty config section
for (char **key = keys; *key; key++) {
char *val = g_key_file_get_string(kf, template_section, *key, &err);
char *val = g_key_file_get_string(kf, section_name, *key, &err);
if (err)
die("Failed to read template value '%s' from config file: %s", *key, err->message);
g_hash_table_insert(templates, g_strdup(*key), val); // hash table takes ownership of both
die("Failed to read config value '%s' (section '%s') from config file: %s", *key, section_name, err->message);
callback(*key, val, arg);
}
}
@ -179,7 +185,7 @@ G_DEFINE_AUTOPTR_CLEANUP_FUNC(char_p_shallow, g_free)
void config_load_ext(int *argc, char ***argv, GOptionEntry *app_entries, const char *description,
char *default_config, char *default_section,
struct rtpengine_common_config *cconfig,
char * const *template_section, GHashTable *templates)
const struct rtpenging_config_callback *callbacks)
{
g_autoptr(GOptionContext) c = NULL;
g_autoptr(GError) er = NULL;
@ -380,8 +386,17 @@ void config_load_ext(int *argc, char ***argv, GOptionEntry *app_entries, const c
}
}
if (template_section && *template_section && templates)
load_templates(kf, *template_section, templates);
for (const struct rtpenging_config_callback *cb = callbacks; cb; cb++) {
switch (cb->type) {
case RCC_END:
break;
case RCC_SECTION_KEYS:
section_keys_callback(kf, *cb->section_keys.name, cb->section_keys.callback, cb->arg);
continue;
}
break;
}
out:
// default common values, if not configured

@ -49,6 +49,30 @@ struct rtpengine_common_config {
extern struct rtpengine_common_config *rtpe_common_config_ptr;
INLINE unsigned int c_str_hash(const char *s);
INLINE gboolean c_str_equal(const char *a, const char *b);
TYPED_GHASHTABLE(charp_ht, char, char, c_str_hash, c_str_equal, g_free, g_free)
union rtpenging_config_callback_arg {
charp_ht ht;
} __attribute__((__transparent_union__));
struct rtpenging_config_callback {
enum {
RCC_END = 0,
RCC_SECTION_KEYS,
} type;
union rtpenging_config_callback_arg arg;
union {
struct {
char * const *name;
void (*callback)(const char *key, char *value,
union rtpenging_config_callback_arg);
} section_keys;
};
};
/*** GLOBALS ***/
@ -69,12 +93,12 @@ void config_load_free(struct rtpengine_common_config *);
void config_load_ext(int *argc, char ***argv, GOptionEntry *entries, const char *description,
char *default_config, char *default_section,
struct rtpengine_common_config *,
char * const *template_section, GHashTable *templates);
const struct rtpenging_config_callback *);
INLINE void config_load(int *argc, char ***argv, GOptionEntry *entries, const char *description,
char *default_config, char *default_section,
struct rtpengine_common_config *cc)
{
config_load_ext(argc, argv, entries, description, default_config, default_section, cc, NULL, NULL);
config_load_ext(argc, argv, entries, description, default_config, default_section, cc, NULL);
}
char *get_thread_buf(void);
@ -113,7 +137,9 @@ INLINE unsigned int c_str_hash(const char *s) {
INLINE gboolean c_str_equal(const char *a, const char *b) {
return g_str_equal(a, b);
}
INLINE void add_c_str_to_ht(const char *key, char *value, charp_ht ht) {
t_hash_table_insert(ht, g_strdup(key), value); // hash table takes ownership of both
}
/*** MUTEX ABSTRACTION ***/

@ -74,7 +74,7 @@ int main(void) {
rtpe_ssl_init();
call_init();
statistics_init();
call_interfaces_init(NULL);
call_interfaces_init(charp_ht_null());
ice_init();
control_ng_init();
dtls_init();

Loading…
Cancel
Save