]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
AST-2014-007: Fix of fix to allow AMI and SIP TCP to send messages.
authorRichard Mudgett <rmudgett@digium.com>
Fri, 13 Jun 2014 05:22:56 +0000 (05:22 +0000)
committerRichard Mudgett <rmudgett@digium.com>
Fri, 13 Jun 2014 05:22:56 +0000 (05:22 +0000)
ASTERISK-23673 #close
Reported by: Richard Mudgett

Review: https://reviewboard.asterisk.org/r/3617/
........

Merged revisions 416066 from http://svn.asterisk.org/svn/asterisk/branches/1.8

git-svn-id: https://origsvn.digium.com/svn/asterisk/certified/branches/1.8.15@416087 65c4cc65-6c06-0410-ace0-fbb531ad65f3

channels/chan_sip.c
include/asterisk/tcptls.h
main/http.c
main/manager.c
main/tcptls.c

index d3517202343176d79c5f85069e6a879e5376a3bc..7991b66aecf7a8a61cd315584bf08a53b08a3822 100644 (file)
@@ -2614,6 +2614,12 @@ static void *_sip_tcp_helper_thread(struct ast_tcptls_session_instance *tcptls_s
                goto cleanup;
        }
 
+       /*
+        * We cannot let the stream exclusively wait for data to arrive.
+        * We have to wake up the task to send outgoing messages.
+        */
+       ast_tcptls_stream_set_exclusive_input(tcptls_session->stream_cookie, 0);
+
        ast_tcptls_stream_set_timeout_sequence(tcptls_session->stream_cookie, ast_tvnow(),
                tcptls_session->client ? -1 : (authtimeout * 1000));
 
index cc7078bff33a8fb64bfc7b2df41a4216514d76af..df64a279d12e87c60168533611796cd265596e50 100644 (file)
@@ -181,6 +181,20 @@ void ast_tcptls_stream_set_timeout_inactivity(struct ast_tcptls_stream *stream,
  */
 void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, struct timeval start, int timeout);
 
+/*!
+ * \brief Set the TCP/TLS stream I/O if it can exclusively depend upon the set timeouts.
+ *
+ * \param stream TCP/TLS stream control data.
+ * \param exclusive_input TRUE if stream can exclusively wait for fd input.
+ * Otherwise, the stream will not wait for fd input.  It will wait while
+ * trying to send data.
+ *
+ * \note The stream timeouts still need to be set.
+ *
+ * \return Nothing
+ */
+void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input);
+
 /*
  * describes a server instance
  */
index 95d2ac268ae80aef78e02dff833dccaaf4f6e025..49836d699901d3b2e703e68d8b37268c96a1588b 100644 (file)
@@ -895,6 +895,9 @@ static void *httpd_helper_thread(void *data)
        flags |= O_NONBLOCK;
        fcntl(ser->fd, F_SETFL, flags);
 
+       /* We can let the stream wait for data to arrive. */
+       ast_tcptls_stream_set_exclusive_input(ser->stream_cookie, 1);
+
        ast_tcptls_stream_set_timeout_inactivity(ser->stream_cookie, session_inactivity);
 
        if (!fgets(buf, sizeof(buf), ser->f) || feof(ser->f)) {
index 77d9863eea7789704c0d5265e6099ab5de3b78ec..db907f2546ce4018e0a92e0472cc6feefc5ad40e 100644 (file)
@@ -5029,6 +5029,12 @@ static void *session_do(void *data)
        }
        ao2_unlock(session);
 
+       /*
+        * We cannot let the stream exclusively wait for data to arrive.
+        * We have to wake up the task to send async events.
+        */
+       ast_tcptls_stream_set_exclusive_input(ser->stream_cookie, 0);
+
        ast_tcptls_stream_set_timeout_sequence(ser->stream_cookie,
                ast_tvnow(), authtimeout * 1000);
 
index cb4041194a42dc88e202054d5bfb8bdf299cd2a4..4233e1f07e534d243a5017c7fa73124fd514f890 100644 (file)
@@ -77,6 +77,8 @@ struct ast_tcptls_stream {
         * feature to work correctly.
         */
        int timeout;
+       /*! TRUE if stream can exclusively wait for fd input. */
+       int exclusive_input;
 };
 
 void ast_tcptls_stream_set_timeout_disable(struct ast_tcptls_stream *stream)
@@ -102,6 +104,13 @@ void ast_tcptls_stream_set_timeout_sequence(struct ast_tcptls_stream *stream, st
        stream->timeout = timeout;
 }
 
+void ast_tcptls_stream_set_exclusive_input(struct ast_tcptls_stream *stream, int exclusive_input)
+{
+       ast_assert(stream != NULL);
+
+       stream->exclusive_input = exclusive_input;
+}
+
 /*!
  * \internal
  * \brief fopencookie()/funopen() stream read function.
@@ -151,6 +160,11 @@ static HOOK_T tcptls_stream_read(void *cookie, char *buf, LEN_T size)
                                ast_debug(1, "TLS clean shutdown alert reading data\n");
                                return 0;
                        case SSL_ERROR_WANT_READ:
+                               if (!stream->exclusive_input) {
+                                       /* We cannot wait for data now. */
+                                       errno = EAGAIN;
+                                       return -1;
+                               }
                                while ((ms = ast_remaining_ms(start, stream->timeout))) {
                                        res = ast_wait_for_input(stream->fd, ms);
                                        if (0 < res) {
@@ -202,7 +216,8 @@ static HOOK_T tcptls_stream_read(void *cookie, char *buf, LEN_T size)
 
        for (;;) {
                res = read(stream->fd, buf, size);
-               if (0 <= res) {
+               if (0 <= res || !stream->exclusive_input) {
+                       /* Got data or we cannot wait for it. */
                        return res;
                }
                if (errno != EINTR && errno != EAGAIN) {