]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
app_dial: Fix infinite loop when sending digits.
authorNaveen Albert <asterisk@phreaknet.org>
Mon, 28 Aug 2023 17:51:23 +0000 (13:51 -0400)
committerNaveen Albert <asterisk@phreaknet.org>
Thu, 31 Aug 2023 13:20:06 +0000 (13:20 +0000)
If the called party hangs up while digits are being
sent, -1 is returned to indicate so, but app_dial
was not checking the return value, resulting in
the hangup being lost and looping forever until
the caller manually hangs up the channel. We now
abort if digit sending fails.

ASTERISK-29428 #close

Resolves: #281

apps/app_dial.c

index 5c6982a292a0839f000b4919a4fb02f365970f89..5be1e0aa6ed48dcaabc701b91c178c3218f66a7f 100644 (file)
@@ -1272,6 +1272,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                }
                winner = ast_waitfor_n(watchers, pos, to);
                AST_LIST_TRAVERSE(out_chans, o, node) {
+                       int res = 0;
                        struct ast_frame *f;
                        struct ast_channel *c = o->chan;
 
@@ -1548,7 +1549,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                                "Sending MF '%s' to %s as result of "
                                                                "receiving a PROGRESS message.\n",
                                                                mf_progress, hearpulsing ? "parties" : "called party");
-                                                       ast_mf_stream(c, (hearpulsing ? NULL : in),
+                                                       res |= ast_mf_stream(c, (hearpulsing ? NULL : in),
                                                        (hearpulsing ? in : NULL), mf_progress, 50, 55, 120, 65, 0);
                                                }
                                                if (!ast_strlen_zero(sf_progress)) {
@@ -1556,7 +1557,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                                "Sending SF '%s' to %s as result of "
                                                                "receiving a PROGRESS message.\n",
                                                                sf_progress, (hearpulsing ? "parties" : "called party"));
-                                                       ast_sf_stream(c, (hearpulsing ? NULL : in),
+                                                       res |= ast_sf_stream(c, (hearpulsing ? NULL : in),
                                                        (hearpulsing ? in : NULL), sf_progress, 0, 0);
                                                }
                                                if (!ast_strlen_zero(dtmf_progress)) {
@@ -1564,7 +1565,11 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                                "Sending DTMF '%s' to the called party as result of "
                                                                "receiving a PROGRESS message.\n",
                                                                dtmf_progress);
-                                                       ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
+                                                       res |= ast_dtmf_stream(c, in, dtmf_progress, 250, 0);
+                                               }
+                                               if (res) {
+                                                       ast_log(LOG_WARNING, "Called channel %s hung up post-progress before all digits could be sent\n", ast_channel_name(c));
+                                                       goto wait_over;
                                                }
                                        }
                                        ast_channel_publish_dial(in, c, NULL, "PROGRESS");
@@ -1578,7 +1583,7 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                                "Sending MF '%s' to %s as result of "
                                                                "receiving a WINK message.\n",
                                                                mf_wink, (hearpulsing ? "parties" : "called party"));
-                                                       ast_mf_stream(c, (hearpulsing ? NULL : in),
+                                                       res |= ast_mf_stream(c, (hearpulsing ? NULL : in),
                                                        (hearpulsing ? in : NULL), mf_wink, 50, 55, 120, 65, 0);
                                                }
                                                if (!ast_strlen_zero(sf_wink)) {
@@ -1586,9 +1591,13 @@ static struct ast_channel *wait_for_answer(struct ast_channel *in,
                                                                "Sending SF '%s' to %s as result of "
                                                                "receiving a WINK message.\n",
                                                                sf_wink, (hearpulsing ? "parties" : "called party"));
-                                                       ast_sf_stream(c, (hearpulsing ? NULL : in),
+                                                       res |= ast_sf_stream(c, (hearpulsing ? NULL : in),
                                                        (hearpulsing ? in : NULL), sf_wink, 0, 0);
                                                }
+                                               if (res) {
+                                                       ast_log(LOG_WARNING, "Called channel %s hung up post-wink before all digits could be sent\n", ast_channel_name(c));
+                                                       goto wait_over;
+                                               }
                                        }
                                        ast_indicate(in, AST_CONTROL_WINK);
                                        break;
@@ -1886,6 +1895,7 @@ skip_frame:;
                }
        }
 
+wait_over:
        if (!*to || ast_check_hangup(in)) {
                ast_verb(3, "Nobody picked up in %d ms\n", orig);
                publish_dial_end_event(in, out_chans, NULL, "NOANSWER");