diff options
-rw-r--r-- | CHANGES | 6 | ||||
-rw-r--r-- | configs/samples/pjsip.conf.sample | 4 | ||||
-rw-r--r-- | contrib/ast-db-manage/config/versions/45e3f47c6c44_add_pjsip_endpoint_identifier_order.py | 21 | ||||
-rw-r--r-- | include/asterisk/res_pjsip.h | 26 | ||||
-rw-r--r-- | res/res_pjsip.c | 119 | ||||
-rw-r--r-- | res/res_pjsip/config_global.c | 21 | ||||
-rw-r--r-- | res/res_pjsip_endpoint_identifier_anonymous.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_endpoint_identifier_ip.c | 2 | ||||
-rw-r--r-- | res/res_pjsip_endpoint_identifier_user.c | 2 |
9 files changed, 196 insertions, 7 deletions
@@ -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; } |