Index: channels/chan_sip.c =================================================================== --- channels/chan_sip.c (revision 41987) +++ channels/chan_sip.c (working copy) @@ -3221,18 +3221,14 @@ /* stop retransmitting an INVITE that has not received a response */ __sip_pretend_ack(p); - /* if we can't send right now, mark it pending */ - if (!ast_test_flag(&p->flags[0], SIP_CAN_BYE)) { - ast_set_flag(&p->flags[0], SIP_PENDINGBYE); - } else { - /* Send a new request: CANCEL */ - transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); - /* 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. */ - ast_clear_flag(&locflags, SIP_NEEDDESTROY); + /* Send a new request: CANCEL */ + transmit_request_with_auth(p, SIP_CANCEL, p->ocseq, XMIT_RELIABLE, FALSE); + /* 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. */ + ast_clear_flag(&locflags, SIP_NEEDDESTROY); - sip_scheddestroy(p, SIP_TRANS_TIMEOUT); - } + sip_scheddestroy(p, SIP_TRANS_TIMEOUT); + if ( p->initid != -1 ) { /* channel still up - reverse dec of inUse counter only if the channel is not auto-congested */ @@ -11235,10 +11231,18 @@ (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 (!ast_test_flag(req, SIP_PKT_IGNORE)) sip_cancel_destroy(p); + if (!ast_strlen_zero(p->theirtag) && !p->pendinginvite) + ast_set_flag(&p->flags[0], SIP_CAN_BYE); check_pendings(p); break; case 180: /* 180 Ringing */ @@ -11257,7 +11261,8 @@ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } - ast_set_flag(&p->flags[0], SIP_CAN_BYE); + if (!ast_strlen_zero(p->theirtag) && !p->pendinginvite) + ast_set_flag(&p->flags[0], SIP_CAN_BYE); check_pendings(p); break; case 183: /* Session progress */ @@ -11271,7 +11276,8 @@ ast_queue_control(p->owner, AST_CONTROL_PROGRESS); } } - ast_set_flag(&p->flags[0], SIP_CAN_BYE); + if (!ast_strlen_zero(p->theirtag) && !p->pendinginvite) + ast_set_flag(&p->flags[0], SIP_CAN_BYE); check_pendings(p); break; case 200: /* 200 OK on invite - someone's answering our call */