mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +00:00
Merge "res_pjsip: Add ignore_uri_user_options option."
This commit is contained in:
11
CHANGES
11
CHANGES
@@ -79,6 +79,17 @@ res_pjsip
|
|||||||
configure these options then you already had to do a reload after making
|
configure these options then you already had to do a reload after making
|
||||||
changes.
|
changes.
|
||||||
|
|
||||||
|
* Added "ignore_uri_user_options" global configuration option for
|
||||||
|
compatibility with an ITSP that sends URI user field options. When enabled
|
||||||
|
the user field is truncated at the first semicolon.
|
||||||
|
Example:
|
||||||
|
URI: "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
|
||||||
|
The user field is "1235557890;phone-context=national"
|
||||||
|
Which is truncated to this: "1235557890"
|
||||||
|
|
||||||
|
Note: The caller-id and redirecting number strings obtained from incoming
|
||||||
|
SIP URI user fields are now always truncated at the first semicolon.
|
||||||
|
|
||||||
app_confbridge
|
app_confbridge
|
||||||
------------------
|
------------------
|
||||||
* Some sounds played into the bridge are played asynchronously. This, for
|
* Some sounds played into the bridge are played asynchronously. This, for
|
||||||
|
@@ -991,6 +991,22 @@
|
|||||||
; If disabled then unsolicited mwi will start processing
|
; If disabled then unsolicited mwi will start processing
|
||||||
; on the endpoint's next contact update.
|
; on the endpoint's next contact update.
|
||||||
|
|
||||||
|
;ignore_uri_user_options=no ; Enable/Disable ignoring SIP URI user field options.
|
||||||
|
; If you have this option enabled and there are semicolons
|
||||||
|
; in the user field of a SIP URI then the field is truncated
|
||||||
|
; at the first semicolon. This effectively makes the semicolon
|
||||||
|
; a non-usable character for PJSIP endpoint names, extensions,
|
||||||
|
; and AORs. This can be useful for improving compatability with
|
||||||
|
; an ITSP that likes to use user options for whatever reason.
|
||||||
|
; Example:
|
||||||
|
; URI: "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
|
||||||
|
; The user field is "1235557890;phone-context=national"
|
||||||
|
; Which becomes this: "1235557890"
|
||||||
|
;
|
||||||
|
; Note: The caller-id and redirecting number strings obtained
|
||||||
|
; from incoming SIP URI user fields are always truncated at the
|
||||||
|
; first semicolon.
|
||||||
|
|
||||||
; MODULE PROVIDING BELOW SECTION(S): res_pjsip_acl
|
; MODULE PROVIDING BELOW SECTION(S): res_pjsip_acl
|
||||||
;==========================ACL SECTION OPTIONS=========================
|
;==========================ACL SECTION OPTIONS=========================
|
||||||
;[acl]
|
;[acl]
|
||||||
|
@@ -0,0 +1,32 @@
|
|||||||
|
"""ps_globals add ignore_uri_user_options
|
||||||
|
|
||||||
|
Revision ID: a6ef36f1309
|
||||||
|
Revises: 7f3e21abe318
|
||||||
|
Create Date: 2016-08-31 12:24:22.368956
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
# revision identifiers, used by Alembic.
|
||||||
|
revision = 'a6ef36f1309'
|
||||||
|
down_revision = '7f3e21abe318'
|
||||||
|
|
||||||
|
from alembic import op
|
||||||
|
import sqlalchemy as sa
|
||||||
|
from sqlalchemy.dialects.postgresql import ENUM
|
||||||
|
|
||||||
|
YESNO_NAME = 'yesno_values'
|
||||||
|
YESNO_VALUES = ['yes', 'no']
|
||||||
|
|
||||||
|
def upgrade():
|
||||||
|
############################# Enums ##############################
|
||||||
|
|
||||||
|
# yesno_values have already been created, so use postgres enum object
|
||||||
|
# type to get around "already created" issue - works okay with mysql
|
||||||
|
yesno_values = ENUM(*YESNO_VALUES, name=YESNO_NAME, create_type=False)
|
||||||
|
|
||||||
|
op.add_column('ps_globals', sa.Column('ignore_uri_user_options', yesno_values))
|
||||||
|
|
||||||
|
|
||||||
|
def downgrade():
|
||||||
|
op.drop_column('ps_globals', 'ignore_uri_user_options')
|
||||||
|
|
@@ -2446,6 +2446,38 @@ int ast_sip_get_mwi_tps_queue_low(void);
|
|||||||
*/
|
*/
|
||||||
unsigned int ast_sip_get_mwi_disable_initial_unsolicited(void);
|
unsigned int ast_sip_get_mwi_disable_initial_unsolicited(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Retrieve the global setting 'ignore_uri_user_options'.
|
||||||
|
* \since 13.12.0
|
||||||
|
*
|
||||||
|
* \retval non zero if ignore the user field options.
|
||||||
|
*/
|
||||||
|
unsigned int ast_sip_get_ignore_uri_user_options(void);
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Truncate the URI user field options string if enabled.
|
||||||
|
* \since 13.12.0
|
||||||
|
*
|
||||||
|
* \param str URI user field string to truncate if enabled
|
||||||
|
*
|
||||||
|
* \details
|
||||||
|
* We need to be able to handle URI's looking like
|
||||||
|
* "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
|
||||||
|
*
|
||||||
|
* Where the URI user field is:
|
||||||
|
* "1235557890;phone-context=national"
|
||||||
|
*
|
||||||
|
* When truncated the string will become:
|
||||||
|
* "1235557890"
|
||||||
|
*/
|
||||||
|
#define AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(str) \
|
||||||
|
do { \
|
||||||
|
char *__semi = strchr((str), ';'); \
|
||||||
|
if (__semi && ast_sip_get_ignore_uri_user_options()) { \
|
||||||
|
*__semi = '\0'; \
|
||||||
|
} \
|
||||||
|
} while (0)
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Retrieve the system debug setting (yes|no|host).
|
* \brief Retrieve the system debug setting (yes|no|host).
|
||||||
*
|
*
|
||||||
|
@@ -1550,6 +1550,30 @@
|
|||||||
</para>
|
</para>
|
||||||
</description>
|
</description>
|
||||||
</configOption>
|
</configOption>
|
||||||
|
<configOption name="ignore_uri_user_options">
|
||||||
|
<synopsis>Enable/Disable ignoring SIP URI user field options.</synopsis>
|
||||||
|
<description>
|
||||||
|
<para>If you have this option enabled and there are semicolons
|
||||||
|
in the user field of a SIP URI then the field is truncated
|
||||||
|
at the first semicolon. This effectively makes the semicolon
|
||||||
|
a non-usable character for PJSIP endpoint names, extensions,
|
||||||
|
and AORs. This can be useful for improving compatability with
|
||||||
|
an ITSP that likes to use user options for whatever reason.
|
||||||
|
</para>
|
||||||
|
<example title="Sample SIP URI">
|
||||||
|
sip:1235557890;phone-context=national@x.x.x.x;user=phone
|
||||||
|
</example>
|
||||||
|
<example title="Sample SIP URI user field">
|
||||||
|
1235557890;phone-context=national
|
||||||
|
</example>
|
||||||
|
<example title="Sample SIP URI user field truncated">
|
||||||
|
1235557890
|
||||||
|
</example>
|
||||||
|
<note><para>The caller-id and redirecting number strings
|
||||||
|
obtained from incoming SIP URI user fields are always truncated
|
||||||
|
at the first semicolon.</para></note>
|
||||||
|
</description>
|
||||||
|
</configOption>
|
||||||
</configObject>
|
</configObject>
|
||||||
</configFile>
|
</configFile>
|
||||||
</configInfo>
|
</configInfo>
|
||||||
|
@@ -47,6 +47,7 @@
|
|||||||
#define DEFAULT_MWI_TPS_QUEUE_HIGH AST_TASKPROCESSOR_HIGH_WATER_LEVEL
|
#define DEFAULT_MWI_TPS_QUEUE_HIGH AST_TASKPROCESSOR_HIGH_WATER_LEVEL
|
||||||
#define DEFAULT_MWI_TPS_QUEUE_LOW -1
|
#define DEFAULT_MWI_TPS_QUEUE_LOW -1
|
||||||
#define DEFAULT_MWI_DISABLE_INITIAL_UNSOLICITED 0
|
#define DEFAULT_MWI_DISABLE_INITIAL_UNSOLICITED 0
|
||||||
|
#define DEFAULT_IGNORE_URI_USER_OPTIONS 0
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief Cached global config object
|
* \brief Cached global config object
|
||||||
@@ -100,6 +101,8 @@ struct global_config {
|
|||||||
/*! Nonzero to disable sending unsolicited mwi to all endpoints on startup */
|
/*! Nonzero to disable sending unsolicited mwi to all endpoints on startup */
|
||||||
unsigned int disable_initial_unsolicited;
|
unsigned int disable_initial_unsolicited;
|
||||||
} mwi;
|
} mwi;
|
||||||
|
/*! Nonzero if URI user field options are ignored. */
|
||||||
|
unsigned int ignore_uri_user_options;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void global_destructor(void *obj)
|
static void global_destructor(void *obj)
|
||||||
@@ -384,6 +387,20 @@ unsigned int ast_sip_get_mwi_disable_initial_unsolicited(void)
|
|||||||
return disable_initial_unsolicited;
|
return disable_initial_unsolicited;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int ast_sip_get_ignore_uri_user_options(void)
|
||||||
|
{
|
||||||
|
unsigned int ignore_uri_user_options;
|
||||||
|
struct global_config *cfg;
|
||||||
|
|
||||||
|
cfg = get_global_cfg();
|
||||||
|
if (!cfg) {
|
||||||
|
return DEFAULT_IGNORE_URI_USER_OPTIONS;
|
||||||
|
}
|
||||||
|
|
||||||
|
ignore_uri_user_options = cfg->ignore_uri_user_options;
|
||||||
|
ao2_ref(cfg, -1);
|
||||||
|
return ignore_uri_user_options;
|
||||||
|
}
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \internal
|
* \internal
|
||||||
@@ -533,6 +550,9 @@ int ast_sip_initialize_sorcery_global(void)
|
|||||||
ast_sorcery_object_field_register(sorcery, "global", "mwi_disable_initial_unsolicited",
|
ast_sorcery_object_field_register(sorcery, "global", "mwi_disable_initial_unsolicited",
|
||||||
DEFAULT_MWI_DISABLE_INITIAL_UNSOLICITED ? "yes" : "no",
|
DEFAULT_MWI_DISABLE_INITIAL_UNSOLICITED ? "yes" : "no",
|
||||||
OPT_BOOL_T, 1, FLDSET(struct global_config, mwi.disable_initial_unsolicited));
|
OPT_BOOL_T, 1, FLDSET(struct global_config, mwi.disable_initial_unsolicited));
|
||||||
|
ast_sorcery_object_field_register(sorcery, "global", "ignore_uri_user_options",
|
||||||
|
DEFAULT_IGNORE_URI_USER_OPTIONS ? "yes" : "no",
|
||||||
|
OPT_BOOL_T, 1, FLDSET(struct global_config, ignore_uri_user_options));
|
||||||
|
|
||||||
if (ast_sorcery_instance_observer_add(sorcery, &observer_callbacks_global)) {
|
if (ast_sorcery_instance_observer_add(sorcery, &observer_callbacks_global)) {
|
||||||
return -1;
|
return -1;
|
||||||
|
@@ -750,8 +750,7 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
|
|||||||
pjsip_sip_uri *sip_ruri;
|
pjsip_sip_uri *sip_ruri;
|
||||||
char exten[AST_MAX_EXTENSION];
|
char exten[AST_MAX_EXTENSION];
|
||||||
|
|
||||||
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method,
|
if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
|
||||||
&pjsip_options_method)) {
|
|
||||||
return PJ_FALSE;
|
return PJ_FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -768,13 +767,20 @@ static pj_bool_t options_on_rx_request(pjsip_rx_data *rdata)
|
|||||||
sip_ruri = pjsip_uri_get_uri(ruri);
|
sip_ruri = pjsip_uri_get_uri(ruri);
|
||||||
ast_copy_pj_str(exten, &sip_ruri->user, sizeof(exten));
|
ast_copy_pj_str(exten, &sip_ruri->user, sizeof(exten));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match in the dialplan without any user
|
||||||
|
* options getting in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(exten);
|
||||||
|
|
||||||
if (ast_shutting_down()) {
|
if (ast_shutting_down()) {
|
||||||
/*
|
/*
|
||||||
* Not taking any new calls at this time.
|
* Not taking any new calls at this time.
|
||||||
* Likely a server availability OPTIONS poll.
|
* Likely a server availability OPTIONS poll.
|
||||||
*/
|
*/
|
||||||
send_options_response(rdata, 503);
|
send_options_response(rdata, 503);
|
||||||
} else if (!ast_strlen_zero(exten) && !ast_exists_extension(NULL, endpoint->context, exten, 1, NULL)) {
|
} else if (!ast_strlen_zero(exten)
|
||||||
|
&& !ast_exists_extension(NULL, endpoint->context, exten, 1, NULL)) {
|
||||||
send_options_response(rdata, 404);
|
send_options_response(rdata, 404);
|
||||||
} else {
|
} else {
|
||||||
send_options_response(rdata, 200);
|
send_options_response(rdata, 200);
|
||||||
|
@@ -46,11 +46,29 @@ static void set_id_from_hdr(pjsip_fromto_hdr *hdr, struct ast_party_id *id)
|
|||||||
char cid_num[AST_CHANNEL_NAME];
|
char cid_num[AST_CHANNEL_NAME];
|
||||||
pjsip_sip_uri *uri;
|
pjsip_sip_uri *uri;
|
||||||
pjsip_name_addr *id_name_addr = (pjsip_name_addr *) hdr->uri;
|
pjsip_name_addr *id_name_addr = (pjsip_name_addr *) hdr->uri;
|
||||||
|
char *semi;
|
||||||
|
|
||||||
uri = pjsip_uri_get_uri(id_name_addr);
|
uri = pjsip_uri_get_uri(id_name_addr);
|
||||||
ast_copy_pj_str(cid_name, &id_name_addr->display, sizeof(cid_name));
|
ast_copy_pj_str(cid_name, &id_name_addr->display, sizeof(cid_name));
|
||||||
ast_copy_pj_str(cid_num, &uri->user, sizeof(cid_num));
|
ast_copy_pj_str(cid_num, &uri->user, sizeof(cid_num));
|
||||||
|
|
||||||
|
/* Always truncate caller-id number at a semicolon. */
|
||||||
|
semi = strchr(cid_num, ';');
|
||||||
|
if (semi) {
|
||||||
|
/*
|
||||||
|
* We need to be able to handle URI's looking like
|
||||||
|
* "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
|
||||||
|
*
|
||||||
|
* Where the uri->user field will result in:
|
||||||
|
* "1235557890;phone-context=national"
|
||||||
|
*
|
||||||
|
* People don't care about anything after the semicolon
|
||||||
|
* showing up on their displays even though the RFC
|
||||||
|
* allows the semicolon.
|
||||||
|
*/
|
||||||
|
*semi = '\0';
|
||||||
|
}
|
||||||
|
|
||||||
ast_free(id->name.str);
|
ast_free(id->name.str);
|
||||||
id->name.str = ast_strdup(cid_name);
|
id->name.str = ast_strdup(cid_name);
|
||||||
if (!ast_strlen_zero(cid_name)) {
|
if (!ast_strlen_zero(cid_name)) {
|
||||||
|
@@ -148,11 +148,32 @@ static void set_redirecting_id(pjsip_name_addr *name_addr, struct ast_party_id *
|
|||||||
struct ast_set_party_id *update)
|
struct ast_set_party_id *update)
|
||||||
{
|
{
|
||||||
pjsip_sip_uri *uri = pjsip_uri_get_uri(name_addr->uri);
|
pjsip_sip_uri *uri = pjsip_uri_get_uri(name_addr->uri);
|
||||||
|
char *semi;
|
||||||
|
pj_str_t uri_user;
|
||||||
|
|
||||||
if (pj_strlen(&uri->user)) {
|
uri_user = uri->user;
|
||||||
|
|
||||||
|
/* Always truncate redirecting number at a semicolon. */
|
||||||
|
semi = pj_strchr(&uri_user, ';');
|
||||||
|
if (semi) {
|
||||||
|
/*
|
||||||
|
* We need to be able to handle URI's looking like
|
||||||
|
* "sip:1235557890;phone-context=national@x.x.x.x;user=phone"
|
||||||
|
*
|
||||||
|
* Where the uri->user field will result in:
|
||||||
|
* "1235557890;phone-context=national"
|
||||||
|
*
|
||||||
|
* People don't care about anything after the semicolon
|
||||||
|
* showing up on their displays even though the RFC
|
||||||
|
* allows the semicolon.
|
||||||
|
*/
|
||||||
|
pj_strset(&uri_user, (char *) pj_strbuf(&uri_user), semi - pj_strbuf(&uri_user));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (pj_strlen(&uri_user)) {
|
||||||
update->number = 1;
|
update->number = 1;
|
||||||
data->number.valid = 1;
|
data->number.valid = 1;
|
||||||
set_redirecting_value(&data->number.str, &uri->user);
|
set_redirecting_value(&data->number.str, &uri_user);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pj_strlen(&name_addr->display)) {
|
if (pj_strlen(&name_addr->display)) {
|
||||||
|
@@ -33,6 +33,7 @@ static int get_from_header(pjsip_rx_data *rdata, char *username, size_t username
|
|||||||
{
|
{
|
||||||
pjsip_uri *from = rdata->msg_info.from->uri;
|
pjsip_uri *from = rdata->msg_info.from->uri;
|
||||||
pjsip_sip_uri *sip_from;
|
pjsip_sip_uri *sip_from;
|
||||||
|
|
||||||
if (!PJSIP_URI_SCHEME_IS_SIP(from) && !PJSIP_URI_SCHEME_IS_SIPS(from)) {
|
if (!PJSIP_URI_SCHEME_IS_SIP(from) && !PJSIP_URI_SCHEME_IS_SIPS(from)) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
@@ -115,18 +116,25 @@ static struct ast_sip_endpoint *find_endpoint(pjsip_rx_data *rdata, char *endpoi
|
|||||||
|
|
||||||
static struct ast_sip_endpoint *username_identify(pjsip_rx_data *rdata)
|
static struct ast_sip_endpoint *username_identify(pjsip_rx_data *rdata)
|
||||||
{
|
{
|
||||||
char username[64], domain[64];
|
char username[64];
|
||||||
|
char domain[64];
|
||||||
struct ast_sip_endpoint *endpoint;
|
struct ast_sip_endpoint *endpoint;
|
||||||
|
|
||||||
if (get_from_header(rdata, username, sizeof(username), domain, sizeof(domain))) {
|
if (get_from_header(rdata, username, sizeof(username), domain, sizeof(domain))) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to be matched without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(username);
|
||||||
|
|
||||||
ast_debug(3, "Attempting identify by From username '%s' domain '%s'\n", username, domain);
|
ast_debug(3, "Attempting identify by From username '%s' domain '%s'\n", username, domain);
|
||||||
|
|
||||||
endpoint = find_endpoint(rdata, username, domain);
|
endpoint = find_endpoint(rdata, username, domain);
|
||||||
if (!endpoint) {
|
if (!endpoint) {
|
||||||
ast_debug(3, "Endpoint not found for From username '%s' domain '%s'\n", username, domain);
|
ast_debug(3, "Endpoint not found for From username '%s' domain '%s'\n", username, domain);
|
||||||
ao2_cleanup(endpoint);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
if (!(endpoint->ident_method & AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME)) {
|
if (!(endpoint->ident_method & AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME)) {
|
||||||
|
@@ -132,6 +132,12 @@ static struct ast_sip_endpoint *get_outbound_endpoint(const char *to, char **uri
|
|||||||
} else if ((aor_uri = strchr(name, '@'))) {
|
} else if ((aor_uri = strchr(name, '@'))) {
|
||||||
/* format was 'endpoint@domain' - discard the domain */
|
/* format was 'endpoint@domain' - discard the domain */
|
||||||
*aor_uri = '\0';
|
*aor_uri = '\0';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* at this point, if name is not empty then it
|
/* at this point, if name is not empty then it
|
||||||
@@ -467,6 +473,12 @@ static enum pjsip_status_code rx_data_to_ast_msg(pjsip_rx_data *rdata, struct as
|
|||||||
sip_ruri = pjsip_uri_get_uri(ruri);
|
sip_ruri = pjsip_uri_get_uri(ruri);
|
||||||
ast_copy_pj_str(exten, &sip_ruri->user, AST_MAX_EXTENSION);
|
ast_copy_pj_str(exten, &sip_ruri->user, AST_MAX_EXTENSION);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match in the dialplan without any user
|
||||||
|
* options getting in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(exten);
|
||||||
|
|
||||||
endpt = ast_pjsip_rdata_get_endpoint(rdata);
|
endpt = ast_pjsip_rdata_get_endpoint(rdata);
|
||||||
ast_assert(endpt != NULL);
|
ast_assert(endpt != NULL);
|
||||||
|
|
||||||
@@ -547,7 +559,7 @@ static void msg_data_destroy(void *obj)
|
|||||||
|
|
||||||
static struct msg_data *msg_data_create(const struct ast_msg *msg, const char *to, const char *from)
|
static struct msg_data *msg_data_create(const struct ast_msg *msg, const char *to, const char *from)
|
||||||
{
|
{
|
||||||
char *tag;
|
char *uri_params;
|
||||||
struct msg_data *mdata = ao2_alloc(sizeof(*mdata), msg_data_destroy);
|
struct msg_data *mdata = ao2_alloc(sizeof(*mdata), msg_data_destroy);
|
||||||
|
|
||||||
if (!mdata) {
|
if (!mdata) {
|
||||||
@@ -572,9 +584,14 @@ static struct msg_data *msg_data_create(const struct ast_msg *msg, const char *t
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* sometimes from can still contain the tag at this point, so remove it */
|
/*
|
||||||
if ((tag = strchr(mdata->from, ';'))) {
|
* Sometimes from URI can contain URI parameters, so remove them.
|
||||||
*tag = '\0';
|
*
|
||||||
|
* sip:user;user-options@domain;uri-parameters
|
||||||
|
*/
|
||||||
|
uri_params = strchr(mdata->from, '@');
|
||||||
|
if (uri_params && (uri_params = strchr(mdata->from, ';'))) {
|
||||||
|
*uri_params = '\0';
|
||||||
}
|
}
|
||||||
return mdata;
|
return mdata;
|
||||||
}
|
}
|
||||||
|
@@ -40,7 +40,8 @@ static struct ast_sip_aor *find_aor(struct ast_sip_endpoint *endpoint, pjsip_uri
|
|||||||
char *configured_aors, *aor_name;
|
char *configured_aors, *aor_name;
|
||||||
pjsip_sip_uri *sip_uri;
|
pjsip_sip_uri *sip_uri;
|
||||||
char *domain_name;
|
char *domain_name;
|
||||||
RAII_VAR(struct ast_str *, id, NULL, ast_free);
|
char *username;
|
||||||
|
struct ast_str *id = NULL;
|
||||||
|
|
||||||
if (ast_strlen_zero(endpoint->aors)) {
|
if (ast_strlen_zero(endpoint->aors)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -49,6 +50,14 @@ static struct ast_sip_aor *find_aor(struct ast_sip_endpoint *endpoint, pjsip_uri
|
|||||||
sip_uri = pjsip_uri_get_uri(uri);
|
sip_uri = pjsip_uri_get_uri(uri);
|
||||||
domain_name = ast_alloca(sip_uri->host.slen + 1);
|
domain_name = ast_alloca(sip_uri->host.slen + 1);
|
||||||
ast_copy_pj_str(domain_name, &sip_uri->host, sip_uri->host.slen + 1);
|
ast_copy_pj_str(domain_name, &sip_uri->host, sip_uri->host.slen + 1);
|
||||||
|
username = ast_alloca(sip_uri->user.slen + 1);
|
||||||
|
ast_copy_pj_str(username, &sip_uri->user, sip_uri->user.slen + 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(username);
|
||||||
|
|
||||||
configured_aors = ast_strdupa(endpoint->aors);
|
configured_aors = ast_strdupa(endpoint->aors);
|
||||||
|
|
||||||
@@ -60,15 +69,16 @@ static struct ast_sip_aor *find_aor(struct ast_sip_endpoint *endpoint, pjsip_uri
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!pj_strcmp2(&sip_uri->user, aor_name)) {
|
if (!strcmp(username, aor_name)) {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!id && !(id = ast_str_create(sip_uri->user.slen + sip_uri->host.slen + 2))) {
|
if (!id && !(id = ast_str_create(strlen(username) + sip_uri->host.slen + 2))) {
|
||||||
return NULL;
|
aor_name = NULL;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ast_str_set(&id, 0, "%.*s@", (int)sip_uri->user.slen, sip_uri->user.ptr);
|
ast_str_set(&id, 0, "%s@", username);
|
||||||
if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
|
if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
|
||||||
ast_str_append(&id, 0, "%s", alias->domain);
|
ast_str_append(&id, 0, "%s", alias->domain);
|
||||||
ao2_cleanup(alias);
|
ao2_cleanup(alias);
|
||||||
@@ -77,10 +87,10 @@ static struct ast_sip_aor *find_aor(struct ast_sip_endpoint *endpoint, pjsip_uri
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(aor_name, ast_str_buffer(id))) {
|
if (!strcmp(aor_name, ast_str_buffer(id))) {
|
||||||
ast_free(id);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
ast_free(id);
|
||||||
|
|
||||||
if (ast_strlen_zero(aor_name)) {
|
if (ast_strlen_zero(aor_name)) {
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@@ -1378,6 +1378,12 @@ static int sub_persistence_recreate(void *obj)
|
|||||||
resource = ast_alloca(resource_size);
|
resource = ast_alloca(resource_size);
|
||||||
ast_copy_pj_str(resource, &request_uri->user, resource_size);
|
ast_copy_pj_str(resource, &request_uri->user, resource_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(resource);
|
||||||
|
|
||||||
handler = subscription_get_handler_from_rdata(rdata);
|
handler = subscription_get_handler_from_rdata(rdata);
|
||||||
if (!handler || !handler->notifier) {
|
if (!handler || !handler->notifier) {
|
||||||
ast_log(LOG_WARNING, "Failed recreating '%s' subscription: Could not get subscription handler.\n",
|
ast_log(LOG_WARNING, "Failed recreating '%s' subscription: Could not get subscription handler.\n",
|
||||||
@@ -2750,6 +2756,12 @@ static pj_bool_t pubsub_on_rx_subscribe_request(pjsip_rx_data *rdata)
|
|||||||
resource = ast_alloca(resource_size);
|
resource = ast_alloca(resource_size);
|
||||||
ast_copy_pj_str(resource, &request_uri_sip->user, resource_size);
|
ast_copy_pj_str(resource, &request_uri_sip->user, resource_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(resource);
|
||||||
|
|
||||||
expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next);
|
expires_header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, rdata->msg_info.msg->hdr.next);
|
||||||
|
|
||||||
if (expires_header) {
|
if (expires_header) {
|
||||||
@@ -2963,6 +2975,12 @@ static struct ast_sip_publication *publish_request_initial(struct ast_sip_endpoi
|
|||||||
resource_name = ast_alloca(resource_size);
|
resource_name = ast_alloca(resource_size);
|
||||||
ast_copy_pj_str(resource_name, &request_uri_sip->user, resource_size);
|
ast_copy_pj_str(resource_name, &request_uri_sip->user, resource_size);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(resource_name);
|
||||||
|
|
||||||
resource = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "inbound-publication", resource_name);
|
resource = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "inbound-publication", resource_name);
|
||||||
if (!resource) {
|
if (!resource) {
|
||||||
ast_debug(1, "No 'inbound-publication' defined for resource '%s'\n", resource_name);
|
ast_debug(1, "No 'inbound-publication' defined for resource '%s'\n", resource_name);
|
||||||
|
@@ -814,6 +814,13 @@ static int refer_incoming_blind_request(struct ast_sip_session *session, pjsip_r
|
|||||||
|
|
||||||
/* Using the user portion of the target URI see if it exists as a valid extension in their context */
|
/* Using the user portion of the target URI see if it exists as a valid extension in their context */
|
||||||
ast_copy_pj_str(exten, &target->user, sizeof(exten));
|
ast_copy_pj_str(exten, &target->user, sizeof(exten));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match in the dialplan without any user
|
||||||
|
* options getting in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(exten);
|
||||||
|
|
||||||
if (!ast_exists_extension(NULL, context, exten, 1, NULL)) {
|
if (!ast_exists_extension(NULL, context, exten, 1, NULL)) {
|
||||||
ast_log(LOG_ERROR, "Channel '%s' from endpoint '%s' attempted blind transfer to '%s@%s' but target does not exist\n",
|
ast_log(LOG_ERROR, "Channel '%s' from endpoint '%s' attempted blind transfer to '%s@%s' but target does not exist\n",
|
||||||
ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint), exten, context);
|
ast_channel_name(session->channel), ast_sorcery_object_get_id(session->endpoint), exten, context);
|
||||||
|
@@ -626,6 +626,12 @@ static struct ast_sip_aor *find_registrar_aor(struct pjsip_rx_data *rdata, struc
|
|||||||
username = ast_alloca(uri->user.slen + 1);
|
username = ast_alloca(uri->user.slen + 1);
|
||||||
ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
|
ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match without any user options getting
|
||||||
|
* in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(username);
|
||||||
|
|
||||||
aor_name = find_aor_name(username, domain_name, endpoint->aors);
|
aor_name = find_aor_name(username, domain_name, endpoint->aors);
|
||||||
if (aor_name) {
|
if (aor_name) {
|
||||||
ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
|
ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
|
||||||
|
@@ -1982,6 +1982,12 @@ static enum sip_get_destination_result get_destination(struct ast_sip_session *s
|
|||||||
sip_ruri = pjsip_uri_get_uri(ruri);
|
sip_ruri = pjsip_uri_get_uri(ruri);
|
||||||
ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten));
|
ast_copy_pj_str(session->exten, &sip_ruri->user, sizeof(session->exten));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match in the dialplan without any user
|
||||||
|
* options getting in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(session->exten);
|
||||||
|
|
||||||
pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
|
pickup_cfg = ast_get_chan_features_pickup_config(session->channel);
|
||||||
if (!pickup_cfg) {
|
if (!pickup_cfg) {
|
||||||
ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
|
ast_log(LOG_ERROR, "Unable to retrieve pickup configuration options. Unable to detect call pickup extension\n");
|
||||||
@@ -3095,6 +3101,13 @@ static pjsip_redirect_op session_inv_on_redirected(pjsip_inv_session *inv, const
|
|||||||
char exten[AST_MAX_EXTENSION];
|
char exten[AST_MAX_EXTENSION];
|
||||||
|
|
||||||
ast_copy_pj_str(exten, &uri->user, sizeof(exten));
|
ast_copy_pj_str(exten, &uri->user, sizeof(exten));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* We may want to match in the dialplan without any user
|
||||||
|
* options getting in the way.
|
||||||
|
*/
|
||||||
|
AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(exten);
|
||||||
|
|
||||||
ast_channel_call_forward_set(session->channel, exten);
|
ast_channel_call_forward_set(session->channel, exten);
|
||||||
} else if (session->endpoint->redirect_method == AST_SIP_REDIRECT_URI_CORE) {
|
} else if (session->endpoint->redirect_method == AST_SIP_REDIRECT_URI_CORE) {
|
||||||
char target_uri[PJSIP_MAX_URL_SIZE];
|
char target_uri[PJSIP_MAX_URL_SIZE];
|
||||||
|
Reference in New Issue
Block a user