From bbf3ace68292c136ae0455332a1893de4c4b4c13 Mon Sep 17 00:00:00 2001 From: George Joseph Date: Fri, 29 Jan 2016 16:56:42 -0700 Subject: res_pjsip: Fix infinite recursion when loading transports from realtime MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- res/res_pjsip_transport_websocket.c | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) (limited to 'res/res_pjsip_transport_websocket.c') diff --git a/res/res_pjsip_transport_websocket.c b/res/res_pjsip_transport_websocket.c index cdf6c6733..b9d94ea3c 100644 --- a/res/res_pjsip_transport_websocket.c +++ b/res/res_pjsip_transport_websocket.c @@ -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) { -- cgit v1.2.3