[Asterisk-code-review] res pjsip: add "via addr", "via port", "call id" to contact (asterisk[master])

Alexei Gradinari asteriskteam at digium.com
Thu May 26 16:18:13 CDT 2016


Alexei Gradinari has uploaded a new change for review.

  https://gerrit.asterisk.org/2913

Change subject: res_pjsip: add "via_addr", "via_port", "call_id" to contact
......................................................................

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
---
M CHANGES
A contrib/ast-db-manage/config/versions/6d8c104e6184_res_pjsip_add_contact_via_addr_and_.py
M include/asterisk/res_pjsip.h
M main/stasis_endpoints.c
M res/res_pjsip.c
M res/res_pjsip/location.c
M res/res_pjsip/pjsip_options.c
M res/res_pjsip_registrar.c
8 files changed, 130 insertions(+), 2 deletions(-)


  git pull ssh://gerrit.asterisk.org:29418/asterisk refs/changes/13/2913/1

diff --git a/CHANGES b/CHANGES
index 281cff3..7b129e0 100644
--- a/CHANGES
+++ b/CHANGES
@@ -328,6 +328,12 @@
 
 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
diff --git a/contrib/ast-db-manage/config/versions/6d8c104e6184_res_pjsip_add_contact_via_addr_and_.py b/contrib/ast-db-manage/config/versions/6d8c104e6184_res_pjsip_add_contact_via_addr_and_.py
new file mode 100644
index 0000000..893d9d8
--- /dev/null
+++ b/contrib/ast-db-manage/config/versions/6d8c104e6184_res_pjsip_add_contact_via_addr_and_.py
@@ -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')
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index cf8c719..50d02d9 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -250,6 +250,12 @@
 	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 @@
  */
 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_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);
 
 /*!
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index 14d3d0c..2d11421 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -104,6 +104,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>
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index bebe941..8fc3c53 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -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>
diff --git a/res/res_pjsip/location.c b/res/res_pjsip/location.c
index fd6db6e..43e6ea4 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -121,6 +121,8 @@
 	}
 
 	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 @@
 
 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 @@
 		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(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 @@
 
 	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 @@
 	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));
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index 62640fe..1114336 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -1156,6 +1156,16 @@
 	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");
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index cbc33ab..0e14ab7 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -447,6 +447,13 @@
 	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,9 +491,30 @@
 
 	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 */
@@ -520,7 +548,7 @@
 
 			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;

-- 
To view, visit https://gerrit.asterisk.org/2913
To unsubscribe, visit https://gerrit.asterisk.org/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I36bcc0bf422b3e0623680152d80486aeafe4c576
Gerrit-PatchSet: 1
Gerrit-Project: asterisk
Gerrit-Branch: master
Gerrit-Owner: Alexei Gradinari <alex2grad at gmail.com>



More information about the asterisk-code-review mailing list