Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 62624) +++ channels/chan_sip.c (working copy) @@ -3375,6 +3375,7 @@ INVITE, but do set an autodestruct just in case we never get it. */ needdestroy = 0; sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); + p->invitestate = INV_CANCELLED; } if ( p->initid != -1 ) { /* channel still up - reverse dec of inUse counter @@ -3387,6 +3388,7 @@ transmit_response_reliable(p, res, &p->initreq); else transmit_response_reliable(p, "603 Declined", &p->initreq); + p->invitestate = INV_TERMINATED; } } else { /* Call is in UP state, send BYE */ if (!p->pendinginvite) { @@ -14114,7 +14116,18 @@ check_via(p, req); sip_alreadygone(p); - p->invitestate = INV_CANCELLED; + /* At this point, we could have cancelled the invite at the same time + as the other side sends a CANCEL. Our final reply with error code + might not have been received by the other side before the CANCEL + was sent, so let's just give up retransmissions and waiting for + ACK on our error code. The call is hanging up any way. */ + if (p->invitestate == INV_TERMINATED) { + /* This call is already either in UP state or dead */ + /* Stop any retransmissions that is going on at this time */ + __sip_pretend_ack(p); + }; + if (p->invitestate != INV_TERMINATED) + p->invitestate = INV_CANCELLED; if (p->owner && p->owner->_state == AST_STATE_UP) { /* This call is up, cancel is ignored, we need a bye */ @@ -14129,7 +14142,7 @@ ast_queue_hangup(p->owner); else sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); - if (p->initreq.len > 0) { + if (p->initreq.len > 0) { /* This is a new dialog */ transmit_response_reliable(p, "487 Request Terminated", &p->initreq); transmit_response(p, "200 OK", req); return 1;