From d60ee2eeaec7f0a298e95aa37d179d391f8871dd Mon Sep 17 00:00:00 2001 From: mohitdhiman <mohitdhiman@drishti-soft.com> Date: Sat, 12 Jan 2019 13:59:12 +0530 Subject: [PATCH] stasis/endpoint: Fix memory leak of channel_ids in ast_endpoint structure. During Bridging of two channels if masquerade operation is performed on a channel (clone channel) which was created with endpoint details (ast_channel_alloc_with_endpoint()) and the original channel which is created without endpoint details (ast_channel_alloc()) then both the channels must exchange their endpoint details or else after masquerade when clone channel is being destroyed the endpoint cleanup callbacks will be destroyed too and after call completion unique_id of original channel will still be there in ast_endpoint structure's channel_ids container. ASTERISK-28197 Change-Id: I97ce73da390af20fd082fb09d722a6fe9cb2f39d --- include/asterisk/channel.h | 12 ++++++++++++ main/channel.c | 5 +++++ main/channel_internal_api.c | 9 +++++++++ 3 files changed, 26 insertions(+) diff --git a/include/asterisk/channel.h b/include/asterisk/channel.h index 58a4879b00..e2f79592d7 100644 --- a/include/asterisk/channel.h +++ b/include/asterisk/channel.h @@ -2658,6 +2658,18 @@ void ast_channel_internal_swap_uniqueid_and_linkedid(struct ast_channel *a, stru */ void ast_channel_internal_swap_topics(struct ast_channel *a, struct ast_channel *b); +/*! + * \brief Swap endpoint_forward between two channels + * \param a First channel + * \param b Second channel + * \return void + * + * \note + * This is used in masquerade to exchange endpoint details if one of the two or both + * the channels were created with endpoint + */ +void ast_channel_internal_swap_endpoint_forward(struct ast_channel *a, struct ast_channel *b); + /*! * \brief Swap snapshots beteween two channels * \param a First channel diff --git a/main/channel.c b/main/channel.c index 7e12f30492..4fb226d491 100644 --- a/main/channel.c +++ b/main/channel.c @@ -6790,6 +6790,11 @@ static void channel_do_masquerade(struct ast_channel *original, struct ast_chann /* Make sure the Stasis topic on the channel is updated appropriately */ ast_channel_internal_swap_topics(clonechan, original); + /* Swap endpoint forward so channel created with endpoint exchanges its state + * with other channel for proper endpoint cleanup. + */ + ast_channel_internal_swap_endpoint_forward(clonechan, original); + /* The old snapshots need to follow the channels so the snapshot update is correct */ ast_channel_internal_swap_snapshots(clonechan, original); diff --git a/main/channel_internal_api.c b/main/channel_internal_api.c index 30d39097e0..22a2bb6b31 100644 --- a/main/channel_internal_api.c +++ b/main/channel_internal_api.c @@ -1438,6 +1438,15 @@ void ast_channel_internal_swap_topics(struct ast_channel *a, struct ast_channel b->channel_forward = forward; } +void ast_channel_internal_swap_endpoint_forward(struct ast_channel *a, struct ast_channel *b) +{ + struct stasis_forward *temp; + + temp = a->endpoint_forward; + a->endpoint_forward = b->endpoint_forward; + b->endpoint_forward = temp; +} + void ast_channel_internal_swap_snapshots(struct ast_channel *a, struct ast_channel *b) { struct ast_channel_snapshot *snapshot; -- GitLab