aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoreliel <eliel@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-03 19:25:30 +0000
committereliel <eliel@f38db490-d61c-443f-a65b-d21fe96a405b>2008-12-03 19:25:30 +0000
commit5b0e2e90296d39d7330786c165bfb6a7fd1f76ca (patch)
tree6d15bbe3d25fbda8c685c1ace5b5fc7668e6e1fe
parent58a09224a1d53367407f1ab6b1beb0bbc152d813 (diff)
- iax2-provision was not freeing iax_templates structure when unloading the chan_iax2.so module.
- Move the code to start using the LIST macros. Review: http://reviewboard.digium.com/r/72 (closes issue #13232) Reported by: eliel Patches: iax2-provision.patch.txt uploaded by eliel (license 64) (with minor changes pointed by Mark Michelson on review board) Tested by: eliel git-svn-id: http://svn.digium.com/svn/asterisk/trunk@160663 f38db490-d61c-443f-a65b-d21fe96a405b
-rw-r--r--channels/iax2-provision.c110
1 files changed, 65 insertions, 45 deletions
diff --git a/channels/iax2-provision.c b/channels/iax2-provision.c
index 7278819b7..4907f63b8 100644
--- a/channels/iax2-provision.c
+++ b/channels/iax2-provision.c
@@ -51,7 +51,6 @@ struct iax_template {
int dead;
char name[80];
char src[80];
- struct iax_template *next;
char user[20];
char pass[20];
char lang[10];
@@ -61,8 +60,13 @@ struct iax_template {
unsigned int altserver;
unsigned int flags;
unsigned int format;
- unsigned int tos;
-} *templates;
+ unsigned int tos;
+ AST_LIST_ENTRY(iax_template) list;
+};
+
+static AST_LIST_HEAD_NOLOCK_STATIC(templates, iax_template);
+
+AST_MUTEX_DEFINE_STATIC(provlock);
static struct iax_flag {
char *name;
@@ -132,20 +136,40 @@ static unsigned int iax_str2flags(const char *buf)
}
return flags;
}
-AST_MUTEX_DEFINE_STATIC(provlock);
+
+static void iax_template_copy(struct iax_template *dst, struct iax_template *src)
+{
+ if (!dst || !src) {
+ return;
+ }
+
+ dst->dead = src->dead;
+ ast_copy_string(dst->name, src->name, sizeof(dst->name));
+ ast_copy_string(dst->src, src->src, sizeof(dst->src));
+ ast_copy_string(dst->user, src->user, sizeof(dst->user));
+ ast_copy_string(dst->pass, src->pass, sizeof(dst->pass));
+ ast_copy_string(dst->lang, src->lang, sizeof(dst->lang));
+ dst->port = src->port;
+ dst->server = src->server;
+ dst->altserver = src->altserver;
+ dst->flags = src->flags;
+ dst->format = src->format;
+ dst->tos = src->tos;
+}
static struct iax_template *iax_template_find(const char *s, int allowdead)
{
struct iax_template *cur;
- cur = templates;
- while(cur) {
+
+ AST_LIST_TRAVERSE(&templates, cur, list) {
if (!strcasecmp(s, cur->name)) {
- if (!allowdead && cur->dead)
+ if (!allowdead && cur->dead) {
cur = NULL;
+ }
break;
}
- cur = cur->next;
}
+
return cur;
}
@@ -158,7 +182,7 @@ char *iax_prov_complete_template(const char *line, const char *word, int pos, in
if (pos == 3) {
ast_mutex_lock(&provlock);
- for (c = templates; c; c = c->next) {
+ AST_LIST_TRAVERSE(&templates, c, list) {
if (!strncasecmp(word, c->name, wordlen) && ++which > state) {
ret = ast_strdup(c->name);
break;
@@ -278,16 +302,15 @@ static int iax_template_parse(struct iax_template *cur, struct ast_config *cfg,
}
if (!src)
return -1;
- ast_mutex_lock(&provlock);
+ ast_mutex_lock(&provlock);
/* Backup old data */
- memcpy(&tmp, cur, sizeof(tmp));
+ iax_template_copy(&tmp, cur);
/* Restore from src */
- memcpy(cur, src, sizeof(tmp));
+ iax_template_copy(cur, src);
/* Restore important headers */
memcpy(cur->name, tmp.name, sizeof(cur->name));
cur->dead = tmp.dead;
- cur->next = tmp.next;
- ast_mutex_unlock(&provlock);
+ ast_mutex_unlock(&provlock);
}
if (def)
strncpy(cur->src, def, sizeof(cur->src) - 1);
@@ -359,12 +382,8 @@ static int iax_process_template(struct ast_config *cfg, char *s, char *def)
/* Find an already existing one if there */
struct iax_template *cur;
int mallocd = 0;
- cur = templates;
- while(cur) {
- if (!strcasecmp(cur->name, s))
- break;
- cur = cur->next;
- }
+
+ cur = iax_template_find(s, 1 /* allow dead */);
if (!cur) {
mallocd = 1;
cur = ast_calloc(1, sizeof(*cur));
@@ -382,8 +401,7 @@ static int iax_process_template(struct ast_config *cfg, char *s, char *def)
/* Link if we're mallocd */
if (mallocd) {
ast_mutex_lock(&provlock);
- cur->next = templates;
- templates = cur;
+ AST_LIST_INSERT_HEAD(&templates, cur, list);
ast_mutex_unlock(&provlock);
}
return 0;
@@ -432,8 +450,9 @@ static char *iax_show_provisioning(struct ast_cli_entry *e, int cmd, struct ast_
if ((a->argc != 3) && (a->argc != 4))
return CLI_SHOWUSAGE;
+
ast_mutex_lock(&provlock);
- for (cur = templates;cur;cur = cur->next) {
+ AST_LIST_TRAVERSE(&templates, cur, list) {
if ((a->argc == 3) || (!strcasecmp(a->argv[3], cur->name))) {
if (found)
ast_cli(a->fd, "\n");
@@ -475,17 +494,35 @@ static int iax_provision_init(void)
return 0;
}
+static void iax_provision_free_templates(int dead)
+{
+ struct iax_template *cur;
+
+ /* Drop dead or not (depending on dead) entries while locked */
+ ast_mutex_lock(&provlock);
+ AST_LIST_TRAVERSE_SAFE_BEGIN(&templates, cur, list) {
+ if ((dead && cur->dead) || !dead) {
+ AST_LIST_REMOVE_CURRENT(list);
+ ast_free(cur);
+ }
+ }
+ AST_LIST_TRAVERSE_SAFE_END;
+ ast_mutex_unlock(&provlock);
+}
+
int iax_provision_unload(void)
{
provinit = 0;
ast_cli_unregister_multiple(cli_iax2_provision, sizeof(cli_iax2_provision) / sizeof(struct ast_cli_entry));
+ iax_provision_free_templates(0 /* Remove all templates. */);
+
return 0;
}
int iax_provision_reload(int reload)
{
struct ast_config *cfg;
- struct iax_template *cur, *prev, *next;
+ struct iax_template *cur;
char *cat;
int found = 0;
struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
@@ -495,10 +532,8 @@ int iax_provision_reload(int reload)
cfg = ast_config_load2("iaxprov.conf", "chan_iax2", config_flags);
if (cfg != NULL && cfg != CONFIG_STATUS_FILEUNCHANGED && cfg != CONFIG_STATUS_FILEINVALID) {
/* Mark all as dead. No need for locking */
- cur = templates;
- while(cur) {
+ AST_LIST_TRAVERSE(&templates, cur, list) {
cur->dead = 1;
- cur = cur->next;
}
/* Load as appropriate */
@@ -516,25 +551,10 @@ int iax_provision_reload(int reload)
return 0;
else
ast_log(LOG_NOTICE, "No IAX provisioning configuration found, IAX provisioning disabled.\n");
- ast_mutex_lock(&provlock);
- /* Drop dead entries while locked */
- prev = NULL;
- cur = templates;
- while(cur) {
- next = cur->next;
- if (cur->dead) {
- if (prev)
- prev->next = next;
- else
- templates = next;
- ast_free(cur);
- } else
- prev = cur;
- cur = next;
- }
- ast_mutex_unlock(&provlock);
+
+ iax_provision_free_templates(1 /* remove only marked as dead */);
+
/* Purge cached signature DB entries */
ast_db_deltree("iax/provisioning/cache", NULL);
return 0;
-
}