aboutsummaryrefslogtreecommitdiffstats
path: root/channels
diff options
context:
space:
mode:
authormmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-09 19:14:38 +0000
committermmichelson <mmichelson@f38db490-d61c-443f-a65b-d21fe96a405b>2009-04-09 19:14:38 +0000
commit8b29c1d3f03916bca41b6808195640e441f23bcc (patch)
tree05ac8c723d0ade0d8a6fba517fc12f66d4fe9a84 /channels
parent7bbc4831fcf98d734146417f392bed377c5db853 (diff)
Merged revisions 187488 via svnmerge from
https://origsvn.digium.com/svn/asterisk/trunk ................ r187488 | mmichelson | 2009-04-09 13:58:41 -0500 (Thu, 09 Apr 2009) | 24 lines Merged revisions 187484 via svnmerge from https://origsvn.digium.com/svn/asterisk/branches/1.4 ........ r187484 | mmichelson | 2009-04-09 13:51:20 -0500 (Thu, 09 Apr 2009) | 18 lines Handle a SIP race condition (reinvite before an ACK) properly. RFC 5047 explains the proper course of action to take if a reINVITE is received before the ACK from a previous invite transaction. What we are to do is to treat the reINVITE as if it were both an ACK and a reINVITE and process it normally. Later, when we receive the ACK we had been expecting, we will ignore it since its CSeq is less than the current iseqno of the sip_pvt representing this dialog. (closes issue #13849) Reported by: klaus3000 Patches: 13849_v2.patch uploaded by mmichelson (license 60) Tested by: mmichelson, klaus3000 ........ ................ git-svn-id: http://svn.digium.com/svn/asterisk/branches/1.6.1@187495 f38db490-d61c-443f-a65b-d21fe96a405b
Diffstat (limited to 'channels')
-rw-r--r--channels/chan_sip.c25
1 files changed, 19 insertions, 6 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 0e36de382..8ac699641 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -17911,12 +17911,25 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
}
if (!req->ignore && p->pendinginvite) {
- /* We already have a pending invite. Sorry. You are on hold. */
- p->glareinvite = seqno; /* must hold on to this seqno to process ack and retransmit correctly */
- transmit_response_reliable(p, "491 Request Pending", req);
- ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
- /* Don't destroy dialog here */
- return 0;
+ if (!ast_test_flag(&p->flags[0], SIP_OUTGOING) && ast_test_flag(&p->flags[1], SIP_PAGE2_DIALOG_ESTABLISHED)) {
+ /* We have received a reINVITE on an incoming call to which we have sent a 200 OK but not yet received
+ * an ACK. According to RFC 5407, Section 3.1.4, the proper way to handle this race condition is to accept
+ * the reINVITE since we have established a dialog.
+ */
+
+ /* Note that this will both clear the pendinginvite flag and cancel the
+ * retransmission of the 200 OK. Basically, we're accepting this reINVITE as both an ACK
+ * and a reINVITE in one request.
+ */
+ __sip_ack(p, p->lastinvite, 1, 0);
+ } else {
+ /* We already have a pending invite. Sorry. You are on hold. */
+ p->glareinvite = seqno;
+ transmit_response_reliable(p, "491 Request Pending", req);
+ ast_debug(1, "Got INVITE on call where we already have pending INVITE, deferring that - %s\n", p->callid);
+ /* Don't destroy dialog here */
+ return 0;
+ }
}
p_replaces = get_header(req, "Replaces");