From 993ae9a669778aa9e8edcc42e3183b12e80a4d69 Mon Sep 17 00:00:00 2001 From: Mark Michelson Date: Fri, 4 Sep 2015 14:40:38 -0500 Subject: [PATCH] res_pjsip: Change default from user value. When Asterisk sends an outbound SIP request, if there is no direct reason to place a specific value for the username in the From header, Asterisk would generate a UUID. For example, this would happen when sending outbound OPTIONS requests when qualifying or when sending outbound INVITE requests when originating (if no explicit caller ID were provided). The issue is that some SIP providers reject these sorts of requests with a "Name too long" error response. This patch aims to fix this by changing the default outbound username in From headers to "asterisk". This value can be overridden by changing the default_from_user option in the global options if desired. ASTERISK-25377 #close Reported by Mark Michelson Change-Id: I6a4d34a56ff73ff4f661b0075aeba5461b7f3190 --- .../154177371065_add_default_from_user.py | 22 +++++++++++++++++++ include/asterisk/res_pjsip.h | 11 ++++++++++ res/res_pjsip.c | 8 +++++-- res/res_pjsip/config_global.c | 21 ++++++++++++++++++ 4 files changed, 60 insertions(+), 2 deletions(-) create mode 100644 contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py diff --git a/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py new file mode 100644 index 0000000000..7e6cf994f6 --- /dev/null +++ b/contrib/ast-db-manage/config/versions/154177371065_add_default_from_user.py @@ -0,0 +1,22 @@ +"""add default_from_user + +Revision ID: 154177371065 +Revises: 26f10cadc157 +Create Date: 2015-09-04 14:13:59.195013 + +""" + +# revision identifiers, used by Alembic. +revision = '154177371065' +down_revision = '26f10cadc157' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column('ps_globals', sa.Column('default_from_user', sa.String(80))) + + +def downgrade(): + op.drop_column('ps_globals', 'default_from_user') diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 508a7be381..b7b875d0f9 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -2018,6 +2018,17 @@ char *ast_sip_get_debug(void); */ char *ast_sip_get_endpoint_identifier_order(void); +/*! + * \brief Retrieve the global default from user. + * + * This is the value placed in outbound requests' From header if there + * is no better option (such as an endpoint-configured from_user or + * caller ID number). + * + * \retval The global default_from_user value. + */ +const char *ast_sip_get_default_from_user(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 b8463cecda..4af886b4ba 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -1286,6 +1286,11 @@ Identifier names are usually derived from and can be found in the endpoint identifier module itself (res_pjsip_endpoint_identifier_*) + + When Asterisk generates an outgoing SIP request, the From header username will be + set to this value if there is no better option (such as CallerID) to be + used. + @@ -2333,10 +2338,9 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u pjsip_sip_uri *sip_uri; pjsip_transport_type_e type = PJSIP_TRANSPORT_UNSPECIFIED; int local_port; - char uuid_str[AST_UUID_STR_LEN]; if (ast_strlen_zero(user)) { - user = ast_uuid_generate_str(uuid_str, sizeof(uuid_str)); + user = ast_sip_get_default_from_user(); } /* Parse the provided target URI so we can determine what transport it will end up using */ diff --git a/res/res_pjsip/config_global.c b/res/res_pjsip/config_global.c index 42ba23487c..b348896c8f 100644 --- a/res/res_pjsip/config_global.c +++ b/res/res_pjsip/config_global.c @@ -34,6 +34,7 @@ #define DEFAULT_DEBUG "no" #define DEFAULT_ENDPOINT_IDENTIFIER_ORDER "ip,username,anonymous" #define DEFAULT_MAX_INITIAL_QUALIFY_TIME 0 +#define DEFAULT_FROM_USER "asterisk" static char default_useragent[256]; @@ -46,6 +47,8 @@ struct global_config { AST_STRING_FIELD(debug); /*! Order by which endpoint identifiers are checked (comma separated list) */ AST_STRING_FIELD(endpoint_identifier_order); + /*! User name to place in From header if there is no better option */ + AST_STRING_FIELD(default_from_user); ); /* Value to put in Max-Forwards header */ unsigned int max_forwards; @@ -179,6 +182,22 @@ unsigned int ast_sip_get_max_initial_qualify_time(void) return time; } +const char *ast_sip_get_default_from_user(void) +{ + const char *from_user; + struct global_config *cfg; + + cfg = get_global_cfg(); + if (!cfg) { + return DEFAULT_FROM_USER; + } + + from_user = cfg->default_from_user; + ao2_ref(cfg, -1); + + return from_user; +} + /*! * \internal * \brief Observer to set default global object if none exist. @@ -292,6 +311,8 @@ int ast_sip_initialize_sorcery_global(void) ast_sorcery_object_field_register(sorcery, "global", "max_initial_qualify_time", __stringify(DEFAULT_MAX_INITIAL_QUALIFY_TIME), OPT_UINT_T, 0, FLDSET(struct global_config, max_initial_qualify_time)); + ast_sorcery_object_field_register(sorcery, "global", "default_from_user", DEFAULT_FROM_USER, + OPT_STRINGFIELD_T, 0, STRFLDSET(struct global_config, default_from_user)); if (ast_sorcery_instance_observer_add(sorcery, &observer_callbacks_global)) { return -1;