MT#65511 AmB2BSession: `media_session` clean in destructor

Normal shutdown already triggers the `clearRtpReceiverRelay()`
in `AmB2BSession::onBeforeDestroy()`, so the destructor should
actually normally see `media_session` ptr nulled.

But it seems in some of the fork/transfer related scenarios
this doesn't happen.

So adding the defensive clean-up on the same manner
the destructor of the `CallLeg` has (it uses the `releaseMediaSession()`,
which is essentially the same: `stop()`; `releaseReference()` and NULLing),
makes it consistent with these other_legs cleanup.

The main reason is caused by a call leg (`AmB2BSession`), which was freed
while the `AmB2BMedia::a` / `AmB2BMedia::b` still points to it.
In this case we can crash during the media-thread DTMF processing.

This fix is a hardening rather than a fix of the root cause.
The root cause still is related to the cleanup path:
certain call leg gets torn down through the path that skips (or maybe even races)
the normal `onBeforeDestroy()`/`clearRtpReceiverRelay()` cleanup,
leaving its shared `AmB2BMedia` with a dangling `a` or `b` pointer.
Meanwhile the `a` / `b` are raw, non-owned pointers, which may remain dangling.

Change-Id: Ia1ee42a27014d2086b37a787f8555e6d7681d4a8
mr26.2
Donat Zenichev 4 weeks ago
parent 1c4e206c53
commit 5e412586e5

@ -127,6 +127,17 @@ AmB2BSession::~AmB2BSession()
{
ILOG_DLG(L_DBG, "relayed_req.size() = %zu\n",relayed_req.size());
/* defensive release of the primary media_session, for the case when
* some fork/transfer path forgets to call clearRtpReceiverRelay(),
* the media_session ptr still gets nulled out before the object's memory is released.
*/
if (media_session) {
ILOG_DLG(L_ERR, "This media_session was not released before AmB2BSession destruction! Do it now.\n");
media_session->stop(a_leg);
media_session->releaseReference();
media_session = NULL;
}
map<int,AmSipRequest>::iterator it = recvd_req.begin();
ILOG_DLG(L_DBG, "recvd_req.size() = %zu\n",recvd_req.size());
for(;it != recvd_req.end(); ++it){
@ -137,7 +148,7 @@ AmB2BSession::~AmB2BSession()
delete subs;
}
void AmB2BSession::set_sip_relay_only(bool r) {
void AmB2BSession::set_sip_relay_only(bool r) {
if (!getLocalTag().empty())
ILOG_DLG(L_DBG, "Set sip_relay_only=%s for local_tag '%s'\n", (r ? "true" : "false"), getLocalTag().c_str());

Loading…
Cancel
Save