From dfb9541b08f033b89a25994fc5c8708ef4889404 Mon Sep 17 00:00:00 2001 From: Andrey Volk Date: Fri, 11 Dec 2020 22:32:25 +0300 Subject: [PATCH] [mod_sofia] Use thread-safe alternatives when destroying nua and nua_handle references. Bump sofia-sip library requirement to version 1.13.3 --- configure.ac | 2 +- debian/bootstrap.sh | 2 +- freeswitch.spec | 2 +- src/mod/endpoints/mod_sofia/mod_sofia.c | 4 ++-- src/mod/endpoints/mod_sofia/mod_sofia.h | 2 +- src/mod/endpoints/mod_sofia/sofia.c | 26 ++++++++++++++++--------- src/mod/endpoints/mod_sofia/sofia_reg.c | 4 ++-- 7 files changed, 25 insertions(+), 17 deletions(-) diff --git a/configure.ac b/configure.ac index 9ea2d11b87..810003eda2 100644 --- a/configure.ac +++ b/configure.ac @@ -725,7 +725,7 @@ PKG_CHECK_MODULES([SPANDSP], [spandsp >= 3.0],[ AC_MSG_ERROR([no usable spandsp; please install spandsp3 devel package or equivalent]) ]) -PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.12.12],[ +PKG_CHECK_MODULES([SOFIA_SIP], [sofia-sip-ua >= 1.13.3],[ AM_CONDITIONAL([HAVE_SOFIA_SIP],[true])],[ AC_MSG_ERROR([no usable sofia-sip; please install sofia-sip-ua devel package or equivalent]) ]) diff --git a/debian/bootstrap.sh b/debian/bootstrap.sh index c9b2d522f9..594e7adb7c 100755 --- a/debian/bootstrap.sh +++ b/debian/bootstrap.sh @@ -332,7 +332,7 @@ Build-Depends: uuid-dev, libexpat1-dev, libgdbm-dev, libdb-dev, # used by many modules libcurl4-openssl-dev | libcurl4-gnutls-dev | libcurl-dev, - bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.12.12), + bison, zlib1g-dev, libsofia-sip-ua-dev (>= 1.13.3), libspandsp3-dev, # used to format the private freeswitch apt-repo key properly gnupg, diff --git a/freeswitch.spec b/freeswitch.spec index 66bd762caa..3bbc518119 100644 --- a/freeswitch.spec +++ b/freeswitch.spec @@ -142,7 +142,7 @@ BuildRequires: curl-devel >= 7.19 BuildRequires: gcc-c++ BuildRequires: libtool >= 1.5.17 BuildRequires: openssl-devel >= 1.0.1e -BuildRequires: sofia-sip-devel >= 1.12.12 +BuildRequires: sofia-sip-devel >= 1.13.3 BuildRequires: spandsp3-devel >= 3.0 BuildRequires: pcre-devel BuildRequires: speex-devel diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index ecc925cf78..8c1b7fd325 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -1328,7 +1328,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi de->session = session; } - sofia_process_dispatch_event(&de); + sofia_process_dispatch_event(&de, SWITCH_FALSE); switch_mutex_unlock(tech_pvt->sofia_mutex); @@ -5791,7 +5791,7 @@ void general_event_handler(switch_event_t *event) TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)), TAG_IF(!zstr(body), SIPTAG_PAYLOAD_STR(body)), TAG_END()); if (call_id && nh) { - nua_handle_unref(nh); + nua_handle_unref_user(nh); } done: diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h index d4631b02d6..db709b9721 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.h +++ b/src/mod/endpoints/mod_sofia/mod_sofia.h @@ -1237,7 +1237,7 @@ uint32_t sofia_presence_get_cseq(sofia_profile_t *profile); void sofia_glue_build_vid_refresh_message(switch_core_session_t *session, const char *pl); char *sofia_glue_gen_contact_str(sofia_profile_t *profile, sip_t const *sip, nua_handle_t *nh, sofia_dispatch_event_t *de, sofia_nat_parse_t *np); void sofia_glue_pause_jitterbuffer(switch_core_session_t *session, switch_bool_t on); -void sofia_process_dispatch_event(sofia_dispatch_event_t **dep); +void sofia_process_dispatch_event(sofia_dispatch_event_t **dep, switch_bool_t stack_thread); void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep); char *sofia_glue_get_host(const char *str, switch_memory_pool_t *pool); void sofia_presence_check_subscriptions(sofia_profile_t *profile, time_t now); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index e1e6435670..b76a804e8e 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -2230,7 +2230,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run_once(switch_thread_t *thread, void if (de) { pool = de->pool; de->pool = NULL; - sofia_process_dispatch_event(&de); + sofia_process_dispatch_event(&de, SWITCH_FALSE); } if (pool) { @@ -2263,7 +2263,7 @@ void sofia_process_dispatch_event_in_thread(sofia_dispatch_event_t **dep) switch_thread_pool_launch_thread(&td); } -void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) +void sofia_process_dispatch_event(sofia_dispatch_event_t **dep, switch_bool_t stack_thread) { sofia_dispatch_event_t *de = *dep; nua_handle_t *nh = de->nh; @@ -2282,8 +2282,15 @@ void sofia_process_dispatch_event(sofia_dispatch_event_t **dep) profile->queued_events--; switch_mutex_unlock(profile->flag_mutex); - if (nh) nua_handle_unref(nh); - nua_unref(nua); + if (stack_thread) { + /* Safe to unref directly */ + if (nh) nua_handle_unref(nh); + nua_unref(nua); + } else { + /* This is not a stack thread, need to call via stack (_user) using events */ + if (nh) nua_handle_unref_user(nh); + nua_unref_user(nua); + } } @@ -2320,7 +2327,7 @@ void *SWITCH_THREAD_FUNC sofia_msg_thread_run(switch_thread_t *thread, void *obj if (pop) { sofia_dispatch_event_t *de = (sofia_dispatch_event_t *) pop; - sofia_process_dispatch_event(&de); + sofia_process_dispatch_event(&de, SWITCH_FALSE); } else { break; } @@ -2374,7 +2381,8 @@ void sofia_queue_message(sofia_dispatch_event_t *de) int launch = 0; if (mod_sofia_globals.running == 0 || !mod_sofia_globals.msg_queue) { - sofia_process_dispatch_event(&de); + /* Calling with SWITCH_TRUE as we are sure this is the stack's thread */ + sofia_process_dispatch_event(&de, SWITCH_TRUE); return; } @@ -7877,7 +7885,7 @@ static void sofia_handle_sip_i_state(switch_core_session_t *session, int status, switch_channel_set_variable(channel, SWITCH_ENDPOINT_DISPOSITION_VARIABLE, "ATTENDED_TRANSFER_ERROR"); switch_channel_hangup(channel, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER); } - nua_handle_unref(bnh); + nua_handle_unref_user(bnh); } su_home_unref(home); home = NULL; @@ -9311,7 +9319,7 @@ void sofia_handle_sip_i_refer(nua_t *nua, sofia_profile_t *profile, nua_handle_t } switch_core_session_rwunlock(b_session); } - nua_handle_unref(bnh); + nua_handle_unref_user(bnh); } else { /* the other channel is on a different box, we have to go find them */ if (exten && (br_a = switch_channel_get_partner_uuid(channel_a))) { switch_core_session_t *a_session; @@ -11344,7 +11352,7 @@ void sofia_handle_sip_i_invite(switch_core_session_t *session, nua_t *nua, sofia switch_core_session_rwunlock(b_session); } } - nua_handle_unref(bnh); + nua_handle_unref_user(bnh); } else if (sip->sip_replaces && sip->sip_replaces->rp_call_id) { switch_core_session_t *b_session = NULL; if ((b_session = switch_core_session_locate((char*) sip->sip_replaces->rp_call_id))) { diff --git a/src/mod/endpoints/mod_sofia/sofia_reg.c b/src/mod/endpoints/mod_sofia/sofia_reg.c index 22997cecae..582de54cb4 100644 --- a/src/mod/endpoints/mod_sofia/sofia_reg.c +++ b/src/mod/endpoints/mod_sofia/sofia_reg.c @@ -694,7 +694,7 @@ void sofia_reg_check_socket(sofia_profile_t *profile, const char *call_id, const switch_mutex_lock(profile->flag_mutex); if ((hnh = switch_core_hash_find(profile->reg_nh_hash, key))) { switch_core_hash_delete(profile->reg_nh_hash, key); - nua_handle_unref(hnh); + nua_handle_unref_user(hnh); nua_handle_destroy(hnh); } switch_mutex_unlock(profile->flag_mutex); @@ -1214,7 +1214,7 @@ void sofia_reg_close_handles(sofia_profile_t *profile) for (hi = switch_core_hash_first_iter( profile->reg_nh_hash, hi); hi; hi = switch_core_hash_next(&hi)) { switch_core_hash_this(hi, &var, NULL, &val); if ((nh = (nua_handle_t *) val)) { - nua_handle_unref(nh); + nua_handle_unref_user(nh); nua_handle_destroy(nh); switch_core_hash_delete(profile->reg_nh_hash, (char *) var); goto top;