Merge "res_pjsip: add "via_addr", "via_port", "call_id" to contact"
This commit is contained in:
commit
11ea121cc8
8 changed files with 130 additions and 2 deletions
6
CHANGES
6
CHANGES
|
@ -328,6 +328,12 @@ res_fax
|
||||||
|
|
||||||
res_pjsip
|
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
|
* Endpoint IP Access Controls
|
||||||
Added new configuration Endpoint options:
|
Added new configuration Endpoint options:
|
||||||
"acl" - list of IP ACL section names in acl.conf
|
"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;
|
struct ast_sip_endpoint *endpoint;
|
||||||
/*! Asterisk Server name */
|
/*! Asterisk Server name */
|
||||||
AST_STRING_FIELD_EXTENDED(reg_server);
|
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"
|
#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,
|
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,
|
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);
|
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,
|
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,
|
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);
|
struct ast_sip_endpoint *endpoint);
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
|
|
|
@ -104,6 +104,12 @@ ASTERISK_REGISTER_FILE()
|
||||||
<parameter name="RegExpire">
|
<parameter name="RegExpire">
|
||||||
<para>Absolute time that this contact is no longer valid after</para>
|
<para>Absolute time that this contact is no longer valid after</para>
|
||||||
</parameter>
|
</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>
|
</syntax>
|
||||||
</managerEventInstance>
|
</managerEventInstance>
|
||||||
</managerEvent>
|
</managerEvent>
|
||||||
|
|
|
@ -1175,6 +1175,28 @@
|
||||||
Asterisk Server name on which SIP endpoint registered.
|
Asterisk Server name on which SIP endpoint registered.
|
||||||
</para></description>
|
</para></description>
|
||||||
</configOption>
|
</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>
|
||||||
<configObject name="aor">
|
<configObject name="aor">
|
||||||
<synopsis>The configuration for a location of an endpoint</synopsis>
|
<synopsis>The configuration for a location of an endpoint</synopsis>
|
||||||
|
@ -1967,6 +1989,12 @@
|
||||||
<parameter name="RegExpire">
|
<parameter name="RegExpire">
|
||||||
<para>Absolute time that this contact is no longer valid after</para>
|
<para>Absolute time that this contact is no longer valid after</para>
|
||||||
</parameter>
|
</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>
|
</syntax>
|
||||||
</managerEventInstance>
|
</managerEventInstance>
|
||||||
</managerEvent>
|
</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, 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 "@@" */
|
/* Dynamic contacts are delimited with ";@" and static ones with "@@" */
|
||||||
if ((aor_separator = strstr(id, ";@")) || (aor_separator = strstr(id, "@@"))) {
|
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,
|
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,
|
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)
|
struct ast_sip_endpoint *endpoint)
|
||||||
{
|
{
|
||||||
char name[MAX_OBJECT_FIELD * 2 + 3];
|
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);
|
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);
|
contact->endpoint = ao2_bump(endpoint);
|
||||||
|
|
||||||
return ast_sorcery_create(ast_sip_get_sorcery(), contact);
|
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,
|
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,
|
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)
|
struct ast_sip_endpoint *endpoint)
|
||||||
{
|
{
|
||||||
int res;
|
int res;
|
||||||
|
@ -356,6 +369,7 @@ int ast_sip_location_add_contact(struct ast_sip_aor *aor, const char *uri,
|
||||||
|
|
||||||
ao2_wrlock(lock);
|
ao2_wrlock(lock);
|
||||||
res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent,
|
res = ast_sip_location_add_contact_nolock(aor, uri, expiration_time, path_info, user_agent,
|
||||||
|
via_addr, via_port, call_id,
|
||||||
endpoint);
|
endpoint);
|
||||||
ao2_unlock(lock);
|
ao2_unlock(lock);
|
||||||
ast_named_lock_put(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", "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", "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", "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", "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));
|
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, "URI: %s\r\n", contact->uri);
|
||||||
ast_str_append(&buf, 0, "UserAgent: %s\r\n", contact->user_agent);
|
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);
|
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));
|
ast_str_append(&buf, 0, "Status: %s\r\n", ast_sip_get_contact_status_label(status->status));
|
||||||
if (status->status == UNKNOWN) {
|
if (status->status == UNKNOWN) {
|
||||||
ast_str_append(&buf, 0, "RoundtripUsec: N/A\r\n");
|
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;
|
char *user_agent = NULL;
|
||||||
pjsip_user_agent_hdr *user_agent_hdr;
|
pjsip_user_agent_hdr *user_agent_hdr;
|
||||||
pjsip_expires_hdr *expires_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 */
|
/* 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);
|
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);
|
user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL);
|
||||||
if (user_agent_hdr) {
|
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);
|
user_agent = ast_alloca(alloc_size);
|
||||||
ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, 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 */
|
/* 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))) {
|
while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
|
||||||
int expiration;
|
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(),
|
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,
|
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",
|
ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
|
||||||
contact_uri, aor_name);
|
contact_uri, aor_name);
|
||||||
continue;
|
continue;
|
||||||
|
|
Loading…
Reference in a new issue