]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
T.140: Fix format ref and memory leaks. 98/4798/2
authorRichard Mudgett <rmudgett@digium.com>
Tue, 10 Jan 2017 23:39:02 +0000 (17:39 -0600)
committerRichard Mudgett <rmudgett@digium.com>
Wed, 25 Jan 2017 19:44:26 +0000 (13:44 -0600)
* channel.c:ast_sendtext(): Fix T.140 SendText memory leak.

* format_compatibility.c: T.140 RED and T.140 were swapped.

* res_rtp_asterisk.c:rtp_red_init(): Fix ast_format_t140_red ref leak.

* res_rtp_asterisk.c:rtp_red_init(): Fix data race after starting periodic
scheduled red_write().

* res_rtp_asterisk.c: Some other minor misc tweaks.

Change-Id: Ifa27a2e0f8a966b1cf628607c86fc4374b0b88cb

main/channel.c
main/format_compatibility.c
res/res_rtp_asterisk.c

index 637488a9c51178c73c27df78ff82c020bc414e26..f305cc8bb37e71d98fc51d0b3abd0f9b24ba117a 100644 (file)
@@ -4889,16 +4889,18 @@ int ast_sendtext(struct ast_channel *chan, const char *text)
        if (ast_channel_tech(chan)->write_text && (ast_format_cap_has_type(ast_channel_nativeformats(chan), AST_MEDIA_TYPE_TEXT))) {
                struct ast_frame f;
 
+               memset(&f, 0, sizeof(f));
                f.frametype = AST_FRAME_TEXT;
                f.src = "DIALPLAN";
                f.mallocd = AST_MALLOCD_DATA;
                f.datalen = strlen(text);
                f.data.ptr = ast_strdup(text);
-               f.offset = 0;
-               f.seqno = 0;
-
                f.subclass.format = ast_format_t140;
-               res = ast_channel_tech(chan)->write_text(chan, &f);
+
+               if (f.data.ptr) {
+                       res = ast_channel_tech(chan)->write_text(chan, &f);
+                       ast_frfree(&f);
+               }
        } else if (ast_channel_tech(chan)->send_text) {
                res = ast_channel_tech(chan)->send_text(chan, text);
        }
index cf66af282a092b067af65f7702b196f6b64d3eee..0f1dff7c8ef03b62237ec97315f6fc052f459009 100644 (file)
@@ -264,10 +264,10 @@ struct ast_format *ast_format_compatibility_bitfield2format(uint64_t bitfield)
 
        /*! T.140 RED Text format RFC 4103 */
        case AST_FORMAT_T140_RED:
-               return ast_format_t140;
+               return ast_format_t140_red;
        /*! T.140 Text format - ITU T.140, RFC 4103 */
        case AST_FORMAT_T140:
-               return ast_format_t140_red;
+               return ast_format_t140;
        }
        return NULL;
 }
index 2409e3aee10785b0f34fc47ade82975b57c7059a..25d2a1fc91f8f2be838019504f945b2411d1d977 100644 (file)
@@ -232,6 +232,7 @@ struct dtls_details {
 /*! \brief RTP session description */
 struct ast_rtp {
        int s;
+       /*! \note The f.subclass.format holds a ref. */
        struct ast_frame f;
        unsigned char rawdata[8192 + AST_FRIENDLY_OFFSET];
        unsigned int ssrc;              /*!< Synchronization source, RFC 3550, page 10. */
@@ -2767,6 +2768,7 @@ static int ast_rtp_destroy(struct ast_rtp_instance *instance)
        if (rtp->red) {
                AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
                ast_free(rtp->red);
+               rtp->red = NULL;
        }
 
 #ifdef HAVE_PJPROJECT
@@ -3487,7 +3489,8 @@ static int ast_rtp_raw_write(struct ast_rtp_instance *instance, struct ast_frame
        return 0;
 }
 
-static struct ast_frame *red_t140_to_red(struct rtp_red *red) {
+static struct ast_frame *red_t140_to_red(struct rtp_red *red)
+{
        unsigned char *data = red->t140red.data.ptr;
        int len = 0;
        int i;
@@ -5062,22 +5065,21 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
        struct ast_rtp *rtp = ast_rtp_instance_get_data(instance);
        int x;
 
-       if (!(rtp->red = ast_calloc(1, sizeof(*rtp->red)))) {
+       rtp->red = ast_calloc(1, sizeof(*rtp->red));
+       if (!rtp->red) {
                return -1;
        }
 
        rtp->red->t140.frametype = AST_FRAME_TEXT;
-       ao2_replace(rtp->red->t140.subclass.format, ast_format_t140_red);
+       rtp->red->t140.subclass.format = ast_format_t140_red;
        rtp->red->t140.data.ptr = &rtp->red->buf_data;
 
-       rtp->red->t140.ts = 0;
        rtp->red->t140red = rtp->red->t140;
        rtp->red->t140red.data.ptr = &rtp->red->t140red_data;
-       rtp->red->t140red.datalen = 0;
+
        rtp->red->ti = buffer_time;
        rtp->red->num_gen = generations;
        rtp->red->hdrlen = generations * 4 + 1;
-       rtp->red->prev_ts = 0;
 
        for (x = 0; x < generations; x++) {
                rtp->red->pt[x] = payloads[x];
@@ -5087,8 +5089,6 @@ static int rtp_red_init(struct ast_rtp_instance *instance, int buffer_time, int
        rtp->red->t140red_data[x*4] = rtp->red->pt[x] = payloads[x]; /* primary pt */
        rtp->red->schedid = ast_sched_add(rtp->sched, generations, red_write, instance);
 
-       rtp->red->t140.datalen = 0;
-
        return 0;
 }
 
@@ -5216,7 +5216,7 @@ static void ast_rtp_stop(struct ast_rtp_instance *instance)
 
        if (rtp->red) {
                AST_SCHED_DEL(rtp->sched, rtp->red->schedid);
-               free(rtp->red);
+               ast_free(rtp->red);
                rtp->red = NULL;
        }