]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
chan_sip: Don't allocate new RTP instances on top of old ones.
authorJoshua Colp <jcolp@digium.com>
Tue, 23 Aug 2016 11:31:05 +0000 (11:31 +0000)
committerJoshua Colp <jcolp@digium.com>
Fri, 9 Sep 2016 10:34:44 +0000 (10:34 +0000)
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-11.patch submitted by Corey Farrell (license 5909)

Change-Id: I3c1d94dea8594fe0702168cb979b898ae0f5fc5d

channels/chan_sip.c

index 1e686c8106a6a9b0d7098aa434d1d7cb87d75bf4..b65f612751f59e96f1baefc3873adad8492a5a26 100644 (file)
@@ -5698,6 +5698,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) {
+               sip_srtp_destroy(p->srtp);
+               p->srtp = NULL;
+       }
+
+       if (p->tsrtp) {
+               sip_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 sip_srtp **srtp)
 {
@@ -5745,6 +5777,9 @@ static int dialog_initialize_rtp(struct sip_pvt *dialog)
                return 0;
        }
 
+       /* Make sure previous RTP instances/FD's do not leak */
+       dialog_clean_rtp(dialog);
+
        ast_sockaddr_copy(&bindaddr_tmp, &bindaddr);
        if (!(dialog->rtp = ast_rtp_instance_new(dialog->engine, sched, &bindaddr_tmp, NULL))) {
                return -1;
@@ -6409,18 +6444,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;
@@ -6456,21 +6483,11 @@ static void sip_pvt_dtor(void *vdoomed)
 
        destroy_msg_headers(p);
 
-       if (p->srtp) {
-               sip_srtp_destroy(p->srtp);
-               p->srtp = NULL;
-       }
-
        if (p->vsrtp) {
                sip_srtp_destroy(p->vsrtp);
                p->vsrtp = NULL;
        }
 
-       if (p->tsrtp) {
-               sip_srtp_destroy(p->tsrtp);
-               p->tsrtp = NULL;
-       }
-
        if (p->directmediaacl) {
                p->directmediaacl = ast_free_acl_list(p->directmediaacl);
        }