[1/2] tls_openssl: Readd support for nonblocking operation

Message ID 20170619125246.65326-1-martin@martin.st
State Committed
Headers show

Commit Message

Martin Storsjö June 19, 2017, 12:52 p.m.
The rtmp protocol uses nonblocking reads, to poll for incoming
messages from the server while publishing a stream. Prior to
94599a6de3822b13c94096d764868128f388ba28 and
d13b124eaf452b267480074b2e6946538ed03a6e, the tls protocol
handled the nonblocking flag.

This fixes publishing over rtmps, with the openssl backend.
---
 libavformat/tls_openssl.c | 21 +++++++++++++++++++--
 1 file changed, 19 insertions(+), 2 deletions(-)

Comments

Diego Biurrun June 20, 2017, 9:35 a.m. | #1
On Mon, Jun 19, 2017 at 03:52:45PM +0300, Martin Storsjö wrote:
> The rtmp protocol uses nonblocking reads, to poll for incoming
> messages from the server while publishing a stream. Prior to
> 94599a6de3822b13c94096d764868128f388ba28 and
> d13b124eaf452b267480074b2e6946538ed03a6e, the tls protocol
> handled the nonblocking flag.

same comment as for gnutls

probably OK

Diego

Patch

diff --git a/libavformat/tls_openssl.c b/libavformat/tls_openssl.c
index 71fa96871d..b9c5dfa6ee 100644
--- a/libavformat/tls_openssl.c
+++ b/libavformat/tls_openssl.c
@@ -109,6 +109,11 @@  void ff_openssl_deinit(void)
 
 static int print_tls_error(URLContext *h, int ret)
 {
+    if (h->flags & AVIO_FLAG_NONBLOCK) {
+        int err = SSL_get_error(c->ssl, ret);
+        if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_READ)
+            return AVERROR(EAGAIN);
+    }
     av_log(h, AV_LOG_ERROR, "%s\n", ERR_error_string(ERR_get_error(), NULL));
     return AVERROR(EIO);
 }
@@ -164,6 +169,8 @@  static int url_bio_bread(BIO *b, char *buf, int len)
     if (ret >= 0)
         return ret;
     BIO_clear_retry_flags(b);
+    if (ret == AVERROR(EAGAIN))
+        BIO_set_retry_read(b);
     if (ret == AVERROR_EXIT)
         return 0;
     return -1;
@@ -176,6 +183,8 @@  static int url_bio_bwrite(BIO *b, const char *buf, int len)
     if (ret >= 0)
         return ret;
     BIO_clear_retry_flags(b);
+    if (ret == AVERROR(EAGAIN))
+        BIO_set_retry_write(b);
     if (ret == AVERROR_EXIT)
         return 0;
     return -1;
@@ -292,7 +301,11 @@  fail:
 static int tls_read(URLContext *h, uint8_t *buf, int size)
 {
     TLSContext *c = h->priv_data;
-    int ret = SSL_read(c->ssl, buf, size);
+    int ret;
+    // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
+    c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
+    c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
+    ret = SSL_read(c->ssl, buf, size);
     if (ret > 0)
         return ret;
     if (ret == 0)
@@ -303,7 +316,11 @@  static int tls_read(URLContext *h, uint8_t *buf, int size)
 static int tls_write(URLContext *h, const uint8_t *buf, int size)
 {
     TLSContext *c = h->priv_data;
-    int ret = SSL_write(c->ssl, buf, size);
+    int ret;
+    // Set or clear the AVIO_FLAG_NONBLOCK on c->tls_shared.tcp
+    c->tls_shared.tcp->flags &= ~AVIO_FLAG_NONBLOCK;
+    c->tls_shared.tcp->flags |= h->flags & AVIO_FLAG_NONBLOCK;
+    ret = SSL_write(c->ssl, buf, size);
     if (ret > 0)
         return ret;
     if (ret == 0)