aboutsummaryrefslogtreecommitdiffstats
path: root/channels/chan_iax2.c
diff options
context:
space:
mode:
authorrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-08-13 15:28:13 +0000
committerrussell <russell@f38db490-d61c-443f-a65b-d21fe96a405b>2007-08-13 15:28:13 +0000
commit9092da6fa7106209d19598f25c47402a3760ec3e (patch)
treedbca8e0278f7db2dc2bf3533512c728a7cbdc5bd /channels/chan_iax2.c
parent0c9b3cfe581180a63bc3c5049c667ffbde45ff63 (diff)
Fix a potential deadlock in socket_process. check_provisioning can eventually
call find_callno. You can't hold a pvt lock while calling find_callno because it goes through and locks every single one looking for a match. git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.4@79214 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels/chan_iax2.c')
-rw-r--r--channels/chan_iax2.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/channels/chan_iax2.c b/channels/chan_iax2.c
index 492a45782..e8f78cf06 100644
--- a/channels/chan_iax2.c
+++ b/channels/chan_iax2.c
@@ -6981,8 +6981,15 @@ retryowner:
/* Ignore if it's already up */
if (ast_test_flag(&iaxs[fr->callno]->state, IAX_STATE_STARTED | IAX_STATE_TBD))
break;
- if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
+ if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
check_provisioning(&sin, fd, ies.serviceident, ies.provver);
+ ast_mutex_lock(&iaxsl[fr->callno]);
+ if (!iaxs[fr->callno]) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ return 1;
+ }
+ }
/* If we're in trunk mode, do it now, and update the trunk number in our frame before continuing */
if (ast_test_flag(iaxs[fr->callno], IAX_TRUNK)) {
int new_callno;
@@ -7583,8 +7590,15 @@ retryowner2:
memset(&sin, 0, sizeof(sin));
if (update_registry(iaxs[fr->callno]->peer, &sin, fr->callno, ies.devicetype, fd, ies.refresh))
ast_log(LOG_WARNING, "Registry error\n");
- if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr)
+ if (ies.provverpres && ies.serviceident && sin.sin_addr.s_addr) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
check_provisioning(&sin, fd, ies.serviceident, ies.provver);
+ ast_mutex_lock(&iaxsl[fr->callno]);
+ if (!iaxs[fr->callno]) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ return 1;
+ }
+ }
break;
}
registry_authrequest(iaxs[fr->callno]->peer, fr->callno);