mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 11:25:35 +00:00
res_pjsip: Fix infinite recursion when loading transports from realtime
Attempting to load a transport from realtime was forcing asterisk into an infinite recursion loop. The first thing transport_apply did was to do a sorcery retrieve by id for an existing transport of the same name. For files, this just returns the previous object from res_sorcery_config's internal container, if any. For realtime, the res_sourcery_realtime driver looks in the database and finds the existing row but now it has to rehydrate it into a sorcery object which means calling... transport_apply. And so it goes. The main issue with loading from realtime (apart from the loop) was that transport stores structures and pointers directly in the ast_sip_transport structure instead of the separate ast_transport_state structure. This patch separates those items into the ast_sip_transport_state structure. The pattern is roughly the same as res_pjsip_outbound_registration. Although all current usages of ast_sip_transport and ast_sip_transport_state were modified to use the new ast_sip_get_transport_state API, the original items are left in ast_sip_transport and kept updated to maintain ABI compatability for third-party modules. They are marked as deprecated and noted that they're now in ast_sip_transport_state. ASTERISK-25606 #close Reported-by: Martin Moučka Change-Id: Ic7a836ea8e786e8def51fe3f8cce855ea54f5f19
This commit is contained in:
@@ -42,14 +42,14 @@ static int get_endpoint_details(pjsip_rx_data *rdata, char *endpoint, size_t end
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int find_transport_in_use(void *obj, void *arg, int flags)
|
||||
static int find_transport_state_in_use(void *obj, void *arg, int flags)
|
||||
{
|
||||
struct ast_sip_transport *transport = obj;
|
||||
struct ast_sip_transport_state *transport_state = obj;
|
||||
pjsip_rx_data *rdata = arg;
|
||||
|
||||
if ((transport->state->transport == rdata->tp_info.transport) ||
|
||||
(transport->state->factory && !pj_strcmp(&transport->state->factory->addr_name.host, &rdata->tp_info.transport->local_name.host) &&
|
||||
transport->state->factory->addr_name.port == rdata->tp_info.transport->local_name.port)) {
|
||||
if (transport_state && ((transport_state->transport == rdata->tp_info.transport) ||
|
||||
(transport_state->factory && !pj_strcmp(&transport_state->factory->addr_name.host, &rdata->tp_info.transport->local_name.host) &&
|
||||
transport_state->factory->addr_name.port == rdata->tp_info.transport->local_name.port))) {
|
||||
return CMP_MATCH | CMP_STOP;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,8 @@ static struct ast_sip_endpoint *username_identify(pjsip_rx_data *rdata)
|
||||
char endpoint_name[64], domain_name[64], id[AST_UUID_STR_LEN];
|
||||
struct ast_sip_endpoint *endpoint;
|
||||
RAII_VAR(struct ast_sip_domain_alias *, alias, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ao2_container *, transports, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ao2_container *, transport_states, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_sip_transport_state *, transport_state, NULL, ao2_cleanup);
|
||||
RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup);
|
||||
|
||||
if (get_endpoint_details(rdata, endpoint_name, sizeof(endpoint_name), domain_name, sizeof(domain_name))) {
|
||||
@@ -83,10 +84,11 @@ static struct ast_sip_endpoint *username_identify(pjsip_rx_data *rdata)
|
||||
}
|
||||
|
||||
/* See if the transport this came in on has a provided domain */
|
||||
if ((transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL)) &&
|
||||
(transport = ao2_callback(transports, 0, find_transport_in_use, rdata)) &&
|
||||
!ast_strlen_zero(transport->domain)) {
|
||||
snprintf(id, sizeof(id), "%s@%s", endpoint_name, transport->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)) {
|
||||
snprintf(id, sizeof(id), "anonymous@%s", transport->domain);
|
||||
if ((endpoint = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "endpoint", id))) {
|
||||
goto done;
|
||||
}
|
||||
|
Reference in New Issue
Block a user