[asterisk-commits] russell: trunk r79273 - in /trunk: ./ channels/chan_iax2.c
SVN commits to the Asterisk project
asterisk-commits at lists.digium.com
Mon Aug 13 14:29:30 CDT 2007
Author: russell
Date: Mon Aug 13 14:29:30 2007
New Revision: 79273
URL: http://svn.digium.com/view/asterisk?view=rev&rev=79273
Log:
Merged revisions 79272 via svnmerge from
https://origsvn.digium.com/svn/asterisk/branches/1.4
........
r79272 | russell | 2007-08-13 14:27:39 -0500 (Mon, 13 Aug 2007) | 9 lines
I am fighting deadlocks in chan_iax2. I have tracked them down to a single
core issue. You can not call find_callno() while holding a pvt lock as this
function has to lock another (every) other pvt lock. Doing so can lead to a
classic deadlock. So, I am tracking down all of the code paths where this
can happen and fixing them.
The fix I committed earlier today was along the same theme. This patch fixes
some code down the path of authenticate_reply.
........
Modified:
trunk/ (props changed)
trunk/channels/chan_iax2.c
Propchange: trunk/
------------------------------------------------------------------------------
Binary property 'branch-1.4-merged' - no diff available.
Modified: trunk/channels/chan_iax2.c
URL: http://svn.digium.com/view/asterisk/trunk/channels/chan_iax2.c?view=diff&rev=79273&r1=79272&r2=79273
==============================================================================
--- trunk/channels/chan_iax2.c (original)
+++ trunk/channels/chan_iax2.c Mon Aug 13 14:29:30 2007
@@ -1397,6 +1397,8 @@
* However, it's too late to change that now. Instead, we need to come up with
* a better way of indexing active calls so that these frequent lookups are not
* so expensive.
+ *
+ * \note Calling this function while holding another pvt lock can cause a deadlock.
*/
static int find_callno(unsigned short callno, unsigned short dcallno, struct sockaddr_in *sin, int new, int lockpeer, int sockfd)
{
@@ -2674,6 +2676,10 @@
return 0;
}
+/*!
+ * \note This function calls reg_source_db -> iax2_poke_peer -> find_callno,
+ * so do not call this with a pvt lock held.
+ */
static struct iax2_peer *realtime_peer(const char *peername, struct sockaddr_in *sin)
{
struct ast_variable *var;
@@ -5496,6 +5502,10 @@
return res;
}
+/*!
+ * \note This function calls realtime_peer -> reg_source_db -> iax2_poke_peer -> find_callno,
+ * so do not call this function with a pvt lock held.
+ */
static int authenticate_reply(struct chan_iax2_pvt *p, struct sockaddr_in *sin, struct iax_ies *ies, const char *override, const char *okey)
{
struct iax2_peer *peer = NULL;
@@ -5503,7 +5513,8 @@
int res = -1;
int authmethods = 0;
struct iax_ie_data ied;
-
+ uint16_t callno = p->callno;
+
memset(&ied, 0, sizeof(ied));
if (ies->username)
@@ -5540,10 +5551,20 @@
if (!peer) {
/* We checked our list and didn't find one. It's unlikely, but possible,
that we're trying to authenticate *to* a realtime peer */
- if ((peer = realtime_peer(p->peer, NULL))) {
+ const char *peer_name = ast_strdupa(p->peer);
+ ast_mutex_unlock(&iaxsl[callno]);
+ if ((peer = realtime_peer(peer_name, NULL))) {
+ ast_mutex_lock(&iaxsl[callno]);
+ if (!(p = iaxs[callno]))
+ return -1;
res = authenticate(p->challenge, peer->secret,peer->outkey, authmethods, &ied, sin, &p->ecx, &p->dcx);
if (ast_test_flag(peer, IAX_TEMPONLY))
destroy_peer(peer);
+ }
+ if (!peer) {
+ ast_mutex_lock(&iaxsl[callno]);
+ if (!(p = iaxs[callno]))
+ return -1;
}
}
}
@@ -7845,6 +7866,10 @@
ast_log(LOG_WARNING,
"I don't know how to authenticate %s to %s\n",
ies.username ? ies.username : "<unknown>", ast_inet_ntoa(iaxs[fr->callno]->addr.sin_addr));
+ }
+ if (!iaxs[fr->callno]) {
+ ast_mutex_unlock(&iaxsl[fr->callno]);
+ return 1;
}
break;
case IAX_COMMAND_AUTHREP:
More information about the asterisk-commits
mailing list