summaryrefslogtreecommitdiff
path: root/channels
diff options
context:
space:
mode:
authorMatthew Jordan <mjordan@digium.com>2012-03-21 13:31:09 +0000
committerMatthew Jordan <mjordan@digium.com>2012-03-21 13:31:09 +0000
commitc88d1c8337a17d3a2eada556708bc5bd87b2639b (patch)
treeb2c325f99babb6081fa3fde8e23daf5a2601ad7b /channels
parent6ff8f14865a47a031a537b4686b23cf4554d0d69 (diff)
Ensure Asterisk sends a BYE when pending on the final response to a re-INVITE
When Asterisk detects a hangup and cannot send a BYE due to a pending INVITE, it sets the pendingbye flag and waits for the final response to that INVITE. When the response is received, it transmits the BYE. If, however, that INVITE request is a pending re-INVITE, it needs to first send a CANCEL request to terminate the pending re-INVITE. In that circumstance, Asterisk was, in some scenarios, clearing the pendingbye flag after processing the CANCEL request and not checking for a pending BYE when receiving the final 487 response to the INVITE. This patch ensures that if the pendingbye flag is set, it is honored regardless of the nature of the INVITE request currently in flight. (closes issue ASTERISK-19365) Reported by: Thomas Arimont Tested by: Thomas Arimont Patches: bugASTERISK-19365_2012_03_08.patch uploaded by mjordan (license 6283) Review: https://reviewboard.asterisk.org/r/1807 ........ Merged revisions 360086 from http://svn.asterisk.org/svn/asterisk/branches/1.8 ........ Merged revisions 360088 from http://svn.asterisk.org/svn/asterisk/branches/10 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@360089 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c18
1 files changed, 12 insertions, 6 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index b1258a796..21e463f9f 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -12635,7 +12635,7 @@ static int transmit_invite(struct sip_pvt *p, int sipmethod, int sdp, int init,
/* If init=1, we should not generate a new branch. If it's 0, we need a new branch. */
reqprep(&req, p, sipmethod, 0, init ? 0 : 1);
}
-
+
if (p->options && p->options->auth) {
add_header(&req, p->options->authheader, p->options->auth);
}
@@ -20552,6 +20552,10 @@ static void check_pendings(struct sip_pvt *p)
if (p->invitestate == INV_PROCEEDING || p->invitestate == INV_EARLY_MEDIA) {
p->invitestate = INV_CANCELLED;
transmit_request(p, SIP_CANCEL, p->lastinvite, XMIT_RELIABLE, FALSE);
+ /* If the cancel occurred on an initial invite, cancel the pending BYE */
+ if (!ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
+ ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
+ }
/* Actually don't destroy us yet, wait for the 487 on our original
INVITE, but do set an autodestruct just in case we never get it. */
} else {
@@ -20565,8 +20569,8 @@ static void check_pendings(struct sip_pvt *p)
}
/* Perhaps there is an SD change INVITE outstanding */
transmit_request_with_auth(p, SIP_BYE, 0, XMIT_RELIABLE, TRUE);
+ ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
}
- ast_clear_flag(&p->flags[0], SIP_PENDINGBYE);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
} else if (ast_test_flag(&p->flags[0], SIP_NEEDREINVITE)) {
/* if we can't REINVITE, hold it for later */
@@ -20728,7 +20732,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
int outgoing = ast_test_flag(&p->flags[0], SIP_OUTGOING);
int res = 0;
int xmitres = 0;
- int reinvite = (p->owner && ast_channel_state(p->owner) == AST_STATE_UP);
+ int reinvite = ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED);
char *p_hdrval;
int rtn;
struct ast_party_connected_line connected;
@@ -20934,10 +20938,11 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
p->authtries = 0;
if (find_sdp(req)) {
if ((res = process_sdp(p, req, SDP_T38_ACCEPT)) && !req->ignore)
- if (!reinvite)
+ if (!reinvite) {
/* This 200 OK's SDP is not acceptable, so we need to ack, then hangup */
/* For re-invites, we try to recover */
ast_set_flag(&p->flags[0], SIP_PENDINGBYE);
+ }
ast_rtp_instance_activate(p->rtp);
}
@@ -20984,7 +20989,6 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
if (!reinvite) {
build_route(p, req, 1, resp);
}
-
if(set_address_from_contact(p)) {
/* Bad contact - we don't know how to reach this device */
/* We need to ACK, but then send a bye */
@@ -21138,6 +21142,7 @@ static void handle_response_invite(struct sip_pvt *p, int resp, const char *rest
update_call_counter(p, DEC_CALL_LIMIT);
append_history(p, "Hangup", "Got 487 on CANCEL request from us on call without owner. Killing this dialog.");
}
+ check_pendings(p);
sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
break;
case 415: /* Unsupported media type */
@@ -21834,8 +21839,9 @@ static void handle_response(struct sip_pvt *p, int resp, const char *rest, struc
}
/* If this is a NOTIFY for a subscription clear the flag that indicates that we have a NOTIFY pending */
- if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite)
+ if (!p->owner && sipmethod == SIP_NOTIFY && p->pendinginvite) {
p->pendinginvite = 0;
+ }
/* Get their tag if we haven't already */
if (ast_strlen_zero(p->theirtag) || (resp >= 200)) {