]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
Fix broken reinvite glare scenario.
authorMark Michelson <mmichelson@digium.com>
Mon, 14 May 2012 19:10:20 +0000 (19:10 +0000)
committerMark Michelson <mmichelson@digium.com>
Mon, 14 May 2012 19:10:20 +0000 (19:10 +0000)
To make a long story short, reinvite glares were broken
because Asterisk would invert the To and From headers
when ACKing a 491 response.

The reason was because the initreq of the dialog was being
changed to the incoming glared reinvite instead of being
set to the outgoing glared reinvite. This change has three
parts

* In handle_incoming, we never will reject an ACK because it
has a to-tag present, even if we think the request may be out
of dialog.
* In handle_request_invite, we do not change the initreq when
receiving a reinvite to which we will respond with a 491.
* In handle_request_invite, several superflous settings up
pendinginvite have been removed since this is dones automatically
by transmit_response_reliable

Review: https://reviewboard.asterisk.org/r/1911

git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/1.8@366389 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c

index 2494d7a67722e9c7ca2448e6b548f513c46e5555..8733f2b9b9725ab9d476a3764ac2c6707f42df47 100644 (file)
@@ -22354,9 +22354,7 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                                }
                        }
                        transmit_response_reliable(p, "491 Request Pending", req);
-                       p->pendinginvite = seqno;
                        check_via(p, req);
-                       copy_request(&p->initreq, 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 */
                        res = 0;
@@ -22376,7 +22374,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                if (p->owner) {
                        ast_debug(3, "INVITE w Replaces on existing call? Refusing action. [%s]\n", p->callid);
                        transmit_response_reliable(p, "400 Bad request", req);  /* The best way to not not accept the transfer */
-                       p->pendinginvite = seqno;
                        check_via(p, req);
                        copy_request(&p->initreq, req);
                        /* Do not destroy existing call */
@@ -22395,7 +22392,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                        append_history(p, "Xfer", "INVITE/Replace Failed. Out of memory.");
                        sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
                        p->invitestate = INV_COMPLETED;
-                       p->pendinginvite = seqno;
                        check_via(p, req);
                        copy_request(&p->initreq, req);
                        res = -1;
@@ -22500,7 +22496,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, int
                        }
                        refer_locked = 0;
                        p->invitestate = INV_COMPLETED;
-                       p->pendinginvite = seqno;
                        check_via(p, req);
                        copy_request(&p->initreq, req);
                        res = -1;
@@ -25192,13 +25187,13 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as
                        if (!req->ignore && req->method == SIP_INVITE) {
                                transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req);
                                /* Will cease to exist after ACK */
+                               return res;
                        } else if (req->method != SIP_ACK) {
                                transmit_response(p, "481 Call/Transaction Does Not Exist", req);
                                sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT);
-                       } else {
-                               ast_debug(1, "Got ACK for unknown dialog... strange.\n");
+                               return res;
                        }
-                       return res;
+                       /* Otherwise, this is an ACK. It will always have a to-tag */
                }
        }