Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 44332) +++ channels/chan_sip.c (working copy) @@ -2475,15 +2475,16 @@ /* are we allowed to send CANCEL yet? if not, mark it pending */ - if (!ast_test_flag(p, SIP_CAN_BYE)) { +/* if (!ast_test_flag(p, SIP_CAN_BYE)) { ast_set_flag(p, SIP_PENDINGBYE); +*/ /* Do we need a timer here if we don't hear from them at all? */ - } else { +/* } else { */ /* Send a new request: CANCEL */ transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, 1, 0); /* Actually don't destroy us yet, wait for the 487 on our original INVITE, but do set an autodestruct just in case we never get it. */ - } +/* } */ if ( p->initid != -1 ) { /* channel still up - reverse dec of inUse counter only if the channel is not auto-congested */ @@ -9616,6 +9617,12 @@ (resp != 183)) resp = 183; + /* Section 12.1 of RFC3261 says a dialog isn't established on a provisional, 1xx, response + unless there is a tag in the To field, aka an "early dialog". Additionally, section 15 + states that a BYE _CANNOT_ be sent in response to an INVITE unless the INVITE has been + ACKed, not pending. If there is no To tag or the INVITE has not been ACKed, there is no + dialog, and therefore a BYE _cannot_ be sent, a CANCEL _must_ be sent instead. + */ switch (resp) { case 100: /* Trying */ if (!ignore) @@ -9637,7 +9644,8 @@ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } - ast_set_flag(p, SIP_CAN_BYE); + if (!ast_strlen_zero(p->theirtag) && !p->pendinginvite) + ast_set_flag(p, SIP_CAN_BYE); check_pendings(p); break; case 183: /* Session progress */ @@ -9651,7 +9659,8 @@ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } - ast_set_flag(p, SIP_CAN_BYE); + if (!ast_strlen_zero(p->theirtag) && !p->pendinginvite) + ast_set_flag(p, SIP_CAN_BYE); check_pendings(p); break; case 200: /* 200 OK on invite - someone's answering our call */