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 18:08:32 -0700 |
commit | 2451d4e4550336197ee2e482750cc53f30afa352 (patch) | |
tree | 10acfac50575f695f66805e5607822e10610d74d /res/res_pjsip.c | |
parent | 78fa818c1bdcbb5c0bcd5c651e14c7f607ac4997 (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.c')
-rw-r--r-- | res/res_pjsip.c | 12 |
1 files changed, 7 insertions, 5 deletions
diff --git a/res/res_pjsip.c b/res/res_pjsip.c index c94f6a9eb..d0d6ba946 100644 --- a/res/res_pjsip.c +++ b/res/res_pjsip.c @@ -2486,6 +2486,7 @@ static int sip_dialog_create_from(pj_pool_t *pool, pj_str_t *from, const char *u static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpoint, pjsip_tpselector *selector) { RAII_VAR(struct ast_sip_transport *, transport, NULL, ao2_cleanup); + RAII_VAR(struct ast_sip_transport_state *, transport_state, NULL, ao2_cleanup); const char *transport_name = endpoint->transport; if (ast_strlen_zero(transport_name)) { @@ -2493,19 +2494,20 @@ static int sip_get_tpselector_from_endpoint(const struct ast_sip_endpoint *endpo } transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_name); + transport_state = ast_sip_get_transport_state(transport_name); - if (!transport || !transport->state) { + if (!transport || !transport_state) { ast_log(LOG_ERROR, "Unable to retrieve PJSIP transport '%s' for endpoint '%s'\n", transport_name, ast_sorcery_object_get_id(endpoint)); return -1; } - if (transport->state->transport) { + if (transport_state->transport) { selector->type = PJSIP_TPSELECTOR_TRANSPORT; - selector->u.transport = transport->state->transport; - } else if (transport->state->factory) { + selector->u.transport = transport_state->transport; + } else if (transport_state->factory) { selector->type = PJSIP_TPSELECTOR_LISTENER; - selector->u.listener = transport->state->factory; + selector->u.listener = transport_state->factory; } else if (transport->type == AST_TRANSPORT_WS || transport->type == AST_TRANSPORT_WSS) { /* The WebSocket transport has no factory as it can not create outgoing connections, so * even if an endpoint is locked to a WebSocket transport we let the PJSIP logic |