summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CHANGES6
-rw-r--r--configs/samples/pjsip.conf.sample4
-rw-r--r--contrib/ast-db-manage/config/versions/45e3f47c6c44_add_pjsip_endpoint_identifier_order.py21
-rw-r--r--include/asterisk/res_pjsip.h26
-rw-r--r--res/res_pjsip.c119
-rw-r--r--res/res_pjsip/config_global.c21
-rw-r--r--res/res_pjsip_endpoint_identifier_anonymous.c2
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c2
-rw-r--r--res/res_pjsip_endpoint_identifier_user.c2
9 files changed, 196 insertions, 7 deletions
diff --git a/CHANGES b/CHANGES
index 749338a4c..6d2e9c730 100644
--- a/CHANGES
+++ b/CHANGES
@@ -26,6 +26,12 @@ res_ari_channels
technologies, this is either a 302 Redirect response to an on-going INVITE
dialog or a SIP REFER request.
+res_pjsip
+------------------
+ * A new 'endpoint_identifier_order' option has been added that allows one to
+ set the order by which endpoint identifiers are processed and checked. This
+ option is specified under the 'global' type configuration section.
+
------------------------------------------------------------------------------
--- Functionality changes from Asterisk 13.1.0 to Asterisk 13.2.0 ------------
------------------------------------------------------------------------------
diff --git a/configs/samples/pjsip.conf.sample b/configs/samples/pjsip.conf.sample
index a214c0e6e..af417cd1b 100644
--- a/configs/samples/pjsip.conf.sample
+++ b/configs/samples/pjsip.conf.sample
@@ -854,6 +854,10 @@
;keep_alive_interval=20 ; The interval (in seconds) at which to send keepalive
; messages on all active connection-oriented transports
; (default: "0")
+;endpoint_identifier_order=ip,username,anonymous
+ ; The order by which endpoint identifiers are given priority.
+ ; Identifier names are derived from res_pjsip_endpoint_identifier_*
+ ; modules. (default: ip,username,anonymous)
; MODULE PROVIDING BELOW SECTION(S): res_pjsip_acl
diff --git a/contrib/ast-db-manage/config/versions/45e3f47c6c44_add_pjsip_endpoint_identifier_order.py b/contrib/ast-db-manage/config/versions/45e3f47c6c44_add_pjsip_endpoint_identifier_order.py
index e69de29bb..213da92fb 100644
--- a/contrib/ast-db-manage/config/versions/45e3f47c6c44_add_pjsip_endpoint_identifier_order.py
+++ b/contrib/ast-db-manage/config/versions/45e3f47c6c44_add_pjsip_endpoint_identifier_order.py
@@ -0,0 +1,21 @@
+"""add pjsip endpoint_identifier_order
+
+Revision ID: 45e3f47c6c44
+Revises: 371a3bf4143e
+Create Date: 2015-03-02 09:32:20.632015
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = '45e3f47c6c44'
+down_revision = '371a3bf4143e'
+
+from alembic import op
+import sqlalchemy as sa
+
+
+def upgrade():
+ op.add_column('ps_globals', sa.Column('endpoint_identifier_order', sa.String(40)))
+
+def downgrade():
+ op.drop_column('ps_globals', 'endpoint_identifier_order')
diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h
index 3dbec9856..2576bc3c1 100644
--- a/include/asterisk/res_pjsip.h
+++ b/include/asterisk/res_pjsip.h
@@ -778,6 +778,23 @@ int ast_sip_register_outbound_authenticator(struct ast_sip_outbound_authenticato
void ast_sip_unregister_outbound_authenticator(struct ast_sip_outbound_authenticator *auth);
/*!
+ * \brief Register a SIP endpoint identifier with a name.
+ *
+ * An endpoint identifier's purpose is to determine which endpoint a given SIP
+ * message has come from.
+ *
+ * Multiple endpoint identifiers may be registered so that if an endpoint
+ * cannot be identified by one identifier, it may be identified by another.
+ *
+ * \param identifier The SIP endpoint identifier to register
+ * \param name The name of the endpoint identifier
+ * \retval 0 Success
+ * \retval -1 Failure
+ */
+int ast_sip_register_endpoint_identifier_by_name(struct ast_sip_endpoint_identifier *identifier,
+ const char *name);
+
+/*!
* \brief Register a SIP endpoint identifier
*
* An endpoint identifier's purpose is to determine which endpoint a given SIP
@@ -1881,6 +1898,15 @@ void ast_sip_unregister_supplement(struct ast_sip_supplement *supplement);
*/
char *ast_sip_get_debug(void);
+/*!
+ * \brief Retrieve the global endpoint_identifier_order setting.
+ *
+ * Specifies the order by which endpoint identifiers should be regarded.
+ *
+ * \retval the global endpoint_identifier_order value
+ */
+char *ast_sip_get_endpoint_identifier_order(void);
+
/*! \brief Determines whether the res_pjsip module is loaded */
#define CHECK_PJSIP_MODULE_LOADED() \
do { \
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index 20ac7a03e..b56b3aec3 100644
--- a/res/res_pjsip.c
+++ b/res/res_pjsip.c
@@ -36,6 +36,7 @@
#include "asterisk/uuid.h"
#include "asterisk/sorcery.h"
#include "asterisk/file.h"
+#include "asterisk/cli.h"
/*** MODULEINFO
<depend>pjproject</depend>
@@ -1193,6 +1194,11 @@
<synopsis>Enable/Disable SIP debug logging. Valid options include yes|no or
a host address</synopsis>
</configOption>
+ <configOption name="endpoint_identifier_order" default="ip,username,anonymous">
+ <synopsis>The order by which endpoint identifiers are processed and checked.
+ Identifier names are usually derived from and can be found in the endpoint
+ identifier module itself (res_pjsip_endpoint_identifier_*)</synopsis>
+ </configOption>
</configObject>
</configFile>
</configInfo>
@@ -1958,15 +1964,19 @@ int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pj
}
struct endpoint_identifier_list {
+ const char *name;
+ unsigned int priority;
struct ast_sip_endpoint_identifier *identifier;
AST_RWLIST_ENTRY(endpoint_identifier_list) list;
};
static AST_RWLIST_HEAD_STATIC(endpoint_identifiers, endpoint_identifier_list);
-int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
+int ast_sip_register_endpoint_identifier_by_name(struct ast_sip_endpoint_identifier *identifier,
+ const char *name)
{
- struct endpoint_identifier_list *id_list_item;
+ char *prev, *current, *identifier_order;
+ struct endpoint_identifier_list *iter, *id_list_item;
SCOPED_LOCK(lock, &endpoint_identifiers, AST_RWLIST_WRLOCK, AST_RWLIST_UNLOCK);
id_list_item = ast_calloc(1, sizeof(*id_list_item));
@@ -1975,14 +1985,78 @@ int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *ide
return -1;
}
id_list_item->identifier = identifier;
+ id_list_item->name = name;
+
+ ast_debug(1, "Register endpoint identifier %s (%p)\n", name, identifier);
+
+ if (ast_strlen_zero(name)) {
+ /* if an identifier has no name then place in front */
+ AST_RWLIST_INSERT_HEAD(&endpoint_identifiers, id_list_item, list);
+ ast_module_ref(ast_module_info->self);
+ return 0;
+ }
+
+ /* see if the name of the identifier is in the global endpoint_identifier_order list */
+ identifier_order = prev = current = ast_sip_get_endpoint_identifier_order();
+
+ if (ast_strlen_zero(identifier_order)) {
+ id_list_item->priority = UINT_MAX;
+ AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
+ ast_module_ref(ast_module_info->self);
+ ast_free(identifier_order);
+ return 0;
+ }
+
+ id_list_item->priority = 0;
+ while ((current = strchr(current, ','))) {
+ ++id_list_item->priority;
+ if (!strncmp(prev, name, current - prev)) {
+ break;
+ }
+ prev = ++current;
+ }
+
+ if (!current) {
+ /* check to see if it is the only or last item */
+ if (!strcmp(prev, name)) {
+ ++id_list_item->priority;
+ } else {
+ id_list_item->priority = UINT_MAX;
+ }
+ }
+
+ if (id_list_item->priority == UINT_MAX || AST_RWLIST_EMPTY(&endpoint_identifiers)) {
+ /* if not in the endpoint_identifier_order list then consider it less in
+ priority and add it to the end */
+ AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
+ ast_module_ref(ast_module_info->self);
+ ast_free(identifier_order);
+ return 0;
+ }
+
+ AST_RWLIST_TRAVERSE_SAFE_BEGIN(&endpoint_identifiers, iter, list) {
+ if (id_list_item->priority < iter->priority) {
+ AST_RWLIST_INSERT_BEFORE_CURRENT(id_list_item, list);
+ break;
+ }
- AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
- ast_debug(1, "Registered endpoint identifier %p\n", identifier);
+ if (!AST_RWLIST_NEXT(iter, list)) {
+ AST_RWLIST_INSERT_AFTER(&endpoint_identifiers, iter, id_list_item, list);
+ break;
+ }
+ }
+ AST_RWLIST_TRAVERSE_SAFE_END;
ast_module_ref(ast_module_info->self);
+ ast_free(identifier_order);
return 0;
}
+int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
+{
+ return ast_sip_register_endpoint_identifier_by_name(identifier, NULL);
+}
+
void ast_sip_unregister_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
{
struct endpoint_identifier_list *iter;
@@ -2014,6 +2088,41 @@ struct ast_sip_endpoint *ast_sip_identify_endpoint(pjsip_rx_data *rdata)
return endpoint;
}
+static char *cli_show_endpoint_identifiers(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
+{
+#define ENDPOINT_IDENTIFIER_FORMAT "%-20.20s\n"
+ struct endpoint_identifier_list *iter;
+
+ switch (cmd) {
+ case CLI_INIT:
+ e->command = "pjsip show identifiers";
+ e->usage = "Usage: pjsip show identifiers\n"
+ " List all registered endpoint identifiers\n";
+ return NULL;
+ case CLI_GENERATE:
+ return NULL;
+ }
+
+ if (a->argc != 3) {
+ return CLI_SHOWUSAGE;
+ }
+
+ ast_cli(a->fd, ENDPOINT_IDENTIFIER_FORMAT, "Identifier Names:");
+ {
+ SCOPED_LOCK(lock, &endpoint_identifiers, AST_RWLIST_RDLOCK, AST_RWLIST_UNLOCK);
+ AST_RWLIST_TRAVERSE(&endpoint_identifiers, iter, list) {
+ ast_cli(a->fd, ENDPOINT_IDENTIFIER_FORMAT,
+ iter->name ? iter->name : "name not specified");
+ }
+ }
+ return CLI_SUCCESS;
+#undef ENDPOINT_IDENTIFIER_FORMAT
+}
+
+static struct ast_cli_entry cli_commands[] = {
+ AST_CLI_DEFINE(cli_show_endpoint_identifiers, "List registered endpoint identifiers")
+};
+
AST_RWLIST_HEAD_STATIC(endpoint_formatters, ast_sip_endpoint_formatter);
void internal_sip_register_endpoint_formatter(struct ast_sip_endpoint_formatter *obj)
@@ -3356,6 +3465,7 @@ static int load_module(void)
}
ast_res_pjsip_init_options_handling(0);
+ ast_cli_register_multiple(cli_commands, ARRAY_LEN(cli_commands));
return AST_MODULE_LOAD_SUCCESS;
}
@@ -3376,6 +3486,7 @@ static int reload_module(void)
static int unload_pjsip(void *data)
{
+ ast_cli_unregister_multiple(cli_commands, ARRAY_LEN(cli_commands));
if (memory_pool) {
pj_pool_release(memory_pool);
memory_pool = NULL;
diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c
index 4cf26f2a4..682e3c0b1 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -31,6 +31,7 @@
#define DEFAULT_USERAGENT_PREFIX "Asterisk PBX"
#define DEFAULT_OUTBOUND_ENDPOINT "default_outbound_endpoint"
#define DEFAULT_DEBUG "no"
+#define DEFAULT_ENDPOINT_IDENTIFIER_ORDER "ip,username,anonymous"
static char default_useragent[256];
@@ -41,6 +42,8 @@ struct global_config {
AST_STRING_FIELD(default_outbound_endpoint);
/*! Debug logging yes|no|host */
AST_STRING_FIELD(debug);
+ /*! Order by which endpoint identifiers are checked (comma separated list) */
+ AST_STRING_FIELD(endpoint_identifier_order);
);
/* Value to put in Max-Forwards header */
unsigned int max_forwards;
@@ -127,6 +130,21 @@ char *ast_sip_get_debug(void)
return res;
}
+char *ast_sip_get_endpoint_identifier_order(void)
+{
+ char *res;
+ struct global_config *cfg;
+
+ cfg = get_global_cfg();
+ if (!cfg) {
+ return ast_strdup(DEFAULT_ENDPOINT_IDENTIFIER_ORDER);
+ }
+
+ res = ast_strdup(cfg->endpoint_identifier_order);
+ ao2_ref(cfg, -1);
+ return res;
+}
+
unsigned int ast_sip_get_keep_alive_interval(void)
{
unsigned int interval;
@@ -228,6 +246,9 @@ int ast_sip_initialize_sorcery_global(void)
OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, default_outbound_endpoint));
ast_sorcery_object_field_register(sorcery, "global", "debug", DEFAULT_DEBUG,
OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, debug));
+ ast_sorcery_object_field_register(sorcery, "global", "endpoint_identifier_order",
+ DEFAULT_ENDPOINT_IDENTIFIER_ORDER,
+ OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, endpoint_identifier_order));
ast_sorcery_object_field_register(sorcery, "global", "keep_alive_interval",
__stringify(DEFAULT_KEEPALIVE_INTERVAL),
OPT_UINT_T, 0, FLDSET(struct global_config, keep_alive_interval));
diff --git a/res/res_pjsip_endpoint_identifier_anonymous.c b/res/res_pjsip_endpoint_identifier_anonymous.c
index a7956b589..f191d99cf 100644
--- a/res/res_pjsip_endpoint_identifier_anonymous.c
+++ b/res/res_pjsip_endpoint_identifier_anonymous.c
@@ -110,7 +110,7 @@ static int load_module(void)
{
CHECK_PJSIP_MODULE_LOADED();
- ast_sip_register_endpoint_identifier(&anonymous_identifier);
+ ast_sip_register_endpoint_identifier_by_name(&anonymous_identifier, "anonymous");
return AST_MODULE_LOAD_SUCCESS;
}
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index 4bd4f122e..b97724e3f 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -491,7 +491,7 @@ static int load_module(void)
ast_sorcery_object_field_register_custom(ast_sip_get_sorcery(), "identify", "match", "", ip_identify_match_handler, match_to_str, match_to_var_list, 0, 0);
ast_sorcery_reload_object(ast_sip_get_sorcery(), "identify");
- ast_sip_register_endpoint_identifier(&ip_identifier);
+ ast_sip_register_endpoint_identifier_by_name(&ip_identifier, "ip");
ast_sip_register_endpoint_formatter(&endpoint_identify_formatter);
cli_formatter = ao2_alloc(sizeof(struct ast_sip_cli_formatter_entry), NULL);
diff --git a/res/res_pjsip_endpoint_identifier_user.c b/res/res_pjsip_endpoint_identifier_user.c
index beae1cdd4..a60057e14 100644
--- a/res/res_pjsip_endpoint_identifier_user.c
+++ b/res/res_pjsip_endpoint_identifier_user.c
@@ -116,7 +116,7 @@ static int load_module(void)
{
CHECK_PJSIP_MODULE_LOADED();
- ast_sip_register_endpoint_identifier(&username_identifier);
+ ast_sip_register_endpoint_identifier_by_name(&username_identifier, "username");
return AST_MODULE_LOAD_SUCCESS;
}