summaryrefslogtreecommitdiff
path: root/res
diff options
context:
space:
mode:
authorKevin Harwell <kharwell@digium.com>2015-03-09 16:13:40 +0000
committerKevin Harwell <kharwell@digium.com>2015-03-09 16:13:40 +0000
commit1ce529d30e900054b9d2417380945d451012313f (patch)
treed22e4bf5bd4562cb21237677e86ee2b8744b307c /res
parenta5f80f17813241cdfe32947722f9845bc32bcd87 (diff)
res_pjsip: allow configuration of endpoint identifier query order
It's possible to have a scenario that will create a conflict between endpoint identifiers. For instance an incoming call could be identified by two different endpoint identifiers and the one chosen depended upon which identifier module loaded first. This of course causes problems when, for example, the incoming call is expected to be identified by username, but instead is identified by ip. This patch adds a new 'global' option to res_pjsip called 'endpoint_identifier_order'. It is a comma separated list of endpoint identifier names that specifies the order by which identifiers are processed and checked. ASTERISK-24840 #close Reported by: Mark Michelson Review: https://reviewboard.asterisk.org/r/4455/ ........ Merged revisions 432638 from http://svn.asterisk.org/svn/asterisk/branches/13 git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@432639 65c4cc65-6c06-0410-ace0-fbb531ad65f3
Diffstat (limited to 'res')
-rw-r--r--res/res_pjsip.c108
-rw-r--r--res/res_pjsip/config_global.c21
-rw-r--r--res/res_pjsip_endpoint_identifier_anonymous.c1
-rw-r--r--res/res_pjsip_endpoint_identifier_ip.c1
-rw-r--r--res/res_pjsip_endpoint_identifier_user.c1
5 files changed, 128 insertions, 4 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c
index f063d7963..423576ee0 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>
@@ -1196,6 +1197,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>
@@ -1964,6 +1970,7 @@ int ast_sip_create_request_with_auth(const struct ast_sip_auth_vector *auths, pj
}
struct endpoint_identifier_list {
+ unsigned int priority;
struct ast_sip_endpoint_identifier *identifier;
AST_RWLIST_ENTRY(endpoint_identifier_list) list;
};
@@ -1972,7 +1979,8 @@ static AST_RWLIST_HEAD_STATIC(endpoint_identifiers, endpoint_identifier_list);
int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *identifier)
{
- 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));
@@ -1982,10 +1990,67 @@ int ast_sip_register_endpoint_identifier(struct ast_sip_endpoint_identifier *ide
}
id_list_item->identifier = identifier;
- AST_RWLIST_INSERT_TAIL(&endpoint_identifiers, id_list_item, list);
- ast_debug(1, "Registered endpoint identifier %p\n", identifier);
+ ast_debug(1, "Register endpoint identifier %s (%p)\n", identifier->name, identifier);
+
+ if (ast_strlen_zero(identifier->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)) {
+ 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, identifier->name, current - prev)) {
+ break;
+ }
+ prev = ++current;
+ }
+
+ if (!current) {
+ /* check to see if it the only or last item */
+ if (!strcmp(prev, identifier->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;
+ }
+
+ 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;
}
@@ -2020,6 +2085,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->identifier->name ? iter->identifier->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 +3456,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 +3477,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 1779c535d..21800850e 100644
--- a/res/res_pjsip/config_global.c
+++ b/res/res_pjsip/config_global.c
@@ -39,6 +39,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;
@@ -57,7 +59,7 @@ static void *global_alloc(const char *name)
{
struct global_config *cfg = ast_sorcery_generic_alloc(sizeof(*cfg), global_destructor);
- if (!cfg || ast_string_field_init(cfg, 80)) {
+ if (!cfg || ast_string_field_init(cfg, 100)) {
return NULL;
}
@@ -116,6 +118,21 @@ char *ast_sip_get_debug(void)
return res;
}
+char *ast_sip_get_endpoint_identifier_order(void)
+{
+ char *res;
+ struct global_config *cfg = get_global_cfg();
+
+ if (!cfg) {
+ return ast_strdup("ip,username,anonymous");
+ }
+
+ 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;
@@ -152,6 +169,8 @@ 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", "no",
OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, debug));
+ ast_sorcery_object_field_register(sorcery, "global", "endpoint_identifier_order", "ip,username,anonymous",
+ OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, endpoint_identifier_order));
ast_sorcery_object_field_register(sorcery, "global", "keep_alive_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..4ce945a7b 100644
--- a/res/res_pjsip_endpoint_identifier_anonymous.c
+++ b/res/res_pjsip_endpoint_identifier_anonymous.c
@@ -103,6 +103,7 @@ done:
}
static struct ast_sip_endpoint_identifier anonymous_identifier = {
+ .name = "anonymous",
.identify_endpoint = anonymous_identify,
};
diff --git a/res/res_pjsip_endpoint_identifier_ip.c b/res/res_pjsip_endpoint_identifier_ip.c
index 4bd4f122e..d1c91a27c 100644
--- a/res/res_pjsip_endpoint_identifier_ip.c
+++ b/res/res_pjsip_endpoint_identifier_ip.c
@@ -150,6 +150,7 @@ static struct ast_sip_endpoint *ip_identify(pjsip_rx_data *rdata)
}
static struct ast_sip_endpoint_identifier ip_identifier = {
+ .name = "ip",
.identify_endpoint = ip_identify,
};
diff --git a/res/res_pjsip_endpoint_identifier_user.c b/res/res_pjsip_endpoint_identifier_user.c
index beae1cdd4..a5c9411f9 100644
--- a/res/res_pjsip_endpoint_identifier_user.c
+++ b/res/res_pjsip_endpoint_identifier_user.c
@@ -109,6 +109,7 @@ done:
}
static struct ast_sip_endpoint_identifier username_identifier = {
+ .name = "username",
.identify_endpoint = username_identify,
};