mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	res_pjsip_session: Add cleanup to ast_sip_session_terminate
If you use ast_request to create a PJSIP channel but then hang it up without causing a transaction to be sent, the session will never be destroyed. This is due ot the fact that it's pjproject that triggers the session cleanup when the transaction ends. app_chanisavail was doing this to get more granular channel state and it's also possible for this to happen via ARI. * ast_sip_session_terminate was modified to explicitly call the cleanup tasks and unreference session if the invite state is NULL AND invite_tsx is NULL (meaning we never sent a transaction). * chan_pjsip/hangup was modified to bump session before it calls ast_sip_session_terminate to insure that session stays valid while it does its own cleanup. * Added test events to session_destructor for a future testsuite test. ASTERISK-26908 #close Reported-by: Richard Mudgett Change-Id: I52daf6f757184e5544c261f64f6fe9602c4680a9
This commit is contained in:
		| @@ -1302,9 +1302,19 @@ static void session_destructor(void *obj) | ||||
| 	struct ast_sip_session *session = obj; | ||||
| 	struct ast_sip_session_supplement *supplement; | ||||
| 	struct ast_sip_session_delayed_request *delay; | ||||
| 	const char *endpoint_name = session->endpoint ? | ||||
| 		ast_sorcery_object_get_id(session->endpoint) : "<none>"; | ||||
|  | ||||
| 	ast_debug(3, "Destroying SIP session with endpoint %s\n", | ||||
| 		session->endpoint ? ast_sorcery_object_get_id(session->endpoint) : "<none>"); | ||||
| 	ast_debug(3, "Destroying SIP session with endpoint %s\n", endpoint_name); | ||||
|  | ||||
| 	ast_test_suite_event_notify("SESSION_DESTROYING", | ||||
| 		"Endpoint: %s\r\n" | ||||
| 		"AOR: %s\r\n" | ||||
| 		"Contact: %s" | ||||
| 		, endpoint_name | ||||
| 		, session->aor ? ast_sorcery_object_get_id(session->aor) : "<none>" | ||||
| 		, session->contact ? ast_sorcery_object_get_id(session->contact) : "<none>" | ||||
| 		); | ||||
|  | ||||
| 	while ((supplement = AST_LIST_REMOVE_HEAD(&session->supplements, next))) { | ||||
| 		if (supplement->session_destroy) { | ||||
| @@ -1333,6 +1343,8 @@ static void session_destructor(void *obj) | ||||
| 	if (session->inv_session) { | ||||
| 		pjsip_dlg_dec_session(session->inv_session->dlg, &session_module); | ||||
| 	} | ||||
|  | ||||
| 	ast_test_suite_event_notify("SESSION_DESTROYED", "Endpoint: %s", endpoint_name); | ||||
| } | ||||
|  | ||||
| static int add_supplements(struct ast_sip_session *session) | ||||
| @@ -1793,6 +1805,9 @@ struct ast_sip_session *ast_sip_session_create_outgoing(struct ast_sip_endpoint | ||||
| 	return ret_session; | ||||
| } | ||||
|  | ||||
| static int session_end(void *vsession); | ||||
| static int session_end_completion(void *vsession); | ||||
|  | ||||
| void ast_sip_session_terminate(struct ast_sip_session *session, int response) | ||||
| { | ||||
| 	pj_status_t status; | ||||
| @@ -1809,7 +1824,25 @@ void ast_sip_session_terminate(struct ast_sip_session *session, int response) | ||||
|  | ||||
| 	switch (session->inv_session->state) { | ||||
| 	case PJSIP_INV_STATE_NULL: | ||||
| 		pjsip_inv_terminate(session->inv_session, response, PJ_TRUE); | ||||
| 		if (!session->inv_session->invite_tsx) { | ||||
| 			/* | ||||
| 			 * Normally, it's pjproject's transaction cleanup that ultimately causes the | ||||
| 			 * final session reference to be released but if both STATE and invite_tsx are NULL, | ||||
| 			 * we never created a transaction in the first place.  In this case, we need to | ||||
| 			 * do the cleanup ourselves. | ||||
| 			 */ | ||||
| 			/* Transfer the inv_session session reference to the session_end_task */ | ||||
| 			session->inv_session->mod_data[session_module.id] = NULL; | ||||
| 			pjsip_inv_terminate(session->inv_session, response, PJ_TRUE); | ||||
| 			session_end(session); | ||||
| 			/* | ||||
| 			 * session_end_completion will cleanup the final session reference unless | ||||
| 			 * ast_sip_session_terminate's caller is holding one. | ||||
| 			 */ | ||||
| 			session_end_completion(session); | ||||
| 		} else { | ||||
| 			pjsip_inv_terminate(session->inv_session, response, PJ_TRUE); | ||||
| 		} | ||||
| 		break; | ||||
| 	case PJSIP_INV_STATE_CONFIRMED: | ||||
| 		if (session->inv_session->invite_tsx) { | ||||
|   | ||||
		Reference in New Issue
	
	Block a user