diff --git a/daemon/src/ringdht/sip_transport_ice.cpp b/daemon/src/ringdht/sip_transport_ice.cpp index 2074e063091e4f74b84837e65b4a846596fb0aff..31e448ce451f4dd83f42c9b7db62e28d461c610a 100644 --- a/daemon/src/ringdht/sip_transport_ice.cpp +++ b/daemon/src/ringdht/sip_transport_ice.cpp @@ -57,13 +57,14 @@ sockaddr_to_host_port(pj_pool_t* pool, SipIceTransport::SipIceTransport(pjsip_endpoint* endpt, pj_pool_t& /* pool */, long /* t_type */, const std::shared_ptr<sfl::IceTransport>& ice, - int comp_id) + int comp_id, std::function<int()> destroy_cb) : base() , pool_(nullptr, pj_pool_release) , rxPool_(nullptr, pj_pool_release) , rdata() , ice_(ice) , comp_id_(comp_id) + , destroy_cb_(destroy_cb) { if (not ice->isCompleted()) throw std::logic_error("ice transport must be completed"); @@ -159,7 +160,6 @@ SipIceTransport::SipIceTransport(pjsip_endpoint* endpt, pj_pool_t& /* pool */, SipIceTransport::~SipIceTransport() { - destroy(); pj_lock_destroy(base.lock); pj_atomic_destroy(base.ref_cnt); } @@ -241,13 +241,8 @@ SipIceTransport::shutdown() pj_status_t SipIceTransport::destroy() { - if (not is_registered_) + if (not is_registered_ or not destroy_cb_) return PJ_SUCCESS; - SFL_WARN("SIP transport ICE: destroy"); - - auto status = pjsip_transport_destroy(&base); - is_registered_ = status != PJ_SUCCESS; - - return status; + return destroy_cb_(); } diff --git a/daemon/src/ringdht/sip_transport_ice.h b/daemon/src/ringdht/sip_transport_ice.h index 680c931f24bc2e4de71dc136b046582c21509d99..c8b2fb93b159928814d1efede101ba45f4486122 100644 --- a/daemon/src/ringdht/sip_transport_ice.h +++ b/daemon/src/ringdht/sip_transport_ice.h @@ -43,7 +43,7 @@ struct SipIceTransport { SipIceTransport(pjsip_endpoint* endpt, pj_pool_t& pool, long t_type, const std::shared_ptr<sfl::IceTransport>& ice, - int comp_id); + int comp_id, std::function<int()> destroy_cb); ~SipIceTransport(); /** @@ -60,11 +60,14 @@ struct SipIceTransport private: std::unique_ptr<pj_pool_t, decltype(pj_pool_release)&> pool_; std::unique_ptr<pj_pool_t, decltype(pj_pool_release)&> rxPool_; + pjsip_rx_data rdata; bool is_registered_ {false}; const std::shared_ptr<sfl::IceTransport> ice_; const int comp_id_; + std::function<int()> destroy_cb_ {}; + pj_status_t send(pjsip_tx_data *tdata, const pj_sockaddr_t *rem_addr, int addr_len, void *token, pjsip_transport_callback callback); diff --git a/daemon/src/sip/siptransport.cpp b/daemon/src/sip/siptransport.cpp index 96467faa84078bcecc6f88bc76b6c01cb0e9e9fa..de0d22b560b4bd20b96504f5aee01a9222a36d3a 100644 --- a/daemon/src/sip/siptransport.cpp +++ b/daemon/src/sip/siptransport.cpp @@ -131,8 +131,20 @@ cp_(cp), pool_(pool), endpt_(endpt) SipTransportBroker::~SipTransportBroker() { + SFL_DBG("Destroying SipTransportBroker"); + + { + std::lock_guard<std::mutex> lock(transportMapMutex_); + udpTransports_.clear(); + transports_.clear(); + } instance = nullptr; pjsip_tpmgr_set_state_cb(pjsip_endpt_get_tpmgr(endpt_), nullptr); + { + std::unique_lock<std::mutex> lock(iceMutex_); + if (not iceTransports_.empty()) + SFL_WARN("Remaining %u registred ICE transports", iceTransports_.size()); + } } /** Static tranport state change callback */ @@ -166,10 +178,11 @@ SipTransportBroker::transportStateChanged(pjsip_transport* tp, pjsip_transport_s } #if PJ_VERSION_NUM > (2 << 24 | 1 << 16) - if (state == PJSIP_TP_STATE_DESTROY) { + if (state == PJSIP_TP_STATE_DESTROY) #else - if (tp->is_destroying) { + if (tp->is_destroying) #endif + { std::lock_guard<std::mutex> lock(transportMapMutex_); // Transport map cleanup @@ -179,30 +192,17 @@ SipTransportBroker::transportStateChanged(pjsip_transport* tp, pjsip_transport_s // If UDP const auto type = tp->key.type; - //if (std::strlen(tp->type_name) >= 3 && std::strncmp(tp->type_name, "UDP", 3ul) == 0) { if (type == PJSIP_TRANSPORT_UDP || type == PJSIP_TRANSPORT_UDP6) { - SFL_WARN("UDP transport destroy"); - auto transport_key = std::find_if(udpTransports_.cbegin(), udpTransports_.cend(), [tp](const std::pair<SipTransportDescr, pjsip_transport*>& i) { return i.second == tp; }); if (transport_key != udpTransports_.end()) { + SFL_WARN("UDP transport destroy"); transports_.erase(transport_key->second); udpTransports_.erase(transport_key); transportDestroyedCv_.notify_all(); } } -#if HAVE_DHT - else if (type == ice_pj_transport_type_) { - SFL_WARN("ICE transport destroy"); - std::unique_lock<std::mutex> lock(iceMutex_); - const auto transport_key = std::find_if(iceTransports_.begin(), iceTransports_.end(), [tp](const SipIceTransport& i) { - return reinterpret_cast<const pjsip_transport*>(&i) == tp; - }); - if (transport_key != iceTransports_.end()) - iceTransports_.erase(transport_key); - } -#endif } } @@ -379,10 +379,20 @@ SipTransportBroker::getTlsTransport(const std::shared_ptr<TlsListener>& l, const #if HAVE_DHT std::shared_ptr<SipTransport> -SipTransportBroker::getIceTransport(const std::shared_ptr<sfl::IceTransport>& ice, unsigned comp_id) +SipTransportBroker::getIceTransport(const std::shared_ptr<sfl::IceTransport> ice, unsigned comp_id) { std::unique_lock<std::mutex> lock(iceMutex_); - iceTransports_.emplace_front(endpt_, pool_, ice_pj_transport_type_, ice, comp_id); + iceTransports_.emplace_front(endpt_, pool_, ice_pj_transport_type_, ice, comp_id, [=]() -> int { + std::unique_lock<std::mutex> lock(iceMutex_); + const auto ice_transport_key = std::find_if(iceTransports_.begin(), iceTransports_.end(), [&](const SipIceTransport& i) { + return i.getIceTransport() == ice; + }); + if (ice_transport_key != iceTransports_.end()) { + iceTransports_.erase(ice_transport_key); + return PJ_SUCCESS; + } + return PJ_ENOTFOUND; + }); auto& sip_ice_tr = iceTransports_.front(); auto ret = std::make_shared<SipTransport>(&sip_ice_tr.base); { diff --git a/daemon/src/sip/siptransport.h b/daemon/src/sip/siptransport.h index 93e7b97877c15f20c3a660a53e4ae14c8b3af4c1..3e94a593a426f407843ca54c760de6bf3e4ad931 100644 --- a/daemon/src/sip/siptransport.h +++ b/daemon/src/sip/siptransport.h @@ -179,7 +179,7 @@ public: #endif #if HAVE_DHT - std::shared_ptr<SipTransport> getIceTransport(const std::shared_ptr<sfl::IceTransport>&, unsigned comp_id); + std::shared_ptr<SipTransport> getIceTransport(const std::shared_ptr<sfl::IceTransport>, unsigned comp_id); #endif std::shared_ptr<SipTransport> findTransport(pjsip_transport*);