diff options
author | George Joseph <george.joseph@fairview5.com> | 2016-01-29 16:56:42 -0700 |
---|---|---|
committer | George Joseph <george.joseph@fairview5.com> | 2016-02-08 19:11:18 -0600 |
commit | bbf3ace68292c136ae0455332a1893de4c4b4c13 (patch) | |
tree | 02ccd7a6a471d095cfbeba6bfc53c1f6e8688b4d /res/res_pjsip_endpoint_identifier_anonymous.c | |
parent | 7e4378770d6c459702e07ecf01c9fc6e1400c207 (diff) |
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
Diffstat (limited to 'res/res_pjsip_endpoint_identifier_anonymous.c')
-rw-r--r-- | res/res_pjsip_endpoint_identifier_anonymous.c | 20 |
1 files changed, 11 insertions, 9 deletions
diff --git a/res/res_pjsip_endpoint_identifier_anonymous.c b/res/res_pjsip_endpoint_identifier_anonymous.c index 06933a9ad..d9d7e03da 100644 --- a/res/res_pjsip_endpoint_identifier_anonymous.c +++ b/res/res_pjsip_endpoint_identifier_anonymous.c @@ -42,14 +42,14 @@ static int get_endpoint_details(pjsip_rx_data *rdata, char *domain, size_t domai 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 *anonymous_identify(pjsip_rx_data *rdata) char 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, domain_name, sizeof(domain_name))) { @@ -83,9 +84,10 @@ static struct ast_sip_endpoint *anonymous_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)) { + 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; |