Merged revisions 79214 via svnmerge from
authorRussell Bryant <russell@russellbryant.com>
Mon, 13 Aug 2007 15:32:05 +0000 (15:32 +0000)
committerRussell Bryant <russell@russellbryant.com>
Mon, 13 Aug 2007 15:32:05 +0000 (15:32 +0000)
https://origsvn.digium.com/svn/asterisk/branches/1.4

........
r79214 | russell | 2007-08-13 10:28:13 -0500 (Mon, 13 Aug 2007) | 4 lines

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: https://origsvn.digium.com/svn/asterisk/trunk@79222 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_iax2.c

index c6ea721..8eff5ca 100644 (file)
@@ -7447,8 +7447,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;
@@ -8109,8 +8116,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);