From fac7eaffa947788a5a42f7dcc94c20ac635f1dab Mon Sep 17 00:00:00 2001 From: Mark Spencer Date: Thu, 4 Dec 2003 23:19:26 +0000 Subject: [PATCH] Fix PGSQL voicemail issues (bug #625) and fix reload races in iax2 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@1827 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- apps/app_voicemail.c | 6 ++- channels/chan_iax2.c | 122 +++++++++++++++++++++++++++++-------------- 2 files changed, 89 insertions(+), 39 deletions(-) diff --git a/apps/app_voicemail.c b/apps/app_voicemail.c index a0e08034f0..a0bea848bd 100755 --- a/apps/app_voicemail.c +++ b/apps/app_voicemail.c @@ -266,11 +266,15 @@ static struct ast_vm_user *find_user(struct ast_vm_user *ivm, char *context, cha if (context) { strcpy(retval->context, context); } + else + { + strcpy(retval->context, "default"); + } if (*retval->context) { sprintf(query, "SELECT password,fullname,email,pager,options FROM voicemail WHERE context='%s' AND mailbox='%s'", context, mailbox); } else { - sprintf(query, "SELECT password,fullname,email,pager,options FROM voicemail WHERE mailbox='%s'", mailbox); + sprintf(query, "SELECT password,fullname,email,pager,options FROM voicemail WHERE context='default' AND mailbox='%s'", mailbox); } /* fprintf(stderr,"postgres find_user: query = %s\n",query); */ ast_mutex_lock(&postgreslock); diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index d3194ea860..30336bf347 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -181,6 +181,7 @@ struct iax2_user { int amaflags; int hascallerid; int delme; + int temponly; int capability; int trunk; char callerid[AST_MAX_EXTENSION]; @@ -216,6 +217,7 @@ struct iax2_peer { int expirey; /* How soon to expire */ int capability; /* Capability */ int delme; /* I need to be deleted */ + int temponly; /* I'm only a temp */ int trunk; /* Treat as an IAX trunking */ struct timeval txtrunktime; /* Transmit trunktime */ struct timeval rxtrunktime; /* Receive trunktime */ @@ -1596,7 +1598,7 @@ static struct iax2_peer *mysql_peer(char *peer) } else { strncpy(p->name, peer, sizeof(p->name) - 1); p->dynamic = 1; - p->delme = 1; + p->temponly = 1; p->expire = -1; p->capability = iax2_capability; p->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; @@ -1652,7 +1654,7 @@ static struct iax2_user *mysql_user(char *user) p = NULL; } else { strncpy(p->name, user, sizeof(p->name) - 1); - p->delme = 1; + p->temponly = 1; p->capability = iax2_capability; p->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; } @@ -1711,7 +1713,7 @@ static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, i if (notransfer) *notransfer=p->notransfer; } else { - if (p->delme) + if (p->temponly) free(p); p = NULL; } @@ -1728,7 +1730,7 @@ static int create_addr(struct sockaddr_in *sin, int *capability, int *sendani, i } } else if (!p) return -1; - if (p->delme) + if (p->temponly) free(p); return 0; } @@ -3049,7 +3051,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * if (!p->dynamic) { if (authdebug) ast_log(LOG_NOTICE, "Peer '%s' is not dynamic (from %s)\n", peer, inet_ntoa(sin->sin_addr)); - if (p->delme) + if (p->temponly) free(p); return -1; } @@ -3057,7 +3059,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * if (!ast_apply_ha(p->ha, sin)) { if (authdebug) ast_log(LOG_NOTICE, "Host %s denied access to register peer '%s'\n", inet_ntoa(sin->sin_addr), p->name); - if (p->delme) + if (p->temponly) free(p); return -1; } @@ -3083,14 +3085,14 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * if (!keyn) { if (authdebug) ast_log(LOG_NOTICE, "Host %s failed RSA authentication with inkeys '%s'\n", peer, p->inkeys); - if (p->delme) + if (p->temponly) free(p); return -1; } } else { if (authdebug) ast_log(LOG_NOTICE, "Host '%s' trying to do RSA authentication, but we have no inkeys\n", peer); - if (p->delme) + if (p->temponly) free(p); return -1; } @@ -3099,7 +3101,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * if (strcmp(secret, p->secret)) { if (authdebug) ast_log(LOG_NOTICE, "Host %s did not provide proper plaintext password for '%s'\n", inet_ntoa(sin->sin_addr), p->name); - if (p->delme) + if (p->temponly) free(p); return -1; } else @@ -3116,7 +3118,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * if (strcasecmp(requeststr, md5secret)) { if (authdebug) ast_log(LOG_NOTICE, "Host %s failed MD5 authentication for '%s' (%s != %s)\n", inet_ntoa(sin->sin_addr), p->name, requeststr, md5secret); - if (p->delme) + if (p->temponly) free(p); return -1; } else @@ -3124,7 +3126,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * } else if (strlen(md5secret) || strlen(secret)) { if (authdebug) ast_log(LOG_NOTICE, "Inappropriate authentication received\n"); - if (p->delme) + if (p->temponly) free(p); return -1; } @@ -3132,7 +3134,7 @@ static int register_verify(int callno, struct sockaddr_in *sin, struct iax_ies * /* Choose lowest expirey number */ if (expire && (expire < iaxs[callno]->expirey)) iaxs[callno]->expirey = expire; - if (p->delme) + if (p->temponly) free(p); return 0; @@ -3564,7 +3566,7 @@ static int update_registry(char *name, struct sockaddr_in *sin, int callno) #endif if (p) { #ifdef MYSQL_FRIENDS - if (p->delme) + if (p->temponly) mysql_update_peer(name, sin); #endif if (inaddrcmp(&p->addr, sin)) { @@ -3596,7 +3598,7 @@ static int update_registry(char *name, struct sockaddr_in *sin, int callno) } if (p->hascallerid) iax_ie_append_str(&ied, IAX_IE_CALLING_NAME, p->callerid); - if (p->delme) + if (p->temponly) free(p); return send_command_final(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGACK, 0, ied.buf, ied.pos, -1);; } @@ -3628,7 +3630,7 @@ static int registry_authrequest(char *name, int callno) iax_ie_append_str(&ied, IAX_IE_CHALLENGE, iaxs[callno]->challenge); } iax_ie_append_str(&ied, IAX_IE_USERNAME, name); - if (p->delme) + if (p->temponly) free(p); return send_command(iaxs[callno], AST_FRAME_IAX, IAX_COMMAND_REGAUTH, 0, ied.buf, ied.pos, -1);; } @@ -5219,10 +5221,36 @@ static struct iax2_peer *build_peer(char *name, struct ast_variable *v) static struct iax2_user *build_user(char *name, struct ast_variable *v) { - struct iax2_user *user; + struct iax2_user *prev, *user; struct iax2_context *con, *conl = NULL; int format; - user = (struct iax2_user *)malloc(sizeof(struct iax2_user)); + int found; + + prev = NULL; + ast_mutex_lock(&userl.lock); + user = userl.users; + while(user) { + if (!strcasecmp(user->name, name)) { + break; + } + prev = user; + user = user->next; + } + if (user) { + found++; + /* Already in the list, remove it and it will be added back (or FREE'd) */ + if (prev) { + prev->next = user->next; + } else { + userl.users = user->next; + } + ast_mutex_unlock(&userl.lock); + } else { + ast_mutex_unlock(&userl.lock); + user = malloc(sizeof(struct iax2_user)); + memset(user, 0, sizeof(struct iax2_user)); + } + if (user) { memset(user, 0, sizeof(struct iax2_user)); user->capability = iax2_capability; @@ -5282,39 +5310,34 @@ static struct iax2_user *build_user(char *name, struct ast_variable *v) // ast_log(LOG_WARNING, "Ignoring %s\n", v->name); v = v->next; } - } - if (!user->authmethods) { - if (strlen(user->secret)) { - user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; - if (strlen(user->inkeys)) - user->authmethods |= IAX_AUTH_RSA; - } else if (strlen(user->inkeys)) { - user->authmethods = IAX_AUTH_RSA; - } else { - user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; + if (!user->authmethods) { + if (strlen(user->secret)) { + user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; + if (strlen(user->inkeys)) + user->authmethods |= IAX_AUTH_RSA; + } else if (strlen(user->inkeys)) { + user->authmethods = IAX_AUTH_RSA; + } else { + user->authmethods = IAX_AUTH_MD5 | IAX_AUTH_PLAINTEXT; + } } + user->delme = 0; } return user; } - -static void delete_users(void){ - struct iax2_user *user, *userlast; +static void delete_users(void) +{ + struct iax2_user *user; struct iax2_peer *peer; struct iax2_registry *reg, *regl; - /* Delete all users */ ast_mutex_lock(&userl.lock); for (user=userl.users;user;) { - ast_free_ha(user->ha); - free_context(user->contexts); - userlast = user; - user=user->next; - free(userlast); + user->delme = 1; + user = user->next; } - userl.users=NULL; ast_mutex_unlock(&userl.lock); - for (reg = registrations;reg;) { regl = reg; reg = reg->next; @@ -5332,6 +5355,28 @@ static void delete_users(void){ ast_mutex_unlock(&peerl.lock); } +static void prune_users(void) +{ + struct iax2_user *user, *usernext, *userlast = NULL; + ast_mutex_lock(&userl.lock); + for (user=userl.users;user;) { + usernext = user->next; + if (user->delme) { + ast_free_ha(user->ha); + free_context(user->contexts); + user=user->next; + free(user); + if (userlast) + userlast->next = usernext; + else + userl.users = usernext; + } else + userlast = user; + user = usernext; + } + ast_mutex_unlock(&userl.lock); +} + static void prune_peers(void){ /* Prune peers who still are supposed to be deleted */ struct iax2_peer *peer, *peerlast, *peernext; @@ -5563,6 +5608,7 @@ static int reload_config(void) delete_users(); set_config(config,&dead_sin); prune_peers(); + prune_users(); for (reg = registrations; reg; reg = reg->next) iax2_do_register(reg); /* Qualify hosts, too */