From 5624f22ad5b88b0fa8c4b60857bd53a37cc1bbd8 Mon Sep 17 00:00:00 2001 From: kpfleming Date: Sun, 15 May 2005 20:00:08 +0000 Subject: fix segfaults in realtime_peer/realtime_user when wrong-type realtime entry is loaded (bug #4266) git-svn-id: http://svn.digium.com/svn/asterisk/trunk@5680 f38db490-d61c-443f-a65b-d21fe96a405b --- channels/chan_iax2.c | 165 +++++++++++++++++++++++++++------------------------ 1 file changed, 86 insertions(+), 79 deletions(-) (limited to 'channels/chan_iax2.c') diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c index e99657ede..36711b775 100755 --- a/channels/chan_iax2.c +++ b/channels/chan_iax2.c @@ -2509,64 +2509,69 @@ static struct iax2_peer *realtime_peer(const char *peername) struct iax2_peer *peer=NULL; time_t regseconds, nowtime; int dynamic=0; + var = ast_load_realtime("iaxpeers", "name", peername, NULL); - if (var) { + if (!var) + return NULL; + + peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); + + if (!peer) + return NULL; + + tmp = var; + while(tmp) { /* Make sure it's not a user only... */ - peer = build_peer(peername, var, ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS) ? 0 : 1); + if (!strcasecmp(tmp->name, "type")) { + if (strcasecmp(tmp->value, "friend") && + strcasecmp(tmp->value, "peer")) { + /* Whoops, we weren't supposed to exist! */ + destroy_peer(peer); + peer = NULL; + break; + } + } else if (!strcasecmp(tmp->name, "regseconds")) { + if (sscanf(tmp->value, "%li", ®seconds) != 1) + regseconds = 0; + } else if (!strcasecmp(tmp->name, "ipaddr")) { + inet_aton(tmp->value, &(peer->addr.sin_addr)); + } else if (!strcasecmp(tmp->name, "port")) { + peer->addr.sin_port = htons(atoi(tmp->value)); + } else if (!strcasecmp(tmp->name, "host")) { + if (!strcasecmp(tmp->value, "dynamic")) + dynamic = 1; + } + tmp = tmp->next; + } + if (!peer) + return NULL; - if (peer) { - tmp = var; - while(tmp) { - if (!strcasecmp(tmp->name, "type")) { - if (strcasecmp(tmp->value, "friend") && - strcasecmp(tmp->value, "peer")) { - /* Whoops, we weren't supposed to exist! */ - destroy_peer(peer); - peer = NULL; - break; - } - } else if (!strcasecmp(tmp->name, "regseconds")) { - if (sscanf(tmp->value, "%li", ®seconds) != 1) - regseconds = 0; - } else if (!strcasecmp(tmp->name, "ipaddr")) { - inet_aton(tmp->value, &(peer->addr.sin_addr)); - } else if (!strcasecmp(tmp->name, "port")) { - peer->addr.sin_port = htons(atoi(tmp->value)); - } else if (!strcasecmp(tmp->name, "host")) { - if (!strcasecmp(tmp->value, "dynamic")) - dynamic = 1; - } - tmp = tmp->next; - } + ast_variables_destroy(var); - /* Add some finishing touches, addresses, etc */ - if(ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { - ast_mutex_lock(&peerl.lock); - peer->next = peerl.peers; - peerl.peers = peer; - ast_mutex_unlock(&peerl.lock); - ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); - if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { - if (peer->expire > -1) { - ast_sched_del(sched, peer->expire); - } - peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, (void *)peer); - } - } else { - ast_set_flag(peer, IAX_TEMPONLY); - } + if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { + ast_copy_flags(peer, &globalflags, IAX_RTAUTOCLEAR|IAX_RTCACHEFRIENDS); + if (ast_test_flag(peer, IAX_RTAUTOCLEAR)) { + if (peer->expire > -1) + ast_sched_del(sched, peer->expire); + peer->expire = ast_sched_add(sched, (global_rtautoclear) * 1000, expire_registry, peer); + } + ast_mutex_lock(&peerl.lock); + peer->next = peerl.peers; + peerl.peers = peer; + ast_mutex_unlock(&peerl.lock); + } else { + ast_set_flag(peer, IAX_TEMPONLY); + } - if (peer && dynamic) { - time(&nowtime); - if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { - memset(&peer->addr, 0, sizeof(peer->addr)); - if (option_debug) - ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime); - } - } + if (dynamic) { + time(&nowtime); + if ((nowtime - regseconds) > IAX_DEFAULT_REG_EXPIRE) { + memset(&peer->addr, 0, sizeof(peer->addr)); + if (option_debug) + ast_log(LOG_DEBUG, "Bah, we're expired (%ld/%ld/%ld)!\n", nowtime - regseconds, regseconds, nowtime); } - ast_variables_destroy(var); } + return peer; } @@ -2575,37 +2580,39 @@ static struct iax2_user *realtime_user(const char *username) struct ast_variable *var; struct ast_variable *tmp; struct iax2_user *user=NULL; + var = ast_load_realtime("iaxusers", "name", username, NULL); - if (var) { - /* Make sure it's not a user only... */ - user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); - if (user) { - /* Add some finishing touches, addresses, etc */ - if(ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { - ast_mutex_lock(&userl.lock); - user->next = userl.users; - userl.users = user; - ast_mutex_unlock(&userl.lock); - ast_set_flag(user, IAX_RTCACHEFRIENDS); - } else { - ast_set_flag(user, IAX_TEMPONLY); - } - tmp = var; - while(tmp) { - if (!strcasecmp(tmp->name, "type")) { - if (strcasecmp(tmp->value, "friend") && - strcasecmp(tmp->value, "user")) { - /* Whoops, we weren't supposed to exist! */ - destroy_user(user); - user = NULL; - break; - } - } - tmp = tmp->next; - } + if (!var) + return NULL; + + tmp = var; + while(tmp) { + /* Make sure it's not a peer only... */ + if (!strcasecmp(tmp->name, "type")) { + if (strcasecmp(tmp->value, "friend") && + strcasecmp(tmp->value, "user")) { + return NULL; + } } - ast_variables_destroy(var); + tmp = tmp->next; } + + user = build_user(username, var, !ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)); + if (!user) + return NULL; + + ast_variables_destroy(var); + + if (ast_test_flag((&globalflags), IAX_RTCACHEFRIENDS)) { + ast_set_flag(user, IAX_RTCACHEFRIENDS); + ast_mutex_lock(&userl.lock); + user->next = userl.users; + userl.users = user; + ast_mutex_unlock(&userl.lock); + } else { + ast_set_flag(user, IAX_TEMPONLY); + } + return user; } -- cgit v1.2.3