From 910a5c5de3e3098340ea94e466a5e755ae909fba Mon Sep 17 00:00:00 2001
From: Mohamed Chibani <mohamed.chibani@savoirfairelinux.com>
Date: Tue, 17 Aug 2021 18:08:21 -0400
Subject: [PATCH] sipcall/ice: remove obsolete temporary shared pointer

This patch removes the temporary ICE shared pointer

Gitlab: #619

Change-Id: Icacac9df1102327d4d1a0f0d67dfa457016048cd
---
 src/ice_transport.cpp             | 152 ++++++++++++++++++------------
 src/ice_transport.h               |   3 +
 src/jamidht/connectionmanager.cpp |   3 +
 src/jamidht/jamiaccount.cpp       |   9 +-
 src/sip/sipcall.cpp               |  93 ++++++++----------
 src/sip/sipcall.h                 |   9 --
 test/unitTest/ice/ice.cpp         |  12 +++
 7 files changed, 151 insertions(+), 130 deletions(-)

diff --git a/src/ice_transport.cpp b/src/ice_transport.cpp
index ad6d69d3e9..e137291180 100644
--- a/src/ice_transport.cpp
+++ b/src/ice_transport.cpp
@@ -81,6 +81,8 @@ public:
     Impl(const char* name, const IceTransportOptions& options);
     ~Impl();
 
+    void initIceInstance();
+
     void onComplete(pj_ice_strans* ice_st, pj_ice_strans_op op, pj_status_t status);
 
     void onReceiveData(unsigned comp_id, void* pkt, pj_size_t size);
@@ -132,7 +134,10 @@ public:
     int flushTimerHeapAndIoQueue();
     int checkEventQueue(int maxEventToPoll);
 
+    std::string sessionName_ {};
     std::unique_ptr<pj_pool_t, std::function<void(pj_pool_t*)>> pool_ {};
+    bool isTcp_ {false};
+    bool upnpEnabled_ {false};
     IceTransportCompleteCb on_initdone_cb_ {};
     IceTransportCompleteCb on_negodone_cb_ {};
     IceRecvInfo on_recv_cb_ {};
@@ -173,12 +178,18 @@ public:
     std::vector<PeerChannel> peerChannels_ {};
     std::vector<IpAddr> iceDefaultRemoteAddr_;
 
+    // ICE controlling role. True for controller agents and false for
+    // controlled agents
     std::atomic_bool initiatorSession_ {true};
 
     // Local/Public addresses used by the account owning the ICE instance.
     IpAddr accountLocalAddr_ {};
     IpAddr accountPublicAddr_ {};
 
+    // STUN and TURN servers
+    std::vector<StunServerInfo> stunServers_;
+    std::vector<TurnServerInfo> turnServers_;
+
     /**
      * Returns the IP of each candidate for a given component in the ICE session
      */
@@ -294,7 +305,13 @@ add_turn_server(pj_pool_t& pool, pj_ice_strans_cfg& cfg, const TurnServerInfo& i
 //==============================================================================
 
 IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
-    : pool_(nullptr, [](pj_pool_t* pool) { pj_pool_release(pool); })
+    : sessionName_(name)
+    , pool_(nullptr,
+            [](pj_pool_t* pool) {
+                pj_pool_release(pool);
+            })
+    , isTcp_(options.tcpEnable)
+    , upnpEnabled_(options.upnpEnable)
     , on_initdone_cb_(options.onInitDone)
     , on_negodone_cb_(options.onNegoDone)
     , streamsCount_(options.streamsCount)
@@ -306,20 +323,77 @@ IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
     , initiatorSession_(options.master)
     , accountLocalAddr_(std::move(options.accountLocalAddr))
     , accountPublicAddr_(std::move(options.accountPublicAddr))
+    , stunServers_(std::move(options.stunServers))
+    , turnServers_(std::move(options.turnServers))
+    , thread_()
 {
     JAMI_DBG("[ice:%p] Creating IceTransport session for \"%s\" - comp count %u - as a %s",
              this,
              name,
              compCount_,
              initiatorSession_ ? "master" : "slave");
+}
+
+IceTransport::Impl::~Impl()
+{
+    JAMI_DBG("[ice:%p] destroying %p", this, icest_);
+
+    threadTerminateFlags_ = true;
+    iceCV_.notify_all();
+
+    if (thread_.joinable()) {
+        thread_.join();
+    }
+
+    pj_ice_strans* strans = nullptr;
+
+    std::swap(strans, icest_);
+
+    assert(strans);
+
+    // must be done before ioqueue/timer destruction
+    JAMI_INFO("[ice:%p] Destroying ice_strans %p", pj_ice_strans_get_user_data(strans), strans);
+
+    pj_ice_strans_stop_ice(strans);
+    pj_ice_strans_destroy(strans);
+
+    // NOTE: This last timer heap and IO queue polling is necessary to close
+    // TURN socket.
+    // Because when destroying the TURN session pjproject creates a pj_timer
+    // to postpone the TURN destruction. This timer is only called if we poll
+    // the event queue.
+
+    int ret = flushTimerHeapAndIoQueue();
+
+    if (ret < 0) {
+        JAMI_ERR("[ice:%p] IO queue polling failed", this);
+    } else if (ret > 0) {
+        JAMI_ERR("[ice:%p] Unexpected left timer in timer heap. Please report the bug", this);
+    }
+
+    if (checkEventQueue(1) > 0) {
+        JAMI_WARN("[ice:%p] Unexpected left events in IO queue", this);
+    }
+
+    if (config_.stun_cfg.ioqueue)
+        pj_ioqueue_destroy(config_.stun_cfg.ioqueue);
+
+    if (config_.stun_cfg.timer_heap)
+        pj_timer_heap_destroy(config_.stun_cfg.timer_heap);
+
+    JAMI_DBG("[ice:%p] done destroying", this);
+}
 
-    if (options.upnpEnable)
+void
+IceTransport::Impl::initIceInstance()
+{
+    if (upnpEnabled_)
         upnp_.reset(new upnp::Controller());
 
     auto& iceTransportFactory = Manager::instance().getIceTransportFactory();
 
     config_ = iceTransportFactory.getIceCfg(); // config copy
-    if (options.tcpEnable) {
+    if (isTcp_) {
         config_.protocol = PJ_ICE_TP_TCP;
         config_.stun.conn_type = PJ_STUN_TP_TCP;
         config_.turn.conn_type = PJ_TURN_TP_TCP;
@@ -329,6 +403,11 @@ IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
         config_.turn.conn_type = PJ_TURN_TP_UDP;
     }
 
+    pool_.reset(
+        pj_pool_create(iceTransportFactory.getPoolFactory(), "IceTransport.pool", 512, 512, NULL));
+    if (not pool_)
+        throw std::runtime_error("pj_pool_create() failed");
+
     // Note: For server reflexive candidates, UPNP mappings will
     // be used if available. Then, the public address learnt during
     // the account registration process will be added only if it
@@ -374,11 +453,6 @@ IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
         JAMI_WARN("[ice:%p] No server reflexive candidates added", this);
     }
 
-    pool_.reset(
-        pj_pool_create(iceTransportFactory.getPoolFactory(), "IceTransport.pool", 512, 512, NULL));
-    if (not pool_)
-        throw std::runtime_error("pj_pool_create() failed");
-
     pj_ice_strans_cb icecb;
     pj_bzero(&icecb, sizeof(icecb));
 
@@ -422,11 +496,11 @@ IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
     };
 
     // Add STUN servers
-    for (auto& server : options.stunServers)
+    for (auto& server : stunServers_)
         add_stun_server(*pool_, config_, server);
 
     // Add TURN servers
-    for (auto& server : options.turnServers)
+    for (auto& server : turnServers_)
         add_turn_server(*pool_, config_, server);
 
     static constexpr auto IOQUEUE_MAX_HANDLES = std::min(PJ_IOQUEUE_MAX_HANDLES, 64);
@@ -460,56 +534,6 @@ IceTransport::Impl::Impl(const char* name, const IceTransportOptions& options)
     iceDefaultRemoteAddr_.reserve(compCount_);
 }
 
-IceTransport::Impl::~Impl()
-{
-    JAMI_DBG("[ice:%p] destroying %p", this, icest_);
-
-    threadTerminateFlags_ = true;
-    iceCV_.notify_all();
-
-    if (thread_.joinable()) {
-        thread_.join();
-    }
-
-    pj_ice_strans* strans = nullptr;
-
-    std::swap(strans, icest_);
-
-    assert(strans);
-
-    // must be done before ioqueue/timer destruction
-    JAMI_INFO("[ice:%p] Destroying ice_strans %p", pj_ice_strans_get_user_data(strans), strans);
-
-    pj_ice_strans_stop_ice(strans);
-    pj_ice_strans_destroy(strans);
-
-    // NOTE: This last timer heap and IO queue polling is necessary to close
-    // TURN socket.
-    // Because when destroying the TURN session pjproject creates a pj_timer
-    // to postpone the TURN destruction. This timer is only called if we poll
-    // the event queue.
-
-    int ret = flushTimerHeapAndIoQueue();
-
-    if (ret < 0) {
-        JAMI_ERR("[ice:%p] IO queue polling failed", this);
-    } else if (ret > 0) {
-        JAMI_ERR("[ice:%p] Unexpected left timer in timer heap. Please report the bug", this);
-    }
-
-    if (checkEventQueue(1) > 0) {
-        JAMI_WARN("[ice:%p] Unexpected left events in IO queue", this);
-    }
-
-    if (config_.stun_cfg.ioqueue)
-        pj_ioqueue_destroy(config_.stun_cfg.ioqueue);
-
-    if (config_.stun_cfg.timer_heap)
-        pj_timer_heap_destroy(config_.stun_cfg.timer_heap);
-
-    JAMI_DBG("[ice:%p] done destroying", this);
-}
-
 bool
 IceTransport::Impl::_isInitialized() const
 {
@@ -652,7 +676,7 @@ IceTransport::Impl::checkEventQueue(int maxEventToPoll)
 }
 
 void
-IceTransport::Impl::onComplete(pj_ice_strans* ice_st, pj_ice_strans_op op, pj_status_t status)
+IceTransport::Impl::onComplete(pj_ice_strans*, pj_ice_strans_op op, pj_status_t status)
 {
     const char* opname = op == PJ_ICE_STRANS_OP_INIT
                              ? "initialization"
@@ -1108,6 +1132,12 @@ IceTransport::~IceTransport()
     cancelOperations();
 }
 
+void
+IceTransport::initIceInstance()
+{
+    pimpl_->initIceInstance();
+}
+
 bool
 IceTransport::isInitialized() const
 {
diff --git a/src/ice_transport.h b/src/ice_transport.h
index 8326ec8153..646767f4b5 100644
--- a/src/ice_transport.h
+++ b/src/ice_transport.h
@@ -132,6 +132,9 @@ public:
      */
     IceTransport(const char* name, const IceTransportOptions& options = {});
     ~IceTransport();
+
+    void initIceInstance();
+
     /**
      * Get current state
      */
diff --git a/src/jamidht/connectionmanager.cpp b/src/jamidht/connectionmanager.cpp
index 51b64b4aed..903990979d 100644
--- a/src/jamidht/connectionmanager.cpp
+++ b/src/jamidht/connectionmanager.cpp
@@ -574,6 +574,7 @@ ConnectionManager::Impl::connectDevice(const std::shared_ptr<dht::crypto::Certif
             info->ice_ = Manager::instance()
                              .getIceTransportFactory()
                              .createUTransport(sthis->account.getAccountID().c_str(), ice_config);
+            info->ice_->initIceInstance();
 
             if (!info->ice_) {
                 JAMI_ERR("Cannot initialize ICE session.");
@@ -933,6 +934,8 @@ ConnectionManager::Impl::onDhtPeerRequest(const PeerConnectionRequest& req,
         info->ice_ = Manager::instance()
                          .getIceTransportFactory()
                          .createUTransport(shared->account.getAccountID().c_str(), ice_config);
+        info->ice_->initIceInstance();
+
         if (not info->ice_) {
             JAMI_ERR("Cannot initialize ICE session.");
             if (shared->connReadyCb_)
diff --git a/src/jamidht/jamiaccount.cpp b/src/jamidht/jamiaccount.cpp
index 1b6477eb64..ece2c7324a 100644
--- a/src/jamidht/jamiaccount.cpp
+++ b/src/jamidht/jamiaccount.cpp
@@ -778,6 +778,8 @@ JamiAccount::onConnectedOutgoingCall(const std::shared_ptr<SIPCall>& call,
 bool
 JamiAccount::SIPStartCall(SIPCall& call, const IpAddr& target)
 {
+    JAMI_DBG("Start SIP call [%s]", call.getCallId().c_str());
+
     if (call.isIceEnabled())
         call.addLocalIceAttributes();
 
@@ -816,13 +818,6 @@ JamiAccount::SIPStartCall(SIPCall& call, const IpAddr& target)
     inv->mod_data[link_.getModId()] = &call;
     call.setInviteSession(inv);
 
-    /*
-        updateDialogViaSentBy(dialog);
-        if (hasServiceRoute())
-            pjsip_dlg_set_route_set(dialog, sip_utils::createRouteSet(getServiceRoute(),
-       call->inv->pool));
-    */
-
     pjsip_tx_data* tdata;
 
     if (pjsip_inv_invite(call.inviteSession_.get(), &tdata) != PJ_SUCCESS) {
diff --git a/src/sip/sipcall.cpp b/src/sip/sipcall.cpp
index f90f997d05..d036d89ea1 100644
--- a/src/sip/sipcall.cpp
+++ b/src/sip/sipcall.cpp
@@ -173,10 +173,7 @@ SIPCall::SIPCall(const std::shared_ptr<SIPAccountBase>& account,
 SIPCall::~SIPCall()
 {
     std::lock_guard<std::recursive_mutex> lk {callMutex_};
-    {
-        std::lock_guard<std::mutex> lk(transportMtx_);
-        resetTransport(std::move(tmpMediaTransport_));
-    }
+
     setTransport({});
     setInviteSession(); // prevents callback usage
 }
@@ -855,7 +852,7 @@ SIPCall::answer(const std::vector<DRing::MediaMap>& mediaList)
         generateMediaPorts();
 
         // Setup and create ICE offer
-        if (account->isIceForMediaEnabled()) {
+        if (isIceEnabled()) {
             sdp_->clearIce();
 
             auto opts = account->getIceOptions();
@@ -867,8 +864,8 @@ SIPCall::answer(const std::vector<DRing::MediaMap>& mediaList)
                 if (auto interfaceAddr = ip_utils::getInterfaceAddr(account->getLocalInterface(),
                                                                     publicAddr.getFamily())) {
                     opts.accountLocalAddr = interfaceAddr;
-                    initIceMediaTransport(true, std::move(opts));
-                    addLocalIceAttributes();
+                    if (initIceMediaTransport(true, std::move(opts)))
+                        addLocalIceAttributes();
                 } else {
                     JAMI_WARN("[call:%s] Cant init ICE transport, missing local address",
                               getCallId().c_str());
@@ -1456,7 +1453,6 @@ SIPCall::removeCall()
     {
         std::lock_guard<std::mutex> lk(transportMtx_);
         resetTransport(std::move(mediaTransport_));
-        resetTransport(std::move(tmpMediaTransport_));
     }
 
     setInviteSession();
@@ -1628,15 +1624,13 @@ SIPCall::onPeerRinging()
 void
 SIPCall::addLocalIceAttributes()
 {
-    auto media_tr = getIceMediaTransport();
-
-    if (not media_tr) {
-        JAMI_WARN("[call:%s] no media ICE transport, SDP not changed", getCallId().c_str());
+    if (not mediaTransport_) {
+        JAMI_ERR("[call:%s] Invalid media ICE transport", getCallId().c_str());
         return;
     }
 
     // we need an initialized ICE to progress further
-    if (media_tr->waitForInitialization(DEFAULT_ICE_INIT_TIMEOUT) <= 0) {
+    if (mediaTransport_->waitForInitialization(DEFAULT_ICE_INIT_TIMEOUT) <= 0) {
         JAMI_ERR("[call:%s] Medias' ICE init failed", getCallId().c_str());
         return;
     }
@@ -1651,10 +1645,12 @@ SIPCall::addLocalIceAttributes()
         return;
     }
 
-    JAMI_DBG("[call:%s] fill SDP with ICE transport %p", getCallId().c_str(), media_tr);
+    JAMI_DBG("[call:%s] Add local attributes for ICE instance [%p]",
+             getCallId().c_str(),
+             mediaTransport_.get());
 
     if (isIceEnabled()) {
-        sdp_->addIceAttributes(media_tr->getLocalAttributes());
+        sdp_->addIceAttributes(mediaTransport_->getLocalAttributes());
     }
 
     if (account->isIceCompIdRfc5245Compliant()) {
@@ -1674,11 +1670,12 @@ SIPCall::addLocalIceAttributes()
                      streamIdx);
             // RTP
             sdp_->addIceCandidates(streamIdx,
-                                   media_tr->getLocalCandidates(streamIdx, ICE_COMP_ID_RTP));
+                                   mediaTransport_->getLocalCandidates(streamIdx, ICE_COMP_ID_RTP));
             // RTCP if it has its own port
             if (not rtcpMuxEnabled_) {
                 sdp_->addIceCandidates(streamIdx,
-                                       media_tr->getLocalCandidates(streamIdx, ICE_COMP_ID_RTP + 1));
+                                       mediaTransport_->getLocalCandidates(streamIdx,
+                                                                           ICE_COMP_ID_RTP + 1));
             }
 
             streamIdx++;
@@ -1696,12 +1693,12 @@ SIPCall::addLocalIceAttributes()
                      stream.mediaAttribute_->toString().c_str(),
                      idx);
             // RTP
-            sdp_->addIceCandidates(idx, media_tr->getLocalCandidates(compId));
+            sdp_->addIceCandidates(idx, mediaTransport_->getLocalCandidates(compId));
             compId++;
 
             // RTCP if it has its own port
             if (not rtcpMuxEnabled_) {
-                sdp_->addIceCandidates(idx, media_tr->getLocalCandidates(compId));
+                sdp_->addIceCandidates(idx, mediaTransport_->getLocalCandidates(compId));
                 compId++;
             }
 
@@ -1713,10 +1710,8 @@ SIPCall::addLocalIceAttributes()
 std::vector<IceCandidate>
 SIPCall::getAllRemoteCandidates()
 {
-    auto media_tr = getIceMediaTransport();
-
-    if (not media_tr) {
-        JAMI_WARN("[call:%s] no media ICE transport", getCallId().c_str());
+    if (not mediaTransport_) {
+        JAMI_ERR("[call:%s] No media ICE transport", getCallId().c_str());
         return {};
     }
 
@@ -1724,8 +1719,8 @@ SIPCall::getAllRemoteCandidates()
     for (unsigned mediaIdx = 0; mediaIdx < static_cast<unsigned>(rtpStreams_.size()); mediaIdx++) {
         IceCandidate cand;
         for (auto& line : sdp_->getIceCandidates(mediaIdx)) {
-            if (media_tr->parseIceAttributeLine(mediaIdx, line, cand)) {
-                JAMI_DBG("[call:%s] add remote ICE candidate: %s",
+            if (mediaTransport_->parseIceAttributeLine(mediaIdx, line, cand)) {
+                JAMI_DBG("[call:%s] Add remote ICE candidate: %s",
                          getCallId().c_str(),
                          line.c_str());
                 rem_candidates.emplace_back(cand);
@@ -2332,22 +2327,20 @@ SIPCall::startIceMedia()
 {
     JAMI_DBG("[call:%s] Starting ICE", getCallId().c_str());
 
-    auto ice = getIceMediaTransport();
-
-    if (not ice or ice->isFailed()) {
+    if (not mediaTransport_ or mediaTransport_->isFailed()) {
         JAMI_ERR("[call:%s] Media ICE init failed", getCallId().c_str());
         onFailure(EIO);
         return;
     }
 
-    if (ice->isStarted()) {
+    if (mediaTransport_->isStarted()) {
         // NOTE: for incoming calls, the ice is already there and running
-        if (ice->isRunning())
+        if (mediaTransport_->isRunning())
             onIceNegoSucceed();
         return;
     }
 
-    if (!ice->isInitialized()) {
+    if (not mediaTransport_->isInitialized()) {
         // In this case, onInitDone will occurs after the startIceMedia
         waitForIceInit_ = true;
         return;
@@ -2362,7 +2355,7 @@ SIPCall::startIceMedia()
         onFailure(EIO);
         return;
     }
-    if (not ice->startIce(rem_ice_attrs, getAllRemoteCandidates())) {
+    if (not mediaTransport_->startIce(rem_ice_attrs, getAllRemoteCandidates())) {
         JAMI_ERR("[call:%s] Media ICE start failed", getCallId().c_str());
         onFailure(EIO);
     }
@@ -2387,13 +2380,7 @@ SIPCall::onIceNegoSucceed()
 
     // Nego succeed: move to the new media transport
     stopAllMedia();
-    {
-        std::unique_lock<std::mutex> lk(transportMtx_);
-        if (tmpMediaTransport_) {
-            resetTransport(std::move(mediaTransport_));
-            mediaTransport_ = std::move(tmpMediaTransport_);
-        }
-    }
+
     startAllMedia();
 }
 
@@ -2563,7 +2550,7 @@ SIPCall::onReceiveOfferIn200OK(const pjmedia_sdp_session* offer)
         openPortsUPnP();
     }
 
-    if (acc->isIceForMediaEnabled()) {
+    if (isIceEnabled()) {
         setupIceResponse();
     }
 
@@ -2823,9 +2810,8 @@ SIPCall::monitor() const
     if (auto codec = getVideoCodec())
         JAMI_DBG("\t- Video codec: %s", codec->systemCodecInfo.name.c_str());
 #endif
-    auto media_tr = getIceMediaTransport();
-    if (media_tr) {
-        JAMI_DBG("\t- Medias: %s", media_tr->link().c_str());
+    if (mediaTransport_) {
+        JAMI_DBG("\t- Medias: %s", mediaTransport_->link().c_str());
     }
 }
 
@@ -2954,30 +2940,30 @@ SIPCall::initIceMediaTransport(bool master, std::optional<IceTransportOptions> o
     // Destroy old ice on a separate io pool
     {
         std::lock_guard<std::mutex> lk(transportMtx_);
-        resetTransport(std::move(tmpMediaTransport_));
-        tmpMediaTransport_ = std::move(transport);
+        resetTransport(std::move(mediaTransport_));
+        mediaTransport_ = iceTransportFactory.createTransport(getCallId().c_str(), iceOptions);
     }
 
-    if (tmpMediaTransport_) {
+    if (mediaTransport_) {
         JAMI_DBG("[call:%s] Successfully created media ICE transport [ice:%p]",
                  getCallId().c_str(),
-                 tmpMediaTransport_.get());
+                 mediaTransport_.get());
+        mediaTransport_->initIceInstance();
     } else {
         JAMI_ERR("[call:%s] Failed to create media ICE transport", getCallId().c_str());
     }
 
-    return static_cast<bool>(tmpMediaTransport_);
+    return static_cast<bool>(mediaTransport_);
 }
 
 std::vector<std::string>
 SIPCall::getLocalIceCandidates(unsigned compId) const
 {
-    auto iceTransp = getIceMediaTransport();
-    if (not iceTransp) {
+    if (not mediaTransport_) {
         JAMI_WARN("[call:%s] no media ICE transport", getCallId().c_str());
         return {};
     }
-    return iceTransp->getLocalCandidates(compId);
+    return mediaTransport_->getLocalCandidates(compId);
 }
 
 void
@@ -3014,15 +3000,16 @@ SIPCall::merge(Call& call)
     localVideoPort_ = subcall.localVideoPort_;
     {
         std::lock_guard<std::mutex> lk(transportMtx_);
+        resetTransport(std::move(mediaTransport_));
         mediaTransport_ = std::move(subcall.mediaTransport_);
-        tmpMediaTransport_ = std::move(subcall.tmpMediaTransport_);
     }
 
     peerUserAgent_ = subcall.peerUserAgent_;
     peerSupportMultiStream_ = subcall.peerSupportMultiStream_;
 
     Call::merge(subcall);
-    startIceMedia();
+    if (isIceEnabled())
+        startIceMedia();
 }
 
 bool
diff --git a/src/sip/sipcall.h b/src/sip/sipcall.h
index 6e196516bc..6cb5c817bb 100644
--- a/src/sip/sipcall.h
+++ b/src/sip/sipcall.h
@@ -277,12 +277,6 @@ public:
     std::unique_ptr<pjsip_inv_session, InvSessionDeleter> inviteSession_;
 
 private:
-    IceTransport* getIceMediaTransport() const
-    {
-        std::lock_guard<std::mutex> lk(transportMtx_);
-        return tmpMediaTransport_ ? tmpMediaTransport_.get() : mediaTransport_.get();
-    }
-
     void generateMediaPorts();
 
     void openPortsUPnP();
@@ -437,9 +431,6 @@ private:
     ///< Transport used for media streams
     std::shared_ptr<IceTransport> mediaTransport_;
 
-    ///< Temporary transport for media. Replace mediaTransport_ when connected with success
-    std::unique_ptr<IceTransport> tmpMediaTransport_;
-
     std::string peerUri_ {};
 
     bool readyToRecord_ {false};
diff --git a/test/unitTest/ice/ice.cpp b/test/unitTest/ice/ice.cpp
index aba7691fae..61bd4cda7d 100644
--- a/test/unitTest/ice/ice.cpp
+++ b/test/unitTest/ice/ice.cpp
@@ -140,6 +140,7 @@ IceTest::testRawIceConnection()
 
     ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
                                                                               ice_config);
+    ice_master->initIceInstance();
     cv_create.notify_all();
     ice_config.onInitDone = [&](bool ok) {
         CPPUNIT_ASSERT(ok);
@@ -174,6 +175,8 @@ IceTest::testRawIceConnection()
 
     ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
                                                                              ice_config);
+    ice_slave->initIceInstance();
+
     cv_create.notify_all();
     CPPUNIT_ASSERT(
         cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@@ -246,6 +249,7 @@ IceTest::testTurnMasterIceConnection()
     ice_config.compCountPerStream = 1;
     ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
                                                                               ice_config);
+    ice_master->initIceInstance();
     cv_create.notify_all();
     ice_config.turnServers = {};
     ice_config.onInitDone = [&](bool ok) {
@@ -289,6 +293,8 @@ IceTest::testTurnMasterIceConnection()
     ice_config.compCountPerStream = 1;
     ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
                                                                              ice_config);
+    ice_slave->initIceInstance();
+
     cv_create.notify_all();
     CPPUNIT_ASSERT(
         cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@@ -356,6 +362,7 @@ IceTest::testTurnSlaveIceConnection()
     ice_config.compCountPerStream = 1;
     ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
                                                                               ice_config);
+    ice_master->initIceInstance();
     cv_create.notify_all();
     ice_config.onInitDone = [&](bool ok) {
         CPPUNIT_ASSERT(ok);
@@ -403,6 +410,7 @@ IceTest::testTurnSlaveIceConnection()
     ice_config.compCountPerStream = 1;
     ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
                                                                              ice_config);
+    ice_slave->initIceInstance();
     cv_create.notify_all();
     CPPUNIT_ASSERT(
         cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@@ -467,6 +475,7 @@ IceTest::testReceiveTooManyCandidates()
 
     ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
                                                                               ice_config);
+    ice_master->initIceInstance();
     cv_create.notify_all();
     ice_config.onInitDone = [&](bool ok) {
         CPPUNIT_ASSERT(ok);
@@ -509,6 +518,7 @@ IceTest::testReceiveTooManyCandidates()
 
     ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
                                                                              ice_config);
+    ice_slave->initIceInstance();
     cv_create.notify_all();
     CPPUNIT_ASSERT(
         cv.wait_for(lk, std::chrono::seconds(10), [&] { return iceMasterReady && iceSlaveReady; }));
@@ -575,6 +585,7 @@ IceTest::testCompleteOnFailure()
     ice_config.compCountPerStream = 1;
     ice_master = Manager::instance().getIceTransportFactory().createTransport("master ICE",
                                                                               ice_config);
+    ice_master->initIceInstance();
     cv_create.notify_all();
     ice_config.onInitDone = [&](bool ok) {
         CPPUNIT_ASSERT(ok);
@@ -622,6 +633,7 @@ IceTest::testCompleteOnFailure()
     ice_config.compCountPerStream = 1;
     ice_slave = Manager::instance().getIceTransportFactory().createTransport("slave ICE",
                                                                              ice_config);
+    ice_slave->initIceInstance();
     cv_create.notify_all();
     // Check that nego failed and callback called
     CPPUNIT_ASSERT(cv.wait_for(lk, std::chrono::seconds(120), [&] {
-- 
GitLab