Commit a251e834 authored by Adrien Béraud's avatar Adrien Béraud Committed by Guillaume Roguez

sip_ice_transport: fix destruction

Refs #63196

Change-Id: I633318843e0b58ddb3cf97c0be8bf94eb4c7431e
parent 47a36280
......@@ -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_();
}
......@@ -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);
......
......@@ -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);
{
......
......@@ -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*);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment