mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
pjsip: Match lifetime of INVITE session to our session.
In some circumstances it was possible for an INVITE session to be destroyed while we were still using it. This occurred due to the reference on the INVITE session being released internally as a result of its state changing to DISCONNECTED. This change adds a reference to the INVITE session which is released when our own session is destroyed, ensuring that the INVITE session remains valid for the lifetime of our session. ASTERISK-29022 Change-Id: I300c6d9005ff0e6efbe1132daefc7e47ca6228c9
This commit is contained in:
committed by
Joshua Colp
parent
90fd1fd96a
commit
6475fe3dd7
@@ -2997,7 +2997,16 @@ static void session_destructor(void *obj)
|
||||
ast_dsp_free(session->dsp);
|
||||
|
||||
if (session->inv_session) {
|
||||
pjsip_dlg_dec_session(session->inv_session->dlg, &session_module);
|
||||
struct pjsip_dialog *dlg = session->inv_session->dlg;
|
||||
|
||||
/* The INVITE session uses the dialog pool for memory, so we need to
|
||||
* decrement its reference first before that of the dialog.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||
pjsip_inv_dec_ref(session->inv_session);
|
||||
#endif
|
||||
pjsip_dlg_dec_session(dlg, &session_module);
|
||||
}
|
||||
|
||||
ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name);
|
||||
@@ -3105,6 +3114,24 @@ struct ast_sip_session *ast_sip_session_alloc(struct ast_sip_endpoint *endpoint,
|
||||
}
|
||||
ast_sip_dialog_set_serializer(inv_session->dlg, session->serializer);
|
||||
ast_sip_dialog_set_endpoint(inv_session->dlg, endpoint);
|
||||
|
||||
/* When a PJSIP INVITE session is created it is created with a reference
|
||||
* count of 1, with that reference being managed by the underlying state
|
||||
* of the INVITE session itself. When the INVITE session transitions to
|
||||
* a DISCONNECTED state that reference is released. This means we can not
|
||||
* rely on that reference to ensure the INVITE session remains for the
|
||||
* lifetime of our session. To ensure it does we add our own reference
|
||||
* and release it when our own session goes away, ensuring that the INVITE
|
||||
* session remains for the lifetime of session.
|
||||
*/
|
||||
|
||||
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||
if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
|
||||
ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
|
||||
return NULL;
|
||||
}
|
||||
#endif
|
||||
|
||||
pjsip_dlg_inc_session(inv_session->dlg, &session_module);
|
||||
inv_session->mod_data[session_module.id] = ao2_bump(session);
|
||||
session->contact = ao2_bump(contact);
|
||||
@@ -3956,9 +3983,6 @@ static int new_invite(struct new_invite *invite)
|
||||
ast_sip_session_get_name(invite->session),
|
||||
invite->session->inv_session->cause,
|
||||
pjsip_get_status_text(invite->session->inv_session->cause)->ptr);
|
||||
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||
pjsip_inv_dec_ref(invite->session->inv_session);
|
||||
#endif
|
||||
SCOPE_EXIT_RTN_VALUE(-1);
|
||||
}
|
||||
|
||||
@@ -4076,9 +4100,6 @@ static int new_invite(struct new_invite *invite)
|
||||
handle_incoming_request(invite->session, invite->rdata);
|
||||
|
||||
end:
|
||||
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||
pjsip_inv_dec_ref(invite->session->inv_session);
|
||||
#endif
|
||||
SCOPE_EXIT_RTN_VALUE(0, "%s\n", ast_sip_session_get_name(invite->session));
|
||||
}
|
||||
|
||||
@@ -4124,19 +4145,6 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
|
||||
* process handling has successfully completed.
|
||||
*/
|
||||
|
||||
|
||||
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||
if (pjsip_inv_add_ref(inv_session) != PJ_SUCCESS) {
|
||||
ast_log(LOG_ERROR, "Can't increase the session reference counter\n");
|
||||
/* Dialog's lock and a reference are removed in new_invite_initial_answer */
|
||||
if (!new_invite_initial_answer(inv_session, rdata, 500, 500, PJ_FALSE)) {
|
||||
/* Terminate the session if it wasn't done in the answer */
|
||||
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
|
||||
}
|
||||
SCOPE_EXIT_RTN("Couldn't add invite session reference\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
session = ast_sip_session_alloc(endpoint, NULL, inv_session, rdata);
|
||||
if (!session) {
|
||||
/* Dialog's lock and reference are removed in new_invite_initial_answer */
|
||||
@@ -4144,9 +4152,6 @@ static void handle_new_invite_request(pjsip_rx_data *rdata)
|
||||
/* Terminate the session if it wasn't done in the answer */
|
||||
pjsip_inv_terminate(inv_session, 500, PJ_FALSE);
|
||||
}
|
||||
#ifdef HAVE_PJSIP_INV_SESSION_REF
|
||||
pjsip_inv_dec_ref(inv_session);
|
||||
#endif
|
||||
SCOPE_EXIT_RTN("Couldn't create session\n");
|
||||
}
|
||||
session->call_direction = AST_SIP_SESSION_INCOMING_CALL;
|
||||
|
Reference in New Issue
Block a user