mirror of
				https://github.com/asterisk/asterisk.git
				synced 2025-10-31 10:47:18 +00:00 
			
		
		
		
	res_pjsip: add "via_addr", "via_port", "call_id" to contact
As res_pjsip_nat rewrites contact's address, only the last Via header can contain the source address of registered endpoint. Also Call-Id header may contain the source address of registered endpoint. Added "via_addr", "via_port", "call_id" to contact. Added new fields ViaAddress, CallID to AMI event ContactStatus. ASTERISK-26011 Change-Id: I36bcc0bf422b3e0623680152d80486aeafe4c576
This commit is contained in:
		
							
								
								
									
										6
									
								
								CHANGES
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								CHANGES
									
									
									
									
									
								
							| @@ -328,6 +328,12 @@ res_fax | ||||
|  | ||||
| res_pjsip | ||||
| ------------------ | ||||
|  * Added "via_addr", "via_port", "call_id" to contacts. | ||||
|    As res_pjsip_nat rewrites contact's address, only the last Via header | ||||
|    can contain the source address of registered endpoint. | ||||
|    Also Call-Id header may contain the source address of registered endpoint. | ||||
|    Added new fields ViaAddress,CallID to AMI event ContactStatus | ||||
|  | ||||
|  * Endpoint IP Access Controls | ||||
|    Added new configuration Endpoint options: | ||||
|     "acl" - list of IP ACL section names in acl.conf | ||||
|   | ||||
| @@ -0,0 +1,25 @@ | ||||
| """res_pjsip: add contact via_addr and callid | ||||
|  | ||||
| Revision ID: a845e4d8ade8 | ||||
| Revises: bca7113d796f | ||||
| Create Date: 2016-05-19 15:51:33.410852 | ||||
|  | ||||
| """ | ||||
|  | ||||
| # revision identifiers, used by Alembic. | ||||
| revision = 'a845e4d8ade8' | ||||
| down_revision = 'bca7113d796f' | ||||
|  | ||||
| from alembic import op | ||||
| import sqlalchemy as sa | ||||
|  | ||||
|  | ||||
| def upgrade(): | ||||
|     op.add_column('ps_contacts', sa.Column('via_addr', sa.String(40))) | ||||
|     op.add_column('ps_contacts', sa.Column('via_port', sa.Integer)) | ||||
|     op.add_column('ps_contacts', sa.Column('call_id', sa.String(255))) | ||||
|  | ||||
| def downgrade(): | ||||
|     op.drop_column('ps_contacts', 'via_addr') | ||||
|     op.drop_column('ps_contacts', 'via_port') | ||||
|     op.drop_column('ps_contacts', 'call_id') | ||||
| @@ -250,6 +250,12 @@ struct ast_sip_contact { | ||||
| 	struct ast_sip_endpoint *endpoint; | ||||
| 	/*! Asterisk Server name */ | ||||
| 	AST_STRING_FIELD_EXTENDED(reg_server); | ||||
| 	/*! IP-address of the Via header in REGISTER request */ | ||||
| 	AST_STRING_FIELD_EXTENDED(via_addr); | ||||
| 	/* Port of the Via header in REGISTER request */ | ||||
| 	int via_port; | ||||
| 	/*! Content of the Call-ID header in REGISTER request */ | ||||
| 	AST_STRING_FIELD_EXTENDED(call_id); | ||||
| }; | ||||
|  | ||||
| #define CONTACT_STATUS "contact_status" | ||||
| @@ -1093,6 +1099,7 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na | ||||
|  */ | ||||
| int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, | ||||
| 	struct timeval expiration_time, const char *path_info, const char *user_agent, | ||||
| 	const char *via_addr, int via_port, const char *call_id, | ||||
| 	struct ast_sip_endpoint *endpoint); | ||||
|  | ||||
| /*! | ||||
| @@ -1114,6 +1121,7 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, | ||||
|  */ | ||||
| int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri, | ||||
| 	struct timeval expiration_time, const char *path_info, const char *user_agent, | ||||
| 	const char *via_addr, int via_port, const char *call_id, | ||||
| 	struct ast_sip_endpoint *endpoint); | ||||
|  | ||||
| /*! | ||||
|   | ||||
| @@ -104,6 +104,12 @@ ASTERISK_REGISTER_FILE() | ||||
| 				<parameter name="RegExpire"> | ||||
| 					<para>Absolute time that this contact is no longer valid after</para> | ||||
| 				</parameter> | ||||
| 				<parameter name="ViaAddress"> | ||||
| 					<para>IP address:port of the last Via header in REGISTER request</para> | ||||
| 				</parameter> | ||||
| 				<parameter name="CallID"> | ||||
| 					<para>Content of the Call-ID header in REGISTER request</para> | ||||
| 				</parameter> | ||||
| 			</syntax> | ||||
| 		</managerEventInstance> | ||||
| 	</managerEvent> | ||||
|   | ||||
| @@ -1175,6 +1175,28 @@ | ||||
| 						Asterisk Server name on which SIP endpoint registered. | ||||
| 					</para></description> | ||||
| 				</configOption> | ||||
| 				<configOption name="via_addr"> | ||||
| 					<synopsis>IP-address of the last Via header from registration.</synopsis> | ||||
| 					<description><para> | ||||
| 						The last Via header should contain the address of UA which sent the request. | ||||
| 						The IP-address of the last Via header is automatically stored based on data present | ||||
| 						in incoming SIP REGISTER requests and is not intended to be configured manually. | ||||
| 					</para></description> | ||||
| 				</configOption> | ||||
| 				<configOption name="via_port"> | ||||
| 					<synopsis>IP-port of the last Via header from registration.</synopsis> | ||||
| 					<description><para> | ||||
| 						The IP-port of the last Via header is automatically stored based on data present | ||||
| 						in incoming SIP REGISTER requests and is not intended to be configured manually. | ||||
| 					</para></description> | ||||
| 				</configOption> | ||||
| 				<configOption name="call_id"> | ||||
| 					<synopsis>Call-ID header from registration.</synopsis> | ||||
| 					<description><para> | ||||
| 						The Call-ID header is automatically stored based on data present | ||||
| 						in incoming SIP REGISTER requests and is not intended to be configured manually. | ||||
| 					</para></description> | ||||
| 				</configOption> | ||||
| 			</configObject> | ||||
| 			<configObject name="aor"> | ||||
| 				<synopsis>The configuration for a location of an endpoint</synopsis> | ||||
| @@ -1967,6 +1989,12 @@ | ||||
| 				<parameter name="RegExpire"> | ||||
| 					<para>Absolute time that this contact is no longer valid after</para> | ||||
| 				</parameter> | ||||
| 				<parameter name="ViaAddress"> | ||||
| 					<para>IP address:port of the last Via header in REGISTER request</para> | ||||
| 				</parameter> | ||||
| 				<parameter name="CallID"> | ||||
| 					<para>Content of the Call-ID header in REGISTER request</para> | ||||
| 				</parameter> | ||||
| 			</syntax> | ||||
| 		</managerEventInstance> | ||||
| 	</managerEvent> | ||||
|   | ||||
| @@ -121,6 +121,8 @@ static void *contact_alloc(const char *name) | ||||
| 	} | ||||
|  | ||||
| 	ast_string_field_init_extended(contact, reg_server); | ||||
| 	ast_string_field_init_extended(contact, via_addr); | ||||
| 	ast_string_field_init_extended(contact, call_id); | ||||
|  | ||||
| 	/* Dynamic contacts are delimited with ";@" and static ones with "@@" */ | ||||
| 	if ((aor_separator = strstr(id, ";@")) || (aor_separator = strstr(id, "@@"))) { | ||||
| @@ -303,6 +305,7 @@ struct ast_sip_contact *ast_sip_location_retrieve_contact(const char *contact_na | ||||
|  | ||||
| int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri, | ||||
| 		struct timeval expiration_time, const char *path_info, const char *user_agent, | ||||
| 		const char *via_addr, int via_port, const char *call_id, | ||||
| 		struct ast_sip_endpoint *endpoint) | ||||
| { | ||||
| 	char name[MAX_OBJECT_FIELD * 2 + 3]; | ||||
| @@ -337,6 +340,15 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri | ||||
| 		ast_string_field_set(contact, reg_server, ast_config_AST_SYSTEM_NAME); | ||||
| 	} | ||||
|  | ||||
| 	if (!ast_strlen_zero(via_addr)) { | ||||
| 		ast_string_field_set(contact, via_addr, via_addr); | ||||
| 	} | ||||
| 	contact->via_port = via_port; | ||||
|  | ||||
| 	if (!ast_strlen_zero(call_id)) { | ||||
| 		ast_string_field_set(contact, call_id, call_id); | ||||
| 	} | ||||
|  | ||||
| 	contact->endpoint = ao2_bump(endpoint); | ||||
|  | ||||
| 	return ast_sorcery_create(ast_sip_get_sorcery(), contact); | ||||
| @@ -344,6 +356,7 @@ int ast_sip_location_add_contact_nolock(struct ast_sip_aor *aor, const char *uri | ||||
|  | ||||
| int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, | ||||
| 		struct timeval expiration_time, const char *path_info, const char *user_agent, | ||||
| 		const char *via_addr, int via_port, const char *call_id, | ||||
| 		struct ast_sip_endpoint *endpoint) | ||||
| { | ||||
| 	int res; | ||||
| @@ -356,6 +369,7 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri, | ||||
|  | ||||
| 	ao2_wrlock(lock); | ||||
| 	res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent, | ||||
| 		via_addr, via_port, call_id, | ||||
| 		endpoint); | ||||
| 	ao2_unlock(lock); | ||||
| 	ast_named_lock_put(lock); | ||||
| @@ -1120,6 +1134,9 @@ int ast_sip_initialize_sorcery_location(void) | ||||
| 	ast_sorcery_object_field_register(sorcery, "contact", "outbound_proxy", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, outbound_proxy)); | ||||
| 	ast_sorcery_object_field_register(sorcery, "contact", "user_agent", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, user_agent)); | ||||
| 	ast_sorcery_object_field_register(sorcery, "contact", "reg_server", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, reg_server)); | ||||
| 	ast_sorcery_object_field_register(sorcery, "contact", "via_addr", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, via_addr)); | ||||
| 	ast_sorcery_object_field_register(sorcery, "contact", "via_port", "0", OPT_UINT_T, 0, FLDSET(struct ast_sip_contact, via_port)); | ||||
| 	ast_sorcery_object_field_register(sorcery, "contact", "call_id", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_contact, call_id)); | ||||
|  | ||||
| 	ast_sorcery_object_field_register(sorcery, "aor", "type", "", OPT_NOOP_T, 0, 0); | ||||
| 	ast_sorcery_object_field_register(sorcery, "aor", "minimum_expiration", "60", OPT_UINT_T, 0, FLDSET(struct ast_sip_aor, minimum_expiration)); | ||||
|   | ||||
| @@ -1156,6 +1156,16 @@ static int format_contact_status(void *obj, void *arg, int flags) | ||||
| 	ast_str_append(&buf, 0, "URI: %s\r\n", contact->uri); | ||||
| 	ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent); | ||||
| 	ast_str_append(&buf, 0, "RegExpire: %ld\r\n", contact->expiration_time.tv_sec); | ||||
| 	if (!ast_strlen_zero(contact->via_addr)) { | ||||
| 		ast_str_append(&buf, 0, "ViaAddress: %s", contact->via_addr); | ||||
| 		if (contact->via_port) { | ||||
| 			ast_str_append(&buf, 0, ":%d", contact->via_port); | ||||
| 		} | ||||
| 		ast_str_append(&buf, 0, "\r\n"); | ||||
| 	} | ||||
| 	if (!ast_strlen_zero(contact->call_id)) { | ||||
| 		ast_str_append(&buf, 0, "CallID: %s\r\n", contact->call_id); | ||||
| 	} | ||||
| 	ast_str_append(&buf, 0, "Status: %s\r\n", ast_sip_get_contact_status_label(status->status)); | ||||
| 	if (status->status == UNKNOWN) { | ||||
| 		ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n"); | ||||
|   | ||||
| @@ -447,6 +447,13 @@ static int rx_task_core(struct rx_task_data *task_data, struct ao2_container *co | ||||
| 	char *user_agent = NULL; | ||||
| 	pjsip_user_agent_hdr *user_agent_hdr; | ||||
| 	pjsip_expires_hdr *expires_hdr; | ||||
| 	pjsip_via_hdr *via_hdr; | ||||
| 	pjsip_via_hdr *via_hdr_last; | ||||
| 	char *via_addr = NULL; | ||||
| 	int via_port = 0; | ||||
| 	pjsip_cid_hdr *call_id_hdr; | ||||
| 	char *call_id = NULL; | ||||
| 	size_t alloc_size; | ||||
|  | ||||
| 	/* So we don't count static contacts against max_contacts we prune them out from the container */ | ||||
| 	ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL); | ||||
| @@ -484,11 +491,32 @@ static int rx_task_core(struct rx_task_data *task_data, struct ao2_container *co | ||||
|  | ||||
| 	user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL); | ||||
| 	if (user_agent_hdr) { | ||||
| 		size_t alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1; | ||||
| 		alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1; | ||||
| 		user_agent = ast_alloca(alloc_size); | ||||
| 		ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size); | ||||
| 	} | ||||
|  | ||||
| 	/* Find the first Via header */ | ||||
| 	via_hdr = via_hdr_last = (pjsip_via_hdr*) pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_VIA, NULL); | ||||
| 	if (via_hdr) { | ||||
| 		/* Find the last Via header */ | ||||
| 		while ( (via_hdr = (pjsip_via_hdr*) pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, | ||||
| 				PJSIP_H_VIA, via_hdr->next)) != NULL) { | ||||
| 			via_hdr_last = via_hdr; | ||||
| 		} | ||||
| 		alloc_size = pj_strlen(&via_hdr_last->sent_by.host) + 1; | ||||
| 		via_addr = ast_alloca(alloc_size); | ||||
| 		ast_copy_pj_str(via_addr, &via_hdr_last->sent_by.host, alloc_size); | ||||
| 		via_port=via_hdr_last->sent_by.port; | ||||
| 	} | ||||
|  | ||||
| 	call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CALL_ID, NULL); | ||||
| 	if (call_id_hdr) { | ||||
| 		alloc_size = pj_strlen(&call_id_hdr->id) + 1; | ||||
| 		call_id = ast_alloca(alloc_size); | ||||
| 		ast_copy_pj_str(call_id, &call_id_hdr->id, alloc_size); | ||||
| 	} | ||||
|  | ||||
| 	/* Iterate each provided Contact header and add, update, or delete */ | ||||
| 	while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) { | ||||
| 		int expiration; | ||||
| @@ -520,7 +548,7 @@ static int rx_task_core(struct rx_task_data *task_data, struct ao2_container *co | ||||
|  | ||||
| 			if (ast_sip_location_add_contact_nolock(task_data->aor, contact_uri, ast_tvadd(ast_tvnow(), | ||||
| 				ast_samp2tv(expiration, 1)), path_str ? ast_str_buffer(path_str) : NULL, | ||||
| 					user_agent, task_data->endpoint)) { | ||||
| 					user_agent, via_addr, via_port, call_id, task_data->endpoint)) { | ||||
| 				ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n", | ||||
| 						contact_uri, aor_name); | ||||
| 				continue; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user