summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoshua Colp <jcolp@digium.com>2016-08-23 11:35:11 +0000
committerJoshua Colp <jcolp@digium.com>2016-09-09 10:33:47 +0000
commit82a3d659dceb3300acde2c3908f97a0e2bf2d6b3 (patch)
tree9e0f7d8891cfd8a79ca17aca05082850ee3a75f4
parent345253fb71d08a70f3ae49e59b37445a2c91e421 (diff)
chan_sip: Don't allocate new RTP instances on top of old ones.
In some scenarios dialog_initialize_rtp can be called multiple times on the same dialog. This can cause RTP instances to be leaked along with multiple file descriptors for each instance. This change makes it so the existing RTP instances are destroyed and not overwritten, stopping the memory leak. ASTERISK-26272 #close patches: ASTERISK-26272-13.patch submitted by Corey Farrell (license 5909) Change-Id: Id529de1184c68f2f4d254ab41a1f458dafdb5f73
-rw-r--r--channels/chan_sip.c61
1 files changed, 39 insertions, 22 deletions
diff --git a/channels/chan_sip.c b/channels/chan_sip.c
index 1d70e8975..28ba05f51 100644
--- a/channels/chan_sip.c
+++ b/channels/chan_sip.c
@@ -5875,6 +5875,38 @@ static void copy_socket_data(struct sip_socket *to_sock, const struct sip_socket
*to_sock = *from_sock;
}
+/*! Cleanup the RTP and SRTP portions of a dialog
+ *
+ * \note This procedure excludes vsrtp as it is initialized differently.
+ */
+static void dialog_clean_rtp(struct sip_pvt *p)
+{
+ if (p->rtp) {
+ ast_rtp_instance_destroy(p->rtp);
+ p->rtp = NULL;
+ }
+
+ if (p->vrtp) {
+ ast_rtp_instance_destroy(p->vrtp);
+ p->vrtp = NULL;
+ }
+
+ if (p->trtp) {
+ ast_rtp_instance_destroy(p->trtp);
+ p->trtp = NULL;
+ }
+
+ if (p->srtp) {
+ ast_sdp_srtp_destroy(p->srtp);
+ p->srtp = NULL;
+ }
+
+ if (p->tsrtp) {
+ ast_sdp_srtp_destroy(p->tsrtp);
+ p->tsrtp = NULL;
+ }
+}
+
/*! \brief Initialize DTLS-SRTP support on an RTP instance */
static int dialog_initialize_dtls_srtp(const struct sip_pvt *dialog, struct ast_rtp_instance *rtp, struct ast_sdp_srtp **srtp)
{
@@ -5928,6 +5960,9 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
}
+ /* Make sure previous RTP instances/FD's do not leak */
+ dialog_clean_rtp(dialog);
+
if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
return -1;
}
@@ -6603,18 +6638,10 @@ static void sip_pvt_dtor(void *vdoomed)
ast_free(p->notify);
p->notify = NULL;
}
- if (p->rtp) {
- ast_rtp_instance_destroy(p->rtp);
- p->rtp = NULL;
- }
- if (p->vrtp) {
- ast_rtp_instance_destroy(p->vrtp);
- p->vrtp = NULL;
- }
- if (p->trtp) {
- ast_rtp_instance_destroy(p->trtp);
- p->trtp = NULL;
- }
+
+ /* Free RTP and SRTP instances */
+ dialog_clean_rtp(p);
+
if (p->udptl) {
ast_udptl_destroy(p->udptl);
p->udptl = NULL;
@@ -6647,21 +6674,11 @@ static void sip_pvt_dtor(void *vdoomed)
destroy_msg_headers(p);
- if (p->srtp) {
- ast_sdp_srtp_destroy(p->srtp);
- p->srtp = NULL;
- }
-
if (p->vsrtp) {
ast_sdp_srtp_destroy(p->vsrtp);
p->vsrtp = NULL;
}
- if (p->tsrtp) {
- ast_sdp_srtp_destroy(p->tsrtp);
- p->tsrtp = NULL;
- }
-
if (p->directmediaacl) {
p->directmediaacl = ast_free_acl_list(p->directmediaacl);
}