mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 02:37:10 +00:00 
			
		
		
		
	chan_sip: Add precautionary p->owner checks.
* Add precautionary p->owner checks in sip_hangup(), get_refer_info(),
get_also_info(), and interpret_t38_parameters().
* Simplify some tangled logic in get_refer_info(), get_also_info(), and
add_rpid().
* Removed some dead code in handle_request_invite().
(closes issue ASTERISK-23323)
Reported by: Walter Doekes
Patches:
      issueA23323-more_p_owner_checks-1.8.x.patch (license #5674) uploaded by wdoekes (modified)
      issueA23323-more_p_owner_checks-11.x.patch (license #5674) uploaded by wdoekes (modified)
      issueA23323-more_p_owner_checks-12.x.patch (license #5674) uploaded by wdoekes (modified)
      issueA23323-more_p_owner_checks-trunk.patch (license #5674) uploaded by wdoekes (modified)
........
Merged revisions 409207 from http://svn.asterisk.org/svn/asterisk/branches/1.8
........
Merged revisions 409255 from http://svn.asterisk.org/svn/asterisk/branches/11
........
Merged revisions 409256 from http://svn.asterisk.org/svn/asterisk/branches/12
git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@409257 65c4cc65-6c06-0410-ace0-fbb531ad65f3
			
			
This commit is contained in:
		| @@ -7167,10 +7167,12 @@ static int sip_hangup(struct ast_channel *ast) | ||||
| 		ast_debug(4, "SIP Transfer: Not hanging up right now... Rescheduling hangup for %s.\n", p->callid); | ||||
| 		sip_scheddestroy(p, DEFAULT_TRANS_TIMEOUT); | ||||
| 		ast_clear_flag(&p->flags[0], SIP_DEFER_BYE_ON_TRANSFER);	/* Really hang up next time */ | ||||
| 		ast_channel_tech_pvt_set(p->owner, dialog_unref(ast_channel_tech_pvt(p->owner), "unref p->owner->tech_pvt")); | ||||
| 		sip_pvt_lock(p); | ||||
| 		sip_set_owner(p, NULL); /* Owner will be gone after we return, so take it away */ | ||||
| 		sip_pvt_unlock(p); | ||||
| 		if (p->owner) { | ||||
| 			ast_channel_tech_pvt_set(p->owner, dialog_unref(ast_channel_tech_pvt(p->owner), "unref p->owner->tech_pvt")); | ||||
| 			sip_pvt_lock(p); | ||||
| 			sip_set_owner(p, NULL); /* Owner will be gone after we return, so take it away */ | ||||
| 			sip_pvt_unlock(p); | ||||
| 		} | ||||
| 		ast_module_unref(ast_module_info->self); | ||||
| 		return 0; | ||||
| 	} | ||||
| @@ -7199,7 +7201,7 @@ static int sip_hangup(struct ast_channel *ast) | ||||
| 
 | ||||
| 	stop_media_flows(p); /* Immediately stop RTP, VRTP and UDPTL as applicable */ | ||||
| 
 | ||||
| 	append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", p->owner ? ast_cause2str(p->hangupcause) : "Unknown"); | ||||
| 	append_history(p, needcancel ? "Cancel" : "Hangup", "Cause %s", ast_cause2str(p->hangupcause)); | ||||
| 
 | ||||
| 	/* Disconnect */ | ||||
| 	disable_dsp_detect(p); | ||||
| @@ -7729,7 +7731,9 @@ static int interpret_t38_parameters(struct sip_pvt *p, const struct ast_control_ | ||||
| 			AST_SCHED_DEL_UNREF(sched, p->t38id, dialog_unref(p, "when you delete the t38id sched, you should dec the refcount for the stored dialog ptr")); | ||||
| 			parameters.max_ifp = ast_udptl_get_far_max_ifp(p->udptl); | ||||
| 			parameters.request_response = AST_T38_REQUEST_NEGOTIATE; | ||||
| 			ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); | ||||
| 			if (p->owner) { | ||||
| 				ast_queue_control_data(p->owner, AST_CONTROL_T38_PARAMETERS, ¶meters, sizeof(parameters)); | ||||
| 			} | ||||
| 			/* we need to return a positive value here, so that applications that
 | ||||
| 			 * send this request can determine conclusively whether it was accepted or not... | ||||
| 			 * older versions of chan_sip would just silently accept it and return zero. | ||||
| @@ -12634,9 +12638,9 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p) | ||||
| { | ||||
| 	struct ast_str *tmp = ast_str_alloca(256); | ||||
| 	char tmp2[256]; | ||||
| 	char *lid_num = NULL; | ||||
| 	char *lid_name = NULL; | ||||
| 	int lid_pres = AST_PRES_NUMBER_NOT_AVAILABLE; | ||||
| 	char *lid_num; | ||||
| 	char *lid_name; | ||||
| 	int lid_pres; | ||||
| 	const char *fromdomain; | ||||
| 	const char *privacy = NULL; | ||||
| 	const char *screen = NULL; | ||||
| @@ -12647,22 +12651,20 @@ static int add_rpid(struct sip_request *req, struct sip_pvt *p) | ||||
| 		return 0; | ||||
| 	} | ||||
| 
 | ||||
| 	if (p->owner) { | ||||
| 		connected_id = ast_channel_connected_effective_id(p->owner); | ||||
| 
 | ||||
| 		if (connected_id.number.valid) { | ||||
| 			lid_num = connected_id.number.str; | ||||
| 		} | ||||
| 		if (connected_id.name.valid) { | ||||
| 			lid_name = connected_id.name.str; | ||||
| 		} | ||||
| 		lid_pres = ast_party_id_presentation(&connected_id); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ast_strlen_zero(lid_num)) | ||||
| 	if (!p->owner) { | ||||
| 		return 0; | ||||
| 	if (ast_strlen_zero(lid_name)) | ||||
| 	} | ||||
| 	connected_id = ast_channel_connected_effective_id(p->owner); | ||||
| 	lid_num = S_COR(connected_id.number.valid, connected_id.number.str, NULL); | ||||
| 	if (!lid_num) { | ||||
| 		return 0; | ||||
| 	} | ||||
| 	lid_name = S_COR(connected_id.name.valid, connected_id.name.str, NULL); | ||||
| 	if (!lid_name) { | ||||
| 		lid_name = lid_num; | ||||
| 	} | ||||
| 	lid_pres = ast_party_id_presentation(&connected_id); | ||||
| 
 | ||||
| 	fromdomain = S_OR(p->fromdomain, ast_sockaddr_stringify_host_remote(&p->ourip)); | ||||
| 
 | ||||
| 	lid_num = ast_uri_encode(lid_num, tmp2, sizeof(tmp2), ast_uri_sip_user); | ||||
| @@ -18124,13 +18126,15 @@ static int get_refer_info(struct sip_pvt *transferer, struct sip_request *outgoi | ||||
| 	} | ||||
| 
 | ||||
| 	/* Determine transfer context */ | ||||
| 	if (transferer->owner)	/* Mimic behaviour in res_features.c */ | ||||
| 	if (transferer->owner) { | ||||
| 		/* By default, use the context in the channel sending the REFER */ | ||||
| 		transfer_context = pbx_builtin_getvar_helper(transferer->owner, "TRANSFER_CONTEXT"); | ||||
| 
 | ||||
| 	/* By default, use the context in the channel sending the REFER */ | ||||
| 		if (ast_strlen_zero(transfer_context)) { | ||||
| 			transfer_context = ast_channel_macrocontext(transferer->owner); | ||||
| 		} | ||||
| 	} | ||||
| 	if (ast_strlen_zero(transfer_context)) { | ||||
| 		transfer_context = S_OR(ast_channel_macrocontext(transferer->owner), | ||||
| 					S_OR(transferer->context, sip_cfg.default_context)); | ||||
| 		transfer_context = S_OR(transferer->context, sip_cfg.default_context); | ||||
| 	} | ||||
| 
 | ||||
| 	ast_string_field_set(refer, refer_to_context, transfer_context); | ||||
| @@ -18184,14 +18188,18 @@ static int get_also_info(struct sip_pvt *p, struct sip_request *oreq) | ||||
| 	if (sip_debug_test_pvt(p)) | ||||
| 		ast_verbose("Looking for %s in %s\n", c, p->context); | ||||
| 
 | ||||
| 	if (p->owner)	/* Mimic behaviour in res_features.c */ | ||||
| 	/* Determine transfer context */ | ||||
| 	if (p->owner) { | ||||
| 		/* By default, use the context in the channel sending the REFER */ | ||||
| 		transfer_context = pbx_builtin_getvar_helper(p->owner, "TRANSFER_CONTEXT"); | ||||
| 
 | ||||
| 	/* By default, use the context in the channel sending the REFER */ | ||||
| 	if (ast_strlen_zero(transfer_context)) { | ||||
| 		transfer_context = S_OR(ast_channel_macrocontext(p->owner), | ||||
| 					S_OR(p->context, sip_cfg.default_context)); | ||||
| 		if (ast_strlen_zero(transfer_context)) { | ||||
| 			transfer_context = ast_channel_macrocontext(p->owner); | ||||
| 		} | ||||
| 	} | ||||
| 	if (ast_strlen_zero(transfer_context)) { | ||||
| 		transfer_context = S_OR(p->context, sip_cfg.default_context); | ||||
| 	} | ||||
| 
 | ||||
| 	if (ast_exists_extension(NULL, transfer_context, c, 1, NULL)) { | ||||
| 		/* This is a blind transfer */ | ||||
| 		ast_debug(1, "SIP Bye-also transfer to Extension %s@%s \n", c, transfer_context); | ||||
| @@ -25397,12 +25405,6 @@ static int handle_request_invite(struct sip_pvt *p, struct sip_request *req, str | ||||
| 			ast_debug(2, "No SDP in Invite, third party call control\n"); | ||||
| 		} | ||||
| 
 | ||||
| 		/* Queue NULL frame to prod ast_rtp_bridge if appropriate */ | ||||
| 		/* This seems redundant ... see !p-owner above */ | ||||
| 		if (p->owner) | ||||
| 			ast_queue_frame(p->owner, &ast_null_frame); | ||||
| 
 | ||||
| 
 | ||||
| 		/* Initialize the context if it hasn't been already */ | ||||
| 		if (ast_strlen_zero(p->context)) | ||||
| 			ast_string_field_set(p, context, sip_cfg.default_context); | ||||
|   | ||||
		Reference in New Issue
	
	Block a user