From 8b8a3dfe660cea125bec1c2f89765ae00a1ab87b Mon Sep 17 00:00:00 2001 From: Simon Morlat <simon.morlat@linphone.org> Date: Mon, 17 Mar 2025 18:25:31 +0100 Subject: [PATCH] Fix a crash when a handling CallSession's pendingActions, fix a crash when linphone_core_get_user_agent() is called while Core is in stopped state. --- coreapi/linphonecore.c | 4 ++++ src/call/call.cpp | 15 +++++++++------ src/call/call.h | 6 +++--- src/conference/session/call-session.cpp | 17 +++++++++++++---- src/conference/session/media-session.cpp | 9 ++++++--- tester/call_ice_tester.cpp | 4 ++-- 6 files changed, 37 insertions(+), 18 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ec4fd0b755..8bc21c4a09 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4157,6 +4157,10 @@ void linphone_core_set_user_agent(LinphoneCore *lc, const char *name, const char } } const char *linphone_core_get_user_agent(LinphoneCore *lc) { + CoreLogContextualizer logContextualizer(lc); + if (!lc->sal) { + return linphone_config_get_string(lc->config, "sip", "user_agent", ""); + } return lc->sal->getUserAgent().c_str(); } diff --git a/src/call/call.cpp b/src/call/call.cpp index 4b698114b5..a0580811cc 100644 --- a/src/call/call.cpp +++ b/src/call/call.cpp @@ -1229,20 +1229,23 @@ const string &Call::getReferTo() const { return getActiveSession()->getReferTo(); } -const std::shared_ptr<Address> Call::getReferToAddress() const { - return getActiveSession()->getReferToAddress(); +std::shared_ptr<Address> Call::getReferToAddress() const { + auto session = getActiveSession(); + return session ? session->getReferToAddress() : nullptr; } std::shared_ptr<const Address> Call::getReferredBy() const { return getActiveSession()->getReferredBy(); } -const std::shared_ptr<Address> Call::getRemoteAddress() const { - return getActiveSession()->getRemoteAddress(); +std::shared_ptr<Address> Call::getRemoteAddress() const { + auto session = getActiveSession(); + return session ? session->getRemoteAddress() : nullptr; } -const std::shared_ptr<Address> Call::getRemoteContactAddress() const { - return getActiveSession()->getRemoteContactAddress(); +std::shared_ptr<Address> Call::getRemoteContactAddress() const { + auto session = getActiveSession(); + return session ? session->getRemoteContactAddress() : nullptr; } const string &Call::getRemoteContact() const { diff --git a/src/call/call.h b/src/call/call.h index 0103215d21..cdaa80f1cc 100644 --- a/src/call/call.h +++ b/src/call/call.h @@ -170,10 +170,10 @@ public: float getRecordVolume() const; std::shared_ptr<Call> getReferer() const; const std::string &getReferTo() const; - const std::shared_ptr<Address> getReferToAddress() const; + std::shared_ptr<Address> getReferToAddress() const; std::shared_ptr<const Address> getReferredBy() const; - const std::shared_ptr<Address> getRemoteAddress() const; - const std::shared_ptr<Address> getRemoteContactAddress() const; + std::shared_ptr<Address> getRemoteAddress() const; + std::shared_ptr<Address> getRemoteContactAddress() const; const std::string &getRemoteContact() const; const MediaSessionParams *getRemoteParams() const; const std::string &getRemoteUserAgent(); diff --git a/src/conference/session/call-session.cpp b/src/conference/session/call-session.cpp index 6e71a5aae8..b6045f1bb3 100644 --- a/src/conference/session/call-session.cpp +++ b/src/conference/session/call-session.cpp @@ -217,7 +217,12 @@ void CallSessionPrivate::setState(CallSession::State newState, const string &mes void CallSessionPrivate::onCallStateChanged(BCTBX_UNUSED(LinphoneCall *call), BCTBX_UNUSED(LinphoneCallState state), BCTBX_UNUSED(const std::string &message)) { - this->executePendingActions(); + L_Q(); + auto zis = q->getSharedFromThis(); + q->getCore()->doLater([zis, this] { + (void)zis; + this->executePendingActions(); + }); } void CallSessionPrivate::executePendingActions() { @@ -226,19 +231,23 @@ void CallSessionPrivate::executePendingActions() { if (networkReachable && (state != CallSession::State::End) && (state != CallSession::State::Released) && (state != CallSession::State::Error)) { std::queue<std::function<LinphoneStatus()>> unsuccessfulActions; - auto copyPendingActions = pendingActions; + std::queue<std::function<LinphoneStatus()>> copyPendingActions; + copyPendingActions.swap(pendingActions); + while (copyPendingActions.empty() == false) { // Store std::function in a temporary variable in order to take it out of the queue before executing it const auto f = copyPendingActions.front(); copyPendingActions.pop(); - pendingActions.pop(); // Execute method const auto result = f(); if (result != 0) { unsuccessfulActions.push(f); } } - pendingActions = unsuccessfulActions; + while (!unsuccessfulActions.empty()) { + pendingActions.push(unsuccessfulActions.front()); + unsuccessfulActions.pop(); + } } } diff --git a/src/conference/session/media-session.cpp b/src/conference/session/media-session.cpp index 932dff77cf..6bd8a71543 100644 --- a/src/conference/session/media-session.cpp +++ b/src/conference/session/media-session.cpp @@ -4610,9 +4610,12 @@ bool MediaSession::initiateOutgoing(const string &subject, const std::shared_ptr << " because ICE candidates must be gathered first"; d->queueIceGatheringTask([this, subject, content]() { L_D(); - if (d->state != CallSession::State::End) // Call has been terminated while gathering: avoid to - // update descriptions. - d->updateLocalMediaDescriptionFromIce(d->localIsOfferer); + if (d->state != CallSession::State::OutgoingInit) { + lInfo() << "Ice gathering done but call is now in [" << Utils::toString(d->state) + << "], nothing to do."; + return 0; + } + d->updateLocalMediaDescriptionFromIce(d->localIsOfferer); startInvite(nullptr, subject, content); return 0; }); diff --git a/tester/call_ice_tester.cpp b/tester/call_ice_tester.cpp index 782b48f8eb..f626fd4541 100644 --- a/tester/call_ice_tester.cpp +++ b/tester/call_ice_tester.cpp @@ -120,8 +120,8 @@ static void _early_media_call_with_ice(bool_t callee_has_ice) { pauline_call = linphone_core_invite_address(pauline->lc, marie->identity); BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallIncomingReceived, 1, 10000)); - BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 3000)); - BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia, 1, 3000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 10000)); + BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallOutgoingEarlyMedia, 1, 10000)); BC_ASSERT_TRUE(linphone_call_get_all_muted(pauline_call)); marie_call = linphone_core_get_current_call(marie->lc); -- GitLab