mirror of
https://github.com/asterisk/asterisk.git
synced 2025-10-12 15:45:18 +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:
@@ -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
|
||||
|
Reference in New Issue
Block a user