summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Michelson <mmichelson@digium.com>2015-01-16 22:12:25 +0000
committerMark Michelson <mmichelson@digium.com>2015-01-16 22:12:25 +0000
commit821c15ae53aa6b237f24d089f0a874916312bfdc (patch)
tree4b75c1484a107e3744b0a23fbb02b52589831e07
parent8bc4a89e1f9cb71295e074158b938e5d800342b0 (diff)
Fix problem where a hung channel could occur on a failed blind transfer.
Different clients react differently to being told that a blind transfer has failed. Some will simply send a BYE and be done with it. Others will attempt to reinvite themselves back onto the call. In the latter case, we were creating a new channel and then leaving it to sit forever doing nothing. With this code change, that new channel will not be created and the dialog with the transferring channel will be cleaned up properly. ASTERISK-24624 #close Reported by Zane Conkle Review: https://reviewboard.asterisk.org/r/4339 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/13@430714 65c4cc65-6c06-0410-ace0-fbb531ad65f3
-rw-r--r--channels/chan_pjsip.c15
-rw-r--r--res/res_pjsip_session.c3
2 files changed, 17 insertions, 1 deletions
diff --git a/channels/chan_pjsip.c b/channels/chan_pjsip.c
index f1bfc4d5c..e580ef177 100644
--- a/channels/chan_pjsip.c
+++ b/channels/chan_pjsip.c
@@ -2014,6 +2014,21 @@ static int chan_pjsip_incoming_request(struct ast_sip_session *session, struct p
return 0;
}
+ if (session->inv_session->state >= PJSIP_INV_STATE_CONFIRMED) {
+ /* Weird case. We've received a reinvite but we don't have a channel. The most
+ * typical case for this happening is that a blind transfer fails, and so the
+ * transferer attempts to reinvite himself back into the call. We already got
+ * rid of that channel, and the other side of the call is unrecoverable.
+ *
+ * We treat this as a failure, so our best bet is to just hang this call
+ * up and not create a new channel. Clearing defer_terminate here ensures that
+ * calling ast_sip_session_terminate() can result in a BYE being sent ASAP.
+ */
+ session->defer_terminate = 0;
+ ast_sip_session_terminate(session, 400);
+ return -1;
+ }
+
datastore = ast_sip_session_alloc_datastore(&transport_info, "transport_info");
if (!datastore) {
return -1;
diff --git a/res/res_pjsip_session.c b/res/res_pjsip_session.c
index 606097700..d659684b9 100644
--- a/res/res_pjsip_session.c
+++ b/res/res_pjsip_session.c
@@ -779,7 +779,8 @@ static pj_bool_t session_reinvite_on_rx_request(pjsip_rx_data *rdata)
if (rdata->msg_info.msg->line.req.method.id != PJSIP_INVITE_METHOD ||
!(dlg = pjsip_ua_find_dialog(&rdata->msg_info.cid->id, &rdata->msg_info.to->tag, &rdata->msg_info.from->tag, PJ_FALSE)) ||
- !(session = ast_sip_dialog_get_session(dlg))) {
+ !(session = ast_sip_dialog_get_session(dlg)) ||
+ !session->channel) {
return PJ_FALSE;
}