aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authordvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-14 19:51:08 +0000
committerdvossel <dvossel@f38db490-d61c-443f-a65b-d21fe96a405b>2010-07-14 19:51:08 +0000
commit2d1c0b787c2df68458609498ce2f3ed4276f1927 (patch)
tree002312ddfba7944381e16f9ee6b20a7c0f47d13f /channels
parentd93fa33a75ef977b9425f11e4d9c69719fea0a9f (diff)
handle special case were "200 Ok" to pending INVITE never receives ACK
Unlike most responses, the 200 Ok to a pending INVITE Request is acknowledged by an ACK Request. If the ACK Request for this Response is not received the previous behavior was to immediately destroy the dialog and hangup the channel. Now in an effort to be more RFC compliant, instead of immediately destroying the dialog during this special case, termination is done with a BYE Request as the dialog is technically confirmed when the 200 Ok is sent even if the ACK is never received. The behavior of immediately hanging up the channel remains. This only affects how dialog termination proceeds for this one special case. RFC 3261 section 13.3.1.4 "If the server retransmits the 2xx response for 64*T1 seconds without receiving an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is accomplished with a BYE, as described in Section 15." git-svn-id: http://svn.digium.com/svn/asterisk/trunk@276439 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c20
1 files changed, 19 insertions, 1 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index e68fc7333..6887e81f1 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -3339,8 +3339,26 @@ static int retrans_pkt(const void *data)
pkt->owner->owner->hangupcause = AST_CAUSE_NO_USER_RESPONSE;
}
if (pkt->owner->owner) {
- sip_alreadygone(pkt->owner);
ast_log(LOG_WARNING, "Hanging up call %s - no reply to our critical packet (see doc/sip-retransmit.txt).\n", pkt->owner->callid);
+
+ if (pkt->is_resp &&
+ (pkt->response_code >= 200) &&
+ (pkt->response_code < 300) &&
+ pkt->owner->pendinginvite &&
+ ast_test_flag(&pkt->owner->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
+ /* This is a timeout of the 2XX response to a pending INVITE. In this case terminate the INVITE
+ * transaction just as if we received the ACK, but immediately hangup with a BYE (sip_hangup
+ * will send the BYE as long as the dialog is not set as "alreadygone")
+ * RFC 3261 section 13.3.1.4.
+ * "If the server retransmits the 2xx response for 64*T1 seconds without receiving
+ * an ACK, the dialog is confirmed, but the session SHOULD be terminated. This is
+ * accomplished with a BYE, as described in Section 15." */
+ pkt->owner->invitestate = INV_TERMINATED;
+ pkt->owner->pendinginvite = 0;
+ } else {
+ /* there is nothing left to do, mark the dialog as gone */
+ sip_alreadygone(pkt->owner);
+ }
ast_queue_hangup_with_cause(pkt->owner->owner, AST_CAUSE_PROTOCOL_ERROR);
ast_channel_unlock(pkt->owner->owner);
} else {