res_fax: Resolve T38 gateway frame leak.
authorCorey Farrell <git@cfware.com>
Tue, 28 Oct 2014 21:10:42 +0000 (21:10 +0000)
committerCorey Farrell <git@cfware.com>
Tue, 28 Oct 2014 21:10:42 +0000 (21:10 +0000)
When frames are translated by a fax gateway they need to be freed.  The
existing call to ast_frfree was unreachable.  This change reorganizes
fax_gateway_framehook to ensure that ast_frfree is called when needed.

ASTERISK-24457 #close
Reported by: Corey Farrell
Review: https://reviewboard.asterisk.org/r/4115/
........

Merged revisions 426527 from http://svn.asterisk.org/svn/asterisk/branches/11
........

Merged revisions 426528 from http://svn.asterisk.org/svn/asterisk/branches/12
........

Merged revisions 426529 from http://svn.asterisk.org/svn/asterisk/branches/13

git-svn-id: https://origsvn.digium.com/svn/asterisk/trunk@426530 65c4cc65-6c06-0410-ace0-fbb531ad65f3

res/res_fax.c

index 01228c1..cfe3dd1 100644 (file)
@@ -3419,26 +3419,25 @@ static struct ast_frame *fax_gateway_framehook(struct ast_channel *chan, struct
 
        /* in gateway mode, gateway some packets */
        if (gateway->t38_state == T38_STATE_NEGOTIATED) {
+               struct ast_trans_pvt *readtrans;
                /* framehooks are called in __ast_read() before frame format
                 * translation is done, so we need to translate here */
-               if ((f->frametype == AST_FRAME_VOICE) && (ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL)) {
-                       if (ast_channel_readtrans(active) && (f = ast_translate(ast_channel_readtrans(active), f, 1)) == NULL) {
+               if ((f->frametype == AST_FRAME_VOICE) && (ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL)
+                       && (readtrans = ast_channel_readtrans(active))) {
+                       if ((f = ast_translate(readtrans, f, 1)) == NULL) {
                                f = &ast_null_frame;
                                return f;
                        }
-               }
-
-               /* XXX we ignore the return value here, perhaps we should
-                * disable the gateway if a write fails. I am not sure how a
-                * write would fail, or even if a failure would be fatal so for
-                * now we'll just ignore the return value. */
-               gateway->s->tech->write(gateway->s, f);
-               if ((f->frametype == AST_FRAME_VOICE) && (ast_format_cmp(f->subclass.format, ast_format_slin) != AST_FORMAT_CMP_EQUAL) &&
-                       ast_channel_readtrans(active)) {
-                       /* Only free the frame if we translated / duplicated it - otherwise,
-                        * let whatever is outside the frame hook do it */
+                       /* XXX we ignore the return value here, perhaps we should
+                        * disable the gateway if a write fails. I am not sure how a
+                        * write would fail, or even if a failure would be fatal so for
+                        * now we'll just ignore the return value. */
+                       gateway->s->tech->write(gateway->s, f);
                        ast_frfree(f);
+               } else {
+                       gateway->s->tech->write(gateway->s, f);
                }
+
                f = &ast_null_frame;
                return f;
        }