summaryrefslogtreecommitdiff
path: root/channels/chan_sip.c
diff options
context:
space:
mode:
authorDavid Vossel <dvossel@digium.com>2010-04-06 14:42:10 +0000
committerDavid Vossel <dvossel@digium.com>2010-04-06 14:42:10 +0000
commitd3f44c979c08ce7e2a28e0016f427f326b9b764f (patch)
treea29eeb1ad85f2a8b8e65735a5f248a541834619a /channels/chan_sip.c
parent1a2f96573a47cc33965caf24b1f4314bc5de2436 (diff)
fixes deadlock in chan_sip caused by usage of MASTER_CHANNEL dialplan function
(closes issue #16767) Reported by: lmsteffan Patches: deadlock_16767v3.diff uploaded by dvossel (license 671) Review: https://reviewboard.asterisk.org/r/606/ git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@256319 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels/chan_sip.c')
-rw-r--r--channels/chan_sip.c21
1 files changed, 16 insertions, 5 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 934a925f0..f2308fabe 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -17495,7 +17495,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
owner = p->owner;
if (owner) {
- char causevar[256], causeval[256];
const char *rp = NULL, *rh = NULL;
owner->hangupcause = 0;
@@ -17513,10 +17512,6 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
if (!owner->hangupcause)
owner->hangupcause = hangup_sip2cause(resp);
-
- snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
- snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
- pbx_builtin_setvar_helper(owner, causevar, causeval);
}
if (p->socket.type == SIP_TRANSPORT_UDP) {
@@ -20922,10 +20917,26 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct so
ast_log(LOG_DEBUG, "Ignoring out of order response %d (expecting %d)\n", seqno, p->ocseq);
return -1;
} else {
+ char causevar[256], causeval[256];
+
if ((respid == 200) || ((respid >= 300) && (respid <= 399))) {
extract_uri(p, req);
}
+
handle_response(p, respid, e + len, req, seqno);
+
+ if (p->owner) {
+ struct ast_channel *owner = p->owner;
+
+ snprintf(causevar, sizeof(causevar), "MASTER_CHANNEL(HASH(SIP_CAUSE,%s))", owner->name);
+ snprintf(causeval, sizeof(causeval), "SIP %s", REQ_OFFSET_TO_STR(req, rlPart2));
+
+ sip_pvt_unlock(p);
+ ast_channel_unlock(owner);
+ *nounlock = 1;
+ pbx_builtin_setvar_helper(owner, causevar, causeval);
+ sip_pvt_lock(p);
+ }
}
return 0;
}