From: Mark Michelson Date: Wed, 6 Jun 2012 19:18:20 +0000 (+0000) Subject: Fix a specific scenario where ACKs are not matched. X-Git-Tag: 10.6.0-rc1~6 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e877fe2ca1cb5361e3e06f9ec73c20e2c38e4aa3;p=thirdparty%2Fasterisk.git Fix a specific scenario where ACKs are not matched. If a dialog-starting INVITE contains a to-tag, then Asterisk will respond with a 481. In this case, the resulting incoming ACK would not be matched, so Asterisk would continue retransmitting the 481 until the transaction times out. There were two issues. Asterisk, upon creating a sip_pvt would generate a local tag. However, when the time came to transmit the 481, since there was a to-tag in the INVITE, Asterisk would place this original to-tag in the 481 response. When the ACK came in, Asterisk would attempt to match the to-tag in the ACK to the generated local tag. Unfortunately, Asterisk never actually transmitted a response with the generated local tag, so the to-tag in the ACK would not match. The other problem was that when the 481 was sent, nothing was set on the sip_pvt to indicate what CSeq is expected in the ACK. To fix the first problem, we zero out the to-tag seen in the incoming INVITE. This way, Asterisk, when time to send a response, will send its generated local tag instead. To fix the second problem, we set the sip_pvt's pendinginvite to the CSeq of the INVITE when we send a 481. (closes issue ASTERISK-19892) Reported by Mark Michelson ........ Merged revisions 368625 from http://svn.asterisk.org/svn/asterisk/branches/1.8 git-svn-id: https://origsvn.digium.com/svn/asterisk/branches/10@368629 65c4cc65-6c06-0410-ace0-fbb531ad65f3 --- diff --git a/channels/chan_sip.c b/channels/chan_sip.c index e40456a400..8f02a266b4 100644 --- a/channels/chan_sip.c +++ b/channels/chan_sip.c @@ -26089,6 +26089,15 @@ static int handle_incoming(struct sip_pvt *p, struct sip_request *req, struct as if (!p->initreq.headers && req->has_to_tag) { /* If this is a first request and it got a to-tag, it is not for us */ if (!req->ignore && req->method == SIP_INVITE) { + /* We will be subversive here. By blanking out the to-tag of the request, + * it will cause us to attach our own generated to-tag instead. This way, + * when we receive an ACK, the ACK will contain the to-tag we generated, + * resulting in a proper to-tag match. + */ + char *to_header = (char *) sip_get_header(req, "To"); + char *tag = strstr(to_header, ";tag="); + *tag = '\0'; + p->pendinginvite = p->icseq; transmit_response_reliable(p, "481 Call/Transaction Does Not Exist", req); /* Will cease to exist after ACK */ return res;