From b4549841bb9e71c7856e145046795f1dd010aeb3 Mon Sep 17 00:00:00 2001 From: Benny Prijono Date: Tue, 19 Nov 2013 10:18:17 +0000 Subject: Fixed #1712: Must not send BYE before ACK is received git-svn-id: http://svn.pjsip.org/repos/pjproject/trunk@4653 74dad513-b988-da41-8d7b-12977e46ad98 --- pjsip/include/pjsip-ua/sip_inv.h | 1 + pjsip/src/pjsip-ua/sip_inv.c | 59 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 60 insertions(+) (limited to 'pjsip') diff --git a/pjsip/include/pjsip-ua/sip_inv.h b/pjsip/include/pjsip-ua/sip_inv.h index 5782cf92..bbf2a7b8 100644 --- a/pjsip/include/pjsip-ua/sip_inv.h +++ b/pjsip/include/pjsip-ua/sip_inv.h @@ -393,6 +393,7 @@ struct pjsip_inv_session pjsip_inv_state state; /**< Invite sess state. */ pj_bool_t cancelling; /**< CANCEL requested */ pj_bool_t pending_cancel; /**< Wait to send CANCEL*/ + pjsip_tx_data *pending_bye; /**< BYE to send later */ pjsip_status_code cause; /**< Disconnect cause. */ pj_str_t cause_text; /**< Cause text. */ pj_bool_t notify; /**< Internal. */ diff --git a/pjsip/src/pjsip-ua/sip_inv.c b/pjsip/src/pjsip-ua/sip_inv.c index e73049bf..74ef08ac 100644 --- a/pjsip/src/pjsip-ua/sip_inv.c +++ b/pjsip/src/pjsip-ua/sip_inv.c @@ -263,6 +263,10 @@ void inv_set_state(pjsip_inv_session *inv, pjsip_inv_state state, pjsip_tx_data_dec_ref(inv->invite_req); inv->invite_req = NULL; } + if (inv->pending_bye) { + pjsip_tx_data_dec_ref(inv->pending_bye); + inv->pending_bye = NULL; + } pjsip_100rel_end_session(inv); pjsip_timer_end_session(inv); pjsip_dlg_dec_session(inv->dlg, &mod_inv.mod); @@ -355,6 +359,26 @@ static const pjmedia_sdp_session *inv_has_pending_answer(pjsip_inv_session *inv, return sdp; } +/* Process pending disconnection + * http://trac.pjsip.org/repos/ticket/1712 + */ +static void inv_perform_pending_bye(pjsip_inv_session *inv) +{ + if (inv->pending_bye) { + pjsip_tx_data *bye = inv->pending_bye; + pj_status_t status; + + PJ_LOG(4,(inv->dlg->obj_name, "Sending pending BYE")); + + inv->pending_bye = NULL; + status = pjsip_inv_send_msg(inv, bye); + + if (status != PJ_SUCCESS) { + PJ_PERROR(1,(inv->dlg->obj_name, status, + "Failed sending pending BYE")); + } + } +} /* * Send ACK for 2xx response. @@ -528,6 +552,14 @@ static pj_bool_t mod_inv_on_rx_request(pjsip_rx_data *rdata) PJSIP_EVENT_INIT_RX_MSG(event, rdata); inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, &event); + + /* Send pending BYE if any: + * http://trac.pjsip.org/repos/ticket/1712 + * Do this after setting the state to CONFIRMED, so that we + * have consistent CONFIRMED state between caller and callee. + */ + if (inv->pending_bye) + inv_perform_pending_bye(inv); } } @@ -2889,6 +2921,23 @@ PJ_DEF(pj_status_t) pjsip_inv_send_msg( pjsip_inv_session *inv, goto on_error; } + /* Don't send BYE before ACK is received + * http://trac.pjsip.org/repos/ticket/1712 + */ + if (tdata->msg->line.req.method.id == PJSIP_BYE_METHOD && + inv->role == PJSIP_ROLE_UAS && + inv->state == PJSIP_INV_STATE_CONNECTING) + { + if (inv->pending_bye) + pjsip_tx_data_dec_ref(inv->pending_bye); + + inv->pending_bye = tdata; + PJ_LOG(4, (inv->obj_name, "Delaying BYE request until " + "ACK is received")); + pjsip_dlg_dec_lock(inv->dlg); + goto on_return; + } + /* Associate our data in outgoing invite transaction */ tsx_inv_data = PJ_POOL_ZALLOC_T(inv->pool, struct tsx_inv_data); tsx_inv_data->inv = inv; @@ -2924,6 +2973,7 @@ PJ_DEF(pj_status_t) pjsip_inv_send_msg( pjsip_inv_session *inv, } /* Done */ +on_return: pj_log_pop_indent(); return PJ_SUCCESS; @@ -4091,6 +4141,15 @@ static void inv_on_state_connecting( pjsip_inv_session *inv, pjsip_event *e) } inv_set_state(inv, PJSIP_INV_STATE_CONFIRMED, e); + + /* Send pending BYE if any: + * http://trac.pjsip.org/repos/ticket/1712 + * Do this after setting the state to CONFIRMED, so that we + * have consistent CONFIRMED state between caller and callee. + */ + if (inv->pending_bye) + inv_perform_pending_bye(inv); + } break; -- cgit v1.2.3