mirror of
https://github.com/asterisk/asterisk.git
synced 2025-09-03 03:20:57 +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:
@@ -275,24 +275,27 @@ static int transport_read(void *data)
|
||||
static int get_write_timeout(void)
|
||||
{
|
||||
int write_timeout = -1;
|
||||
struct ao2_container *transports;
|
||||
struct ao2_container *transport_states;
|
||||
|
||||
transports = ast_sorcery_retrieve_by_fields(ast_sip_get_sorcery(), "transport", AST_RETRIEVE_FLAG_ALL, NULL);
|
||||
transport_states = ast_sip_get_transport_states();
|
||||
|
||||
if (transports) {
|
||||
struct ao2_iterator it_transports = ao2_iterator_init(transports, 0);
|
||||
struct ast_sip_transport *transport;
|
||||
if (transport_states) {
|
||||
struct ao2_iterator it_transport_states = ao2_iterator_init(transport_states, 0);
|
||||
struct ast_sip_transport_state *transport_state;
|
||||
|
||||
for (; (transport = ao2_iterator_next(&it_transports)); ao2_cleanup(transport)) {
|
||||
if (transport->type != AST_TRANSPORT_WS && transport->type != AST_TRANSPORT_WSS) {
|
||||
for (; (transport_state = ao2_iterator_next(&it_transport_states)); ao2_cleanup(transport_state)) {
|
||||
struct ast_sip_transport *transport;
|
||||
if (transport_state->type != AST_TRANSPORT_WS && transport_state->type != AST_TRANSPORT_WSS) {
|
||||
continue;
|
||||
}
|
||||
transport = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "transport", transport_state->id);
|
||||
ast_debug(5, "Found %s transport with write timeout: %d\n",
|
||||
transport->type == AST_TRANSPORT_WS ? "WS" : "WSS",
|
||||
transport->write_timeout);
|
||||
write_timeout = MAX(write_timeout, transport->write_timeout);
|
||||
}
|
||||
ao2_cleanup(transports);
|
||||
ao2_iterator_destroy(&it_transport_states);
|
||||
ao2_cleanup(transport_states);
|
||||
}
|
||||
|
||||
if (write_timeout < 0) {
|
||||
|
Reference in New Issue
Block a user