diff --git a/include/asterisk/res_pjsip.h b/include/asterisk/res_pjsip.h index 2fafd5790a..08b140db90 100644 --- a/include/asterisk/res_pjsip.h +++ b/include/asterisk/res_pjsip.h @@ -236,6 +236,8 @@ struct ast_sip_transport { AST_STRING_FIELD(external_media_address); /*! Optional domain to use for messages if provided could not be found */ AST_STRING_FIELD(domain); + /*! Optional username suffix to use in endpoint lookups by username */ + AST_STRING_FIELD(endpoint_suffix); ); /*! Type of transport */ enum ast_transport type; diff --git a/res/res_pjsip/config_transport.c b/res/res_pjsip/config_transport.c index 2acf9a9312..60fb86e02c 100644 --- a/res/res_pjsip/config_transport.c +++ b/res/res_pjsip/config_transport.c @@ -1830,6 +1830,7 @@ int ast_sip_initialize_sorcery_transport(void) ast_sorcery_object_field_register(sorcery, "transport", "external_signaling_port", "0", OPT_UINT_T, PARSE_IN_RANGE, FLDSET(struct ast_sip_transport, external_signaling_port), 0, 65535); ast_sorcery_object_field_register(sorcery, "transport", "external_media_address", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, external_media_address)); ast_sorcery_object_field_register(sorcery, "transport", "domain", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, domain)); + ast_sorcery_object_field_register(sorcery, "transport", "endpoint_suffix", "", OPT_STRINGFIELD_T, 0, STRFLDSET(struct ast_sip_transport, endpoint_suffix)); ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_server", "", transport_tls_bool_handler, verify_server_to_str, NULL, 0, 0); ast_sorcery_object_field_register_custom(sorcery, "transport", "verify_client", "", transport_tls_bool_handler, verify_client_to_str, NULL, 0, 0); ast_sorcery_object_field_register_custom(sorcery, "transport", "require_client_cert", "", transport_tls_bool_handler, require_client_cert_to_str, NULL, 0, 0); diff --git a/res/res_pjsip_endpoint_identifier_user.c b/res/res_pjsip_endpoint_identifier_user.c index bc3f0902a4..73dfe57685 100644 --- a/res/res_pjsip_endpoint_identifier_user.c +++ b/res/res_pjsip_endpoint_identifier_user.c @@ -75,19 +75,36 @@ static int find_transport_state_in_use(void *obj, void *arg, int flags) return 0; } +static struct ast_sip_transport* find_transport(pjsip_rx_data *rdata) +{ + struct ao2_container *transport_states; + struct ast_sip_transport_state *transport_state = NULL; + struct ast_sip_transport *transport = NULL; + + transport_states = ast_sip_get_transport_states(); + if (transport_states) { + transport_state = ao2_callback(transport_states, 0, find_transport_state_in_use, rdata); + } + if (transport_state) { + transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id); + } + + ao2_cleanup(transport_state); + ao2_cleanup(transport_states); + + return transport; +} + #define DOMAIN_NAME_LEN 255 #define USERNAME_LEN 255 -static struct ast_sip_endpoint *find_endpoint(pjsip_rx_data *rdata, char *endpoint_name, - char *domain_name) +static struct ast_sip_endpoint *find_endpoint2(pjsip_rx_data *rdata, char *endpoint_name, + char *domain_name, struct ast_sip_transport *transport) { struct ast_sip_endpoint *endpoint; if (!ast_sip_get_disable_multi_domain()) { struct ast_sip_domain_alias *alias; - struct ao2_container *transport_states; - struct ast_sip_transport_state *transport_state = NULL; - struct ast_sip_transport *transport = NULL; char id[DOMAIN_NAME_LEN + USERNAME_LEN + sizeof("@")]; /* Attempt to find the endpoint given the name and domain provided */ @@ -110,16 +127,11 @@ static struct ast_sip_endpoint *find_endpoint(pjsip_rx_data *rdata, char *endpoi } /* See if the transport this came in on has a provided domain */ - if ((transport_states = ast_sip_get_transport_states()) - && (transport_state = ao2_callback(transport_states, 0, find_transport_state_in_use, rdata)) - && (transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id)) - && !ast_strlen_zero(transport->domain)) { + if (transport && !ast_strlen_zero(transport->domain)) { snprintf(id, sizeof(id), "%s@%s", endpoint_name, transport->domain); endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id); } - ao2_cleanup(transport); - ao2_cleanup(transport_state); - ao2_cleanup(transport_states); + if (endpoint) { return endpoint; } @@ -129,6 +141,26 @@ static struct ast_sip_endpoint *find_endpoint(pjsip_rx_data *rdata, char *endpoi return ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", endpoint_name); } +static struct ast_sip_endpoint *find_endpoint(pjsip_rx_data *rdata, char *endpoint_base, + char *domain_name) +{ + struct ast_sip_endpoint *endpoint = NULL; + struct ast_sip_transport *transport = find_transport(rdata); + + if (transport &&!!ast_strlen_zero(transport->endpoint_suffix)) { + char endpoint_full[USERNAME_LEN + 1]; + snprintf(endpoint_full, sizeof(endpoint_full), "%s%s", endpoint_base, transport->endpoint_suffix); + endpoint = find_endpoint2(rdata, endpoint_full, domain_name, transport); + } + + if (!endpoint) { + endpoint = find_endpoint2(rdata, endpoint_base, domain_name, transport); + } + ao2_cleanup(transport); + + return endpoint; +} + static struct ast_sip_endpoint *username_identify(pjsip_rx_data *rdata) { char username[USERNAME_LEN + 1];