summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2016-05-31 07:41:43 -0500
committerGerrit Code Review <gerrit2@gerrit.digium.api>2016-05-31 07:41:43 -0500
commite3c9ad63828852aec248355d2d49206687fa87fd (patch)
tree866dcc5b1a8b064abaa9263de8f3006bb1afe6a5
parenteff382c72b03d5b48a8adbaf625088f725e5b87b (diff)
parent230686f4ec82a774e2a41aaa5e86909fd589f9b4 (diff)
Merge "res_pjsip: add "via_addr", "via_port", "call_id" to contact" into 13
-rw-r--r--CHANGES6
-rw-r--r--contrib/ast-db-manage/config/versions/6d8c104e6184_res_pjsip_add_contact_via_addr_and_.py25
-rw-r--r--include/asterisk/res_pjsip.h8
-rw-r--r--main/stasis_endpoints.c6
-rw-r--r--res/res_pjsip.c28
-rw-r--r--res/res_pjsip/location.c17
-rw-r--r--res/res_pjsip/pjsip_options.c10
-rw-r--r--res/res_pjsip_registrar.c32
8 files changed, 130 insertions, 2 deletions
diff --git a/CHANGES b/CHANGES
index 63ca0bcf0..890b3afb3 100644
--- a/CHANGES
+++ b/CHANGES
@@ -25,6 +25,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
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 000000000..893d9d82e
--- /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 d20d27e70..b64ad624b 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -250,6 +250,12 @@ struct ast_sip_contact {
char *aor;
/*! 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"
@@ -1101,6 +1107,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);
/*!
@@ -1122,6 +1129,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);
/*!
diff --git a/main/stasis_endpoints.c b/main/stasis_endpoints.c
index a91cd9f6b..c31714bf4 100644
--- a/main/stasis_endpoints.c
+++ b/main/stasis_endpoints.c
@@ -104,6 +104,12 @@ ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
<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 9162431a1..adc4d4120 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -1172,6 +1172,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>
@@ -1961,6 +1983,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 ef06456a7..f55bd0fb4 100644
--- a/res/res_pjsip/location.c
+++ b/res/res_pjsip/location.c
@@ -122,6 +122,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, "@@"))) {
@@ -308,6 +310,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];
@@ -342,6 +345,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);
@@ -349,6 +361,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;
@@ -361,6 +374,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);
@@ -1125,6 +1139,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));
diff --git a/res/res_pjsip/pjsip_options.c b/res/res_pjsip/pjsip_options.c
index b9339f60b..d73766cb2 100644
--- a/res/res_pjsip/pjsip_options.c
+++ b/res/res_pjsip/pjsip_options.c
@@ -1167,6 +1167,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");
diff --git a/res/res_pjsip_registrar.c b/res/res_pjsip_registrar.c
index a8144fc05..838f4616d 100644
--- a/res/res_pjsip_registrar.c
+++ b/res/res_pjsip_registrar.c
@@ -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;