[glib-networking/enable-openssl-tests: 1/2] fixup! openssl: reimplement read/write to be always non blocking



commit db9a571f612bd1e2746bada98c28935e277af3e6
Author: Ignacio Casal Quinteiro <icq gnome org>
Date:   Fri May 24 16:22:54 2019 +0200

    fixup! openssl: reimplement read/write to be always non blocking

 tls/openssl/gtlsbio.c                | 17 +++++++++++------
 tls/openssl/gtlsconnection-openssl.c | 23 ++++++++++++++---------
 2 files changed, 25 insertions(+), 15 deletions(-)
---
diff --git a/tls/openssl/gtlsbio.c b/tls/openssl/gtlsbio.c
index 826cb50..4dfd058 100644
--- a/tls/openssl/gtlsbio.c
+++ b/tls/openssl/gtlsbio.c
@@ -35,6 +35,8 @@ typedef struct {
   gboolean write_blocking;
   GError **read_error;
   GError **write_error;
+  GMainContext *context;
+  GMainLoop *loop;
 } GTlsBio;
 
 static void
@@ -43,6 +45,8 @@ free_gbio (gpointer user_data)
   GTlsBio *bio = (GTlsBio *)user_data;
 
   g_object_unref (bio->io_stream);
+  g_main_context_unref (bio->context);
+  g_main_loop_unref (bio->loop);
   g_free (bio);
 }
 
@@ -290,6 +294,8 @@ g_tls_bio_new (GIOStream *io_stream)
 
   gbio = g_new0 (GTlsBio, 1);
   gbio->io_stream = g_object_ref (io_stream);
+  gbio->context = g_main_context_new ();
+  gbio->loop = g_main_loop_new (gbio->context, FALSE);
 
 #if OPENSSL_VERSION_NUMBER < 0x10100000L || defined (LIBRESSL_VERSION_NUMBER)
   ret->ptr = gbio;
@@ -415,7 +421,6 @@ g_tls_bio_wait_available (BIO          *bio,
                           GCancellable *cancellable)
 {
   GTlsBio *gbio;
-  GMainLoop *loop;
   GSource *source;
 
   g_return_if_fail (bio != NULL);
@@ -426,7 +431,7 @@ g_tls_bio_wait_available (BIO          *bio,
   gbio = BIO_get_data (bio);
 #endif
 
-  loop = g_main_loop_new (g_main_context_get_thread_default (), FALSE);
+  g_main_context_push_thread_default (gbio->context);
 
   if (condition & G_IO_IN)
     source = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream 
(gbio->io_stream)),
@@ -435,11 +440,11 @@ g_tls_bio_wait_available (BIO          *bio,
     source = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream 
(gbio->io_stream)),
                                                      cancellable);
 
-  g_source_set_callback (source, (GSourceFunc)on_source_ready, loop, NULL);
-  g_source_attach (source, g_main_context_get_thread_default ());
+  g_source_set_callback (source, (GSourceFunc)on_source_ready, gbio->loop, NULL);
+  g_source_attach (source, gbio->context);
 
-  g_main_loop_run (loop);
-  g_main_loop_unref (loop);
+  g_main_loop_run (gbio->loop);
+  g_main_context_pop_thread_default (gbio->context);
 
   g_source_destroy (source);
   g_source_unref (source);
diff --git a/tls/openssl/gtlsconnection-openssl.c b/tls/openssl/gtlsconnection-openssl.c
index 515f4fb..96dcd16 100644
--- a/tls/openssl/gtlsconnection-openssl.c
+++ b/tls/openssl/gtlsconnection-openssl.c
@@ -70,6 +70,7 @@ static GTlsConnectionBaseStatus
 end_openssl_io (GTlsConnectionOpenssl  *openssl,
                 GIOCondition            direction,
                 int                     ret,
+                gboolean                blocking,
                 GError                **error,
                 const char             *err_prefix,
                 const char             *err_str)
@@ -89,8 +90,9 @@ end_openssl_io (GTlsConnectionOpenssl  *openssl,
 
   status = g_tls_connection_base_pop_io (tls, direction, ret > 0, &my_error);
 
-  if (err_code == SSL_ERROR_WANT_READ ||
-      err_code == SSL_ERROR_WANT_WRITE)
+  if ((err_code == SSL_ERROR_WANT_READ ||
+       err_code == SSL_ERROR_WANT_WRITE) &&
+      blocking)
     {
       if (my_error)
         g_error_free (my_error);
@@ -205,9 +207,9 @@ end_openssl_io (GTlsConnectionOpenssl  *openssl,
     g_tls_connection_base_push_io (G_TLS_CONNECTION_BASE (openssl),         \
                                    direction, timeout, cancellable);
 
-#define END_OPENSSL_IO(openssl, direction, ret, status, errmsg, err)        \
+#define END_OPENSSL_IO(openssl, direction, ret, timeout, status, errmsg, err) \
     ERR_error_string_n (SSL_get_error (ssl, ret), error_str, sizeof(error_str)); \
-    status = end_openssl_io (openssl, direction, ret, err, errmsg, error_str); \
+    status = end_openssl_io (openssl, direction, ret, timeout == -1, err, errmsg, error_str); \
   } while (status == G_TLS_CONNECTION_BASE_TRY_AGAIN);
 
 static GTlsConnectionBaseStatus
@@ -251,7 +253,7 @@ g_tls_connection_openssl_request_rehandshake (GTlsConnectionBase  *tls,
 
   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, timeout, cancellable);
   ret = SSL_renegotiate (ssl);
-  END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
+  END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, timeout, status,
                   _("Error performing TLS handshake"), error);
 
   return status;
@@ -301,7 +303,7 @@ g_tls_connection_openssl_handshake_thread_handshake (GTlsConnectionBase  *tls,
 
   BEGIN_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, timeout, cancellable);
   ret = SSL_do_handshake (ssl);
-  END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
+  END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, timeout, status,
                   _("Error performing TLS handshake"), error);
 
   if (ret > 0)
@@ -394,6 +396,9 @@ g_tls_connection_openssl_read (GTlsConnectionBase    *tls,
 
   ssl = g_tls_connection_openssl_get_ssl (openssl);
 
+  /* FIXME: revert back to use BEGIN/END_OPENSSL_IO once we move all the ssl
+   * operations into a worker thread
+   */
   while (TRUE)
     {
       char error_str[256];
@@ -405,7 +410,7 @@ g_tls_connection_openssl_read (GTlsConnectionBase    *tls,
       ret = SSL_read (ssl, buffer, count);
 
       ERR_error_string_n (SSL_get_error (ssl, ret), error_str, sizeof (error_str));
-      status = end_openssl_io (openssl, G_IO_IN, ret, error,
+      status = end_openssl_io (openssl, G_IO_IN, ret, timeout == -1, error,
                                _("Error reading data from TLS socket"), error_str);
 
       if (status != G_TLS_CONNECTION_BASE_TRY_AGAIN)
@@ -450,7 +455,7 @@ g_tls_connection_openssl_write (GTlsConnectionBase    *tls,
       ret = SSL_write (ssl, buffer, count);
 
       ERR_error_string_n (SSL_get_error (ssl, ret), error_str, sizeof (error_str));
-      status = end_openssl_io (openssl, G_IO_OUT, ret, error,
+      status = end_openssl_io (openssl, G_IO_OUT, ret, timeout == -1, error,
                                _("Error writing data to TLS socket"), error_str);
 
       if (status != G_TLS_CONNECTION_BASE_TRY_AGAIN)
@@ -488,7 +493,7 @@ g_tls_connection_openssl_close (GTlsConnectionBase  *tls,
    * it means it will close the write direction
    */
   ret = ret == 0 ? 1 : ret;
-  END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, status,
+  END_OPENSSL_IO (openssl, G_IO_IN | G_IO_OUT, ret, timeout, status,
                   _("Error performing TLS close"), error);
 
   return status;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]